From c6810c05eae419986345ff31853c108913f5be4e Mon Sep 17 00:00:00 2001 From: Kam Date: Tue, 27 Jan 2026 16:43:47 -0500 Subject: [PATCH] More Ability Fixes. --- .../data/ability/type/AbilitySweeper.java | 4 +- .../kamkeel/npcs/util/AnchorPointHelper.java | 29 ++++--- .../npcs/client/gui/SubGuiColorSelector.java | 6 +- .../client/gui/advanced/GuiNPCAbilities.java | 29 ++++++- .../gui/advanced/SubGuiAbilityConfig.java | 85 +++++++++++++++---- .../advanced/ability/SubGuiAbilityCutter.java | 8 +- .../advanced/ability/SubGuiAbilityDash.java | 4 +- .../advanced/ability/SubGuiAbilityDisc.java | 47 +++++++--- .../ability/SubGuiAbilityEnergyBeam.java | 46 ++++++---- .../advanced/ability/SubGuiAbilityGuard.java | 5 +- .../advanced/ability/SubGuiAbilityHazard.java | 12 ++- .../advanced/ability/SubGuiAbilityHeal.java | 12 ++- .../ability/SubGuiAbilityLaserShot.java | 17 ++-- .../advanced/ability/SubGuiAbilityOrb.java | 34 +++++--- .../ability/SubGuiAbilityProjectile.java | 26 ++++-- .../ability/SubGuiAbilitySweeper.java | 8 +- .../ability/SubGuiAbilityTeleport.java | 16 +++- .../advanced/ability/SubGuiAbilityTrap.java | 4 +- .../advanced/ability/SubGuiAbilityVortex.java | 8 +- .../gui/select/GuiAnimationSelection.java | 5 +- .../npcs/client/gui/util/GuiNPCInterface.java | 47 +++++++--- .../assets/customnpcs/lang/en_US.lang | 49 ++++++++++- 22 files changed, 378 insertions(+), 123 deletions(-) diff --git a/src/main/java/kamkeel/npcs/controllers/data/ability/type/AbilitySweeper.java b/src/main/java/kamkeel/npcs/controllers/data/ability/type/AbilitySweeper.java index ca41ed6e3..5a61c5dce 100644 --- a/src/main/java/kamkeel/npcs/controllers/data/ability/type/AbilitySweeper.java +++ b/src/main/java/kamkeel/npcs/controllers/data/ability/type/AbilitySweeper.java @@ -30,7 +30,7 @@ public class AbilitySweeper extends Ability { // Type-specific parameters private float beamLength = 10.0f; private float beamWidth = 0.3f; // Thin like beam trail - private float beamHeight = 0.8f; // Height above ground (low enough to jump over) + private float beamHeight = 0.5f; // Height above ground (low enough to jump over) private float damage = 5.0f; private int damageInterval = 5; private boolean piercing = true; @@ -172,7 +172,7 @@ public class AbilitySweeper extends Ability { public void readTypeNBT(NBTTagCompound nbt) { this.beamLength = nbt.hasKey("beamLength") ? nbt.getFloat("beamLength") : 10.0f; this.beamWidth = nbt.hasKey("beamWidth") ? nbt.getFloat("beamWidth") : 0.3f; - this.beamHeight = nbt.hasKey("beamHeight") ? nbt.getFloat("beamHeight") : 0.8f; + this.beamHeight = nbt.hasKey("beamHeight") ? nbt.getFloat("beamHeight") : 0.5f; this.damage = nbt.hasKey("damage") ? nbt.getFloat("damage") : 5.0f; this.damageInterval = nbt.hasKey("damageInterval") ? nbt.getInteger("damageInterval") : 5; this.piercing = !nbt.hasKey("piercing") || nbt.getBoolean("piercing"); diff --git a/src/main/java/kamkeel/npcs/util/AnchorPointHelper.java b/src/main/java/kamkeel/npcs/util/AnchorPointHelper.java index 79ad2cea4..45e4f3eab 100644 --- a/src/main/java/kamkeel/npcs/util/AnchorPointHelper.java +++ b/src/main/java/kamkeel/npcs/util/AnchorPointHelper.java @@ -40,9 +40,10 @@ public class AnchorPointHelper { // Distance in front for FRONT anchor private static final float DEFAULT_FRONT_DISTANCE = 1.0f; - // Fallback arm positioning (when no animation) - private static final float FALLBACK_LATERAL = 0.35f; - private static final float FALLBACK_FORWARD = 0.3f; + // Fallback arm positioning (when no animation, arms hang at sides) + private static final float FALLBACK_LATERAL = 0.35f; // Distance from body center to arm + private static final float FALLBACK_FORWARD = 0.1f; // Slight forward offset + private static final float FALLBACK_ARM_HEIGHT = 0.45f; // Hand height when arms hang down (near hip) /** * Calculate world position for an anchor point on an entity. @@ -274,6 +275,7 @@ public class AnchorPointHelper { /** * Calculate fallback hand position when no animation is active. + * Represents arms hanging at sides in default idle pose. */ private static Vec3 calculateFallbackHandPosition(EntityLivingBase entity, boolean rightHand, float scale) { float bodyYaw = (float) Math.toRadians(entity.renderYawOffset); @@ -281,20 +283,23 @@ public class AnchorPointHelper { // Get arm scale for EntityCustomNpc ModelScalePart armScale = getArmScale(entity); - // Perpendicular direction for lateral offset + // Perpendicular direction for lateral offset (right = +90°, left = -90° from body facing) float perpYaw = bodyYaw + (rightHand ? (float) (Math.PI / 2) : (float) (-Math.PI / 2)); - // Calculate offsets scaled by model size and arm scale - double lateralX = -Math.sin(perpYaw) * FALLBACK_LATERAL * scale * armScale.scaleX; - double lateralZ = Math.cos(perpYaw) * FALLBACK_LATERAL * scale * armScale.scaleX; - double forwardX = -Math.sin(bodyYaw) * FALLBACK_FORWARD * scale * armScale.scaleZ; - double forwardZ = Math.cos(bodyYaw) * FALLBACK_FORWARD * scale * armScale.scaleZ; + // Calculate lateral offset - arms hang at sides + // Scale by model size, but not by arm scale (lateral distance is fixed by skeleton) + double lateralX = -Math.sin(perpYaw) * FALLBACK_LATERAL * scale; + double lateralZ = Math.cos(perpYaw) * FALLBACK_LATERAL * scale; - // Arm length affects vertical position - double armLengthOffset = (1 - armScale.scaleY) * 0.3; + // Small forward offset + double forwardX = -Math.sin(bodyYaw) * FALLBACK_FORWARD * scale; + double forwardZ = Math.cos(bodyYaw) * FALLBACK_FORWARD * scale; + + // Arm length affects vertical position - longer arms = lower hands + double armLengthOffset = armScale.scaleY * 0.3 * scale; double x = entity.posX + lateralX + forwardX; - double y = entity.posY + entity.height * ARM_HEIGHT - armLengthOffset; + double y = entity.posY + entity.height * FALLBACK_ARM_HEIGHT + armLengthOffset; double z = entity.posZ + lateralZ + forwardZ; return Vec3.createVectorHelper(x, y, z); diff --git a/src/main/java/noppes/npcs/client/gui/SubGuiColorSelector.java b/src/main/java/noppes/npcs/client/gui/SubGuiColorSelector.java index 947825f5a..be8c07f8a 100644 --- a/src/main/java/noppes/npcs/client/gui/SubGuiColorSelector.java +++ b/src/main/java/noppes/npcs/client/gui/SubGuiColorSelector.java @@ -25,10 +25,10 @@ public class SubGuiColorSelector extends SubGuiInterface implements ITextfieldLi public int color; public SubGuiColorSelector(int color) { - xSize = 176; + xSize = 182; ySize = 222; this.color = color; - setBackground("smallbg.png"); + setBackground("menubg.png"); } @Override @@ -40,7 +40,7 @@ public class SubGuiColorSelector extends SubGuiInterface implements ITextfieldLi this.addTextField(textfield = new GuiNpcTextField(0, this, guiLeft + 53, guiTop + 20, 70, 20, getColor())); textfield.setTextColor(color); - addButton(new GuiNpcButton(66, guiLeft + 112, guiTop + 198, 60, 20, "gui.done")); + addButton(new GuiNpcButton(66, guiLeft + 112, guiTop + 175, 60, 20, "gui.done")); } public String getColor() { diff --git a/src/main/java/noppes/npcs/client/gui/advanced/GuiNPCAbilities.java b/src/main/java/noppes/npcs/client/gui/advanced/GuiNPCAbilities.java index c0fb15596..9abcebbe7 100644 --- a/src/main/java/noppes/npcs/client/gui/advanced/GuiNPCAbilities.java +++ b/src/main/java/noppes/npcs/client/gui/advanced/GuiNPCAbilities.java @@ -73,15 +73,15 @@ public class GuiNPCAbilities extends GuiNPCInterface2 implements IScrollData, IC addLabel(new GuiNpcLabel(100, "gui.enabled", guiLeft + 5, y + 5)); addButton(new GuiNpcButton(100, guiLeft + 55, y, 50, 20, new String[]{"gui.no", "gui.yes"}, abilitiesEnabled ? 1 : 0)); - // Cooldown range: Min Cooldown and Max Cooldown + // Cooldown range: Min Cooldown and Max Cooldown (spaced apart more) addLabel(new GuiNpcLabel(101, "ability.minCooldown", guiLeft + 115, y + 5)); - GuiNpcTextField minField = new GuiNpcTextField(101, this, fontRendererObj, guiLeft + 185, y, 40, 20, String.valueOf(minCooldown)); + GuiNpcTextField minField = new GuiNpcTextField(101, this, fontRendererObj, guiLeft + 165, y, 40, 20, String.valueOf(minCooldown)); minField.setIntegersOnly(); minField.setMinMaxDefault(0, 10000, 20); addTextField(minField); - addLabel(new GuiNpcLabel(102, "ability.maxCooldown", guiLeft + 235, y + 5)); - GuiNpcTextField maxField = new GuiNpcTextField(102, this, fontRendererObj, guiLeft + 305, y, 40, 20, String.valueOf(maxCooldown)); + addLabel(new GuiNpcLabel(102, "ability.maxCooldown", guiLeft + 260, y + 5)); + GuiNpcTextField maxField = new GuiNpcTextField(102, this, fontRendererObj, guiLeft + 310, y, 40, 20, String.valueOf(maxCooldown)); maxField.setIntegersOnly(); maxField.setMinMaxDefault(0, 10000, 60); addTextField(maxField); @@ -123,6 +123,14 @@ public class GuiNPCAbilities extends GuiNPCInterface2 implements IScrollData, IC // Load button (under the add/remove arrows) addButton(new GuiNpcButton(75, centerX, y + 90, 40, 20, "gui.load")); + // On/Off toggle for selected ability (under Load button) + if (selectedAbilityIndex >= 0 && selectedAbilityIndex < npcAbilities.size()) { + Ability selectedAbility = npcAbilities.get(selectedAbilityIndex); + GuiNpcButton toggleBtn = new GuiNpcButton(77, centerX, y + 112, 40, 20, + new String[]{"gui.off", "gui.on"}, selectedAbility.isEnabled() ? 1 : 0); + addButton(toggleBtn); + } + // Right side buttons: Edit and Up/Down carrots with Save button addButton(new GuiNpcButton(72, guiLeft + 210, y + 145, 55, 20, "gui.edit")); getButton(72).setEnabled(selectedAbilityIndex >= 0); @@ -243,6 +251,19 @@ public class GuiNPCAbilities extends GuiNPCInterface2 implements IScrollData, IC return; } + // Toggle selected ability on/off + if (id == 77) { + if (selectedAbilityIndex >= 0 && selectedAbilityIndex < npcAbilities.size()) { + Ability ability = npcAbilities.get(selectedAbilityIndex); + ability.setEnabled(((GuiNpcButton) guibutton).getValue() == 1); + updateNpcAbilitiesList(); + selectAbilityByIndex(selectedAbilityIndex); + initGui(); + save(); + } + return; + } + initGui(); } diff --git a/src/main/java/noppes/npcs/client/gui/advanced/SubGuiAbilityConfig.java b/src/main/java/noppes/npcs/client/gui/advanced/SubGuiAbilityConfig.java index 040c999a4..831420473 100644 --- a/src/main/java/noppes/npcs/client/gui/advanced/SubGuiAbilityConfig.java +++ b/src/main/java/noppes/npcs/client/gui/advanced/SubGuiAbilityConfig.java @@ -4,6 +4,9 @@ import kamkeel.npcs.controllers.data.ability.Ability; import kamkeel.npcs.controllers.data.ability.Condition; import kamkeel.npcs.controllers.data.ability.TargetingMode; import kamkeel.npcs.controllers.data.telegraph.TelegraphType; +import noppes.npcs.controllers.data.Animation; +import noppes.npcs.controllers.data.Frame; +import noppes.npcs.controllers.AnimationController; import net.minecraft.client.gui.GuiButton; import net.minecraft.nbt.NBTTagCompound; import net.minecraft.util.StatCollector; @@ -140,7 +143,7 @@ public class SubGuiAbilityConfig extends SubGuiInterface implements ITextfieldLi this.hasTypeSettings = ability.hasTypeSettings(); this.hasVisualSettings = hasVisualSettings(); - setBackground("menubg.png"); + setBackground("menubg.png", 217); xSize = 356; ySize = 200; } @@ -248,13 +251,17 @@ public class SubGuiAbilityConfig extends SubGuiInterface implements ITextfieldLi addTextField(weightField); addLabel(new GuiNpcLabel(5, "ability.lockMove", col2LabelX, y + 5)); - addButton(new GuiNpcButton(16, col2FieldX, y, 40, 20, new String[]{"gui.no", "gui.yes"}, lockMovement ? 1 : 0)); + GuiNpcButton lockMoveBtn = new GuiNpcButton(16, col2FieldX, y, 40, 20, new String[]{"gui.no", "gui.yes"}, lockMovement ? 1 : 0); + lockMoveBtn.setHoverText("ability.hover.lockMove"); + addButton(lockMoveBtn); y += 24; // Row 3: Interruptible + Dazed Ticks (only if interruptible) addLabel(new GuiNpcLabel(6, "ability.interruptible", col1LabelX, y + 5)); - addButton(new GuiNpcButton(14, guiLeft + 85, y, 40, 20, new String[]{"gui.no", "gui.yes"}, interruptible ? 1 : 0)); + GuiNpcButton interruptBtn = new GuiNpcButton(14, guiLeft + 85, y, 40, 20, new String[]{"gui.no", "gui.yes"}, interruptible ? 1 : 0); + interruptBtn.setHoverText("ability.hover.interruptible"); + addButton(interruptBtn); // Only show dazed ticks if interruptible is enabled if (interruptible) { @@ -278,6 +285,13 @@ public class SubGuiAbilityConfig extends SubGuiInterface implements ITextfieldLi windupField.setMinMaxDefault(0, 1000, 20); addTextField(windupField); + // Sync button - only show if windup animation is selected + if (windUpAnimationId >= 0) { + GuiNpcButton syncBtn = new GuiNpcButton(17, guiLeft + 115, y, 40, 20, "gui.sync"); + syncBtn.setHoverText("ability.hover.sync"); + addButton(syncBtn); + } + addLabel(new GuiNpcLabel(13, "ability.cooldown", col2LabelX, y + 5)); GuiNpcTextField cooldownField = new GuiNpcTextField(10, this, fontRendererObj, col2FieldX, y, 40, 20, String.valueOf(cooldownTicks)); cooldownField.setIntegersOnly(); @@ -387,7 +401,9 @@ public class SubGuiAbilityConfig extends SubGuiInterface implements ITextfieldLi if (!targetingModeLocked) { String[] targetingModes = getAvailableTargetingModes(); int selectedIndex = getTargetingModeIndex(targetingMode); - addButton(new GuiNpcButton(4, col1FieldX, y, 90, 20, targetingModes, selectedIndex)); + GuiNpcButton targetBtn = new GuiNpcButton(4, col1FieldX, y, 90, 20, targetingModes, selectedIndex); + targetBtn.setHoverText("ability.hover.targeting"); + addButton(targetBtn); } else { String modeName = "ability.target." + targetingMode.name().toLowerCase(); addLabel(new GuiNpcLabel(23, modeName, col1FieldX, y + 5)); @@ -534,7 +550,9 @@ public class SubGuiAbilityConfig extends SubGuiInterface implements ITextfieldLi // Show Telegraph addLabel(new GuiNpcLabel(41, "ability.showTelegraph", col1LabelX, y + 5)); - addButton(new GuiNpcButton(20, guiLeft + 95, y, 40, 20, new String[]{"gui.no", "gui.yes"}, showTelegraph ? 1 : 0)); + GuiNpcButton telegraphBtn = new GuiNpcButton(20, guiLeft + 95, y, 40, 20, new String[]{"gui.no", "gui.yes"}, showTelegraph ? 1 : 0); + telegraphBtn.setHoverText("ability.hover.showTelegraph"); + addButton(telegraphBtn); // Telegraph Type (separate column) String typeKey = ability.getTelegraphType().name().toLowerCase(); @@ -544,20 +562,20 @@ public class SubGuiAbilityConfig extends SubGuiInterface implements ITextfieldLi y += 24; - // Colors - addLabel(new GuiNpcLabel(44, "ability.windUpColor", col1LabelX, y + 5)); - String windUpHex = String.format("%06X", windUpColor & 0xFFFFFF); - GuiNpcButton windUpColorBtn = new GuiNpcButton(22, guiLeft + 95, y, 55, 20, windUpHex); - windUpColorBtn.setEnabled(showTelegraph); - windUpColorBtn.setTextColor(windUpColor & 0xFFFFFF); - addButton(windUpColorBtn); + // Colors - only show when telegraph is enabled + if (showTelegraph) { + addLabel(new GuiNpcLabel(44, "ability.windUpColor", col1LabelX, y + 5)); + String windUpHex = String.format("%06X", windUpColor & 0xFFFFFF); + GuiNpcButton windUpColorBtn = new GuiNpcButton(22, guiLeft + 95, y, 55, 20, windUpHex); + windUpColorBtn.setTextColor(windUpColor & 0xFFFFFF); + addButton(windUpColorBtn); - addLabel(new GuiNpcLabel(45, "ability.activeColor", guiLeft + 200, y + 5)); - String activeHex = String.format("%06X", activeColor & 0xFFFFFF); - GuiNpcButton activeColorBtn = new GuiNpcButton(24, guiLeft + 280, y, 55, 20, activeHex); - activeColorBtn.setEnabled(showTelegraph); - activeColorBtn.setTextColor(activeColor & 0xFFFFFF); - addButton(activeColorBtn); + addLabel(new GuiNpcLabel(45, "ability.activeColor", guiLeft + 200, y + 5)); + String activeHex = String.format("%06X", activeColor & 0xFFFFFF); + GuiNpcButton activeColorBtn = new GuiNpcButton(24, guiLeft + 280, y, 55, 20, activeHex); + activeColorBtn.setTextColor(activeColor & 0xFFFFFF); + addButton(activeColorBtn); + } } } @@ -627,6 +645,9 @@ public class SubGuiAbilityConfig extends SubGuiInterface implements ITextfieldLi initGui(); // Refresh to show/hide dazed ticks field } else if (id == 16) { lockMovement = ((GuiNpcButton) guibutton).getValue() == 1; + } else if (id == 17) { + // Sync windup ticks with animation duration + syncWindupWithAnimation(); } // Target tab - Targeting mode @@ -918,6 +939,34 @@ public class SubGuiAbilityConfig extends SubGuiInterface implements ITextfieldLi initGui(); } + // ═══════════════════════════════════════════════════════════════════════════ + // SYNC ANIMATION + // ═══════════════════════════════════════════════════════════════════════════ + + /** + * Syncs windup ticks with the selected windup animation's total duration. + */ + private void syncWindupWithAnimation() { + if (windUpAnimationId < 0 || AnimationController.Instance == null) { + return; + } + + Animation animation = (Animation) AnimationController.Instance.get(windUpAnimationId); + if (animation == null || animation.frames.isEmpty()) { + return; + } + + // Calculate total duration by summing all frame durations + int totalDuration = 0; + for (Frame frame : animation.frames) { + totalDuration += frame.getDuration(); + } + + // Update the cached value and refresh GUI + windUpTicks = totalDuration; + initGui(); + } + // ═══════════════════════════════════════════════════════════════════════════ // HELPER METHODS FOR SUBCLASSES // ═══════════════════════════════════════════════════════════════════════════ 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 f3dbc64c7..f10c63eef 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 @@ -61,10 +61,14 @@ public class SubGuiAbilityCutter extends SubGuiAbilityConfig { // Row 4: Sweep Mode + Piercing addLabel(new GuiNpcLabel(106, "ability.sweepMode", labelX, y + 5)); String[] sweepModes = {"Swipe", "Spin"}; - addButton(new GuiNpcButton(106, fieldX, y, 70, 20, sweepModes, cutter.getSweepMode().ordinal())); + GuiNpcButton sweepModeBtn = new GuiNpcButton(106, fieldX, y, 70, 20, sweepModes, cutter.getSweepMode().ordinal()); + sweepModeBtn.setHoverText("ability.hover.sweepMode"); + addButton(sweepModeBtn); addLabel(new GuiNpcLabel(107, "ability.piercing", col2LabelX, y + 5)); - addButton(new GuiNpcButton(107, col2FieldX, y, 50, 20, new String[]{"gui.no", "gui.yes"}, cutter.isPiercing() ? 1 : 0)); + GuiNpcButton piercingBtn = new GuiNpcButton(107, col2FieldX, y, 50, 20, new String[]{"gui.no", "gui.yes"}, cutter.isPiercing() ? 1 : 0); + piercingBtn.setHoverText("ability.hover.piercing"); + addButton(piercingBtn); y += 24; diff --git a/src/main/java/noppes/npcs/client/gui/advanced/ability/SubGuiAbilityDash.java b/src/main/java/noppes/npcs/client/gui/advanced/ability/SubGuiAbilityDash.java index 26bfd6610..f113b3c1c 100644 --- a/src/main/java/noppes/npcs/client/gui/advanced/ability/SubGuiAbilityDash.java +++ b/src/main/java/noppes/npcs/client/gui/advanced/ability/SubGuiAbilityDash.java @@ -30,7 +30,9 @@ public class SubGuiAbilityDash extends SubGuiAbilityConfig { // Row 1: Dash Mode addLabel(new GuiNpcLabel(100, "ability.mode", labelX, y + 5)); String[] dashModes = {"Aggressive", "Defensive"}; - addButton(new GuiNpcButton(100, fieldX, y, 80, 20, dashModes, dash.getDashMode().ordinal())); + GuiNpcButton modeBtn = new GuiNpcButton(100, fieldX, y, 80, 20, dashModes, dash.getDashMode().ordinal()); + modeBtn.setHoverText("ability.hover.dashMode"); + addButton(modeBtn); y += 24; 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 33c5372fd..2b804d99b 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 @@ -57,30 +57,42 @@ public class SubGuiAbilityDisc extends SubGuiAbilityConfig { y += 24; - // Row 3: Homing + Homing Strength + // Row 3: Homing + Homing Strength (only show strength if homing) addLabel(new GuiNpcLabel(104, "ability.homing", labelX, y + 5)); - addButton(new GuiNpcButton(104, fieldX, y, 50, 20, new String[]{"gui.no", "gui.yes"}, disc.isHoming() ? 1 : 0)); + GuiNpcButton homingBtn = new GuiNpcButton(104, fieldX, y, 50, 20, new String[]{"gui.no", "gui.yes"}, disc.isHoming() ? 1 : 0); + homingBtn.setHoverText("ability.hover.homing"); + addButton(homingBtn); - addLabel(new GuiNpcLabel(105, "ability.homingStr", col2LabelX, y + 5)); - addTextField(createFloatField(105, col2FieldX, y, 50, disc.getHomingStrength())); + if (disc.isHoming()) { + addLabel(new GuiNpcLabel(105, "ability.homingStr", col2LabelX, y + 5)); + addTextField(createFloatField(105, col2FieldX, y, 50, disc.getHomingStrength())); + } y += 24; - // Row 4: Boomerang + Boomerang Delay + // Row 4: Boomerang + Boomerang Delay (only show delay if boomerang) addLabel(new GuiNpcLabel(106, "ability.boomerang", labelX, y + 5)); - addButton(new GuiNpcButton(106, fieldX, y, 50, 20, new String[]{"gui.no", "gui.yes"}, disc.isBoomerang() ? 1 : 0)); + GuiNpcButton boomerangBtn = new GuiNpcButton(106, fieldX, y, 50, 20, new String[]{"gui.no", "gui.yes"}, disc.isBoomerang() ? 1 : 0); + boomerangBtn.setHoverText("ability.hover.boomerang"); + addButton(boomerangBtn); - addLabel(new GuiNpcLabel(107, "ability.boomerangDelay", col2LabelX, y + 5)); - addTextField(createIntField(107, col2FieldX, y, 50, disc.getBoomerangDelay())); + if (disc.isBoomerang()) { + addLabel(new GuiNpcLabel(107, "ability.boomerangDelay", col2LabelX, y + 5)); + addTextField(createIntField(107, col2FieldX, y, 50, disc.getBoomerangDelay())); + } y += 24; - // Row 5: Explosive + Explosion Radius + // Row 5: Explosive + Explosion Radius (only show radius if explosive) addLabel(new GuiNpcLabel(108, "ability.explosive", labelX, y + 5)); - addButton(new GuiNpcButton(108, fieldX, y, 50, 20, new String[]{"gui.no", "gui.yes"}, disc.isExplosive() ? 1 : 0)); + GuiNpcButton explosiveBtn = new GuiNpcButton(108, fieldX, y, 50, 20, new String[]{"gui.no", "gui.yes"}, disc.isExplosive() ? 1 : 0); + explosiveBtn.setHoverText("ability.hover.explosive"); + addButton(explosiveBtn); - addLabel(new GuiNpcLabel(109, "ability.explosionRad", col2LabelX, y + 5)); - addTextField(createFloatField(109, col2FieldX, y, 50, disc.getExplosionRadius())); + if (disc.isExplosive()) { + addLabel(new GuiNpcLabel(109, "ability.explosionRad", col2LabelX, y + 5)); + addTextField(createFloatField(109, col2FieldX, y, 50, disc.getExplosionRadius())); + } y += 24; @@ -110,7 +122,9 @@ public class SubGuiAbilityDisc extends SubGuiAbilityConfig { // Row 1: Anchor Point addLabel(new GuiNpcLabel(210, "ability.anchorPoint", labelX, y + 5)); - addButton(new GuiNpcButton(210, fieldX, y, 80, 20, AnchorPoint.getDisplayNames(), disc.getAnchorPoint().getId())); + GuiNpcButton anchorBtn = new GuiNpcButton(210, fieldX, y, 80, 20, AnchorPoint.getDisplayNames(), disc.getAnchorPoint().getId()); + anchorBtn.setHoverText("ability.hover.anchorPoint"); + addButton(anchorBtn); y += 24; @@ -149,7 +163,9 @@ public class SubGuiAbilityDisc extends SubGuiAbilityConfig { // Row 4: Lightning Effect Enabled addLabel(new GuiNpcLabel(205, "ability.lightning", labelX, y + 5)); - addButton(new GuiNpcButton(205, fieldX, y, 50, 20, new String[]{"gui.no", "gui.yes"}, disc.hasLightningEffect() ? 1 : 0)); + GuiNpcButton lightningBtn = new GuiNpcButton(205, fieldX, y, 50, 20, new String[]{"gui.no", "gui.yes"}, disc.hasLightningEffect() ? 1 : 0); + lightningBtn.setHoverText("ability.hover.lightning"); + addButton(lightningBtn); // Only show Lightning settings if Lightning is enabled if (disc.hasLightningEffect()) { @@ -174,12 +190,15 @@ public class SubGuiAbilityDisc extends SubGuiAbilityConfig { switch (id) { case 104: disc.setHoming(value == 1); + initGui(); break; case 106: disc.setBoomerang(value == 1); + initGui(); break; case 108: disc.setExplosive(value == 1); + initGui(); break; case 150: setSubGui(new SubGuiAbilityEffects(disc.getEffects())); 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 626fac6b9..6e90428ce 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 @@ -58,30 +58,40 @@ public class SubGuiAbilityEnergyBeam extends SubGuiAbilityConfig { y += 24; - // Row 3: Homing + Homing Strength + // Row 3: Homing + Homing Strength (only show strength if homing) addLabel(new GuiNpcLabel(104, "ability.homing", labelX, y + 5)); - addButton(new GuiNpcButton(104, fieldX, y, 50, 20, new String[]{"gui.no", "gui.yes"}, beam.isHoming() ? 1 : 0)); + GuiNpcButton homingBtn = new GuiNpcButton(104, fieldX, y, 50, 20, new String[]{"gui.no", "gui.yes"}, beam.isHoming() ? 1 : 0); + homingBtn.setHoverText("ability.hover.homing"); + addButton(homingBtn); - addLabel(new GuiNpcLabel(105, "ability.homingStr", col2LabelX, y + 5)); - addTextField(createFloatField(105, col2FieldX, y, 50, beam.getHomingStrength())); + if (beam.isHoming()) { + addLabel(new GuiNpcLabel(105, "ability.homingStr", col2LabelX, y + 5)); + addTextField(createFloatField(105, col2FieldX, y, 50, beam.getHomingStrength())); + } y += 24; - // Row 4: Homing Range + Max Distance - addLabel(new GuiNpcLabel(106, "ability.homingRange", labelX, y + 5)); - addTextField(createFloatField(106, fieldX, y, 50, beam.getHomingRange())); + // Row 4: Max Distance (+ Homing Range only if homing) + if (beam.isHoming()) { + addLabel(new GuiNpcLabel(106, "ability.homingRange", labelX, y + 5)); + addTextField(createFloatField(106, fieldX, y, 50, beam.getHomingRange())); + } - addLabel(new GuiNpcLabel(107, "ability.maxDist", col2LabelX, y + 5)); - addTextField(createFloatField(107, col2FieldX, y, 50, beam.getMaxDistance())); + addLabel(new GuiNpcLabel(107, "ability.maxDist", beam.isHoming() ? col2LabelX : labelX, y + 5)); + addTextField(createFloatField(107, beam.isHoming() ? col2FieldX : fieldX, y, 50, beam.getMaxDistance())); y += 24; - // Row 5: Explosive + Explosion Radius + // Row 5: Explosive + Explosion Radius (only show radius if explosive) addLabel(new GuiNpcLabel(108, "ability.explosive", labelX, y + 5)); - addButton(new GuiNpcButton(108, fieldX, y, 50, 20, new String[]{"gui.no", "gui.yes"}, beam.isExplosive() ? 1 : 0)); + GuiNpcButton explosiveBtn = new GuiNpcButton(108, fieldX, y, 50, 20, new String[]{"gui.no", "gui.yes"}, beam.isExplosive() ? 1 : 0); + explosiveBtn.setHoverText("ability.hover.explosive"); + addButton(explosiveBtn); - addLabel(new GuiNpcLabel(109, "ability.explosionRad", col2LabelX, y + 5)); - addTextField(createFloatField(109, col2FieldX, y, 50, beam.getExplosionRadius())); + if (beam.isExplosive()) { + addLabel(new GuiNpcLabel(109, "ability.explosionRad", col2LabelX, y + 5)); + addTextField(createFloatField(109, col2FieldX, y, 50, beam.getExplosionRadius())); + } y += 24; @@ -108,7 +118,9 @@ public class SubGuiAbilityEnergyBeam extends SubGuiAbilityConfig { // Row 1: Anchor Point addLabel(new GuiNpcLabel(210, "ability.anchorPoint", labelX, y + 5)); - addButton(new GuiNpcButton(210, fieldX, y, 80, 20, AnchorPoint.getDisplayNames(), beam.getAnchorPoint().getId())); + GuiNpcButton anchorBtn = new GuiNpcButton(210, fieldX, y, 80, 20, AnchorPoint.getDisplayNames(), beam.getAnchorPoint().getId()); + anchorBtn.setHoverText("ability.hover.anchorPoint"); + addButton(anchorBtn); y += 24; @@ -147,7 +159,9 @@ public class SubGuiAbilityEnergyBeam extends SubGuiAbilityConfig { // Row 4: Lightning Effect Enabled (only affects head) addLabel(new GuiNpcLabel(205, "ability.lightning", labelX, y + 5)); - addButton(new GuiNpcButton(205, fieldX, y, 50, 20, new String[]{"gui.no", "gui.yes"}, beam.hasLightningEffect() ? 1 : 0)); + GuiNpcButton lightningBtn = new GuiNpcButton(205, fieldX, y, 50, 20, new String[]{"gui.no", "gui.yes"}, beam.hasLightningEffect() ? 1 : 0); + lightningBtn.setHoverText("ability.hover.lightning"); + addButton(lightningBtn); // Only show Lightning settings if Lightning is enabled if (beam.hasLightningEffect()) { @@ -172,9 +186,11 @@ public class SubGuiAbilityEnergyBeam extends SubGuiAbilityConfig { switch (id) { case 104: beam.setHoming(value == 1); + initGui(); break; case 108: beam.setExplosive(value == 1); + initGui(); break; case 150: setSubGui(new SubGuiAbilityEffects(beam.getEffects())); 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 183d66814..a975a97fc 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 @@ -44,11 +44,14 @@ public class SubGuiAbilityGuard extends SubGuiAbilityConfig { // 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)); + GuiNpcButton canCounterBtn = new GuiNpcButton(101, fieldX, y, 50, 20, new String[]{"gui.no", "gui.yes"}, guard.isCanCounter() ? 1 : 0); + canCounterBtn.setHoverText("ability.hover.canCounter"); + addButton(canCounterBtn); 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.setHoverText("ability.hover.counterType"); counterTypeButton.setEnabled(guard.isCanCounter()); addButton(counterTypeButton); 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 c9633c0f9..9822d9f90 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 @@ -39,14 +39,18 @@ public class SubGuiAbilityHazard extends SubGuiAbilityConfig { addLabel(new GuiNpcLabel(100, "ability.shape", col2LabelX, y + 5)); String[] shapes = {"Circle", "Ring", "Cone"}; - addButton(new GuiNpcButton(100, col2FieldX, y, 55, 20, shapes, hazard.getShape().ordinal())); + GuiNpcButton shapeBtn = new GuiNpcButton(100, col2FieldX, y, 55, 20, shapes, hazard.getShape().ordinal()); + shapeBtn.setHoverText("ability.hover.shape"); + addButton(shapeBtn); y += 24; // Row 2: Placement addLabel(new GuiNpcLabel(101, "ability.placement", labelX, y + 5)); String[] placements = {"Caster", "Target", "FollowCast", "FollowTgt"}; - addButton(new GuiNpcButton(101, fieldX, y, 70, 20, placements, hazard.getPlacement().ordinal())); + GuiNpcButton placementBtn = new GuiNpcButton(101, fieldX, y, 70, 20, placements, hazard.getPlacement().ordinal()); + placementBtn.setHoverText("ability.hover.placement"); + addButton(placementBtn); y += 24; @@ -82,7 +86,9 @@ public class SubGuiAbilityHazard extends SubGuiAbilityConfig { addTextField(createIntField(108, fieldX, y, 50, hazard.getPoisonLevel())); 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)); + GuiNpcButton affectsCasterBtn = new GuiNpcButton(109, col2FieldX, y, 50, 20, new String[]{"gui.no", "gui.yes"}, hazard.isAffectsCaster() ? 1 : 0); + affectsCasterBtn.setHoverText("ability.hover.affectsCaster"); + addButton(affectsCasterBtn); y += 24; diff --git a/src/main/java/noppes/npcs/client/gui/advanced/ability/SubGuiAbilityHeal.java b/src/main/java/noppes/npcs/client/gui/advanced/ability/SubGuiAbilityHeal.java index 010da51cf..490b4773a 100644 --- a/src/main/java/noppes/npcs/client/gui/advanced/ability/SubGuiAbilityHeal.java +++ b/src/main/java/noppes/npcs/client/gui/advanced/ability/SubGuiAbilityHeal.java @@ -29,7 +29,9 @@ public class SubGuiAbilityHeal extends SubGuiAbilityConfig { // Row 1: Instant Heal + Duration (only shown if not instant) addLabel(new GuiNpcLabel(103, "dialog.instant", labelX, y + 5)); - addButton(new GuiNpcButton(103, fieldX, y, 50, 20, new String[]{"gui.no", "gui.yes"}, heal.isInstantHeal() ? 1 : 0)); + GuiNpcButton instantBtn = new GuiNpcButton(103, fieldX, y, 50, 20, new String[]{"gui.no", "gui.yes"}, heal.isInstantHeal() ? 1 : 0); + instantBtn.setHoverText("ability.hover.instant"); + addButton(instantBtn); if (!heal.isInstantHeal()) { addLabel(new GuiNpcLabel(99, "ability.duration", col2LabelX, y + 5)); @@ -57,10 +59,14 @@ public class SubGuiAbilityHeal extends SubGuiAbilityConfig { // Row 4: Heal Self + Heal Allies addLabel(new GuiNpcLabel(104, "ability.healSelf", labelX, y + 5)); - addButton(new GuiNpcButton(104, fieldX, y, 50, 20, new String[]{"gui.no", "gui.yes"}, heal.isHealSelf() ? 1 : 0)); + GuiNpcButton healSelfBtn = new GuiNpcButton(104, fieldX, y, 50, 20, new String[]{"gui.no", "gui.yes"}, heal.isHealSelf() ? 1 : 0); + healSelfBtn.setHoverText("ability.hover.healSelf"); + addButton(healSelfBtn); addLabel(new GuiNpcLabel(105, "ability.healAllies", col2LabelX, y + 5)); - addButton(new GuiNpcButton(105, col2FieldX, y, 50, 20, new String[]{"gui.no", "gui.yes"}, heal.isHealAllies() ? 1 : 0)); + GuiNpcButton healAlliesBtn = new GuiNpcButton(105, col2FieldX, y, 50, 20, new String[]{"gui.no", "gui.yes"}, heal.isHealAllies() ? 1 : 0); + healAlliesBtn.setHoverText("ability.hover.healAllies"); + addButton(healAlliesBtn); } @Override 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 614a8bce0..50e8fa92c 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 @@ -65,12 +65,16 @@ public class SubGuiAbilityLaserShot extends SubGuiAbilityConfig { y += 24; - // Row 4: Explosive + Explosion Radius + // Row 4: Explosive + Explosion Radius (only show radius if explosive) addLabel(new GuiNpcLabel(106, "ability.explosive", labelX, y + 5)); - addButton(new GuiNpcButton(106, fieldX, y, 50, 20, new String[]{"gui.no", "gui.yes"}, laser.isExplosive() ? 1 : 0)); + GuiNpcButton explosiveBtn = new GuiNpcButton(106, fieldX, y, 50, 20, new String[]{"gui.no", "gui.yes"}, laser.isExplosive() ? 1 : 0); + explosiveBtn.setHoverText("ability.hover.explosive"); + addButton(explosiveBtn); - addLabel(new GuiNpcLabel(107, "ability.explosionRad", col2LabelX, y + 5)); - addTextField(createFloatField(107, col2FieldX, y, 50, laser.getExplosionRadius())); + if (laser.isExplosive()) { + addLabel(new GuiNpcLabel(107, "ability.explosionRad", col2LabelX, y + 5)); + addTextField(createFloatField(107, col2FieldX, y, 50, laser.getExplosionRadius())); + } y += 24; @@ -124,7 +128,9 @@ public class SubGuiAbilityLaserShot extends SubGuiAbilityConfig { // Row 3: Lightning Effect Enabled addLabel(new GuiNpcLabel(204, "ability.lightning", labelX, y + 5)); - addButton(new GuiNpcButton(204, fieldX, y, 50, 20, new String[]{"gui.no", "gui.yes"}, laser.hasLightningEffect() ? 1 : 0)); + GuiNpcButton lightningBtn = new GuiNpcButton(204, fieldX, y, 50, 20, new String[]{"gui.no", "gui.yes"}, laser.hasLightningEffect() ? 1 : 0); + lightningBtn.setHoverText("ability.hover.lightning"); + addButton(lightningBtn); // Only show Lightning settings if Lightning is enabled if (laser.hasLightningEffect()) { @@ -149,6 +155,7 @@ public class SubGuiAbilityLaserShot extends SubGuiAbilityConfig { switch (id) { case 106: laser.setExplosive(value == 1); + initGui(); break; case 150: setSubGui(new SubGuiAbilityEffects(laser.getEffects())); 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 c43569c46..858eeefa7 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 @@ -57,21 +57,29 @@ public class SubGuiAbilityOrb extends SubGuiAbilityConfig { y += 24; - // Row 3: Homing + Homing Strength + // Row 3: Homing + Homing Strength (only show strength if homing) addLabel(new GuiNpcLabel(104, "ability.homing", labelX, y + 5)); - addButton(new GuiNpcButton(104, fieldX, y, 50, 20, new String[]{"gui.no", "gui.yes"}, orb.isHoming() ? 1 : 0)); + GuiNpcButton homingBtn = new GuiNpcButton(104, fieldX, y, 50, 20, new String[]{"gui.no", "gui.yes"}, orb.isHoming() ? 1 : 0); + homingBtn.setHoverText("ability.hover.homing"); + addButton(homingBtn); - addLabel(new GuiNpcLabel(105, "ability.homingStr", col2LabelX, y + 5)); - addTextField(createFloatField(105, col2FieldX, y, 50, orb.getHomingStrength())); + if (orb.isHoming()) { + addLabel(new GuiNpcLabel(105, "ability.homingStr", col2LabelX, y + 5)); + addTextField(createFloatField(105, col2FieldX, y, 50, orb.getHomingStrength())); + } y += 24; - // Row 4: Explosive + Explosion Radius + // Row 4: Explosive + Explosion Radius (only show radius if explosive) addLabel(new GuiNpcLabel(106, "ability.explosive", labelX, y + 5)); - addButton(new GuiNpcButton(106, fieldX, y, 50, 20, new String[]{"gui.no", "gui.yes"}, orb.isExplosive() ? 1 : 0)); + GuiNpcButton explosiveBtn = new GuiNpcButton(106, fieldX, y, 50, 20, new String[]{"gui.no", "gui.yes"}, orb.isExplosive() ? 1 : 0); + explosiveBtn.setHoverText("ability.hover.explosive"); + addButton(explosiveBtn); - addLabel(new GuiNpcLabel(107, "ability.explosionRad", col2LabelX, y + 5)); - addTextField(createFloatField(107, col2FieldX, y, 50, orb.getExplosionRadius())); + if (orb.isExplosive()) { + addLabel(new GuiNpcLabel(107, "ability.explosionRad", col2LabelX, y + 5)); + addTextField(createFloatField(107, col2FieldX, y, 50, orb.getExplosionRadius())); + } y += 24; @@ -98,7 +106,9 @@ public class SubGuiAbilityOrb extends SubGuiAbilityConfig { // Row 1: Anchor Point addLabel(new GuiNpcLabel(210, "ability.anchorPoint", labelX, y + 5)); - addButton(new GuiNpcButton(210, fieldX, y, 80, 20, AnchorPoint.getDisplayNames(), orb.getAnchorPoint().getId())); + GuiNpcButton anchorBtn = new GuiNpcButton(210, fieldX, y, 80, 20, AnchorPoint.getDisplayNames(), orb.getAnchorPoint().getId()); + anchorBtn.setHoverText("ability.hover.anchorPoint"); + addButton(anchorBtn); y += 24; @@ -137,7 +147,9 @@ public class SubGuiAbilityOrb extends SubGuiAbilityConfig { // Row 4: Lightning Effect Enabled addLabel(new GuiNpcLabel(205, "ability.lightning", labelX, y + 5)); - addButton(new GuiNpcButton(205, fieldX, y, 50, 20, new String[]{"gui.no", "gui.yes"}, orb.hasLightningEffect() ? 1 : 0)); + GuiNpcButton lightningBtn = new GuiNpcButton(205, fieldX, y, 50, 20, new String[]{"gui.no", "gui.yes"}, orb.hasLightningEffect() ? 1 : 0); + lightningBtn.setHoverText("ability.hover.lightning"); + addButton(lightningBtn); // Only show Lightning settings if Lightning is enabled if (orb.hasLightningEffect()) { @@ -162,9 +174,11 @@ public class SubGuiAbilityOrb extends SubGuiAbilityConfig { switch (id) { case 104: orb.setHoming(value == 1); + initGui(); break; case 106: orb.setExplosive(value == 1); + initGui(); break; case 150: setSubGui(new SubGuiAbilityEffects(orb.getEffects())); 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 52bf7a092..fe66fa242 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 @@ -58,21 +58,29 @@ public class SubGuiAbilityProjectile extends SubGuiAbilityConfig { y += 24; - // Row 3: Explosive + Explosion Radius + // Row 3: Explosive + Explosion Radius (only show radius if explosive) addLabel(new GuiNpcLabel(104, "ability.explosive", labelX, y + 5)); - addButton(new GuiNpcButton(104, fieldX, y, 50, 20, new String[]{"gui.no", "gui.yes"}, projectile.isExplosive() ? 1 : 0)); + GuiNpcButton explosiveBtn = new GuiNpcButton(104, fieldX, y, 50, 20, new String[]{"gui.no", "gui.yes"}, projectile.isExplosive() ? 1 : 0); + explosiveBtn.setHoverText("ability.hover.explosive"); + addButton(explosiveBtn); - addLabel(new GuiNpcLabel(105, "ability.explosionRad", col2LabelX, y + 5)); - addTextField(createFloatField(105, col2FieldX, y, 50, projectile.getExplosionRadius())); + if (projectile.isExplosive()) { + addLabel(new GuiNpcLabel(105, "ability.explosionRad", col2LabelX, y + 5)); + addTextField(createFloatField(105, col2FieldX, y, 50, projectile.getExplosionRadius())); + } y += 24; - // Row 4: Homing + Homing Strength + // Row 4: Homing + Homing Strength (only show strength if homing) addLabel(new GuiNpcLabel(106, "ability.homing", labelX, y + 5)); - addButton(new GuiNpcButton(106, fieldX, y, 50, 20, new String[]{"gui.no", "gui.yes"}, projectile.isHoming() ? 1 : 0)); + GuiNpcButton homingBtn = new GuiNpcButton(106, fieldX, y, 50, 20, new String[]{"gui.no", "gui.yes"}, projectile.isHoming() ? 1 : 0); + homingBtn.setHoverText("ability.hover.homing"); + addButton(homingBtn); - addLabel(new GuiNpcLabel(107, "ability.homingStr", col2LabelX, y + 5)); - addTextField(createFloatField(107, col2FieldX, y, 50, projectile.getHomingStrength())); + if (projectile.isHoming()) { + addLabel(new GuiNpcLabel(107, "ability.homingStr", col2LabelX, y + 5)); + addTextField(createFloatField(107, col2FieldX, y, 50, projectile.getHomingStrength())); + } y += 24; @@ -90,9 +98,11 @@ public class SubGuiAbilityProjectile extends SubGuiAbilityConfig { break; case 104: projectile.setExplosive(value == 1); + initGui(); break; case 106: projectile.setHoming(value == 1); + initGui(); break; case 150: setSubGui(new SubGuiAbilityEffects(projectile.getEffects())); 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 9a3dc2fe8..1561b408a 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 @@ -71,13 +71,17 @@ public class SubGuiAbilitySweeper extends SubGuiAbilityConfig { addTextField(createIntField(106, fieldX, y, 50, sweeper.getNumberOfRotations())); addLabel(new GuiNpcLabel(107, "ability.piercing", col2LabelX, y + 5)); - addButton(new GuiNpcButton(107, col2FieldX, y, 50, 20, new String[]{"gui.no", "gui.yes"}, sweeper.isPiercing() ? 1 : 0)); + GuiNpcButton piercingBtn = new GuiNpcButton(107, col2FieldX, y, 50, 20, new String[]{"gui.no", "gui.yes"}, sweeper.isPiercing() ? 1 : 0); + piercingBtn.setHoverText("ability.hover.piercing"); + addButton(piercingBtn); y += 24; // 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)); + GuiNpcButton lockTargetBtn = new GuiNpcButton(108, fieldX, y, 50, 20, new String[]{"gui.no", "gui.yes"}, sweeper.isLockOnTarget() ? 1 : 0); + lockTargetBtn.setHoverText("ability.hover.lockTarget"); + addButton(lockTargetBtn); y += 24; 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 1dfb12d22..e39918d2d 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 @@ -54,7 +54,9 @@ public class SubGuiAbilityTeleport extends SubGuiAbilityConfig { 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)); + GuiNpcButton losBtn1 = new GuiNpcButton(105, col2FieldX, y, 50, 20, new String[]{"gui.no", "gui.yes"}, teleport.isRequireLineOfSight() ? 1 : 0); + losBtn1.setHoverText("ability.hover.lineOfSight"); + addButton(losBtn1); y += 24; break; case SINGLE: @@ -63,7 +65,9 @@ public class SubGuiAbilityTeleport extends SubGuiAbilityConfig { 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)); + GuiNpcButton losBtn2 = new GuiNpcButton(105, col2FieldX, y, 50, 20, new String[]{"gui.no", "gui.yes"}, teleport.isRequireLineOfSight() ? 1 : 0); + losBtn2.setHoverText("ability.hover.lineOfSight"); + addButton(losBtn2); y += 24; break; case BEHIND: @@ -85,10 +89,14 @@ public class SubGuiAbilityTeleport extends SubGuiAbilityConfig { // 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)); + GuiNpcButton dmgStartBtn = new GuiNpcButton(108, fieldX, y, 50, 20, new String[]{"gui.no", "gui.yes"}, teleport.isDamageAtStart() ? 1 : 0); + dmgStartBtn.setHoverText("ability.hover.dmgAtStart"); + addButton(dmgStartBtn); 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)); + GuiNpcButton dmgEndBtn = new GuiNpcButton(109, col2FieldX, y, 50, 20, new String[]{"gui.no", "gui.yes"}, teleport.isDamageAtEnd() ? 1 : 0); + dmgEndBtn.setHoverText("ability.hover.dmgAtEnd"); + addButton(dmgEndBtn); y += 24; 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 c846565c4..edeb59635 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 @@ -39,7 +39,9 @@ public class SubGuiAbilityTrap extends SubGuiAbilityConfig { addLabel(new GuiNpcLabel(100, "ability.placement", col2LabelX, y + 5)); String[] placements = {"Caster", "Target", "Ahead"}; - addButton(new GuiNpcButton(100, col2FieldX, y, 55, 20, placements, trap.getPlacement().ordinal())); + GuiNpcButton placementBtn = new GuiNpcButton(100, col2FieldX, y, 55, 20, placements, trap.getPlacement().ordinal()); + placementBtn.setHoverText("ability.hover.placement"); + addButton(placementBtn); y += 24; 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 4cc7bc89a..b56828470 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 @@ -51,7 +51,9 @@ public class SubGuiAbilityVortex extends SubGuiAbilityConfig { // Row 3: AOE + Max Targets addLabel(new GuiNpcLabel(104, "ability.aoe", labelX, y + 5)); - addButton(new GuiNpcButton(104, fieldX, y, 50, 20, new String[]{"gui.no", "gui.yes"}, vortex.isAoe() ? 1 : 0)); + GuiNpcButton aoeBtn = new GuiNpcButton(104, fieldX, y, 50, 20, new String[]{"gui.no", "gui.yes"}, vortex.isAoe() ? 1 : 0); + aoeBtn.setHoverText("ability.hover.aoe"); + addButton(aoeBtn); addLabel(new GuiNpcLabel(105, "ability.maxTargets", col2LabelX, y + 5)); addTextField(createIntField(105, col2FieldX, y, 50, vortex.getMaxTargets())); @@ -65,7 +67,9 @@ public class SubGuiAbilityVortex extends SubGuiAbilityConfig { // Row 5: Damage on Pull + Pull Damage addLabel(new GuiNpcLabel(108, "ability.dmgOnPull", labelX, y + 5)); - addButton(new GuiNpcButton(108, fieldX, y, 50, 20, new String[]{"gui.no", "gui.yes"}, vortex.isDamageOnPull() ? 1 : 0)); + GuiNpcButton dmgOnPullBtn = new GuiNpcButton(108, fieldX, y, 50, 20, new String[]{"gui.no", "gui.yes"}, vortex.isDamageOnPull() ? 1 : 0); + dmgOnPullBtn.setHoverText("ability.hover.dmgOnPull"); + addButton(dmgOnPullBtn); addLabel(new GuiNpcLabel(109, "ability.pullDamage", col2LabelX, y + 5)); addTextField(createFloatField(109, col2FieldX, y, 50, vortex.getPullDamage())); diff --git a/src/main/java/noppes/npcs/client/gui/select/GuiAnimationSelection.java b/src/main/java/noppes/npcs/client/gui/select/GuiAnimationSelection.java index 882f5817b..cc3e06cca 100644 --- a/src/main/java/noppes/npcs/client/gui/select/GuiAnimationSelection.java +++ b/src/main/java/noppes/npcs/client/gui/select/GuiAnimationSelection.java @@ -58,7 +58,7 @@ public class GuiAnimationSelection extends SubGuiInterface implements ICustomScr if (scrollAnimations == null) { scrollAnimations = new GuiCustomScroll(this, 0, 0); - scrollAnimations.setSize(212, 163); + scrollAnimations.setSize(212, 150); } scrollAnimations.setList(getSearchList()); if (selectedName != null) { @@ -68,7 +68,8 @@ public class GuiAnimationSelection extends SubGuiInterface implements ICustomScr scrollAnimations.guiTop = guiTop + 14; this.addScroll(scrollAnimations); - addTextField(new GuiNpcTextField(55, this, fontRendererObj, guiLeft + 4, guiTop + 179, 212, 20, search)); + // Search textbox - moved up to avoid overlapping with buttons + addTextField(new GuiNpcTextField(55, this, fontRendererObj, guiLeft + 4, guiTop + 166, 212, 20, search)); } @Override diff --git a/src/main/java/noppes/npcs/client/gui/util/GuiNPCInterface.java b/src/main/java/noppes/npcs/client/gui/util/GuiNPCInterface.java index 8444c5c1d..11bbaf451 100644 --- a/src/main/java/noppes/npcs/client/gui/util/GuiNPCInterface.java +++ b/src/main/java/noppes/npcs/client/gui/util/GuiNPCInterface.java @@ -57,6 +57,7 @@ public abstract class GuiNPCInterface extends GuiScreen { public float bgScaleX = 1; public float bgScaleY = 1; public float bgScaleZ = 1; + public int bgTextureHeight = 256; // Actual content height in texture (for bottom border stitching) public GuiNPCInterface(EntityNPCInterface npc) { this.player = Minecraft.getMinecraft().thePlayer; @@ -74,6 +75,11 @@ public abstract class GuiNPCInterface extends GuiScreen { background = new ResourceLocation("customnpcs", "textures/gui/" + texture); } + public void setBackground(String texture, int textureHeight) { + background = new ResourceLocation("customnpcs", "textures/gui/" + texture); + bgTextureHeight = textureHeight; + } + public ResourceLocation getResource(String texture) { return new ResourceLocation("customnpcs", "textures/gui/" + texture); } @@ -421,23 +427,44 @@ public abstract class GuiNPCInterface extends GuiScreen { GL11.glTranslatef(guiLeft, guiTop, 0); GL11.glScalef(bgScale * bgScaleX, bgScale * bgScaleY, bgScale * bgScaleZ); mc.renderEngine.bindTexture(background); + + // Handle Y dimension: if ySize < texture content height, stitch bottom border + int topHeight = ySize; + int bottomHeight = 0; + int bottomTextureV = 0; + if (ySize < bgTextureHeight) { + // Keep bottom border from texture bottom (last 6 pixels of actual content) + bottomHeight = 6; + topHeight = ySize - bottomHeight; + bottomTextureV = bgTextureHeight - bottomHeight; + } + if (xSize > 256) { // GUI wider than texture: draw left portion, then right portion from texture edge - drawTexturedModalRect(0, 0, 0, 0, 250, ySize); - drawTexturedModalRect(250, 0, 256 - (xSize - 250), 0, xSize - 250, ySize); + drawTexturedModalRect(0, 0, 0, 0, 250, topHeight); + drawTexturedModalRect(250, 0, 256 - (xSize - 250), 0, xSize - 250, topHeight); + if (bottomHeight > 0) { + drawTexturedModalRect(0, topHeight, 0, bottomTextureV, 250, bottomHeight); + drawTexturedModalRect(250, topHeight, 256 - (xSize - 250), bottomTextureV, xSize - 250, bottomHeight); + } } else if (xSize < 256) { // GUI narrower than texture: stitch left and right edges together - // Left portion (first half of GUI) int leftWidth = xSize / 2; - // Right portion width (remaining) int rightWidth = xSize - leftWidth; - // Draw left side from texture start - drawTexturedModalRect(0, 0, 0, 0, leftWidth, ySize); - // Draw right side from texture end (256 - rightWidth) - drawTexturedModalRect(leftWidth, 0, 256 - rightWidth, 0, rightWidth, ySize); + // Draw top portion + drawTexturedModalRect(0, 0, 0, 0, leftWidth, topHeight); + drawTexturedModalRect(leftWidth, 0, 256 - rightWidth, 0, rightWidth, topHeight); + // Draw bottom border strip + if (bottomHeight > 0) { + drawTexturedModalRect(0, topHeight, 0, bottomTextureV, leftWidth, bottomHeight); + drawTexturedModalRect(leftWidth, topHeight, 256 - rightWidth, bottomTextureV, rightWidth, bottomHeight); + } } else { - // GUI exactly 256px: draw full texture - drawTexturedModalRect(0, 0, 0, 0, xSize, ySize); + // GUI exactly 256px wide + drawTexturedModalRect(0, 0, 0, 0, xSize, topHeight); + if (bottomHeight > 0) { + drawTexturedModalRect(0, topHeight, 0, bottomTextureV, xSize, bottomHeight); + } } GL11.glPopMatrix(); } diff --git a/src/main/resources/assets/customnpcs/lang/en_US.lang b/src/main/resources/assets/customnpcs/lang/en_US.lang index 8ac2d99c0..750a75f54 100644 --- a/src/main/resources/assets/customnpcs/lang/en_US.lang +++ b/src/main/resources/assets/customnpcs/lang/en_US.lang @@ -115,6 +115,7 @@ gui.play=Play gui.selectSound=Select Sound gui.selectnpc=Select NPC gui.select=Select +gui.sync=Sync gui.range=Range gui.partly=Partially gui.copy=Copy @@ -1504,6 +1505,8 @@ menu.abilities=Abilities ability.availableTypes=Available Types ability.npcAbilities=NPC Abilities ability.globalCooldown=Global Cooldown +ability.minCooldown=Min CD +ability.maxCooldown=Max CD ability.edit=Edit Ability ability.weight=Weight ability.targeting=Targeting @@ -1679,7 +1682,7 @@ ability.innerColor=Inner Color ability.outerColor=Outer Color ability.outerEnabled=Outer Glow ability.outerWidth=Outer Width -ability.lightning=Enable Lightning +ability.lightning=Lightning ability.lightningDensity=Density ability.lightningRadius=Radius ability.anchorPoint=Anchor Point @@ -1725,6 +1728,50 @@ ability.typeId=Type ID ability.conditions=Conditions ability.noTypeSettings=No type-specific settings +ability.hover.weight=Higher weight = more likely to be chosen when multiple abilities available +ability.hover.lockMove=Prevents NPC from moving while ability is charging or active +ability.hover.interruptible=If enabled, ability can be interrupted by taking damage +ability.hover.dazed=Stun duration in ticks if ability is interrupted (20 ticks = 1 second) +ability.hover.windup=Charge-up time before ability activates (20 ticks = 1 second) +ability.hover.cooldown=Time before ability can be used again (20 ticks = 1 second) +ability.hover.sync=Set windup ticks to match animation duration +ability.hover.minRange=Target must be at least this far away +ability.hover.maxRange=Target must be within this distance +ability.hover.targeting=How the ability selects its target +ability.hover.conditions=Requirements that must be met for ability to activate +ability.hover.showTelegraph=Show visual warning indicator during windup +ability.hover.windUpColor=Color of telegraph during charge-up phase +ability.hover.activeColor=Color of telegraph when ability is active +ability.hover.homing=Projectile tracks toward target +ability.hover.homingStr=How aggressively the projectile tracks (higher = tighter turns) +ability.hover.explosive=Creates explosion on impact +ability.hover.explosionRad=Size of explosion radius +ability.hover.piercing=Hits multiple targets instead of stopping on first hit +ability.hover.lightning=Add electrical effect to visuals +ability.hover.outerGlow=Enable outer glow layer around projectile +ability.hover.anchorPoint=Where on the NPC the ability spawns from +ability.hover.damage=Base damage dealt to targets +ability.hover.speed=Movement speed of projectile +ability.hover.lifetime=Maximum ticks before despawning +ability.hover.knockback=Push force applied to targets +ability.hover.boomerang=Projectile returns to caster after reaching max distance +ability.hover.dashMode=Aggressive dashes toward target, Defensive dashes away +ability.hover.aoe=Affects all valid targets in range instead of just one +ability.hover.dmgOnPull=Deal damage continuously while pulling targets +ability.hover.lineOfSight=Requires clear line of sight to the target +ability.hover.dmgAtStart=Deal damage at the teleport origin location +ability.hover.dmgAtEnd=Deal damage at the teleport destination +ability.hover.instant=Heals instantly instead of over time +ability.hover.healSelf=Ability can heal the casting NPC +ability.hover.healAllies=Ability can heal nearby allied NPCs +ability.hover.placement=Where the ability effect is placed (Caster, Target, etc.) +ability.hover.lockTarget=Sweeper beam tracks the target's position +ability.hover.canCounter=Enable counterattack when blocking damage +ability.hover.counterType=Flat = fixed damage, Percent = % of blocked damage +ability.hover.shape=Shape of the hazard zone (Circle, Ring, Cone) +ability.hover.affectsCaster=Hazard can damage the NPC that created it +ability.hover.sweepMode=Swipe = single arc attack, Spin = continuous rotation + # Conditions condition.edit=Edit Condition condition.hp_above=NPC HP Above