diff --git a/src/main/java/noppes/npcs/DataAI.java b/src/main/java/noppes/npcs/DataAI.java index 8793791f9..694b189a1 100644 --- a/src/main/java/noppes/npcs/DataAI.java +++ b/src/main/java/noppes/npcs/DataAI.java @@ -55,8 +55,6 @@ public class DataAI { public boolean movingPause = true; - public boolean ignoreCobweb = false; - public DataAI(EntityNPCInterface npc){ this.npc = npc; } @@ -79,7 +77,6 @@ public class DataAI { tacticalRadius = compound.getInteger("TacticalRadius"); tacticalChance = compound.getInteger("TacticalChance"); movingPause = compound.getBoolean("MovingPause"); - ignoreCobweb = compound.getBoolean("IgnoreCobweb"); npcInteracting = compound.getBoolean("npcInteracting"); stopAndInteract = compound.getBoolean("stopAndInteract"); @@ -149,7 +146,6 @@ public class DataAI { compound.setInteger("TacticalRadius", tacticalRadius); compound.setInteger("TacticalChance", tacticalChance); compound.setBoolean("MovingPause", movingPause); - compound.setBoolean("IgnoreCobweb", ignoreCobweb); compound.setBoolean("npcInteracting", npcInteracting); compound.setBoolean("stopAndInteract", stopAndInteract); diff --git a/src/main/java/noppes/npcs/DataStats.java b/src/main/java/noppes/npcs/DataStats.java index a061901cd..5fea87974 100644 --- a/src/main/java/noppes/npcs/DataStats.java +++ b/src/main/java/noppes/npcs/DataStats.java @@ -11,7 +11,7 @@ import noppes.npcs.util.ValueUtil; public class DataStats { private float attackStrength = 5; - public int attackSpeed = 20, attackRange = 2, knockback = 0; + public int attackSpeed = 20, attackDelay = 0, attackRange = 2, knockback = 0; public int minDelay = 20, maxDelay = 40, rangedRange = 15, fireRate = 5, burstCount = 1, shotCount = 1, accuracy = 60; public int aggroRange = 16; @@ -28,6 +28,7 @@ public class DataStats { public Resistances resistances = new Resistances(); + public boolean ignoreCobweb = false; public boolean immuneToFire = false; public boolean potionImmune = false; public int drowningType = 1; // 0 - Never, 1 - Water, 2 - Air @@ -64,12 +65,14 @@ public class DataStats { compound.setInteger("RespawnTime", respawnTime); compound.setInteger("SpawnCycle", spawnCycle); compound.setInteger("CreatureType", creatureType.ordinal()); + compound.setBoolean("IgnoreCobweb", ignoreCobweb); compound.setFloat("HealthRegen", healthRegen); compound.setFloat("CombatRegen", combatRegen); compound.setFloat("AttackStrenght", attackStrength); compound.setInteger("AttackRange", attackRange); compound.setInteger("AttackSpeed", attackSpeed); + compound.setInteger("attackDelay", attackDelay); compound.setInteger("KnockBack", knockback); compound.setInteger("PotionEffect", potionType.ordinal()); compound.setInteger("PotionDuration", potionDuration); @@ -123,11 +126,13 @@ public class DataStats { respawnTime = compound.getInteger("RespawnTime"); spawnCycle = compound.getInteger("SpawnCycle"); creatureType = EnumCreatureAttribute.values()[compound.getInteger("CreatureType") % EnumPotionType.values().length]; + ignoreCobweb = compound.getBoolean("IgnoreCobweb"); healthRegen = compound.getFloat("HealthRegen"); combatRegen = compound.getFloat("CombatRegen"); setAttackStrength(compound.getFloat("AttackStrenght")); attackSpeed = compound.getInteger("AttackSpeed"); + attackDelay = ValueUtil.clamp(compound.getInteger("attackDelay"), 0, 1000); attackRange = compound.getInteger("AttackRange"); knockback = compound.getInteger("KnockBack"); potionType = EnumPotionType.values()[compound.getInteger("PotionEffect") % EnumPotionType.values().length]; diff --git a/src/main/java/noppes/npcs/ai/EntityAIAttackTarget.java b/src/main/java/noppes/npcs/ai/EntityAIAttackTarget.java index 4ed4d94ce..b924b03c3 100644 --- a/src/main/java/noppes/npcs/ai/EntityAIAttackTarget.java +++ b/src/main/java/noppes/npcs/ai/EntityAIAttackTarget.java @@ -115,13 +115,15 @@ public class EntityAIAttackTarget extends EntityAIBase public void updateTask() { this.npc.getLookHelper().setLookPositionWithEntity(this.entityTarget, 30.0F, 30.0F); + + if (!navOverride && --this.field_75445_i <= 0) { this.field_75445_i = 4 + this.npc.getRNG().nextInt(7); this.npc.getNavigator().tryMoveToEntityLiving(this.entityTarget, 1.3f); } - this.attackTick = Math.max(this.attackTick - 1, 0); + double distance = this.npc.getDistanceSq(this.entityTarget.posX, this.entityTarget.boundingBox.minY, this.entityTarget.posZ); double range = npc.stats.attackRange * npc.stats.attackRange + entityTarget.width; double minRange = this.npc.width * 2.0F * this.npc.width * 2.0F + entityTarget.width; @@ -129,15 +131,18 @@ public class EntityAIAttackTarget extends EntityAIBase range = minRange; if (distance <= range && (npc.canSee(this.entityTarget) || distance < minRange)) { - if (this.attackTick <= 0) - { + if (this.attackTick <= 0) { this.attackTick = this.npc.stats.attackSpeed; + if(this.npc.stats.attackDelay == 0) + this.npc.attackEntityAsMob(this.entityTarget); this.npc.swingItem(); + } else if (this.npc.stats.attackDelay > 0 && this.attackTick == this.npc.stats.attackSpeed - this.npc.stats.attackDelay) { + // Perform the actual attack that deals damage this.npc.attackEntityAsMob(this.entityTarget); } } } - + public void navOverride(boolean nav){ this.navOverride = nav; this.setMutexBits(this.navOverride ? AiMutex.PATHING : AiMutex.LOOK + AiMutex.PASSIVE); diff --git a/src/main/java/noppes/npcs/client/gui/SubGuiNpcMeleeProperties.java b/src/main/java/noppes/npcs/client/gui/SubGuiNpcMeleeProperties.java index bb7ad0b1a..23fc8a939 100644 --- a/src/main/java/noppes/npcs/client/gui/SubGuiNpcMeleeProperties.java +++ b/src/main/java/noppes/npcs/client/gui/SubGuiNpcMeleeProperties.java @@ -23,28 +23,32 @@ public class SubGuiNpcMeleeProperties extends SubGuiInterface implements ITextfi { super.initGui(); addLabel(new GuiNpcLabel(1,"stats.meleestrength", guiLeft + 5, guiTop + 15)); - addTextField(new GuiNpcTextField(1,this, fontRendererObj, guiLeft + 85, guiTop + 10, 50, 18, String.format("%.0f", stats.getAttackStrength()) + "")); + addTextField(new GuiNpcTextField(1,this, fontRendererObj, guiLeft + 85, guiTop + 10, 160, 18, String.format("%.0f", stats.getAttackStrength()) + "")); getTextField(1).floatsOnly = true; getTextField(1).setMinMaxDefaultFloat(0,Float.MAX_VALUE,5); addLabel(new GuiNpcLabel(2,"stats.meleerange", guiLeft + 5, guiTop + 45)); - addTextField(new GuiNpcTextField(2,this, fontRendererObj, guiLeft + 85, guiTop + 40, 50, 18, stats.attackRange+"")); + addTextField(new GuiNpcTextField(2,this, fontRendererObj, guiLeft + 85, guiTop + 40, 40, 18, stats.attackRange+"")); getTextField(2).integersOnly = true; getTextField(2).setMinMaxDefault(1, Integer.MAX_VALUE, 2); addLabel(new GuiNpcLabel(3,"stats.meleespeed", guiLeft + 5, guiTop + 75)); - addTextField(new GuiNpcTextField(3,this, fontRendererObj, guiLeft + 85, guiTop + 70, 50, 18, stats.attackSpeed+"")); + addTextField(new GuiNpcTextField(3,this, fontRendererObj, guiLeft + 85, guiTop + 70, 40, 18, stats.attackSpeed+"")); getTextField(3).integersOnly = true; getTextField(3).setMinMaxDefault(1, Integer.MAX_VALUE, 20); + addLabel(new GuiNpcLabel(8,"stats.swingdelay", guiLeft + 130, guiTop + 75)); + addTextField(new GuiNpcTextField(8,this, fontRendererObj, guiLeft + 220, guiTop + 70, 30, 18, stats.attackDelay+"")); + getTextField(8).integersOnly = true; + getTextField(8).setMinMaxDefault(0, 1000, 0); addLabel(new GuiNpcLabel(4,"enchantment.knockback", guiLeft + 5, guiTop + 105)); - addTextField(new GuiNpcTextField(4,this, fontRendererObj, guiLeft + 85, guiTop + 100, 50, 18, stats.knockback + "")); + addTextField(new GuiNpcTextField(4,this, fontRendererObj, guiLeft + 85, guiTop + 100, 40, 18, stats.knockback + "")); getTextField(4).integersOnly = true; getTextField(4).setMinMaxDefault(0, Integer.MAX_VALUE, 0); addLabel(new GuiNpcLabel(5,"stats.meleeeffect", guiLeft + 5, guiTop + 135)); addButton(new GuiButtonBiDirectional(5,guiLeft + 85, guiTop + 130, 100, 20, potionNames, stats.potionType.ordinal())); if(stats.potionType != EnumPotionType.None) { addLabel(new GuiNpcLabel(6,"gui.time", guiLeft + 5, guiTop + 165)); - addTextField(new GuiNpcTextField(6,this, fontRendererObj, guiLeft + 85, guiTop + 160, 50, 18, stats.potionDuration + "")); + addTextField(new GuiNpcTextField(6,this, fontRendererObj, guiLeft + 85, guiTop + 160, 40, 18, stats.potionDuration + "")); getTextField(6).integersOnly = true; getTextField(6).setMinMaxDefault(1, Integer.MAX_VALUE, 5); if(stats.potionType != EnumPotionType.Fire) { @@ -71,6 +75,9 @@ public class SubGuiNpcMeleeProperties extends SubGuiInterface implements ITextfi else if(textfield.id == 6){ stats.potionDuration = textfield.getInteger(); } + else if(textfield.id == 8){ + stats.attackDelay = textfield.getInteger(); + } } protected void actionPerformed(GuiButton guibutton) diff --git a/src/main/java/noppes/npcs/client/gui/mainmenu/GuiNpcAI.java b/src/main/java/noppes/npcs/client/gui/mainmenu/GuiNpcAI.java index 0a316636a..9fe3cd19c 100644 --- a/src/main/java/noppes/npcs/client/gui/mainmenu/GuiNpcAI.java +++ b/src/main/java/noppes/npcs/client/gui/mainmenu/GuiNpcAI.java @@ -90,9 +90,6 @@ public class GuiNpcAI extends GuiNPCInterface2 implements ITextfieldListener, IG addLabel(new GuiNpcLabel(2,"ai.movement", guiLeft + 4, guiTop + 165)); addButton(new GuiNpcButton(2, guiLeft + 86, guiTop + 160, 60, 20, "selectServer.edit")); - - addLabel(new GuiNpcLabel(22,"ai.cobwebAffected", guiLeft + 4, guiTop + 190)); - addButton(new GuiNpcButton(22 ,guiLeft + 86, guiTop + 185, 60, 20, new String[]{"gui.no", "gui.yes"}, npc.ai.ignoreCobweb ? 0:1)); } @Override @@ -155,9 +152,6 @@ public class GuiNpcAI extends GuiNPCInterface2 implements ITextfieldListener, IG ai.directLOS = EnumNavType.values()[button.getValue()] != EnumNavType.Stalk && this.ai.directLOS; initGui(); } - else if (button.id == 22) { - ai.ignoreCobweb = (button.getValue() == 0); - } else if (button.id == 25) { ai.combatPolicy = EnumCombatPolicy.values()[button.getValue()]; } diff --git a/src/main/java/noppes/npcs/client/gui/mainmenu/GuiNpcStats.java b/src/main/java/noppes/npcs/client/gui/mainmenu/GuiNpcStats.java index b3aaa507f..10ed35082 100644 --- a/src/main/java/noppes/npcs/client/gui/mainmenu/GuiNpcStats.java +++ b/src/main/java/noppes/npcs/client/gui/mainmenu/GuiNpcStats.java @@ -23,51 +23,54 @@ public class GuiNpcStats extends GuiNPCInterface2 implements ITextfieldListener, super.initGui(); int y = guiTop + 10; addLabel(new GuiNpcLabel(0,"stats.health", guiLeft + 5, y + 5)); - addTextField(new GuiNpcTextField(0,this, guiLeft + 85, y, 50, 18, String.format("%.0f", stats.maxHealth) + "")); + addTextField(new GuiNpcTextField(0,this, guiLeft + 82, y, 185, 18, String.format("%.0f", stats.maxHealth) + "")); getTextField(0).doublesOnly = true; getTextField(0).setMinMaxDefaultDouble(0, Double.MAX_VALUE,20); - addLabel(new GuiNpcLabel(1,"stats.aggro", guiLeft + 140, y + 5)); - addTextField(new GuiNpcTextField(1, this, fontRendererObj, guiLeft + 220, y, 50, 18, stats.aggroRange+"")); + + addLabel(new GuiNpcLabel(1,"stats.aggro", guiLeft + 275, y + 5)); + addTextField(new GuiNpcTextField(1, this, fontRendererObj, guiLeft + 355, y, 56, 18, stats.aggroRange+"")); getTextField(1).integersOnly = true; getTextField(1).setMinMaxDefault(1, 96, 2); // Doesn't work past 32 technically (MC Limitations) - addLabel(new GuiNpcLabel(34,"stats.creaturetype", guiLeft + 275, y + 5)); - addButton(new GuiNpcButton(8,guiLeft + 355, y, 56, 20, new String[]{"stats.normal","stats.undead","stats.arthropod"} ,stats.creatureType.ordinal())); addButton(new GuiNpcButton(0,guiLeft + 82, y+=22, 56, 20, "selectServer.edit")); addLabel(new GuiNpcLabel(2,"stats.respawn", guiLeft + 5, y + 5)); - this.addButton(new GuiNpcButton(2, guiLeft + 82, y+=22, 56, 20, "selectServer.edit")); + this.addButton(new GuiNpcButton(2, guiLeft + 82, y+=22, 56, 20, "selectServer.edit")); addLabel(new GuiNpcLabel(5,"stats.meleeproperties", guiLeft + 5, y + 5)); + this.addButton(new GuiNpcButton(3, guiLeft + 82, y+=22, 56, 20, "selectServer.edit")); addLabel(new GuiNpcLabel(6,"stats.rangedproperties", guiLeft + 5, y + 5)); this.addButton(new GuiNpcButton(9, guiLeft + 217, y, 56, 20, "selectServer.edit")); addLabel(new GuiNpcLabel(7,"stats.projectileproperties", guiLeft + 140, y + 5)); + addTextField(new GuiNpcTextField(14, this, guiLeft + 355, y, 56, 20, String.format("%.0f", stats.healthRegen) + "").setFloatsOnly()); + addLabel(new GuiNpcLabel(14,"stats.regenhealth", guiLeft + 275, y + 5)); this.addButton(new GuiNpcButton(15, guiLeft + 82, y+=34, 56, 20, "selectServer.edit")); addLabel(new GuiNpcLabel(15,"potion.resistance", guiLeft + 5, y + 5)); - this.addButton(new GuiNpcButton(21, guiLeft + 217, y, 56, 20, new String[]{"gui.no","gui.yes"}, this.stats.resistances.disableDamage? 1:0)); addLabel(new GuiNpcLabel(21,"stats.disabledamage", guiLeft + 140, y + 5)); + addTextField(new GuiNpcTextField(16, this, guiLeft + 355, y, 56, 20, String.format("%.0f", stats.combatRegen) + "").setFloatsOnly()); + addLabel(new GuiNpcLabel(16,"stats.combatregen", guiLeft + 275, y + 5)); addButton(new GuiNpcButton(4,guiLeft + 82, y+=34, 56, 20, new String[]{"gui.no","gui.yes"} ,npc.isImmuneToFire()? 1:0)); addLabel(new GuiNpcLabel(10,"stats.fireimmune", guiLeft + 5, y + 5)); addButton(new GuiNpcButton(5,guiLeft + 217, y, 56, 20, new String[]{"stats.never","stats.inWater","stats.inAir"} , stats.drowningType)); addLabel(new GuiNpcLabel(11,"stats.candrown", guiLeft + 140, y + 5)); - addTextField(new GuiNpcTextField(14, this, guiLeft + 355, y, 56, 20, String.format("%.0f", stats.healthRegen) + "").setFloatsOnly()); - addLabel(new GuiNpcLabel(14,"stats.regenhealth", guiLeft + 275, y + 5)); - addTextField(new GuiNpcTextField(16, this, guiLeft + 355, y+=22, 56, 20, String.format("%.0f", stats.combatRegen) + "").setFloatsOnly()); - addLabel(new GuiNpcLabel(16,"stats.combatregen", guiLeft + 275, y + 5)); - addButton(new GuiNpcButton(6,guiLeft + 82, y, 56, 20, new String[]{"gui.no","gui.yes"} ,stats.burnInSun? 1:0)); + addButton(new GuiNpcButton(6,guiLeft + 82, y+=22, 56, 20, new String[]{"gui.no","gui.yes"} ,stats.burnInSun? 1:0)); addLabel(new GuiNpcLabel(12,"stats.burninsun", guiLeft + 5, y + 5)); addButton(new GuiNpcButton(7,guiLeft + 217, y, 56, 20, new String[]{"gui.no","gui.yes"} ,stats.noFallDamage? 1:0)); addLabel(new GuiNpcLabel(13,"stats.nofalldamage", guiLeft + 140, y + 5)); + addLabel(new GuiNpcLabel(22,"ai.cobwebAffected", guiLeft + 275, y + 5)); + addButton(new GuiNpcButton(22 ,guiLeft + 358, y, 56, 20, new String[]{"gui.no", "gui.yes"}, npc.stats.ignoreCobweb ? 0:1)); addButton(new GuiNpcButtonYesNo(17, guiLeft + 82, y+=22, 56, 20, stats.potionImmune)); addLabel(new GuiNpcLabel(17,"stats.potionImmune", guiLeft + 5, y + 5)); addButton(new GuiNpcButtonYesNo(18, guiLeft + 217, y, 56, 20, stats.attackInvisible)); addLabel(new GuiNpcLabel(18,"stats.attackInvisible", guiLeft + 140, y + 5)); - } + addLabel(new GuiNpcLabel(34,"stats.creaturetype", guiLeft + 275, y + 5)); + addButton(new GuiNpcButton(8,guiLeft + 358, y, 56, 20, new String[]{"stats.normal","stats.undead","stats.arthropod"} ,stats.creatureType.ordinal())); + } @Override public void unFocused(GuiNpcTextField textfield){ @@ -128,6 +131,9 @@ public class GuiNpcStats extends GuiNPCInterface2 implements ITextfieldListener, else if(button.id == 21){ stats.resistances.disableDamage = ((GuiNpcButton)guibutton).getValue() == 1; } + else if (button.id == 22) { + stats.ignoreCobweb = (button.getValue() == 0); + } } @Override public void save() { diff --git a/src/main/java/noppes/npcs/client/gui/script/GuiScriptAllNPCs.java b/src/main/java/noppes/npcs/client/gui/script/GuiScriptAllNPCs.java index 8bb387593..0002bc955 100644 --- a/src/main/java/noppes/npcs/client/gui/script/GuiScriptAllNPCs.java +++ b/src/main/java/noppes/npcs/client/gui/script/GuiScriptAllNPCs.java @@ -20,6 +20,7 @@ public class GuiScriptAllNPCs extends GuiScriptInterface { hookList.add("damaged"); hookList.add("killed"); hookList.add("meleeAttack"); + hookList.add("meleeSwing"); hookList.add("rangedLaunched"); hookList.add("target"); hookList.add("collide"); diff --git a/src/main/java/noppes/npcs/entity/EntityNPCInterface.java b/src/main/java/noppes/npcs/entity/EntityNPCInterface.java index 78b055a2c..fbf217987 100644 --- a/src/main/java/noppes/npcs/entity/EntityNPCInterface.java +++ b/src/main/java/noppes/npcs/entity/EntityNPCInterface.java @@ -23,6 +23,7 @@ import net.minecraft.item.Item; import net.minecraft.item.ItemBow; import net.minecraft.item.ItemStack; import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.network.play.server.S0BPacketAnimation; import net.minecraft.pathfinding.PathNavigate; import net.minecraft.potion.Potion; import net.minecraft.potion.PotionEffect; @@ -268,6 +269,34 @@ public abstract class EntityNPCInterface extends EntityCreature implements IEnti return var4; } + @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) + { + NpcEvent.SwingEvent event = new NpcEvent.SwingEvent(wrappedNPC, stack); + if(EventHooks.onNPCMeleeSwing(this, event)) + return; + + this.swingProgressInt = -1; + this.isSwingInProgress = true; + + if (this.worldObj instanceof WorldServer) + { + ((WorldServer)this.worldObj).getEntityTracker().func_151247_a(this, new S0BPacketAnimation(this, 0)); + } + } + } + @Override public void onLivingUpdate(){ if(CustomNpcs.FreezeNPCs) @@ -1701,7 +1730,7 @@ public abstract class EntityNPCInterface extends EntityCreature implements IEnti } @Override public void setInWeb(){ - if(!ai.ignoreCobweb) + if(!stats.ignoreCobweb) super.setInWeb(); } diff --git a/src/main/java/noppes/npcs/scripted/entity/ScriptNpc.java b/src/main/java/noppes/npcs/scripted/entity/ScriptNpc.java index 5cd836aef..c32e90fbc 100644 --- a/src/main/java/noppes/npcs/scripted/entity/ScriptNpc.java +++ b/src/main/java/noppes/npcs/scripted/entity/ScriptNpc.java @@ -766,11 +766,11 @@ public class ScriptNpc extends ScriptLiving imp } public void setIgnoreCobweb(boolean ignore){ - npc.ai.ignoreCobweb = ignore; + npc.stats.ignoreCobweb = ignore; } public boolean getIgnoreCobweb(){ - return npc.ai.ignoreCobweb; + return npc.stats.ignoreCobweb; } public void setOnFoundEnemy(int onAttack){