diff --git a/src/main/java/kamkeel/npcs/controllers/data/ability/Ability.java b/src/main/java/kamkeel/npcs/controllers/data/ability/Ability.java index b6c392b5c..4d62a934f 100644 --- a/src/main/java/kamkeel/npcs/controllers/data/ability/Ability.java +++ b/src/main/java/kamkeel/npcs/controllers/data/ability/Ability.java @@ -117,9 +117,16 @@ public abstract class Ability implements IAbility { * @param hitEntity The entity being hit * @param damage The damage amount * @param knockback The horizontal knockback - * @param knockbackUp The vertical knockback * @return true if damage was applied (not cancelled), false if cancelled */ + protected boolean applyAbilityDamage(EntityNPCInterface npc, EntityLivingBase hitEntity, + float damage, float knockback) { + return applyAbilityDamage(npc, hitEntity, damage, knockback, 0.0f); + } + + /** + * Backward-compatible signature (vertical knockback is ignored). + */ protected boolean applyAbilityDamage(EntityNPCInterface npc, EntityLivingBase hitEntity, float damage, float knockback, float knockbackUp) { DataAbilities dataAbilities = npc.abilities; @@ -133,7 +140,6 @@ public abstract class Ability implements IAbility { // Apply damage with potentially modified values float finalDamage = event.getDamage(); float finalKnockback = event.getKnockback(); - float finalKnockbackUp = event.getKnockbackUp(); // Apply damage if (finalDamage > 0) { @@ -141,18 +147,10 @@ public abstract class Ability implements IAbility { } // Apply knockback if any - if (finalKnockback > 0 || finalKnockbackUp > 0) { + if (finalKnockback > 0) { double dx = hitEntity.posX - npc.posX; double dz = hitEntity.posZ - npc.posZ; - double len = Math.sqrt(dx * dx + dz * dz); - if (len > 0 && finalKnockback > 0) { - dx /= len; - dz /= len; - hitEntity.motionX += dx * finalKnockback; - hitEntity.motionZ += dz * finalKnockback; - } - hitEntity.motionY += finalKnockbackUp; - hitEntity.velocityChanged = true; + applyNpcKnockback(hitEntity, dx, dz, finalKnockback); } return true; @@ -166,17 +164,16 @@ public abstract class Ability implements IAbility { * @param hitEntity The entity being hit * @param damage The damage amount * @param knockback The horizontal knockback - * @param knockbackUp The vertical knockback * @param knockbackDirX The X component of knockback direction (normalized) * @param knockbackDirZ The Z component of knockback direction (normalized) * @return true if damage was applied (not cancelled), false if cancelled */ protected boolean applyAbilityDamageWithDirection(EntityNPCInterface npc, EntityLivingBase hitEntity, - float damage, float knockback, float knockbackUp, + float damage, float knockback, double knockbackDirX, double knockbackDirZ) { DataAbilities dataAbilities = npc.abilities; AbilityEvent.HitEvent event = dataAbilities.fireHitEvent( - this, currentTarget, hitEntity, damage, knockback, knockbackUp); + this, currentTarget, hitEntity, damage, knockback, 0.0f); if (event == null) { return false; // Cancelled @@ -185,7 +182,6 @@ public abstract class Ability implements IAbility { // Apply damage with potentially modified values float finalDamage = event.getDamage(); float finalKnockback = event.getKnockback(); - float finalKnockbackUp = event.getKnockbackUp(); // Apply damage if (finalDamage > 0) { @@ -193,15 +189,23 @@ public abstract class Ability implements IAbility { } // Apply knockback in specified direction - if (finalKnockback > 0 || finalKnockbackUp > 0) { - hitEntity.motionX = knockbackDirX * finalKnockback; - hitEntity.motionY = finalKnockbackUp; - hitEntity.motionZ = knockbackDirZ * finalKnockback; - hitEntity.velocityChanged = true; + if (finalKnockback > 0) { + applyNpcKnockback(hitEntity, knockbackDirX, knockbackDirZ, finalKnockback); } return true; } + + private void applyNpcKnockback(EntityLivingBase hitEntity, double dirX, double dirZ, float knockback) { + double len = Math.sqrt(dirX * dirX + dirZ * dirZ); + if (len <= 0) { + return; + } + double x = (dirX / len) * knockback * 0.5; + double z = (dirZ / len) * knockback * 0.5; + hitEntity.addVelocity(x, 0.1D, z); + hitEntity.velocityChanged = true; + } public float getTelegraphRadius() { return 5.0f; } public float getTelegraphLength() { return 5.0f; } public float getTelegraphWidth() { return 2.0f; } diff --git a/src/main/java/kamkeel/npcs/controllers/data/ability/type/AbilityBeam.java b/src/main/java/kamkeel/npcs/controllers/data/ability/type/AbilityBeam.java index 2dc67e5c0..f094a4f0d 100644 --- a/src/main/java/kamkeel/npcs/controllers/data/ability/type/AbilityBeam.java +++ b/src/main/java/kamkeel/npcs/controllers/data/ability/type/AbilityBeam.java @@ -169,7 +169,7 @@ public class AbilityBeam extends Ability { if (isInBeamPath(livingEntity, startX, startY, startZ, dirX, dirZ)) { hitThisTick.add(entity.getEntityId()); // Apply damage with scripted event support (no knockback for beam) - applyAbilityDamage(npc, livingEntity, damage, 0, 0); + applyAbilityDamage(npc, livingEntity, damage, 0); if (!piercing) { return; // Stop at first hit diff --git a/src/main/java/kamkeel/npcs/controllers/data/ability/type/AbilityCharge.java b/src/main/java/kamkeel/npcs/controllers/data/ability/type/AbilityCharge.java index f2a88edb6..841a8dc7e 100644 --- a/src/main/java/kamkeel/npcs/controllers/data/ability/type/AbilityCharge.java +++ b/src/main/java/kamkeel/npcs/controllers/data/ability/type/AbilityCharge.java @@ -32,9 +32,7 @@ public class AbilityCharge extends Ability { private float chargeSpeed = 0.8f; private float damage = 15.0f; private float knockback = 3.0f; - private float knockbackUp = 0.3f; - private float maxDistance = 20.0f; - private float hitRadius = 1.5f; + private float hitWidth = 1.5f; // Runtime state (transient) private transient double startX, startY, startZ; @@ -56,6 +54,8 @@ public class AbilityCharge extends Ability { // LINE telegraph showing charge path this.telegraphType = TelegraphType.LINE; this.showTelegraph = true; + this.windUpSound = "mob.zombie.wood"; + this.activeSound = "mob.zombie.attack"; } @Override @@ -154,13 +154,18 @@ public class AbilityCharge extends Ability { ); // Check if reached max distance - if (distanceTraveled >= maxDistance) { + if (distanceTraveled >= maxRange) { npc.motionX = 0; npc.motionZ = 0; npc.velocityChanged = true; return; } + if (isChargeBlocked(npc)) { + stopMomentum(npc); + return; + } + // Move NPC npc.motionX = chargeDirection.xCoord * chargeSpeed; npc.motionY = 0; @@ -169,7 +174,7 @@ public class AbilityCharge extends Ability { // Server-side collision damage if (!world.isRemote) { - AxisAlignedBB hitBox = npc.boundingBox.expand(hitRadius, hitRadius * 0.5, hitRadius); + AxisAlignedBB hitBox = npc.boundingBox.expand(hitWidth, hitWidth * 0.5, hitWidth); @SuppressWarnings("unchecked") List entities = world.getEntitiesWithinAABB(EntityLivingBase.class, hitBox); @@ -185,7 +190,7 @@ public class AbilityCharge extends Ability { hitEntities.add(entity.getEntityId()); // Apply damage with scripted event support - boolean wasHit = applyAbilityDamageWithDirection(npc, livingEntity, damage, knockback, knockbackUp, + boolean wasHit = applyAbilityDamageWithDirection(npc, livingEntity, damage, knockback, chargeDirection.xCoord, chargeDirection.zCoord); // Play impact sound if hit wasn't cancelled @@ -214,6 +219,13 @@ public class AbilityCharge extends Ability { npc.velocityChanged = true; } + private boolean isChargeBlocked(EntityNPCInterface npc) { + double nextX = chargeDirection.xCoord * chargeSpeed; + double nextZ = chargeDirection.zCoord * chargeSpeed; + AxisAlignedBB nextBox = npc.boundingBox.copy().offset(nextX, 0, nextZ); + return !npc.worldObj.getCollidingBoundingBoxes(npc, nextBox).isEmpty(); + } + @Override public void reset() { super.reset(); @@ -223,7 +235,7 @@ public class AbilityCharge extends Ability { @Override public float getTelegraphLength() { - return maxDistance; + return maxRange; } @Override @@ -275,9 +287,7 @@ public class AbilityCharge extends Ability { nbt.setFloat("chargeSpeed", chargeSpeed); nbt.setFloat("damage", damage); nbt.setFloat("knockback", knockback); - nbt.setFloat("knockbackUp", knockbackUp); - nbt.setFloat("maxDistance", maxDistance); - nbt.setFloat("hitRadius", hitRadius); + nbt.setFloat("hitWidth", hitWidth); } @Override @@ -285,9 +295,13 @@ public class AbilityCharge extends Ability { this.chargeSpeed = nbt.hasKey("chargeSpeed") ? nbt.getFloat("chargeSpeed") : 0.8f; this.damage = nbt.hasKey("damage") ? nbt.getFloat("damage") : 15.0f; this.knockback = nbt.hasKey("knockback") ? nbt.getFloat("knockback") : 3.0f; - this.knockbackUp = nbt.hasKey("knockbackUp") ? nbt.getFloat("knockbackUp") : 0.3f; - this.maxDistance = nbt.hasKey("maxDistance") ? nbt.getFloat("maxDistance") : 20.0f; - this.hitRadius = nbt.hasKey("hitRadius") ? nbt.getFloat("hitRadius") : 1.5f; + if (nbt.hasKey("hitWidth")) { + this.hitWidth = nbt.getFloat("hitWidth"); + } else if (nbt.hasKey("hitRadius")) { + this.hitWidth = nbt.getFloat("hitRadius"); + } else { + this.hitWidth = 1.5f; + } } // Getters & Setters @@ -300,12 +314,6 @@ public class AbilityCharge extends Ability { public float getKnockback() { return knockback; } public void setKnockback(float knockback) { this.knockback = knockback; } - public float getKnockbackUp() { return knockbackUp; } - public void setKnockbackUp(float knockbackUp) { this.knockbackUp = knockbackUp; } - - public float getMaxDistance() { return maxDistance; } - public void setMaxDistance(float maxDistance) { this.maxDistance = maxDistance; } - - public float getHitRadius() { return hitRadius; } - public void setHitRadius(float hitRadius) { this.hitRadius = hitRadius; } + public float getHitWidth() { return hitWidth; } + public void setHitWidth(float hitWidth) { this.hitWidth = hitWidth; } } diff --git a/src/main/java/kamkeel/npcs/controllers/data/ability/type/AbilityCutter.java b/src/main/java/kamkeel/npcs/controllers/data/ability/type/AbilityCutter.java index 5e81501a9..b258e6127 100644 --- a/src/main/java/kamkeel/npcs/controllers/data/ability/type/AbilityCutter.java +++ b/src/main/java/kamkeel/npcs/controllers/data/ability/type/AbilityCutter.java @@ -29,32 +29,26 @@ import java.util.Set; public class AbilityCutter extends Ability { public enum SweepMode { - INSTANT, - EXPANDING, - ROTATING + SWIPE, + SPIN } private float arcAngle = 90.0f; private float range = 6.0f; private float damage = 12.0f; private float knockback = 1.5f; - private float knockbackUp = 0.2f; - private SweepMode sweepMode = SweepMode.INSTANT; - private int sweepWaves = 1; - private int waveInterval = 5; - private float rotationSpeed = 5.0f; - private float startAngleOffset = 0.0f; + private SweepMode sweepMode = SweepMode.SWIPE; + private float sweepSpeed = 6.0f; private int stunDuration = 0; - private int bleedDuration = 0; - private int bleedLevel = 0; + private int poisonDurationSeconds = 0; + private int poisonLevel = 0; private boolean piercing = true; private float innerRadius = 0.0f; // Runtime state private transient Set hitEntities = new HashSet<>(); - private transient int currentWave = 0; private transient float currentRotation = 0.0f; public AbilityCutter() { @@ -68,6 +62,8 @@ public class AbilityCutter extends Ability { this.activeTicks = 15; this.recoveryTicks = 15; this.telegraphType = TelegraphType.CONE; + this.windUpSound = "random.bow"; + this.activeSound = "random.break"; } @Override @@ -99,12 +95,7 @@ public class AbilityCutter extends Ability { @Override public void onExecute(EntityNPCInterface npc, EntityLivingBase target, World world) { hitEntities.clear(); - currentWave = 0; - currentRotation = startAngleOffset; - - if (sweepMode == SweepMode.INSTANT && !world.isRemote) { - performSweepDamage(npc, world, 0.0f, range); - } + currentRotation = -arcAngle / 2.0f; } @Override @@ -112,29 +103,24 @@ public class AbilityCutter extends Ability { if (world.isRemote) return; switch (sweepMode) { - case EXPANDING: - if (tick % waveInterval == 0 && currentWave < sweepWaves) { - float waveProgress = (float)(currentWave + 1) / sweepWaves; - float waveInner = innerRadius + (range - innerRadius) * ((float)currentWave / sweepWaves); - float waveOuter = innerRadius + (range - innerRadius) * waveProgress; - performSweepDamage(npc, world, waveInner, waveOuter); - currentWave++; + case SWIPE: + if (currentRotation > arcAngle / 2.0f) { + return; } + performSweepDamage(npc, world, innerRadius, range, currentRotation); + currentRotation += sweepSpeed; break; - case ROTATING: - currentRotation += rotationSpeed; + case SPIN: + currentRotation = (currentRotation + sweepSpeed) % 360.0f; hitEntities.clear(); - performSweepDamage(npc, world, innerRadius, range); - break; - - case INSTANT: + performSweepDamage(npc, world, innerRadius, range, currentRotation); break; } } - private void performSweepDamage(EntityNPCInterface npc, World world, float minDist, float maxDist) { - float casterYaw = npc.rotationYaw + currentRotation; + private void performSweepDamage(EntityNPCInterface npc, World world, float minDist, float maxDist, float angleOffset) { + float casterYaw = npc.rotationYaw + angleOffset; AxisAlignedBB searchBox = AxisAlignedBB.getBoundingBox( npc.posX - maxDist, npc.posY - 1, npc.posZ - maxDist, @@ -163,7 +149,7 @@ public class AbilityCutter extends Ability { float actualDamage = damage * distFactor; // Apply damage with scripted event support - boolean wasHit = applyAbilityDamage(npc, entity, actualDamage, knockback, knockbackUp); + boolean wasHit = applyAbilityDamage(npc, entity, actualDamage, knockback); // Only apply effects if hit wasn't cancelled if (wasHit) { @@ -171,8 +157,8 @@ public class AbilityCutter extends Ability { entity.addPotionEffect(new PotionEffect(Potion.moveSlowdown.id, stunDuration, 10)); entity.addPotionEffect(new PotionEffect(Potion.weakness.id, stunDuration, 2)); } - if (bleedDuration > 0) { - entity.addPotionEffect(new PotionEffect(Potion.wither.id, bleedDuration, bleedLevel)); + if (poisonDurationSeconds > 0) { + entity.addPotionEffect(new PotionEffect(Potion.poison.id, poisonDurationSeconds * 20, poisonLevel)); } } } @@ -193,15 +179,13 @@ public class AbilityCutter extends Ability { @Override public void onComplete(EntityNPCInterface npc, EntityLivingBase target) { hitEntities.clear(); - currentWave = 0; - currentRotation = startAngleOffset; + currentRotation = 0.0f; } @Override public void onInterrupt(EntityNPCInterface npc, DamageSource source, float damage) { hitEntities.clear(); - currentWave = 0; - currentRotation = startAngleOffset; + currentRotation = 0.0f; } @Override @@ -210,15 +194,11 @@ public class AbilityCutter extends Ability { nbt.setFloat("range", range); nbt.setFloat("damage", damage); nbt.setFloat("knockback", knockback); - nbt.setFloat("knockbackUp", knockbackUp); nbt.setString("sweepMode", sweepMode.name()); - nbt.setInteger("sweepWaves", sweepWaves); - nbt.setInteger("waveInterval", waveInterval); - nbt.setFloat("rotationSpeed", rotationSpeed); - nbt.setFloat("startAngleOffset", startAngleOffset); + nbt.setFloat("sweepSpeed", sweepSpeed); nbt.setInteger("stunDuration", stunDuration); - nbt.setInteger("bleedDuration", bleedDuration); - nbt.setInteger("bleedLevel", bleedLevel); + nbt.setInteger("poisonDurationSeconds", poisonDurationSeconds); + nbt.setInteger("poisonLevel", poisonLevel); nbt.setBoolean("piercing", piercing); nbt.setFloat("innerRadius", innerRadius); } @@ -229,19 +209,15 @@ public class AbilityCutter extends Ability { this.range = nbt.hasKey("range") ? nbt.getFloat("range") : 6.0f; this.damage = nbt.hasKey("damage") ? nbt.getFloat("damage") : 12.0f; this.knockback = nbt.hasKey("knockback") ? nbt.getFloat("knockback") : 1.5f; - this.knockbackUp = nbt.hasKey("knockbackUp") ? nbt.getFloat("knockbackUp") : 0.2f; try { this.sweepMode = SweepMode.valueOf(nbt.getString("sweepMode")); } catch (Exception e) { - this.sweepMode = SweepMode.INSTANT; + this.sweepMode = SweepMode.SWIPE; } - this.sweepWaves = nbt.hasKey("sweepWaves") ? nbt.getInteger("sweepWaves") : 1; - this.waveInterval = nbt.hasKey("waveInterval") ? nbt.getInteger("waveInterval") : 5; - this.rotationSpeed = nbt.hasKey("rotationSpeed") ? nbt.getFloat("rotationSpeed") : 5.0f; - this.startAngleOffset = nbt.hasKey("startAngleOffset") ? nbt.getFloat("startAngleOffset") : 0.0f; + this.sweepSpeed = nbt.hasKey("sweepSpeed") ? nbt.getFloat("sweepSpeed") : 6.0f; this.stunDuration = nbt.hasKey("stunDuration") ? nbt.getInteger("stunDuration") : 0; - this.bleedDuration = nbt.hasKey("bleedDuration") ? nbt.getInteger("bleedDuration") : 0; - this.bleedLevel = nbt.hasKey("bleedLevel") ? nbt.getInteger("bleedLevel") : 0; + this.poisonDurationSeconds = nbt.hasKey("poisonDurationSeconds") ? nbt.getInteger("poisonDurationSeconds") : 0; + this.poisonLevel = nbt.hasKey("poisonLevel") ? nbt.getInteger("poisonLevel") : 0; this.piercing = !nbt.hasKey("piercing") || nbt.getBoolean("piercing"); this.innerRadius = nbt.hasKey("innerRadius") ? nbt.getFloat("innerRadius") : 0.0f; } @@ -259,32 +235,20 @@ public class AbilityCutter extends Ability { public float getKnockback() { return knockback; } public void setKnockback(float knockback) { this.knockback = knockback; } - public float getKnockbackUp() { return knockbackUp; } - public void setKnockbackUp(float knockbackUp) { this.knockbackUp = knockbackUp; } - public SweepMode getSweepMode() { return sweepMode; } public void setSweepMode(SweepMode sweepMode) { this.sweepMode = sweepMode; } - public int getSweepWaves() { return sweepWaves; } - public void setSweepWaves(int sweepWaves) { this.sweepWaves = sweepWaves; } - - public int getWaveInterval() { return waveInterval; } - public void setWaveInterval(int waveInterval) { this.waveInterval = waveInterval; } - - public float getRotationSpeed() { return rotationSpeed; } - public void setRotationSpeed(float rotationSpeed) { this.rotationSpeed = rotationSpeed; } - - public float getStartAngleOffset() { return startAngleOffset; } - public void setStartAngleOffset(float startAngleOffset) { this.startAngleOffset = startAngleOffset; } + public float getSweepSpeed() { return sweepSpeed; } + public void setSweepSpeed(float sweepSpeed) { this.sweepSpeed = sweepSpeed; } public int getStunDuration() { return stunDuration; } public void setStunDuration(int stunDuration) { this.stunDuration = stunDuration; } - public int getBleedDuration() { return bleedDuration; } - public void setBleedDuration(int bleedDuration) { this.bleedDuration = bleedDuration; } + public int getPoisonDurationSeconds() { return poisonDurationSeconds; } + public void setPoisonDurationSeconds(int poisonDurationSeconds) { this.poisonDurationSeconds = poisonDurationSeconds; } - public int getBleedLevel() { return bleedLevel; } - public void setBleedLevel(int bleedLevel) { this.bleedLevel = bleedLevel; } + public int getPoisonLevel() { return poisonLevel; } + public void setPoisonLevel(int poisonLevel) { this.poisonLevel = poisonLevel; } public boolean isPiercing() { return piercing; } public void setPiercing(boolean piercing) { this.piercing = piercing; } diff --git a/src/main/java/kamkeel/npcs/controllers/data/ability/type/AbilityDash.java b/src/main/java/kamkeel/npcs/controllers/data/ability/type/AbilityDash.java index 920e57f96..db34b0bb8 100644 --- a/src/main/java/kamkeel/npcs/controllers/data/ability/type/AbilityDash.java +++ b/src/main/java/kamkeel/npcs/controllers/data/ability/type/AbilityDash.java @@ -95,6 +95,8 @@ public class AbilityDash extends Ability { // No telegraph for dash - it's a quick evasive move this.telegraphType = TelegraphType.NONE; this.showTelegraph = false; + this.windUpSound = "mob.bat.takeoff"; + this.activeSound = "mob.endermen.portal"; } @Override @@ -152,8 +154,6 @@ public class AbilityDash extends Ability { Math.cos(yawRad) ); - // Play dash sound - world.playSoundAtEntity(npc, "mob.endermen.portal", 0.5f, 1.5f); } @Override @@ -174,6 +174,13 @@ public class AbilityDash extends Ability { return; } + if (isDashBlocked(npc)) { + npc.motionX = 0; + npc.motionZ = 0; + npc.velocityChanged = true; + return; + } + // Move NPC npc.motionX = dashDirection.xCoord * dashSpeed; npc.motionY = 0; @@ -202,6 +209,12 @@ public class AbilityDash extends Ability { chosenDirection = null; } + private boolean isDashBlocked(EntityNPCInterface npc) { + double nextX = dashDirection.xCoord * dashSpeed; + double nextZ = dashDirection.zCoord * dashSpeed; + return !npc.worldObj.getCollidingBoundingBoxes(npc, npc.boundingBox.copy().offset(nextX, 0, nextZ)).isEmpty(); + } + @Override public void reset() { super.reset(); diff --git a/src/main/java/kamkeel/npcs/controllers/data/ability/type/AbilityGuard.java b/src/main/java/kamkeel/npcs/controllers/data/ability/type/AbilityGuard.java index 8afc45063..2ef0a446c 100644 --- a/src/main/java/kamkeel/npcs/controllers/data/ability/type/AbilityGuard.java +++ b/src/main/java/kamkeel/npcs/controllers/data/ability/type/AbilityGuard.java @@ -28,12 +28,21 @@ public class AbilityGuard extends Ability { // Type-specific parameters private float damageReduction = 0.5f; private boolean canCounter = false; - private float counterDamage = 10.0f; + private CounterType counterType = CounterType.FLAT; + private float counterValue = 10.0f; private float counterChance = 0.3f; + private String counterSound = "random.wood_click"; + private int counterAnimationId = -1; // Runtime state private transient EntityLivingBase lastAttacker; private transient boolean counterTriggered; + private transient float lastDamageTaken; + + public enum CounterType { + FLAT, + PERCENT + } public AbilityGuard() { this.typeId = "ability.cnpc.guard"; @@ -48,6 +57,8 @@ public class AbilityGuard extends Ability { // No telegraph for guard - it's a defensive stance this.telegraphType = TelegraphType.NONE; this.showTelegraph = false; + this.windUpSound = "random.anvil_use"; + this.activeSound = "random.anvil_land"; } @Override @@ -72,22 +83,14 @@ public class AbilityGuard extends Ability { public void onExecute(EntityNPCInterface npc, EntityLivingBase target, World world) { lastAttacker = null; counterTriggered = false; + lastDamageTaken = 0.0f; } @Override public void onActiveTick(EntityNPCInterface npc, EntityLivingBase target, World world, int tick) { // Counter attack logic if triggered if (canCounter && counterTriggered && lastAttacker != null && !world.isRemote) { - // Apply counter damage with scripted event support - boolean wasHit = applyAbilityDamage(npc, lastAttacker, counterDamage, 0.5f, 0); - - // Play counter sound if hit wasn't cancelled - if (wasHit) { - world.playSoundAtEntity(npc, "random.wood_click", 1.0f, 1.2f); - } - - counterTriggered = false; - lastAttacker = null; + performCounter(npc, world); } } @@ -98,13 +101,53 @@ public class AbilityGuard extends Ability { * @param attacker The entity that attacked * @param damage The damage amount (after reduction) */ - public void onDamageTaken(EntityLivingBase attacker, float damage) { - if (attacker != null && canCounter && RANDOM.nextFloat() < counterChance) { - lastAttacker = attacker; - counterTriggered = true; + public void onDamageTaken(EntityNPCInterface npc, EntityLivingBase attacker, DamageSource source, float damage) { + if (!canCounter || attacker == null) return; + if (!isDirectHit(source)) return; + if (RANDOM.nextFloat() >= counterChance) return; + + lastAttacker = attacker; + lastDamageTaken = damage; + counterTriggered = true; + + if (interruptible) { + performCounter(npc, npc.worldObj); + npc.abilities.interruptCurrentAbility(source, damage); } } + private void performCounter(EntityNPCInterface npc, World world) { + float counterDamage = counterType == CounterType.PERCENT + ? lastDamageTaken * (counterValue / 100.0f) + : counterValue; + + boolean wasHit = applyAbilityDamage(npc, lastAttacker, counterDamage, 0.5f); + if (wasHit && counterSound != null && !counterSound.isEmpty()) { + world.playSoundAtEntity(npc, counterSound, 1.0f, 1.2f); + } + if (counterAnimationId >= 0) { + if (noppes.npcs.controllers.AnimationController.Instance != null) { + noppes.npcs.controllers.data.Animation animation = + noppes.npcs.controllers.AnimationController.Instance.animations.get(counterAnimationId); + if (animation != null) { + npc.display.animationData.setEnabled(true); + npc.display.animationData.setAnimation(animation); + npc.display.animationData.updateClient(); + } + } + } + + counterTriggered = false; + lastAttacker = null; + lastDamageTaken = 0.0f; + } + + private boolean isDirectHit(DamageSource source) { + if (source == null) return false; + if (source.isMagicDamage() || source.isFireDamage() || source.isExplosion()) return false; + return source.getEntity() instanceof EntityLivingBase; + } + /** * Get the damage reduction factor while guarding. * Returns 0.5 for 50% reduction. @@ -128,6 +171,7 @@ public class AbilityGuard extends Ability { super.reset(); lastAttacker = null; counterTriggered = false; + lastDamageTaken = 0.0f; } @Override @@ -139,16 +183,32 @@ public class AbilityGuard extends Ability { public void writeTypeNBT(NBTTagCompound nbt) { nbt.setFloat("damageReduction", damageReduction); nbt.setBoolean("canCounter", canCounter); - nbt.setFloat("counterDamage", counterDamage); + nbt.setString("counterType", counterType.name()); + nbt.setFloat("counterValue", counterValue); nbt.setFloat("counterChance", counterChance); + nbt.setString("counterSound", counterSound); + nbt.setInteger("counterAnimationId", counterAnimationId); } @Override public void readTypeNBT(NBTTagCompound nbt) { this.damageReduction = nbt.hasKey("damageReduction") ? nbt.getFloat("damageReduction") : 0.5f; this.canCounter = nbt.hasKey("canCounter") && nbt.getBoolean("canCounter"); - this.counterDamage = nbt.hasKey("counterDamage") ? nbt.getFloat("counterDamage") : 10.0f; + try { + this.counterType = CounterType.valueOf(nbt.getString("counterType")); + } catch (Exception e) { + this.counterType = CounterType.FLAT; + } + if (nbt.hasKey("counterValue")) { + this.counterValue = nbt.getFloat("counterValue"); + } else if (nbt.hasKey("counterDamage")) { + this.counterValue = nbt.getFloat("counterDamage"); + } else { + this.counterValue = 10.0f; + } this.counterChance = nbt.hasKey("counterChance") ? nbt.getFloat("counterChance") : 0.3f; + this.counterSound = nbt.hasKey("counterSound") ? nbt.getString("counterSound") : "random.wood_click"; + this.counterAnimationId = nbt.hasKey("counterAnimationId") ? nbt.getInteger("counterAnimationId") : -1; } // Getters & Setters @@ -158,9 +218,18 @@ public class AbilityGuard extends Ability { public boolean isCanCounter() { return canCounter; } public void setCanCounter(boolean canCounter) { this.canCounter = canCounter; } - public float getCounterDamage() { return counterDamage; } - public void setCounterDamage(float counterDamage) { this.counterDamage = counterDamage; } + public CounterType getCounterType() { return counterType; } + public void setCounterType(CounterType counterType) { this.counterType = counterType; } + + public float getCounterValue() { return counterValue; } + public void setCounterValue(float counterValue) { this.counterValue = counterValue; } public float getCounterChance() { return counterChance; } public void setCounterChance(float counterChance) { this.counterChance = counterChance; } + + public String getCounterSound() { return counterSound; } + public void setCounterSound(String counterSound) { this.counterSound = counterSound; } + + public int getCounterAnimationId() { return counterAnimationId; } + public void setCounterAnimationId(int counterAnimationId) { this.counterAnimationId = counterAnimationId; } } diff --git a/src/main/java/kamkeel/npcs/controllers/data/ability/type/AbilityHazard.java b/src/main/java/kamkeel/npcs/controllers/data/ability/type/AbilityHazard.java index 9ac5509d5..d211e7516 100644 --- a/src/main/java/kamkeel/npcs/controllers/data/ability/type/AbilityHazard.java +++ b/src/main/java/kamkeel/npcs/controllers/data/ability/type/AbilityHazard.java @@ -290,7 +290,7 @@ public class AbilityHazard extends Ability { entity.hurtResistantTime = 0; } // Apply damage with scripted event support (no knockback for hazard ticks) - boolean wasHit = applyAbilityDamage(npc, entity, damagePerTick, 0, 0); + boolean wasHit = applyAbilityDamage(npc, entity, damagePerTick, 0); if (!wasHit) continue; // Skip debuffs if hit was cancelled } diff --git a/src/main/java/kamkeel/npcs/controllers/data/ability/type/AbilityHeavyHit.java b/src/main/java/kamkeel/npcs/controllers/data/ability/type/AbilityHeavyHit.java index b76412606..288af63d7 100644 --- a/src/main/java/kamkeel/npcs/controllers/data/ability/type/AbilityHeavyHit.java +++ b/src/main/java/kamkeel/npcs/controllers/data/ability/type/AbilityHeavyHit.java @@ -24,8 +24,9 @@ public class AbilityHeavyHit extends Ability { private float damage = 15.0f; private float knockback = 2.0f; - private float knockbackUp = 0.3f; - private int stunTicks = 40; + private int slownessLevel = 1; + private int weaknessLevel = 0; + private int potionDurationSeconds = 2; public AbilityHeavyHit() { this.typeId = "ability.cnpc.heavy_hit"; @@ -40,6 +41,8 @@ public class AbilityHeavyHit extends Ability { this.recoveryTicks = 20; this.telegraphType = TelegraphType.POINT; this.showTelegraph = false; + this.windUpSound = "random.anvil_use"; + this.activeSound = "random.anvil_land"; } @Override @@ -65,12 +68,16 @@ public class AbilityHeavyHit extends Ability { if (world.isRemote || target == null) return; // Apply damage with scripted event support - boolean wasHit = applyAbilityDamage(npc, target, damage, knockback, knockbackUp); + boolean wasHit = applyAbilityDamage(npc, target, damage, knockback); - // Apply stun (slowness + weakness) if the hit wasn't cancelled - if (wasHit && stunTicks > 0) { - target.addPotionEffect(new PotionEffect(Potion.moveSlowdown.id, stunTicks, 10)); - target.addPotionEffect(new PotionEffect(Potion.weakness.id, stunTicks, 2)); + if (wasHit && potionDurationSeconds > 0) { + int durationTicks = potionDurationSeconds * 20; + if (slownessLevel >= 0) { + target.addPotionEffect(new PotionEffect(Potion.moveSlowdown.id, durationTicks, slownessLevel)); + } + if (weaknessLevel >= 0) { + target.addPotionEffect(new PotionEffect(Potion.weakness.id, durationTicks, weaknessLevel)); + } } } @@ -83,16 +90,18 @@ public class AbilityHeavyHit extends Ability { public void writeTypeNBT(NBTTagCompound nbt) { nbt.setFloat("damage", damage); nbt.setFloat("knockback", knockback); - nbt.setFloat("knockbackUp", knockbackUp); - nbt.setInteger("stunTicks", stunTicks); + nbt.setInteger("slownessLevel", slownessLevel); + nbt.setInteger("weaknessLevel", weaknessLevel); + nbt.setInteger("potionDurationSeconds", potionDurationSeconds); } @Override public void readTypeNBT(NBTTagCompound nbt) { this.damage = nbt.hasKey("damage") ? nbt.getFloat("damage") : 15.0f; this.knockback = nbt.hasKey("knockback") ? nbt.getFloat("knockback") : 2.0f; - this.knockbackUp = nbt.hasKey("knockbackUp") ? nbt.getFloat("knockbackUp") : 0.3f; - this.stunTicks = nbt.hasKey("stunTicks") ? nbt.getInteger("stunTicks") : 40; + this.slownessLevel = nbt.hasKey("slownessLevel") ? nbt.getInteger("slownessLevel") : 1; + this.weaknessLevel = nbt.hasKey("weaknessLevel") ? nbt.getInteger("weaknessLevel") : 0; + this.potionDurationSeconds = nbt.hasKey("potionDurationSeconds") ? nbt.getInteger("potionDurationSeconds") : 2; } // Getters & Setters @@ -102,9 +111,12 @@ public class AbilityHeavyHit extends Ability { public float getKnockback() { return knockback; } public void setKnockback(float knockback) { this.knockback = knockback; } - public float getKnockbackUp() { return knockbackUp; } - public void setKnockbackUp(float knockbackUp) { this.knockbackUp = knockbackUp; } + public int getSlownessLevel() { return slownessLevel; } + public void setSlownessLevel(int slownessLevel) { this.slownessLevel = slownessLevel; } - public int getStunTicks() { return stunTicks; } - public void setStunTicks(int stunTicks) { this.stunTicks = stunTicks; } + public int getWeaknessLevel() { return weaknessLevel; } + public void setWeaknessLevel(int weaknessLevel) { this.weaknessLevel = weaknessLevel; } + + public int getPotionDurationSeconds() { return potionDurationSeconds; } + public void setPotionDurationSeconds(int potionDurationSeconds) { this.potionDurationSeconds = potionDurationSeconds; } } diff --git a/src/main/java/kamkeel/npcs/controllers/data/ability/type/AbilityOrb.java b/src/main/java/kamkeel/npcs/controllers/data/ability/type/AbilityOrb.java index afc8f6eb8..cf1555898 100644 --- a/src/main/java/kamkeel/npcs/controllers/data/ability/type/AbilityOrb.java +++ b/src/main/java/kamkeel/npcs/controllers/data/ability/type/AbilityOrb.java @@ -194,7 +194,7 @@ public class AbilityOrb extends Ability { doExplosion(npc, world); } else { // Apply damage with scripted event support - boolean wasHit = applyAbilityDamage(npc, entity, damage, knockback, 0.2f); + boolean wasHit = applyAbilityDamage(npc, entity, damage, knockback); if (wasHit) { applyEffects(entity); } @@ -231,7 +231,7 @@ public class AbilityOrb extends Ability { if (dist <= explosionRadius) { float falloff = 1.0f - (float)(dist / explosionRadius) * explosionDamageFalloff; // Apply damage with scripted event support - boolean wasHit = applyAbilityDamage(npc, blastTarget, damage * falloff, knockback * falloff, 0.3f); + boolean wasHit = applyAbilityDamage(npc, blastTarget, damage * falloff, knockback * falloff); if (wasHit) { applyEffects(blastTarget); } diff --git a/src/main/java/kamkeel/npcs/controllers/data/ability/type/AbilityProjectile.java b/src/main/java/kamkeel/npcs/controllers/data/ability/type/AbilityProjectile.java index b5f47e8b1..4d2143b36 100644 --- a/src/main/java/kamkeel/npcs/controllers/data/ability/type/AbilityProjectile.java +++ b/src/main/java/kamkeel/npcs/controllers/data/ability/type/AbilityProjectile.java @@ -83,7 +83,7 @@ public class AbilityProjectile extends Ability { // Deal instant damage with scripted event support // TODO: Use custom EntityAbilityProjectile for actual tracking - applyAbilityDamageWithDirection(npc, target, damage, knockback, 0.1f, dx, dz); + applyAbilityDamageWithDirection(npc, target, damage, knockback, dx, dz); // Play sound world.playSoundAtEntity(npc, "random.bow", 1.0f, 0.8f); @@ -101,7 +101,7 @@ public class AbilityProjectile extends Ability { if (dist < explosionRadius) { float falloff = 1.0f - (dist / explosionRadius); // Apply splash damage with scripted event support (no knockback) - applyAbilityDamage(npc, living, damage * falloff * 0.5f, 0, 0); + applyAbilityDamage(npc, living, damage * falloff * 0.5f, 0); } } } diff --git a/src/main/java/kamkeel/npcs/controllers/data/ability/type/AbilityShockwave.java b/src/main/java/kamkeel/npcs/controllers/data/ability/type/AbilityShockwave.java index 1204dbc4d..340b92826 100644 --- a/src/main/java/kamkeel/npcs/controllers/data/ability/type/AbilityShockwave.java +++ b/src/main/java/kamkeel/npcs/controllers/data/ability/type/AbilityShockwave.java @@ -27,11 +27,9 @@ public class AbilityShockwave extends Ability { private float pushRadius = 8.0f; private float pushStrength = 1.5f; - private float pushUp = 0.5f; private float damage = 10.0f; private int stunDuration = 0; private int maxTargets = 10; - private boolean aoe = true; // Runtime state private transient boolean executed = false; @@ -47,6 +45,8 @@ public class AbilityShockwave extends Ability { this.activeTicks = 5; this.recoveryTicks = 20; this.telegraphType = TelegraphType.CIRCLE; + this.windUpSound = "random.explode"; + this.activeSound = "random.explode"; } @Override @@ -79,9 +79,6 @@ public class AbilityShockwave extends Ability { if (executed) return; executed = true; - // Play shockwave sound - world.playSoundAtEntity(npc, "random.explode", 0.5f, 1.5f); - // Get all entities in radius AxisAlignedBB box = npc.boundingBox.expand(pushRadius, pushRadius / 2, pushRadius); @SuppressWarnings("unchecked") @@ -116,10 +113,8 @@ public class AbilityShockwave extends Ability { // Scale knockback by distance (closer = stronger) float distFactor = 1.0f - (float)(dist / pushRadius) * 0.5f; float finalPush = pushStrength * distFactor; - float finalPushUp = pushUp * distFactor; - // Apply damage with custom knockback direction - boolean wasHit = applyAbilityDamageWithDirection(npc, entity, damage * distFactor, finalPush, finalPushUp, dx, dz); + boolean wasHit = applyAbilityDamageWithDirection(npc, entity, damage * distFactor, finalPush, dx, dz); // Apply stun if hit connected if (wasHit && stunDuration > 0) { @@ -143,22 +138,18 @@ public class AbilityShockwave extends Ability { public void writeTypeNBT(NBTTagCompound nbt) { nbt.setFloat("pushRadius", pushRadius); nbt.setFloat("pushStrength", pushStrength); - nbt.setFloat("pushUp", pushUp); nbt.setFloat("damage", damage); nbt.setInteger("stunDuration", stunDuration); nbt.setInteger("maxTargets", maxTargets); - nbt.setBoolean("aoe", aoe); } @Override public void readTypeNBT(NBTTagCompound nbt) { this.pushRadius = nbt.hasKey("pushRadius") ? nbt.getFloat("pushRadius") : 8.0f; this.pushStrength = nbt.hasKey("pushStrength") ? nbt.getFloat("pushStrength") : 1.5f; - this.pushUp = nbt.hasKey("pushUp") ? nbt.getFloat("pushUp") : 0.5f; this.damage = nbt.hasKey("damage") ? nbt.getFloat("damage") : 10.0f; this.stunDuration = nbt.hasKey("stunDuration") ? nbt.getInteger("stunDuration") : 0; this.maxTargets = nbt.hasKey("maxTargets") ? nbt.getInteger("maxTargets") : 10; - this.aoe = !nbt.hasKey("aoe") || nbt.getBoolean("aoe"); } // Getters & Setters @@ -168,9 +159,6 @@ public class AbilityShockwave extends Ability { public float getPushStrength() { return pushStrength; } public void setPushStrength(float pushStrength) { this.pushStrength = pushStrength; } - public float getPushUp() { return pushUp; } - public void setPushUp(float pushUp) { this.pushUp = pushUp; } - public float getDamage() { return damage; } public void setDamage(float damage) { this.damage = damage; } @@ -180,6 +168,4 @@ public class AbilityShockwave extends Ability { public int getMaxTargets() { return maxTargets; } public void setMaxTargets(int maxTargets) { this.maxTargets = maxTargets; } - public boolean isAoe() { return aoe; } - public void setAoe(boolean aoe) { this.aoe = aoe; } } diff --git a/src/main/java/kamkeel/npcs/controllers/data/ability/type/AbilitySlam.java b/src/main/java/kamkeel/npcs/controllers/data/ability/type/AbilitySlam.java index 1d72f23cc..321b9058f 100644 --- a/src/main/java/kamkeel/npcs/controllers/data/ability/type/AbilitySlam.java +++ b/src/main/java/kamkeel/npcs/controllers/data/ability/type/AbilitySlam.java @@ -36,8 +36,7 @@ public class AbilitySlam extends Ability { private float radius = 5.0f; private float knockbackStrength = 1.5f; private float leapSpeed = 1.0f; - private float minLeapDistance = 2.0f; - private float maxLeapDistance = 15.0f; + private float leapHeight = 4.0f; // Runtime state private transient double targetX, targetY, targetZ; @@ -58,6 +57,8 @@ public class AbilitySlam extends Ability { this.minRange = 2.0f; this.maxRange = 15.0f; this.telegraphType = TelegraphType.CIRCLE; + this.windUpSound = "mob.irongolem.throw"; + this.activeSound = "random.explode"; } @Override @@ -157,11 +158,11 @@ public class AbilitySlam extends Ability { } // Cap the distance if too far - if (horizontalDist > maxLeapDistance) { - double scale = maxLeapDistance / horizontalDist; + if (horizontalDist > maxRange) { + double scale = maxRange / horizontalDist; dx *= scale; dz *= scale; - horizontalDist = maxLeapDistance; + horizontalDist = maxRange; targetX = npc.posX + dx; targetZ = npc.posZ + dz; } @@ -188,7 +189,7 @@ public class AbilitySlam extends Ability { // Calculate required upward velocity to create a nice arc and land at target height // Peak height should be proportional to horizontal distance for visual appeal - double arcHeight = Math.max(3.0, horizontalDist * 0.3) * leapSpeed; + double arcHeight = Math.max(1.0, leapHeight) * leapSpeed; // Approximate the required initial vertical velocity // Account for gravity and drag - use a simplified model @@ -222,8 +223,6 @@ public class AbilitySlam extends Ability { npc.rotationYaw = targetYaw; npc.rotationYawHead = targetYaw; - // Play launch sound - npc.worldObj.playSoundAtEntity(npc, "mob.irongolem.throw", 0.8f, 0.8f); } @Override @@ -287,15 +286,12 @@ public class AbilitySlam extends Ability { double dx = livingTarget.posX - npc.posX; double dz = livingTarget.posZ - npc.posZ; if (dx * dx + dz * dz <= radius * radius) { - // Apply damage with scripted event support (0.3f is the upward knockback boost) - applyAbilityDamage(npc, livingTarget, damage, knockbackStrength, 0.3f); + // Apply damage with scripted event support + applyAbilityDamage(npc, livingTarget, damage, knockbackStrength); } } } - // Play impact sound - world.playSoundAtEntity(npc, "random.explode", 0.5f, 1.2f); - // Spawn particles spawnSlamParticles(world, npc.posX, npc.posY, npc.posZ); } @@ -418,8 +414,7 @@ public class AbilitySlam extends Ability { nbt.setFloat("radius", radius); nbt.setFloat("knockback", knockbackStrength); nbt.setFloat("leapSpeed", leapSpeed); - nbt.setFloat("minLeapDistance", minLeapDistance); - nbt.setFloat("maxLeapDistance", maxLeapDistance); + nbt.setFloat("leapHeight", leapHeight); } @Override @@ -428,8 +423,7 @@ public class AbilitySlam extends Ability { radius = nbt.hasKey("radius") ? nbt.getFloat("radius") : 5.0f; knockbackStrength = nbt.hasKey("knockback") ? nbt.getFloat("knockback") : 1.5f; leapSpeed = nbt.hasKey("leapSpeed") ? nbt.getFloat("leapSpeed") : 1.0f; - minLeapDistance = nbt.hasKey("minLeapDistance") ? nbt.getFloat("minLeapDistance") : 2.0f; - maxLeapDistance = nbt.hasKey("maxLeapDistance") ? nbt.getFloat("maxLeapDistance") : 15.0f; + leapHeight = nbt.hasKey("leapHeight") ? nbt.getFloat("leapHeight") : 4.0f; } // Getters & Setters @@ -445,9 +439,6 @@ public class AbilitySlam extends Ability { public float getLeapSpeed() { return leapSpeed; } public void setLeapSpeed(float leapSpeed) { this.leapSpeed = leapSpeed; } - public float getMinLeapDistance() { return minLeapDistance; } - public void setMinLeapDistance(float minLeapDistance) { this.minLeapDistance = minLeapDistance; } - - public float getMaxLeapDistance() { return maxLeapDistance; } - public void setMaxLeapDistance(float maxLeapDistance) { this.maxLeapDistance = maxLeapDistance; } + public float getLeapHeight() { return leapHeight; } + public void setLeapHeight(float leapHeight) { this.leapHeight = leapHeight; } } diff --git a/src/main/java/kamkeel/npcs/controllers/data/ability/type/AbilityTeleport.java b/src/main/java/kamkeel/npcs/controllers/data/ability/type/AbilityTeleport.java index f4a4780e8..72971c572 100644 --- a/src/main/java/kamkeel/npcs/controllers/data/ability/type/AbilityTeleport.java +++ b/src/main/java/kamkeel/npcs/controllers/data/ability/type/AbilityTeleport.java @@ -29,26 +29,22 @@ import java.util.Random; public class AbilityTeleport extends Ability { /** - * Pattern for teleport destination. + * Teleport behavior mode. */ - public enum TeleportPattern { - RANDOM, - TOWARD_TARGET, - AWAY_FROM_TARGET, - BEHIND_TARGET, - IN_FRONT_OF_TARGET, - AROUND_TARGET, - TO_TARGET + public enum TeleportMode { + BLINK, + BEHIND, + SINGLE } private static final Random RANDOM = new Random(); // Type-specific parameters - private int blinkCount = 1; + private TeleportMode mode = TeleportMode.BLINK; + private int blinkCount = 3; private int blinkDelayTicks = 10; private float blinkRadius = 8.0f; - private float minBlinkRadius = 3.0f; - private TeleportPattern pattern = TeleportPattern.RANDOM; + private float behindDistance = 2.0f; private boolean requireLineOfSight = true; private boolean damageAtStart = false; private boolean damageAtEnd = false; @@ -72,6 +68,8 @@ public class AbilityTeleport extends Ability { // No telegraph for teleport - it's instant repositioning this.telegraphType = TelegraphType.NONE; this.showTelegraph = false; + this.windUpSound = "mob.endermen.portal"; + this.activeSound = "mob.endermen.portal"; } @Override @@ -100,7 +98,8 @@ public class AbilityTeleport extends Ability { @Override public void onActiveTick(EntityNPCInterface npc, EntityLivingBase target, World world, int tick) { - if (currentBlink >= blinkCount) return; + int blinkLimit = mode == TeleportMode.BLINK ? blinkCount : 1; + if (currentBlink >= blinkLimit) return; ticksSinceLastBlink++; @@ -121,27 +120,17 @@ public class AbilityTeleport extends Ability { Vec3 destination = calculateDestination(npc, target, world); if (destination == null) return; - // Verify line of sight if required - if (requireLineOfSight && !hasLineOfSight(world, oldX, oldY + npc.getEyeHeight(), oldZ, - destination.xCoord, destination.yCoord + npc.getEyeHeight(), destination.zCoord)) { + boolean mustHaveLOS = mode == TeleportMode.BEHIND || requireLineOfSight; + if (mustHaveLOS && !hasLineOfSight(world, oldX, oldY + npc.getEyeHeight(), oldZ, + destination.xCoord, destination.yCoord + npc.getEyeHeight(), destination.zCoord)) { destination = findValidPositionAlongLine(world, npc, oldX, oldY, oldZ, - destination.xCoord, destination.yCoord, destination.zCoord); + destination.xCoord, destination.yCoord, destination.zCoord); if (destination == null) return; } - // Verify destination is safe - if (!isSafeLocation(world, (int)Math.floor(destination.xCoord), - (int)Math.floor(destination.yCoord), - (int)Math.floor(destination.zCoord))) { - double safeY = findSafeY(world, destination.xCoord, destination.yCoord, destination.zCoord); - destination = Vec3.createVectorHelper(destination.xCoord, safeY, destination.zCoord); - - if (!isSafeLocation(world, (int)Math.floor(destination.xCoord), - (int)Math.floor(destination.yCoord), - (int)Math.floor(destination.zCoord))) { - return; - } - } + destination = findSafeDestination(world, oldX, oldY, oldZ, + destination.xCoord, destination.yCoord, destination.zCoord); + if (destination == null) return; // Damage at origin if (damageAtStart) { @@ -158,9 +147,6 @@ public class AbilityTeleport extends Ability { // Spawn particles at destination spawnTeleportParticles(world, destination.xCoord, destination.yCoord, destination.zCoord); - // Play teleport sound - world.playSoundAtEntity(npc, "mob.endermen.portal", 1.0f, 1.0f); - // Damage at destination if (damageAtEnd) { dealDamageAt(npc, world, destination.xCoord, destination.yCoord, destination.zCoord); @@ -189,96 +175,67 @@ public class AbilityTeleport extends Ability { } private Vec3 calculateDestination(EntityNPCInterface npc, EntityLivingBase target, World world) { - double newX, newY, newZ; + if (target == null) return null; - switch (pattern) { - case TOWARD_TARGET: - if (target != null) { - double dx = target.posX - npc.posX; - double dz = target.posZ - npc.posZ; - double dist = Math.sqrt(dx * dx + dz * dz); - if (dist > 0) { - double blinkDist = Math.min(blinkRadius, dist - 2.0); - blinkDist = Math.max(minBlinkRadius, blinkDist); - newX = npc.posX + (dx / dist) * blinkDist; - newZ = npc.posZ + (dz / dist) * blinkDist; - newY = findSafeY(world, newX, npc.posY, newZ); - return Vec3.createVectorHelper(newX, newY, newZ); - } - } - return null; + double newX; + double newY; + double newZ; - case AWAY_FROM_TARGET: - if (target != null) { - double dx = npc.posX - target.posX; - double dz = npc.posZ - target.posZ; - double dist = Math.sqrt(dx * dx + dz * dz); - if (dist > 0) { - dx /= dist; - dz /= dist; - } else { - dx = RANDOM.nextDouble() - 0.5; - dz = RANDOM.nextDouble() - 0.5; - double len = Math.sqrt(dx * dx + dz * dz); - dx /= len; - dz /= len; - } - double blinkDist = minBlinkRadius + RANDOM.nextDouble() * (blinkRadius - minBlinkRadius); - newX = npc.posX + dx * blinkDist; - newZ = npc.posZ + dz * blinkDist; - newY = findSafeY(world, newX, npc.posY, newZ); - return Vec3.createVectorHelper(newX, newY, newZ); - } - return null; - - case BEHIND_TARGET: - if (target != null) { - float targetYaw = (float) Math.toRadians(target.rotationYaw); - double behindX = target.posX + Math.sin(targetYaw) * 3.0; - double behindZ = target.posZ - Math.cos(targetYaw) * 3.0; - newY = findSafeY(world, behindX, target.posY, behindZ); - return Vec3.createVectorHelper(behindX, newY, behindZ); - } - return null; - - case IN_FRONT_OF_TARGET: - if (target != null) { - float targetYaw = (float) Math.toRadians(target.rotationYaw); - double frontX = target.posX - Math.sin(targetYaw) * 3.0; - double frontZ = target.posZ + Math.cos(targetYaw) * 3.0; - newY = findSafeY(world, frontX, target.posY, frontZ); - return Vec3.createVectorHelper(frontX, newY, frontZ); - } - return null; - - case AROUND_TARGET: - if (target != null) { - double angle = RANDOM.nextDouble() * Math.PI * 2; - double dist = minBlinkRadius + RANDOM.nextDouble() * (blinkRadius - minBlinkRadius); - newX = target.posX + Math.cos(angle) * dist; - newZ = target.posZ + Math.sin(angle) * dist; - newY = findSafeY(world, newX, target.posY, newZ); - return Vec3.createVectorHelper(newX, newY, newZ); - } - return null; - - case TO_TARGET: - if (target != null) { - return Vec3.createVectorHelper(target.posX, target.posY, target.posZ); - } - return null; - - case RANDOM: + switch (mode) { + case BEHIND: + double yaw = Math.toRadians(target.rotationYaw); + newX = target.posX + Math.sin(yaw) * behindDistance; + newZ = target.posZ - Math.cos(yaw) * behindDistance; + newY = target.posY; + return Vec3.createVectorHelper(newX, newY, newZ); + case SINGLE: + case BLINK: default: double angle = RANDOM.nextDouble() * Math.PI * 2; - double blinkDist = minBlinkRadius + RANDOM.nextDouble() * (blinkRadius - minBlinkRadius); - newX = npc.posX + Math.cos(angle) * blinkDist; - newZ = npc.posZ + Math.sin(angle) * blinkDist; - newY = findSafeY(world, newX, npc.posY, newZ); + double dist = Math.min(blinkRadius, maxRange); + double offset = RANDOM.nextDouble() * dist; + newX = target.posX + Math.cos(angle) * offset; + newZ = target.posZ + Math.sin(angle) * offset; + newY = target.posY; return Vec3.createVectorHelper(newX, newY, newZ); } } + private Vec3 findSafeDestination(World world, double oldX, double oldY, double oldZ, + double destX, double destY, double destZ) { + int oldBlockX = (int) Math.floor(oldX); + int oldBlockY = (int) Math.floor(oldY); + int oldBlockZ = (int) Math.floor(oldZ); + int destBlockX = (int) Math.floor(destX); + int destBlockY = (int) Math.floor(destY); + int destBlockZ = (int) Math.floor(destZ); + + if (oldBlockX == destBlockX && oldBlockY == destBlockY && oldBlockZ == destBlockZ) { + return null; + } + + double safeY = findSafeYNear(world, destX, destY, destZ); + Vec3 safe = Vec3.createVectorHelper(destX, safeY, destZ); + + if (!isSafeLocation(world, (int) Math.floor(safe.xCoord), + (int) Math.floor(safe.yCoord), (int) Math.floor(safe.zCoord))) { + return null; + } + + return safe; + } + + private double findSafeYNear(World world, double x, double baseY, double z) { + int[] offsets = new int[]{0, 1, -1, 2, -2}; + for (int offset : offsets) { + double y = baseY + offset; + if (isSafeLocation(world, (int) Math.floor(x), (int) Math.floor(y), (int) Math.floor(z))) { + return y; + } + } + return findSafeY(world, x, baseY, z); + } + private boolean hasLineOfSight(World world, double x1, double y1, double z1, double x2, double y2, double z2) { double dx = x2 - x1; @@ -319,7 +276,7 @@ public class AbilityTeleport extends Ability { double dz = z2 - z1; double distance = Math.sqrt(dx * dx + dy * dy + dz * dz); - if (distance < minBlinkRadius) return null; + if (distance < 1.0) return null; dx /= distance; dy /= distance; @@ -328,7 +285,7 @@ public class AbilityTeleport extends Ability { Vec3 lastValid = null; double step = 0.5; - for (double d = minBlinkRadius; d < distance; d += step) { + for (double d = 1.0; d < distance; d += step) { double checkX = x1 + dx * d; double checkY = y1 + dy * d; double checkZ = z1 + dz * d; @@ -394,7 +351,7 @@ public class AbilityTeleport extends Ability { double dist = Math.sqrt(Math.pow(living.posX - x, 2) + Math.pow(living.posZ - z, 2)); if (dist <= damageRadius) { // Apply damage with scripted event support (no knockback for teleport damage) - applyAbilityDamage(npc, living, damage, 0, 0); + applyAbilityDamage(npc, living, damage, 0); } } } @@ -413,11 +370,11 @@ public class AbilityTeleport extends Ability { @Override public void writeTypeNBT(NBTTagCompound nbt) { + nbt.setString("mode", mode.name()); nbt.setInteger("blinkCount", blinkCount); nbt.setInteger("blinkDelayTicks", blinkDelayTicks); nbt.setFloat("blinkRadius", blinkRadius); - nbt.setFloat("minBlinkRadius", minBlinkRadius); - nbt.setString("pattern", pattern.name()); + nbt.setFloat("behindDistance", behindDistance); nbt.setBoolean("requireLineOfSight", requireLineOfSight); nbt.setBoolean("damageAtStart", damageAtStart); nbt.setBoolean("damageAtEnd", damageAtEnd); @@ -427,15 +384,28 @@ public class AbilityTeleport extends Ability { @Override public void readTypeNBT(NBTTagCompound nbt) { - this.blinkCount = nbt.hasKey("blinkCount") ? nbt.getInteger("blinkCount") : 1; + if (nbt.hasKey("mode")) { + try { + this.mode = TeleportMode.valueOf(nbt.getString("mode")); + } catch (Exception e) { + this.mode = TeleportMode.BLINK; + } + } else if (nbt.hasKey("pattern")) { + String legacy = nbt.getString("pattern"); + if ("BEHIND_TARGET".equals(legacy)) { + this.mode = TeleportMode.BEHIND; + } else if ("RANDOM".equals(legacy)) { + this.mode = TeleportMode.BLINK; + } else { + this.mode = TeleportMode.SINGLE; + } + } else { + this.mode = TeleportMode.BLINK; + } + this.blinkCount = nbt.hasKey("blinkCount") ? nbt.getInteger("blinkCount") : 3; this.blinkDelayTicks = nbt.hasKey("blinkDelayTicks") ? nbt.getInteger("blinkDelayTicks") : 10; this.blinkRadius = nbt.hasKey("blinkRadius") ? nbt.getFloat("blinkRadius") : 8.0f; - this.minBlinkRadius = nbt.hasKey("minBlinkRadius") ? nbt.getFloat("minBlinkRadius") : 3.0f; - try { - this.pattern = TeleportPattern.valueOf(nbt.getString("pattern")); - } catch (Exception e) { - this.pattern = TeleportPattern.RANDOM; - } + this.behindDistance = nbt.hasKey("behindDistance") ? nbt.getFloat("behindDistance") : 2.0f; this.requireLineOfSight = !nbt.hasKey("requireLineOfSight") || nbt.getBoolean("requireLineOfSight"); this.damageAtStart = nbt.hasKey("damageAtStart") && nbt.getBoolean("damageAtStart"); this.damageAtEnd = nbt.hasKey("damageAtEnd") && nbt.getBoolean("damageAtEnd"); @@ -444,6 +414,9 @@ public class AbilityTeleport extends Ability { } // Getters & Setters + public TeleportMode getMode() { return mode; } + public void setMode(TeleportMode mode) { this.mode = mode; } + public int getBlinkCount() { return blinkCount; } public void setBlinkCount(int blinkCount) { this.blinkCount = blinkCount; } @@ -453,11 +426,8 @@ public class AbilityTeleport extends Ability { public float getBlinkRadius() { return blinkRadius; } public void setBlinkRadius(float blinkRadius) { this.blinkRadius = blinkRadius; } - public float getMinBlinkRadius() { return minBlinkRadius; } - public void setMinBlinkRadius(float minBlinkRadius) { this.minBlinkRadius = minBlinkRadius; } - - public TeleportPattern getPattern() { return pattern; } - public void setPattern(TeleportPattern pattern) { this.pattern = pattern; } + public float getBehindDistance() { return behindDistance; } + public void setBehindDistance(float behindDistance) { this.behindDistance = behindDistance; } public boolean isRequireLineOfSight() { return requireLineOfSight; } public void setRequireLineOfSight(boolean requireLineOfSight) { this.requireLineOfSight = requireLineOfSight; } diff --git a/src/main/java/kamkeel/npcs/controllers/data/ability/type/AbilityTrap.java b/src/main/java/kamkeel/npcs/controllers/data/ability/type/AbilityTrap.java index 64e6e07bb..9d1090da6 100644 --- a/src/main/java/kamkeel/npcs/controllers/data/ability/type/AbilityTrap.java +++ b/src/main/java/kamkeel/npcs/controllers/data/ability/type/AbilityTrap.java @@ -45,7 +45,6 @@ public class AbilityTrap extends Ability { private float damage = 10.0f; private float damageRadius = 0.0f; private float knockback = 0.5f; - private float knockbackUp = 0.3f; private int stunDuration = 0; private int rootDuration = 40; private int slowDuration = 0; @@ -274,7 +273,7 @@ public class AbilityTrap extends Ability { for (EntityLivingBase entity : affected) { // Apply damage with scripted event support - boolean wasHit = applyAbilityDamage(npc, entity, damage, knockback, knockbackUp); + boolean wasHit = applyAbilityDamage(npc, entity, damage, knockback); // Only apply effects if the hit wasn't cancelled if (wasHit) { @@ -323,7 +322,6 @@ public class AbilityTrap extends Ability { nbt.setFloat("damage", damage); nbt.setFloat("damageRadius", damageRadius); nbt.setFloat("knockback", knockback); - nbt.setFloat("knockbackUp", knockbackUp); nbt.setInteger("stunDuration", stunDuration); nbt.setInteger("rootDuration", rootDuration); nbt.setInteger("slowDuration", slowDuration); @@ -351,7 +349,6 @@ public class AbilityTrap extends Ability { this.damage = nbt.hasKey("damage") ? nbt.getFloat("damage") : 10.0f; this.damageRadius = nbt.hasKey("damageRadius") ? nbt.getFloat("damageRadius") : 0.0f; this.knockback = nbt.hasKey("knockback") ? nbt.getFloat("knockback") : 0.5f; - this.knockbackUp = nbt.hasKey("knockbackUp") ? nbt.getFloat("knockbackUp") : 0.3f; this.stunDuration = nbt.hasKey("stunDuration") ? nbt.getInteger("stunDuration") : 0; this.rootDuration = nbt.hasKey("rootDuration") ? nbt.getInteger("rootDuration") : 40; this.slowDuration = nbt.hasKey("slowDuration") ? nbt.getInteger("slowDuration") : 0; @@ -392,9 +389,6 @@ public class AbilityTrap extends Ability { public float getKnockback() { return knockback; } public void setKnockback(float knockback) { this.knockback = knockback; } - public float getKnockbackUp() { return knockbackUp; } - public void setKnockbackUp(float knockbackUp) { this.knockbackUp = knockbackUp; } - public int getStunDuration() { return stunDuration; } public void setStunDuration(int stunDuration) { this.stunDuration = stunDuration; } diff --git a/src/main/java/kamkeel/npcs/controllers/data/ability/type/AbilityVortex.java b/src/main/java/kamkeel/npcs/controllers/data/ability/type/AbilityVortex.java index ab368cdba..ccd8d4a19 100644 --- a/src/main/java/kamkeel/npcs/controllers/data/ability/type/AbilityVortex.java +++ b/src/main/java/kamkeel/npcs/controllers/data/ability/type/AbilityVortex.java @@ -31,8 +31,6 @@ public class AbilityVortex extends Ability { private float pullRadius = 8.0f; private float pullStrength = 0.8f; - private float minPullDistance = 1.5f; - private float pullToDistance = 0.0f; private float damage = 0.0f; private float knockback = 0.0f; private int stunDuration = 0; @@ -45,6 +43,7 @@ public class AbilityVortex extends Ability { // Runtime state private transient Set pulledEntities = new HashSet<>(); private transient boolean pullComplete = false; + private transient int ticksSincePullDamage = 0; public AbilityVortex() { this.typeId = "ability.cnpc.vortex"; @@ -57,6 +56,8 @@ public class AbilityVortex extends Ability { this.activeTicks = 40; this.recoveryTicks = 20; this.telegraphType = TelegraphType.CIRCLE; + this.windUpSound = "mob.ghast.charge"; + this.activeSound = "mob.ghast.fireball"; } @Override @@ -84,6 +85,7 @@ public class AbilityVortex extends Ability { public void onExecute(EntityNPCInterface npc, EntityLivingBase target, World world) { pulledEntities.clear(); pullComplete = false; + ticksSincePullDamage = 0; if (aoe) { AxisAlignedBB box = npc.boundingBox.expand(pullRadius, pullRadius / 2, pullRadius); @@ -96,7 +98,7 @@ public class AbilityVortex extends Ability { if (entity.isDead) continue; double dist = npc.getDistanceToEntity(entity); - if (dist <= pullRadius && dist > minPullDistance) { + if (dist <= pullRadius) { pulledEntities.add(entity.getUniqueID()); count++; if (count >= maxTargets) break; @@ -106,7 +108,7 @@ public class AbilityVortex extends Ability { // Single target mode - still check pullRadius if (target != null && !target.isDead) { double dist = npc.getDistanceToEntity(target); - if (dist <= pullRadius && dist > minPullDistance) { + if (dist <= pullRadius) { pulledEntities.add(target.getUniqueID()); } } @@ -123,13 +125,8 @@ public class AbilityVortex extends Ability { double destY = npc.posY; double destZ = npc.posZ; - if (pullToDistance > 0) { - double yaw = Math.toRadians(npc.rotationYaw); - destX -= Math.sin(yaw) * pullToDistance; - destZ += Math.cos(yaw) * pullToDistance; - } - boolean anyStillPulling = false; + ticksSincePullDamage++; for (UUID uuid : new HashSet<>(pulledEntities)) { EntityLivingBase entity = findEntity(world, uuid); @@ -143,7 +140,7 @@ public class AbilityVortex extends Ability { double dz = destZ - entity.posZ; double dist = Math.sqrt(dx * dx + dy * dy + dz * dz); - if (dist <= minPullDistance) { + if (dist <= 1.0f) { pulledEntities.remove(uuid); onTargetArrived(npc, entity, world); continue; @@ -152,14 +149,25 @@ public class AbilityVortex extends Ability { anyStillPulling = true; double factor = pullStrength / dist; - entity.motionX = dx * factor; - entity.motionY = dy * factor * 0.5; - entity.motionZ = dz * factor; + double nextX = dx * factor; + double nextY = dy * factor * 0.5; + double nextZ = dz * factor; + + AxisAlignedBB nextBox = entity.boundingBox.copy().offset(nextX, nextY, nextZ); + if (!world.getCollidingBoundingBoxes(entity, nextBox).isEmpty()) { + pulledEntities.remove(uuid); + continue; + } + + entity.motionX = nextX; + entity.motionY = nextY; + entity.motionZ = nextZ; entity.velocityChanged = true; - if (damageOnPull && pullDamage > 0) { - // Apply damage with scripted event support (no knockback during pull) - applyAbilityDamage(npc, entity, pullDamage, 0, 0); + if (damageOnPull && pullDamage > 0 && ticksSincePullDamage >= 10) { + ticksSincePullDamage = 0; + entity.hurtResistantTime = 0; + applyAbilityDamage(npc, entity, pullDamage * 0.5f, 0); } } @@ -170,7 +178,7 @@ public class AbilityVortex extends Ability { private void onTargetArrived(EntityNPCInterface npc, EntityLivingBase entity, World world) { // Apply damage with scripted event support - boolean wasHit = applyAbilityDamage(npc, entity, damage, knockback * 0.5f, 0); + boolean wasHit = applyAbilityDamage(npc, entity, damage, knockback * 0.5f); // Only apply effects if hit wasn't cancelled if (wasHit) { @@ -202,20 +210,20 @@ public class AbilityVortex extends Ability { public void onComplete(EntityNPCInterface npc, EntityLivingBase target) { pulledEntities.clear(); pullComplete = false; + ticksSincePullDamage = 0; } @Override public void onInterrupt(EntityNPCInterface npc, DamageSource source, float damage) { pulledEntities.clear(); pullComplete = false; + ticksSincePullDamage = 0; } @Override public void writeTypeNBT(NBTTagCompound nbt) { nbt.setFloat("pullRadius", pullRadius); nbt.setFloat("pullStrength", pullStrength); - nbt.setFloat("minPullDistance", minPullDistance); - nbt.setFloat("pullToDistance", pullToDistance); nbt.setFloat("damage", damage); nbt.setFloat("knockback", knockback); nbt.setInteger("stunDuration", stunDuration); @@ -230,8 +238,6 @@ public class AbilityVortex extends Ability { public void readTypeNBT(NBTTagCompound nbt) { this.pullRadius = nbt.hasKey("pullRadius") ? nbt.getFloat("pullRadius") : 8.0f; this.pullStrength = nbt.hasKey("pullStrength") ? nbt.getFloat("pullStrength") : 0.8f; - this.minPullDistance = nbt.hasKey("minPullDistance") ? nbt.getFloat("minPullDistance") : 1.5f; - this.pullToDistance = nbt.hasKey("pullToDistance") ? nbt.getFloat("pullToDistance") : 0.0f; this.damage = nbt.hasKey("damage") ? nbt.getFloat("damage") : 0.0f; this.knockback = nbt.hasKey("knockback") ? nbt.getFloat("knockback") : 0.0f; this.stunDuration = nbt.hasKey("stunDuration") ? nbt.getInteger("stunDuration") : 0; @@ -249,12 +255,6 @@ public class AbilityVortex extends Ability { public float getPullStrength() { return pullStrength; } public void setPullStrength(float pullStrength) { this.pullStrength = pullStrength; } - public float getMinPullDistance() { return minPullDistance; } - public void setMinPullDistance(float minPullDistance) { this.minPullDistance = minPullDistance; } - - public float getPullToDistance() { return pullToDistance; } - public void setPullToDistance(float pullToDistance) { this.pullToDistance = pullToDistance; } - public float getDamage() { return damage; } public void setDamage(float damage) { this.damage = damage; } diff --git a/src/main/java/noppes/npcs/DataAbilities.java b/src/main/java/noppes/npcs/DataAbilities.java index 4e77611de..d9655b20a 100644 --- a/src/main/java/noppes/npcs/DataAbilities.java +++ b/src/main/java/noppes/npcs/DataAbilities.java @@ -537,7 +537,7 @@ public class DataAbilities { * @param hitEntity The entity being hit * @param damage The damage amount * @param knockback The horizontal knockback - * @param knockbackUp The vertical knockback + * @param knockbackUp The vertical knockback (deprecated, ignored) * @return The event (with possibly modified values), or null if cancelled */ public AbilityEvent.HitEvent fireHitEvent(Ability ability, EntityLivingBase target, diff --git a/src/main/java/noppes/npcs/ai/CombatHandler.java b/src/main/java/noppes/npcs/ai/CombatHandler.java index e067bf2bd..e3eb85fbe 100644 --- a/src/main/java/noppes/npcs/ai/CombatHandler.java +++ b/src/main/java/noppes/npcs/ai/CombatHandler.java @@ -79,6 +79,15 @@ public class CombatHandler { aggressors.put(el, f + damageAmount); } + // Handle guard counter before interruption + if (npc.abilities.getCurrentAbility() instanceof kamkeel.npcs.controllers.data.ability.type.AbilityGuard) { + kamkeel.npcs.controllers.data.ability.type.AbilityGuard guard = + (kamkeel.npcs.controllers.data.ability.type.AbilityGuard) npc.abilities.getCurrentAbility(); + if (guard.isGuarding() && e instanceof EntityLivingBase) { + guard.onDamageTaken(npc, (EntityLivingBase) e, source, damageAmount); + } + } + // Check for ability interruption npc.abilities.onDamage(source, damageAmount); } diff --git a/src/main/java/noppes/npcs/client/gui/advanced/ability/SubGuiAbilityCharge.java b/src/main/java/noppes/npcs/client/gui/advanced/ability/SubGuiAbilityCharge.java index 009cf0efc..a7b19b05c 100644 --- a/src/main/java/noppes/npcs/client/gui/advanced/ability/SubGuiAbilityCharge.java +++ b/src/main/java/noppes/npcs/client/gui/advanced/ability/SubGuiAbilityCharge.java @@ -35,21 +35,16 @@ public class SubGuiAbilityCharge extends SubGuiAbilityConfig { y += 24; - // Row 2: Knockback + Knockback Up + // Row 2: Knockback addLabel(new GuiNpcLabel(102, "ability.knockback", labelX, y + 5)); addTextField(createFloatField(102, fieldX, y, 50, charge.getKnockback())); - addLabel(new GuiNpcLabel(103, "ability.knockbackUp", col2LabelX, y + 5)); - addTextField(createFloatField(103, col2FieldX, y, 50, charge.getKnockbackUp())); - y += 24; - // Row 3: Max Distance + Hit Radius - addLabel(new GuiNpcLabel(104, "ability.maxDist", labelX, y + 5)); - addTextField(createFloatField(104, fieldX, y, 50, charge.getMaxDistance())); + // Row 3: Hit Width + addLabel(new GuiNpcLabel(104, "ability.hitWidth", labelX, y + 5)); + addTextField(createFloatField(104, fieldX, y, 50, charge.getHitWidth())); - addLabel(new GuiNpcLabel(105, "ability.hitRadius", col2LabelX, y + 5)); - addTextField(createFloatField(105, col2FieldX, y, 50, charge.getHitRadius())); } @Override @@ -58,9 +53,7 @@ public class SubGuiAbilityCharge extends SubGuiAbilityConfig { case 100: charge.setDamage(parseFloat(field, charge.getDamage())); break; case 101: charge.setChargeSpeed(parseFloat(field, charge.getChargeSpeed())); break; case 102: charge.setKnockback(parseFloat(field, charge.getKnockback())); break; - case 103: charge.setKnockbackUp(parseFloat(field, charge.getKnockbackUp())); break; - case 104: charge.setMaxDistance(parseFloat(field, charge.getMaxDistance())); break; - case 105: charge.setHitRadius(parseFloat(field, charge.getHitRadius())); break; + case 104: charge.setHitWidth(parseFloat(field, charge.getHitWidth())); break; } } } diff --git a/src/main/java/noppes/npcs/client/gui/advanced/ability/SubGuiAbilityCutter.java b/src/main/java/noppes/npcs/client/gui/advanced/ability/SubGuiAbilityCutter.java index 965becf29..b825789a8 100644 --- a/src/main/java/noppes/npcs/client/gui/advanced/ability/SubGuiAbilityCutter.java +++ b/src/main/java/noppes/npcs/client/gui/advanced/ability/SubGuiAbilityCutter.java @@ -45,18 +45,18 @@ public class SubGuiAbilityCutter extends SubGuiAbilityConfig { y += 24; - // Row 3: Knockback + Knockback Up + // Row 3: Knockback + Sweep Speed addLabel(new GuiNpcLabel(104, "ability.knockback", labelX, y + 5)); addTextField(createFloatField(104, fieldX, y, 50, cutter.getKnockback())); - addLabel(new GuiNpcLabel(105, "ability.knockbackUp", col2LabelX, y + 5)); - addTextField(createFloatField(105, col2FieldX, y, 50, cutter.getKnockbackUp())); + addLabel(new GuiNpcLabel(105, "ability.sweepSpeed", col2LabelX, y + 5)); + addTextField(createFloatField(105, col2FieldX, y, 50, cutter.getSweepSpeed())); y += 24; // Row 4: Sweep Mode + Piercing addLabel(new GuiNpcLabel(106, "ability.sweepMode", labelX, y + 5)); - String[] sweepModes = {"Instant", "Expanding", "Rotating"}; + String[] sweepModes = {"Swipe", "Spin"}; addButton(new GuiNpcButton(106, fieldX, y, 70, 20, sweepModes, cutter.getSweepMode().ordinal())); addLabel(new GuiNpcLabel(107, "ability.piercing", col2LabelX, y + 5)); @@ -64,12 +64,18 @@ public class SubGuiAbilityCutter extends SubGuiAbilityConfig { y += 24; - // Row 5: Stun Duration + Bleed Duration + // Row 5: Stun Duration + Poison Time addLabel(new GuiNpcLabel(108, "ability.stunDuration", labelX, y + 5)); addTextField(createIntField(108, fieldX, y, 50, cutter.getStunDuration())); - addLabel(new GuiNpcLabel(109, "ability.bleedDuration", col2LabelX, y + 5)); - addTextField(createIntField(109, col2FieldX, y, 50, cutter.getBleedDuration())); + addLabel(new GuiNpcLabel(109, "ability.poisonTime", col2LabelX, y + 5)); + addTextField(createIntField(109, col2FieldX, y, 50, cutter.getPoisonDurationSeconds())); + + y += 24; + + // Row 6: Poison Level + addLabel(new GuiNpcLabel(110, "ability.poisonLvl", labelX, y + 5)); + addTextField(createIntField(110, fieldX, y, 50, cutter.getPoisonLevel())); } @Override @@ -89,9 +95,10 @@ public class SubGuiAbilityCutter extends SubGuiAbilityConfig { case 102: cutter.setArcAngle(parseFloat(field, cutter.getArcAngle())); break; case 103: cutter.setInnerRadius(parseFloat(field, cutter.getInnerRadius())); break; case 104: cutter.setKnockback(parseFloat(field, cutter.getKnockback())); break; - case 105: cutter.setKnockbackUp(parseFloat(field, cutter.getKnockbackUp())); break; + case 105: cutter.setSweepSpeed(parseFloat(field, cutter.getSweepSpeed())); break; case 108: cutter.setStunDuration(field.getInteger()); break; - case 109: cutter.setBleedDuration(field.getInteger()); break; + case 109: cutter.setPoisonDurationSeconds(field.getInteger()); break; + case 110: cutter.setPoisonLevel(field.getInteger()); break; } } } diff --git a/src/main/java/noppes/npcs/client/gui/advanced/ability/SubGuiAbilityGuard.java b/src/main/java/noppes/npcs/client/gui/advanced/ability/SubGuiAbilityGuard.java index 009b21755..4858445fb 100644 --- a/src/main/java/noppes/npcs/client/gui/advanced/ability/SubGuiAbilityGuard.java +++ b/src/main/java/noppes/npcs/client/gui/advanced/ability/SubGuiAbilityGuard.java @@ -28,34 +28,58 @@ public class SubGuiAbilityGuard extends SubGuiAbilityConfig { int col2FieldX = guiLeft + 225; // Row 1: Damage Reduction - addLabel(new GuiNpcLabel(100, "ability.dmgReduction", labelX, y + 5)); + addLabel(new GuiNpcLabel(100, "ability.dmgReduce", labelX, y + 5)); addTextField(createFloatField(100, fieldX, y, 50, guard.getDamageReduction())); y += 24; - // Row 2: Can Counter + Counter Damage + // Row 2: Can Counter + Counter Type addLabel(new GuiNpcLabel(101, "ability.canCounter", labelX, y + 5)); addButton(new GuiNpcButton(101, fieldX, y, 50, 20, new String[]{"gui.no", "gui.yes"}, guard.isCanCounter() ? 1 : 0)); - addLabel(new GuiNpcLabel(102, "ability.counterDmg", col2LabelX, y + 5)); - GuiNpcTextField counterDmgField = createFloatField(102, col2FieldX, y, 40, guard.getCounterDamage()); - counterDmgField.setEnabled(guard.isCanCounter()); - addTextField(counterDmgField); + addLabel(new GuiNpcLabel(102, "ability.counterType", col2LabelX, y + 5)); + String[] types = {"Flat", "Percent"}; + GuiNpcButton counterTypeButton = new GuiNpcButton(102, col2FieldX, y, 60, 20, types, guard.getCounterType().ordinal()); + counterTypeButton.setEnabled(guard.isCanCounter()); + addButton(counterTypeButton); y += 24; - // Row 3: Counter Chance - addLabel(new GuiNpcLabel(103, "ability.counterChance", labelX, y + 5)); - GuiNpcTextField counterChanceField = createFloatField(103, fieldX, y, 50, guard.getCounterChance()); + // Row 3: Counter Value + Counter Chance + addLabel(new GuiNpcLabel(103, "ability.counterValue", labelX, y + 5)); + GuiNpcTextField counterValueField = createFloatField(103, fieldX, y, 50, guard.getCounterValue()); + counterValueField.setEnabled(guard.isCanCounter()); + addTextField(counterValueField); + + addLabel(new GuiNpcLabel(104, "ability.counterChance", col2LabelX, y + 5)); + GuiNpcTextField counterChanceField = createFloatField(104, col2FieldX, y, 50, guard.getCounterChance()); counterChanceField.setEnabled(guard.isCanCounter()); addTextField(counterChanceField); + + y += 24; + + // Row 4: Counter Sound + Counter Animation + addLabel(new GuiNpcLabel(105, "ability.counterSound", labelX, y + 5)); + GuiNpcTextField counterSoundField = new GuiNpcTextField(105, this, fontRendererObj, fieldX, y, 100, 20, guard.getCounterSound()); + counterSoundField.setEnabled(guard.isCanCounter()); + addTextField(counterSoundField); + + addLabel(new GuiNpcLabel(106, "ability.counterAnim", col2LabelX, y + 5)); + GuiNpcTextField counterAnimField = createIntField(106, col2FieldX, y, 50, guard.getCounterAnimationId()); + counterAnimField.setEnabled(guard.isCanCounter()); + addTextField(counterAnimField); } @Override protected void handleTypeButton(int id, GuiNpcButton button) { - if (id == 101) { - guard.setCanCounter(button.getValue() == 1); - initGui(); + switch (id) { + case 101: + guard.setCanCounter(button.getValue() == 1); + initGui(); + break; + case 102: + guard.setCounterType(AbilityGuard.CounterType.values()[button.getValue()]); + break; } } @@ -63,8 +87,10 @@ public class SubGuiAbilityGuard extends SubGuiAbilityConfig { protected void handleTypeTextField(int id, GuiNpcTextField field) { switch (id) { case 100: guard.setDamageReduction(parseFloat(field, guard.getDamageReduction())); break; - case 102: guard.setCounterDamage(parseFloat(field, guard.getCounterDamage())); break; - case 103: guard.setCounterChance(parseFloat(field, guard.getCounterChance())); break; + case 103: guard.setCounterValue(parseFloat(field, guard.getCounterValue())); break; + case 104: guard.setCounterChance(parseFloat(field, guard.getCounterChance())); break; + case 105: guard.setCounterSound(field.getText()); break; + case 106: guard.setCounterAnimationId(field.getInteger()); break; } } } diff --git a/src/main/java/noppes/npcs/client/gui/advanced/ability/SubGuiAbilityHeavyHit.java b/src/main/java/noppes/npcs/client/gui/advanced/ability/SubGuiAbilityHeavyHit.java index e569b9baf..c045833b9 100644 --- a/src/main/java/noppes/npcs/client/gui/advanced/ability/SubGuiAbilityHeavyHit.java +++ b/src/main/java/noppes/npcs/client/gui/advanced/ability/SubGuiAbilityHeavyHit.java @@ -26,30 +26,37 @@ public class SubGuiAbilityHeavyHit extends SubGuiAbilityConfig { int col2LabelX = guiLeft + 145; int col2FieldX = guiLeft + 205; - // Row 1: Damage + Stun Ticks + // Row 1: Damage + Potion Time addLabel(new GuiNpcLabel(100, "ability.damage", labelX, y + 5)); addTextField(createFloatField(100, fieldX, y, 50, heavyHit.getDamage())); - addLabel(new GuiNpcLabel(101, "ability.stunTicks", col2LabelX, y + 5)); - addTextField(createIntField(101, col2FieldX, y, 50, heavyHit.getStunTicks())); + addLabel(new GuiNpcLabel(101, "ability.potionTime", col2LabelX, y + 5)); + addTextField(createIntField(101, col2FieldX, y, 50, heavyHit.getPotionDurationSeconds())); y += 24; - // Row 2: Knockback + Knockback Up + // Row 2: Knockback + Slowness Level addLabel(new GuiNpcLabel(102, "ability.knockback", labelX, y + 5)); addTextField(createFloatField(102, fieldX, y, 50, heavyHit.getKnockback())); - addLabel(new GuiNpcLabel(103, "ability.knockbackUp", col2LabelX, y + 5)); - addTextField(createFloatField(103, col2FieldX, y, 50, heavyHit.getKnockbackUp())); + addLabel(new GuiNpcLabel(103, "ability.slownessLvl", col2LabelX, y + 5)); + addTextField(createIntField(103, col2FieldX, y, 50, heavyHit.getSlownessLevel())); + + y += 24; + + // Row 3: Weakness Level + addLabel(new GuiNpcLabel(104, "ability.weaknessLvl", labelX, y + 5)); + addTextField(createIntField(104, fieldX, y, 50, heavyHit.getWeaknessLevel())); } @Override protected void handleTypeTextField(int id, GuiNpcTextField field) { switch (id) { case 100: heavyHit.setDamage(parseFloat(field, heavyHit.getDamage())); break; - case 101: heavyHit.setStunTicks(field.getInteger()); break; + case 101: heavyHit.setPotionDurationSeconds(field.getInteger()); break; case 102: heavyHit.setKnockback(parseFloat(field, heavyHit.getKnockback())); break; - case 103: heavyHit.setKnockbackUp(parseFloat(field, heavyHit.getKnockbackUp())); break; + case 103: heavyHit.setSlownessLevel(field.getInteger()); break; + case 104: heavyHit.setWeaknessLevel(field.getInteger()); break; } } } diff --git a/src/main/java/noppes/npcs/client/gui/advanced/ability/SubGuiAbilityShockwave.java b/src/main/java/noppes/npcs/client/gui/advanced/ability/SubGuiAbilityShockwave.java index 12342f8ed..9230e242c 100644 --- a/src/main/java/noppes/npcs/client/gui/advanced/ability/SubGuiAbilityShockwave.java +++ b/src/main/java/noppes/npcs/client/gui/advanced/ability/SubGuiAbilityShockwave.java @@ -3,7 +3,6 @@ package noppes.npcs.client.gui.advanced.ability; import kamkeel.npcs.controllers.data.ability.type.AbilityShockwave; import noppes.npcs.client.gui.util.IAbilityConfigCallback; import noppes.npcs.client.gui.advanced.SubGuiAbilityConfig; -import noppes.npcs.client.gui.util.GuiNpcButton; import noppes.npcs.client.gui.util.GuiNpcLabel; import noppes.npcs.client.gui.util.GuiNpcTextField; @@ -36,21 +35,21 @@ public class SubGuiAbilityShockwave extends SubGuiAbilityConfig { y += 24; - // Row 2: Push Strength + Push Up + // Row 2: Push Strength addLabel(new GuiNpcLabel(102, "ability.pushStrength", labelX, y + 5)); addTextField(createFloatField(102, fieldX, y, 50, shockwave.getPushStrength())); - addLabel(new GuiNpcLabel(103, "ability.pushUp", col2LabelX, y + 5)); - addTextField(createFloatField(103, col2FieldX, y, 50, shockwave.getPushUp())); - y += 24; // Row 3: Stun Duration + Max Targets - addLabel(new GuiNpcLabel(104, "ability.stunDuration", labelX, y + 5)); - addTextField(createIntField(104, fieldX, y, 50, shockwave.getStunDuration())); + addLabel(new GuiNpcLabel(103, "ability.stunDuration", labelX, y + 5)); + addTextField(createIntField(103, fieldX, y, 50, shockwave.getStunDuration())); - addLabel(new GuiNpcLabel(105, "ability.maxTargets", col2LabelX, y + 5)); - addTextField(createIntField(105, col2FieldX, y, 50, shockwave.getMaxTargets())); + addLabel(new GuiNpcLabel(104, "ability.maxTargets", col2LabelX, y + 5)); + addTextField(createIntField(104, col2FieldX, y, 50, shockwave.getMaxTargets())); + + y += 24; + addLabel(new GuiNpcLabel(105, "ability.shockwaveFalloff", labelX, y + 5)); } @Override @@ -59,9 +58,8 @@ public class SubGuiAbilityShockwave extends SubGuiAbilityConfig { case 100: shockwave.setDamage(parseFloat(field, shockwave.getDamage())); break; case 101: shockwave.setPushRadius(parseFloat(field, shockwave.getPushRadius())); break; case 102: shockwave.setPushStrength(parseFloat(field, shockwave.getPushStrength())); break; - case 103: shockwave.setPushUp(parseFloat(field, shockwave.getPushUp())); break; - case 104: shockwave.setStunDuration(field.getInteger()); break; - case 105: shockwave.setMaxTargets(field.getInteger()); break; + case 103: shockwave.setStunDuration(field.getInteger()); break; + case 104: shockwave.setMaxTargets(field.getInteger()); break; } } } diff --git a/src/main/java/noppes/npcs/client/gui/advanced/ability/SubGuiAbilitySlam.java b/src/main/java/noppes/npcs/client/gui/advanced/ability/SubGuiAbilitySlam.java index 5afe2276b..2fdb0d7fb 100644 --- a/src/main/java/noppes/npcs/client/gui/advanced/ability/SubGuiAbilitySlam.java +++ b/src/main/java/noppes/npcs/client/gui/advanced/ability/SubGuiAbilitySlam.java @@ -3,7 +3,6 @@ package noppes.npcs.client.gui.advanced.ability; import kamkeel.npcs.controllers.data.ability.type.AbilitySlam; import noppes.npcs.client.gui.util.IAbilityConfigCallback; import noppes.npcs.client.gui.advanced.SubGuiAbilityConfig; -import noppes.npcs.client.gui.util.GuiNpcButton; import noppes.npcs.client.gui.util.GuiNpcLabel; import noppes.npcs.client.gui.util.GuiNpcTextField; @@ -45,12 +44,9 @@ public class SubGuiAbilitySlam extends SubGuiAbilityConfig { y += 24; - // Row 3: Min/Max Leap Distance - addLabel(new GuiNpcLabel(104, "ability.minDist", labelX, y + 5)); - addTextField(createFloatField(104, fieldX, y, 50, slam.getMinLeapDistance())); - - addLabel(new GuiNpcLabel(105, "ability.maxDist", col2LabelX, y + 5)); - addTextField(createFloatField(105, col2FieldX, y, 50, slam.getMaxLeapDistance())); + // Row 3: Leap Height + addLabel(new GuiNpcLabel(104, "ability.leapHeight", labelX, y + 5)); + addTextField(createFloatField(104, fieldX, y, 50, slam.getLeapHeight())); } @Override @@ -60,8 +56,7 @@ public class SubGuiAbilitySlam extends SubGuiAbilityConfig { case 101: slam.setRadius(parseFloat(field, slam.getRadius())); break; case 102: slam.setKnockbackStrength(parseFloat(field, slam.getKnockbackStrength())); break; case 103: slam.setLeapSpeed(parseFloat(field, slam.getLeapSpeed())); break; - case 104: slam.setMinLeapDistance(parseFloat(field, slam.getMinLeapDistance())); break; - case 105: slam.setMaxLeapDistance(parseFloat(field, slam.getMaxLeapDistance())); break; + case 104: slam.setLeapHeight(parseFloat(field, slam.getLeapHeight())); break; } } } diff --git a/src/main/java/noppes/npcs/client/gui/advanced/ability/SubGuiAbilityTeleport.java b/src/main/java/noppes/npcs/client/gui/advanced/ability/SubGuiAbilityTeleport.java index 1f6a74ab0..c4e9154e5 100644 --- a/src/main/java/noppes/npcs/client/gui/advanced/ability/SubGuiAbilityTeleport.java +++ b/src/main/java/noppes/npcs/client/gui/advanced/ability/SubGuiAbilityTeleport.java @@ -27,55 +27,77 @@ public class SubGuiAbilityTeleport extends SubGuiAbilityConfig { int col2LabelX = guiLeft + 145; int col2FieldX = guiLeft + 205; - // Row 1: Pattern - addLabel(new GuiNpcLabel(100, "ability.pattern", labelX, y + 5)); - String[] patterns = {"Random", "Toward", "Away", "Behind", "InFront", "Around", "ToTarget"}; - addButton(new GuiNpcButton(100, fieldX, y, 80, 20, patterns, teleport.getPattern().ordinal())); + // Row 1: Mode + addLabel(new GuiNpcLabel(100, "ability.mode", labelX, y + 5)); + String[] modes = {"Blink", "Behind", "Single"}; + addButton(new GuiNpcButton(100, fieldX, y, 80, 20, modes, teleport.getMode().ordinal())); y += 24; - // Row 2: Blink Radius + Min Blink Radius - addLabel(new GuiNpcLabel(101, "ability.blinkRadius", labelX, y + 5)); - addTextField(createFloatField(101, fieldX, y, 50, teleport.getBlinkRadius())); + switch (teleport.getMode()) { + case BLINK: + // Row 2: Blink Radius + Blink Count + addLabel(new GuiNpcLabel(101, "ability.blinkRadius", labelX, y + 5)); + addTextField(createFloatField(101, fieldX, y, 50, teleport.getBlinkRadius())); - addLabel(new GuiNpcLabel(102, "ability.minBlinkRad", col2LabelX, y + 5)); - addTextField(createFloatField(102, col2FieldX, y, 50, teleport.getMinBlinkRadius())); + addLabel(new GuiNpcLabel(102, "ability.blinkCount", col2LabelX, y + 5)); + addTextField(createIntField(102, col2FieldX, y, 50, teleport.getBlinkCount())); + + y += 24; + + // Row 3: Blink Delay + Line of Sight + addLabel(new GuiNpcLabel(103, "ability.blinkDelay", labelX, y + 5)); + addTextField(createIntField(103, fieldX, y, 50, teleport.getBlinkDelayTicks())); + + addLabel(new GuiNpcLabel(105, "ability.lineOfSight", col2LabelX, y + 5)); + addButton(new GuiNpcButton(105, col2FieldX, y, 50, 20, new String[]{"gui.no", "gui.yes"}, teleport.isRequireLineOfSight() ? 1 : 0)); + y += 24; + break; + case SINGLE: + // Row 2: Blink Radius + Line of Sight + addLabel(new GuiNpcLabel(101, "ability.blinkRadius", labelX, y + 5)); + addTextField(createFloatField(101, fieldX, y, 50, teleport.getBlinkRadius())); + + addLabel(new GuiNpcLabel(105, "ability.lineOfSight", col2LabelX, y + 5)); + addButton(new GuiNpcButton(105, col2FieldX, y, 50, 20, new String[]{"gui.no", "gui.yes"}, teleport.isRequireLineOfSight() ? 1 : 0)); + y += 24; + break; + case BEHIND: + // Row 2: Behind Distance + addLabel(new GuiNpcLabel(104, "ability.behindDistance", labelX, y + 5)); + addTextField(createFloatField(104, fieldX, y, 50, teleport.getBehindDistance())); + y += 24; + break; + } + + // Damage + Damage Radius + addLabel(new GuiNpcLabel(106, "ability.damage", labelX, y + 5)); + addTextField(createFloatField(106, fieldX, y, 50, teleport.getDamage())); + + addLabel(new GuiNpcLabel(107, "ability.dmgRadius", col2LabelX, y + 5)); + addTextField(createFloatField(107, col2FieldX, y, 50, teleport.getDamageRadius())); y += 24; - // Row 3: Blink Count + Blink Delay - addLabel(new GuiNpcLabel(103, "ability.blinkCount", labelX, y + 5)); - addTextField(createIntField(103, fieldX, y, 50, teleport.getBlinkCount())); + // Damage at Start/End + addLabel(new GuiNpcLabel(108, "ability.dmgAtStart", labelX, y + 5)); + addButton(new GuiNpcButton(108, fieldX, y, 50, 20, new String[]{"gui.no", "gui.yes"}, teleport.isDamageAtStart() ? 1 : 0)); - addLabel(new GuiNpcLabel(104, "ability.blinkDelay", col2LabelX, y + 5)); - addTextField(createIntField(104, col2FieldX, y, 50, teleport.getBlinkDelayTicks())); - - y += 24; - - // Row 4: Damage + Damage Radius - addLabel(new GuiNpcLabel(105, "ability.damage", labelX, y + 5)); - addTextField(createFloatField(105, fieldX, y, 50, teleport.getDamage())); - - addLabel(new GuiNpcLabel(106, "ability.dmgRadius", col2LabelX, y + 5)); - addTextField(createFloatField(106, col2FieldX, y, 50, teleport.getDamageRadius())); - - y += 24; - - // Row 5: Damage at Start/End + Require LOS - addLabel(new GuiNpcLabel(107, "ability.dmgAtStart", labelX, y + 5)); - addButton(new GuiNpcButton(107, fieldX, y, 50, 20, new String[]{"gui.no", "gui.yes"}, teleport.isDamageAtStart() ? 1 : 0)); - - addLabel(new GuiNpcLabel(108, "ability.dmgAtEnd", col2LabelX, y + 5)); - addButton(new GuiNpcButton(108, col2FieldX, y, 50, 20, new String[]{"gui.no", "gui.yes"}, teleport.isDamageAtEnd() ? 1 : 0)); + addLabel(new GuiNpcLabel(109, "ability.dmgAtEnd", col2LabelX, y + 5)); + addButton(new GuiNpcButton(109, col2FieldX, y, 50, 20, new String[]{"gui.no", "gui.yes"}, teleport.isDamageAtEnd() ? 1 : 0)); } @Override protected void handleTypeButton(int id, GuiNpcButton button) { int value = button.getValue(); switch (id) { - case 100: teleport.setPattern(AbilityTeleport.TeleportPattern.values()[value]); break; - case 107: teleport.setDamageAtStart(value == 1); break; - case 108: teleport.setDamageAtEnd(value == 1); break; + case 100: + teleport.setMode(AbilityTeleport.TeleportMode.values()[value]); + initGui(); + break; + case 105: teleport.setRequireLineOfSight(value == 1); break; + case 108: teleport.setDamageAtStart(value == 1); break; + case 109: teleport.setDamageAtEnd(value == 1); break; } } @@ -83,11 +105,11 @@ public class SubGuiAbilityTeleport extends SubGuiAbilityConfig { protected void handleTypeTextField(int id, GuiNpcTextField field) { switch (id) { case 101: teleport.setBlinkRadius(parseFloat(field, teleport.getBlinkRadius())); break; - case 102: teleport.setMinBlinkRadius(parseFloat(field, teleport.getMinBlinkRadius())); break; - case 103: teleport.setBlinkCount(field.getInteger()); break; - case 104: teleport.setBlinkDelayTicks(field.getInteger()); break; - case 105: teleport.setDamage(parseFloat(field, teleport.getDamage())); break; - case 106: teleport.setDamageRadius(parseFloat(field, teleport.getDamageRadius())); break; + case 102: teleport.setBlinkCount(field.getInteger()); break; + case 103: teleport.setBlinkDelayTicks(field.getInteger()); break; + case 104: teleport.setBehindDistance(parseFloat(field, teleport.getBehindDistance())); break; + case 106: teleport.setDamage(parseFloat(field, teleport.getDamage())); break; + case 107: teleport.setDamageRadius(parseFloat(field, teleport.getDamageRadius())); break; } } } diff --git a/src/main/java/noppes/npcs/client/gui/advanced/ability/SubGuiAbilityTrap.java b/src/main/java/noppes/npcs/client/gui/advanced/ability/SubGuiAbilityTrap.java index fd1a67bc6..8c8d92bb4 100644 --- a/src/main/java/noppes/npcs/client/gui/advanced/ability/SubGuiAbilityTrap.java +++ b/src/main/java/noppes/npcs/client/gui/advanced/ability/SubGuiAbilityTrap.java @@ -64,12 +64,9 @@ public class SubGuiAbilityTrap extends SubGuiAbilityConfig { y += 24; - // Row 5: Knockback + Knockback Up + // Row 5: Knockback addLabel(new GuiNpcLabel(108, "ability.knockback", labelX, y + 5)); addTextField(createFloatField(108, fieldX, y, 50, trap.getKnockback())); - - addLabel(new GuiNpcLabel(109, "ability.knockbackUp", col2LabelX, y + 5)); - addTextField(createFloatField(109, col2FieldX, y, 50, trap.getKnockbackUp())); } @Override @@ -90,7 +87,6 @@ public class SubGuiAbilityTrap extends SubGuiAbilityConfig { case 106: trap.setRootDuration(field.getInteger()); break; case 107: trap.setStunDuration(field.getInteger()); break; case 108: trap.setKnockback(parseFloat(field, trap.getKnockback())); break; - case 109: trap.setKnockbackUp(parseFloat(field, trap.getKnockbackUp())); break; } } } diff --git a/src/main/resources/assets/customnpcs/lang/en_US.lang b/src/main/resources/assets/customnpcs/lang/en_US.lang index cd1982f21..73124d9bf 100644 --- a/src/main/resources/assets/customnpcs/lang/en_US.lang +++ b/src/main/resources/assets/customnpcs/lang/en_US.lang @@ -1519,6 +1519,15 @@ ability.lifetime=Lifetime ability.stunTicks=Stun ability.stunDur=Stun Dur ability.rootDur=Root Dur +ability.rootDuration=Root Duration +ability.stunDuration=Stun Duration +ability.leapHeight=Leap Height +ability.hitWidth=Hit Width +ability.potionTime=Potion Time (s) +ability.weaknessLvl=Weakness Lvl +ability.poisonTime=Poison Time (s) +ability.slownessLvl=Slowness Lvl +ability.poisonLvl=Poison Lvl # Slam Settings ability.leapSpeed=Leap Speed @@ -1550,6 +1559,8 @@ ability.maxTargets=Max Targets ability.dashMode=Mode ability.dash.aggressive=Aggressive ability.dash.defensive=Defensive +ability.mode=Mode +ability.behindDistance=Behind Dist # Teleport Settings ability.blinkCount=Blinks @@ -1576,6 +1587,10 @@ ability.dmgReduce=Dmg Reduce ability.counterDmg=Counter Dmg ability.canCounter=Counter ability.counterChance=Counter % +ability.counterType=Counter Type +ability.counterValue=Counter Value +ability.counterSound=Counter Sound +ability.counterAnim=Counter Anim # Heal Settings ability.healAmount=Amount @@ -1631,6 +1646,7 @@ ability.activeColor=Active Color # Shockwave Settings ability.pushRadius=Push Radius ability.pushStrength=Push Str +ability.shockwaveFalloff=Damage/knockback drop off with distance # Ability Config GUI ability.typeId=Type ID