diff --git a/src/api b/src/api index 3cfe8be05..e13c6762f 160000 --- a/src/api +++ b/src/api @@ -1 +1 @@ -Subproject commit 3cfe8be0562243595015c76cbbcff6fc15a73cfb +Subproject commit e13c6762f39d5f48c7f2333fc203765f876dbfa3 diff --git a/src/main/java/noppes/npcs/entity/EntityNPCInterface.java b/src/main/java/noppes/npcs/entity/EntityNPCInterface.java index f7fb6ef40..c50a62125 100644 --- a/src/main/java/noppes/npcs/entity/EntityNPCInterface.java +++ b/src/main/java/noppes/npcs/entity/EntityNPCInterface.java @@ -74,6 +74,7 @@ import noppes.npcs.controllers.data.*; import noppes.npcs.entity.data.DataTimers; import noppes.npcs.roles.*; import noppes.npcs.scripted.NpcAPI; +import noppes.npcs.scripted.ScriptedActionManager; import noppes.npcs.scripted.entity.ScriptNpc; import noppes.npcs.scripted.event.NpcEvent; import noppes.npcs.util.GameProfileAlt; @@ -82,611 +83,602 @@ import java.io.IOException; import java.util.*; public abstract class EntityNPCInterface extends EntityCreature implements IEntityAdditionalSpawnData, ICommandSender, IRangedAttackMob, IBossDisplayData { - public ICustomNpc wrappedNPC; + public ICustomNpc wrappedNPC; - public static final GameProfileAlt chateventProfile = new GameProfileAlt(); - public static FakePlayer chateventPlayer; - public DataDisplay display; - public DataStats stats; - public DataAI ais; - public DataAdvanced advanced; - public DataInventory inventory; - public DataScript script; - public DataTransform transform; - public DataTimers timers; + public static final GameProfileAlt chateventProfile = new GameProfileAlt(); + public static FakePlayer chateventPlayer; + public DataDisplay display; + public DataStats stats; + public DataAI ais; + public DataAdvanced advanced; + public DataInventory inventory; + public DataScript script; + public DataTransform transform; + public DataTimers timers; - public CombatHandler combatHandler = new CombatHandler(this); + public CombatHandler combatHandler = new CombatHandler(this); + public ScriptedActionManager actionManager = new ScriptedActionManager(); - public String linkedName = ""; - public long linkedLast = 0; - public LinkedData linkedData; + public String linkedName = ""; + public long linkedLast = 0; + public LinkedData linkedData; - public float baseHeight = 1.8f; - public float scaleX, scaleY, scaleZ; - private boolean wasKilled = false; - public RoleInterface roleInterface; - public JobInterface jobInterface; - public HashMap dialogs; - public boolean hasDied = false; - public long killedtime = 0; - public long totalTicksAlive = 0; - private int taskCount = 1; - public int lastInteract = 0; + public float baseHeight = 1.8f; + public float scaleX, scaleY, scaleZ; + private boolean wasKilled = false; + public RoleInterface roleInterface; + public JobInterface jobInterface; + public HashMap dialogs; + public boolean hasDied = false; + public long killedtime = 0; + public long totalTicksAlive = 0; + private int taskCount = 1; + public int lastInteract = 0; public boolean isDrawn = false; - public Faction faction; //should only be used server side + public Faction faction; //should only be used server side - private EntityAIRangedAttack aiRange; - private EntityAIBase aiResponse, aiLeap, aiSprint, aiAttackTarget; + private EntityAIRangedAttack aiRange; + private EntityAIBase aiResponse, aiLeap, aiSprint, aiAttackTarget; - public List interactingEntities = new ArrayList(); + public List interactingEntities = new ArrayList(); - public ResourceLocation textureLocation = null; + public ResourceLocation textureLocation = null; - public EnumAnimation currentAnimation = EnumAnimation.NONE; + public EnumAnimation currentAnimation = EnumAnimation.NONE; - public int npcVersion = VersionCompatibility.ModRev; - public IChatMessages messages; + public int npcVersion = VersionCompatibility.ModRev; + public IChatMessages messages; - public boolean updateClient = false; - public boolean updateAI = false; + public boolean updateClient = false; + public boolean updateAI = false; - public FlyingMoveHelper flyMoveHelper = new FlyingMoveHelper(this); - public PathNavigate flyNavigator = new PathNavigateFlying(this, worldObj); + public FlyingMoveHelper flyMoveHelper = new FlyingMoveHelper(this); + public PathNavigate flyNavigator = new PathNavigateFlying(this, worldObj); - public EntityNPCInterface(World world) { - super(world); - try{ - if (canFly()) { - this.getNavigator().setCanSwim(true); - this.tasks.addTask(0, new EntityAISwimming(this)); - } else { - this.tasks.addTask(0, new EntityAIWaterNav(this)); - } + public EntityNPCInterface(World world) { + super(world); + try { + if (canFly()) { + this.getNavigator().setCanSwim(true); + this.tasks.addTask(0, new EntityAISwimming(this)); + } else { + this.tasks.addTask(0, new EntityAIWaterNav(this)); + } - dialogs = new HashMap(); - if(!ConfigMain.DefaultInteractLine.isEmpty()) - advanced.interactLines.lines.put(0, new Line(ConfigMain.DefaultInteractLine)); + dialogs = new HashMap(); + if (!ConfigMain.DefaultInteractLine.isEmpty()) + advanced.interactLines.lines.put(0, new Line(ConfigMain.DefaultInteractLine)); - experienceValue = 0; - scaleX = scaleY = scaleZ = 0.9375f; + experienceValue = 0; + scaleX = scaleY = scaleZ = 0.9375f; - faction = getFaction(); - setFaction(faction.id); - setSize(1, 1); - this.updateTasks(); - this.func_110163_bv(); + faction = getFaction(); + setFaction(faction.id); + setSize(1, 1); + this.updateTasks(); + this.func_110163_bv(); - if (!this.isRemote() && this.wrappedNPC == null) { - this.wrappedNPC = new ScriptNpc<>(this); - } - } - catch(Exception e){ - e.printStackTrace(); - } - } + if (!this.isRemote() && this.wrappedNPC == null) { + this.wrappedNPC = new ScriptNpc<>(this); + } + } catch (Exception e) { + e.printStackTrace(); + } + } - @Override - protected void applyEntityAttributes(){ - super.applyEntityAttributes(); + @Override + protected void applyEntityAttributes() { + super.applyEntityAttributes(); - display = new DataDisplay(this); - stats = new DataStats(this); - ais = new DataAI(this); - advanced = new DataAdvanced(this); - inventory = new DataInventory(this); - transform = new DataTransform(this); - script = new DataScript(this); - timers = new DataTimers(this); - this.getAttributeMap().registerAttribute(SharedMonsterAttributes.attackDamage); + display = new DataDisplay(this); + stats = new DataStats(this); + ais = new DataAI(this); + advanced = new DataAdvanced(this); + inventory = new DataInventory(this); + transform = new DataTransform(this); + script = new DataScript(this); + timers = new DataTimers(this); + this.getAttributeMap().registerAttribute(SharedMonsterAttributes.attackDamage); - this.getEntityAttribute(SharedMonsterAttributes.maxHealth).setBaseValue(stats.maxHealth); - this.getEntityAttribute(SharedMonsterAttributes.followRange).setBaseValue(ConfigMain.NpcNavRange); - this.getEntityAttribute(SharedMonsterAttributes.movementSpeed).setBaseValue(this.getSpeed()); - this.getEntityAttribute(SharedMonsterAttributes.attackDamage).setBaseValue(stats.getAttackStrength()); - } + this.getEntityAttribute(SharedMonsterAttributes.maxHealth).setBaseValue(stats.maxHealth); + this.getEntityAttribute(SharedMonsterAttributes.followRange).setBaseValue(ConfigMain.NpcNavRange); + this.getEntityAttribute(SharedMonsterAttributes.movementSpeed).setBaseValue(this.getSpeed()); + this.getEntityAttribute(SharedMonsterAttributes.attackDamage).setBaseValue(stats.getAttackStrength()); + } - @Override - protected void entityInit() { - super.entityInit(); - this.dataWatcher.addObject(13, String.valueOf(""));//faction - this.dataWatcher.addObject(14, Integer.valueOf(0)); // Animation - this.dataWatcher.addObject(15, Integer.valueOf(0)); // isWalking - this.dataWatcher.addObject(16, String.valueOf("")); // Role - } - protected boolean isAIEnabled(){ - return true; - } + @Override + protected void entityInit() { + super.entityInit(); + this.dataWatcher.addObject(13, String.valueOf(""));//faction + this.dataWatcher.addObject(14, Integer.valueOf(0)); // Animation + this.dataWatcher.addObject(15, Integer.valueOf(0)); // isWalking + this.dataWatcher.addObject(16, String.valueOf("")); // Role + } - @Override - public boolean getLeashed(){ - return false; //Prevents npcs from being leashed - } + protected boolean isAIEnabled() { + return true; + } - @Override - public boolean isEntityAlive(){ - return super.isEntityAlive() && !isKilled(); - } + @Override + public boolean getLeashed() { + return false; //Prevents npcs from being leashed + } - @Override - public void onUpdate(){ - super.onUpdate(); - if (!isRemote()) { - if (this.ticksExisted % 10 == 0) { - EventHooks.onNPCUpdate(this); - } - for(int i=1;i<3;i++){ - ItemStack itemstack = inventory.prevWeapons.get(i); - ItemStack itemstack1 = inventory.weapons.get(i); - if (!ItemStack.areItemStacksEqual(itemstack1, itemstack)) - { - NBTTagCompound itemNBT = new NBTTagCompound(); - if(itemstack1!=null){ - itemstack1.writeToNBT(itemNBT); - } + @Override + public boolean isEntityAlive() { + return super.isEntityAlive() && !isKilled(); + } + + @Override + public void onUpdate() { + super.onUpdate(); + if (!isRemote()) { + if (this.ticksExisted % 10 == 0) { + EventHooks.onNPCUpdate(this); + } + for (int i = 1; i < 3; i++) { + ItemStack itemstack = inventory.prevWeapons.get(i); + ItemStack itemstack1 = inventory.weapons.get(i); + if (!ItemStack.areItemStacksEqual(itemstack1, itemstack)) { + NBTTagCompound itemNBT = new NBTTagCompound(); + if (itemstack1 != null) { + itemstack1.writeToNBT(itemNBT); + } PacketHandler.Instance.sendTracking(new WeaponNpcPacket(getEntityId(), i, itemNBT), this); - inventory.prevWeapons.put(i,itemstack1 == null ? null : itemstack1.copy()); - } - } - this.timers.update(); - } - } - - public void setWorld(World world){ - super.setWorld(world); - script.setWorld(world); - } - - public int getMaxSafePointTries() - { - return 3; - } - - @Override - public boolean attackEntityAsMob(Entity receiver){ - float f = stats.getAttackStrength(); - - if (stats.attackSpeed < 10){ - receiver.hurtResistantTime = 0; - } - if(receiver instanceof EntityLivingBase && !isRemote()){ - NpcEvent.MeleeAttackEvent event = new NpcEvent.MeleeAttackEvent(wrappedNPC, f, (EntityLivingBase)receiver); - if(EventHooks.onNPCMeleeAttack(this, event)) - return false; - f = event.getDamage(); - } - - boolean didAttack = false; - if(DBCAddon.instance.canDBCAttack(this, f, receiver)){ - didAttack = receiver.attackEntityFrom(new NpcDamageSource("mob", this), 0.001f); - if(didAttack) - DBCAddon.instance.doDBCDamage(this, f, receiver); + inventory.prevWeapons.put(i, itemstack1 == null ? null : itemstack1.copy()); + } + } + this.timers.update(); } - else + } + + public void setWorld(World world) { + super.setWorld(world); + script.setWorld(world); + } + + public int getMaxSafePointTries() { + return 3; + } + + @Override + public boolean attackEntityAsMob(Entity receiver) { + float f = stats.getAttackStrength(); + + if (stats.attackSpeed < 10) { + receiver.hurtResistantTime = 0; + } + if (receiver instanceof EntityLivingBase && !isRemote()) { + NpcEvent.MeleeAttackEvent event = new NpcEvent.MeleeAttackEvent(wrappedNPC, f, (EntityLivingBase) receiver); + if (EventHooks.onNPCMeleeAttack(this, event)) + return false; + f = event.getDamage(); + } + + boolean didAttack = false; + if (DBCAddon.instance.canDBCAttack(this, f, receiver)) { + didAttack = receiver.attackEntityFrom(new NpcDamageSource("mob", this), 0.001f); + if (didAttack) + DBCAddon.instance.doDBCDamage(this, f, receiver); + } else didAttack = receiver.attackEntityFrom(new NpcDamageSource("mob", this), f); - if (didAttack){ - if(getOwner() instanceof EntityPlayer) - NPCEntityHelper.setRecentlyHit((EntityLivingBase)receiver); - if (stats.knockback > 0){ - receiver.addVelocity((double)(-MathHelper.sin(this.rotationYaw * (float)Math.PI / 180.0F) * (float)stats.knockback * 0.5F), 0.1D, (double)(MathHelper.cos(this.rotationYaw * (float)Math.PI / 180.0F) * (float)stats.knockback * 0.5F)); - this.motionX *= 0.6D; - this.motionZ *= 0.6D; - } - if(advanced.role == EnumRoleType.Companion){ - ((RoleCompanion)roleInterface).attackedEntity(receiver); - } - } + if (didAttack) { + if (getOwner() instanceof EntityPlayer) + NPCEntityHelper.setRecentlyHit((EntityLivingBase) receiver); + if (stats.knockback > 0) { + receiver.addVelocity((double) (-MathHelper.sin(this.rotationYaw * (float) Math.PI / 180.0F) * (float) stats.knockback * 0.5F), 0.1D, (double) (MathHelper.cos(this.rotationYaw * (float) Math.PI / 180.0F) * (float) stats.knockback * 0.5F)); + this.motionX *= 0.6D; + this.motionZ *= 0.6D; + } + if (advanced.role == EnumRoleType.Companion) { + ((RoleCompanion) roleInterface).attackedEntity(receiver); + } + } - if (stats.potionType != EnumPotionType.None){ - if (stats.potionType != EnumPotionType.Fire) - ((EntityLivingBase)receiver).addPotionEffect(new PotionEffect(this.getPotionEffect(stats.potionType), stats.potionDuration * 20, stats.potionAmp)); - else - receiver.setFire(stats.potionDuration); - } - return didAttack; - } + if (stats.potionType != EnumPotionType.None) { + if (stats.potionType != EnumPotionType.Fire) + ((EntityLivingBase) receiver).addPotionEffect(new PotionEffect(this.getPotionEffect(stats.potionType), stats.potionDuration * 20, stats.potionAmp)); + else + receiver.setFire(stats.potionDuration); + } + return didAttack; + } - @Override - public void swingItem() - { - ItemStack stack = this.getHeldItem(); - if (stack != null && stack.getItem() != null) - { - Item item = stack.getItem(); - if (item.onEntitySwing(this, stack)) - { - return; - } - } - if (!this.isSwingInProgress || this.swingProgressInt >= this.getArmSwingAnimationEnd() / 2 || this.swingProgressInt < 0) - { - this.swingProgressInt = -1; - this.isSwingInProgress = true; + @Override + public void swingItem() { + ItemStack stack = this.getHeldItem(); + if (stack != null && stack.getItem() != null) { + Item item = stack.getItem(); + if (item.onEntitySwing(this, stack)) { + return; + } + } + if (!this.isSwingInProgress || this.swingProgressInt >= this.getArmSwingAnimationEnd() / 2 || this.swingProgressInt < 0) { + this.swingProgressInt = -1; + this.isSwingInProgress = true; - if (this.worldObj instanceof WorldServer) - { - if(!isRemote()){ + if (this.worldObj instanceof WorldServer) { + if (!isRemote()) { NpcEvent.SwingEvent event = new NpcEvent.SwingEvent(wrappedNPC, stack); - if(EventHooks.onNPCMeleeSwing(this, event)) + if (EventHooks.onNPCMeleeSwing(this, event)) return; } - ((WorldServer)this.worldObj).getEntityTracker().func_151247_a(this, new S0BPacketAnimation(this, 0)); - } - } - } + ((WorldServer) this.worldObj).getEntityTracker().func_151247_a(this, new S0BPacketAnimation(this, 0)); + } + } + } - @Override - public void onLivingUpdate(){ - if(CustomNpcs.FreezeNPCs) - return; - totalTicksAlive++; - this.updateArmSwingProgress(); - if(this.ticksExisted % 20 == 0) - faction = getFaction(); - if(!worldObj.isRemote){ - if(!isKilled() && this.ticksExisted % 20 == 0){ - if(this.getHealth() < this.getMaxHealth()){ - if(stats.healthRegen > 0 && !isAttacking()) - heal(stats.healthRegen); - if(stats.combatRegen > 0 && isAttacking()) - heal(stats.combatRegen); - } - if(faction.getsAttacked && !isAttacking()){ - List list = this.worldObj.getEntitiesWithinAABB(EntityMob.class, this.boundingBox.expand(16, 16, 16)); - for(EntityMob mob : list){ - if(mob.getAttackTarget() == null && this.canSee(mob)){ - if(mob instanceof EntityZombie && !mob.getEntityData().hasKey("AttackNpcs")){ - mob.tasks.addTask(2, new EntityAIAttackOnCollide(mob, EntityLivingBase.class, 1.0D, false)); - mob.getEntityData().setBoolean("AttackNpcs", true); - } - mob.setAttackTarget(this); - } - } - } - if(linkedData != null && linkedData.time > linkedLast){ - LinkedNpcController.Instance.loadNpcData(this); - } - if(updateClient){ - this.updateClient(); - } - if(updateAI){ - updateTasks(); - updateAI = false; - } - } - if(getHealth() <= 0){ - clearActivePotions(); - setBoolFlag(true, 8); - updateTasks(); - updateHitbox(); - } - setBoolFlag(!getNavigator().noPath(), 1); - setBoolFlag(isInteracting(), 2); - combatHandler.update(); - onCollide(); - } + @Override + public void onLivingUpdate() { + if (CustomNpcs.FreezeNPCs) + return; + totalTicksAlive++; + this.updateArmSwingProgress(); + if (this.ticksExisted % 20 == 0) + faction = getFaction(); + if (!worldObj.isRemote) { + if (!isKilled() && this.ticksExisted % 20 == 0) { + if (this.getHealth() < this.getMaxHealth()) { + if (stats.healthRegen > 0 && !isAttacking()) + heal(stats.healthRegen); + if (stats.combatRegen > 0 && isAttacking()) + heal(stats.combatRegen); + } + if (faction.getsAttacked && !isAttacking()) { + List list = this.worldObj.getEntitiesWithinAABB(EntityMob.class, this.boundingBox.expand(16, 16, 16)); + for (EntityMob mob : list) { + if (mob.getAttackTarget() == null && this.canSee(mob)) { + if (mob instanceof EntityZombie && !mob.getEntityData().hasKey("AttackNpcs")) { + mob.tasks.addTask(2, new EntityAIAttackOnCollide(mob, EntityLivingBase.class, 1.0D, false)); + mob.getEntityData().setBoolean("AttackNpcs", true); + } + mob.setAttackTarget(this); + } + } + } + if (linkedData != null && linkedData.time > linkedLast) { + LinkedNpcController.Instance.loadNpcData(this); + } + if (updateClient) { + this.updateClient(); + } + if (updateAI) { + updateTasks(); + updateAI = false; + } + } + if (getHealth() <= 0) { + clearActivePotions(); + setBoolFlag(true, 8); + updateTasks(); + updateHitbox(); + } + setBoolFlag(!getNavigator().noPath(), 1); + setBoolFlag(isInteracting(), 2); + combatHandler.update(); + onCollide(); - if(wasKilled != isKilled() && wasKilled){ - reset(); - } + actionManager.tick(ticksExisted); + } - wasKilled = isKilled(); + if (wasKilled != isKilled() && wasKilled) { + reset(); + } - if (this.worldObj.isDaytime() && !this.worldObj.isRemote && this.stats.burnInSun){ - float f = this.getBrightness(1.0F); + wasKilled = isKilled(); - if (f > 0.5F && this.rand.nextFloat() * 30.0F < (f - 0.4F) * 2.0F && this.worldObj.canBlockSeeTheSky(MathHelper.floor_double(this.posX), MathHelper.floor_double(this.posY), MathHelper.floor_double(this.posZ))){ - this.setFire(8); - } - } + if (this.worldObj.isDaytime() && !this.worldObj.isRemote && this.stats.burnInSun) { + float f = this.getBrightness(1.0F); - super.onLivingUpdate(); + if (f > 0.5F && this.rand.nextFloat() * 30.0F < (f - 0.4F) * 2.0F && this.worldObj.canBlockSeeTheSky(MathHelper.floor_double(this.posX), MathHelper.floor_double(this.posY), MathHelper.floor_double(this.posZ))) { + this.setFire(8); + } + } - if (worldObj.isRemote){ - if(roleInterface != null){ - roleInterface.clientUpdate(); - } + super.onLivingUpdate(); - if(!display.cloakTexture.isEmpty()) - cloakUpdate(); - if(currentAnimation.ordinal() != dataWatcher.getWatchableObjectInt(14)){ - currentAnimation = EnumAnimation.values()[dataWatcher.getWatchableObjectInt(14)]; - updateHitbox(); - } - if(advanced.job == EnumJobType.Bard) - ((JobBard)jobInterface).onLivingUpdate(); + if (worldObj.isRemote) { + if (roleInterface != null) { + roleInterface.clientUpdate(); + } + + if (!display.cloakTexture.isEmpty()) + cloakUpdate(); + if (currentAnimation.ordinal() != dataWatcher.getWatchableObjectInt(14)) { + currentAnimation = EnumAnimation.values()[dataWatcher.getWatchableObjectInt(14)]; + updateHitbox(); + } + if (advanced.job == EnumJobType.Bard) + ((JobBard) jobInterface).onLivingUpdate(); DBCClient.Instance.renderDBCAuras(this); - } - } + } + } - @Override - protected void damageEntity(DamageSource damageSrc, float damageAmount){ - super.damageEntity(damageSrc, damageAmount); - combatHandler.damage(damageSrc, damageAmount); - } + @Override + protected void damageEntity(DamageSource damageSrc, float damageAmount) { + super.damageEntity(damageSrc, damageAmount); + combatHandler.damage(damageSrc, damageAmount); + } - public void updateClient() { - NBTTagCompound compound = writeSpawnData(); - compound.setInteger("EntityId", getEntityId()); + public void updateClient() { + NBTTagCompound compound = writeSpawnData(); + compound.setInteger("EntityId", getEntityId()); PacketHandler.Instance.sendTracking(new UpdateNpcPacket(compound), this); updateClient = false; - } + } - @Override - public boolean interact(EntityPlayer player) { - if(worldObj.isRemote) - return false; - ItemStack currentItem = player.inventory.getCurrentItem(); - if (currentItem != null) { - Item item = currentItem.getItem(); - if (item == CustomItems.cloner || item == CustomItems.wand || item == CustomItems.mount || item == CustomItems.scripter || item == CustomItems.soulstoneEmpty) { - setAttackTarget(null); - setRevengeTarget(null); - return true; - } - if (item == CustomItems.moving) { - setAttackTarget(null); - if(currentItem.stackTagCompound == null) - currentItem.stackTagCompound = new NBTTagCompound(); + @Override + public boolean interact(EntityPlayer player) { + if (worldObj.isRemote) + return false; + ItemStack currentItem = player.inventory.getCurrentItem(); + if (currentItem != null) { + Item item = currentItem.getItem(); + if (item == CustomItems.cloner || item == CustomItems.wand || item == CustomItems.mount || item == CustomItems.scripter || item == CustomItems.soulstoneEmpty) { + setAttackTarget(null); + setRevengeTarget(null); + return true; + } + if (item == CustomItems.moving) { + setAttackTarget(null); + if (currentItem.stackTagCompound == null) + currentItem.stackTagCompound = new NBTTagCompound(); - currentItem.stackTagCompound.setInteger("NPCID",this.getEntityId()); - player.addChatMessage(new ChatComponentTranslation("Registered " + this.getCommandSenderName() + " to your NPC Pather")); - return true; - } - } - - if(EventHooks.onNPCInteract(this, player) || isAttacking() || isKilled() || faction.isAggressiveToPlayer(player)) - return false; - - addInteract(player); - - Dialog dialog = getDialog(player); - PlayerQuestData playerdata = PlayerDataController.Instance.getPlayerData(player).questData; - QuestData data = playerdata.getQuestCompletion(player, this); - Party partyCompleted = playerdata.getPartyQuestCompletion(player, this); - if(partyCompleted != null){ - NoppesUtilPlayer.questPartyCompletion(partyCompleted); + currentItem.stackTagCompound.setInteger("NPCID", this.getEntityId()); + player.addChatMessage(new ChatComponentTranslation("Registered " + this.getCommandSenderName() + " to your NPC Pather")); + return true; + } } - else if (data != null){ - NoppesUtilPlayer.questCompletion((EntityPlayerMP) player, data.quest.id); - QuestCompletionPacket.sendQuestComplete((EntityPlayerMP)player, data.quest.writeToNBT(new NBTTagCompound())); - } - else if (dialog != null){ - NoppesUtilServer.openDialog(player, this, dialog, 0); - } - else if(roleInterface != null) - roleInterface.interact(player); - else - say(player, advanced.getInteractLine()); - return true; - } + if (EventHooks.onNPCInteract(this, player) || isAttacking() || isKilled() || faction.isAggressiveToPlayer(player)) + return false; - @Override - public PathNavigate getNavigator() { - if(canFly()) - return this.flyNavigator; - else { - return super.getNavigator(); - } - } + addInteract(player); - @Override - public EntityMoveHelper getMoveHelper() { - if(canFly()) - return this.flyMoveHelper; - else { - return super.getMoveHelper(); - } - } + Dialog dialog = getDialog(player); + PlayerQuestData playerdata = PlayerDataController.Instance.getPlayerData(player).questData; + QuestData data = playerdata.getQuestCompletion(player, this); + Party partyCompleted = playerdata.getPartyQuestCompletion(player, this); + if (partyCompleted != null) { + NoppesUtilPlayer.questPartyCompletion(partyCompleted); + } else if (data != null) { + NoppesUtilPlayer.questCompletion((EntityPlayerMP) player, data.quest.id); + QuestCompletionPacket.sendQuestComplete((EntityPlayerMP) player, data.quest.writeToNBT(new NBTTagCompound())); + } else if (dialog != null) { + NoppesUtilServer.openDialog(player, this, dialog, 0); + } else if (roleInterface != null) + roleInterface.interact(player); + else + say(player, advanced.getInteractLine()); - public boolean canBreathe() { - return this.isInWater() && this.stats.drowningType == 2 || !this.isInWater() && this.stats.drowningType == 1 || this.stats.drowningType == 0; - } + return true; + } - @Override - protected void updateAITasks() - { - this.getNavigator().onUpdateNavigation(); - this.getMoveHelper().onUpdateMoveHelper(); - try { - super.updateAITasks(); - } catch (ConcurrentModificationException ignored){} + @Override + public PathNavigate getNavigator() { + if (canFly()) + return this.flyNavigator; + else { + return super.getNavigator(); + } + } - if (!this.canBreathe()) { - this.setAir(this.decreaseAirSupply(this.getAir())); + @Override + public EntityMoveHelper getMoveHelper() { + if (canFly()) + return this.flyMoveHelper; + else { + return super.getMoveHelper(); + } + } - if (this.getAir() <= -20) { - this.setAir(0); - this.attackEntityFrom(DamageSource.drown, 2.0F); - } - } - } + public boolean canBreathe() { + return this.isInWater() && this.stats.drowningType == 2 || !this.isInWater() && this.stats.drowningType == 1 || this.stats.drowningType == 0; + } - public void addInteract(EntityLivingBase entity){ - if( !ais.stopAndInteract || isAttacking() || !entity.isEntityAlive()) - return; - if((ticksExisted - lastInteract) < 180) - interactingEntities.clear(); - getNavigator().clearPathEntity(); - lastInteract = ticksExisted; - if(!interactingEntities.contains(entity)) - interactingEntities.add(entity); - } + @Override + protected void updateAITasks() { + this.getNavigator().onUpdateNavigation(); + this.getMoveHelper().onUpdateMoveHelper(); + try { + super.updateAITasks(); + } catch (ConcurrentModificationException ignored) { + } - public boolean isInteracting(){ - if((ticksExisted - lastInteract) < 40 || isRemote() && getBoolFlag(2)) - return true; - return ais.stopAndInteract && !interactingEntities.isEmpty() && (ticksExisted - lastInteract) < 180; - } + if (!this.canBreathe()) { + this.setAir(this.decreaseAirSupply(this.getAir())); - private Dialog getDialog(EntityPlayer player) { - for (DialogOption option : dialogs.values()) { - if (option == null) - continue; - if (!option.hasDialog()) - continue; - Dialog dialog = option.getDialog(); - if (dialog.availability.isAvailable(player)){ - return dialog; - } - } - return null; - } + if (this.getAir() <= -20) { + this.setAir(0); + this.attackEntityFrom(DamageSource.drown, 2.0F); + } + } + } - @Override - public boolean attackEntityFrom(DamageSource damagesource, float i) { - if (this.worldObj.isRemote || CustomNpcs.FreezeNPCs || (damagesource.damageType != null && damagesource.damageType.equals("inWall"))){ - return false; - } - if(damagesource.damageType != null && damagesource.damageType.equals("outOfWorld") && isKilled()){ - reset(); - } - i = stats.resistances.applyResistance(damagesource, i); - if((float)this.hurtResistantTime > (float)this.maxHurtResistantTime / 2.0F && i <= this.lastDamage) - return false; - - Entity entity = NoppesUtilServer.GetDamageSource(damagesource); - EntityLivingBase attackingEntity = null; - - if (entity instanceof EntityLivingBase) - attackingEntity = (EntityLivingBase) entity; - - if(attackingEntity != null && attackingEntity == getOwner()) - return false; - else if (attackingEntity instanceof EntityNPCInterface){ - EntityNPCInterface npc = (EntityNPCInterface) attackingEntity; - if(npc.faction.id == faction.id) - return false; - if(npc.getOwner() instanceof EntityPlayer) - this.recentlyHit = 100; - } - else if (attackingEntity instanceof EntityPlayer && faction.isFriendlyToPlayer((EntityPlayer) attackingEntity)) - return false; - NpcEvent.DamagedEvent event = new NpcEvent.DamagedEvent(this.wrappedNPC, attackingEntity, i, damagesource); - if(EventHooks.onNPCDamaged(this, event) || isKilled()) - return false; - i = event.getDamage(); - - if(isKilled()) - return false; - - if(attackingEntity == null) - return super.attackEntityFrom(damagesource, i); - - try{ - if (isAttacking()){ - if (getAttackTarget() != null) { - if (ais.combatPolicy != EnumCombatPolicy.Brute) { - boolean closerTargetFound = this.getDistanceSqToEntity(getAttackTarget()) > this.getDistanceSqToEntity(attackingEntity); - switch (ais.combatPolicy) { - case Flip: - if (closerTargetFound) { - setAttackTarget(attackingEntity); - } - break; - case Stubborn: - if (closerTargetFound && combatHandler.shouldChangeTarget(ais.tacticalChance)) { - setAttackTarget(attackingEntity); - } - break; - case Tactical: - if (attackingEntity != getAttackTarget() && combatHandler.shouldSwitchTactically(getAttackTarget(), attackingEntity, ais.tacticalChance > 50)) { - setAttackTarget(attackingEntity); - } - break; - default: - break; - } - } - } - return super.attackEntityFrom(damagesource, i); - } - if (i > 0){ - List inRange = worldObj.getEntitiesWithinAABB(EntityNPCInterface.class, this.boundingBox.expand(32D, 16D, 32D)); - for (EntityNPCInterface npc : inRange) { - if (npc.isKilled() || !npc.advanced.defendFaction || npc.faction.id != faction.id) - continue; - - if (npc.canSee(this) || npc.ais.directLOS || npc.canSee(attackingEntity)) - npc.onAttack(attackingEntity); - } - setAttackTarget(attackingEntity); - } - return super.attackEntityFrom(damagesource, i); - } - finally{ - if(event.getClearTarget()){ - setAttackTarget(null); - setRevengeTarget(null); - } - } - } - public void onAttack(EntityLivingBase entity) { - if (entity == null || entity == this || isAttacking() || ais.onAttack == 3 || entity == getOwner()) - return; - super.setAttackTarget(entity); - } - - @Override - public void setAttackTarget(EntityLivingBase entity){ - if(entity instanceof EntityPlayer && ((EntityPlayer)entity).capabilities.disableDamage || entity != null && entity == getOwner()) - return; - if(entity instanceof EntityPlayer && DBCAddon.instance.isKO(this, (EntityPlayer) entity)) + public void addInteract(EntityLivingBase entity) { + if (!ais.stopAndInteract || isAttacking() || !entity.isEntityAlive()) return; - if (!isRemote()) { - if (getAttackTarget() != entity && entity != null) { - NpcEvent.TargetEvent event = new NpcEvent.TargetEvent(wrappedNPC,entity); - if (EventHooks.onNPCTarget(this, event)) - return; + if ((ticksExisted - lastInteract) < 180) + interactingEntities.clear(); + getNavigator().clearPathEntity(); + lastInteract = ticksExisted; + if (!interactingEntities.contains(entity)) + interactingEntities.add(entity); + } - if (event.getTarget() == null) - entity = null; - else - entity = event.getTarget().getMCEntity(); - } else { - if(EventHooks.onNPCTargetLost(this, getAttackTarget(), entity)) - return; - } - if (entity != null && entity != this && ais.onAttack != 3 && !isAttacking()) { - Line line = advanced.getAttackLine(); - if (line != null) - saySurrounding(line.formatTarget(entity)); - } - } + public boolean isInteracting() { + if ((ticksExisted - lastInteract) < 40 || isRemote() && getBoolFlag(2)) + return true; + return ais.stopAndInteract && !interactingEntities.isEmpty() && (ticksExisted - lastInteract) < 180; + } - super.setAttackTarget(entity); - } + private Dialog getDialog(EntityPlayer player) { + for (DialogOption option : dialogs.values()) { + if (option == null) + continue; + if (!option.hasDialog()) + continue; + Dialog dialog = option.getDialog(); + if (dialog.availability.isAvailable(player)) { + return dialog; + } + } + return null; + } - @Override - public void attackEntityWithRangedAttack(EntityLivingBase entity, float f) { - ItemStack proj = inventory.getProjectile(); - if(proj == null){ - updateTasks(); - return; - } - if (!isRemote()) { - NpcEvent.RangedLaunchedEvent event = new NpcEvent.RangedLaunchedEvent(wrappedNPC,stats.pDamage,entity); - if (EventHooks.onNPCRangedAttack(this, event)) - return; - for (int i = 0; i < this.stats.shotCount; i++) { - EntityProjectile projectile = shoot(entity, stats.accuracy, proj, f == 1); - projectile.damage = event.getDamage(); - } - this.playSound(this.stats.fireSound, 2.0F, 1.0f); - } - } + @Override + public boolean attackEntityFrom(DamageSource damagesource, float i) { + if (this.worldObj.isRemote || CustomNpcs.FreezeNPCs || (damagesource.damageType != null && damagesource.damageType.equals("inWall"))) { + return false; + } + if (damagesource.damageType != null && damagesource.damageType.equals("outOfWorld") && isKilled()) { + reset(); + } + i = stats.resistances.applyResistance(damagesource, i); + if ((float) this.hurtResistantTime > (float) this.maxHurtResistantTime / 2.0F && i <= this.lastDamage) + return false; - public EntityProjectile shoot(EntityLivingBase entity, int accuracy, ItemStack proj, boolean indirect){ - return shoot(entity.posX, entity.boundingBox.minY + (double)(entity.height / 2.0F), entity.posZ, accuracy, proj, indirect); - } + Entity entity = NoppesUtilServer.GetDamageSource(damagesource); + EntityLivingBase attackingEntity = null; - public EntityProjectile shoot(double x, double y, double z, int accuracy, ItemStack proj, boolean indirect){ + if (entity instanceof EntityLivingBase) + attackingEntity = (EntityLivingBase) entity; + + if (attackingEntity != null && attackingEntity == getOwner()) + return false; + else if (attackingEntity instanceof EntityNPCInterface) { + EntityNPCInterface npc = (EntityNPCInterface) attackingEntity; + if (npc.faction.id == faction.id) + return false; + if (npc.getOwner() instanceof EntityPlayer) + this.recentlyHit = 100; + } else if (attackingEntity instanceof EntityPlayer && faction.isFriendlyToPlayer((EntityPlayer) attackingEntity)) + return false; + NpcEvent.DamagedEvent event = new NpcEvent.DamagedEvent(this.wrappedNPC, attackingEntity, i, damagesource); + if (EventHooks.onNPCDamaged(this, event) || isKilled()) + return false; + i = event.getDamage(); + + if (isKilled()) + return false; + + if (attackingEntity == null) + return super.attackEntityFrom(damagesource, i); + + try { + if (isAttacking()) { + if (getAttackTarget() != null) { + if (ais.combatPolicy != EnumCombatPolicy.Brute) { + boolean closerTargetFound = this.getDistanceSqToEntity(getAttackTarget()) > this.getDistanceSqToEntity(attackingEntity); + switch (ais.combatPolicy) { + case Flip: + if (closerTargetFound) { + setAttackTarget(attackingEntity); + } + break; + case Stubborn: + if (closerTargetFound && combatHandler.shouldChangeTarget(ais.tacticalChance)) { + setAttackTarget(attackingEntity); + } + break; + case Tactical: + if (attackingEntity != getAttackTarget() && combatHandler.shouldSwitchTactically(getAttackTarget(), attackingEntity, ais.tacticalChance > 50)) { + setAttackTarget(attackingEntity); + } + break; + default: + break; + } + } + } + return super.attackEntityFrom(damagesource, i); + } + if (i > 0) { + List inRange = worldObj.getEntitiesWithinAABB(EntityNPCInterface.class, this.boundingBox.expand(32D, 16D, 32D)); + for (EntityNPCInterface npc : inRange) { + if (npc.isKilled() || !npc.advanced.defendFaction || npc.faction.id != faction.id) + continue; + + if (npc.canSee(this) || npc.ais.directLOS || npc.canSee(attackingEntity)) + npc.onAttack(attackingEntity); + } + setAttackTarget(attackingEntity); + } + return super.attackEntityFrom(damagesource, i); + } finally { + if (event.getClearTarget()) { + setAttackTarget(null); + setRevengeTarget(null); + } + } + } + + public void onAttack(EntityLivingBase entity) { + if (entity == null || entity == this || isAttacking() || ais.onAttack == 3 || entity == getOwner()) + return; + super.setAttackTarget(entity); + } + + @Override + public void setAttackTarget(EntityLivingBase entity) { + if (entity instanceof EntityPlayer && ((EntityPlayer) entity).capabilities.disableDamage || entity != null && entity == getOwner()) + return; + if (entity instanceof EntityPlayer && DBCAddon.instance.isKO(this, (EntityPlayer) entity)) + return; + if (!isRemote()) { + if (getAttackTarget() != entity && entity != null) { + NpcEvent.TargetEvent event = new NpcEvent.TargetEvent(wrappedNPC, entity); + if (EventHooks.onNPCTarget(this, event)) + return; + + if (event.getTarget() == null) + entity = null; + else + entity = event.getTarget().getMCEntity(); + } else { + if (EventHooks.onNPCTargetLost(this, getAttackTarget(), entity)) + return; + } + if (entity != null && entity != this && ais.onAttack != 3 && !isAttacking()) { + Line line = advanced.getAttackLine(); + if (line != null) + saySurrounding(line.formatTarget(entity)); + } + } + + super.setAttackTarget(entity); + } + + @Override + public void attackEntityWithRangedAttack(EntityLivingBase entity, float f) { + ItemStack proj = inventory.getProjectile(); + if (proj == null) { + updateTasks(); + return; + } + if (!isRemote()) { + NpcEvent.RangedLaunchedEvent event = new NpcEvent.RangedLaunchedEvent(wrappedNPC, stats.pDamage, entity); + if (EventHooks.onNPCRangedAttack(this, event)) + return; + for (int i = 0; i < this.stats.shotCount; i++) { + EntityProjectile projectile = shoot(entity, stats.accuracy, proj, f == 1); + projectile.damage = event.getDamage(); + } + this.playSound(this.stats.fireSound, 2.0F, 1.0f); + } + } + + public EntityProjectile shoot(EntityLivingBase entity, int accuracy, ItemStack proj, boolean indirect) { + return shoot(entity.posX, entity.boundingBox.minY + (double) (entity.height / 2.0F), entity.posZ, accuracy, proj, indirect); + } + + public EntityProjectile shoot(double x, double y, double z, int accuracy, ItemStack proj, boolean indirect) { EntityProjectile projectile = new EntityProjectile(this.worldObj, this, proj.copy(), true); double throwerHeight = this.getEyeHeight(); @@ -699,61 +691,60 @@ public abstract class EntityNPCInterface extends EntityCreature implements IEnti projectile.setThrowableHeading(varX, varY, varZ, angle, acc); worldObj.spawnEntityInWorld(projectile); return projectile; - } + } - private void clearTasks(EntityAITasks tasks){ + private void clearTasks(EntityAITasks tasks) { Iterator iterator = tasks.taskEntries.iterator(); List list = new ArrayList(tasks.taskEntries); - for (EntityAITaskEntry entityaitaskentry : list) - { + for (EntityAITaskEntry entityaitaskentry : list) { try { tasks.removeTask(entityaitaskentry.action); - } - catch(Throwable e) { + } catch (Throwable e) { } } tasks.taskEntries = new ArrayList(); - } - public void updateTasks() { - if (worldObj == null || worldObj.isRemote) - return; + } - clearTasks(tasks); - clearTasks(targetTasks); - if(isKilled()) - return; + public void updateTasks() { + if (worldObj == null || worldObj.isRemote) + return; - IEntitySelector attackEntitySelector = new NPCAttackSelector(this); - this.targetTasks.addTask(0, new EntityAIClearTarget(this)); - this.targetTasks.addTask(1, new EntityAIHurtByTarget(this, false)); - this.targetTasks.addTask(2, new EntityAIClosestTarget(this, EntityLivingBase.class, 4, this.ais.directLOS, false, attackEntitySelector)); - this.targetTasks.addTask(3, new EntityAIOwnerHurtByTarget(this)); - this.targetTasks.addTask(4, new EntityAIOwnerHurtTarget(this)); + clearTasks(tasks); + clearTasks(targetTasks); + if (isKilled()) + return; - if (canFly()) { - this.getNavigator().setCanSwim(true); - } else { - this.tasks.addTask(0, new EntityAIWaterNav(this)); - } + IEntitySelector attackEntitySelector = new NPCAttackSelector(this); + this.targetTasks.addTask(0, new EntityAIClearTarget(this)); + this.targetTasks.addTask(1, new EntityAIHurtByTarget(this, false)); + this.targetTasks.addTask(2, new EntityAIClosestTarget(this, EntityLivingBase.class, 4, this.ais.directLOS, false, attackEntitySelector)); + this.targetTasks.addTask(3, new EntityAIOwnerHurtByTarget(this)); + this.targetTasks.addTask(4, new EntityAIOwnerHurtTarget(this)); - this.taskCount = 1; - this.doorInteractType(); - this.seekShelter(); - this.setResponse(); - this.setMoveType(); + if (canFly()) { + this.getNavigator().setCanSwim(true); + } else { + this.tasks.addTask(0, new EntityAIWaterNav(this)); + } + + this.taskCount = 1; + this.doorInteractType(); + this.seekShelter(); + this.setResponse(); + this.setMoveType(); this.addRegularEntries(); - } + } - private void removeTask(EntityAIBase task){ - if(task != null) - tasks.removeTask(task); - } + private void removeTask(EntityAIBase task) { + if (task != null) + tasks.removeTask(task); + } - /* - * Branch task function for setting how an NPC responds to a threat - */ - public void setResponse(){ + /* + * Branch task function for setting how an NPC responds to a threat + */ + public void setResponse() { removeTask(aiLeap); removeTask(aiResponse); removeTask(aiSprint); @@ -761,1244 +752,1222 @@ public abstract class EntityNPCInterface extends EntityCreature implements IEnti removeTask(aiRange); aiLeap = aiAttackTarget = aiResponse = aiSprint = aiRange = null; - if (this.ais.canSprint) - this.tasks.addTask(this.taskCount++, new EntityAISprintToTarget(this)); + if (this.ais.canSprint) + this.tasks.addTask(this.taskCount++, new EntityAISprintToTarget(this)); - if (this.ais.onAttack == 1) - this.tasks.addTask(this.taskCount++, aiResponse = new EntityAIPanic(this, 1.2F)); - else if (this.ais.onAttack == 2) { - this.tasks.addTask(this.taskCount++, aiResponse = new EntityAIAvoidTarget(this)); - } - else if (this.ais.onAttack == 0) { - this.setLeapTask(); - if (this.inventory.getProjectile() == null || this.ais.useRangeMelee == 2) - { - switch(this.ais.tacticalVariant) - { - case Dodge : this.tasks.addTask(this.taskCount++, aiResponse = new EntityAIZigZagTarget(this, 1.2D, this.ais.tacticalRadius)); break; - case Surround : this.tasks.addTask(this.taskCount++, aiResponse = new EntityAIOrbitTarget(this, 1.2D, this.ais.tacticalRadius, true)); break; - case HitNRun : this.tasks.addTask(this.taskCount++, aiResponse = new EntityAIAvoidTarget(this)); break; - case Ambush : this.tasks.addTask(this.taskCount++, aiResponse = new EntityAIAmbushTarget(this, 1.2D, this.ais.tacticalRadius, false)); break; - case Stalk : this.tasks.addTask(this.taskCount++, aiResponse = new EntityAIStalkTarget(this, this.ais.tacticalRadius)); break; - default : - } - } - else - { - switch(this.ais.tacticalVariant) - { - case Dodge : this.tasks.addTask(this.taskCount++, aiResponse = new EntityAIDodgeShoot(this)); break; - case Surround : this.tasks.addTask(this.taskCount++, aiResponse = new EntityAIOrbitTarget(this, 1.2D, stats.rangedRange, false)); break; - case HitNRun : this.tasks.addTask(this.taskCount++, aiResponse = new EntityAIAvoidTarget(this)); break; - case Ambush : this.tasks.addTask(this.taskCount++, aiResponse = new EntityAIAmbushTarget(this, 1.2D, this.ais.tacticalRadius, false)); break; - case Stalk : this.tasks.addTask(this.taskCount++, aiResponse = new EntityAIStalkTarget(this, this.ais.tacticalRadius)); break; - default : - } - } - this.tasks.addTask(this.taskCount, aiAttackTarget = new EntityAIAttackTarget(this)); - ((EntityAIAttackTarget)aiAttackTarget).navOverride(ais.tacticalVariant == EnumNavType.None); + if (this.ais.onAttack == 1) + this.tasks.addTask(this.taskCount++, aiResponse = new EntityAIPanic(this, 1.2F)); + else if (this.ais.onAttack == 2) { + this.tasks.addTask(this.taskCount++, aiResponse = new EntityAIAvoidTarget(this)); + } else if (this.ais.onAttack == 0) { + this.setLeapTask(); + if (this.inventory.getProjectile() == null || this.ais.useRangeMelee == 2) { + switch (this.ais.tacticalVariant) { + case Dodge: + this.tasks.addTask(this.taskCount++, aiResponse = new EntityAIZigZagTarget(this, 1.2D, this.ais.tacticalRadius)); + break; + case Surround: + this.tasks.addTask(this.taskCount++, aiResponse = new EntityAIOrbitTarget(this, 1.2D, this.ais.tacticalRadius, true)); + break; + case HitNRun: + this.tasks.addTask(this.taskCount++, aiResponse = new EntityAIAvoidTarget(this)); + break; + case Ambush: + this.tasks.addTask(this.taskCount++, aiResponse = new EntityAIAmbushTarget(this, 1.2D, this.ais.tacticalRadius, false)); + break; + case Stalk: + this.tasks.addTask(this.taskCount++, aiResponse = new EntityAIStalkTarget(this, this.ais.tacticalRadius)); + break; + default: + } + } else { + switch (this.ais.tacticalVariant) { + case Dodge: + this.tasks.addTask(this.taskCount++, aiResponse = new EntityAIDodgeShoot(this)); + break; + case Surround: + this.tasks.addTask(this.taskCount++, aiResponse = new EntityAIOrbitTarget(this, 1.2D, stats.rangedRange, false)); + break; + case HitNRun: + this.tasks.addTask(this.taskCount++, aiResponse = new EntityAIAvoidTarget(this)); + break; + case Ambush: + this.tasks.addTask(this.taskCount++, aiResponse = new EntityAIAmbushTarget(this, 1.2D, this.ais.tacticalRadius, false)); + break; + case Stalk: + this.tasks.addTask(this.taskCount++, aiResponse = new EntityAIStalkTarget(this, this.ais.tacticalRadius)); + break; + default: + } + } + this.tasks.addTask(this.taskCount, aiAttackTarget = new EntityAIAttackTarget(this)); + ((EntityAIAttackTarget) aiAttackTarget).navOverride(ais.tacticalVariant == EnumNavType.None); - if(this.inventory.getProjectile() != null){ - this.tasks.addTask(this.taskCount++, aiRange = new EntityAIRangedAttack(this)); - aiRange.navOverride(ais.tacticalVariant == EnumNavType.None); - } - } - else if (this.ais.onAttack == 3) { - //do nothing - } - } - - /* - * Branch task function for setting if an NPC wanders or not - */ - public void setMoveType(){ - if (ais.movingType == EnumMovingType.Wandering){ - this.tasks.addTask(this.taskCount++, new EntityAIWander(this)); - } - if (ais.movingType == EnumMovingType.MovingPath){ - this.tasks.addTask(this.taskCount++, new EntityAIMovingPath(this)); - } - } - /* - * Branch task function for adjusting NPC door interactivity - */ - public void doorInteractType(){ - if(canFly()) //currently flying does not support opening doors - return; - EntityAIBase aiDoor = null; - if (this.ais.doorInteract == 1) - { - this.tasks.addTask(this.taskCount++, aiDoor = new EntityAIOpenDoor(this, true)); - } - else if (this.ais.doorInteract == 0) - { - this.tasks.addTask(this.taskCount++, aiDoor = new EntityAIBustDoor(this)); - } - this.getNavigator().setBreakDoors(aiDoor != null); - } - - /* - * Branch task function for finding shelter under the appropriate conditions - */ - public void seekShelter() { - if (this.ais.findShelter == 0) - { - this.tasks.addTask(this.taskCount++, new EntityAIMoveIndoors(this)); - } - else if (this.ais.findShelter == 1) - { - if(!canFly()) // doesnt work when flying - this.tasks.addTask(this.taskCount++, new EntityAIRestrictSun(this)); - this.tasks.addTask(this.taskCount++, new EntityAIFindShade(this)); - } - } - - /* - * Branch task function for leaping - */ - public void setLeapTask() { - if (this.ais.leapType == 1) - this.tasks.addTask(this.taskCount++, aiLeap = new EntityAILeapAtTarget(this, 0.4F)); - if (this.ais.leapType == 2) - this.tasks.addTask(this.taskCount++, aiLeap = new EntityAIPounceTarget(this)); - } - - /* - * Add immutable task entries. - */ - public void addRegularEntries() { - this.tasks.addTask(this.taskCount++, new EntityAIFollow(this)); - this.tasks.addTask(this.taskCount++, new EntityAIReturn(this)); - if (this.ais.standingType != EnumStandingType.NoRotation && this.ais.standingType != EnumStandingType.HeadRotation) - this.tasks.addTask(this.taskCount++, new EntityAIWatchClosest(this, EntityLivingBase.class, 5.0F)); - this.tasks.addTask(this.taskCount++, new EntityAILook(this)); - this.tasks.addTask(this.taskCount++, new EntityAIWorldLines(this)); - this.tasks.addTask(this.taskCount++, new EntityAIJob(this)); - this.tasks.addTask(this.taskCount++, new EntityAIRole(this)); - this.tasks.addTask(this.taskCount++, new EntityAIAnimation(this)); - if(transform.isValid()) - this.tasks.addTask(this.taskCount++, new EntityAITransform(this)); - } - - /* - * Function for getting proper move speeds. This way we don't have to modify them every time we use them. - */ - public float getSpeed() { - return (float) ais.getWalkingSpeed() / 20.0F; - } - - @Override - public float getBlockPathWeight(int par1, int par2, int par3){ - float weight = this.worldObj.getLightBrightness(par1, par2, par3) - 0.5F; - Block block = worldObj.getBlock(par1, par2, par3); - if(block.isOpaqueCube()) - weight += 10; - return weight; - } - - /* - * Used for getting the applied potion effect from dataStats. - */ - private int getPotionEffect(EnumPotionType p) { - switch(p) - { - case Poison : return Potion.poison.id; - case Hunger : return Potion.hunger.id; - case Weakness : return Potion.weakness.id; - case Slowness : return Potion.moveSlowdown.id; - case Nausea : return Potion.confusion.id; - case Blindness : return Potion.blindness.id; - case Wither : return Potion.wither.id; - default : return 0; - } - } - - @Override - public void setAir(int air) { - if (this.isInWater() || air < this.getAir() || this.stats.drowningType != 2) { - super.setAir(air); - } - } - - @Override - protected int decreaseAirSupply(int par1) - { - if (this.stats.drowningType == 0) - return par1; - return super.decreaseAirSupply(par1); - } - - @Override - public EnumCreatureAttribute getCreatureAttribute() - { - return this.stats.creatureType; - } - - /** - * Returns the sound this mob makes while it's alive. - */ - @Override - protected String getLivingSound() { - if (!this.isEntityAlive()) - return null; - if (this.getAttackTarget() != null) - return advanced.angrySound.isEmpty() ? null : advanced.angrySound; - - return advanced.idleSound.isEmpty() ? null : advanced.idleSound; - } - - @Override - public int getTalkInterval(){ - return 160; - } - /** - * Returns the sound this mob makes when it is hurt. - */ - @Override - protected String getHurtSound(){ - if(this.advanced.hurtSound.isEmpty()) - return null; - return this.advanced.hurtSound; - } - - /** - * Returns the sound this mob makes on death. - */ - @Override - protected String getDeathSound(){ - if(this.advanced.deathSound.isEmpty()) - return null; - return this.advanced.deathSound; - } - - @Override - protected float getSoundPitch(){ - if(this.advanced.disablePitch) - return 1; - return super.getSoundPitch(); - } - - /** - * Plays step sound at given x, y, z for the entity - */ - @Override - protected void func_145780_a(int p_145780_1_, int p_145780_2_, int p_145780_3_, Block p_145780_4_) - { - if (!this.advanced.stepSound.equals("")) - { - this.playSound(this.advanced.stepSound, 0.15F, 1.0F); - } - else - { - super.func_145780_a(p_145780_1_, p_145780_2_, p_145780_3_, p_145780_4_); - } - } - - - public EntityPlayerMP getFakePlayer(){ - if(worldObj.isRemote) - return null; - if(chateventPlayer == null) - chateventPlayer = new FakePlayer((WorldServer)worldObj, chateventProfile); - EntityUtil.Copy(this, chateventPlayer); - chateventProfile.npc = this; - chateventPlayer.refreshDisplayName(); - IItemStack stack = NpcAPI.Instance().createItem("minecraft:stone",0,1); - chateventPlayer.setCurrentItemOrArmor(0, stack.getMCItemStack()); - return chateventPlayer; - } - - public void saySurrounding(ILine line) { - if (line == null || line.getText() == null || getFakePlayer() == null) - return; - ServerChatEvent event = new ServerChatEvent(getFakePlayer(), line.getText(), new ChatComponentTranslation(line.getText().replace("%", "%%"))); - if (MinecraftForge.EVENT_BUS.post(event) || event.component == null){ - return; - } - line.setText(event.component.getUnformattedText().replace("%%", "%")); - List inRange = worldObj.getEntitiesWithinAABB( - EntityPlayer.class, this.boundingBox.expand(20D, 20D, 20D)); - for (EntityPlayer player : inRange) - say(player, line); - } - - public void say(EntityPlayer player, ILine line) { - if (line == null || !this.canSee(player) || line.getText() == null) - return; - - if(!line.getSound().isEmpty()){ - PacketHandler.Instance.sendToPlayer(new SoundManagementPacket(EnumSoundOperation.PLAY_SOUND, line.getSound(), (float)posX, (float)posY, (float)posZ), (EntityPlayerMP)player); + if (this.inventory.getProjectile() != null) { + this.tasks.addTask(this.taskCount++, aiRange = new EntityAIRangedAttack(this)); + aiRange.navOverride(ais.tacticalVariant == EnumNavType.None); + } + } else if (this.ais.onAttack == 3) { + //do nothing } - PacketHandler.Instance.sendToPlayer(new ChatBubblePacket(this.getEntityId(), line.getText(), !line.hideText()), (EntityPlayerMP)player); - } - public boolean getAlwaysRenderNameTagForRender(){ - return true; - } + } - @Override - public void readEntityFromNBT(NBTTagCompound compound) { - super.readEntityFromNBT(compound); - npcVersion = compound.getInteger("ModRev"); - VersionCompatibility.CheckNpcCompatibility(this, compound); + /* + * Branch task function for setting if an NPC wanders or not + */ + public void setMoveType() { + if (ais.movingType == EnumMovingType.Wandering) { + this.tasks.addTask(this.taskCount++, new EntityAIWander(this)); + } + if (ais.movingType == EnumMovingType.MovingPath) { + this.tasks.addTask(this.taskCount++, new EntityAIMovingPath(this)); + } + } - display.readToNBT(compound); - stats.readToNBT(compound); - ais.readToNBT(compound); - script.readFromNBT(compound); - script.readEventsFromNBT(compound); - timers.readFromNBT(compound); - advanced.readToNBT(compound); - if (advanced.role != EnumRoleType.None && roleInterface != null) - roleInterface.readFromNBT(compound); - if (advanced.job != EnumJobType.None && jobInterface != null) - jobInterface.readFromNBT(compound); + /* + * Branch task function for adjusting NPC door interactivity + */ + public void doorInteractType() { + if (canFly()) //currently flying does not support opening doors + return; + EntityAIBase aiDoor = null; + if (this.ais.doorInteract == 1) { + this.tasks.addTask(this.taskCount++, aiDoor = new EntityAIOpenDoor(this, true)); + } else if (this.ais.doorInteract == 0) { + this.tasks.addTask(this.taskCount++, aiDoor = new EntityAIBustDoor(this)); + } + this.getNavigator().setBreakDoors(aiDoor != null); + } - inventory.readEntityFromNBT(compound); - transform.readToNBT(compound); + /* + * Branch task function for finding shelter under the appropriate conditions + */ + public void seekShelter() { + if (this.ais.findShelter == 0) { + this.tasks.addTask(this.taskCount++, new EntityAIMoveIndoors(this)); + } else if (this.ais.findShelter == 1) { + if (!canFly()) // doesnt work when flying + this.tasks.addTask(this.taskCount++, new EntityAIRestrictSun(this)); + this.tasks.addTask(this.taskCount++, new EntityAIFindShade(this)); + } + } - killedtime = compound.getLong("KilledTime"); - totalTicksAlive = compound.getLong("TotalTicksAlive"); + /* + * Branch task function for leaping + */ + public void setLeapTask() { + if (this.ais.leapType == 1) + this.tasks.addTask(this.taskCount++, aiLeap = new EntityAILeapAtTarget(this, 0.4F)); + if (this.ais.leapType == 2) + this.tasks.addTask(this.taskCount++, aiLeap = new EntityAIPounceTarget(this)); + } - linkedName = compound.getString("LinkedNpcName"); + /* + * Add immutable task entries. + */ + public void addRegularEntries() { + this.tasks.addTask(this.taskCount++, new EntityAIFollow(this)); + this.tasks.addTask(this.taskCount++, new EntityAIReturn(this)); + if (this.ais.standingType != EnumStandingType.NoRotation && this.ais.standingType != EnumStandingType.HeadRotation) + this.tasks.addTask(this.taskCount++, new EntityAIWatchClosest(this, EntityLivingBase.class, 5.0F)); + this.tasks.addTask(this.taskCount++, new EntityAILook(this)); + this.tasks.addTask(this.taskCount++, new EntityAIWorldLines(this)); + this.tasks.addTask(this.taskCount++, new EntityAIJob(this)); + this.tasks.addTask(this.taskCount++, new EntityAIRole(this)); + this.tasks.addTask(this.taskCount++, new EntityAIAnimation(this)); + if (transform.isValid()) + this.tasks.addTask(this.taskCount++, new EntityAITransform(this)); + } - if(!isRemote()) - LinkedNpcController.Instance.loadNpcData(this); + /* + * Function for getting proper move speeds. This way we don't have to modify them every time we use them. + */ + public float getSpeed() { + return (float) ais.getWalkingSpeed() / 20.0F; + } - this.getEntityAttribute(SharedMonsterAttributes.followRange).setBaseValue(ConfigMain.NpcNavRange); + @Override + public float getBlockPathWeight(int par1, int par2, int par3) { + float weight = this.worldObj.getLightBrightness(par1, par2, par3) - 0.5F; + Block block = worldObj.getBlock(par1, par2, par3); + if (block.isOpaqueCube()) + weight += 10; + return weight; + } - this.updateTasks(); - this.func_110163_bv(); - } + /* + * Used for getting the applied potion effect from dataStats. + */ + private int getPotionEffect(EnumPotionType p) { + switch (p) { + case Poison: + return Potion.poison.id; + case Hunger: + return Potion.hunger.id; + case Weakness: + return Potion.weakness.id; + case Slowness: + return Potion.moveSlowdown.id; + case Nausea: + return Potion.confusion.id; + case Blindness: + return Potion.blindness.id; + case Wither: + return Potion.wither.id; + default: + return 0; + } + } + @Override + public void setAir(int air) { + if (this.isInWater() || air < this.getAir() || this.stats.drowningType != 2) { + super.setAir(air); + } + } + @Override + protected int decreaseAirSupply(int par1) { + if (this.stats.drowningType == 0) + return par1; + return super.decreaseAirSupply(par1); + } - @Override - public void writeEntityToNBT(NBTTagCompound compound) { - super.writeEntityToNBT(compound); - display.writeToNBT(compound); - stats.writeToNBT(compound); - ais.writeToNBT(compound); - script.writeToNBT(compound); - script.writeEventsToNBT(compound); - timers.writeToNBT(compound); - advanced.writeToNBT(compound); - if (advanced.role != EnumRoleType.None && roleInterface != null) - roleInterface.writeToNBT(compound); - if (advanced.job != EnumJobType.None && jobInterface != null) - jobInterface.writeToNBT(compound); + @Override + public EnumCreatureAttribute getCreatureAttribute() { + return this.stats.creatureType; + } - inventory.writeEntityToNBT(compound); - transform.writeToNBT(compound); + /** + * Returns the sound this mob makes while it's alive. + */ + @Override + protected String getLivingSound() { + if (!this.isEntityAlive()) + return null; + if (this.getAttackTarget() != null) + return advanced.angrySound.isEmpty() ? null : advanced.angrySound; - compound.setLong("KilledTime", killedtime); - compound.setLong("TotalTicksAlive", totalTicksAlive); - compound.setInteger("ModRev", npcVersion); - compound.setString("LinkedNpcName", linkedName); - } + return advanced.idleSound.isEmpty() ? null : advanced.idleSound; + } - public void updateHitbox() { + @Override + public int getTalkInterval() { + return 160; + } - if(currentAnimation == EnumAnimation.LYING || currentAnimation == EnumAnimation.CRAWLING){ - width = 0.8f; - height = 0.4f; - } - else if (isRiding()){ - width = 0.6f; - height = baseHeight * 0.77f; - } - else{ - width = 0.6f; - height = baseHeight; - } - width = (width / 5f) * display.modelSize; - height = (height / 5f) * display.modelSize; + /** + * Returns the sound this mob makes when it is hurt. + */ + @Override + protected String getHurtSound() { + if (this.advanced.hurtSound.isEmpty()) + return null; + return this.advanced.hurtSound; + } - if(display.hitboxData.isHitboxEnabled()){ + /** + * Returns the sound this mob makes on death. + */ + @Override + protected String getDeathSound() { + if (this.advanced.deathSound.isEmpty()) + return null; + return this.advanced.deathSound; + } + + @Override + protected float getSoundPitch() { + if (this.advanced.disablePitch) + return 1; + return super.getSoundPitch(); + } + + /** + * Plays step sound at given x, y, z for the entity + */ + @Override + protected void func_145780_a(int p_145780_1_, int p_145780_2_, int p_145780_3_, Block p_145780_4_) { + if (!this.advanced.stepSound.equals("")) { + this.playSound(this.advanced.stepSound, 0.15F, 1.0F); + } else { + super.func_145780_a(p_145780_1_, p_145780_2_, p_145780_3_, p_145780_4_); + } + } + + public EntityPlayerMP getFakePlayer() { + if (worldObj.isRemote) + return null; + if (chateventPlayer == null) + chateventPlayer = new FakePlayer((WorldServer) worldObj, chateventProfile); + EntityUtil.Copy(this, chateventPlayer); + chateventProfile.npc = this; + chateventPlayer.refreshDisplayName(); + IItemStack stack = NpcAPI.Instance().createItem("minecraft:stone", 0, 1); + chateventPlayer.setCurrentItemOrArmor(0, stack.getMCItemStack()); + return chateventPlayer; + } + + public void saySurrounding(ILine line) { + if (line == null || line.getText() == null || getFakePlayer() == null) + return; + ServerChatEvent event = new ServerChatEvent(getFakePlayer(), line.getText(), new ChatComponentTranslation(line.getText().replace("%", "%%"))); + if (MinecraftForge.EVENT_BUS.post(event) || event.component == null) { + return; + } + line.setText(event.component.getUnformattedText().replace("%%", "%")); + List inRange = worldObj.getEntitiesWithinAABB(EntityPlayer.class, this.boundingBox.expand(20D, 20D, 20D)); + for (EntityPlayer player : inRange) + say(player, line); + } + + public void say(EntityPlayer player, ILine line) { + if (line == null || !this.canSee(player) || line.getText() == null) + return; + + if (!line.getSound().isEmpty()) { + PacketHandler.Instance.sendToPlayer(new SoundManagementPacket(EnumSoundOperation.PLAY_SOUND, line.getSound(), (float) posX, (float) posY, (float) posZ), (EntityPlayerMP) player); + } + PacketHandler.Instance.sendToPlayer(new ChatBubblePacket(this.getEntityId(), line.getText(), !line.hideText()), (EntityPlayerMP) player); + } + + public boolean getAlwaysRenderNameTagForRender() { + return true; + } + + @Override + public void readEntityFromNBT(NBTTagCompound compound) { + super.readEntityFromNBT(compound); + npcVersion = compound.getInteger("ModRev"); + VersionCompatibility.CheckNpcCompatibility(this, compound); + + display.readToNBT(compound); + stats.readToNBT(compound); + ais.readToNBT(compound); + script.readFromNBT(compound); + script.readEventsFromNBT(compound); + timers.readFromNBT(compound); + advanced.readToNBT(compound); + if (advanced.role != EnumRoleType.None && roleInterface != null) + roleInterface.readFromNBT(compound); + if (advanced.job != EnumJobType.None && jobInterface != null) + jobInterface.readFromNBT(compound); + + inventory.readEntityFromNBT(compound); + transform.readToNBT(compound); + + killedtime = compound.getLong("KilledTime"); + totalTicksAlive = compound.getLong("TotalTicksAlive"); + + linkedName = compound.getString("LinkedNpcName"); + + if (!isRemote()) + LinkedNpcController.Instance.loadNpcData(this); + + this.getEntityAttribute(SharedMonsterAttributes.followRange).setBaseValue(ConfigMain.NpcNavRange); + + this.updateTasks(); + this.func_110163_bv(); + } + + @Override + public void writeEntityToNBT(NBTTagCompound compound) { + super.writeEntityToNBT(compound); + display.writeToNBT(compound); + stats.writeToNBT(compound); + ais.writeToNBT(compound); + script.writeToNBT(compound); + script.writeEventsToNBT(compound); + timers.writeToNBT(compound); + advanced.writeToNBT(compound); + if (advanced.role != EnumRoleType.None && roleInterface != null) + roleInterface.writeToNBT(compound); + if (advanced.job != EnumJobType.None && jobInterface != null) + jobInterface.writeToNBT(compound); + + inventory.writeEntityToNBT(compound); + transform.writeToNBT(compound); + + compound.setLong("KilledTime", killedtime); + compound.setLong("TotalTicksAlive", totalTicksAlive); + compound.setInteger("ModRev", npcVersion); + compound.setString("LinkedNpcName", linkedName); + } + + public void updateHitbox() { + + if (currentAnimation == EnumAnimation.LYING || currentAnimation == EnumAnimation.CRAWLING) { + width = 0.8f; + height = 0.4f; + } else if (isRiding()) { + width = 0.6f; + height = baseHeight * 0.77f; + } else { + width = 0.6f; + height = baseHeight; + } + width = (width / 5f) * display.modelSize; + height = (height / 5f) * display.modelSize; + + if (display.hitboxData.isHitboxEnabled()) { width = width * display.hitboxData.getWidthScale(); height = height * display.hitboxData.getHeightScale(); } - if(isKilled() && stats.hideKilledBody) { - width = 0.00001f; - } - if(width / 2 > worldObj.MAX_ENTITY_RADIUS) { - worldObj.MAX_ENTITY_RADIUS = width / 2; - } - this.setPosition(posX, posY, posZ); - } - - @Override - public void onDeathUpdate(){ - if(stats.spawnCycle == 3){ - super.onDeathUpdate(); - return; - } - - ++this.deathTime; - if(worldObj.isRemote) - return; - if(!hasDied){ - setDead(); - } - if (killedtime < System.currentTimeMillis()) { - if (stats.spawnCycle == 0 || (this.worldObj.isDaytime() && stats.spawnCycle == 1) || (!this.worldObj.isDaytime() && stats.spawnCycle == 2)) { - reset(); - } - } - } - - public void reset() { - hasDied = false; - isDead = false; - wasKilled = false; - setSprinting(false); - setHealth(getMaxHealth()); - dataWatcher.updateObject(14, 0); // animation Normal - dataWatcher.updateObject(15, 0); - - combatHandler.reset(); - this.setAttackTarget(null); - this.setRevengeTarget(null); - this.deathTime = 0; - //fleeingTick = 0; - if(ais.returnToStart && !hasOwner() && !this.isRemote()) - setLocationAndAngles(getStartXPos(), getStartYPos(), getStartZPos(), rotationYaw, rotationPitch); - killedtime = 0; - extinguish(); - this.clearActivePotions(); - getNavigator().clearPathEntity(); - if(this.canFly()){ - ((PathNavigateFlying)getNavigator()).targetPos = null; - ((PathNavigateFlying)getNavigator()).clearPathEntity(); - ((FlyingMoveHelper)getMoveHelper()).update = false; - } - moveEntityWithHeading(0,0); - distanceWalkedModified = 0; - currentAnimation = EnumAnimation.NONE; - updateHitbox(); - updateAI = true; - ais.movingPos = 0; - if(getOwner() != null){ - getOwner().setLastAttacker(null); - } - - if(jobInterface != null) - jobInterface.reset(); - - if (!isRemote()) { - EventHooks.onNPCInit(this); - } - } - - public void onCollide() { - if(!isEntityAlive() || ticksExisted % 4 != 0) - return; - - AxisAlignedBB axisalignedbb = null; - - if (this.ridingEntity != null && this.ridingEntity.isEntityAlive()){ - axisalignedbb = this.boundingBox.func_111270_a(this.ridingEntity.boundingBox).expand(1.0D, 0.0D, 1.0D); - } - else{ - axisalignedbb = this.boundingBox.expand(1.0D, 0.5D, 1.0D); - } - - List list = this.worldObj.getEntitiesWithinAABBExcludingEntity(this, axisalignedbb); - if(list == null) - return; - - if (!isRemote()) { - for (int i = 0; i < list.size(); ++i) { - Entity entity = (Entity) list.get(i); - if (entity.isEntityAlive()) { - EventHooks.onNPCCollide(this, entity); - } - } - } - - } - - - - @Override - public void setInPortal(){ - //prevent npcs from walking into portals - } - - public double field_20066_r; - public double field_20065_s; - public double field_20064_t; - public double field_20063_u; - public double field_20062_v; - public double field_20061_w; - - public void cloakUpdate() { - field_20066_r = field_20063_u; - field_20065_s = field_20062_v; - field_20064_t = field_20061_w; - double d = posX - field_20063_u; - double d1 = posY - field_20062_v; - double d2 = posZ - field_20061_w; - double d3 = 10D; - if (d > d3) { - field_20066_r = field_20063_u = posX; - } - if (d2 > d3) { - field_20064_t = field_20061_w = posZ; - } - if (d1 > d3) { - field_20065_s = field_20062_v = posY; - } - if (d < -d3) { - field_20066_r = field_20063_u = posX; - } - if (d2 < -d3) { - field_20064_t = field_20061_w = posZ; - } - if (d1 < -d3) { - field_20065_s = field_20062_v = posY; - } - field_20063_u += d * 0.25D; - field_20061_w += d2 * 0.25D; - field_20062_v += d1 * 0.25D; - } - - @Override - protected boolean canDespawn() { - return stats.canDespawn; - } - - @Override - public ItemStack getHeldItem() { - if (isAttacking()) - return inventory.getWeapon(); - else if(advanced.role == EnumRoleType.Companion) - return ((RoleCompanion)roleInterface).getHeldItem(); - else if (jobInterface != null && jobInterface.overrideMainHand) - return jobInterface.mainhand; - else - return inventory.getWeapon(); - } - - @Override - public ItemStack getEquipmentInSlot(int slot){ - if(slot == 0) - return inventory.weapons.get(0); - return inventory.armorItemInSlot(4 - slot); - } - - @Override - public ItemStack func_130225_q(int slot){ - return inventory.armorItemInSlot(3 - slot); - } - - @Override - public void setCurrentItemOrArmor(int slot, ItemStack item){ - if(slot == 0) - inventory.setWeapon(item); - else{ - inventory.armor.put(4 - slot, item); - } - } - private static final ItemStack[] lastActive = new ItemStack[5]; - @Override - public ItemStack[] getLastActiveItems(){ - return lastActive; - } - - @Override - protected void dropEquipment(boolean p_82160_1_, int p_82160_2_){ - - } - - public ItemStack getOffHand() { - if (isAttacking()) - return inventory.getOffHand(); - else if (jobInterface != null && jobInterface.overrideOffHand) - return jobInterface.offhand; - else - return inventory.getOffHand(); - } - - @Override - public void onDeath(DamageSource damagesource){ - setSprinting(false); - getNavigator().clearPathEntity(); - extinguish(); - clearActivePotions(); - - Entity entity = damagesource.getEntity(); - - EntityLivingBase attackingEntity = null; - - if (entity instanceof EntityLivingBase) - attackingEntity = (EntityLivingBase) entity; - - if ((entity instanceof EntityArrow) && ((EntityArrow) entity).shootingEntity instanceof EntityLivingBase) - attackingEntity = (EntityLivingBase) ((EntityArrow) entity).shootingEntity; - else if ((entity instanceof EntityThrowable)) - attackingEntity = ((EntityThrowable) entity).getThrower(); - - - int droppedXp = inventory.getDroppedXp(); - ArrayList droppedItems = inventory.getDroppedItems(damagesource); - - if(!isRemote()){ - NpcEvent.DiedEvent event = new NpcEvent.DiedEvent(this.wrappedNPC,damagesource,entity,droppedItems, droppedXp); - if(EventHooks.onNPCKilled(this, event)) - return; - - droppedItems.clear(); - for (IItemStack iItemStack : event.droppedItems) { - droppedItems.add(iItemStack.getMCItemStack()); - } - droppedXp = event.expDropped; - - if(this.recentlyHit > 0) { - inventory.dropItems(entity, droppedItems); - inventory.dropXp(entity, droppedXp); - } - Line line = advanced.getKilledLine(); - if(line != null) - saySurrounding(line.formatTarget(attackingEntity)); - } - super.onDeath(damagesource); - } - - @Override - public void setDead() { - hasDied = true; - if(worldObj.isRemote || stats.spawnCycle == 3){ - this.spawnExplosionParticle(); - delete(); - } - else { - if(this.riddenByEntity != null) - this.riddenByEntity.mountEntity(null); - if(this.ridingEntity != null) - this.mountEntity(null); - setHealth(-1); - setSprinting(false); - getNavigator().clearPathEntity(); - if(killedtime <= 0) - killedtime = stats.respawnTime * 1000 + System.currentTimeMillis(); - - if (advanced.role != EnumRoleType.None && roleInterface != null) - roleInterface.killed(); - if (advanced.job != EnumJobType.None && jobInterface != null) - jobInterface.killed(); - } - } - - public void delete() { - if (advanced.role != EnumRoleType.None && roleInterface != null) - roleInterface.delete(); - if (advanced.job != EnumJobType.None && jobInterface != null) - jobInterface.delete(); - super.setDead(); - } - - public float getStartXPos(){ - - return getStartPos()[0] + ais.bodyOffsetX / 10; - } - - public float getStartZPos(){ - return getStartPos()[2] + ais.bodyOffsetZ / 10; - } - - public int[] getStartPos(){ - if(ais.startPos == null || ais.startPos.length != 3) - ais.startPos = new int[] { - MathHelper.floor_double(posX), - MathHelper.floor_double(posY), - MathHelper.floor_double(posZ) }; - return ais.startPos; - } - - public boolean isVeryNearAssignedPlace() { - double xx = posX - getStartXPos(); - double zz = posZ - getStartZPos(); - if (xx < -0.2 || xx > 0.2) - return false; - if (zz < -0.2 || zz > 0.2) - return false; - return true; - } - - @Override - public IIcon getItemIcon(ItemStack par1ItemStack, int par2){ - if (par1ItemStack.getItem() instanceof ItemBow){ - return par1ItemStack.getItem().getIcon(par1ItemStack, par2); - } - EntityPlayer player = CustomNpcs.proxy.getPlayer(); - if(player == null) - return super.getItemIcon(par1ItemStack, par2); - return player.getItemIcon(par1ItemStack, par2); - } - - public double getStartYPos() { - int i = getStartPos()[0]; - int j = getStartPos()[1]; - int k = getStartPos()[2]; - double yy = 0; - for (int ii = j; ii >= 0; ii--) { - if (this.canFly()) { - if (ii < j - 1) { - yy = j; - break; - } - Block block = worldObj.getBlock(i, ii, k); - AxisAlignedBB bb = block.getCollisionBoundingBoxFromPool(worldObj, i, ii, k); - if (bb != null) { - yy = bb.maxY; - break; - } - } else { - Block block = worldObj.getBlock(i, ii, k); - if (block == null || block == Blocks.air) - continue; - AxisAlignedBB bb = block.getCollisionBoundingBoxFromPool(worldObj, i, ii, k); - if (bb == null) - continue; - yy = bb.maxY; - break; - } - } - if (yy <= 0) - setDead(); - return yy; - } - - public void givePlayerItem(EntityPlayer player, ItemStack item) { - if (worldObj.isRemote) { - return; - } - item = item.copy(); - float f = 0.7F; - double d = (double) (worldObj.rand.nextFloat() * f) - + (double) (1.0F - f); - double d1 = (double) (worldObj.rand.nextFloat() * f) - + (double) (1.0F - f); - double d2 = (double) (worldObj.rand.nextFloat() * f) - + (double) (1.0F - f); - EntityItem entityitem = new EntityItem(worldObj, posX + d, posY + d1, - posZ + d2, item); - entityitem.delayBeforeCanPickup = 2; - worldObj.spawnEntityInWorld(entityitem); - - int i = item.stackSize; - - if (player.inventory.addItemStackToInventory(item)) { - worldObj.playSoundAtEntity( - entityitem, - "random.pop", - 0.2F, - ((rand.nextFloat() - rand.nextFloat()) * 0.7F + 1.0F) * 2.0F); - player.onItemPickup(entityitem, i); - - if (item.stackSize <= 0) { - entityitem.setDead(); - } - } - } - - @Override - public boolean isPlayerSleeping() { - return currentAnimation == EnumAnimation.LYING && !isAttacking(); - } - - @Override - public boolean isRiding() { - return currentAnimation == EnumAnimation.SITTING && !isAttacking() || ridingEntity != null; - } - - public boolean isWalking() { - return ais.movingType != EnumMovingType.Standing || isAttacking() || isFollower() || getBoolFlag(1); - } - - public void setBoolFlag(boolean bo, int id){ - int i = dataWatcher.getWatchableObjectInt(15); - if(bo && (i & id) == 0) - dataWatcher.updateObject(15, i | id); - if(!bo && (i & id) != 0) - dataWatcher.updateObject(15, i - id); - } - - /** - * 1: walking, 2:interacting, 4:attacking, 8:killed - */ - public boolean getBoolFlag(int id){ - return (dataWatcher.getWatchableObjectInt(15) & id) != 0; - } - - @Override - public boolean isSneaking() { - return currentAnimation == EnumAnimation.SNEAKING; - } - @Override - public void knockBack(Entity par1Entity, float par2, double par3, double par5) - { - if(stats.resistances.knockback >= 2) - return; - this.isAirBorne = true; - float f1 = MathHelper.sqrt_double(par3 * par3 + par5 * par5); - float f2 = 0.5F * (2 - stats.resistances.knockback); - this.motionX /= 2.0D; - this.motionY /= 2.0D; - this.motionZ /= 2.0D; - this.motionX -= par3 / (double)f1 * (double)f2; - this.motionY += 0.2 + f2 / 2; - this.motionZ -= par5 / (double)f1 * (double)f2; - - if (this.motionY > 0.4000000059604645D) - { - this.motionY = 0.4000000059604645D; - } - } - - @Override - public void addVelocity(double p_70024_1_, double p_70024_3_, double p_70024_5_) { - if (this.attackingPlayer != null) { - float f2 = 0.5F * (2 - stats.resistances.knockback); - super.addVelocity(p_70024_1_ * (double)f2,p_70024_3_ * (double)f2,p_70024_5_ * (double)f2); - } else { - super.addVelocity(p_70024_1_,p_70024_3_,p_70024_5_); - } - } - - public Faction getFaction() { - String[] split = dataWatcher.getWatchableObjectString(13).split(":"); - int faction = 0; - if(worldObj == null || split.length <= 1 && worldObj.isRemote) - return new Faction(); - if(split.length > 1) - faction = Integer.parseInt(split[0]); - if(worldObj.isRemote){ - Faction fac = new Faction(); - fac.id = faction; - fac.color = Integer.parseInt(split[1]); - fac.name = split[2]; - return fac; - } - else{ - Faction fac = FactionController.getInstance().get(faction); - if (fac == null) { - faction = FactionController.getInstance().getFirstFactionId(); - fac = FactionController.getInstance().get(faction); - } - return fac; - } - } - public boolean isRemote(){ - return worldObj == null || worldObj.isRemote; - } - public void setFaction(int integer) { - if(integer < 0|| isRemote()) - return; - Faction faction = FactionController.getInstance().get(integer); - if(faction == null) - return; - String str = faction.id + ":" + faction.color + ":" + faction.name; - if(str.length() > 64) - str = str.substring(0, 64); - dataWatcher.updateObject(13, str); - } - - @Override - public boolean isPotionApplicable(PotionEffect effect){ - if(stats.potionImmune) - return false; - if(getCreatureAttribute() == EnumCreatureAttribute.ARTHROPOD && effect.getPotionID() == Potion.poison.id) - return false; - return super.isPotionApplicable(effect); - } - - public boolean isAttacking() { - return getBoolFlag(4); - } - - public boolean isKilled() { - return getBoolFlag(8) || isDead; - } - - @Override - public void writeSpawnData(ByteBuf buffer) { - try { - ByteBufUtils.writeNBT(buffer, writeSpawnData()); - } catch (IOException e) { - e.printStackTrace(); - } - } - - public NBTTagCompound writeSpawnData() { - NBTTagCompound compound = new NBTTagCompound(); - display.writeToNBT(compound); - compound.setDouble("MaxHealth", stats.maxHealth); - compound.setTag("Armor", NBTTags.nbtItemStackList(inventory.getArmor())); - compound.setTag("Weapons", NBTTags.nbtItemStackList(inventory.getWeapons())); - compound.setInteger("Speed", ais.getWalkingSpeed()); - compound.setBoolean("DeadBody", stats.hideKilledBody); - compound.setInteger("StandingState", ais.standingType.ordinal()); - compound.setInteger("MovingState", ais.movingType.ordinal()); - compound.setInteger("Orientation", ais.orientation); - compound.setFloat("OffsetY", ais.bodyOffsetY); - compound.setInteger("Role", advanced.role.ordinal()); - compound.setInteger("Job", advanced.job.ordinal()); - if(advanced.job == EnumJobType.Bard){ - NBTTagCompound bard = new NBTTagCompound(); - jobInterface.writeToNBT(bard); - compound.setTag("Bard", bard); - } - if(advanced.role == EnumRoleType.Companion){ - NBTTagCompound bard = new NBTTagCompound(); - roleInterface.writeToNBT(bard); - compound.setTag("Companion", bard); - } - - if(this instanceof EntityCustomNpc){ - compound.setTag("ModelData", ((EntityCustomNpc)this).modelData.writeToNBT()); - } - return compound; - } - @Override - public void readSpawnData(ByteBuf buf) { - try { - readSpawnData(ByteBufUtils.readNBT(buf)); - } catch (IOException e) { - } - } - public void readSpawnData(NBTTagCompound compound) { - stats.maxHealth = compound.getDouble("MaxHealth"); - ais.setWalkingSpeed(compound.getInteger("Speed")); - stats.hideKilledBody = compound.getBoolean("DeadBody"); - ais.standingType = EnumStandingType.values()[compound.getInteger("StandingState") % EnumStandingType.values().length]; - ais.movingType = EnumMovingType.values()[compound.getInteger("MovingState") % EnumMovingType.values().length]; - ais.orientation = compound.getInteger("Orientation"); - ais.bodyOffsetY=compound.getFloat("OffsetY"); - - this.getEntityAttribute(SharedMonsterAttributes.maxHealth).setBaseValue(stats.maxHealth); - inventory.setArmor(NBTTags.getItemStackList(compound.getTagList("Armor", 10))); - inventory.setWeapons(NBTTags.getItemStackList(compound.getTagList("Weapons", 10))); - advanced.setRole(compound.getInteger("Role")); - advanced.setJob(compound.getInteger("Job")); - if(advanced.job == EnumJobType.Bard){ - NBTTagCompound bard = compound.getCompoundTag("Bard"); - jobInterface.readFromNBT(bard); - } - if(advanced.role == EnumRoleType.Companion){ - NBTTagCompound companion = compound.getCompoundTag("Companion"); - roleInterface.readFromNBT(companion); - } - if(this instanceof EntityCustomNpc){ - ((EntityCustomNpc)this).modelData.readFromNBT(compound.getCompoundTag("ModelData")); - } - display.readToNBT(compound); - } - - @Override - public String getCommandSenderName() { - return display.name; - } - - @Override - public boolean canCommandSenderUseCommand(int var1, String var2) { - if(ConfigMain.NpcUseOpCommands) - return true; - return var1 <= 2; - } - - @Override - public ChunkCoordinates getPlayerCoordinates() { - return new ChunkCoordinates(MathHelper.floor_double(posX), MathHelper.floor_double(posY), MathHelper.floor_double(posZ)); - } - - @Override - public boolean canAttackClass(Class par1Class) - { - return EntityBat.class != par1Class; - } - public void setImmuneToFire(boolean immuneToFire) { - this.isImmuneToFire = immuneToFire; - stats.immuneToFire = immuneToFire; - } - - public boolean handleLavaMovement() - { - return !stats.immuneToFire && super.handleLavaMovement(); - } - - public boolean handleWaterMovement() - { - if (stats.drowningType != 1) { - if (this.worldObj.handleMaterialAcceleration(this.boundingBox.expand(0.0D, -this.height/2.0D, 0.0D).contract(0.001D, 0.001D, 0.001D), Material.water, this)) { - this.fallDistance = 0.0F; - this.inWater = true; - this.setFire(0); - } else { - this.inWater = false; - } - return false; - } else { - return super.handleWaterMovement(); - } - } - - public boolean canBreatheUnderwater() - { - return stats.drowningType != 1; - } - - public void setAvoidWater(boolean avoidWater) { - this.getNavigator().setAvoidsWater(avoidWater); - ais.avoidsWater = avoidWater; - } - @Override - protected void fall(float par1) { - if (!this.stats.noFallDamage) - super.fall(par1); - } - @Override - public void setInWeb(){ - if(!stats.ignoreCobweb) - super.setInWeb(); - } - - public boolean isInRange(Entity entity, double range){ - return this.isInRange(entity.posX, entity.posY, entity.posZ, range); - } - - public boolean isInRange(double posX, double posY, double posZ, double range){ - double y = Math.abs(this.posY - posY); - if(posY >= 0 && y > range) - return false; - - double x = Math.abs(this.posX - posX); - double z = Math.abs(this.posZ - posZ); - - return x <= range && z <= range; - } - - @Override - public boolean canBeCollidedWith(){ - return !isKilled(); - } - - @Override - public boolean canBePushed() { - return this.stats.collidesWith == 0; - } - - // checks for any entity within a certain boundingbox, eg minecarts - @Override - protected void collideWithNearbyEntities() { - if(this.stats.collidesWith != 1) { - List list = this.worldObj.getEntitiesWithinAABBExcludingEntity(this, this.boundingBox.expand(0.20000000298023224D, 0.0D, 0.20000000298023224D)); - - if (list != null && !list.isEmpty()) { - for (int i = 0; i < list.size(); ++i) { - Entity entity = (Entity) list.get(i); - - if (this.canBePushed() || - (entity instanceof EntityNPCInterface && (this.stats.collidesWith == 2 || this.stats.collidesWith == 4)) || - (entity instanceof EntityPlayerMP && (this.stats.collidesWith == 3 || this.stats.collidesWith == 4)) - ) { - super.collideWithEntity(entity); - } - } - } - } - } - - public void applyEntityCollision(Entity entity) - { - if (entity.riddenByEntity != this && entity.ridingEntity != this) - { - double d0 = entity.posX - this.posX; - double d1 = entity.posZ - this.posZ; - double d2 = MathHelper.abs_max(d0, d1); - - if (d2 >= 0.009999999776482582D) - { - d2 = (double)MathHelper.sqrt_double(d2); - d0 /= d2; - d1 /= d2; - double d3 = 1.0D / d2; - - if (d3 > 1.0D) - { - d3 = 1.0D; - } - - d0 *= d3; - d1 *= d3; - d0 *= 0.05000000074505806D; - d1 *= 0.05000000074505806D; - d0 *= (double)(1.0F - this.entityCollisionReduction); - d1 *= (double)(1.0F - this.entityCollisionReduction); - if (this.canBePushed() || - (entity instanceof EntityNPCInterface && (this.stats.collidesWith == 2 || this.stats.collidesWith == 4)) || - (entity instanceof EntityPlayerMP && (this.stats.collidesWith == 3 || this.stats.collidesWith == 4)) - ) - this.addVelocity(-d0, 0.0D, -d1); - entity.addVelocity(d0, 0.0D, d1); - } - } - } - - // not any entity can collide. if you want projectiles to still be - // effective, you will have to handle those yourself - @Override - protected void collideWithEntity(Entity p_82167_1_) { - - } - - public boolean canFly(){ - return false; - } - - public EntityAIRangedAttack getRangedTask(){ - return this.aiRange; - } - - public String getRoleDataWatcher(){ - return dataWatcher.getWatchableObjectString(16); - } - - public void setRoleDataWatcher(String s){ - dataWatcher.updateObject(16, s); - } - - @Override - public World getEntityWorld() { - return worldObj; - } - - @Override - public boolean isInvisibleToPlayer(EntityPlayer player){ - return (scriptInvisibleToPlayer(player) || display.visible == 1) && (player.getHeldItem() == null || player.getHeldItem().getItem() != CustomItems.wand); - } - - public boolean scriptInvisibleToPlayer(EntityPlayer player){ - if(FMLCommonHandler.instance().getEffectiveSide() == Side.CLIENT){ + if (isKilled() && stats.hideKilledBody) { + width = 0.00001f; + } + if (width / 2 > worldObj.MAX_ENTITY_RADIUS) { + worldObj.MAX_ENTITY_RADIUS = width / 2; + } + this.setPosition(posX, posY, posZ); + } + + @Override + public void onDeathUpdate() { + if (stats.spawnCycle == 3) { + super.onDeathUpdate(); + return; + } + + ++this.deathTime; + if (worldObj.isRemote) + return; + if (!hasDied) { + setDead(); + } + if (killedtime < System.currentTimeMillis()) { + if (stats.spawnCycle == 0 || (this.worldObj.isDaytime() && stats.spawnCycle == 1) || (!this.worldObj.isDaytime() && stats.spawnCycle == 2)) { + reset(); + } + } + } + + public void reset() { + hasDied = false; + isDead = false; + wasKilled = false; + setSprinting(false); + setHealth(getMaxHealth()); + dataWatcher.updateObject(14, 0); // animation Normal + dataWatcher.updateObject(15, 0); + actionManager.clear(); + combatHandler.reset(); + this.setAttackTarget(null); + this.setRevengeTarget(null); + this.deathTime = 0; + //fleeingTick = 0; + if (ais.returnToStart && !hasOwner() && !this.isRemote()) + setLocationAndAngles(getStartXPos(), getStartYPos(), getStartZPos(), rotationYaw, rotationPitch); + killedtime = 0; + extinguish(); + this.clearActivePotions(); + getNavigator().clearPathEntity(); + if (this.canFly()) { + ((PathNavigateFlying) getNavigator()).targetPos = null; + ((PathNavigateFlying) getNavigator()).clearPathEntity(); + ((FlyingMoveHelper) getMoveHelper()).update = false; + } + moveEntityWithHeading(0, 0); + distanceWalkedModified = 0; + currentAnimation = EnumAnimation.NONE; + updateHitbox(); + updateAI = true; + ais.movingPos = 0; + if (getOwner() != null) { + getOwner().setLastAttacker(null); + } + + if (jobInterface != null) + jobInterface.reset(); + + if (!isRemote()) { + EventHooks.onNPCInit(this); + } + } + + public void onCollide() { + if (!isEntityAlive() || ticksExisted % 4 != 0) + return; + + AxisAlignedBB axisalignedbb = null; + + if (this.ridingEntity != null && this.ridingEntity.isEntityAlive()) { + axisalignedbb = this.boundingBox.func_111270_a(this.ridingEntity.boundingBox).expand(1.0D, 0.0D, 1.0D); + } else { + axisalignedbb = this.boundingBox.expand(1.0D, 0.5D, 1.0D); + } + + List list = this.worldObj.getEntitiesWithinAABBExcludingEntity(this, axisalignedbb); + if (list == null) + return; + + if (!isRemote()) { + for (int i = 0; i < list.size(); ++i) { + Entity entity = (Entity) list.get(i); + if (entity.isEntityAlive()) { + EventHooks.onNPCCollide(this, entity); + } + } + } + } + + @Override + public void setInPortal() { + //prevent npcs from walking into portals + } + + public double field_20066_r; + public double field_20065_s; + public double field_20064_t; + public double field_20063_u; + public double field_20062_v; + public double field_20061_w; + + public void cloakUpdate() { + field_20066_r = field_20063_u; + field_20065_s = field_20062_v; + field_20064_t = field_20061_w; + double d = posX - field_20063_u; + double d1 = posY - field_20062_v; + double d2 = posZ - field_20061_w; + double d3 = 10D; + if (d > d3) { + field_20066_r = field_20063_u = posX; + } + if (d2 > d3) { + field_20064_t = field_20061_w = posZ; + } + if (d1 > d3) { + field_20065_s = field_20062_v = posY; + } + if (d < -d3) { + field_20066_r = field_20063_u = posX; + } + if (d2 < -d3) { + field_20064_t = field_20061_w = posZ; + } + if (d1 < -d3) { + field_20065_s = field_20062_v = posY; + } + field_20063_u += d * 0.25D; + field_20061_w += d2 * 0.25D; + field_20062_v += d1 * 0.25D; + } + + @Override + protected boolean canDespawn() { + return stats.canDespawn; + } + + @Override + public ItemStack getHeldItem() { + if (isAttacking()) + return inventory.getWeapon(); + else if (advanced.role == EnumRoleType.Companion) + return ((RoleCompanion) roleInterface).getHeldItem(); + else if (jobInterface != null && jobInterface.overrideMainHand) + return jobInterface.mainhand; + else + return inventory.getWeapon(); + } + + @Override + public ItemStack getEquipmentInSlot(int slot) { + if (slot == 0) + return inventory.weapons.get(0); + return inventory.armorItemInSlot(4 - slot); + } + + @Override + public ItemStack func_130225_q(int slot) { + return inventory.armorItemInSlot(3 - slot); + } + + @Override + public void setCurrentItemOrArmor(int slot, ItemStack item) { + if (slot == 0) + inventory.setWeapon(item); + else { + inventory.armor.put(4 - slot, item); + } + } + + private static final ItemStack[] lastActive = new ItemStack[5]; + + @Override + public ItemStack[] getLastActiveItems() { + return lastActive; + } + + @Override + protected void dropEquipment(boolean p_82160_1_, int p_82160_2_) { + + } + + public ItemStack getOffHand() { + if (isAttacking()) + return inventory.getOffHand(); + else if (jobInterface != null && jobInterface.overrideOffHand) + return jobInterface.offhand; + else + return inventory.getOffHand(); + } + + @Override + public void onDeath(DamageSource damagesource) { + setSprinting(false); + getNavigator().clearPathEntity(); + extinguish(); + clearActivePotions(); + + Entity entity = damagesource.getEntity(); + + EntityLivingBase attackingEntity = null; + + if (entity instanceof EntityLivingBase) + attackingEntity = (EntityLivingBase) entity; + + if ((entity instanceof EntityArrow) && ((EntityArrow) entity).shootingEntity instanceof EntityLivingBase) + attackingEntity = (EntityLivingBase) ((EntityArrow) entity).shootingEntity; + else if ((entity instanceof EntityThrowable)) + attackingEntity = ((EntityThrowable) entity).getThrower(); + + + int droppedXp = inventory.getDroppedXp(); + ArrayList droppedItems = inventory.getDroppedItems(damagesource); + + if (!isRemote()) { + NpcEvent.DiedEvent event = new NpcEvent.DiedEvent(this.wrappedNPC, damagesource, entity, droppedItems, droppedXp); + if (EventHooks.onNPCKilled(this, event)) + return; + + droppedItems.clear(); + for (IItemStack iItemStack : event.droppedItems) { + droppedItems.add(iItemStack.getMCItemStack()); + } + droppedXp = event.expDropped; + + if (this.recentlyHit > 0) { + inventory.dropItems(entity, droppedItems); + inventory.dropXp(entity, droppedXp); + } + Line line = advanced.getKilledLine(); + if (line != null) + saySurrounding(line.formatTarget(attackingEntity)); + } + super.onDeath(damagesource); + } + + @Override + public void setDead() { + hasDied = true; + if (worldObj.isRemote || stats.spawnCycle == 3) { + this.spawnExplosionParticle(); + delete(); + } else { + if (this.riddenByEntity != null) + this.riddenByEntity.mountEntity(null); + if (this.ridingEntity != null) + this.mountEntity(null); + setHealth(-1); + setSprinting(false); + getNavigator().clearPathEntity(); + if (killedtime <= 0) + killedtime = stats.respawnTime * 1000 + System.currentTimeMillis(); + + if (advanced.role != EnumRoleType.None && roleInterface != null) + roleInterface.killed(); + if (advanced.job != EnumJobType.None && jobInterface != null) + jobInterface.killed(); + } + } + + public void delete() { + if (advanced.role != EnumRoleType.None && roleInterface != null) + roleInterface.delete(); + if (advanced.job != EnumJobType.None && jobInterface != null) + jobInterface.delete(); + super.setDead(); + } + + public float getStartXPos() { + + return getStartPos()[0] + ais.bodyOffsetX / 10; + } + + public float getStartZPos() { + return getStartPos()[2] + ais.bodyOffsetZ / 10; + } + + public int[] getStartPos() { + if (ais.startPos == null || ais.startPos.length != 3) + ais.startPos = new int[]{MathHelper.floor_double(posX), MathHelper.floor_double(posY), MathHelper.floor_double(posZ)}; + return ais.startPos; + } + + public boolean isVeryNearAssignedPlace() { + double xx = posX - getStartXPos(); + double zz = posZ - getStartZPos(); + if (xx < -0.2 || xx > 0.2) + return false; + if (zz < -0.2 || zz > 0.2) + return false; + return true; + } + + @Override + public IIcon getItemIcon(ItemStack par1ItemStack, int par2) { + if (par1ItemStack.getItem() instanceof ItemBow) { + return par1ItemStack.getItem().getIcon(par1ItemStack, par2); + } + EntityPlayer player = CustomNpcs.proxy.getPlayer(); + if (player == null) + return super.getItemIcon(par1ItemStack, par2); + return player.getItemIcon(par1ItemStack, par2); + } + + public double getStartYPos() { + int i = getStartPos()[0]; + int j = getStartPos()[1]; + int k = getStartPos()[2]; + double yy = 0; + for (int ii = j; ii >= 0; ii--) { + if (this.canFly()) { + if (ii < j - 1) { + yy = j; + break; + } + Block block = worldObj.getBlock(i, ii, k); + AxisAlignedBB bb = block.getCollisionBoundingBoxFromPool(worldObj, i, ii, k); + if (bb != null) { + yy = bb.maxY; + break; + } + } else { + Block block = worldObj.getBlock(i, ii, k); + if (block == null || block == Blocks.air) + continue; + AxisAlignedBB bb = block.getCollisionBoundingBoxFromPool(worldObj, i, ii, k); + if (bb == null) + continue; + yy = bb.maxY; + break; + } + } + if (yy <= 0) + setDead(); + return yy; + } + + public void givePlayerItem(EntityPlayer player, ItemStack item) { + if (worldObj.isRemote) { + return; + } + item = item.copy(); + float f = 0.7F; + double d = (double) (worldObj.rand.nextFloat() * f) + (double) (1.0F - f); + double d1 = (double) (worldObj.rand.nextFloat() * f) + (double) (1.0F - f); + double d2 = (double) (worldObj.rand.nextFloat() * f) + (double) (1.0F - f); + EntityItem entityitem = new EntityItem(worldObj, posX + d, posY + d1, posZ + d2, item); + entityitem.delayBeforeCanPickup = 2; + worldObj.spawnEntityInWorld(entityitem); + + int i = item.stackSize; + + if (player.inventory.addItemStackToInventory(item)) { + worldObj.playSoundAtEntity(entityitem, "random.pop", 0.2F, ((rand.nextFloat() - rand.nextFloat()) * 0.7F + 1.0F) * 2.0F); + player.onItemPickup(entityitem, i); + + if (item.stackSize <= 0) { + entityitem.setDead(); + } + } + } + + @Override + public boolean isPlayerSleeping() { + return currentAnimation == EnumAnimation.LYING && !isAttacking(); + } + + @Override + public boolean isRiding() { + return currentAnimation == EnumAnimation.SITTING && !isAttacking() || ridingEntity != null; + } + + public boolean isWalking() { + return ais.movingType != EnumMovingType.Standing || isAttacking() || isFollower() || getBoolFlag(1); + } + + public void setBoolFlag(boolean bo, int id) { + int i = dataWatcher.getWatchableObjectInt(15); + if (bo && (i & id) == 0) + dataWatcher.updateObject(15, i | id); + if (!bo && (i & id) != 0) + dataWatcher.updateObject(15, i - id); + } + + /** + * 1: walking, 2:interacting, 4:attacking, 8:killed + */ + public boolean getBoolFlag(int id) { + return (dataWatcher.getWatchableObjectInt(15) & id) != 0; + } + + @Override + public boolean isSneaking() { + return currentAnimation == EnumAnimation.SNEAKING; + } + + @Override + public void knockBack(Entity par1Entity, float par2, double par3, double par5) { + if (stats.resistances.knockback >= 2) + return; + this.isAirBorne = true; + float f1 = MathHelper.sqrt_double(par3 * par3 + par5 * par5); + float f2 = 0.5F * (2 - stats.resistances.knockback); + this.motionX /= 2.0D; + this.motionY /= 2.0D; + this.motionZ /= 2.0D; + this.motionX -= par3 / (double) f1 * (double) f2; + this.motionY += 0.2 + f2 / 2; + this.motionZ -= par5 / (double) f1 * (double) f2; + + if (this.motionY > 0.4000000059604645D) { + this.motionY = 0.4000000059604645D; + } + } + + @Override + public void addVelocity(double p_70024_1_, double p_70024_3_, double p_70024_5_) { + if (this.attackingPlayer != null) { + float f2 = 0.5F * (2 - stats.resistances.knockback); + super.addVelocity(p_70024_1_ * (double) f2, p_70024_3_ * (double) f2, p_70024_5_ * (double) f2); + } else { + super.addVelocity(p_70024_1_, p_70024_3_, p_70024_5_); + } + } + + public Faction getFaction() { + String[] split = dataWatcher.getWatchableObjectString(13).split(":"); + int faction = 0; + if (worldObj == null || split.length <= 1 && worldObj.isRemote) + return new Faction(); + if (split.length > 1) + faction = Integer.parseInt(split[0]); + if (worldObj.isRemote) { + Faction fac = new Faction(); + fac.id = faction; + fac.color = Integer.parseInt(split[1]); + fac.name = split[2]; + return fac; + } else { + Faction fac = FactionController.getInstance().get(faction); + if (fac == null) { + faction = FactionController.getInstance().getFirstFactionId(); + fac = FactionController.getInstance().get(faction); + } + return fac; + } + } + + public boolean isRemote() { + return worldObj == null || worldObj.isRemote; + } + + public void setFaction(int integer) { + if (integer < 0 || isRemote()) + return; + Faction faction = FactionController.getInstance().get(integer); + if (faction == null) + return; + String str = faction.id + ":" + faction.color + ":" + faction.name; + if (str.length() > 64) + str = str.substring(0, 64); + dataWatcher.updateObject(13, str); + } + + @Override + public boolean isPotionApplicable(PotionEffect effect) { + if (stats.potionImmune) + return false; + if (getCreatureAttribute() == EnumCreatureAttribute.ARTHROPOD && effect.getPotionID() == Potion.poison.id) + return false; + return super.isPotionApplicable(effect); + } + + public boolean isAttacking() { + return getBoolFlag(4); + } + + public boolean isKilled() { + return getBoolFlag(8) || isDead; + } + + @Override + public void writeSpawnData(ByteBuf buffer) { + try { + ByteBufUtils.writeNBT(buffer, writeSpawnData()); + } catch (IOException e) { + e.printStackTrace(); + } + } + + public NBTTagCompound writeSpawnData() { + NBTTagCompound compound = new NBTTagCompound(); + display.writeToNBT(compound); + compound.setDouble("MaxHealth", stats.maxHealth); + compound.setTag("Armor", NBTTags.nbtItemStackList(inventory.getArmor())); + compound.setTag("Weapons", NBTTags.nbtItemStackList(inventory.getWeapons())); + compound.setInteger("Speed", ais.getWalkingSpeed()); + compound.setBoolean("DeadBody", stats.hideKilledBody); + compound.setInteger("StandingState", ais.standingType.ordinal()); + compound.setInteger("MovingState", ais.movingType.ordinal()); + compound.setInteger("Orientation", ais.orientation); + compound.setFloat("OffsetY", ais.bodyOffsetY); + compound.setInteger("Role", advanced.role.ordinal()); + compound.setInteger("Job", advanced.job.ordinal()); + if (advanced.job == EnumJobType.Bard) { + NBTTagCompound bard = new NBTTagCompound(); + jobInterface.writeToNBT(bard); + compound.setTag("Bard", bard); + } + if (advanced.role == EnumRoleType.Companion) { + NBTTagCompound bard = new NBTTagCompound(); + roleInterface.writeToNBT(bard); + compound.setTag("Companion", bard); + } + + if (this instanceof EntityCustomNpc) { + compound.setTag("ModelData", ((EntityCustomNpc) this).modelData.writeToNBT()); + } + return compound; + } + + @Override + public void readSpawnData(ByteBuf buf) { + try { + readSpawnData(ByteBufUtils.readNBT(buf)); + } catch (IOException e) { + } + } + + public void readSpawnData(NBTTagCompound compound) { + stats.maxHealth = compound.getDouble("MaxHealth"); + ais.setWalkingSpeed(compound.getInteger("Speed")); + stats.hideKilledBody = compound.getBoolean("DeadBody"); + ais.standingType = EnumStandingType.values()[compound.getInteger("StandingState") % EnumStandingType.values().length]; + ais.movingType = EnumMovingType.values()[compound.getInteger("MovingState") % EnumMovingType.values().length]; + ais.orientation = compound.getInteger("Orientation"); + ais.bodyOffsetY = compound.getFloat("OffsetY"); + + this.getEntityAttribute(SharedMonsterAttributes.maxHealth).setBaseValue(stats.maxHealth); + inventory.setArmor(NBTTags.getItemStackList(compound.getTagList("Armor", 10))); + inventory.setWeapons(NBTTags.getItemStackList(compound.getTagList("Weapons", 10))); + advanced.setRole(compound.getInteger("Role")); + advanced.setJob(compound.getInteger("Job")); + if (advanced.job == EnumJobType.Bard) { + NBTTagCompound bard = compound.getCompoundTag("Bard"); + jobInterface.readFromNBT(bard); + } + if (advanced.role == EnumRoleType.Companion) { + NBTTagCompound companion = compound.getCompoundTag("Companion"); + roleInterface.readFromNBT(companion); + } + if (this instanceof EntityCustomNpc) { + ((EntityCustomNpc) this).modelData.readFromNBT(compound.getCompoundTag("ModelData")); + } + display.readToNBT(compound); + } + + @Override + public String getCommandSenderName() { + return display.name; + } + + @Override + public boolean canCommandSenderUseCommand(int var1, String var2) { + if (ConfigMain.NpcUseOpCommands) + return true; + return var1 <= 2; + } + + @Override + public ChunkCoordinates getPlayerCoordinates() { + return new ChunkCoordinates(MathHelper.floor_double(posX), MathHelper.floor_double(posY), MathHelper.floor_double(posZ)); + } + + @Override + public boolean canAttackClass(Class par1Class) { + return EntityBat.class != par1Class; + } + + public void setImmuneToFire(boolean immuneToFire) { + this.isImmuneToFire = immuneToFire; + stats.immuneToFire = immuneToFire; + } + + public boolean handleLavaMovement() { + return !stats.immuneToFire && super.handleLavaMovement(); + } + + public boolean handleWaterMovement() { + if (stats.drowningType != 1) { + if (this.worldObj.handleMaterialAcceleration(this.boundingBox.expand(0.0D, -this.height / 2.0D, 0.0D).contract(0.001D, 0.001D, 0.001D), Material.water, this)) { + this.fallDistance = 0.0F; + this.inWater = true; + this.setFire(0); + } else { + this.inWater = false; + } + return false; + } else { + return super.handleWaterMovement(); + } + } + + public boolean canBreatheUnderwater() { + return stats.drowningType != 1; + } + + public void setAvoidWater(boolean avoidWater) { + this.getNavigator().setAvoidsWater(avoidWater); + ais.avoidsWater = avoidWater; + } + + @Override + protected void fall(float par1) { + if (!this.stats.noFallDamage) + super.fall(par1); + } + + @Override + public void setInWeb() { + if (!stats.ignoreCobweb) + super.setInWeb(); + } + + public boolean isInRange(Entity entity, double range) { + return this.isInRange(entity.posX, entity.posY, entity.posZ, range); + } + + public boolean isInRange(double posX, double posY, double posZ, double range) { + double y = Math.abs(this.posY - posY); + if (posY >= 0 && y > range) + return false; + + double x = Math.abs(this.posX - posX); + double z = Math.abs(this.posZ - posZ); + + return x <= range && z <= range; + } + + @Override + public boolean canBeCollidedWith() { + return !isKilled(); + } + + @Override + public boolean canBePushed() { + return this.stats.collidesWith == 0; + } + + // checks for any entity within a certain boundingbox, eg minecarts + @Override + protected void collideWithNearbyEntities() { + if (this.stats.collidesWith != 1) { + List list = this.worldObj.getEntitiesWithinAABBExcludingEntity(this, this.boundingBox.expand(0.20000000298023224D, 0.0D, 0.20000000298023224D)); + + if (list != null && !list.isEmpty()) { + for (int i = 0; i < list.size(); ++i) { + Entity entity = (Entity) list.get(i); + + if (this.canBePushed() || (entity instanceof EntityNPCInterface && (this.stats.collidesWith == 2 || this.stats.collidesWith == 4)) || (entity instanceof EntityPlayerMP && (this.stats.collidesWith == 3 || this.stats.collidesWith == 4))) { + super.collideWithEntity(entity); + } + } + } + } + } + + public void applyEntityCollision(Entity entity) { + if (entity.riddenByEntity != this && entity.ridingEntity != this) { + double d0 = entity.posX - this.posX; + double d1 = entity.posZ - this.posZ; + double d2 = MathHelper.abs_max(d0, d1); + + if (d2 >= 0.009999999776482582D) { + d2 = (double) MathHelper.sqrt_double(d2); + d0 /= d2; + d1 /= d2; + double d3 = 1.0D / d2; + + if (d3 > 1.0D) { + d3 = 1.0D; + } + + d0 *= d3; + d1 *= d3; + d0 *= 0.05000000074505806D; + d1 *= 0.05000000074505806D; + d0 *= (double) (1.0F - this.entityCollisionReduction); + d1 *= (double) (1.0F - this.entityCollisionReduction); + if (this.canBePushed() || (entity instanceof EntityNPCInterface && (this.stats.collidesWith == 2 || this.stats.collidesWith == 4)) || (entity instanceof EntityPlayerMP && (this.stats.collidesWith == 3 || this.stats.collidesWith == 4))) + this.addVelocity(-d0, 0.0D, -d1); + entity.addVelocity(d0, 0.0D, d1); + } + } + } + + // not any entity can collide. if you want projectiles to still be + // effective, you will have to handle those yourself + @Override + protected void collideWithEntity(Entity p_82167_1_) { + + } + + public boolean canFly() { + return false; + } + + public EntityAIRangedAttack getRangedTask() { + return this.aiRange; + } + + public String getRoleDataWatcher() { + return dataWatcher.getWatchableObjectString(16); + } + + public void setRoleDataWatcher(String s) { + dataWatcher.updateObject(16, s); + } + + @Override + public World getEntityWorld() { + return worldObj; + } + + @Override + public boolean isInvisibleToPlayer(EntityPlayer player) { + return (scriptInvisibleToPlayer(player) || display.visible == 1) && (player.getHeldItem() == null || player.getHeldItem().getItem() != CustomItems.wand); + } + + public boolean scriptInvisibleToPlayer(EntityPlayer player) { + if (FMLCommonHandler.instance().getEffectiveSide() == Side.CLIENT) { return isInvisibleToClient(player); - }else { + } else { return display.invisibleToList != null && display.invisibleToList.contains(player.getPersistentID()); } - } + } @SideOnly(Side.CLIENT) - public boolean isInvisibleToClient(EntityPlayer player){ + public boolean isInvisibleToClient(EntityPlayer player) { return (player == Minecraft.getMinecraft().thePlayer ? display.isInvisibleToMe : display.getTempScriptInvisible(player.getEntityId())); } - @Override - public boolean isInvisible(){ - return display.visible != 0; - } + @Override + public boolean isInvisible() { + return display.visible != 0; + } - @Override - public void addChatMessage(IChatComponent var1) {} + @Override + public void addChatMessage(IChatComponent var1) { + } - public void setCurrentAnimation(EnumAnimation animation) { - currentAnimation = animation; - dataWatcher.updateObject(14, animation.ordinal()); - } + public void setCurrentAnimation(EnumAnimation animation) { + currentAnimation = animation; + dataWatcher.updateObject(14, animation.ordinal()); + } - public boolean canSee(Entity entity){ - return this.getEntitySenses().canSee(entity); - } + public boolean canSee(Entity entity) { + return this.getEntitySenses().canSee(entity); + } - public boolean isFollower() { - return advanced.role == EnumRoleType.Follower && ((RoleFollower) roleInterface).isFollowing() || - advanced.role == EnumRoleType.Companion && ((RoleCompanion) roleInterface).isFollowing() || - advanced.job == EnumJobType.Follower && ((JobFollower)jobInterface).isFollowing(); - } + public boolean isFollower() { + return advanced.role == EnumRoleType.Follower && ((RoleFollower) roleInterface).isFollowing() || advanced.role == EnumRoleType.Companion && ((RoleCompanion) roleInterface).isFollowing() || advanced.job == EnumJobType.Follower && ((JobFollower) jobInterface).isFollowing(); + } - public EntityLivingBase getOwner(){ - if(roleInterface instanceof RoleFollower) - return ((RoleFollower)roleInterface).owner; + public EntityLivingBase getOwner() { + if (roleInterface instanceof RoleFollower) + return ((RoleFollower) roleInterface).owner; - if(roleInterface instanceof RoleCompanion) - return ((RoleCompanion)roleInterface).owner; + if (roleInterface instanceof RoleCompanion) + return ((RoleCompanion) roleInterface).owner; - if(jobInterface instanceof JobFollower) - return ((JobFollower)jobInterface).following; + if (jobInterface instanceof JobFollower) + return ((JobFollower) jobInterface).following; - return null; - } + return null; + } - public boolean hasOwner(){ - return advanced.role == EnumRoleType.Follower && ((RoleFollower) roleInterface).hasOwner() || - advanced.role == EnumRoleType.Companion && ((RoleCompanion) roleInterface).hasOwner() || - advanced.job == EnumJobType.Follower && ((JobFollower)jobInterface).hasOwner(); - } + public boolean hasOwner() { + return advanced.role == EnumRoleType.Follower && ((RoleFollower) roleInterface).hasOwner() || advanced.role == EnumRoleType.Companion && ((RoleCompanion) roleInterface).hasOwner() || advanced.job == EnumJobType.Follower && ((JobFollower) jobInterface).hasOwner(); + } - public int followRange() { - if(advanced.role == EnumRoleType.Follower && ((RoleFollower) roleInterface).isFollowing()) - return 36; - if(advanced.role == EnumRoleType.Companion && ((RoleCompanion) roleInterface).isFollowing()) - return ((RoleCompanion) roleInterface).followRange(); - if(advanced.job == EnumJobType.Follower && ((JobFollower)jobInterface).isFollowing()) - return 16; + public int followRange() { + if (advanced.role == EnumRoleType.Follower && ((RoleFollower) roleInterface).isFollowing()) + return 36; + if (advanced.role == EnumRoleType.Companion && ((RoleCompanion) roleInterface).isFollowing()) + return ((RoleCompanion) roleInterface).followRange(); + if (advanced.job == EnumJobType.Follower && ((JobFollower) jobInterface).isFollowing()) + return 16; - return 225; - } + return 225; + } - @Override - public void setHomeArea(int x, int y, int z, int range){ - super.setHomeArea(x, y, z, range); - ais.startPos = new int[]{x, y, z}; - } + @Override + public void setHomeArea(int x, int y, int z, int range) { + super.setHomeArea(x, y, z, range); + ais.startPos = new int[]{x, y, z}; + } - @Override - protected float applyArmorCalculations(DamageSource source, float damage){ - if(advanced.role == EnumRoleType.Companion) - damage = ((RoleCompanion)roleInterface).applyArmorCalculations(source, damage); - return damage; - } + @Override + protected float applyArmorCalculations(DamageSource source, float damage) { + if (advanced.role == EnumRoleType.Companion) + damage = ((RoleCompanion) roleInterface).applyArmorCalculations(source, damage); + return damage; + } - @Override - public boolean isOnSameTeam(EntityLivingBase entity){ - if(entity instanceof EntityPlayer && !isRemote() && getFaction().isFriendlyToPlayer((EntityPlayer)entity)) - return true; - return super.isOnSameTeam(entity); - } + @Override + public boolean isOnSameTeam(EntityLivingBase entity) { + if (entity instanceof EntityPlayer && !isRemote() && getFaction().isFriendlyToPlayer((EntityPlayer) entity)) + return true; + return super.isOnSameTeam(entity); + } - public void setDataWatcher(DataWatcher dataWatcher) { - this.dataWatcher = dataWatcher; - } + public void setDataWatcher(DataWatcher dataWatcher) { + this.dataWatcher = dataWatcher; + } - @Override - public void moveEntityWithHeading(float p_70612_1_, float p_70612_2_){ - double d0 = this.posX; - double d1 = this.posY; - double d2 = this.posZ; - super.moveEntityWithHeading(p_70612_1_, p_70612_2_); - if(advanced.role == EnumRoleType.Companion && !isRemote()) - ((RoleCompanion)roleInterface).addMovementStat(this.posX - d0, this.posY - d1, this.posZ - d2); - } + @Override + public void moveEntityWithHeading(float p_70612_1_, float p_70612_2_) { + double d0 = this.posX; + double d1 = this.posY; + double d2 = this.posZ; + super.moveEntityWithHeading(p_70612_1_, p_70612_2_); + if (advanced.role == EnumRoleType.Companion && !isRemote()) + ((RoleCompanion) roleInterface).addMovementStat(this.posX - d0, this.posY - d1, this.posZ - d2); + } - @Override - public boolean allowLeashing(){ - return false; - } + @Override + public boolean allowLeashing() { + return false; + } - @Override - public boolean shouldDismountInWater(Entity rider){ - return false; - } + @Override + public boolean shouldDismountInWater(Entity rider) { + return false; + } - // Model Types: 0: Steve 64x32, 1: Steve 64x64, 2: Alex 64x64 - public int getModelType() - { - return this.display.modelType; - } + // Model Types: 0: Steve 64x32, 1: Steve 64x64, 2: Alex 64x64 + public int getModelType() { + return this.display.modelType; + } - public void setModelType(int val) - { - this.display.modelType = val; - } + public void setModelType(int val) { + this.display.modelType = val; + } - protected void updateLeashedState(){} + protected void updateLeashedState() { + } } diff --git a/src/main/java/noppes/npcs/scripted/ScriptedActionManager.java b/src/main/java/noppes/npcs/scripted/ScriptedActionManager.java new file mode 100644 index 000000000..426497c37 --- /dev/null +++ b/src/main/java/noppes/npcs/scripted/ScriptedActionManager.java @@ -0,0 +1,188 @@ +package noppes.npcs.scripted; + +import noppes.npcs.api.IAction; +import noppes.npcs.api.IActionManager; + +import java.util.HashMap; +import java.util.LinkedList; +import java.util.Queue; +import java.util.function.Consumer; + +public class ScriptedActionManager implements IActionManager { + private boolean isWorking; + private Queue actionQueue = new LinkedList<>(); + + @Override + public IAction createAction(String name, int maxDuration, int startAfterTicks, Consumer action) { + return new CustomAction(name, maxDuration, startAfterTicks, action); + } + + @Override + public void start() { + isWorking = true; + } + + @Override + public void stop() { + isWorking = false; + } + + @Override + public void addScheduledAction(IAction action) { + actionQueue.add(action); + } + + @Override + public void addScheduledAction(String name, int maxDuration, int startAfterTicks, Consumer action) { + addScheduledAction(createAction(name, maxDuration, startAfterTicks, action)); + } + + @Override + public void addScheduledActionAt(int index, IAction action) { + ((LinkedList) actionQueue).add(index, action); + } + + @Override + public void scheduleActionAfter(IAction after, IAction toSchedule) { + int index = getActionIndex(after); + if (index != -1) + addScheduledActionAt(index + 1, toSchedule); + } + + @Override + public int getActionIndex(IAction action) { + if (action == null) + return -1; + return ((LinkedList) actionQueue).indexOf(action); + } + + @Override + public IAction getCurrentAction() { + return actionQueue.peek(); + } + + @Override + public Queue getActionQueue() { + return actionQueue; + } + + public void clear(){ + actionQueue.clear(); + } + public void tick(int ticksExisted) { + if (isWorking) { + CustomAction current = (CustomAction) getCurrentAction(); + if (current != null) { + current.tick(ticksExisted); + if (current.isDone || current.duration >= current.maxDuration) { + current.destroy(); + actionQueue.poll(); + } + } + } + } + + //Nested not static to access outer class instance + public class CustomAction implements IAction { + Consumer action; + private HashMap data = new HashMap<>(); + + private String name; + private int startAfterTicks; //number of ticks to start action after + private int count; //number of times action ran + private int duration, maxDuration; //duration since action began + private int updateEveryXTick = 5; + + private boolean isDone; + + public CustomAction(String name, int maxDuration, int startAfterTicks, Consumer task) { + this.name = name; + this.maxDuration = maxDuration; + this.startAfterTicks = startAfterTicks; + this.action = task; + } + + private void tick(int ticksExisted) { + if (startAfterTicks <= 0) { + if (ticksExisted % updateEveryXTick == 0) { + action.accept(this); + count++; + } + duration++; + } else + startAfterTicks--; + } + + private void destroy() { + data.clear(); + } + + @Override + public int getCount() { + return count; + } + + @Override + public int getDuration() { + return duration; + } + + @Override + public String getName() { + return name; + } + + @Override + public int getMaxDuration() { + return maxDuration; + } + + @Override + public void setDone(boolean done) { + isDone = done; + } + + @Override + public boolean isDone() { + return isDone; + } + + @Override + public Object getData(String key) { + return data.get(key); + } + + @Override + public void addData(String key, Object value) { + data.put(key, value); + } + + @Override + public int getUpdateEveryXTick() { + return updateEveryXTick; + } + + @Override + public void setUpdateEveryXTick(int X) { + this.updateEveryXTick = X; + } + + @Override + public int getStartAfterTicks() { + return startAfterTicks; + } + + @Override + public IAction create(String name, int maxDuration, int startAfterTicks, Consumer action) { + return createAction(name, maxDuration, startAfterTicks, action); + } + + @Override + public void scheduleAfter(IAction action) { + scheduleActionAfter(this, action); + } + } +} + + + diff --git a/src/main/java/noppes/npcs/scripted/entity/ScriptNpc.java b/src/main/java/noppes/npcs/scripted/entity/ScriptNpc.java index 45694f845..ed6bff1db 100644 --- a/src/main/java/noppes/npcs/scripted/entity/ScriptNpc.java +++ b/src/main/java/noppes/npcs/scripted/entity/ScriptNpc.java @@ -3,6 +3,7 @@ package noppes.npcs.scripted.entity; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.item.ItemStack; import noppes.npcs.NoppesUtilServer; +import noppes.npcs.api.IActionManager; import noppes.npcs.api.IPos; import noppes.npcs.api.ITimers; import noppes.npcs.api.entity.ICustomNpc; @@ -1379,4 +1380,9 @@ public class ScriptNpc extends ScriptLiving imp public void updateClient() { this.npc.updateClient(); } public void updateAI() { this.npc.updateTasks(); } + + @Override + public IActionManager getActionManager() { + return npc.actionManager; + } }