package com.hypixel.hytale.server.npc.entities;
import com.hypixel.hytale.assetstore.map.JsonAssetWithMap;
import com.hypixel.hytale.codec.Codec;
import com.hypixel.hytale.codec.KeyedCodec;
import com.hypixel.hytale.codec.builder.BuilderCodec;
import com.hypixel.hytale.component.ComponentAccessor;
import com.hypixel.hytale.component.ComponentType;
import com.hypixel.hytale.component.Ref;
import com.hypixel.hytale.component.Store;
import com.hypixel.hytale.logger.HytaleLogger;
import com.hypixel.hytale.math.random.RandomExtra;
import com.hypixel.hytale.math.vector.Vector3d;
import com.hypixel.hytale.math.vector.Vector3f;
import com.hypixel.hytale.protocol.AnimationSlot;
import com.hypixel.hytale.protocol.BlockMaterial;
import com.hypixel.hytale.server.core.asset.type.entityeffect.config.ApplicationEffects;
import com.hypixel.hytale.server.core.asset.type.entityeffect.config.EntityEffect;
import com.hypixel.hytale.server.core.asset.type.environment.config.Environment;
import com.hypixel.hytale.server.core.asset.type.model.config.Model;
import com.hypixel.hytale.server.core.asset.type.model.config.ModelAsset;
import com.hypixel.hytale.server.core.entity.AnimationUtils;
import com.hypixel.hytale.server.core.entity.Entity;
import com.hypixel.hytale.server.core.entity.LivingEntity;
import com.hypixel.hytale.server.core.entity.effect.EffectControllerComponent;
import com.hypixel.hytale.server.core.entity.entities.Player;
import com.hypixel.hytale.server.core.inventory.Inventory;
import com.hypixel.hytale.server.core.modules.entity.EntityModule;
import com.hypixel.hytale.server.core.modules.entity.component.ActiveAnimationComponent;
import com.hypixel.hytale.server.core.modules.entity.component.ModelComponent;
import com.hypixel.hytale.server.core.universe.world.World;
import com.hypixel.hytale.server.core.universe.world.npc.INonPlayerCharacter;
import com.hypixel.hytale.server.core.universe.world.storage.EntityStore;
import com.hypixel.hytale.server.npc.NPCPlugin;
import com.hypixel.hytale.server.npc.blackboard.Blackboard;
import com.hypixel.hytale.server.npc.blackboard.view.blocktype.BlockTypeView;
import com.hypixel.hytale.server.npc.blackboard.view.event.EntityEventNotification;
import com.hypixel.hytale.server.npc.blackboard.view.event.EventNotification;
import com.hypixel.hytale.server.npc.blackboard.view.event.block.BlockEventType;
import com.hypixel.hytale.server.npc.blackboard.view.event.block.BlockEventView;
import com.hypixel.hytale.server.npc.blackboard.view.event.entity.EntityEventType;
import com.hypixel.hytale.server.npc.blackboard.view.event.entity.EntityEventView;
import com.hypixel.hytale.server.npc.components.messaging.EntityEventSupport;
import com.hypixel.hytale.server.npc.components.messaging.EventSupport;
import com.hypixel.hytale.server.npc.components.messaging.NPCBlockEventSupport;
import com.hypixel.hytale.server.npc.components.messaging.NPCEntityEventSupport;
import com.hypixel.hytale.server.npc.components.messaging.PlayerBlockEventSupport;
import com.hypixel.hytale.server.npc.components.messaging.PlayerEntityEventSupport;
import com.hypixel.hytale.server.npc.role.Role;
import com.hypixel.hytale.server.npc.role.RoleDebugFlags;
import com.hypixel.hytale.server.npc.storage.AlarmStore;
import com.hypixel.hytale.server.npc.util.DamageData;
import com.hypixel.hytale.server.spawning.assets.spawns.config.WorldNPCSpawn;
import it.unimi.dsi.fastutil.ints.IntList;
import it.unimi.dsi.fastutil.ints.IntSet;
import java.time.Instant;
import java.util.EnumMap;
import java.util.EnumSet;
import java.util.HashSet;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
import java.util.UUID;
import java.util.concurrent.TimeUnit;
import java.util.logging.Level;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
public class NPCEntity extends LivingEntity implements INonPlayerCharacter {
public static final BuilderCodec<NPCEntity> CODEC;
private String roleName;
private int roleIndex = -2147483648;
@Nullable
private Role role = null;
private int spawnRoleIndex = -2147483648;
@Nullable
private String spawnRoleName;
@Nullable
private String spawnConfigurationName;
private int environmentIndex = -2147483648;
private int spawnConfigurationIndex = -2147483648;
private boolean isSpawnTracked;
private boolean isDespawning;
private boolean isPlayingDespawnAnim;
private float despawnRemainingSeconds;
private float despawnCheckRemainingSeconds = RandomExtra.randomRange(1.0F, 5.0F);
private float despawnAnimationRemainingSeconds;
private float cachedEntityHorizontalSpeedMultiplier = 3.4028235E38F;
private final Vector3d leashPoint = new Vector3d();
private float leashHeading;
private float leashPitch;
private boolean hasLeashPosition;
private float hoverPhase;
private double hoverHeight;
private float initialModelScale = 1.0F;
private Instant spawnInstant;
@Nonnull
private PathManager pathManager = new PathManager();
private final DamageData damageData = new DamageData();
@Nullable
private BlockTypeView blackboardBlockTypeView;
private IntList blackboardBlockTypeSets;
private BlockEventView blackboardBlockChangeView;
private Map<BlockEventType, IntSet> blackboardBlockChangeSets;
private EntityEventView blackboardEntityEventView;
private Map<EntityEventType, IntSet> blackboardEntityEventSets;
private AlarmStore alarmStore;
@Deprecated(
forRemoval = true
)
private int worldgenId = 0;
@Nonnull
private final Set<UUID> reservedBy = new HashSet();
private final Vector3d oldPosition = new Vector3d();
@Nullable
public static ComponentType<EntityStore, NPCEntity> getComponentType() {
return EntityModule.get().getComponentType(NPCEntity.class);
}
public NPCEntity() {
}
public NPCEntity(@Nonnull World world) {
super(world);
}
@Nonnull
public AlarmStore getAlarmStore() {
if (this.alarmStore == null) {
this.alarmStore = new AlarmStore();
}
return this.alarmStore;
}
@Nonnull
protected Inventory createDefaultInventory() {
return new Inventory((short)0, Inventory.DEFAULT_ARMOR_CAPACITY, (short)3, (short)0, (short)0);
}
@Nullable
public Role getRole() {
return this.role;
}
public void invalidateCachedHorizontalSpeedMultiplier() {
this.cachedEntityHorizontalSpeedMultiplier = 3.4028235E38F;
}
public void storeTickStartPosition(@Nonnull Vector3d position) {
this.oldPosition.assign(position);
}
public boolean tickDespawnAnimationRemainingSeconds(float dt) {
return (this.despawnAnimationRemainingSeconds -= dt) <= 0.0F;
}
public void setDespawnAnimationRemainingSeconds(float seconds) {
this.despawnAnimationRemainingSeconds = seconds;
}
public boolean tickDespawnRemainingSeconds(float dt) {
return (this.despawnRemainingSeconds -= dt) <= 0.0F;
}
public void setDespawnRemainingSeconds(float seconds) {
this.despawnRemainingSeconds = seconds;
}
public void setDespawning(boolean despawning) {
this.isDespawning = despawning;
}
public void setPlayingDespawnAnim(boolean playingDespawnAnim) {
this.isPlayingDespawnAnim = playingDespawnAnim;
}
public boolean tickDespawnCheckRemainingSeconds(float dt) {
return (this.despawnCheckRemainingSeconds -= dt) <= 0.0F;
}
public void setDespawnCheckRemainingSeconds(float seconds) {
this.despawnCheckRemainingSeconds = seconds;
}
public void setInitialModelScale(float scale) {
this.initialModelScale = scale;
}
public Vector3d getOldPosition() {
return this.oldPosition;
}
public void playAnimation(@Nonnull Ref<EntityStore> ref, @Nonnull AnimationSlot animationSlot, @Nullable String animationId, @Nonnull ComponentAccessor<EntityStore> componentAccessor) {
Model model = null;
ModelComponent modelComponent = (ModelComponent)componentAccessor.getComponent(ref, ModelComponent.getComponentType());
if (modelComponent != null) {
model = modelComponent.getModel();
}
if (animationSlot != AnimationSlot.Action && animationId != null && model != null && !model.getAnimationSetMap().containsKey(animationId)) {
((HytaleLogger.Api)Entity.LOGGER.at(Level.WARNING).atMostEvery(1, TimeUnit.MINUTES)).log("Missing animation '%s' for Model '%s'", animationId, model.getModelAssetId());
} else {
ActiveAnimationComponent activeAnimationComponent = (ActiveAnimationComponent)componentAccessor.getComponent(ref, ActiveAnimationComponent.getComponentType());
if (activeAnimationComponent == null) {
((HytaleLogger.Api)Entity.LOGGER.at(Level.WARNING).atMostEvery(1, TimeUnit.MINUTES)).log("Missing active animation component for entity: %s", this.roleName);
} else {
String[] activeAnimations = activeAnimationComponent.getActiveAnimations();
if (animationSlot == AnimationSlot.Action || !Objects.equals(activeAnimations[animationSlot.ordinal()], animationId)) {
activeAnimations[animationSlot.ordinal()] = animationId;
activeAnimationComponent.setPlayingAnimation(animationSlot, animationId);
AnimationUtils.playAnimation(ref, animationSlot, animationId, componentAccessor);
}
}
}
}
public void clearDamageData() {
this.damageData.reset();
}
public void setToDespawn() {
this.isDespawning = true;
}
public void setDespawnTime(float time) {
if (this.isDespawning) {
this.despawnRemainingSeconds = time;
}
}
public double getDespawnTime() {
return (double)this.despawnRemainingSeconds;
}
public boolean canBreathe(@Nonnull Ref<EntityStore> ref, @Nonnull BlockMaterial breathingMaterial, int fluidId, @Nonnull ComponentAccessor<EntityStore> componentAccessor) {
return this.role.canBreathe(breathingMaterial, fluidId);
}
public DamageData getDamageData() {
return this.damageData;
}
public boolean getCanCauseDamage(@Nonnull Ref<EntityStore> attackerRef, @Nonnull ComponentAccessor<EntityStore> componentAccessor) {
return this.role.getCombatSupport().getCanCauseDamage(attackerRef, componentAccessor);
}
public void onFlockSetState(@Nonnull Ref<EntityStore> ref, @Nonnull String state, @Nullable String subState, @Nonnull ComponentAccessor<EntityStore> componentAccessor) {
this.role.getStateSupport().setState(ref, state, subState, componentAccessor);
}
public void onFlockSetTarget(@Nonnull String targetSlot, @Nonnull Ref<EntityStore> target) {
this.role.setMarkedTarget(targetSlot, target);
}
public void saveLeashInformation(@Nonnull Vector3d position, @Nonnull Vector3f rotation) {
this.leashPoint.assign(position);
this.leashHeading = rotation.getYaw();
this.leashPitch = rotation.getPitch();
this.saveLeashBlockType();
}
public void saveLeashBlockType() {
}
public boolean requiresLeashPosition() {
return this.role != null ? this.role.requiresLeashPosition() : this.hasLeashPosition;
}
public Vector3d getLeashPoint() {
return this.leashPoint;
}
public void setLeashPoint(@Nonnull Vector3d leashPoint) {
this.leashPoint.assign(leashPoint);
}
public float getLeashHeading() {
return this.leashHeading;
}
public void setLeashHeading(float leashHeading) {
this.leashHeading = leashHeading;
}
public float getLeashPitch() {
return this.leashPitch;
}
public void setLeashPitch(float leashPitch) {
this.leashPitch = leashPitch;
}
public float getHoverPhase() {
return this.hoverPhase;
}
public void setHoverPhase(float hoverPhase) {
this.hoverPhase = hoverPhase;
}
public double getHoverHeight() {
return this.hoverHeight;
}
public void setHoverHeight(double hoverHeight) {
this.hoverHeight = hoverHeight;
}
public String getRoleName() {
return this.roleName;
}
public void setRoleName(String roleName) {
this.roleName = roleName;
}
public int getRoleIndex() {
return this.roleIndex;
}
public void setRoleIndex(int roleIndex) {
this.roleIndex = roleIndex;
}
public void setRole(Role role) {
this.role = role;
}
public int getSpawnRoleIndex() {
return this.spawnRoleIndex != -2147483648 ? this.spawnRoleIndex : this.roleIndex;
}
public void setSpawnRoleIndex(int spawnRoleIndex) {
if (spawnRoleIndex == this.roleIndex) {
spawnRoleIndex = -2147483648;
}
this.spawnRoleIndex = spawnRoleIndex;
if (spawnRoleIndex == -2147483648) {
this.spawnRoleName = null;
} else {
this.spawnRoleName = NPCPlugin.get().getName(spawnRoleIndex);
}
}
@Nonnull
public BlockTypeView getBlockTypeBlackboardView(@Nonnull Ref<EntityStore> ref, @Nonnull Store<EntityStore> store) {
if (this.blackboardBlockTypeView == null) {
this.initBlockTypeBlackboardView(ref, store);
}
if (this.blackboardBlockTypeView.isOutdated(ref, store)) {
this.blackboardBlockTypeView = this.blackboardBlockTypeView.getUpdatedView(ref, store);
}
return this.blackboardBlockTypeView;
}
@Nullable
public BlockTypeView removeBlockTypeBlackboardView() {
BlockTypeView view = this.blackboardBlockTypeView;
this.blackboardBlockTypeView = null;
return view;
}
public void initBlockTypeBlackboardView(@Nonnull Ref<EntityStore> ref, ComponentAccessor<EntityStore> componentAccessor) {
if (this.blackboardBlockTypeSets != null) {
this.blackboardBlockTypeView = (BlockTypeView)((Blackboard)componentAccessor.getResource(Blackboard.getResourceType())).getView(BlockTypeView.class, ref, componentAccessor);
this.blackboardBlockTypeView.initialiseEntity(ref, this);
}
}
public void initBlockChangeBlackboardView(@Nonnull Ref<EntityStore> ref, ComponentAccessor<EntityStore> componentAccessor) {
if (this.blackboardBlockChangeSets != null) {
this.blackboardBlockChangeView = (BlockEventView)((Blackboard)componentAccessor.getResource(Blackboard.getResourceType())).getView(BlockEventView.class, ref, componentAccessor);
this.blackboardBlockChangeView.initialiseEntity(ref, this);
}
if (this.blackboardEntityEventSets != null) {
this.blackboardEntityEventView = (EntityEventView)((Blackboard)componentAccessor.getResource(Blackboard.getResourceType())).getView(EntityEventView.class, ref, componentAccessor);
this.blackboardEntityEventView.initialiseEntity(ref, this);
}
}
public void addBlackboardBlockTypeSets(IntList blackboardBlockSets) {
this.blackboardBlockTypeSets = blackboardBlockSets;
}
public IntList getBlackboardBlockTypeSets() {
return this.blackboardBlockTypeSets;
}
public void addBlackboardBlockChangeSets(@Nonnull BlockEventType type, @Nonnull IntSet sets) {
if (this.blackboardBlockChangeSets == null) {
this.blackboardBlockChangeSets = new EnumMap(BlockEventType.class);
}
this.blackboardBlockChangeSets.put(type, sets);
}
public IntSet getBlackboardBlockChangeSet(BlockEventType type) {
return (IntSet)this.blackboardBlockChangeSets.getOrDefault(type, (Object)null);
}
public Map<BlockEventType, IntSet> getBlackboardBlockChangeSets() {
return this.blackboardBlockChangeSets;
}
public void notifyBlockChange(@Nonnull BlockEventType type, @Nonnull EventNotification notification) {
Store<EntityStore> store = this.world.getEntityStore().getStore();
Ref<EntityStore> initiator = notification.getInitiator();
boolean isPlayer = store.getArchetype(initiator).contains(Player.getComponentType());
EventSupport<BlockEventType, EventNotification> support;
if (isPlayer) {
support = (EventSupport)store.getComponent(this.reference, PlayerBlockEventSupport.getComponentType());
} else {
support = (EventSupport)store.getComponent(this.reference, NPCBlockEventSupport.getComponentType());
}
if (support != null) {
support.postMessage(type, notification, this.getReference(), store);
}
}
public void addBlackboardEntityEventSets(@Nonnull EntityEventType type, @Nonnull IntSet sets) {
if (this.blackboardEntityEventSets == null) {
this.blackboardEntityEventSets = new EnumMap(EntityEventType.class);
}
this.blackboardEntityEventSets.put(type, sets);
}
public IntSet getBlackboardEntityEventSet(@Nonnull EntityEventType type) {
return (IntSet)this.blackboardEntityEventSets.getOrDefault(type, (Object)null);
}
public Map<EntityEventType, IntSet> getBlackboardEntityEventSets() {
return this.blackboardEntityEventSets;
}
public void notifyEntityEvent(@Nonnull EntityEventType type, @Nonnull EntityEventNotification notification) {
Store<EntityStore> store = this.world.getEntityStore().getStore();
Ref<EntityStore> initiator = notification.getInitiator();
boolean isPlayer = store.getArchetype(initiator).contains(Player.getComponentType());
EntityEventSupport support;
if (isPlayer) {
support = (EntityEventSupport)store.getComponent(this.reference, PlayerEntityEventSupport.getComponentType());
} else {
support = (EntityEventSupport)store.getComponent(this.reference, NPCEntityEventSupport.getComponentType());
}
if (support != null) {
support.postMessage(type, notification, this.reference, store);
}
}
public void setEnvironment(int env) {
this.environmentIndex = env;
}
public int getEnvironment() {
return this.environmentIndex;
}
public int getSpawnConfiguration() {
return this.spawnConfigurationIndex;
}
public void setSpawnConfiguration(int spawnConfigurationIndex) {
if (spawnConfigurationIndex == -2147483648) {
this.spawnConfigurationIndex = -2147483648;
this.spawnConfigurationName = null;
} else {
String name = ((WorldNPCSpawn)WorldNPCSpawn.getAssetMap().getAsset(spawnConfigurationIndex)).getId();
if (name == null) {
throw new IllegalArgumentException("setSpawnConfiguration: Cannot find spawn configuration name for index: " + spawnConfigurationIndex);
} else {
this.spawnConfigurationIndex = spawnConfigurationIndex;
this.spawnConfigurationName = name;
}
}
}
public boolean updateSpawnTrackingState(boolean newState) {
boolean oldState = this.isSpawnTracked;
this.isSpawnTracked = newState;
return oldState;
}
public boolean isDespawning() {
return this.isDespawning;
}
public boolean isPlayingDespawnAnim() {
return this.isPlayingDespawnAnim;
}
public EnumSet<RoleDebugFlags> getRoleDebugFlags() {
return this.role.getDebugSupport().getDebugFlags();
}
public void setRoleDebugFlags(@Nonnull EnumSet<RoleDebugFlags> flags) {
this.role.getDebugSupport().setDebugFlags(flags);
}
public void setSpawnInstant(@Nonnull Instant spawned) {
this.spawnInstant = spawned;
}
public Instant getSpawnInstant() {
return this.spawnInstant;
}
public void setInventorySize(int hotbarCapacity, int inventoryCapacity, int offHandCapacity) {
this.setInventory(new Inventory((short)inventoryCapacity, Inventory.DEFAULT_ARMOR_CAPACITY, (short)hotbarCapacity, (short)offHandCapacity, (short)0));
}
@Deprecated(
forRemoval = true
)
public int getLegacyWorldgenId() {
return this.worldgenId;
}
@Nonnull
public PathManager getPathManager() {
return this.pathManager;
}
public static boolean setAppearance(@Nonnull Ref<EntityStore> ref, @Nonnull String name, @Nonnull ComponentAccessor<EntityStore> componentAccessor) {
if (name.isEmpty()) {
throw new IllegalArgumentException("Appearance can't be changed to empty");
} else {
ModelComponent modelComponent = (ModelComponent)componentAccessor.getComponent(ref, ModelComponent.getComponentType());
if (modelComponent == null) {
return false;
} else {
Model model = modelComponent.getModel();
if (name.equals(model.getModelAssetId())) {
return true;
} else {
NPCEntity npcComponent = (NPCEntity)componentAccessor.getComponent(ref, getComponentType());
assert npcComponent != null;
ModelAsset modelAsset = (ModelAsset)ModelAsset.getAssetMap().getAsset(name);
if (modelAsset == null) {
NPCPlugin.get().getLogger().at(Level.SEVERE).log("Role '%s': Cannot find model '%s'", npcComponent.roleName, name);
return false;
} else {
npcComponent.setAppearance(ref, modelAsset, componentAccessor);
return true;
}
}
}
}
}
public void setAppearance(@Nonnull Ref<EntityStore> ref, @Nonnull ModelAsset modelAsset, @Nonnull ComponentAccessor<EntityStore> componentAccessor) {
Model model = Model.createScaledModel(modelAsset, this.initialModelScale);
componentAccessor.putComponent(ref, ModelComponent.getComponentType(), new ModelComponent(model));
this.role.updateMotionControllers(ref, model, model.getBoundingBox(), componentAccessor);
}
public float getCurrentHorizontalSpeedMultiplier(@Nullable Ref<EntityStore> ref, @Nullable ComponentAccessor<EntityStore> componentAccessor) {
if (this.cachedEntityHorizontalSpeedMultiplier != 3.4028235E38F) {
return this.cachedEntityHorizontalSpeedMultiplier;
} else {
this.cachedEntityHorizontalSpeedMultiplier = 1.0F;
if (ref != null && componentAccessor != null) {
EffectControllerComponent effectControllerComponent = (EffectControllerComponent)componentAccessor.getComponent(ref, EffectControllerComponent.getComponentType());
if (effectControllerComponent == null) {
return this.cachedEntityHorizontalSpeedMultiplier;
} else {
int[] cachedEffectIndexes = effectControllerComponent.getActiveEffectIndexes();
if (cachedEffectIndexes == null) {
return this.cachedEntityHorizontalSpeedMultiplier;
} else {
for(int cachedEffectIndex : cachedEffectIndexes) {
EntityEffect effect = (EntityEffect)EntityEffect.getAssetMap().getAsset(cachedEffectIndex);
if (effect != null) {
ApplicationEffects applicationEffects = effect.getApplicationEffects();
if (applicationEffects != null) {
float multiplier = applicationEffects.getHorizontalSpeedMultiplier();
if (multiplier >= 0.0F) {
this.cachedEntityHorizontalSpeedMultiplier *= multiplier;
}
}
}
}
return this.cachedEntityHorizontalSpeedMultiplier;
}
}
} else {
return this.cachedEntityHorizontalSpeedMultiplier;
}
}
}
@Nonnull
public String toString() {
String var10000 = String.valueOf(this.role);
return "NPCEntity{role=" + var10000 + ", spawnRoleIndex=" + this.spawnRoleIndex + ", spawnPoint=" + String.valueOf(this.leashPoint) + ", spawnHeading=" + this.leashHeading + ", spawnPitch=" + this.leashPitch + ", environmentIndex='" + this.environmentIndex + "'} " + super.toString();
}
public String getNPCTypeId() {
return this.roleName;
}
public int getNPCTypeIndex() {
return this.roleIndex;
}
public void addReservation(@Nonnull UUID playerUUID) {
this.reservedBy.add(playerUUID);
}
public void removeReservation(@Nonnull UUID playerUUID) {
this.reservedBy.remove(playerUUID);
}
public boolean isReserved() {
return !this.reservedBy.isEmpty();
}
public boolean isReservedBy(@Nonnull UUID playerUUID) {
return this.reservedBy.contains(playerUUID);
}
static {
CODEC = ((BuilderCodec.Builder)((BuilderCodec.Builder)((BuilderCodec.Builder)((BuilderCodec.Builder)((BuilderCodec.Builder)((BuilderCodec.Builder)((BuilderCodec.Builder)((BuilderCodec.Builder)((BuilderCodec.Builder)((BuilderCodec.Builder)((BuilderCodec.Builder)((BuilderCodec.Builder)((BuilderCodec.Builder)((BuilderCodec.Builder)BuilderCodec.builder(NPCEntity.class, NPCEntity::new, LivingEntity.CODEC).addField(new KeyedCodec("Env", Codec.STRING), (npcEntity, s) -> npcEntity.environmentIndex = Environment.getAssetMap().getIndex(s), (npcEntity) -> {
Environment environment = (Environment)Environment.getAssetMap().getAssetOrDefault(npcEntity.environmentIndex, (JsonAssetWithMap)null);
return environment != null ? environment.getId() : null;
})).addField(new KeyedCodec("HvrPhs", Codec.DOUBLE), (npcEntity, d) -> npcEntity.hoverPhase = d.floatValue(), (npcEntity) -> (double)npcEntity.hoverPhase)).addField(new KeyedCodec("HvrHght", Codec.DOUBLE), (npcEntity, d) -> npcEntity.hoverHeight = d, (npcEntity) -> npcEntity.hoverHeight)).addField(new KeyedCodec("SpawnName", Codec.STRING), (npcEntity, s) -> {
npcEntity.spawnRoleName = s;
npcEntity.spawnRoleIndex = NPCPlugin.get().getIndex(s);
}, (npcEntity) -> npcEntity.spawnRoleName)).addField(new KeyedCodec("MdlScl", Codec.DOUBLE), (npcEntity, d) -> npcEntity.initialModelScale = d.floatValue(), (npcEntity) -> (double)npcEntity.initialModelScale)).addField(new KeyedCodec("SpawnConfig", Codec.STRING), (npcEntity, s) -> {
npcEntity.spawnConfigurationName = s;
npcEntity.spawnConfigurationIndex = WorldNPCSpawn.getAssetMap().getIndex(s);
}, (npcEntity) -> npcEntity.spawnConfigurationName)).addField(new KeyedCodec("SpawnInstant", Codec.INSTANT), (npcEntity, instant) -> npcEntity.spawnInstant = instant, (npcEntity) -> npcEntity.spawnInstant)).append(new KeyedCodec("AlarmStore", AlarmStore.CODEC), (npcEntity, alarmStore) -> npcEntity.alarmStore = alarmStore, (npcEntity) -> npcEntity.alarmStore).add()).addField(new KeyedCodec("WorldgenId", Codec.INTEGER), (npcEntity, i) -> npcEntity.worldgenId = i, (npcEntity) -> npcEntity.worldgenId)).append(new KeyedCodec("PathManager", PathManager.CODEC), (npcEntity, manager) -> npcEntity.pathManager = manager, (npcEntity) -> npcEntity.pathManager).add()).addField(new KeyedCodec("LeashPos", Vector3d.CODEC), (npcEntity, v) -> {
npcEntity.leashPoint.assign(v);
npcEntity.hasLeashPosition = true;
}, (npcEntity) -> npcEntity.requiresLeashPosition() ? npcEntity.leashPoint : null)).addField(new KeyedCodec("LeashHdg", Codec.DOUBLE), (npcEntity, v) -> npcEntity.leashHeading = v.floatValue(), (npcEntity) -> npcEntity.requiresLeashPosition() ? (double)npcEntity.leashHeading : null)).addField(new KeyedCodec("LeashPtch", Codec.DOUBLE), (npcEntity, v) -> npcEntity.leashPitch = v.floatValue(), (npcEntity) -> npcEntity.requiresLeashPosition() ? (double)npcEntity.leashPitch : null)).addField(new KeyedCodec("RoleName", Codec.STRING), (npcEntity, s) -> npcEntity.roleName = s, (npcEntity) -> npcEntity.roleName)).build();
}
}