From 563b6f7a26ab73bf73b6af9ef2faf0883040c76c Mon Sep 17 00:00:00 2001 From: Kam Date: Mon, 26 Jan 2026 22:02:51 -0500 Subject: [PATCH] Ability Effects --- .../controllers/data/ability/Ability.java | 63 +++++- .../data/ability/AbilityEffect.java | 146 +++++++++++++ .../data/ability/type/AbilityCutter.java | 45 +--- .../data/ability/type/AbilityHeavyHit.java | 46 +--- .../data/ability/type/AbilityShockwave.java | 20 +- .../data/ability/type/AbilityTeleport.java | 17 +- .../data/ability/type/AbilityTrap.java | 87 +------- .../data/ability/type/AbilityVortex.java | 54 ++--- .../advanced/ability/SubGuiAbilityCharge.java | 27 ++- .../advanced/ability/SubGuiAbilityCutter.java | 42 ++-- .../advanced/ability/SubGuiAbilityDisc.java | 17 ++ .../ability/SubGuiAbilityEffects.java | 197 ++++++++++++++++++ .../ability/SubGuiAbilityEnergyBeam.java | 17 ++ .../advanced/ability/SubGuiAbilityGuard.java | 26 +++ .../advanced/ability/SubGuiAbilityHazard.java | 24 +++ .../ability/SubGuiAbilityHeavyHit.java | 50 +++-- .../ability/SubGuiAbilityLaserShot.java | 17 ++ .../advanced/ability/SubGuiAbilityOrb.java | 17 ++ .../ability/SubGuiAbilityProjectile.java | 24 +++ .../ability/SubGuiAbilityShockwave.java | 36 +++- .../advanced/ability/SubGuiAbilitySlam.java | 28 ++- .../ability/SubGuiAbilitySweeper.java | 17 ++ .../ability/SubGuiAbilityTeleport.java | 24 +++ .../advanced/ability/SubGuiAbilityTrap.java | 37 ++-- .../advanced/ability/SubGuiAbilityVortex.java | 33 +-- .../assets/customnpcs/lang/en_US.lang | 12 +- 26 files changed, 799 insertions(+), 324 deletions(-) create mode 100644 src/main/java/kamkeel/npcs/controllers/data/ability/AbilityEffect.java create mode 100644 src/main/java/noppes/npcs/client/gui/advanced/ability/SubGuiAbilityEffects.java 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 3f2165718..d7a8b9eab 100644 --- a/src/main/java/kamkeel/npcs/controllers/data/ability/Ability.java +++ b/src/main/java/kamkeel/npcs/controllers/data/ability/Ability.java @@ -78,6 +78,9 @@ public abstract class Ability implements IAbility { // Custom data for external mods protected NBTTagCompound customData = new NBTTagCompound(); + // Configurable potion effects + protected List effects = new ArrayList<>(); + // ═══════════════════════════════════════════════════════════════════ // EXECUTION STATE (not saved, reset each combat) // ═══════════════════════════════════════════════════════════════════ @@ -224,6 +227,21 @@ public abstract class Ability implements IAbility { hitEntity.velocityChanged = true; } + /** + * Applies all configured effects to the given entity. + * Call this after damage is applied to the target. + * + * @param entity The entity to apply effects to + */ + protected void applyEffects(EntityLivingBase entity) { + if (entity == null || effects.isEmpty()) { + return; + } + for (AbilityEffect effect : effects) { + effect.apply(entity); + } + } + public float getTelegraphRadius() { return 5.0f; } @@ -662,6 +680,13 @@ public abstract class Ability implements IAbility { for (Condition c : conditions) condList.appendTag(c.writeNBT()); nbt.setTag("conditions", condList); + // Effects + NBTTagList effectList = new NBTTagList(); + for (AbilityEffect effect : effects) { + effectList.appendTag(effect.writeNBT()); + } + nbt.setTag("effects", effectList); + // Type-specific NBTTagCompound typeNBT = new NBTTagCompound(); writeTypeNBT(typeNBT); @@ -735,6 +760,18 @@ public abstract class Ability implements IAbility { if (c != null) conditions.add(c); } + // Effects + effects.clear(); + if (nbt.hasKey("effects")) { + NBTTagList effectList = nbt.getTagList("effects", 10); + for (int i = 0; i < effectList.tagCount(); i++) { + AbilityEffect effect = AbilityEffect.fromNBT(effectList.getCompoundTagAt(i)); + if (effect != null && effect.isValid()) { + effects.add(effect); + } + } + } + readTypeNBT(nbt.getCompoundTag("typeData")); } @@ -807,7 +844,7 @@ public abstract class Ability implements IAbility { } public void setCooldownTicks(int cooldownTicks) { - this.cooldownTicks = cooldownTicks; + this.cooldownTicks = Math.max(0, cooldownTicks); } public int getWindUpTicks() { @@ -815,7 +852,7 @@ public abstract class Ability implements IAbility { } public void setWindUpTicks(int windUpTicks) { - this.windUpTicks = windUpTicks; + this.windUpTicks = Math.max(0, windUpTicks); } public int getActiveTicks() { @@ -823,7 +860,7 @@ public abstract class Ability implements IAbility { } public void setActiveTicks(int activeTicks) { - this.activeTicks = activeTicks; + this.activeTicks = Math.max(1, activeTicks); } public int getRecoveryTicks() { @@ -831,7 +868,7 @@ public abstract class Ability implements IAbility { } public void setRecoveryTicks(int recoveryTicks) { - this.recoveryTicks = recoveryTicks; + this.recoveryTicks = Math.max(0, recoveryTicks); } public boolean isInterruptible() { @@ -963,6 +1000,24 @@ public abstract class Ability implements IAbility { conditions.add(c); } + public List getEffects() { + return effects; + } + + public void setEffects(List effects) { + this.effects = effects != null ? effects : new ArrayList<>(); + } + + public void addEffect(AbilityEffect effect) { + if (effect != null && effect.isValid()) { + effects.add(effect); + } + } + + public void clearEffects() { + effects.clear(); + } + // ═══════════════════════════════════════════════════════════════════ // IAbility API METHODS // ═══════════════════════════════════════════════════════════════════ diff --git a/src/main/java/kamkeel/npcs/controllers/data/ability/AbilityEffect.java b/src/main/java/kamkeel/npcs/controllers/data/ability/AbilityEffect.java new file mode 100644 index 000000000..47e03f10d --- /dev/null +++ b/src/main/java/kamkeel/npcs/controllers/data/ability/AbilityEffect.java @@ -0,0 +1,146 @@ +package kamkeel.npcs.controllers.data.ability; + +import net.minecraft.entity.EntityLivingBase; +import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.potion.Potion; +import net.minecraft.potion.PotionEffect; + +/** + * Represents a configurable potion effect that can be applied by abilities. + * Provides a unified system for managing debuffs like slowness, weakness, poison, etc. + */ +public class AbilityEffect { + + public enum EffectType { + NONE("gui.none", -1), + SLOWNESS("potion.moveSlowdown", Potion.moveSlowdown.id), + WEAKNESS("potion.weakness", Potion.weakness.id), + POISON("potion.poison", Potion.poison.id), + WITHER("potion.wither", Potion.wither.id), + BLINDNESS("potion.blindness", Potion.blindness.id), + NAUSEA("potion.confusion", Potion.confusion.id), + HUNGER("potion.hunger", Potion.hunger.id), + MINING_FATIGUE("potion.digSlowDown", Potion.digSlowdown.id); + + private final String langKey; + private final int potionId; + + EffectType(String langKey, int potionId) { + this.langKey = langKey; + this.potionId = potionId; + } + + public String getLangKey() { + return langKey; + } + + public int getPotionId() { + return potionId; + } + + public static EffectType fromOrdinal(int ordinal) { + EffectType[] values = values(); + if (ordinal >= 0 && ordinal < values.length) { + return values[ordinal]; + } + return NONE; + } + } + + private EffectType type = EffectType.NONE; + private int durationTicks = 60; + private int amplifier = 0; // 0-10 + + public AbilityEffect() { + } + + public AbilityEffect(EffectType type, int durationTicks, int amplifier) { + this.type = type; + this.durationTicks = Math.max(1, durationTicks); + this.amplifier = Math.max(0, Math.min(10, amplifier)); + } + + /** + * Creates a copy of this effect. + */ + public AbilityEffect copy() { + return new AbilityEffect(type, durationTicks, amplifier); + } + + /** + * Applies this effect to the given entity. + * Does nothing if type is NONE. + */ + public void apply(EntityLivingBase entity) { + if (entity == null || type == EffectType.NONE) { + return; + } + + int potionId = type.getPotionId(); + if (potionId >= 0) { + entity.addPotionEffect(new PotionEffect(potionId, durationTicks, amplifier)); + } + } + + /** + * Writes this effect to NBT. + */ + public NBTTagCompound writeNBT() { + NBTTagCompound nbt = new NBTTagCompound(); + nbt.setInteger("type", type.ordinal()); + nbt.setInteger("duration", durationTicks); + nbt.setInteger("amplifier", amplifier); + return nbt; + } + + /** + * Reads this effect from NBT. + */ + public void readNBT(NBTTagCompound nbt) { + this.type = EffectType.fromOrdinal(nbt.getInteger("type")); + this.durationTicks = nbt.hasKey("duration") ? nbt.getInteger("duration") : 60; + this.amplifier = nbt.hasKey("amplifier") ? nbt.getInteger("amplifier") : 0; + } + + /** + * Creates an AbilityEffect from NBT. + */ + public static AbilityEffect fromNBT(NBTTagCompound nbt) { + AbilityEffect effect = new AbilityEffect(); + effect.readNBT(nbt); + return effect; + } + + // Getters & Setters + + public EffectType getType() { + return type; + } + + public void setType(EffectType type) { + this.type = type != null ? type : EffectType.NONE; + } + + public int getDurationTicks() { + return durationTicks; + } + + public void setDurationTicks(int durationTicks) { + this.durationTicks = Math.max(1, durationTicks); + } + + public int getAmplifier() { + return amplifier; + } + + public void setAmplifier(int amplifier) { + this.amplifier = Math.max(0, Math.min(10, amplifier)); + } + + /** + * Returns true if this effect is configured (not NONE). + */ + public boolean isValid() { + return type != EffectType.NONE; + } +} 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 611d0a4a6..8274b4d79 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 @@ -7,8 +7,6 @@ import kamkeel.npcs.controllers.data.ability.TargetingMode; import kamkeel.npcs.controllers.data.telegraph.TelegraphType; import net.minecraft.entity.EntityLivingBase; import net.minecraft.nbt.NBTTagCompound; -import net.minecraft.potion.Potion; -import net.minecraft.potion.PotionEffect; import net.minecraft.util.AxisAlignedBB; import net.minecraft.util.DamageSource; import net.minecraft.world.World; @@ -41,9 +39,6 @@ public class AbilityCutter extends Ability { private SweepMode sweepMode = SweepMode.SWIPE; private float sweepSpeed = 6.0f; - private int stunDuration = 0; - private int poisonDurationSeconds = 0; - private int poisonLevel = 0; private boolean piercing = true; private float innerRadius = 0.0f; @@ -161,15 +156,9 @@ public class AbilityCutter extends Ability { // Apply damage with scripted event support boolean wasHit = applyAbilityDamage(npc, entity, actualDamage, knockback); - // Only apply effects if hit wasn't cancelled + // Apply effects if hit wasn't cancelled if (wasHit) { - if (stunDuration > 0) { - entity.addPotionEffect(new PotionEffect(Potion.moveSlowdown.id, stunDuration, 10)); - entity.addPotionEffect(new PotionEffect(Potion.weakness.id, stunDuration, 2)); - } - if (poisonDurationSeconds > 0) { - entity.addPotionEffect(new PotionEffect(Potion.poison.id, poisonDurationSeconds * 20, poisonLevel)); - } + applyEffects(entity); } } } @@ -206,9 +195,6 @@ public class AbilityCutter extends Ability { nbt.setFloat("knockback", knockback); nbt.setString("sweepMode", sweepMode.name()); nbt.setFloat("sweepSpeed", sweepSpeed); - nbt.setInteger("stunDuration", stunDuration); - nbt.setInteger("poisonDurationSeconds", poisonDurationSeconds); - nbt.setInteger("poisonLevel", poisonLevel); nbt.setBoolean("piercing", piercing); nbt.setFloat("innerRadius", innerRadius); } @@ -225,9 +211,6 @@ public class AbilityCutter extends Ability { this.sweepMode = SweepMode.SWIPE; } this.sweepSpeed = nbt.hasKey("sweepSpeed") ? nbt.getFloat("sweepSpeed") : 6.0f; - this.stunDuration = nbt.hasKey("stunDuration") ? nbt.getInteger("stunDuration") : 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; } @@ -281,30 +264,6 @@ public class AbilityCutter extends Ability { this.sweepSpeed = sweepSpeed; } - public int getStunDuration() { - return stunDuration; - } - - public void setStunDuration(int stunDuration) { - this.stunDuration = stunDuration; - } - - public int getPoisonDurationSeconds() { - return poisonDurationSeconds; - } - - public void setPoisonDurationSeconds(int poisonDurationSeconds) { - this.poisonDurationSeconds = poisonDurationSeconds; - } - - public int getPoisonLevel() { - return poisonLevel; - } - - public void setPoisonLevel(int poisonLevel) { - this.poisonLevel = poisonLevel; - } - public boolean isPiercing() { return piercing; } 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 abdcc6f86..fc68200b7 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 @@ -7,8 +7,6 @@ import kamkeel.npcs.controllers.data.ability.TargetingMode; import kamkeel.npcs.controllers.data.telegraph.TelegraphType; import net.minecraft.entity.EntityLivingBase; import net.minecraft.nbt.NBTTagCompound; -import net.minecraft.potion.Potion; -import net.minecraft.potion.PotionEffect; import net.minecraft.world.World; import noppes.npcs.client.gui.advanced.SubGuiAbilityConfig; import noppes.npcs.client.gui.advanced.ability.SubGuiAbilityHeavyHit; @@ -23,9 +21,6 @@ public class AbilityHeavyHit extends Ability { private float damage = 8.0f; private float knockback = 2.0f; - private int slownessLevel = 1; - private int weaknessLevel = 0; - private int potionDurationSeconds = 2; public AbilityHeavyHit() { this.typeId = "ability.cnpc.heavy_hit"; @@ -73,14 +68,9 @@ public class AbilityHeavyHit extends Ability { // Apply damage with scripted event support boolean wasHit = applyAbilityDamage(npc, target, damage, knockback); - 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)); - } + // Apply effects if hit wasn't cancelled + if (wasHit) { + applyEffects(target); } } @@ -93,18 +83,12 @@ public class AbilityHeavyHit extends Ability { public void writeTypeNBT(NBTTagCompound nbt) { nbt.setFloat("damage", damage); nbt.setFloat("knockback", knockback); - 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") : 8.0f; this.knockback = nbt.hasKey("knockback") ? nbt.getFloat("knockback") : 2.0f; - 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 @@ -123,28 +107,4 @@ public class AbilityHeavyHit extends Ability { public void setKnockback(float knockback) { this.knockback = knockback; } - - public int getSlownessLevel() { - return slownessLevel; - } - - public void setSlownessLevel(int slownessLevel) { - this.slownessLevel = slownessLevel; - } - - 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/AbilityShockwave.java b/src/main/java/kamkeel/npcs/controllers/data/ability/type/AbilityShockwave.java index 1708b49bd..b5a35831f 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 @@ -7,8 +7,6 @@ import kamkeel.npcs.controllers.data.ability.TargetingMode; import kamkeel.npcs.controllers.data.telegraph.TelegraphType; import net.minecraft.entity.EntityLivingBase; import net.minecraft.nbt.NBTTagCompound; -import net.minecraft.potion.Potion; -import net.minecraft.potion.PotionEffect; import net.minecraft.util.AxisAlignedBB; import net.minecraft.util.DamageSource; import net.minecraft.world.World; @@ -28,7 +26,6 @@ public class AbilityShockwave extends Ability { private float pushRadius = 8.0f; private float pushStrength = 1.5f; private float damage = 8.0f; - private int stunDuration = 0; private int maxTargets = 10; // Runtime state @@ -122,10 +119,9 @@ public class AbilityShockwave extends Ability { // Apply damage with custom knockback direction boolean wasHit = applyAbilityDamageWithDirection(npc, entity, damage * distFactor, finalPush, dx, dz); - // Apply stun if hit connected - if (wasHit && stunDuration > 0) { - entity.addPotionEffect(new PotionEffect(Potion.moveSlowdown.id, stunDuration, 10)); - entity.addPotionEffect(new PotionEffect(Potion.weakness.id, stunDuration, 2)); + // Apply effects if hit connected + if (wasHit) { + applyEffects(entity); } } } @@ -145,7 +141,6 @@ public class AbilityShockwave extends Ability { nbt.setFloat("pushRadius", pushRadius); nbt.setFloat("pushStrength", pushStrength); nbt.setFloat("damage", damage); - nbt.setInteger("stunDuration", stunDuration); nbt.setInteger("maxTargets", maxTargets); } @@ -154,7 +149,6 @@ public class AbilityShockwave extends Ability { this.pushRadius = nbt.hasKey("pushRadius") ? nbt.getFloat("pushRadius") : 8.0f; this.pushStrength = nbt.hasKey("pushStrength") ? nbt.getFloat("pushStrength") : 1.5f; this.damage = nbt.hasKey("damage") ? nbt.getFloat("damage") : 8.0f; - this.stunDuration = nbt.hasKey("stunDuration") ? nbt.getInteger("stunDuration") : 0; this.maxTargets = nbt.hasKey("maxTargets") ? nbt.getInteger("maxTargets") : 10; } @@ -183,14 +177,6 @@ public class AbilityShockwave extends Ability { this.damage = damage; } - public int getStunDuration() { - return stunDuration; - } - - public void setStunDuration(int stunDuration) { - this.stunDuration = stunDuration; - } - public int getMaxTargets() { return maxTargets; } 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 ad5989f25..a79223d5d 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 @@ -261,8 +261,13 @@ public class AbilityTeleport extends Ability { int blockY = MathHelper.floor_double(checkY); int blockZ = MathHelper.floor_double(checkZ); + // Skip out-of-world coordinates + if (blockY < 0 || blockY >= 256) { + continue; + } + Block block = world.getBlock(blockX, blockY, blockZ); - if (block.getMaterial().isSolid() && block.isOpaqueCube()) { + if (block != null && block.getMaterial().isSolid() && block.isOpaqueCube()) { return false; } } @@ -327,10 +332,20 @@ public class AbilityTeleport extends Ability { } private boolean isSafeLocation(World world, int x, int y, int z) { + // Bounds check - ensure we're within valid world coordinates + if (y < 1 || y >= 255) { + return false; + } + Block groundBlock = world.getBlock(x, y - 1, z); Block feetBlock = world.getBlock(x, y, z); Block headBlock = world.getBlock(x, y + 1, z); + // Defensive null checks (shouldn't happen in MC 1.7.10, but safe) + if (groundBlock == null || feetBlock == null || headBlock == null) { + return false; + } + return groundBlock.getMaterial().isSolid() && !feetBlock.getMaterial().isSolid() && !headBlock.getMaterial().isSolid(); 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 fa2fefb4c..77ac4a5fe 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 @@ -8,8 +8,6 @@ import kamkeel.npcs.controllers.data.telegraph.TelegraphInstance; import kamkeel.npcs.controllers.data.telegraph.TelegraphType; import net.minecraft.entity.EntityLivingBase; import net.minecraft.nbt.NBTTagCompound; -import net.minecraft.potion.Potion; -import net.minecraft.potion.PotionEffect; import net.minecraft.util.AxisAlignedBB; import net.minecraft.util.DamageSource; import net.minecraft.world.World; @@ -45,12 +43,6 @@ public class AbilityTrap extends Ability { private float damage = 6.0f; private float damageRadius = 0.0f; private float knockback = 0.5f; - private int stunDuration = 0; - private int rootDuration = 40; - private int slowDuration = 0; - private int slowLevel = 1; - private int poisonDuration = 0; - private int poisonLevel = 0; private boolean visible = true; // Offset parameters - trap spawns near target, not exactly on them @@ -262,24 +254,9 @@ public class AbilityTrap extends Ability { // Apply damage with scripted event support boolean wasHit = applyAbilityDamage(npc, entity, damage, knockback); - // Only apply effects if the hit wasn't cancelled + // Apply effects if the hit wasn't cancelled if (wasHit) { - if (stunDuration > 0) { - entity.addPotionEffect(new PotionEffect(Potion.moveSlowdown.id, stunDuration, 10)); - entity.addPotionEffect(new PotionEffect(Potion.weakness.id, stunDuration, 2)); - } - - if (rootDuration > 0) { - entity.addPotionEffect(new PotionEffect(Potion.moveSlowdown.id, rootDuration, 127)); - } - - if (slowDuration > 0) { - entity.addPotionEffect(new PotionEffect(Potion.moveSlowdown.id, slowDuration, slowLevel)); - } - - if (poisonDuration > 0 && poisonLevel >= 0) { - entity.addPotionEffect(new PotionEffect(Potion.poison.id, poisonDuration, poisonLevel)); - } + applyEffects(entity); } } } @@ -309,12 +286,6 @@ public class AbilityTrap extends Ability { nbt.setFloat("damage", damage); nbt.setFloat("damageRadius", damageRadius); nbt.setFloat("knockback", knockback); - nbt.setInteger("stunDuration", stunDuration); - nbt.setInteger("rootDuration", rootDuration); - nbt.setInteger("slowDuration", slowDuration); - nbt.setInteger("slowLevel", slowLevel); - nbt.setInteger("poisonDuration", poisonDuration); - nbt.setInteger("poisonLevel", poisonLevel); nbt.setBoolean("visible", visible); nbt.setFloat("minOffset", minOffset); nbt.setFloat("maxOffset", maxOffset); @@ -336,12 +307,6 @@ public class AbilityTrap extends Ability { this.damage = nbt.hasKey("damage") ? nbt.getFloat("damage") : 6.0f; this.damageRadius = nbt.hasKey("damageRadius") ? nbt.getFloat("damageRadius") : 0.0f; this.knockback = nbt.hasKey("knockback") ? nbt.getFloat("knockback") : 0.5f; - 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; - this.slowLevel = nbt.hasKey("slowLevel") ? nbt.getInteger("slowLevel") : 1; - this.poisonDuration = nbt.hasKey("poisonDuration") ? nbt.getInteger("poisonDuration") : 0; - this.poisonLevel = nbt.hasKey("poisonLevel") ? nbt.getInteger("poisonLevel") : 0; this.visible = !nbt.hasKey("visible") || nbt.getBoolean("visible"); this.minOffset = nbt.hasKey("minOffset") ? nbt.getFloat("minOffset") : 0.0f; this.maxOffset = nbt.hasKey("maxOffset") ? nbt.getFloat("maxOffset") : 1.5f; @@ -421,54 +386,6 @@ public class AbilityTrap extends Ability { this.knockback = knockback; } - public int getStunDuration() { - return stunDuration; - } - - public void setStunDuration(int stunDuration) { - this.stunDuration = stunDuration; - } - - public int getRootDuration() { - return rootDuration; - } - - public void setRootDuration(int rootDuration) { - this.rootDuration = rootDuration; - } - - public int getSlowDuration() { - return slowDuration; - } - - public void setSlowDuration(int slowDuration) { - this.slowDuration = slowDuration; - } - - public int getSlowLevel() { - return slowLevel; - } - - public void setSlowLevel(int slowLevel) { - this.slowLevel = slowLevel; - } - - public int getPoisonDuration() { - return poisonDuration; - } - - public void setPoisonDuration(int poisonDuration) { - this.poisonDuration = poisonDuration; - } - - public int getPoisonLevel() { - return poisonLevel; - } - - public void setPoisonLevel(int poisonLevel) { - this.poisonLevel = poisonLevel; - } - public boolean isVisible() { return visible; } 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 f0e08dd56..666b19bbc 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 @@ -7,8 +7,6 @@ import kamkeel.npcs.controllers.data.ability.TargetingMode; import kamkeel.npcs.controllers.data.telegraph.TelegraphType; import net.minecraft.entity.EntityLivingBase; import net.minecraft.nbt.NBTTagCompound; -import net.minecraft.potion.Potion; -import net.minecraft.potion.PotionEffect; import net.minecraft.util.AxisAlignedBB; import net.minecraft.util.DamageSource; import net.minecraft.world.World; @@ -32,8 +30,6 @@ public class AbilityVortex extends Ability { private float pullStrength = 0.8f; private float damage = 0.0f; private float knockback = 0.0f; - private int stunDuration = 0; - private int rootDuration = 0; private boolean aoe = false; private int maxTargets = 5; private boolean damageOnPull = false; @@ -134,7 +130,7 @@ public class AbilityVortex extends Ability { ticksSincePullDamage++; for (UUID uuid : new HashSet<>(pulledEntities)) { - EntityLivingBase entity = findEntity(world, uuid); + EntityLivingBase entity = findEntity(npc, world, uuid); if (entity == null || entity.isDead) { pulledEntities.remove(uuid); continue; @@ -187,25 +183,23 @@ public class AbilityVortex extends Ability { // Only apply effects if hit wasn't cancelled if (wasHit) { - if (stunDuration > 0) { - entity.addPotionEffect(new PotionEffect(Potion.moveSlowdown.id, stunDuration, 10)); - entity.addPotionEffect(new PotionEffect(Potion.weakness.id, stunDuration, 2)); - } - - if (rootDuration > 0) { - entity.addPotionEffect(new PotionEffect(Potion.moveSlowdown.id, rootDuration, 127)); - } + applyEffects(entity); } } + /** + * Find an entity by UUID within the vortex pull area. + * Uses AABB search instead of iterating all loaded entities. + */ @SuppressWarnings("unchecked") - private EntityLivingBase findEntity(World world, UUID uuid) { - for (Object obj : world.loadedEntityList) { - if (obj instanceof EntityLivingBase) { - EntityLivingBase entity = (EntityLivingBase) obj; - if (entity.getUniqueID().equals(uuid)) { - return entity; - } + private EntityLivingBase findEntity(EntityNPCInterface npc, World world, UUID uuid) { + // Search within pull radius (entities being pulled should be within this area) + AxisAlignedBB searchBox = npc.boundingBox.expand(pullRadius, pullRadius / 2, pullRadius); + List nearbyEntities = world.getEntitiesWithinAABB(EntityLivingBase.class, searchBox); + + for (EntityLivingBase entity : nearbyEntities) { + if (entity.getUniqueID().equals(uuid)) { + return entity; } } return null; @@ -231,8 +225,6 @@ public class AbilityVortex extends Ability { nbt.setFloat("pullStrength", pullStrength); nbt.setFloat("damage", damage); nbt.setFloat("knockback", knockback); - nbt.setInteger("stunDuration", stunDuration); - nbt.setInteger("rootDuration", rootDuration); nbt.setBoolean("aoe", aoe); nbt.setInteger("maxTargets", maxTargets); nbt.setBoolean("damageOnPull", damageOnPull); @@ -245,8 +237,6 @@ public class AbilityVortex extends Ability { this.pullStrength = nbt.hasKey("pullStrength") ? nbt.getFloat("pullStrength") : 0.8f; 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; - this.rootDuration = nbt.hasKey("rootDuration") ? nbt.getInteger("rootDuration") : 0; this.aoe = nbt.hasKey("aoe") && nbt.getBoolean("aoe"); this.maxTargets = nbt.hasKey("maxTargets") ? nbt.getInteger("maxTargets") : 5; this.damageOnPull = nbt.hasKey("damageOnPull") && nbt.getBoolean("damageOnPull"); @@ -286,22 +276,6 @@ public class AbilityVortex extends Ability { this.knockback = knockback; } - public int getStunDuration() { - return stunDuration; - } - - public void setStunDuration(int stunDuration) { - this.stunDuration = stunDuration; - } - - public int getRootDuration() { - return rootDuration; - } - - public void setRootDuration(int rootDuration) { - this.rootDuration = rootDuration; - } - public boolean isAoe() { return aoe; } 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 4d7486c5e..ea35797c4 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 @@ -1,10 +1,15 @@ package noppes.npcs.client.gui.advanced.ability; +import kamkeel.npcs.controllers.data.ability.AbilityEffect; import kamkeel.npcs.controllers.data.ability.type.AbilityCharge; 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; import noppes.npcs.client.gui.util.IAbilityConfigCallback; +import noppes.npcs.client.gui.util.SubGuiInterface; + +import java.util.List; /** * GUI for configuring Charge ability type-specific settings. @@ -41,10 +46,30 @@ public class SubGuiAbilityCharge extends SubGuiAbilityConfig { y += 24; - // Row 3: Hit Width + // Row 3: Hit Width + Effects addLabel(new GuiNpcLabel(104, "ability.hitWidth", labelX, y + 5)); addTextField(createFloatField(104, fieldX, y, 50, charge.getHitWidth())); + addButton(new GuiNpcButton(150, col2LabelX, y, 80, 20, "ability.effects")); + } + + @Override + protected void handleTypeButton(int id, GuiNpcButton button) { + if (id == 150) { + setSubGui(new SubGuiAbilityEffects(charge.getEffects())); + } + } + + @Override + public void subGuiClosed(SubGuiInterface subgui) { + super.subGuiClosed(subgui); + if (subgui instanceof SubGuiAbilityEffects) { + SubGuiAbilityEffects effectsGui = (SubGuiAbilityEffects) subgui; + List result = effectsGui.getResult(); + if (result != null) { + charge.setEffects(result); + } + } } @Override 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 514391f8a..10f5ab8c1 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 @@ -1,11 +1,15 @@ package noppes.npcs.client.gui.advanced.ability; +import kamkeel.npcs.controllers.data.ability.AbilityEffect; import kamkeel.npcs.controllers.data.ability.type.AbilityCutter; 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; import noppes.npcs.client.gui.util.IAbilityConfigCallback; +import noppes.npcs.client.gui.util.SubGuiInterface; + +import java.util.List; /** * GUI for configuring Cutter ability type-specific settings. @@ -64,18 +68,8 @@ public class SubGuiAbilityCutter extends SubGuiAbilityConfig { y += 24; - // 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.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())); + // Row 5: Effects button + addButton(new GuiNpcButton(150, labelX, y, 80, 20, "ability.effects")); } @Override @@ -88,6 +82,21 @@ public class SubGuiAbilityCutter extends SubGuiAbilityConfig { case 107: cutter.setPiercing(value == 1); break; + case 150: + setSubGui(new SubGuiAbilityEffects(cutter.getEffects())); + break; + } + } + + @Override + public void subGuiClosed(SubGuiInterface subgui) { + super.subGuiClosed(subgui); + if (subgui instanceof SubGuiAbilityEffects) { + SubGuiAbilityEffects effectsGui = (SubGuiAbilityEffects) subgui; + List result = effectsGui.getResult(); + if (result != null) { + cutter.setEffects(result); + } } } @@ -112,15 +121,6 @@ public class SubGuiAbilityCutter extends SubGuiAbilityConfig { case 105: cutter.setSweepSpeed(parseFloat(field, cutter.getSweepSpeed())); break; - case 108: - cutter.setStunDuration(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/SubGuiAbilityDisc.java b/src/main/java/noppes/npcs/client/gui/advanced/ability/SubGuiAbilityDisc.java index 373752fa6..2a3439af1 100644 --- a/src/main/java/noppes/npcs/client/gui/advanced/ability/SubGuiAbilityDisc.java +++ b/src/main/java/noppes/npcs/client/gui/advanced/ability/SubGuiAbilityDisc.java @@ -1,5 +1,6 @@ package noppes.npcs.client.gui.advanced.ability; +import kamkeel.npcs.controllers.data.ability.AbilityEffect; import kamkeel.npcs.controllers.data.ability.type.AbilityDisc; import noppes.npcs.client.gui.SubGuiColorSelector; import noppes.npcs.client.gui.advanced.SubGuiAbilityConfig; @@ -9,6 +10,8 @@ import noppes.npcs.client.gui.util.GuiNpcTextField; import noppes.npcs.client.gui.util.IAbilityConfigCallback; import noppes.npcs.client.gui.util.SubGuiInterface; +import java.util.List; + /** * GUI for configuring Disc ability type-specific settings. */ @@ -86,6 +89,11 @@ public class SubGuiAbilityDisc extends SubGuiAbilityConfig { addLabel(new GuiNpcLabel(111, "ability.maxDist", col2LabelX, y + 5)); addTextField(createFloatField(111, col2FieldX, y, 50, disc.getMaxDistance())); + + y += 24; + + // Row 7: Effects button + addButton(new GuiNpcButton(150, labelX, y, 80, 20, "ability.effects")); } @Override @@ -163,6 +171,9 @@ public class SubGuiAbilityDisc extends SubGuiAbilityConfig { case 108: disc.setExplosive(value == 1); break; + case 150: + setSubGui(new SubGuiAbilityEffects(disc.getEffects())); + break; } } @@ -201,6 +212,12 @@ public class SubGuiAbilityDisc extends SubGuiAbilityConfig { } editingVisualColorId = 0; initGui(); + } else if (subgui instanceof SubGuiAbilityEffects) { + SubGuiAbilityEffects effectsGui = (SubGuiAbilityEffects) subgui; + List result = effectsGui.getResult(); + if (result != null) { + disc.setEffects(result); + } } else { super.subGuiClosed(subgui); } diff --git a/src/main/java/noppes/npcs/client/gui/advanced/ability/SubGuiAbilityEffects.java b/src/main/java/noppes/npcs/client/gui/advanced/ability/SubGuiAbilityEffects.java new file mode 100644 index 000000000..103d87224 --- /dev/null +++ b/src/main/java/noppes/npcs/client/gui/advanced/ability/SubGuiAbilityEffects.java @@ -0,0 +1,197 @@ +package noppes.npcs.client.gui.advanced.ability; + +import kamkeel.npcs.controllers.data.ability.AbilityEffect; +import net.minecraft.client.gui.GuiButton; +import noppes.npcs.client.gui.util.GuiNpcButton; +import noppes.npcs.client.gui.util.GuiNpcLabel; +import noppes.npcs.client.gui.util.GuiNpcTextField; +import noppes.npcs.client.gui.util.ITextfieldListener; +import noppes.npcs.client.gui.util.SubGuiInterface; + +import java.util.ArrayList; +import java.util.List; + +/** + * SubGui for editing ability effects (potion effects that apply to targets). + * Allows adding/removing effects and configuring type, duration, and amplifier. + */ +public class SubGuiAbilityEffects extends SubGuiInterface implements ITextfieldListener { + + private static final int MAX_EFFECTS = 5; + + // Effect type names for display + private static final String[] EFFECT_TYPE_NAMES = { + "gui.none", + "potion.moveSlowdown", + "potion.weakness", + "potion.poison", + "potion.wither", + "potion.blindness", + "potion.confusion", + "potion.hunger", + "potion.digSlowDown" + }; + + // Working copy of effects + private List effects; + private boolean cancelled = false; + + public SubGuiAbilityEffects(List existingEffects) { + // Create working copies of effects + this.effects = new ArrayList<>(); + if (existingEffects != null) { + for (AbilityEffect effect : existingEffects) { + this.effects.add(effect.copy()); + } + } + + setBackground("menubg.png"); + xSize = 280; + ySize = 180; + } + + @Override + public void initGui() { + super.initGui(); + + int y = guiTop + 8; + int labelX = guiLeft + 8; + + // Title + addLabel(new GuiNpcLabel(0, "ability.effects", labelX, y)); + y += 16; + + // Column headers + addLabel(new GuiNpcLabel(1, "gui.type", guiLeft + 10, y)); + addLabel(new GuiNpcLabel(2, "gui.duration", guiLeft + 115, y)); + addLabel(new GuiNpcLabel(3, "gui.amp", guiLeft + 175, y)); + y += 14; + + // Effect rows + for (int i = 0; i < effects.size() && i < MAX_EFFECTS; i++) { + AbilityEffect effect = effects.get(i); + int baseId = 1 + i * 10; + + // Type selector button + int typeIndex = effect.getType().ordinal(); + addButton(new GuiNpcButton(baseId, guiLeft + 8, y, 100, 20, EFFECT_TYPE_NAMES, typeIndex)); + + // Duration text field + GuiNpcTextField durField = new GuiNpcTextField(baseId + 1, this, fontRendererObj, + guiLeft + 112, y, 50, 20, String.valueOf(effect.getDurationTicks())); + durField.setIntegersOnly(); + durField.setMinMaxDefault(1, 12000, 60); + addTextField(durField); + + // Amplifier selector (0-10) + String[] ampValues = new String[11]; + for (int a = 0; a <= 10; a++) { + ampValues[a] = String.valueOf(a); + } + addButton(new GuiNpcButton(baseId + 2, guiLeft + 168, y, 40, 20, ampValues, effect.getAmplifier())); + + // Delete button + addButton(new GuiNpcButton(baseId + 3, guiLeft + 215, y, 20, 20, "X")); + + y += 24; + } + + // Add button (if space available) + if (effects.size() < MAX_EFFECTS) { + addButton(new GuiNpcButton(100, guiLeft + 8, y, 50, 20, "gui.add")); + } + + // Bottom buttons + addButton(new GuiNpcButton(65, guiLeft + 8, guiTop + ySize - 28, 60, 20, "gui.cancel")); + addButton(new GuiNpcButton(66, guiLeft + xSize - 68, guiTop + ySize - 28, 60, 20, "gui.done")); + } + + @Override + public void buttonEvent(GuiButton guibutton) { + int id = guibutton.id; + + // Add button + if (id == 100) { + if (effects.size() < MAX_EFFECTS) { + // Add new effect with default values (Slowness, 60 ticks, amp 0) + effects.add(new AbilityEffect(AbilityEffect.EffectType.SLOWNESS, 60, 0)); + initGui(); + } + return; + } + + // Cancel button + if (id == 65) { + cancelled = true; + close(); + return; + } + + // Done button + if (id == 66) { + // Remove any NONE effects before saving + effects.removeIf(e -> !e.isValid()); + cancelled = false; + close(); + return; + } + + // Effect row buttons (id >= 1 and < 100) + if (id >= 1 && id < 100) { + int effectIndex = (id - 1) / 10; + int action = (id - 1) % 10; + + if (effectIndex >= 0 && effectIndex < effects.size()) { + AbilityEffect effect = effects.get(effectIndex); + + switch (action) { + case 0: // Type selector + int typeIndex = ((GuiNpcButton) guibutton).getValue(); + effect.setType(AbilityEffect.EffectType.fromOrdinal(typeIndex)); + break; + case 2: // Amplifier selector + int amp = ((GuiNpcButton) guibutton).getValue(); + effect.setAmplifier(amp); + break; + case 3: // Delete button + effects.remove(effectIndex); + initGui(); + break; + } + } + } + } + + @Override + public void unFocused(GuiNpcTextField textField) { + int id = textField.id; + + // Duration text fields (baseId + 1) + if (id >= 2 && id < 100) { + int effectIndex = (id - 1) / 10; + int action = (id - 1) % 10; + + if (action == 1 && effectIndex >= 0 && effectIndex < effects.size()) { + effects.get(effectIndex).setDurationTicks(textField.getInteger()); + } + } + } + + /** + * Returns the resulting effects list after the dialog closes. + * Returns null if cancelled. + */ + public List getResult() { + if (cancelled) { + return null; + } + return effects; + } + + /** + * Returns true if the dialog was cancelled. + */ + public boolean wasCancelled() { + return cancelled; + } +} diff --git a/src/main/java/noppes/npcs/client/gui/advanced/ability/SubGuiAbilityEnergyBeam.java b/src/main/java/noppes/npcs/client/gui/advanced/ability/SubGuiAbilityEnergyBeam.java index ad15bb576..1c7179deb 100644 --- a/src/main/java/noppes/npcs/client/gui/advanced/ability/SubGuiAbilityEnergyBeam.java +++ b/src/main/java/noppes/npcs/client/gui/advanced/ability/SubGuiAbilityEnergyBeam.java @@ -1,5 +1,6 @@ package noppes.npcs.client.gui.advanced.ability; +import kamkeel.npcs.controllers.data.ability.AbilityEffect; import kamkeel.npcs.controllers.data.ability.type.AbilityEnergyBeam; import noppes.npcs.client.gui.SubGuiColorSelector; import noppes.npcs.client.gui.advanced.SubGuiAbilityConfig; @@ -9,6 +10,8 @@ import noppes.npcs.client.gui.util.GuiNpcTextField; import noppes.npcs.client.gui.util.IAbilityConfigCallback; import noppes.npcs.client.gui.util.SubGuiInterface; +import java.util.List; + /** * GUI for configuring Energy Beam ability type-specific settings. * Energy Beam is a homing head with trailing path (DBZ-style). @@ -87,6 +90,11 @@ public class SubGuiAbilityEnergyBeam extends SubGuiAbilityConfig { addLabel(new GuiNpcLabel(111, "ability.lifetime", col2LabelX, y + 5)); addTextField(createIntField(111, col2FieldX, y, 50, beam.getMaxLifetime())); + + y += 24; + + // Row 7: Effects button + addButton(new GuiNpcButton(150, labelX, y, 80, 20, "ability.effects")); } @Override @@ -161,6 +169,9 @@ public class SubGuiAbilityEnergyBeam extends SubGuiAbilityConfig { case 108: beam.setExplosive(value == 1); break; + case 150: + setSubGui(new SubGuiAbilityEffects(beam.getEffects())); + break; } } @@ -199,6 +210,12 @@ public class SubGuiAbilityEnergyBeam extends SubGuiAbilityConfig { } editingVisualColorId = 0; initGui(); + } else if (subgui instanceof SubGuiAbilityEffects) { + SubGuiAbilityEffects effectsGui = (SubGuiAbilityEffects) subgui; + List result = effectsGui.getResult(); + if (result != null) { + beam.setEffects(result); + } } else { super.subGuiClosed(subgui); } 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 c5240d862..25383c926 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 @@ -1,11 +1,15 @@ package noppes.npcs.client.gui.advanced.ability; +import kamkeel.npcs.controllers.data.ability.AbilityEffect; import kamkeel.npcs.controllers.data.ability.type.AbilityGuard; 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; import noppes.npcs.client.gui.util.IAbilityConfigCallback; +import noppes.npcs.client.gui.util.SubGuiInterface; + +import java.util.List; /** * GUI for configuring Guard ability type-specific settings. @@ -68,6 +72,13 @@ public class SubGuiAbilityGuard extends SubGuiAbilityConfig { GuiNpcTextField counterAnimField = createIntField(106, col2FieldX, y, 50, guard.getCounterAnimationId()); counterAnimField.setEnabled(guard.isCanCounter()); addTextField(counterAnimField); + + y += 24; + + // Row 5: Effects button (applies on counter) + GuiNpcButton effectsBtn = new GuiNpcButton(150, labelX, y, 80, 20, "ability.effects"); + effectsBtn.setEnabled(guard.isCanCounter()); + addButton(effectsBtn); } @Override @@ -80,6 +91,21 @@ public class SubGuiAbilityGuard extends SubGuiAbilityConfig { case 102: guard.setCounterType(AbilityGuard.CounterType.values()[button.getValue()]); break; + case 150: + setSubGui(new SubGuiAbilityEffects(guard.getEffects())); + break; + } + } + + @Override + public void subGuiClosed(SubGuiInterface subgui) { + super.subGuiClosed(subgui); + if (subgui instanceof SubGuiAbilityEffects) { + SubGuiAbilityEffects effectsGui = (SubGuiAbilityEffects) subgui; + List result = effectsGui.getResult(); + if (result != null) { + guard.setEffects(result); + } } } diff --git a/src/main/java/noppes/npcs/client/gui/advanced/ability/SubGuiAbilityHazard.java b/src/main/java/noppes/npcs/client/gui/advanced/ability/SubGuiAbilityHazard.java index 1ec615d7a..8a91798d0 100644 --- a/src/main/java/noppes/npcs/client/gui/advanced/ability/SubGuiAbilityHazard.java +++ b/src/main/java/noppes/npcs/client/gui/advanced/ability/SubGuiAbilityHazard.java @@ -1,11 +1,15 @@ package noppes.npcs.client.gui.advanced.ability; +import kamkeel.npcs.controllers.data.ability.AbilityEffect; import kamkeel.npcs.controllers.data.ability.type.AbilityHazard; 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; import noppes.npcs.client.gui.util.IAbilityConfigCallback; +import noppes.npcs.client.gui.util.SubGuiInterface; + +import java.util.List; /** * GUI for configuring Hazard ability type-specific settings. @@ -71,6 +75,11 @@ public class SubGuiAbilityHazard extends SubGuiAbilityConfig { addLabel(new GuiNpcLabel(109, "ability.affectsCaster", col2LabelX, y + 5)); addButton(new GuiNpcButton(109, col2FieldX, y, 50, 20, new String[]{"gui.no", "gui.yes"}, hazard.isAffectsCaster() ? 1 : 0)); + + y += 24; + + // Row 6: Effects button + addButton(new GuiNpcButton(150, labelX, y, 80, 20, "ability.effects")); } @Override @@ -86,6 +95,21 @@ public class SubGuiAbilityHazard extends SubGuiAbilityConfig { case 109: hazard.setAffectsCaster(value == 1); break; + case 150: + setSubGui(new SubGuiAbilityEffects(hazard.getEffects())); + break; + } + } + + @Override + public void subGuiClosed(SubGuiInterface subgui) { + super.subGuiClosed(subgui); + if (subgui instanceof SubGuiAbilityEffects) { + SubGuiAbilityEffects effectsGui = (SubGuiAbilityEffects) subgui; + List result = effectsGui.getResult(); + if (result != null) { + hazard.setEffects(result); + } } } 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 ea21127dc..897a4af1f 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 @@ -1,10 +1,15 @@ package noppes.npcs.client.gui.advanced.ability; +import kamkeel.npcs.controllers.data.ability.AbilityEffect; import kamkeel.npcs.controllers.data.ability.type.AbilityHeavyHit; 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; import noppes.npcs.client.gui.util.IAbilityConfigCallback; +import noppes.npcs.client.gui.util.SubGuiInterface; + +import java.util.List; /** * GUI for configuring Heavy Hit ability type-specific settings. @@ -24,29 +29,37 @@ public class SubGuiAbilityHeavyHit extends SubGuiAbilityConfig { int labelX = guiLeft + 8; int fieldX = guiLeft + 85; int col2LabelX = guiLeft + 145; - int col2FieldX = guiLeft + 205; - // Row 1: Damage + Potion Time + // Row 1: Damage + Knockback addLabel(new GuiNpcLabel(100, "enchantment.damage", labelX, y + 5)); addTextField(createFloatField(100, fieldX, y, 50, heavyHit.getDamage())); - addLabel(new GuiNpcLabel(101, "ability.potionTime", col2LabelX, y + 5)); - addTextField(createIntField(101, col2FieldX, y, 50, heavyHit.getPotionDurationSeconds())); + addLabel(new GuiNpcLabel(102, "ability.knockback", col2LabelX, y + 5)); + addTextField(createFloatField(102, guiLeft + 205, y, 50, heavyHit.getKnockback())); y += 24; - // Row 2: Knockback + Slowness Level - addLabel(new GuiNpcLabel(102, "ability.knockback", labelX, y + 5)); - addTextField(createFloatField(102, fieldX, y, 50, heavyHit.getKnockback())); + // Row 2: Effects button + addButton(new GuiNpcButton(150, labelX, y, 80, 20, "ability.effects")); + } - addLabel(new GuiNpcLabel(103, "ability.slownessLvl", col2LabelX, y + 5)); - addTextField(createIntField(103, col2FieldX, y, 50, heavyHit.getSlownessLevel())); + @Override + protected void handleTypeButton(int id, GuiNpcButton button) { + if (id == 150) { + setSubGui(new SubGuiAbilityEffects(heavyHit.getEffects())); + } + } - y += 24; - - // Row 3: Weakness Level - addLabel(new GuiNpcLabel(104, "ability.weaknessLvl", labelX, y + 5)); - addTextField(createIntField(104, fieldX, y, 50, heavyHit.getWeaknessLevel())); + @Override + public void subGuiClosed(SubGuiInterface subgui) { + super.subGuiClosed(subgui); + if (subgui instanceof SubGuiAbilityEffects) { + SubGuiAbilityEffects effectsGui = (SubGuiAbilityEffects) subgui; + List result = effectsGui.getResult(); + if (result != null) { + heavyHit.setEffects(result); + } + } } @Override @@ -55,18 +68,9 @@ public class SubGuiAbilityHeavyHit extends SubGuiAbilityConfig { case 100: heavyHit.setDamage(parseFloat(field, heavyHit.getDamage())); break; - case 101: - heavyHit.setPotionDurationSeconds(field.getInteger()); - break; case 102: heavyHit.setKnockback(parseFloat(field, heavyHit.getKnockback())); 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/SubGuiAbilityLaserShot.java b/src/main/java/noppes/npcs/client/gui/advanced/ability/SubGuiAbilityLaserShot.java index f83e93baf..614a8bce0 100644 --- a/src/main/java/noppes/npcs/client/gui/advanced/ability/SubGuiAbilityLaserShot.java +++ b/src/main/java/noppes/npcs/client/gui/advanced/ability/SubGuiAbilityLaserShot.java @@ -1,5 +1,6 @@ package noppes.npcs.client.gui.advanced.ability; +import kamkeel.npcs.controllers.data.ability.AbilityEffect; import kamkeel.npcs.controllers.data.ability.type.AbilityLaserShot; import noppes.npcs.client.gui.SubGuiColorSelector; import noppes.npcs.client.gui.advanced.SubGuiAbilityConfig; @@ -9,6 +10,8 @@ import noppes.npcs.client.gui.util.GuiNpcTextField; import noppes.npcs.client.gui.util.IAbilityConfigCallback; import noppes.npcs.client.gui.util.SubGuiInterface; +import java.util.List; + /** * GUI for configuring Laser Shot ability type-specific settings. */ @@ -77,6 +80,11 @@ public class SubGuiAbilityLaserShot extends SubGuiAbilityConfig { addLabel(new GuiNpcLabel(109, "ability.knockbackUp", col2LabelX, y + 5)); addTextField(createFloatField(109, col2FieldX, y, 50, laser.getKnockbackUp())); + + y += 24; + + // Row 6: Effects button + addButton(new GuiNpcButton(150, labelX, y, 80, 20, "ability.effects")); } @Override @@ -142,6 +150,9 @@ public class SubGuiAbilityLaserShot extends SubGuiAbilityConfig { case 106: laser.setExplosive(value == 1); break; + case 150: + setSubGui(new SubGuiAbilityEffects(laser.getEffects())); + break; } } @@ -180,6 +191,12 @@ public class SubGuiAbilityLaserShot extends SubGuiAbilityConfig { } editingVisualColorId = 0; initGui(); + } else if (subgui instanceof SubGuiAbilityEffects) { + SubGuiAbilityEffects effectsGui = (SubGuiAbilityEffects) subgui; + List result = effectsGui.getResult(); + if (result != null) { + laser.setEffects(result); + } } else { super.subGuiClosed(subgui); } diff --git a/src/main/java/noppes/npcs/client/gui/advanced/ability/SubGuiAbilityOrb.java b/src/main/java/noppes/npcs/client/gui/advanced/ability/SubGuiAbilityOrb.java index 42dd6a773..6c5c598ba 100644 --- a/src/main/java/noppes/npcs/client/gui/advanced/ability/SubGuiAbilityOrb.java +++ b/src/main/java/noppes/npcs/client/gui/advanced/ability/SubGuiAbilityOrb.java @@ -1,5 +1,6 @@ package noppes.npcs.client.gui.advanced.ability; +import kamkeel.npcs.controllers.data.ability.AbilityEffect; import kamkeel.npcs.controllers.data.ability.type.AbilityOrb; import noppes.npcs.client.gui.SubGuiColorSelector; import noppes.npcs.client.gui.advanced.SubGuiAbilityConfig; @@ -9,6 +10,8 @@ import noppes.npcs.client.gui.util.GuiNpcTextField; import noppes.npcs.client.gui.util.IAbilityConfigCallback; import noppes.npcs.client.gui.util.SubGuiInterface; +import java.util.List; + /** * GUI for configuring Orb ability type-specific settings. */ @@ -77,6 +80,11 @@ public class SubGuiAbilityOrb extends SubGuiAbilityConfig { addLabel(new GuiNpcLabel(109, "ability.lifetime", col2LabelX, y + 5)); addTextField(createIntField(109, col2FieldX, y, 50, orb.getMaxLifetime())); + + y += 24; + + // Row 6: Effects button + addButton(new GuiNpcButton(150, labelX, y, 80, 20, "ability.effects")); } @Override @@ -151,6 +159,9 @@ public class SubGuiAbilityOrb extends SubGuiAbilityConfig { case 106: orb.setExplosive(value == 1); break; + case 150: + setSubGui(new SubGuiAbilityEffects(orb.getEffects())); + break; } } @@ -189,6 +200,12 @@ public class SubGuiAbilityOrb extends SubGuiAbilityConfig { } editingVisualColorId = 0; initGui(); + } else if (subgui instanceof SubGuiAbilityEffects) { + SubGuiAbilityEffects effectsGui = (SubGuiAbilityEffects) subgui; + List result = effectsGui.getResult(); + if (result != null) { + orb.setEffects(result); + } } else { super.subGuiClosed(subgui); } diff --git a/src/main/java/noppes/npcs/client/gui/advanced/ability/SubGuiAbilityProjectile.java b/src/main/java/noppes/npcs/client/gui/advanced/ability/SubGuiAbilityProjectile.java index c9be00e38..52bf7a092 100644 --- a/src/main/java/noppes/npcs/client/gui/advanced/ability/SubGuiAbilityProjectile.java +++ b/src/main/java/noppes/npcs/client/gui/advanced/ability/SubGuiAbilityProjectile.java @@ -1,11 +1,15 @@ package noppes.npcs.client.gui.advanced.ability; +import kamkeel.npcs.controllers.data.ability.AbilityEffect; import kamkeel.npcs.controllers.data.ability.type.AbilityProjectile; 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; import noppes.npcs.client.gui.util.IAbilityConfigCallback; +import noppes.npcs.client.gui.util.SubGuiInterface; + +import java.util.List; /** * GUI for configuring Projectile ability type-specific settings. @@ -69,6 +73,11 @@ public class SubGuiAbilityProjectile extends SubGuiAbilityConfig { addLabel(new GuiNpcLabel(107, "ability.homingStr", col2LabelX, y + 5)); addTextField(createFloatField(107, col2FieldX, y, 50, projectile.getHomingStrength())); + + y += 24; + + // Row 5: Effects button + addButton(new GuiNpcButton(150, labelX, y, 80, 20, "ability.effects")); } @Override @@ -85,6 +94,21 @@ public class SubGuiAbilityProjectile extends SubGuiAbilityConfig { case 106: projectile.setHoming(value == 1); break; + case 150: + setSubGui(new SubGuiAbilityEffects(projectile.getEffects())); + break; + } + } + + @Override + public void subGuiClosed(SubGuiInterface subgui) { + super.subGuiClosed(subgui); + if (subgui instanceof SubGuiAbilityEffects) { + SubGuiAbilityEffects effectsGui = (SubGuiAbilityEffects) subgui; + List result = effectsGui.getResult(); + if (result != null) { + projectile.setEffects(result); + } } } 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 a03a85736..48c2c5295 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 @@ -1,10 +1,15 @@ package noppes.npcs.client.gui.advanced.ability; +import kamkeel.npcs.controllers.data.ability.AbilityEffect; import kamkeel.npcs.controllers.data.ability.type.AbilityShockwave; 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; import noppes.npcs.client.gui.util.IAbilityConfigCallback; +import noppes.npcs.client.gui.util.SubGuiInterface; + +import java.util.List; /** * GUI for configuring Shockwave ability type-specific settings. @@ -41,17 +46,35 @@ public class SubGuiAbilityShockwave extends SubGuiAbilityConfig { y += 24; - // Row 3: Stun Duration + Max Targets - addLabel(new GuiNpcLabel(103, "ability.stunDuration", labelX, y + 5)); - addTextField(createIntField(103, fieldX, y, 50, shockwave.getStunDuration())); + // Row 3: Max Targets + Effects button + addLabel(new GuiNpcLabel(104, "ability.maxTargets", labelX, y + 5)); + addTextField(createIntField(104, fieldX, y, 50, shockwave.getMaxTargets())); - addLabel(new GuiNpcLabel(104, "ability.maxTargets", col2LabelX, y + 5)); - addTextField(createIntField(104, col2FieldX, y, 50, shockwave.getMaxTargets())); + addButton(new GuiNpcButton(150, col2LabelX, y, 80, 20, "ability.effects")); y += 24; addLabel(new GuiNpcLabel(105, "ability.shockwaveFalloff", labelX, y + 5)); } + @Override + protected void handleTypeButton(int id, GuiNpcButton button) { + if (id == 150) { + setSubGui(new SubGuiAbilityEffects(shockwave.getEffects())); + } + } + + @Override + public void subGuiClosed(SubGuiInterface subgui) { + super.subGuiClosed(subgui); + if (subgui instanceof SubGuiAbilityEffects) { + SubGuiAbilityEffects effectsGui = (SubGuiAbilityEffects) subgui; + List result = effectsGui.getResult(); + if (result != null) { + shockwave.setEffects(result); + } + } + } + @Override protected void handleTypeTextField(int id, GuiNpcTextField field) { switch (id) { @@ -64,9 +87,6 @@ public class SubGuiAbilityShockwave extends SubGuiAbilityConfig { case 102: shockwave.setPushStrength(parseFloat(field, shockwave.getPushStrength())); 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 989202037..4e020829b 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 @@ -1,10 +1,15 @@ package noppes.npcs.client.gui.advanced.ability; +import kamkeel.npcs.controllers.data.ability.AbilityEffect; import kamkeel.npcs.controllers.data.ability.type.AbilitySlam; 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; import noppes.npcs.client.gui.util.IAbilityConfigCallback; +import noppes.npcs.client.gui.util.SubGuiInterface; + +import java.util.List; /** * GUI for configuring Slam ability type-specific settings. @@ -44,9 +49,30 @@ public class SubGuiAbilitySlam extends SubGuiAbilityConfig { y += 24; - // Row 3: Leap Height + // Row 3: Leap Height + Effects addLabel(new GuiNpcLabel(104, "ability.leapHeight", labelX, y + 5)); addTextField(createFloatField(104, fieldX, y, 50, slam.getLeapHeight())); + + addButton(new GuiNpcButton(150, col2LabelX, y, 80, 20, "ability.effects")); + } + + @Override + protected void handleTypeButton(int id, GuiNpcButton button) { + if (id == 150) { + setSubGui(new SubGuiAbilityEffects(slam.getEffects())); + } + } + + @Override + public void subGuiClosed(SubGuiInterface subgui) { + super.subGuiClosed(subgui); + if (subgui instanceof SubGuiAbilityEffects) { + SubGuiAbilityEffects effectsGui = (SubGuiAbilityEffects) subgui; + List result = effectsGui.getResult(); + if (result != null) { + slam.setEffects(result); + } + } } @Override diff --git a/src/main/java/noppes/npcs/client/gui/advanced/ability/SubGuiAbilitySweeper.java b/src/main/java/noppes/npcs/client/gui/advanced/ability/SubGuiAbilitySweeper.java index 95f54619b..9a3dc2fe8 100644 --- a/src/main/java/noppes/npcs/client/gui/advanced/ability/SubGuiAbilitySweeper.java +++ b/src/main/java/noppes/npcs/client/gui/advanced/ability/SubGuiAbilitySweeper.java @@ -1,5 +1,6 @@ package noppes.npcs.client.gui.advanced.ability; +import kamkeel.npcs.controllers.data.ability.AbilityEffect; import kamkeel.npcs.controllers.data.ability.type.AbilitySweeper; import noppes.npcs.client.gui.SubGuiColorSelector; import noppes.npcs.client.gui.advanced.SubGuiAbilityConfig; @@ -9,6 +10,8 @@ import noppes.npcs.client.gui.util.GuiNpcTextField; import noppes.npcs.client.gui.util.IAbilityConfigCallback; import noppes.npcs.client.gui.util.SubGuiInterface; +import java.util.List; + /** * GUI for configuring Sweeper ability type-specific settings. * Sweeper is a low rotating beam that players can jump over. @@ -75,6 +78,11 @@ public class SubGuiAbilitySweeper extends SubGuiAbilityConfig { // Row 5: Lock On Target addLabel(new GuiNpcLabel(108, "ability.lockTarget", labelX, y + 5)); addButton(new GuiNpcButton(108, fieldX, y, 50, 20, new String[]{"gui.no", "gui.yes"}, sweeper.isLockOnTarget() ? 1 : 0)); + + y += 24; + + // Row 6: Effects button + addButton(new GuiNpcButton(150, labelX, y, 80, 20, "ability.effects")); } @Override @@ -121,6 +129,9 @@ public class SubGuiAbilitySweeper extends SubGuiAbilityConfig { case 108: sweeper.setLockOnTarget(value == 1); break; + case 150: + setSubGui(new SubGuiAbilityEffects(sweeper.getEffects())); + break; } } @@ -155,6 +166,12 @@ public class SubGuiAbilitySweeper extends SubGuiAbilityConfig { } editingVisualColorId = 0; initGui(); + } else if (subgui instanceof SubGuiAbilityEffects) { + SubGuiAbilityEffects effectsGui = (SubGuiAbilityEffects) subgui; + List result = effectsGui.getResult(); + if (result != null) { + sweeper.setEffects(result); + } } else { super.subGuiClosed(subgui); } 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 6173f9ded..1dfb12d22 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 @@ -1,11 +1,15 @@ package noppes.npcs.client.gui.advanced.ability; +import kamkeel.npcs.controllers.data.ability.AbilityEffect; import kamkeel.npcs.controllers.data.ability.type.AbilityTeleport; 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; import noppes.npcs.client.gui.util.IAbilityConfigCallback; +import noppes.npcs.client.gui.util.SubGuiInterface; + +import java.util.List; /** * GUI for configuring Teleport ability type-specific settings. @@ -85,6 +89,11 @@ public class SubGuiAbilityTeleport extends SubGuiAbilityConfig { 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)); + + y += 24; + + // Effects button + addButton(new GuiNpcButton(150, labelX, y, 80, 20, "ability.effects")); } @Override @@ -104,6 +113,21 @@ public class SubGuiAbilityTeleport extends SubGuiAbilityConfig { case 109: teleport.setDamageAtEnd(value == 1); break; + case 150: + setSubGui(new SubGuiAbilityEffects(teleport.getEffects())); + break; + } + } + + @Override + public void subGuiClosed(SubGuiInterface subgui) { + super.subGuiClosed(subgui); + if (subgui instanceof SubGuiAbilityEffects) { + SubGuiAbilityEffects effectsGui = (SubGuiAbilityEffects) subgui; + List result = effectsGui.getResult(); + if (result != null) { + teleport.setEffects(result); + } } } 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 781d0665a..2c0fc3a68 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 @@ -1,11 +1,15 @@ package noppes.npcs.client.gui.advanced.ability; +import kamkeel.npcs.controllers.data.ability.AbilityEffect; import kamkeel.npcs.controllers.data.ability.type.AbilityTrap; 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; import noppes.npcs.client.gui.util.IAbilityConfigCallback; +import noppes.npcs.client.gui.util.SubGuiInterface; + +import java.util.List; /** * GUI for configuring Trap ability type-specific settings. @@ -55,24 +59,31 @@ public class SubGuiAbilityTrap extends SubGuiAbilityConfig { y += 24; - // Row 4: Root Duration + Stun Duration - addLabel(new GuiNpcLabel(106, "ability.rootDuration", labelX, y + 5)); - addTextField(createIntField(106, fieldX, y, 50, trap.getRootDuration())); - - addLabel(new GuiNpcLabel(107, "ability.stunDuration", col2LabelX, y + 5)); - addTextField(createIntField(107, col2FieldX, y, 50, trap.getStunDuration())); - - y += 24; - - // Row 5: Knockback + // Row 4: Knockback + Effects button addLabel(new GuiNpcLabel(108, "ability.knockback", labelX, y + 5)); addTextField(createFloatField(108, fieldX, y, 50, trap.getKnockback())); + + addButton(new GuiNpcButton(150, col2LabelX, y, 80, 20, "ability.effects")); } @Override protected void handleTypeButton(int id, GuiNpcButton button) { if (id == 100) { trap.setPlacement(AbilityTrap.TrapPlacement.values()[button.getValue()]); + } else if (id == 150) { + setSubGui(new SubGuiAbilityEffects(trap.getEffects())); + } + } + + @Override + public void subGuiClosed(SubGuiInterface subgui) { + super.subGuiClosed(subgui); + if (subgui instanceof SubGuiAbilityEffects) { + SubGuiAbilityEffects effectsGui = (SubGuiAbilityEffects) subgui; + List result = effectsGui.getResult(); + if (result != null) { + trap.setEffects(result); + } } } @@ -94,12 +105,6 @@ public class SubGuiAbilityTrap extends SubGuiAbilityConfig { case 105: trap.setMaxTriggers(field.getInteger()); break; - case 106: - trap.setRootDuration(field.getInteger()); - break; - case 107: - trap.setStunDuration(field.getInteger()); - break; case 108: trap.setKnockback(parseFloat(field, trap.getKnockback())); break; diff --git a/src/main/java/noppes/npcs/client/gui/advanced/ability/SubGuiAbilityVortex.java b/src/main/java/noppes/npcs/client/gui/advanced/ability/SubGuiAbilityVortex.java index 003cef5c6..4cc7bc89a 100644 --- a/src/main/java/noppes/npcs/client/gui/advanced/ability/SubGuiAbilityVortex.java +++ b/src/main/java/noppes/npcs/client/gui/advanced/ability/SubGuiAbilityVortex.java @@ -1,11 +1,15 @@ package noppes.npcs.client.gui.advanced.ability; +import kamkeel.npcs.controllers.data.ability.AbilityEffect; import kamkeel.npcs.controllers.data.ability.type.AbilityVortex; 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; import noppes.npcs.client.gui.util.IAbilityConfigCallback; +import noppes.npcs.client.gui.util.SubGuiInterface; + +import java.util.List; /** * GUI for configuring Vortex ability type-specific settings. @@ -54,12 +58,8 @@ public class SubGuiAbilityVortex extends SubGuiAbilityConfig { y += 24; - // Row 4: Stun Duration + Root Duration - addLabel(new GuiNpcLabel(106, "ability.stunDuration", labelX, y + 5)); - addTextField(createIntField(106, fieldX, y, 50, vortex.getStunDuration())); - - addLabel(new GuiNpcLabel(107, "ability.rootDuration", col2LabelX, y + 5)); - addTextField(createIntField(107, col2FieldX, y, 50, vortex.getRootDuration())); + // Row 4: Effects button + addButton(new GuiNpcButton(150, labelX, y, 80, 20, "ability.effects")); y += 24; @@ -81,6 +81,21 @@ public class SubGuiAbilityVortex extends SubGuiAbilityConfig { case 108: vortex.setDamageOnPull(value == 1); break; + case 150: + setSubGui(new SubGuiAbilityEffects(vortex.getEffects())); + break; + } + } + + @Override + public void subGuiClosed(SubGuiInterface subgui) { + super.subGuiClosed(subgui); + if (subgui instanceof SubGuiAbilityEffects) { + SubGuiAbilityEffects effectsGui = (SubGuiAbilityEffects) subgui; + List result = effectsGui.getResult(); + if (result != null) { + vortex.setEffects(result); + } } } @@ -102,12 +117,6 @@ public class SubGuiAbilityVortex extends SubGuiAbilityConfig { case 105: vortex.setMaxTargets(field.getInteger()); break; - case 106: - vortex.setStunDuration(field.getInteger()); - break; - case 107: - vortex.setRootDuration(field.getInteger()); - break; case 109: vortex.setPullDamage(parseFloat(field, vortex.getPullDamage())); break; diff --git a/src/main/resources/assets/customnpcs/lang/en_US.lang b/src/main/resources/assets/customnpcs/lang/en_US.lang index b7e33a029..d5dc945ce 100644 --- a/src/main/resources/assets/customnpcs/lang/en_US.lang +++ b/src/main/resources/assets/customnpcs/lang/en_US.lang @@ -1575,17 +1575,11 @@ ability.minDist=Min Dist ability.distance=Distance 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 +ability.effects=Effects +gui.duration=Duration +gui.amp=Amp # Slam Settings ability.leapSpeed=Leap Speed