From 0ff501bb167713f7dcf52df1bb5fa3e68578a781 Mon Sep 17 00:00:00 2001 From: Kam Date: Mon, 2 Feb 2026 16:17:37 -0500 Subject: [PATCH] Declarative ability GUI: replace 18 SubGui classes with FieldDef system All ability GUI tabs (General, Target, Effects, Type, Visual) are now fully declarative via FieldDef definitions. Deleted 18 SubGuiAbility* classes (~3100 lines) and rewrote SubGuiAbilityConfig to use GuiScrollWindow for every tab with a unified field renderer. - Add FieldDef, FieldType, TabTarget, ColumnHint, TabDef gui framework - Add getFieldDefinitions() to all 18 ability subclasses - Add getBaseFieldDefinitions() to Ability.java for shared tabs - Merge COLOR/EFFECTS into SUB_GUI with convenience factories - Net reduction: ~3100 lines removed Co-Authored-By: Claude Opus 4.5 --- .../controllers/data/ability/Ability.java | 89 ++ .../data/ability/gui/ColumnHint.java | 7 + .../data/ability/gui/FieldDef.java | 287 +++++ .../data/ability/gui/FieldType.java | 11 + .../controllers/data/ability/gui/TabDef.java | 28 + .../data/ability/gui/TabTarget.java | 10 + .../data/ability/type/AbilityCharge.java | 23 +- .../data/ability/type/AbilityCutter.java | 35 +- .../data/ability/type/AbilityDash.java | 24 +- .../data/ability/type/AbilityDisc.java | 66 +- .../data/ability/type/AbilityEnergyBeam.java | 64 +- .../data/ability/type/AbilityGuard.java | 40 +- .../data/ability/type/AbilityHazard.java | 38 +- .../data/ability/type/AbilityHeal.java | 32 +- .../data/ability/type/AbilityHeavyHit.java | 26 +- .../data/ability/type/AbilityLaserShot.java | 55 +- .../data/ability/type/AbilityOrb.java | 62 +- .../data/ability/type/AbilityProjectile.java | 34 +- .../data/ability/type/AbilityShockwave.java | 24 +- .../data/ability/type/AbilitySlam.java | 24 +- .../data/ability/type/AbilitySweeper.java | 45 +- .../data/ability/type/AbilityTeleport.java | 41 +- .../data/ability/type/AbilityTrap.java | 32 +- .../data/ability/type/AbilityVortex.java | 32 +- .../gui/advanced/SubGuiAbilityConfig.java | 1145 +++++------------ .../advanced/ability/SubGuiAbilityCharge.java | 92 -- .../advanced/ability/SubGuiAbilityCutter.java | 141 -- .../advanced/ability/SubGuiAbilityDash.java | 65 - .../advanced/ability/SubGuiAbilityDisc.java | 323 ----- .../ability/SubGuiAbilityEnergyBeam.java | 312 ----- .../advanced/ability/SubGuiAbilityGuard.java | 143 -- .../advanced/ability/SubGuiAbilityHazard.java | 159 --- .../advanced/ability/SubGuiAbilityHeal.java | 106 -- .../ability/SubGuiAbilityHeavyHit.java | 76 -- .../ability/SubGuiAbilityLaserShot.java | 268 ---- .../advanced/ability/SubGuiAbilityOrb.java | 294 ----- .../ability/SubGuiAbilityProjectile.java | 145 --- .../ability/SubGuiAbilityShockwave.java | 95 -- .../advanced/ability/SubGuiAbilitySlam.java | 98 -- .../ability/SubGuiAbilitySweeper.java | 219 ---- .../ability/SubGuiAbilityTeleport.java | 165 --- .../advanced/ability/SubGuiAbilityTrap.java | 126 -- .../advanced/ability/SubGuiAbilityVortex.java | 129 -- 43 files changed, 1232 insertions(+), 3998 deletions(-) create mode 100644 src/main/java/kamkeel/npcs/controllers/data/ability/gui/ColumnHint.java create mode 100644 src/main/java/kamkeel/npcs/controllers/data/ability/gui/FieldDef.java create mode 100644 src/main/java/kamkeel/npcs/controllers/data/ability/gui/FieldType.java create mode 100644 src/main/java/kamkeel/npcs/controllers/data/ability/gui/TabDef.java create mode 100644 src/main/java/kamkeel/npcs/controllers/data/ability/gui/TabTarget.java delete mode 100644 src/main/java/noppes/npcs/client/gui/advanced/ability/SubGuiAbilityCharge.java delete mode 100644 src/main/java/noppes/npcs/client/gui/advanced/ability/SubGuiAbilityCutter.java delete mode 100644 src/main/java/noppes/npcs/client/gui/advanced/ability/SubGuiAbilityDash.java delete mode 100644 src/main/java/noppes/npcs/client/gui/advanced/ability/SubGuiAbilityDisc.java delete mode 100644 src/main/java/noppes/npcs/client/gui/advanced/ability/SubGuiAbilityEnergyBeam.java delete mode 100644 src/main/java/noppes/npcs/client/gui/advanced/ability/SubGuiAbilityGuard.java delete mode 100644 src/main/java/noppes/npcs/client/gui/advanced/ability/SubGuiAbilityHazard.java delete mode 100644 src/main/java/noppes/npcs/client/gui/advanced/ability/SubGuiAbilityHeal.java delete mode 100644 src/main/java/noppes/npcs/client/gui/advanced/ability/SubGuiAbilityHeavyHit.java delete mode 100644 src/main/java/noppes/npcs/client/gui/advanced/ability/SubGuiAbilityLaserShot.java delete mode 100644 src/main/java/noppes/npcs/client/gui/advanced/ability/SubGuiAbilityOrb.java delete mode 100644 src/main/java/noppes/npcs/client/gui/advanced/ability/SubGuiAbilityProjectile.java delete mode 100644 src/main/java/noppes/npcs/client/gui/advanced/ability/SubGuiAbilityShockwave.java delete mode 100644 src/main/java/noppes/npcs/client/gui/advanced/ability/SubGuiAbilitySlam.java delete mode 100644 src/main/java/noppes/npcs/client/gui/advanced/ability/SubGuiAbilitySweeper.java delete mode 100644 src/main/java/noppes/npcs/client/gui/advanced/ability/SubGuiAbilityTeleport.java delete mode 100644 src/main/java/noppes/npcs/client/gui/advanced/ability/SubGuiAbilityTrap.java delete mode 100644 src/main/java/noppes/npcs/client/gui/advanced/ability/SubGuiAbilityVortex.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 b67ed95ac..b368d6267 100644 --- a/src/main/java/kamkeel/npcs/controllers/data/ability/Ability.java +++ b/src/main/java/kamkeel/npcs/controllers/data/ability/Ability.java @@ -23,7 +23,11 @@ import noppes.npcs.entity.EntityNPCInterface; import noppes.npcs.scripted.NpcAPI; import noppes.npcs.scripted.event.AbilityEvent; +import kamkeel.npcs.controllers.data.ability.gui.FieldDef; +import kamkeel.npcs.controllers.data.ability.gui.TabTarget; + import java.util.ArrayList; +import java.util.Collections; import java.util.List; import net.minecraft.entity.Entity; @@ -300,6 +304,91 @@ public abstract class Ability implements IAbility { return true; } + /** + * Returns the declarative field definitions for this ability's GUI. + * Override in subclasses to declare type-specific and visual fields. + * The GUI rendering engine in SubGuiAbilityConfig uses this list to + * automatically build the Type and Visual tabs. + */ + public List getFieldDefinitions() { + return Collections.emptyList(); + } + + /** + * Returns field definitions for all base Ability fields (General, Target, Effects tabs). + */ + @SideOnly(Side.CLIENT) + public List getBaseFieldDefinitions() { + List defs = new ArrayList<>(); + + // General tab + defs.add(FieldDef.stringField("gui.name", this::getName, this::setName) + .tab(TabTarget.GENERAL)); + defs.add(FieldDef.intField("ability.weight", this::getWeight, this::setWeight) + .tab(TabTarget.GENERAL).range(1, 1000)); + defs.add(FieldDef.enumField("ability.lockMove", LockMovementType.class, + this::getLockMovement, this::setLockMovement) + .tab(TabTarget.GENERAL).hover("ability.hover.lockMove")); + defs.add(FieldDef.boolField("ability.interruptible", this::isInterruptible, this::setInterruptible) + .tab(TabTarget.GENERAL).hover("ability.hover.interruptible")); + defs.add(FieldDef.intField("ability.dazed", this::getDazedTicks, this::setDazedTicks) + .tab(TabTarget.GENERAL).range(0, 1000) + .visibleWhen(this::isInterruptible)); + defs.add(FieldDef.intField("ability.windup", this::getWindUpTicks, this::setWindUpTicks) + .tab(TabTarget.GENERAL).range(0, 1000)); + defs.add(FieldDef.intField("ability.cooldown", this::getCooldownTicks, this::setCooldownTicks) + .tab(TabTarget.GENERAL).range(0, 10000)); + defs.add(FieldDef.boolField("gui.enabled", this::isEnabled, this::setEnabled) + .tab(TabTarget.GENERAL)); + + // Target tab + defs.add(FieldDef.intField("ability.minRange", () -> (int) getMinRange(), v -> setMinRange(v)) + .tab(TabTarget.TARGET).range(0, 100)); + defs.add(FieldDef.intField("ability.maxRange", () -> (int) getMaxRange(), v -> setMaxRange(v)) + .tab(TabTarget.TARGET).range(1, 100)); + if (!isTargetingModeLocked()) { + defs.add(FieldDef.enumField("ability.targeting", TargetingMode.class, + this::getTargetingMode, this::setTargetingMode) + .tab(TabTarget.TARGET).hover("ability.hover.targeting")); + } + + // Effects tab + defs.add(FieldDef.soundSubGui("ability.windUpSound", this::getWindUpSound, this::setWindUpSound) + .tab(TabTarget.EFFECTS)); + defs.add(FieldDef.soundSubGui("ability.activeSound", this::getActiveSound, this::setActiveSound) + .tab(TabTarget.EFFECTS)); + defs.add(FieldDef.animSubGui("ability.windUpAnim", + this::getWindUpAnimationId, this::setWindUpAnimationId, + this::getWindUpAnimationName, this::setWindUpAnimationName) + .tab(TabTarget.EFFECTS)); + defs.add(FieldDef.animSubGui("ability.activeAnim", + this::getActiveAnimationId, this::setActiveAnimationId, + this::getActiveAnimationName, this::setActiveAnimationName) + .tab(TabTarget.EFFECTS)); + + TelegraphType tType = getTelegraphType(); + if (tType != null && tType != TelegraphType.NONE) { + defs.add(FieldDef.boolField("ability.showTelegraph", this::isShowTelegraph, this::setShowTelegraph) + .tab(TabTarget.EFFECTS).hover("ability.hover.showTelegraph")); + defs.add(FieldDef.colorSubGui("ability.windUpColor", this::getWindUpColor, this::setWindUpColor) + .tab(TabTarget.EFFECTS).visibleWhen(this::isShowTelegraph)); + defs.add(FieldDef.colorSubGui("ability.activeColor", this::getActiveColor, this::setActiveColor) + .tab(TabTarget.EFFECTS).visibleWhen(this::isShowTelegraph)); + } + + return defs; + } + + /** + * Returns ALL field definitions: base (General/Target/Effects) + type-specific (Type/Visual). + */ + @SideOnly(Side.CLIENT) + public final List getAllFieldDefinitions() { + List all = new ArrayList<>(getBaseFieldDefinitions()); + all.addAll(getFieldDefinitions()); + return all; + } + /** * Returns true if this ability type has custom settings that need a Type-specific tab. * Override to return true if the ability has settings beyond the base Ability fields. diff --git a/src/main/java/kamkeel/npcs/controllers/data/ability/gui/ColumnHint.java b/src/main/java/kamkeel/npcs/controllers/data/ability/gui/ColumnHint.java new file mode 100644 index 000000000..a1b5dd270 --- /dev/null +++ b/src/main/java/kamkeel/npcs/controllers/data/ability/gui/ColumnHint.java @@ -0,0 +1,7 @@ +package kamkeel.npcs.controllers.data.ability.gui; + +public enum ColumnHint { + FULL, + LEFT, + RIGHT +} diff --git a/src/main/java/kamkeel/npcs/controllers/data/ability/gui/FieldDef.java b/src/main/java/kamkeel/npcs/controllers/data/ability/gui/FieldDef.java new file mode 100644 index 000000000..25ec6cb66 --- /dev/null +++ b/src/main/java/kamkeel/npcs/controllers/data/ability/gui/FieldDef.java @@ -0,0 +1,287 @@ +package kamkeel.npcs.controllers.data.ability.gui; + +import kamkeel.npcs.controllers.data.ability.AbilityEffect; +import noppes.npcs.client.gui.SubGuiColorSelector; +import noppes.npcs.client.gui.advanced.ability.SubGuiAbilityEffects; +import noppes.npcs.client.gui.select.GuiAnimationSelection; +import noppes.npcs.client.gui.select.GuiSoundSelection; +import noppes.npcs.client.gui.util.SubGuiInterface; + +import java.util.List; +import java.util.function.BooleanSupplier; +import java.util.function.Consumer; +import java.util.function.Supplier; + +/** + * Declarative field definition for ability GUI rendering. + * Built via static factories and chaining methods. + */ +public class FieldDef { + + private final String label; + private final FieldType type; + private TabTarget tab = TabTarget.TYPE; + private String customTabName = null; + private ColumnHint column = ColumnHint.FULL; + private Supplier getter; + private Consumer setter; + private BooleanSupplier visibleWhen = () -> true; + private String tooltip = null; + private String hoverText = null; + + // Numeric range + private float min = Float.MIN_VALUE; + private float max = Float.MAX_VALUE; + + // Enum support + private Class> enumClass; + private String[] stringEnumValues; + private Supplier stringEnumGetter; + private Consumer stringEnumSetter; + + // Sub-gui support + private Supplier subGuiFactory; + private Consumer subGuiResultHandler; + + // Button display + private Supplier buttonLabelSupplier; + private Supplier buttonTextColorSupplier; + private Runnable clearAction; + + private FieldDef(String label, FieldType type) { + this.label = label; + this.type = type; + } + + // ═══════════════════════════════════════════════════════════════════ + // STATIC FACTORIES + // ═══════════════════════════════════════════════════════════════════ + + public static FieldDef floatField(String label, Supplier getter, Consumer setter) { + FieldDef def = new FieldDef(label, FieldType.FLOAT); + def.getter = () -> getter.get(); + def.setter = v -> setter.accept(((Number) v).floatValue()); + return def; + } + + public static FieldDef intField(String label, Supplier getter, Consumer setter) { + FieldDef def = new FieldDef(label, FieldType.INT); + def.getter = () -> getter.get(); + def.setter = v -> setter.accept(((Number) v).intValue()); + return def; + } + + public static FieldDef boolField(String label, Supplier getter, Consumer setter) { + FieldDef def = new FieldDef(label, FieldType.BOOLEAN); + def.getter = () -> getter.get(); + def.setter = v -> setter.accept((Boolean) v); + return def; + } + + @SuppressWarnings("unchecked") + public static > FieldDef enumField(String label, Class enumClass, Supplier getter, Consumer setter) { + FieldDef def = new FieldDef(label, FieldType.ENUM); + def.enumClass = enumClass; + def.getter = () -> getter.get(); + def.setter = v -> setter.accept((E) v); + return def; + } + + public static FieldDef stringEnumField(String label, String[] values, Supplier getter, Consumer setter) { + FieldDef def = new FieldDef(label, FieldType.STRING_ENUM); + def.stringEnumValues = values; + def.stringEnumGetter = getter; + def.stringEnumSetter = setter; + return def; + } + + public static FieldDef stringField(String label, Supplier getter, Consumer setter) { + FieldDef def = new FieldDef(label, FieldType.STRING); + def.getter = () -> getter.get(); + def.setter = v -> setter.accept((String) v); + return def; + } + + public static FieldDef subGuiField(String label, Supplier factory, Consumer resultHandler) { + FieldDef def = new FieldDef(label, FieldType.SUB_GUI); + def.subGuiFactory = factory; + def.subGuiResultHandler = resultHandler; + return def; + } + + // ═══════════════════════════════════════════════════════════════════ + // CONVENIENCE FACTORIES (SUB_GUI wrappers) + // ═══════════════════════════════════════════════════════════════════ + + public static FieldDef colorSubGui(String label, Supplier getter, Consumer setter) { + return subGuiField(label, + () -> new SubGuiColorSelector(getter.get()), + gui -> setter.accept(((SubGuiColorSelector) gui).color & 0x00FFFFFF)) + .buttonLabel(() -> String.format("%06X", getter.get() & 0xFFFFFF)) + .buttonTextColor(() -> getter.get() & 0xFFFFFF); + } + + public static FieldDef effectsSubGui(String label, Supplier> getter, Consumer> setter) { + return subGuiField(label, + () -> new SubGuiAbilityEffects(getter.get()), + gui -> { + List r = ((SubGuiAbilityEffects) gui).getResult(); + if (r != null) setter.accept(r); + }); + } + + public static FieldDef soundSubGui(String label, Supplier getter, Consumer setter) { + return subGuiField(label, + () -> new GuiSoundSelection(getter.get()), + gui -> { + GuiSoundSelection s = (GuiSoundSelection) gui; + if (s.selectedResource != null) setter.accept(s.selectedResource.toString()); + }) + .buttonLabel(() -> { + String s = getter.get(); + return s == null || s.isEmpty() ? "gui.none" : truncateEnd(s, 10); + }) + .clearable(() -> setter.accept("")); + } + + public static FieldDef animSubGui(String label, + Supplier idGetter, Consumer idSetter, + Supplier nameGetter, Consumer nameSetter) { + return subGuiField(label, + () -> new GuiAnimationSelection(idGetter.get(), nameGetter.get()), + gui -> { + GuiAnimationSelection sel = (GuiAnimationSelection) gui; + if (sel.isBuiltInSelected()) { + nameSetter.accept(sel.selectedBuiltInName); + idSetter.accept(-1); + } else { + idSetter.accept(sel.selectedAnimationId); + nameSetter.accept(""); + } + }) + .buttonLabel(() -> { + String name = nameGetter.get(); + if (name != null && !name.isEmpty()) return truncateEnd(name, 8); + int id = idGetter.get(); + return id >= 0 ? "ID: " + id : "gui.none"; + }) + .clearable(() -> { idSetter.accept(-1); nameSetter.accept(""); }); + } + + // ═══════════════════════════════════════════════════════════════════ + // CHAINING METHODS + // ═══════════════════════════════════════════════════════════════════ + + public FieldDef tab(TabTarget tab) { + this.tab = tab; + return this; + } + + public FieldDef customTab(String tabName) { + this.tab = TabTarget.CUSTOM; + this.customTabName = tabName; + return this; + } + + public FieldDef range(float min, float max) { + this.min = min; + this.max = max; + return this; + } + + public FieldDef column(ColumnHint column) { + this.column = column; + return this; + } + + public FieldDef visibleWhen(BooleanSupplier condition) { + this.visibleWhen = condition; + return this; + } + + public FieldDef tooltip(String tooltip) { + this.tooltip = tooltip; + return this; + } + + public FieldDef hover(String hoverText) { + this.hoverText = hoverText; + return this; + } + + public FieldDef buttonLabel(Supplier supplier) { + this.buttonLabelSupplier = supplier; + return this; + } + + public FieldDef buttonTextColor(Supplier supplier) { + this.buttonTextColorSupplier = supplier; + return this; + } + + public FieldDef clearable(Runnable action) { + this.clearAction = action; + return this; + } + + // ═══════════════════════════════════════════════════════════════════ + // GETTERS + // ═══════════════════════════════════════════════════════════════════ + + public String getLabel() { return label; } + public FieldType getType() { return type; } + public TabTarget getTab() { return tab; } + public String getCustomTabName() { return customTabName; } + public ColumnHint getColumn() { return column; } + public boolean isVisible() { return visibleWhen.getAsBoolean(); } + public String getTooltip() { return tooltip; } + public String getHoverText() { return hoverText; } + public float getMin() { return min; } + public float getMax() { return max; } + public boolean hasRange() { return min != Float.MIN_VALUE || max != Float.MAX_VALUE; } + public Class> getEnumClass() { return enumClass; } + public String[] getStringEnumValues() { return stringEnumValues; } + public Supplier getSubGuiFactory() { return subGuiFactory; } + public Consumer getSubGuiResultHandler() { return subGuiResultHandler; } + public boolean hasClearAction() { return clearAction != null; } + public Runnable getClearAction() { return clearAction; } + + public Object getValue() { + return getter != null ? getter.get() : null; + } + + public void setValue(Object value) { + if (setter != null) setter.accept(value); + } + + public String getStringEnumValue() { + return stringEnumGetter != null ? stringEnumGetter.get() : null; + } + + public void setStringEnumValue(String value) { + if (stringEnumSetter != null) stringEnumSetter.accept(value); + } + + public String getButtonLabel() { + if (buttonLabelSupplier != null) return buttonLabelSupplier.get(); + return label; + } + + public Integer getButtonTextColor() { + return buttonTextColorSupplier != null ? buttonTextColorSupplier.get() : null; + } + + // ═══════════════════════════════════════════════════════════════════ + // HELPERS + // ═══════════════════════════════════════════════════════════════════ + + static String truncateEnd(String str, int maxLen) { + if (str == null) return ""; + if (str.length() <= maxLen) return str; + int lastSlash = str.lastIndexOf('/'); + if (lastSlash >= 0 && str.length() - lastSlash <= maxLen) { + return "..." + str.substring(lastSlash); + } + return "..." + str.substring(str.length() - maxLen + 3); + } +} diff --git a/src/main/java/kamkeel/npcs/controllers/data/ability/gui/FieldType.java b/src/main/java/kamkeel/npcs/controllers/data/ability/gui/FieldType.java new file mode 100644 index 000000000..b908d9b88 --- /dev/null +++ b/src/main/java/kamkeel/npcs/controllers/data/ability/gui/FieldType.java @@ -0,0 +1,11 @@ +package kamkeel.npcs.controllers.data.ability.gui; + +public enum FieldType { + FLOAT, + INT, + BOOLEAN, + ENUM, + STRING_ENUM, + SUB_GUI, + STRING +} diff --git a/src/main/java/kamkeel/npcs/controllers/data/ability/gui/TabDef.java b/src/main/java/kamkeel/npcs/controllers/data/ability/gui/TabDef.java new file mode 100644 index 000000000..64d1501fd --- /dev/null +++ b/src/main/java/kamkeel/npcs/controllers/data/ability/gui/TabDef.java @@ -0,0 +1,28 @@ +package kamkeel.npcs.controllers.data.ability.gui; + +/** + * Simple data class representing a tab in the ability config GUI. + * Built automatically from the FieldDef list. + */ +public class TabDef { + + public final String name; + public final TabTarget target; + public int index; + + public TabDef(String name, TabTarget target, int index) { + this.name = name; + this.target = target; + this.index = index; + } + + /** + * Returns a unique key combining target and custom name for deduplication. + */ + public String getKey() { + if (target == TabTarget.CUSTOM && name != null) { + return "CUSTOM:" + name; + } + return target.name(); + } +} diff --git a/src/main/java/kamkeel/npcs/controllers/data/ability/gui/TabTarget.java b/src/main/java/kamkeel/npcs/controllers/data/ability/gui/TabTarget.java new file mode 100644 index 000000000..aba49646b --- /dev/null +++ b/src/main/java/kamkeel/npcs/controllers/data/ability/gui/TabTarget.java @@ -0,0 +1,10 @@ +package kamkeel.npcs.controllers.data.ability.gui; + +public enum TabTarget { + GENERAL, + TYPE, + TARGET, + EFFECTS, + VISUAL, + CUSTOM +} diff --git a/src/main/java/kamkeel/npcs/controllers/data/ability/type/AbilityCharge.java b/src/main/java/kamkeel/npcs/controllers/data/ability/type/AbilityCharge.java index 25941e0a5..8241fab86 100644 --- a/src/main/java/kamkeel/npcs/controllers/data/ability/type/AbilityCharge.java +++ b/src/main/java/kamkeel/npcs/controllers/data/ability/type/AbilityCharge.java @@ -14,13 +14,13 @@ import net.minecraft.nbt.NBTTagCompound; import net.minecraft.util.AxisAlignedBB; import net.minecraft.util.Vec3; import net.minecraft.world.World; -import noppes.npcs.client.gui.advanced.SubGuiAbilityConfig; -import noppes.npcs.client.gui.advanced.ability.SubGuiAbilityCharge; -import noppes.npcs.client.gui.util.IAbilityConfigCallback; import noppes.npcs.entity.EntityNPCInterface; +import kamkeel.npcs.controllers.data.ability.gui.FieldDef; +import kamkeel.npcs.controllers.data.ability.gui.TabTarget; import noppes.npcs.api.ability.type.IAbilityCharge; +import java.util.Arrays; import java.util.HashSet; import java.util.List; import java.util.Set; @@ -63,12 +63,6 @@ public class AbilityCharge extends Ability implements IAbilityCharge { return true; } - @Override - @SideOnly(Side.CLIENT) - public SubGuiAbilityConfig createConfigGui(IAbilityConfigCallback callback) { - return new SubGuiAbilityCharge(this, callback); - } - @Override public boolean isTargetingModeLocked() { return true; @@ -405,4 +399,15 @@ public class AbilityCharge extends Ability implements IAbilityCharge { public void setHitWidth(float hitWidth) { this.hitWidth = hitWidth; } + + @Override + public List getFieldDefinitions() { + return Arrays.asList( + FieldDef.floatField("enchantment.damage", this::getDamage, this::setDamage), + FieldDef.floatField("stats.speed", this::getChargeSpeed, this::setChargeSpeed), + FieldDef.floatField("ability.knockback", this::getKnockback, this::setKnockback), + FieldDef.floatField("ability.hitWidth", this::getHitWidth, this::setHitWidth), + FieldDef.effectsSubGui("ability.effects", this::getEffects, this::setEffects) + ); + } } 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 9db9d7700..29ae4aa22 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 @@ -1,7 +1,5 @@ package kamkeel.npcs.controllers.data.ability.type; -import cpw.mods.fml.relauncher.Side; -import cpw.mods.fml.relauncher.SideOnly; import kamkeel.npcs.controllers.data.ability.Ability; import kamkeel.npcs.controllers.data.ability.LockMovementType; import kamkeel.npcs.controllers.data.ability.TargetingMode; @@ -11,13 +9,14 @@ import net.minecraft.nbt.NBTTagCompound; import net.minecraft.util.AxisAlignedBB; import net.minecraft.util.DamageSource; import net.minecraft.world.World; -import noppes.npcs.client.gui.advanced.SubGuiAbilityConfig; -import noppes.npcs.client.gui.advanced.ability.SubGuiAbilityCutter; -import noppes.npcs.client.gui.util.IAbilityConfigCallback; import noppes.npcs.entity.EntityNPCInterface; import noppes.npcs.api.ability.type.IAbilityCutter; +import kamkeel.npcs.controllers.data.ability.gui.FieldDef; +import kamkeel.npcs.controllers.data.ability.gui.TabTarget; + +import java.util.Arrays; import java.util.HashSet; import java.util.List; import java.util.Set; @@ -68,12 +67,6 @@ public class AbilityCutter extends Ability implements IAbilityCutter { return true; } - @Override - @SideOnly(Side.CLIENT) - public SubGuiAbilityConfig createConfigGui(IAbilityConfigCallback callback) { - return new SubGuiAbilityCutter(this, callback); - } - @Override public boolean isTargetingModeLocked() { return true; @@ -311,4 +304,24 @@ public class AbilityCutter extends Ability implements IAbilityCutter { public float getCurrentRotation() { return currentRotation; } + + @Override + public List getFieldDefinitions() { + return Arrays.asList( + FieldDef.floatField("enchantment.damage", this::getDamage, this::setDamage), + FieldDef.floatField("gui.range", this::getRange, this::setRange), + FieldDef.floatField("ability.arcAngle", this::getArcAngle, this::setArcAngle), + FieldDef.floatField("ability.innerRadius", this::getInnerRadius, this::setInnerRadius), + FieldDef.floatField("ability.knockback", this::getKnockback, this::setKnockback), + FieldDef.floatField("ability.sweepSpeed", this::getSweepSpeed, this::setSweepSpeed), + FieldDef.enumField("ability.sweepMode", SweepMode.class, this::getSweepModeEnum, this::setSweepModeEnum) + .hover("ability.hover.sweepMode"), + FieldDef.boolField("ability.piercing", this::isPiercing, this::setPiercing) + .hover("ability.hover.piercing"), + FieldDef.intField("ability.duration", this::getSpinDurationTicks, this::setSpinDurationTicks) + .range(1, 1000) + .visibleWhen(() -> this.getSweepModeEnum() == SweepMode.SPIN), + FieldDef.effectsSubGui("ability.effects", this::getEffects, this::setEffects) + ); + } } diff --git a/src/main/java/kamkeel/npcs/controllers/data/ability/type/AbilityDash.java b/src/main/java/kamkeel/npcs/controllers/data/ability/type/AbilityDash.java index 054176a7b..3684a8b73 100644 --- a/src/main/java/kamkeel/npcs/controllers/data/ability/type/AbilityDash.java +++ b/src/main/java/kamkeel/npcs/controllers/data/ability/type/AbilityDash.java @@ -10,13 +10,14 @@ import net.minecraft.entity.EntityLivingBase; import net.minecraft.nbt.NBTTagCompound; import net.minecraft.util.Vec3; import net.minecraft.world.World; -import noppes.npcs.client.gui.advanced.SubGuiAbilityConfig; -import noppes.npcs.client.gui.advanced.ability.SubGuiAbilityDash; -import noppes.npcs.client.gui.util.IAbilityConfigCallback; import noppes.npcs.entity.EntityNPCInterface; +import kamkeel.npcs.controllers.data.ability.gui.FieldDef; +import kamkeel.npcs.controllers.data.ability.gui.TabTarget; import noppes.npcs.api.ability.type.IAbilityDash; +import java.util.Arrays; +import java.util.List; import java.util.Random; /** @@ -104,13 +105,6 @@ public class AbilityDash extends Ability implements IAbilityDash { return true; } - @Override - @SideOnly(Side.CLIENT) - public SubGuiAbilityConfig createConfigGui( - IAbilityConfigCallback callback) { - return new SubGuiAbilityDash(this, callback); - } - @Override public boolean isTargetingModeLocked() { return true; @@ -349,4 +343,14 @@ public class AbilityDash extends Ability implements IAbilityDash { public DashDirection getChosenDirection() { return chosenDirection; } + + @Override + public List getFieldDefinitions() { + return Arrays.asList( + FieldDef.enumField("ability.mode", DashMode.class, this::getDashModeEnum, this::setDashModeEnum) + .hover("ability.hover.dashMode"), + FieldDef.floatField("ability.dashDist", this::getDashDistance, this::setDashDistance), + FieldDef.floatField("ability.dashSpeed", this::getDashSpeed, this::setDashSpeed) + ); + } } diff --git a/src/main/java/kamkeel/npcs/controllers/data/ability/type/AbilityDisc.java b/src/main/java/kamkeel/npcs/controllers/data/ability/type/AbilityDisc.java index 3ef2e164d..fb2f94646 100644 --- a/src/main/java/kamkeel/npcs/controllers/data/ability/type/AbilityDisc.java +++ b/src/main/java/kamkeel/npcs/controllers/data/ability/type/AbilityDisc.java @@ -17,10 +17,12 @@ import net.minecraft.entity.EntityLivingBase; import net.minecraft.nbt.NBTTagCompound; import net.minecraft.util.Vec3; import net.minecraft.world.World; -import noppes.npcs.client.gui.advanced.SubGuiAbilityConfig; -import noppes.npcs.client.gui.advanced.ability.SubGuiAbilityDisc; -import noppes.npcs.client.gui.util.IAbilityConfigCallback; +import kamkeel.npcs.controllers.data.ability.gui.FieldDef; +import kamkeel.npcs.controllers.data.ability.gui.TabTarget; import noppes.npcs.api.ability.type.IAbilityDisc; + +import java.util.Arrays; +import java.util.List; import noppes.npcs.entity.EntityNPCInterface; /** @@ -69,12 +71,6 @@ public class AbilityDisc extends Ability implements IAbilityDisc { return true; } - @Override - @SideOnly(Side.CLIENT) - public SubGuiAbilityConfig createConfigGui(IAbilityConfigCallback callback) { - return new SubGuiAbilityDisc(this, callback); - } - @Override public boolean isTargetingModeLocked() { return true; @@ -279,4 +275,56 @@ public class AbilityDisc extends Ability implements IAbilityDisc { public int getPreviewActiveDuration() { return lifespanData.maxLifetime > 0 ? Math.min(lifespanData.maxLifetime, 100) : 100; } + + @Override + public List getFieldDefinitions() { + return Arrays.asList( + // Type tab + FieldDef.floatField("enchantment.damage", this::getDamage, this::setDamage), + FieldDef.floatField("stats.speed", this::getSpeed, this::setSpeed), + FieldDef.floatField("ability.discRadius", this::getDiscRadius, this::setDiscRadius), + FieldDef.floatField("ability.discThickness", this::getDiscThickness, this::setDiscThickness), + FieldDef.boolField("ability.homing", this::isHoming, this::setHoming) + .hover("ability.hover.homing"), + FieldDef.floatField("ability.homingStr", this::getHomingStrength, this::setHomingStrength) + .visibleWhen(this::isHoming), + FieldDef.boolField("ability.boomerang", this::isBoomerang, this::setBoomerang) + .hover("ability.hover.boomerang"), + FieldDef.intField("ability.boomerangDelay", this::getBoomerangDelay, this::setBoomerangDelay) + .visibleWhen(this::isBoomerang), + FieldDef.boolField("ability.explosive", this::isExplosive, this::setExplosive) + .hover("ability.hover.explosive"), + FieldDef.floatField("ability.explosionRad", this::getExplosionRadius, this::setExplosionRadius) + .visibleWhen(this::isExplosive), + FieldDef.floatField("ability.knockback", this::getKnockback, this::setKnockback), + FieldDef.floatField("ability.maxDist", this::getMaxDistance, this::setMaxDistance), + FieldDef.intField("ability.lifetime", this::getMaxLifetime, this::setMaxLifetime), + FieldDef.effectsSubGui("ability.effects", this::getEffects, this::setEffects), + // Visual tab + FieldDef.enumField("ability.anchorPoint", AnchorPoint.class, this::getAnchorPointEnum, this::setAnchorPointEnum) + .tab(TabTarget.VISUAL), + FieldDef.colorSubGui("ability.innerColor", this::getInnerColor, this::setInnerColor) + .tab(TabTarget.VISUAL), + FieldDef.colorSubGui("ability.outerColor", this::getOuterColor, this::setOuterColor) + .tab(TabTarget.VISUAL), + FieldDef.boolField("ability.outerEnabled", this::isOuterColorEnabled, this::setOuterColorEnabled) + .tab(TabTarget.VISUAL), + FieldDef.floatField("ability.outerWidth", this::getOuterColorWidth, this::setOuterColorWidth) + .tab(TabTarget.VISUAL) + .visibleWhen(this::isOuterColorEnabled), + FieldDef.floatField("ability.outerAlpha", this::getOuterColorAlpha, this::setOuterColorAlpha) + .tab(TabTarget.VISUAL).range(0, 1) + .visibleWhen(this::isOuterColorEnabled), + FieldDef.floatField("ability.rotationSpeed", this::getRotationSpeed, this::setRotationSpeed) + .tab(TabTarget.VISUAL), + FieldDef.boolField("ability.lightning", this::hasLightningEffect, this::setLightningEffect) + .tab(TabTarget.VISUAL), + FieldDef.floatField("ability.lightningDensity", this::getLightningDensity, this::setLightningDensity) + .tab(TabTarget.VISUAL).range(0.01f, 5.0f) + .visibleWhen(this::hasLightningEffect), + FieldDef.floatField("ability.lightningRadius", this::getLightningRadius, this::setLightningRadius) + .tab(TabTarget.VISUAL).range(0.1f, 10.0f) + .visibleWhen(this::hasLightningEffect) + ); + } } diff --git a/src/main/java/kamkeel/npcs/controllers/data/ability/type/AbilityEnergyBeam.java b/src/main/java/kamkeel/npcs/controllers/data/ability/type/AbilityEnergyBeam.java index 53377161a..89fe6acfc 100644 --- a/src/main/java/kamkeel/npcs/controllers/data/ability/type/AbilityEnergyBeam.java +++ b/src/main/java/kamkeel/npcs/controllers/data/ability/type/AbilityEnergyBeam.java @@ -17,10 +17,12 @@ import net.minecraft.entity.EntityLivingBase; import net.minecraft.nbt.NBTTagCompound; import net.minecraft.util.Vec3; import net.minecraft.world.World; -import noppes.npcs.client.gui.advanced.SubGuiAbilityConfig; -import noppes.npcs.client.gui.advanced.ability.SubGuiAbilityEnergyBeam; -import noppes.npcs.client.gui.util.IAbilityConfigCallback; +import kamkeel.npcs.controllers.data.ability.gui.FieldDef; +import kamkeel.npcs.controllers.data.ability.gui.TabTarget; import noppes.npcs.api.ability.type.IAbilityEnergyBeam; + +import java.util.Arrays; +import java.util.List; import noppes.npcs.entity.EntityNPCInterface; /** @@ -66,12 +68,6 @@ public class AbilityEnergyBeam extends Ability implements IAbilityEnergyBeam { return true; } - @Override - @SideOnly(Side.CLIENT) - public SubGuiAbilityConfig createConfigGui(IAbilityConfigCallback callback) { - return new SubGuiAbilityEnergyBeam(this, callback); - } - @Override public boolean isTargetingModeLocked() { return true; @@ -282,4 +278,54 @@ public class AbilityEnergyBeam extends Ability implements IAbilityEnergyBeam { public int getPreviewActiveDuration() { return lifespanData.maxLifetime > 0 ? Math.min(lifespanData.maxLifetime, 100) : 100; } + + @Override + public List getFieldDefinitions() { + return Arrays.asList( + // Type tab + FieldDef.floatField("enchantment.damage", this::getDamage, this::setDamage), + FieldDef.floatField("stats.speed", this::getSpeed, this::setSpeed), + FieldDef.floatField("ability.beamWidth", this::getBeamWidth, this::setBeamWidth), + FieldDef.floatField("ability.headSize", this::getHeadSize, this::setHeadSize), + FieldDef.boolField("ability.homing", this::isHoming, this::setHoming) + .hover("ability.hover.homing"), + FieldDef.floatField("ability.homingStr", this::getHomingStrength, this::setHomingStrength) + .visibleWhen(this::isHoming), + FieldDef.floatField("ability.homingRange", this::getHomingRange, this::setHomingRange) + .visibleWhen(this::isHoming), + FieldDef.floatField("ability.maxDist", this::getMaxDistance, this::setMaxDistance), + FieldDef.boolField("ability.explosive", this::isExplosive, this::setExplosive) + .hover("ability.hover.explosive"), + FieldDef.floatField("ability.explosionRad", this::getExplosionRadius, this::setExplosionRadius) + .visibleWhen(this::isExplosive), + FieldDef.floatField("ability.knockback", this::getKnockback, this::setKnockback), + FieldDef.intField("ability.lifetime", this::getMaxLifetime, this::setMaxLifetime), + FieldDef.effectsSubGui("ability.effects", this::getEffects, this::setEffects), + // Visual tab + FieldDef.enumField("ability.anchorPoint", AnchorPoint.class, this::getAnchorPointEnum, this::setAnchorPointEnum) + .tab(TabTarget.VISUAL), + FieldDef.colorSubGui("ability.innerColor", this::getInnerColor, this::setInnerColor) + .tab(TabTarget.VISUAL), + FieldDef.colorSubGui("ability.outerColor", this::getOuterColor, this::setOuterColor) + .tab(TabTarget.VISUAL), + FieldDef.boolField("ability.outerEnabled", this::isOuterColorEnabled, this::setOuterColorEnabled) + .tab(TabTarget.VISUAL), + FieldDef.floatField("ability.outerWidth", this::getOuterColorWidth, this::setOuterColorWidth) + .tab(TabTarget.VISUAL) + .visibleWhen(this::isOuterColorEnabled), + FieldDef.floatField("ability.outerAlpha", this::getOuterColorAlpha, this::setOuterColorAlpha) + .tab(TabTarget.VISUAL).range(0, 1) + .visibleWhen(this::isOuterColorEnabled), + FieldDef.floatField("ability.rotationSpeed", this::getRotationSpeed, this::setRotationSpeed) + .tab(TabTarget.VISUAL), + FieldDef.boolField("ability.lightning", this::hasLightningEffect, this::setLightningEffect) + .tab(TabTarget.VISUAL), + FieldDef.floatField("ability.lightningDensity", this::getLightningDensity, this::setLightningDensity) + .tab(TabTarget.VISUAL).range(0.01f, 5.0f) + .visibleWhen(this::hasLightningEffect), + FieldDef.floatField("ability.lightningRadius", this::getLightningRadius, this::setLightningRadius) + .tab(TabTarget.VISUAL).range(0.1f, 10.0f) + .visibleWhen(this::hasLightningEffect) + ); + } } diff --git a/src/main/java/kamkeel/npcs/controllers/data/ability/type/AbilityGuard.java b/src/main/java/kamkeel/npcs/controllers/data/ability/type/AbilityGuard.java index 92c7ca58e..bfa7b0f34 100644 --- a/src/main/java/kamkeel/npcs/controllers/data/ability/type/AbilityGuard.java +++ b/src/main/java/kamkeel/npcs/controllers/data/ability/type/AbilityGuard.java @@ -1,7 +1,5 @@ package kamkeel.npcs.controllers.data.ability.type; -import cpw.mods.fml.relauncher.Side; -import cpw.mods.fml.relauncher.SideOnly; import kamkeel.npcs.controllers.data.ability.Ability; import kamkeel.npcs.controllers.data.ability.LockMovementType; import kamkeel.npcs.controllers.data.ability.TargetingMode; @@ -10,13 +8,15 @@ import net.minecraft.entity.EntityLivingBase; import net.minecraft.nbt.NBTTagCompound; import net.minecraft.util.DamageSource; import net.minecraft.world.World; -import noppes.npcs.client.gui.advanced.SubGuiAbilityConfig; -import noppes.npcs.client.gui.advanced.ability.SubGuiAbilityGuard; -import noppes.npcs.client.gui.util.IAbilityConfigCallback; import noppes.npcs.entity.EntityNPCInterface; import noppes.npcs.api.ability.type.IAbilityGuard; +import kamkeel.npcs.controllers.data.ability.gui.FieldDef; +import kamkeel.npcs.controllers.data.ability.gui.TabTarget; + +import java.util.Arrays; +import java.util.List; import java.util.Random; /** @@ -67,13 +67,6 @@ public class AbilityGuard extends Ability implements IAbilityGuard { return true; } - @Override - @SideOnly(Side.CLIENT) - public SubGuiAbilityConfig createConfigGui( - IAbilityConfigCallback callback) { - return new SubGuiAbilityGuard(this, callback); - } - @Override public boolean isTargetingModeLocked() { return true; @@ -290,4 +283,27 @@ public class AbilityGuard extends Ability implements IAbilityGuard { public void setCounterAnimationId(int counterAnimationId) { this.counterAnimationId = counterAnimationId; } + + @Override + public List getFieldDefinitions() { + return Arrays.asList( + FieldDef.intField("ability.duration", this::getDurationTicks, this::setDurationTicks) + .range(1, 1000), + FieldDef.floatField("ability.dmgReduce", this::getDamageReduction, this::setDamageReduction), + FieldDef.boolField("ability.canCounter", this::isCanCounter, this::setCanCounter) + .hover("ability.hover.canCounter"), + FieldDef.enumField("ability.counterType", CounterType.class, this::getCounterTypeEnum, this::setCounterTypeEnum) + .hover("ability.hover.counterType") + .visibleWhen(this::isCanCounter), + FieldDef.floatField("ability.counterValue", this::getCounterValue, this::setCounterValue) + .visibleWhen(this::isCanCounter), + FieldDef.floatField("ability.counterChance", this::getCounterChance, this::setCounterChance) + .visibleWhen(this::isCanCounter), + FieldDef.stringField("ability.counterSound", this::getCounterSound, this::setCounterSound) + .visibleWhen(this::isCanCounter), + FieldDef.intField("ability.counterAnim", this::getCounterAnimationId, this::setCounterAnimationId) + .visibleWhen(this::isCanCounter), + FieldDef.effectsSubGui("ability.effects", this::getEffects, this::setEffects) + ); + } } diff --git a/src/main/java/kamkeel/npcs/controllers/data/ability/type/AbilityHazard.java b/src/main/java/kamkeel/npcs/controllers/data/ability/type/AbilityHazard.java index 61841ded4..cd5194b29 100644 --- a/src/main/java/kamkeel/npcs/controllers/data/ability/type/AbilityHazard.java +++ b/src/main/java/kamkeel/npcs/controllers/data/ability/type/AbilityHazard.java @@ -1,7 +1,5 @@ package kamkeel.npcs.controllers.data.ability.type; -import cpw.mods.fml.relauncher.Side; -import cpw.mods.fml.relauncher.SideOnly; import kamkeel.npcs.controllers.data.ability.Ability; import kamkeel.npcs.controllers.data.ability.LockMovementType; import kamkeel.npcs.controllers.data.ability.TargetingMode; @@ -14,13 +12,14 @@ import net.minecraft.potion.PotionEffect; import net.minecraft.util.AxisAlignedBB; import net.minecraft.util.DamageSource; import net.minecraft.world.World; -import noppes.npcs.client.gui.advanced.SubGuiAbilityConfig; -import noppes.npcs.client.gui.advanced.ability.SubGuiAbilityHazard; -import noppes.npcs.client.gui.util.IAbilityConfigCallback; import noppes.npcs.entity.EntityNPCInterface; import noppes.npcs.api.ability.type.IAbilityHazard; +import kamkeel.npcs.controllers.data.ability.gui.FieldDef; +import kamkeel.npcs.controllers.data.ability.gui.TabTarget; + +import java.util.Arrays; import java.util.HashSet; import java.util.List; import java.util.Random; @@ -95,13 +94,6 @@ public class AbilityHazard extends Ability implements IAbilityHazard { return true; } - @Override - @SideOnly(Side.CLIENT) - public SubGuiAbilityConfig createConfigGui( - IAbilityConfigCallback callback) { - return new SubGuiAbilityHazard(this, callback); - } - @Override public boolean isTargetingModeLocked() { return true; @@ -616,4 +608,26 @@ public class AbilityHazard extends Ability implements IAbilityHazard { public double getZoneZ() { return zoneZ; } + + @Override + public List getFieldDefinitions() { + return Arrays.asList( + FieldDef.intField("ability.duration", this::getDurationTicks, this::setDurationTicks) + .range(1, 2000), + FieldDef.enumField("ability.shape", HazardShape.class, this::getShapeEnum, this::setShapeEnum) + .hover("ability.hover.shape"), + FieldDef.enumField("ability.placement", PlacementMode.class, this::getPlacementEnum, this::setPlacementEnum) + .hover("ability.hover.placement"), + FieldDef.floatField("ability.radius", this::getRadius, this::setRadius), + FieldDef.floatField("ability.innerRadius", this::getInnerRadius, this::setInnerRadius), + FieldDef.floatField("ability.dmgPerSec", this::getDamagePerSecond, this::setDamagePerSecond), + FieldDef.intField("ability.dmgInterval", this::getDamageInterval, this::setDamageInterval), + FieldDef.intField("ability.slownessLvl", this::getSlownessLevel, this::setSlownessLevel), + FieldDef.intField("ability.debuffDur", this::getDebuffDuration, this::setDebuffDuration), + FieldDef.intField("ability.poisonLvl", this::getPoisonLevel, this::setPoisonLevel), + FieldDef.boolField("ability.affectsCaster", this::isAffectsCaster, this::setAffectsCaster) + .hover("ability.hover.affectsCaster"), + FieldDef.effectsSubGui("ability.effects", this::getEffects, this::setEffects) + ); + } } diff --git a/src/main/java/kamkeel/npcs/controllers/data/ability/type/AbilityHeal.java b/src/main/java/kamkeel/npcs/controllers/data/ability/type/AbilityHeal.java index 406be2f3a..543a26821 100644 --- a/src/main/java/kamkeel/npcs/controllers/data/ability/type/AbilityHeal.java +++ b/src/main/java/kamkeel/npcs/controllers/data/ability/type/AbilityHeal.java @@ -1,7 +1,5 @@ package kamkeel.npcs.controllers.data.ability.type; -import cpw.mods.fml.relauncher.Side; -import cpw.mods.fml.relauncher.SideOnly; import kamkeel.npcs.controllers.data.ability.Ability; import kamkeel.npcs.controllers.data.ability.LockMovementType; import kamkeel.npcs.controllers.data.ability.TargetingMode; @@ -11,14 +9,14 @@ import net.minecraft.entity.EntityLivingBase; import net.minecraft.nbt.NBTTagCompound; import net.minecraft.util.AxisAlignedBB; import net.minecraft.world.World; -import noppes.npcs.client.gui.advanced.SubGuiAbilityConfig; -import noppes.npcs.client.gui.advanced.ability.SubGuiAbilityHeal; -import noppes.npcs.client.gui.util.IAbilityConfigCallback; import noppes.npcs.entity.EntityNPCInterface; +import kamkeel.npcs.controllers.data.ability.gui.FieldDef; +import kamkeel.npcs.controllers.data.ability.gui.TabTarget; import noppes.npcs.api.ability.type.IAbilityHeal; import java.util.ArrayList; +import java.util.Arrays; import java.util.List; /** @@ -63,12 +61,6 @@ public class AbilityHeal extends Ability implements IAbilityHeal { return true; } - @Override - @SideOnly(Side.CLIENT) - public SubGuiAbilityConfig createConfigGui(IAbilityConfigCallback callback) { - return new SubGuiAbilityHeal(this, callback); - } - @Override public boolean isTargetingModeLocked() { return true; @@ -289,4 +281,22 @@ public class AbilityHeal extends Ability implements IAbilityHeal { public void setInstantHeal(boolean instantHeal) { this.instantHeal = instantHeal; } + + @Override + public List getFieldDefinitions() { + return Arrays.asList( + FieldDef.boolField("dialog.instant", this::isInstantHeal, this::setInstantHeal) + .hover("ability.hover.instant"), + FieldDef.intField("ability.duration", this::getDurationTicks, this::setDurationTicks) + .range(1, 1000) + .visibleWhen(() -> !this.isInstantHeal()), + FieldDef.floatField("ability.healAmount", this::getHealAmount, this::setHealAmount), + FieldDef.floatField("ability.healPercent", this::getHealPercent, this::setHealPercent), + FieldDef.floatField("ability.healRadius", this::getHealRadius, this::setHealRadius), + FieldDef.boolField("ability.healSelf", this::isHealSelf, this::setHealSelf) + .hover("ability.hover.healSelf"), + FieldDef.boolField("ability.healAllies", this::isHealAllies, this::setHealAllies) + .hover("ability.hover.healAllies") + ); + } } 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 4ed4a0e78..a86662304 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 @@ -1,7 +1,5 @@ package kamkeel.npcs.controllers.data.ability.type; -import cpw.mods.fml.relauncher.Side; -import cpw.mods.fml.relauncher.SideOnly; import kamkeel.npcs.controllers.data.ability.Ability; import kamkeel.npcs.controllers.data.ability.LockMovementType; import kamkeel.npcs.controllers.data.ability.TargetingMode; @@ -9,12 +7,14 @@ import kamkeel.npcs.controllers.data.telegraph.TelegraphType; import net.minecraft.entity.EntityLivingBase; import net.minecraft.nbt.NBTTagCompound; import net.minecraft.world.World; -import noppes.npcs.client.gui.advanced.SubGuiAbilityConfig; -import noppes.npcs.client.gui.advanced.ability.SubGuiAbilityHeavyHit; -import noppes.npcs.client.gui.util.IAbilityConfigCallback; +import kamkeel.npcs.controllers.data.ability.gui.FieldDef; +import kamkeel.npcs.controllers.data.ability.gui.TabTarget; import noppes.npcs.api.ability.type.IAbilityHeavyHit; import noppes.npcs.entity.EntityNPCInterface; +import java.util.Arrays; +import java.util.List; + /** * Heavy Hit ability: Single-target melee attack with optional stun. * Deals high damage to one target and can stun them. @@ -44,13 +44,6 @@ public class AbilityHeavyHit extends Ability implements IAbilityHeavyHit { return true; } - @Override - @SideOnly(Side.CLIENT) - public SubGuiAbilityConfig createConfigGui( - IAbilityConfigCallback callback) { - return new SubGuiAbilityHeavyHit(this, callback); - } - @Override public boolean isTargetingModeLocked() { return true; @@ -113,4 +106,13 @@ public class AbilityHeavyHit extends Ability implements IAbilityHeavyHit { public void setKnockback(float knockback) { this.knockback = knockback; } + + @Override + public List getFieldDefinitions() { + return Arrays.asList( + FieldDef.floatField("enchantment.damage", this::getDamage, this::setDamage), + FieldDef.floatField("ability.knockback", this::getKnockback, this::setKnockback), + FieldDef.effectsSubGui("ability.effects", this::getEffects, this::setEffects) + ); + } } diff --git a/src/main/java/kamkeel/npcs/controllers/data/ability/type/AbilityLaserShot.java b/src/main/java/kamkeel/npcs/controllers/data/ability/type/AbilityLaserShot.java index 3b45894b4..4d3ce9fbe 100644 --- a/src/main/java/kamkeel/npcs/controllers/data/ability/type/AbilityLaserShot.java +++ b/src/main/java/kamkeel/npcs/controllers/data/ability/type/AbilityLaserShot.java @@ -6,6 +6,8 @@ import kamkeel.npcs.controllers.data.ability.Ability; import kamkeel.npcs.controllers.data.ability.LockMovementType; import kamkeel.npcs.controllers.data.ability.TargetingMode; import kamkeel.npcs.controllers.data.ability.data.EnergyColorData; +import kamkeel.npcs.controllers.data.ability.gui.FieldDef; +import kamkeel.npcs.controllers.data.ability.gui.TabTarget; import kamkeel.npcs.controllers.data.ability.data.EnergyCombatData; import kamkeel.npcs.controllers.data.ability.data.EnergyLifespanData; import kamkeel.npcs.controllers.data.ability.data.EnergyLightningData; @@ -16,10 +18,10 @@ import net.minecraft.entity.EntityLivingBase; import net.minecraft.nbt.NBTTagCompound; import net.minecraft.util.DamageSource; import net.minecraft.world.World; -import noppes.npcs.client.gui.advanced.SubGuiAbilityConfig; -import noppes.npcs.client.gui.advanced.ability.SubGuiAbilityLaserShot; -import noppes.npcs.client.gui.util.IAbilityConfigCallback; import noppes.npcs.api.ability.type.IAbilityLaserShot; + +import java.util.Arrays; +import java.util.List; import noppes.npcs.entity.EntityNPCInterface; /** @@ -63,12 +65,6 @@ public class AbilityLaserShot extends Ability implements IAbilityLaserShot { return true; } - @Override - @SideOnly(Side.CLIENT) - public SubGuiAbilityConfig createConfigGui(IAbilityConfigCallback callback) { - return new SubGuiAbilityLaserShot(this, callback); - } - @Override public boolean isTargetingModeLocked() { return false; @@ -229,4 +225,45 @@ public class AbilityLaserShot extends Ability implements IAbilityLaserShot { public boolean spawnPreviewDuringWindup() { return false; // Laser has no charging, spawns at active phase } + + @Override + public List getFieldDefinitions() { + return Arrays.asList( + // Type tab + FieldDef.floatField("enchantment.damage", this::getDamage, this::setDamage), + FieldDef.floatField("ability.laserWidth", this::getLaserWidth, this::setLaserWidth), + FieldDef.floatField("ability.expansionSpeed", this::getExpansionSpeed, this::setExpansionSpeed), + FieldDef.intField("ability.lingerTicks", this::getLingerTicks, this::setLingerTicks), + FieldDef.floatField("ability.maxDist", this::getMaxDistance, this::setMaxDistance), + FieldDef.intField("ability.lifetime", this::getMaxLifetime, this::setMaxLifetime), + FieldDef.boolField("ability.explosive", this::isExplosive, this::setExplosive) + .hover("ability.hover.explosive"), + FieldDef.floatField("ability.explosionRad", this::getExplosionRadius, this::setExplosionRadius) + .visibleWhen(this::isExplosive), + FieldDef.floatField("ability.knockback", this::getKnockback, this::setKnockback), + FieldDef.floatField("ability.knockbackUp", this::getKnockbackUp, this::setKnockbackUp), + FieldDef.effectsSubGui("ability.effects", this::getEffects, this::setEffects), + // Visual tab + FieldDef.colorSubGui("ability.innerColor", this::getInnerColor, this::setInnerColor) + .tab(TabTarget.VISUAL), + FieldDef.colorSubGui("ability.outerColor", this::getOuterColor, this::setOuterColor) + .tab(TabTarget.VISUAL), + FieldDef.boolField("ability.outerEnabled", this::isOuterColorEnabled, this::setOuterColorEnabled) + .tab(TabTarget.VISUAL), + FieldDef.floatField("ability.outerWidth", this::getOuterColorWidth, this::setOuterColorWidth) + .tab(TabTarget.VISUAL) + .visibleWhen(this::isOuterColorEnabled), + FieldDef.floatField("ability.outerAlpha", this::getOuterColorAlpha, this::setOuterColorAlpha) + .tab(TabTarget.VISUAL).range(0, 1) + .visibleWhen(this::isOuterColorEnabled), + FieldDef.boolField("ability.lightning", this::hasLightningEffect, this::setLightningEffect) + .tab(TabTarget.VISUAL), + FieldDef.floatField("ability.lightningDensity", this::getLightningDensity, this::setLightningDensity) + .tab(TabTarget.VISUAL).range(0.01f, 5.0f) + .visibleWhen(this::hasLightningEffect), + FieldDef.floatField("ability.lightningRadius", this::getLightningRadius, this::setLightningRadius) + .tab(TabTarget.VISUAL).range(0.1f, 10.0f) + .visibleWhen(this::hasLightningEffect) + ); + } } diff --git a/src/main/java/kamkeel/npcs/controllers/data/ability/type/AbilityOrb.java b/src/main/java/kamkeel/npcs/controllers/data/ability/type/AbilityOrb.java index 78936adbf..f4c156f49 100644 --- a/src/main/java/kamkeel/npcs/controllers/data/ability/type/AbilityOrb.java +++ b/src/main/java/kamkeel/npcs/controllers/data/ability/type/AbilityOrb.java @@ -17,10 +17,12 @@ import net.minecraft.entity.EntityLivingBase; import net.minecraft.nbt.NBTTagCompound; import net.minecraft.util.Vec3; import net.minecraft.world.World; -import noppes.npcs.client.gui.advanced.SubGuiAbilityConfig; -import noppes.npcs.client.gui.advanced.ability.SubGuiAbilityOrb; -import noppes.npcs.client.gui.util.IAbilityConfigCallback; +import kamkeel.npcs.controllers.data.ability.gui.FieldDef; +import kamkeel.npcs.controllers.data.ability.gui.TabTarget; import noppes.npcs.api.ability.type.IAbilityOrb; + +import java.util.Arrays; +import java.util.List; import noppes.npcs.entity.EntityNPCInterface; /** @@ -65,12 +67,6 @@ public class AbilityOrb extends Ability implements IAbilityOrb { return true; } - @Override - @SideOnly(Side.CLIENT) - public SubGuiAbilityConfig createConfigGui(IAbilityConfigCallback callback) { - return new SubGuiAbilityOrb(this, callback); - } - @Override public boolean isTargetingModeLocked() { return true; @@ -418,4 +414,52 @@ public class AbilityOrb extends Ability implements IAbilityOrb { public int getPreviewActiveDuration() { return lifespanData.maxLifetime > 0 ? Math.min(lifespanData.maxLifetime, 100) : 100; } + + @Override + public List getFieldDefinitions() { + return Arrays.asList( + // Type tab + FieldDef.floatField("enchantment.damage", this::getDamage, this::setDamage), + FieldDef.floatField("stats.speed", this::getOrbSpeed, this::setOrbSpeed), + FieldDef.floatField("stats.size", this::getOrbSize, this::setOrbSize), + FieldDef.floatField("ability.maxDist", this::getMaxDistance, this::setMaxDistance), + FieldDef.boolField("ability.homing", this::isHoming, this::setHoming) + .hover("ability.hover.homing"), + FieldDef.floatField("ability.homingStr", this::getHomingStrength, this::setHomingStrength) + .visibleWhen(this::isHoming), + FieldDef.boolField("ability.explosive", this::isExplosive, this::setExplosive) + .hover("ability.hover.explosive"), + FieldDef.floatField("ability.explosionRad", this::getExplosionRadius, this::setExplosionRadius) + .visibleWhen(this::isExplosive), + FieldDef.floatField("ability.knockback", this::getKnockback, this::setKnockback), + FieldDef.intField("ability.lifetime", this::getMaxLifetime, this::setMaxLifetime), + FieldDef.effectsSubGui("ability.effects", this::getEffects, this::setEffects), + // Visual tab + FieldDef.enumField("ability.anchorPoint", AnchorPoint.class, this::getAnchorPointEnum, this::setAnchorPointEnum) + .tab(TabTarget.VISUAL), + FieldDef.colorSubGui("ability.innerColor", this::getInnerColor, this::setInnerColor) + .tab(TabTarget.VISUAL), + FieldDef.floatField("ability.rotationSpeed", this::getRotationSpeed, this::setRotationSpeed) + .tab(TabTarget.VISUAL), + FieldDef.boolField("ability.outerEnabled", this::isOuterColorEnabled, this::setOuterColorEnabled) + .tab(TabTarget.VISUAL), + FieldDef.floatField("ability.outerAlpha", this::getOuterColorAlpha, this::setOuterColorAlpha) + .tab(TabTarget.VISUAL).range(0, 1) + .visibleWhen(this::isOuterColorEnabled), + FieldDef.colorSubGui("ability.outerColor", this::getOuterColor, this::setOuterColor) + .tab(TabTarget.VISUAL) + .visibleWhen(this::isOuterColorEnabled), + FieldDef.floatField("ability.outerWidth", this::getOuterColorWidth, this::setOuterColorWidth) + .tab(TabTarget.VISUAL) + .visibleWhen(this::isOuterColorEnabled), + FieldDef.boolField("ability.lightning", this::hasLightningEffect, this::setLightningEffect) + .tab(TabTarget.VISUAL), + FieldDef.floatField("ability.lightningDensity", this::getLightningDensity, this::setLightningDensity) + .tab(TabTarget.VISUAL).range(0.01f, 5.0f) + .visibleWhen(this::hasLightningEffect), + FieldDef.floatField("ability.lightningRadius", this::getLightningRadius, this::setLightningRadius) + .tab(TabTarget.VISUAL).range(0.1f, 10.0f) + .visibleWhen(this::hasLightningEffect) + ); + } } diff --git a/src/main/java/kamkeel/npcs/controllers/data/ability/type/AbilityProjectile.java b/src/main/java/kamkeel/npcs/controllers/data/ability/type/AbilityProjectile.java index 6b81fabe7..03b815441 100644 --- a/src/main/java/kamkeel/npcs/controllers/data/ability/type/AbilityProjectile.java +++ b/src/main/java/kamkeel/npcs/controllers/data/ability/type/AbilityProjectile.java @@ -1,7 +1,5 @@ package kamkeel.npcs.controllers.data.ability.type; -import cpw.mods.fml.relauncher.Side; -import cpw.mods.fml.relauncher.SideOnly; import kamkeel.npcs.controllers.data.ability.Ability; import kamkeel.npcs.controllers.data.ability.LockMovementType; import kamkeel.npcs.controllers.data.ability.TargetingMode; @@ -10,13 +8,14 @@ import net.minecraft.entity.Entity; import net.minecraft.entity.EntityLivingBase; import net.minecraft.nbt.NBTTagCompound; import net.minecraft.world.World; -import noppes.npcs.client.gui.advanced.SubGuiAbilityConfig; -import noppes.npcs.client.gui.advanced.ability.SubGuiAbilityProjectile; -import noppes.npcs.client.gui.util.IAbilityConfigCallback; import noppes.npcs.entity.EntityNPCInterface; import noppes.npcs.api.ability.type.IAbilityProjectile; +import kamkeel.npcs.controllers.data.ability.gui.FieldDef; +import kamkeel.npcs.controllers.data.ability.gui.TabTarget; + +import java.util.Arrays; import java.util.List; /** @@ -54,12 +53,6 @@ public class AbilityProjectile extends Ability implements IAbilityProjectile { return true; } - @Override - @SideOnly(Side.CLIENT) - public SubGuiAbilityConfig createConfigGui(IAbilityConfigCallback callback) { - return new SubGuiAbilityProjectile(this, callback); - } - @Override public boolean isTargetingModeLocked() { return true; @@ -258,4 +251,23 @@ public class AbilityProjectile extends Ability implements IAbilityProjectile { public void setHomingStrength(float homingStrength) { this.homingStrength = homingStrength; } + + @Override + public List getFieldDefinitions() { + return Arrays.asList( + FieldDef.floatField("enchantment.damage", this::getDamage, this::setDamage), + FieldDef.floatField("stats.speed", this::getSpeed, this::setSpeed), + FieldDef.floatField("ability.knockback", this::getKnockback, this::setKnockback), + FieldDef.stringEnumField("ability.projType", new String[]{"fireball", "arrow", "magic"}, this::getProjectileType, this::setProjectileType), + FieldDef.boolField("ability.explosive", this::isExplosive, this::setExplosive) + .hover("ability.hover.explosive"), + FieldDef.floatField("ability.explosionRad", this::getExplosionRadius, this::setExplosionRadius) + .visibleWhen(this::isExplosive), + FieldDef.boolField("ability.homing", this::isHoming, this::setHoming) + .hover("ability.hover.homing"), + FieldDef.floatField("ability.homingStr", this::getHomingStrength, this::setHomingStrength) + .visibleWhen(this::isHoming), + FieldDef.effectsSubGui("ability.effects", this::getEffects, this::setEffects) + ); + } } 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 006084f5e..83af93df7 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 @@ -1,7 +1,5 @@ package kamkeel.npcs.controllers.data.ability.type; -import cpw.mods.fml.relauncher.Side; -import cpw.mods.fml.relauncher.SideOnly; import kamkeel.npcs.controllers.data.ability.Ability; import kamkeel.npcs.controllers.data.ability.LockMovementType; import kamkeel.npcs.controllers.data.ability.TargetingMode; @@ -11,13 +9,13 @@ import net.minecraft.nbt.NBTTagCompound; import net.minecraft.util.AxisAlignedBB; import net.minecraft.util.DamageSource; import net.minecraft.world.World; -import noppes.npcs.client.gui.advanced.SubGuiAbilityConfig; -import noppes.npcs.client.gui.advanced.ability.SubGuiAbilityShockwave; -import noppes.npcs.client.gui.util.IAbilityConfigCallback; import noppes.npcs.entity.EntityNPCInterface; +import kamkeel.npcs.controllers.data.ability.gui.FieldDef; +import kamkeel.npcs.controllers.data.ability.gui.TabTarget; import noppes.npcs.api.ability.type.IAbilityShockwave; +import java.util.Arrays; import java.util.List; /** @@ -49,12 +47,6 @@ public class AbilityShockwave extends Ability implements IAbilityShockwave { return true; } - @Override - @SideOnly(Side.CLIENT) - public SubGuiAbilityConfig createConfigGui(IAbilityConfigCallback callback) { - return new SubGuiAbilityShockwave(this, callback); - } - @Override public boolean isTargetingModeLocked() { return true; @@ -175,4 +167,14 @@ public class AbilityShockwave extends Ability implements IAbilityShockwave { this.maxTargets = maxTargets; } + @Override + public List getFieldDefinitions() { + return Arrays.asList( + FieldDef.floatField("enchantment.damage", this::getDamage, this::setDamage), + FieldDef.floatField("ability.pushRadius", this::getPushRadius, this::setPushRadius), + FieldDef.floatField("ability.pushStrength", this::getPushStrength, this::setPushStrength), + FieldDef.intField("ability.maxTargets", this::getMaxTargets, this::setMaxTargets), + FieldDef.effectsSubGui("ability.effects", this::getEffects, this::setEffects) + ); + } } diff --git a/src/main/java/kamkeel/npcs/controllers/data/ability/type/AbilitySlam.java b/src/main/java/kamkeel/npcs/controllers/data/ability/type/AbilitySlam.java index b3c800d81..b26e203c1 100644 --- a/src/main/java/kamkeel/npcs/controllers/data/ability/type/AbilitySlam.java +++ b/src/main/java/kamkeel/npcs/controllers/data/ability/type/AbilitySlam.java @@ -13,14 +13,14 @@ import net.minecraft.entity.EntityLivingBase; import net.minecraft.nbt.NBTTagCompound; import net.minecraft.util.DamageSource; import net.minecraft.world.World; -import noppes.npcs.client.gui.advanced.SubGuiAbilityConfig; -import noppes.npcs.client.gui.advanced.ability.SubGuiAbilitySlam; -import noppes.npcs.client.gui.util.IAbilityConfigCallback; import noppes.npcs.entity.EntityNPCInterface; import noppes.npcs.api.ability.type.IAbilitySlam; import somehussar.gui.annotationHandling.GuiEditable; +import kamkeel.npcs.controllers.data.ability.gui.FieldDef; +import kamkeel.npcs.controllers.data.ability.gui.TabTarget; +import java.util.Arrays; import java.util.List; /** @@ -71,12 +71,6 @@ public class AbilitySlam extends Ability implements IAbilitySlam { return true; } - @Override - @SideOnly(Side.CLIENT) - public SubGuiAbilityConfig createConfigGui(IAbilityConfigCallback callback) { - return new SubGuiAbilitySlam(this, callback); - } - /** * Slam can be AOE_SELF (jump in place) or AOE_TARGET (leap to target). */ @@ -573,4 +567,16 @@ public class AbilitySlam extends Ability implements IAbilitySlam { public void setLeapHeight(float leapHeight) { this.leapHeight = leapHeight; } + + @Override + public List getFieldDefinitions() { + return Arrays.asList( + FieldDef.floatField("enchantment.damage", this::getDamage, this::setDamage), + FieldDef.floatField("ability.radius", this::getRadius, this::setRadius), + FieldDef.floatField("ability.knockback", this::getKnockbackStrength, this::setKnockbackStrength), + FieldDef.floatField("ability.leapSpeed", this::getLeapSpeed, this::setLeapSpeed), + FieldDef.floatField("ability.leapHeight", this::getLeapHeight, this::setLeapHeight), + FieldDef.effectsSubGui("ability.effects", this::getEffects, this::setEffects) + ); + } } 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 976d9e44e..ef00df35e 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 @@ -1,11 +1,11 @@ package kamkeel.npcs.controllers.data.ability.type; -import cpw.mods.fml.relauncher.Side; -import cpw.mods.fml.relauncher.SideOnly; import kamkeel.npcs.controllers.data.ability.Ability; import kamkeel.npcs.controllers.data.ability.LockMovementType; import kamkeel.npcs.controllers.data.ability.TargetingMode; import kamkeel.npcs.controllers.data.ability.data.EnergyColorData; +import kamkeel.npcs.controllers.data.ability.gui.FieldDef; +import kamkeel.npcs.controllers.data.ability.gui.TabTarget; import kamkeel.npcs.controllers.data.telegraph.Telegraph; import kamkeel.npcs.controllers.data.telegraph.TelegraphInstance; import kamkeel.npcs.controllers.data.telegraph.TelegraphType; @@ -14,10 +14,10 @@ import net.minecraft.entity.EntityLivingBase; import net.minecraft.nbt.NBTTagCompound; import net.minecraft.world.World; import noppes.npcs.LogWriter; -import noppes.npcs.client.gui.advanced.SubGuiAbilityConfig; -import noppes.npcs.client.gui.advanced.ability.SubGuiAbilitySweeper; -import noppes.npcs.client.gui.util.IAbilityConfigCallback; import noppes.npcs.api.ability.type.IAbilitySweeper; + +import java.util.Arrays; +import java.util.List; import noppes.npcs.entity.EntityNPCInterface; /** @@ -66,12 +66,6 @@ public class AbilitySweeper extends Ability implements IAbilitySweeper { return true; } - @Override - @SideOnly(Side.CLIENT) - public SubGuiAbilityConfig createConfigGui(IAbilityConfigCallback callback) { - return new SubGuiAbilitySweeper(this, callback); - } - @Override public boolean isTargetingModeLocked() { return true; @@ -205,4 +199,33 @@ public class AbilitySweeper extends Ability implements IAbilitySweeper { public void setOuterColorWidth(float outerColorWidth) { colorData.outerColorWidth = outerColorWidth; } public boolean isOuterColorEnabled() { return colorData.outerColorEnabled; } public void setOuterColorEnabled(boolean outerColorEnabled) { colorData.outerColorEnabled = outerColorEnabled; } + + @Override + public List getFieldDefinitions() { + return Arrays.asList( + // Type tab + FieldDef.floatField("enchantment.damage", this::getDamage, this::setDamage), + FieldDef.intField("ability.dmgInterval", this::getDamageInterval, this::setDamageInterval), + FieldDef.floatField("ability.beamLength", this::getBeamLength, this::setBeamLength), + FieldDef.floatField("ability.beamWidth", this::getBeamWidth, this::setBeamWidth), + FieldDef.floatField("ability.beamHeight", this::getBeamHeight, this::setBeamHeight), + FieldDef.floatField("ability.sweepSpeed", this::getSweepSpeed, this::setSweepSpeed), + FieldDef.intField("ability.rotations", this::getNumberOfRotations, this::setNumberOfRotations), + FieldDef.boolField("ability.piercing", this::isPiercing, this::setPiercing) + .hover("ability.hover.piercing"), + FieldDef.boolField("ability.lockTarget", this::isLockOnTarget, this::setLockOnTarget) + .hover("ability.hover.lockTarget"), + FieldDef.effectsSubGui("ability.effects", this::getEffects, this::setEffects), + // Visual tab + FieldDef.colorSubGui("ability.innerColor", this::getInnerColor, this::setInnerColor) + .tab(TabTarget.VISUAL), + FieldDef.colorSubGui("ability.outerColor", this::getOuterColor, this::setOuterColor) + .tab(TabTarget.VISUAL), + FieldDef.boolField("ability.outerEnabled", this::isOuterColorEnabled, this::setOuterColorEnabled) + .tab(TabTarget.VISUAL), + FieldDef.floatField("ability.outerWidth", this::getOuterColorWidth, this::setOuterColorWidth) + .tab(TabTarget.VISUAL) + .visibleWhen(this::isOuterColorEnabled) + ); + } } 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 1fef00a55..284bdec03 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 @@ -1,7 +1,5 @@ package kamkeel.npcs.controllers.data.ability.type; -import cpw.mods.fml.relauncher.Side; -import cpw.mods.fml.relauncher.SideOnly; import kamkeel.npcs.controllers.data.ability.Ability; import kamkeel.npcs.controllers.data.ability.LockMovementType; import kamkeel.npcs.controllers.data.ability.TargetingMode; @@ -14,13 +12,14 @@ import net.minecraft.util.AxisAlignedBB; import net.minecraft.util.MathHelper; import net.minecraft.util.Vec3; import net.minecraft.world.World; -import noppes.npcs.client.gui.advanced.SubGuiAbilityConfig; -import noppes.npcs.client.gui.advanced.ability.SubGuiAbilityTeleport; -import noppes.npcs.client.gui.util.IAbilityConfigCallback; import noppes.npcs.entity.EntityNPCInterface; import noppes.npcs.api.ability.type.IAbilityTeleport; +import kamkeel.npcs.controllers.data.ability.gui.FieldDef; +import kamkeel.npcs.controllers.data.ability.gui.TabTarget; + +import java.util.Arrays; import java.util.List; import java.util.Random; @@ -77,13 +76,6 @@ public class AbilityTeleport extends Ability implements IAbilityTeleport { return true; } - @Override - @SideOnly(Side.CLIENT) - public SubGuiAbilityConfig createConfigGui( - IAbilityConfigCallback callback) { - return new SubGuiAbilityTeleport(this, callback); - } - @Override public boolean isTargetingModeLocked() { return true; @@ -534,4 +526,29 @@ public class AbilityTeleport extends Ability implements IAbilityTeleport { public void setDamageRadius(float damageRadius) { this.damageRadius = damageRadius; } + + @Override + public List getFieldDefinitions() { + return Arrays.asList( + FieldDef.enumField("ability.mode", TeleportMode.class, this::getModeEnum, this::setModeEnum), + FieldDef.floatField("ability.blinkRadius", this::getBlinkRadius, this::setBlinkRadius) + .visibleWhen(() -> this.getModeEnum() == TeleportMode.BLINK || this.getModeEnum() == TeleportMode.SINGLE), + FieldDef.intField("ability.blinkCount", this::getBlinkCount, this::setBlinkCount) + .visibleWhen(() -> this.getModeEnum() == TeleportMode.BLINK), + FieldDef.intField("ability.blinkDelay", this::getBlinkDelayTicks, this::setBlinkDelayTicks) + .visibleWhen(() -> this.getModeEnum() == TeleportMode.BLINK), + FieldDef.floatField("ability.behindDistance", this::getBehindDistance, this::setBehindDistance) + .visibleWhen(() -> this.getModeEnum() == TeleportMode.BEHIND), + FieldDef.boolField("ability.lineOfSight", this::isRequireLineOfSight, this::setRequireLineOfSight) + .hover("ability.hover.lineOfSight") + .visibleWhen(() -> this.getModeEnum() == TeleportMode.BLINK || this.getModeEnum() == TeleportMode.SINGLE), + FieldDef.floatField("enchantment.damage", this::getDamage, this::setDamage), + FieldDef.floatField("ability.dmgRadius", this::getDamageRadius, this::setDamageRadius), + FieldDef.boolField("ability.dmgAtStart", this::isDamageAtStart, this::setDamageAtStart) + .hover("ability.hover.dmgAtStart"), + FieldDef.boolField("ability.dmgAtEnd", this::isDamageAtEnd, this::setDamageAtEnd) + .hover("ability.hover.dmgAtEnd"), + FieldDef.effectsSubGui("ability.effects", this::getEffects, this::setEffects) + ); + } } 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 6bf69a60b..2cb7a8a26 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 @@ -1,7 +1,5 @@ package kamkeel.npcs.controllers.data.ability.type; -import cpw.mods.fml.relauncher.Side; -import cpw.mods.fml.relauncher.SideOnly; import kamkeel.npcs.controllers.data.ability.Ability; import kamkeel.npcs.controllers.data.ability.LockMovementType; import kamkeel.npcs.controllers.data.ability.TargetingMode; @@ -12,13 +10,14 @@ import net.minecraft.nbt.NBTTagCompound; import net.minecraft.util.AxisAlignedBB; import net.minecraft.util.DamageSource; import net.minecraft.world.World; -import noppes.npcs.client.gui.advanced.SubGuiAbilityConfig; -import noppes.npcs.client.gui.advanced.ability.SubGuiAbilityTrap; -import noppes.npcs.client.gui.util.IAbilityConfigCallback; import noppes.npcs.entity.EntityNPCInterface; import noppes.npcs.api.ability.type.IAbilityTrap; +import kamkeel.npcs.controllers.data.ability.gui.FieldDef; +import kamkeel.npcs.controllers.data.ability.gui.TabTarget; + +import java.util.Arrays; import java.util.HashSet; import java.util.List; import java.util.Random; @@ -78,12 +77,6 @@ public class AbilityTrap extends Ability implements IAbilityTrap { return true; } - @Override - @SideOnly(Side.CLIENT) - public SubGuiAbilityConfig createConfigGui(IAbilityConfigCallback callback) { - return new SubGuiAbilityTrap(this, callback); - } - @Override public boolean isTargetingModeLocked() { return true; @@ -464,4 +457,21 @@ public class AbilityTrap extends Ability implements IAbilityTrap { public boolean isArmed() { return armed; } + + @Override + public List getFieldDefinitions() { + return Arrays.asList( + FieldDef.intField("ability.duration", this::getDurationTicks, this::setDurationTicks) + .range(1, 2000), + FieldDef.enumField("ability.placement", TrapPlacement.class, this::getPlacementEnum, this::setPlacementEnum) + .hover("ability.hover.placement"), + FieldDef.floatField("ability.triggerRad", this::getTriggerRadius, this::setTriggerRadius), + FieldDef.floatField("enchantment.damage", this::getDamage, this::setDamage), + FieldDef.floatField("ability.dmgRadius", this::getDamageRadius, this::setDamageRadius), + FieldDef.intField("ability.armTime", this::getArmTime, this::setArmTime), + FieldDef.intField("ability.maxTriggers", this::getMaxTriggers, this::setMaxTriggers), + FieldDef.floatField("ability.knockback", this::getKnockback, this::setKnockback), + FieldDef.effectsSubGui("ability.effects", this::getEffects, this::setEffects) + ); + } } 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 1bcfb7cbc..61e246bc9 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 @@ -1,7 +1,5 @@ package kamkeel.npcs.controllers.data.ability.type; -import cpw.mods.fml.relauncher.Side; -import cpw.mods.fml.relauncher.SideOnly; import kamkeel.npcs.controllers.data.ability.Ability; import kamkeel.npcs.controllers.data.ability.LockMovementType; import kamkeel.npcs.controllers.data.ability.TargetingMode; @@ -10,13 +8,13 @@ import net.minecraft.entity.EntityLivingBase; import net.minecraft.nbt.NBTTagCompound; import net.minecraft.util.AxisAlignedBB; import net.minecraft.world.World; -import noppes.npcs.client.gui.advanced.SubGuiAbilityConfig; -import noppes.npcs.client.gui.advanced.ability.SubGuiAbilityVortex; -import noppes.npcs.client.gui.util.IAbilityConfigCallback; import noppes.npcs.entity.EntityNPCInterface; +import kamkeel.npcs.controllers.data.ability.gui.FieldDef; +import kamkeel.npcs.controllers.data.ability.gui.TabTarget; import noppes.npcs.api.ability.type.IAbilityVortex; +import java.util.Arrays; import java.util.HashSet; import java.util.List; import java.util.Set; @@ -67,13 +65,6 @@ public class AbilityVortex extends Ability implements IAbilityVortex { return true; } - @Override - @SideOnly(Side.CLIENT) - public SubGuiAbilityConfig createConfigGui( - IAbilityConfigCallback callback) { - return new SubGuiAbilityVortex(this, callback); - } - @Override public boolean isTargetingModeLocked() { return true; @@ -309,4 +300,21 @@ public class AbilityVortex extends Ability implements IAbilityVortex { public void setPullDamage(float pullDamage) { this.pullDamage = pullDamage; } + + @Override + public List getFieldDefinitions() { + return Arrays.asList( + FieldDef.floatField("ability.pullRadius", this::getPullRadius, this::setPullRadius), + FieldDef.floatField("ability.pullStrength", this::getPullStrength, this::setPullStrength), + FieldDef.floatField("enchantment.damage", this::getDamage, this::setDamage), + FieldDef.floatField("ability.knockback", this::getKnockback, this::setKnockback), + FieldDef.boolField("ability.aoe", this::isAoe, this::setAoe) + .hover("ability.hover.aoe"), + FieldDef.intField("ability.maxTargets", this::getMaxTargets, this::setMaxTargets), + FieldDef.boolField("ability.dmgOnPull", this::isDamageOnPull, this::setDamageOnPull) + .hover("ability.hover.dmgOnPull"), + FieldDef.floatField("ability.pullDamage", this::getPullDamage, this::setPullDamage), + FieldDef.effectsSubGui("ability.effects", this::getEffects, this::setEffects) + ); + } } 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 684138891..9c862e3b0 100644 --- a/src/main/java/noppes/npcs/client/gui/advanced/SubGuiAbilityConfig.java +++ b/src/main/java/noppes/npcs/client/gui/advanced/SubGuiAbilityConfig.java @@ -2,171 +2,95 @@ package noppes.npcs.client.gui.advanced; import kamkeel.npcs.controllers.data.ability.Ability; import kamkeel.npcs.controllers.data.ability.Condition; -import kamkeel.npcs.controllers.data.ability.LockMovementType; -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 kamkeel.npcs.controllers.data.ability.gui.FieldDef; +import kamkeel.npcs.controllers.data.ability.gui.FieldType; +import kamkeel.npcs.controllers.data.ability.gui.TabTarget; import net.minecraft.client.gui.GuiButton; import net.minecraft.nbt.NBTTagCompound; import net.minecraft.util.StatCollector; -import noppes.npcs.client.gui.SubGuiColorSelector; -import noppes.npcs.client.gui.select.GuiAnimationSelection; -import noppes.npcs.client.gui.select.GuiSoundSelection; import noppes.npcs.client.gui.util.GuiMenuTopButton; 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.GuiScrollWindow; import noppes.npcs.client.gui.util.IAbilityConfigCallback; import noppes.npcs.client.gui.util.ISubGuiListener; import noppes.npcs.client.gui.util.ITextfieldListener; import noppes.npcs.client.gui.util.SubGuiInterface; import java.util.ArrayList; +import java.util.HashMap; import java.util.List; +import java.util.Map; -/** - * Base SubGui for editing ability configuration with tabbed interface. - * Uses GuiMenuTopButton for navigation tabs. - *

- * Tabs: - * - General: Name, Weight, Lock Movement, Interruptible, Timing - * - Type: Type-specific settings per Ability (override in subclasses) - * - Target: Min/Max Range, Targeting Mode, Conditions (up to 3) - * - Effects: Sounds, Animations, Telegraph settings, Colors - *

- * Subclasses should override initTypeTab() and handleTypeButton()/handleTypeTextField() - * to provide type-specific settings UI. - */ public class SubGuiAbilityConfig extends SubGuiInterface implements ITextfieldListener, ISubGuiListener { - // Tab constants - protected static final int TAB_GENERAL = 0; - protected static final int TAB_TYPE = 1; - protected static final int TAB_TARGET = 2; - protected static final int TAB_EFFECTS = 3; - protected static final int TAB_VISUAL = 4; + private static final int DECLARATIVE_ID_START = 1000; + private static final int CLEAR_ID_START = 2000; - // Core references - protected final Ability ability; - protected final IAbilityConfigCallback callback; - protected int activeTab = TAB_GENERAL; + private static final int TAB_GENERAL = 0; + private static final int TAB_TYPE = 1; + private static final int TAB_TARGET = 2; + private static final int TAB_EFFECTS = 3; + private static final int TAB_VISUAL = 4; - // ═══════════════════════════════════════════════════════════════════════════ - // CACHED VALUES - General Tab - // ═══════════════════════════════════════════════════════════════════════════ - protected String name; - protected boolean enabled; - protected int weight; - protected LockMovementType lockMovement; - protected boolean interruptible; + private final Ability ability; + private final IAbilityConfigCallback callback; + private int activeTab = TAB_GENERAL; - // Timing - protected int cooldownTicks; - protected int windUpTicks; - protected int dazedTicks; - protected boolean syncWindupWithAnimation = true; // Sync windup ticks with animation duration + private List fieldDefs; + private boolean hasTypeFields; + private boolean hasVisualFields; - // ═══════════════════════════════════════════════════════════════════════════ - // CACHED VALUES - Target Tab - // ═══════════════════════════════════════════════════════════════════════════ - protected float minRange; - protected float maxRange; - protected TargetingMode targetingMode; - protected List conditions; + // Conditions are complex (list with add/edit/remove) - cached separately + private List conditions; + private int editingConditionIndex = -1; - // ═══════════════════════════════════════════════════════════════════════════ - // CACHED VALUES - Effects Tab - // ═══════════════════════════════════════════════════════════════════════════ - protected String windUpSound; - protected String activeSound; - protected int windUpAnimationId; - protected int activeAnimationId; - protected String windUpAnimationName = null; - protected String activeAnimationName = null; - - // Telegraph - protected boolean showTelegraph; - protected int windUpColor; - protected int activeColor; - - // Editing state - protected int editingColorId = 0; - protected int editingSoundId = 0; - protected int editingAnimationId = 0; - protected int editingConditionIndex = -1; - - // ═══════════════════════════════════════════════════════════════════════════ - // ABILITY TYPE FEATURES - // ═══════════════════════════════════════════════════════════════════════════ - protected final boolean supportsTelegraph; - protected final boolean targetingModeLocked; - protected final boolean hasTypeSettings; - protected final boolean hasVisualSettings; + // Event routing + private final Map buttonFieldMap = new HashMap<>(); + private final Map textFieldMap = new HashMap<>(); + private final Map clearFieldMap = new HashMap<>(); + private FieldDef activeSubGuiField = null; public SubGuiAbilityConfig(Ability ability, IAbilityConfigCallback callback) { this.ability = ability; this.callback = callback; - - // Cache values from ability - General - this.name = ability.getName() != null ? ability.getName() : ""; - this.enabled = ability.isEnabled(); - this.weight = ability.getWeight(); - this.lockMovement = ability.getLockMovement(); - this.interruptible = ability.isInterruptible(); - - // Timing - this.cooldownTicks = ability.getCooldownTicks(); - this.windUpTicks = ability.getWindUpTicks(); - this.dazedTicks = ability.getDazedTicks(); - - // Target - this.minRange = ability.getMinRange(); - this.maxRange = ability.getMaxRange(); - this.targetingMode = ability.getTargetingMode(); this.conditions = new ArrayList<>(ability.getConditions()); - // Effects - this.windUpSound = ability.getWindUpSound(); - this.activeSound = ability.getActiveSound(); - // Animation: check name first (built-in), then ID (user) - this.windUpAnimationName = ability.getWindUpAnimationName(); - this.activeAnimationName = ability.getActiveAnimationName(); - this.windUpAnimationId = ability.getWindUpAnimationId(); - this.activeAnimationId = ability.getActiveAnimationId(); - - // Telegraph - this.showTelegraph = ability.isShowTelegraph(); - this.windUpColor = ability.getWindUpColor(); - this.activeColor = ability.getActiveColor(); - - // Determine ability type features - TelegraphType defaultType = ability.getTelegraphType(); - this.supportsTelegraph = defaultType != null && defaultType != TelegraphType.NONE; - this.targetingModeLocked = ability.isTargetingModeLocked(); - this.hasTypeSettings = ability.hasTypeSettings(); - this.hasVisualSettings = hasVisualSettings(); + this.fieldDefs = ability.getAllFieldDefinitions(); + this.hasTypeFields = hasFieldsForTab(TabTarget.TYPE); + this.hasVisualFields = hasFieldsForTab(TabTarget.VISUAL); setBackground("menubg.png", 217); xSize = 356; ySize = 200; } + private boolean hasFieldsForTab(TabTarget target) { + for (FieldDef def : fieldDefs) { + if (def.getTab() == target) return true; + } + return false; + } + + // ═══════════════════════════════════════════════════════════════════════════ + // INIT GUI + // ═══════════════════════════════════════════════════════════════════════════ + @Override public void initGui() { super.initGui(); + buttonFieldMap.clear(); + textFieldMap.clear(); + clearFieldMap.clear(); - // ═══════════════════════════════════════════════════════════════════════ - // TOP TABS using GuiMenuTopButton - // ═══════════════════════════════════════════════════════════════════════ + // Tab buttons GuiMenuTopButton generalTab = new GuiMenuTopButton(90, guiLeft + 4, guiTop - 17, "menu.general"); generalTab.active = (activeTab == TAB_GENERAL); addTopButton(generalTab); - GuiMenuTopButton lastTab = generalTab; - if (hasTypeSettings) { + if (hasTypeFields) { GuiMenuTopButton typeTab = new GuiMenuTopButton(91, lastTab, "gui.type"); typeTab.active = (activeTab == TAB_TYPE); addTopButton(typeTab); @@ -183,277 +107,197 @@ public class SubGuiAbilityConfig extends SubGuiInterface implements ITextfieldLi addTopButton(effectsTab); lastTab = effectsTab; - if (hasVisualSettings) { + if (hasVisualFields) { GuiMenuTopButton visualTab = new GuiMenuTopButton(94, lastTab, "ability.tab.visual"); visualTab.active = (activeTab == TAB_VISUAL); addTopButton(visualTab); } - // Close button (X) in top menu bar - use -1000 to avoid any ID conflicts GuiMenuTopButton closeBtn = new GuiMenuTopButton(-1000, guiLeft + xSize - 22, guiTop - 17, "X"); addTopButton(closeBtn); - int contentY = guiTop + 5; + // Scroll window for tab content + int swX = guiLeft + 4; + int swY = guiTop + 5; + int swW = xSize - 8; + int swH = ySize - 10; - // ═══════════════════════════════════════════════════════════════════════ - // TAB CONTENT - // ═══════════════════════════════════════════════════════════════════════ - switch (activeTab) { - case TAB_GENERAL: - initGeneralTab(contentY); - break; - case TAB_TYPE: - initTypeTab(contentY); - break; - case TAB_TARGET: - initTargetTab(contentY); - break; - case TAB_EFFECTS: - initEffectsTab(contentY); - break; - case TAB_VISUAL: - initVisualTab(contentY); - break; - } + GuiScrollWindow sw = new GuiScrollWindow(this, swX, swY, swW, swH, 0); - // ═══════════════════════════════════════════════════════════════════════ - // BOTTOM ROW - Enabled toggle (only on General tab) - // ═══════════════════════════════════════════════════════════════════════ + TabTarget tabTarget = tabTargetForIndex(activeTab); + int y = 5; + int idCounter = DECLARATIVE_ID_START; + int clearCounter = CLEAR_ID_START; + + // General tab: show type label at top if (activeTab == TAB_GENERAL) { - addLabel(new GuiNpcLabel(99, "gui.enabled", guiLeft + 8, guiTop + ySize - 18)); - GuiNpcButton enabledBtn = new GuiNpcButton(2, guiLeft + 55, guiTop + ySize - 24, 40, 20, new String[]{"gui.no", "gui.yes"}, enabled ? 1 : 0); - enabledBtn.setTextColor(enabled ? 0x00FF00 : 0xFF0000); - addButton(enabledBtn); + sw.addLabel(new GuiNpcLabel(1, "gui.type", 5, y + 5)); + sw.addLabel(new GuiNpcLabel(2, ability.getTypeId(), 50, y + 5)); + y += 24; + } + + // Render declarative fields for this tab + List tabFields = getVisibleFieldsForTab(tabTarget); + for (FieldDef def : tabFields) { + int widgetId = idCounter++; + int clearId = clearCounter++; + y = renderField(sw, def, widgetId, clearId, y); + } + + // Target tab: append conditions list + if (activeTab == TAB_TARGET) { + y = renderConditions(sw, y); + } + + sw.maxScrollY = Math.max(y - swH, 0); + addScrollableGui(0, sw); + } + + private TabTarget tabTargetForIndex(int tab) { + switch (tab) { + case TAB_GENERAL: return TabTarget.GENERAL; + case TAB_TYPE: return TabTarget.TYPE; + case TAB_TARGET: return TabTarget.TARGET; + case TAB_EFFECTS: return TabTarget.EFFECTS; + case TAB_VISUAL: return TabTarget.VISUAL; + default: return TabTarget.TYPE; } } - // ═══════════════════════════════════════════════════════════════════════════ - // GENERAL TAB - // ═══════════════════════════════════════════════════════════════════════════ - - private void initGeneralTab(int startY) { - int y = startY; - int col1LabelX = guiLeft + 8; - int col1FieldX = guiLeft + 70; - int col2LabelX = guiLeft + 180; - int col2FieldX = guiLeft + 248; - - // Row 1: Type (read-only) + Name - addLabel(new GuiNpcLabel(1, "gui.type", col1LabelX, y + 5)); - addLabel(new GuiNpcLabel(2, ability.getTypeId(), col1FieldX, y + 5)); - - addLabel(new GuiNpcLabel(3, "gui.name", col2LabelX, y + 5)); - GuiNpcTextField nameField = new GuiNpcTextField(1, this, fontRendererObj, col2FieldX, y, 100, 20, name); - addTextField(nameField); - - y += 24; - - // Row 2: Weight + Lock Movement - addLabel(new GuiNpcLabel(4, "ability.weight", col1LabelX, y + 5)); - GuiNpcTextField weightField = new GuiNpcTextField(3, this, fontRendererObj, col1FieldX, y, 40, 20, String.valueOf(weight)); - weightField.setIntegersOnly(); - weightField.setMinMaxDefault(1, 1000, 10); - addTextField(weightField); - - addLabel(new GuiNpcLabel(5, "ability.lockMove", col2LabelX, y + 5)); - GuiNpcButton lockMoveBtn = new GuiNpcButton(16, col2FieldX, y, 60, 20, LockMovementType.getDisplayKeys(), lockMovement.ordinal()); - 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)); - 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) { - addLabel(new GuiNpcLabel(12, "ability.dazed", col2LabelX, y + 5)); - GuiNpcTextField dazedField = new GuiNpcTextField(13, this, fontRendererObj, col2FieldX, y, 40, 20, String.valueOf(dazedTicks)); - dazedField.setIntegersOnly(); - dazedField.setMinMaxDefault(0, 1000, 80); - addTextField(dazedField); + private List getVisibleFieldsForTab(TabTarget target) { + List result = new ArrayList<>(); + for (FieldDef def : fieldDefs) { + if (def.getTab() == target && def.isVisible()) { + result.add(def); + } } + return result; + } - y += 28; + // ═══════════════════════════════════════════════════════════════════════════ + // FIELD RENDERING + // ═══════════════════════════════════════════════════════════════════════════ - // Separator - Timing section header - addLabel(new GuiNpcLabel(7, "ability.timing", col1LabelX, y)); + @SuppressWarnings({"unchecked", "rawtypes"}) + private int renderField(GuiScrollWindow sw, FieldDef def, int widgetId, int clearId, int y) { + int labelX = 5; + int fieldX = 100; + int fieldW = 60; + + sw.addLabel(new GuiNpcLabel(widgetId, def.getLabel(), labelX, y + 5)); + + switch (def.getType()) { + case FLOAT: { + float fVal = def.getValue() instanceof Number ? ((Number) def.getValue()).floatValue() : 0f; + GuiNpcTextField tf = new GuiNpcTextField(widgetId, this, fontRendererObj, fieldX, y, fieldW, 20, String.format("%.2f", fVal)); + tf.setFloatsOnly(); + if (def.hasRange()) tf.setMinMaxDefaultFloat(def.getMin(), def.getMax(), fVal); + if (def.getTooltip() != null) tf.setHoverText(def.getTooltip()); + sw.addTextField(tf); + textFieldMap.put(widgetId, def); + break; + } + case INT: { + int iVal = def.getValue() instanceof Number ? ((Number) def.getValue()).intValue() : 0; + GuiNpcTextField tf = new GuiNpcTextField(widgetId, this, fontRendererObj, fieldX, y, fieldW, 20, String.valueOf(iVal)); + tf.setIntegersOnly(); + if (def.hasRange()) tf.setMinMaxDefault((int) def.getMin(), (int) def.getMax(), iVal); + if (def.getTooltip() != null) tf.setHoverText(def.getTooltip()); + sw.addTextField(tf); + textFieldMap.put(widgetId, def); + break; + } + case STRING: { + String sVal = def.getValue() != null ? def.getValue().toString() : ""; + GuiNpcTextField tf = new GuiNpcTextField(widgetId, this, fontRendererObj, fieldX, y, fieldW + 40, 20, sVal); + if (def.getTooltip() != null) tf.setHoverText(def.getTooltip()); + sw.addTextField(tf); + textFieldMap.put(widgetId, def); + break; + } + case BOOLEAN: { + boolean bVal = def.getValue() instanceof Boolean ? (Boolean) def.getValue() : false; + GuiNpcButton btn = new GuiNpcButton(widgetId, fieldX, y, 40, 20, new String[]{"gui.no", "gui.yes"}, bVal ? 1 : 0); + if (def.getHoverText() != null) btn.setHoverText(def.getHoverText()); + sw.addButton(btn); + buttonFieldMap.put(widgetId, def); + break; + } + case ENUM: { + Class> enumClass = def.getEnumClass(); + if (enumClass != null) { + Enum[] constants = enumClass.getEnumConstants(); + String[] names = new String[constants.length]; + for (int i = 0; i < constants.length; i++) names[i] = constants[i].toString(); + int selected = def.getValue() instanceof Enum ? ((Enum) def.getValue()).ordinal() : 0; + GuiNpcButton btn = new GuiNpcButton(widgetId, fieldX, y, 80, 20, names, selected); + if (def.getHoverText() != null) btn.setHoverText(def.getHoverText()); + sw.addButton(btn); + buttonFieldMap.put(widgetId, def); + } + break; + } + case STRING_ENUM: { + String[] values = def.getStringEnumValues(); + if (values != null && values.length > 0) { + String curVal = def.getStringEnumValue(); + int selected = 0; + for (int i = 0; i < values.length; i++) { + if (values[i].equals(curVal)) { selected = i; break; } + } + GuiNpcButton btn = new GuiNpcButton(widgetId, fieldX, y, 80, 20, values, selected); + if (def.getHoverText() != null) btn.setHoverText(def.getHoverText()); + sw.addButton(btn); + buttonFieldMap.put(widgetId, def); + } + break; + } + case SUB_GUI: { + String btnText = def.getButtonLabel(); + int btnW = def.hasClearAction() ? 60 : 80; + GuiNpcButton btn = new GuiNpcButton(widgetId, fieldX, y, btnW, 20, btnText); + Integer textColor = def.getButtonTextColor(); + if (textColor != null) btn.setTextColor(textColor); + if (def.getHoverText() != null) btn.setHoverText(def.getHoverText()); + sw.addButton(btn); + buttonFieldMap.put(widgetId, def); + + if (def.hasClearAction()) { + GuiNpcButton clearBtn = new GuiNpcButton(clearId, fieldX + btnW + 5, y, 20, 20, "X"); + sw.addButton(clearBtn); + clearFieldMap.put(clearId, def); + } + break; + } + } + return y + 24; + } + + // ═══════════════════════════════════════════════════════════════════════════ + // CONDITIONS (Target tab special handling) + // ═══════════════════════════════════════════════════════════════════════════ + + private int renderConditions(GuiScrollWindow sw, int y) { + int x = 5; + + sw.addLabel(new GuiNpcLabel(50, "ability.conditions", x, y)); y += 14; - // Check if windup animation is selected (either by name or ID) - boolean hasWindupAnimation = windUpAnimationId >= 0 || (windUpAnimationName != null && !windUpAnimationName.isEmpty()); - - // Row 4: Windup Ticks + Cooldown Ticks - addLabel(new GuiNpcLabel(10, "ability.windup", col1LabelX, y + 5)); - - // Only show windup textbox if sync is off or no animation selected - if (!syncWindupWithAnimation || !hasWindupAnimation) { - GuiNpcTextField windupField = new GuiNpcTextField(11, this, fontRendererObj, col1FieldX, y, 40, 20, String.valueOf(windUpTicks)); - windupField.setIntegersOnly(); - windupField.setMinMaxDefault(0, 1000, 20); - addTextField(windupField); - } else { - // Show calculated value as label when synced - addLabel(new GuiNpcLabel(11, String.valueOf(windUpTicks), col1FieldX + 5, y + 5)); - } - - // Sync toggle button - only show if windup animation is selected - if (hasWindupAnimation) { - String syncLabel = syncWindupWithAnimation ? "ability.syncOn" : "ability.syncOff"; - GuiNpcButton syncBtn = new GuiNpcButton(17, guiLeft + 115, y, 50, 20, syncLabel); - 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(); - cooldownField.setMinMaxDefault(0, 10000, 0); - addTextField(cooldownField); - } - - // ═══════════════════════════════════════════════════════════════════════════ - // TYPE TAB - Override in subclasses for type-specific settings - // ═══════════════════════════════════════════════════════════════════════════ - - /** - * Override this method to render type-specific settings in the Type tab. - * Use the helper methods createFloatField(), createIntField(), etc. - * Button/TextField IDs should start at 100. - * - * @param startY The Y position to start rendering from - */ - protected void initTypeTab(int startY) { - // Default: show message that no type settings are available - addLabel(new GuiNpcLabel(100, "ability.noTypeSettings", guiLeft + 8, startY + 5)); - } - - /** - * Override this method to handle button clicks for type-specific buttons. - * Button IDs 100+ are reserved for type-specific use. - */ - protected void handleTypeButton(int id, GuiNpcButton button) { - // Default: no-op - } - - /** - * Override this method to handle text field changes for type-specific fields. - * Field IDs 100+ are reserved for type-specific use. - */ - protected void handleTypeTextField(int id, GuiNpcTextField field) { - // Default: no-op - } - - // ═══════════════════════════════════════════════════════════════════════════ - // VISUAL TAB - Override in subclasses for visual settings (colors, etc.) - // ═══════════════════════════════════════════════════════════════════════════ - - /** - * Override to return true if this ability has visual settings (colors, glow, etc.). - * When true, a Visual tab will be shown in the GUI. - */ - protected boolean hasVisualSettings() { - return false; - } - - /** - * Override this method to render visual settings in the Visual tab. - * Use button/text field IDs starting at 200 for visual settings. - * - * @param startY The Y position to start rendering from - */ - protected void initVisualTab(int startY) { - // Default: show message that no visual settings are available - addLabel(new GuiNpcLabel(200, "ability.noVisualSettings", guiLeft + 8, startY + 5)); - } - - /** - * Override this method to handle button clicks for visual-specific buttons. - * Button IDs 200+ are reserved for visual-specific use. - */ - protected void handleVisualButton(int id, GuiNpcButton button) { - // Default: no-op - } - - /** - * Override this method to handle text field changes for visual-specific fields. - * Field IDs 200+ are reserved for visual-specific use. - */ - protected void handleVisualTextField(int id, GuiNpcTextField field) { - // Default: no-op - } - - // ═══════════════════════════════════════════════════════════════════════════ - // TARGET TAB - // ═══════════════════════════════════════════════════════════════════════════ - - private void initTargetTab(int startY) { - int y = startY; - int col1LabelX = guiLeft + 8; - int col1FieldX = guiLeft + 70; - int col2LabelX = guiLeft + 180; - int col2FieldX = guiLeft + 248; - - // Row 1: Min Range + Max Range - addLabel(new GuiNpcLabel(20, "ability.minRange", col1LabelX, y + 5)); - GuiNpcTextField minRangeField = new GuiNpcTextField(5, this, fontRendererObj, col1FieldX, y, 40, 20, String.valueOf((int) minRange)); - minRangeField.setIntegersOnly(); - minRangeField.setMinMaxDefault(0, 100, 0); - addTextField(minRangeField); - - addLabel(new GuiNpcLabel(21, "ability.maxRange", col2LabelX, y + 5)); - GuiNpcTextField maxRangeField = new GuiNpcTextField(6, this, fontRendererObj, col2FieldX, y, 40, 20, String.valueOf((int) maxRange)); - maxRangeField.setIntegersOnly(); - maxRangeField.setMinMaxDefault(1, 100, 20); - addTextField(maxRangeField); - - y += 24; - - // Row 2: Targeting Mode (if not locked) - addLabel(new GuiNpcLabel(22, "ability.targeting", col1LabelX, y + 5)); - if (!targetingModeLocked) { - String[] targetingModes = getAvailableTargetingModes(); - int selectedIndex = getTargetingModeIndex(targetingMode); - 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)); - } - - y += 28; - - // ───────────────────────────────────────────────────────────────────── - // CONDITIONS SECTION (up to 3) - // ───────────────────────────────────────────────────────────────────── - addLabel(new GuiNpcLabel(24, "ability.conditions", col1LabelX, y)); - y += 14; - - // Display existing conditions (similar to Marks pattern) for (int i = 0; i < conditions.size() && i < 3; i++) { Condition cond = conditions.get(i); String condName = getConditionDisplayName(cond); - - // Condition type button - addButton(new GuiNpcButton(50 + i * 10, col1LabelX, y, 140, 20, condName)); - - // Edit button - addButton(new GuiNpcButton(51 + i * 10, col1LabelX + 145, y, 40, 20, "gui.edit")); - - // Delete button - addButton(new GuiNpcButton(52 + i * 10, col1LabelX + 190, y, 20, 20, "X")); - + sw.addButton(new GuiNpcButton(50 + i * 10, x, y, 140, 20, condName)); + sw.addButton(new GuiNpcButton(51 + i * 10, x + 145, y, 40, 20, "gui.edit")); + sw.addButton(new GuiNpcButton(52 + i * 10, x + 190, y, 20, 20, "X")); y += 22; } - // Add button (if less than 3 conditions) if (conditions.size() < 3) { - addButton(new GuiNpcButton(80, col1LabelX, y, 50, 20, "gui.add")); + sw.addButton(new GuiNpcButton(80, x, y, 50, 20, "gui.add")); + y += 24; } + + return y; } private String getConditionDisplayName(Condition cond) { @@ -469,310 +313,102 @@ public class SubGuiAbilityConfig extends SubGuiInterface implements ITextfieldLi case "target_hp_below": return StatCollector.translateToLocal("condition.target_hp_below") + " " + (int) (getConditionThreshold(cond) * 100) + "%"; case "hit_count": - Condition.ConditionHitCount hitCount = (Condition.ConditionHitCount) cond; - return StatCollector.translateToLocal("condition.hit_count") + ": " + hitCount.getRequiredHits() + "/" + hitCount.getWithinTicks() + "t"; + Condition.ConditionHitCount hc = (Condition.ConditionHitCount) cond; + return StatCollector.translateToLocal("condition.hit_count") + ": " + hc.getRequiredHits() + "/" + hc.getWithinTicks() + "t"; default: return typeId; } } private float getConditionThreshold(Condition cond) { - // Read threshold from NBT since inner classes don't expose it NBTTagCompound nbt = cond.writeNBT(); return nbt.hasKey("threshold") ? nbt.getFloat("threshold") : 0.5f; } - private String[] getAvailableTargetingModes() { - TargetingMode[] modes = ability.getAllowedTargetingModes(); - if (modes == null) { - modes = TargetingMode.values(); - } - String[] result = new String[modes.length]; - for (int i = 0; i < modes.length; i++) { - result[i] = "ability.target." + modes[i].name().toLowerCase(); - } - return result; - } - - private int getTargetingModeIndex(TargetingMode mode) { - TargetingMode[] modes = ability.getAllowedTargetingModes(); - if (modes == null) { - return mode.ordinal(); - } - for (int i = 0; i < modes.length; i++) { - if (modes[i] == mode) return i; - } - return 0; - } - - // ═══════════════════════════════════════════════════════════════════════════ - // EFFECTS TAB - // ═══════════════════════════════════════════════════════════════════════════ - - private void initEffectsTab(int startY) { - int y = startY; - int col1LabelX = guiLeft + 8; - int col1FieldX = guiLeft + 85; - int col1ClearX = guiLeft + 160; - int col2LabelX = guiLeft + 185; - int col2FieldX = guiLeft + 255; - - // ───────────────────────────────────────────────────────────────────── - // SOUNDS SECTION - // ───────────────────────────────────────────────────────────────────── - addLabel(new GuiNpcLabel(30, "advanced.sounds", col1LabelX, y)); - y += 14; - - // Wind Up Sound - addLabel(new GuiNpcLabel(31, "ability.windUpSound", col1LabelX, y + 5)); - String windUpSoundDisplay = windUpSound != null && !windUpSound.isEmpty() ? truncateString(windUpSound, 10) : StatCollector.translateToLocal("gui.none"); - addButton(new GuiNpcButton(30, col1FieldX, y, 70, 20, windUpSoundDisplay)); - addButton(new GuiNpcButton(35, col1ClearX, y, 20, 20, "X")); - - // Active Sound - addLabel(new GuiNpcLabel(32, "ability.activeSound", col2LabelX, y + 5)); - String activeSoundDisplay = activeSound != null && !activeSound.isEmpty() ? truncateString(activeSound, 10) : StatCollector.translateToLocal("gui.none"); - addButton(new GuiNpcButton(31, col2FieldX, y, 70, 20, activeSoundDisplay)); - addButton(new GuiNpcButton(36, col2FieldX + 75, y, 20, 20, "X")); - - y += 26; - - // ───────────────────────────────────────────────────────────────────── - // ANIMATIONS SECTION - // ───────────────────────────────────────────────────────────────────── - addLabel(new GuiNpcLabel(33, "menu.animations", col1LabelX, y)); - y += 14; - - // Wind Up Animation - addLabel(new GuiNpcLabel(34, "ability.windUpAnim", col1LabelX, y + 5)); - String windUpAnimName = getAnimationName(windUpAnimationId, true); - addButton(new GuiNpcButton(32, col1FieldX, y, 70, 20, windUpAnimName)); - addButton(new GuiNpcButton(37, col1ClearX, y, 20, 20, "X")); - - // Active Animation - addLabel(new GuiNpcLabel(35, "ability.activeAnim", col2LabelX, y + 5)); - String activeAnimName = getAnimationName(activeAnimationId, false); - addButton(new GuiNpcButton(33, col2FieldX, y, 70, 20, activeAnimName)); - addButton(new GuiNpcButton(38, col2FieldX + 75, y, 20, 20, "X")); - - y += 26; - - // ───────────────────────────────────────────────────────────────────── - // TELEGRAPH SECTION (only if supported) - // ───────────────────────────────────────────────────────────────────── - if (supportsTelegraph) { - addLabel(new GuiNpcLabel(40, "ability.telegraph", col1LabelX, y)); - y += 14; - - // Show Telegraph - addLabel(new GuiNpcLabel(41, "ability.showTelegraph", col1LabelX, y + 5)); - 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(); - addLabel(new GuiNpcLabel(42, "ability.telegraphType", guiLeft + 200, y + 5)); - String telegraphLangKey = typeKey.equals("none") ? "gui.none" : "telegraph." + typeKey; - addLabel(new GuiNpcLabel(43, telegraphLangKey, guiLeft + 280, y + 5)); - - y += 24; - - // 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.setTextColor(activeColor & 0xFFFFFF); - addButton(activeColorBtn); - } - } - } - - private String truncateString(String str, int maxLen) { - if (str == null) return ""; - if (str.length() <= maxLen) return str; - int lastSlash = str.lastIndexOf('/'); - if (lastSlash >= 0 && str.length() - lastSlash <= maxLen) { - return "..." + str.substring(lastSlash); - } - return "..." + str.substring(str.length() - maxLen + 3); - } - - private String getAnimationName(int animId, boolean isWindUp) { - String animName = isWindUp ? windUpAnimationName : activeAnimationName; - // Check if we have a built-in animation (by name) - if (animName != null && !animName.isEmpty()) { - return truncateString(animName, 8); - } - // Check if we have a user animation (by ID) - if (animId >= 0) { - return "ID: " + animId; - } - return StatCollector.translateToLocal("gui.none"); - } - // ═══════════════════════════════════════════════════════════════════════════ // BUTTON EVENTS // ═══════════════════════════════════════════════════════════════════════════ @Override + @SuppressWarnings({"unchecked", "rawtypes"}) public void buttonEvent(GuiButton guibutton) { int id = guibutton.id; // Tab switching - if (id == 90) { - activeTab = TAB_GENERAL; - initGui(); - return; - } - if (id == 91 && hasTypeSettings) { - activeTab = TAB_TYPE; - initGui(); - return; - } - if (id == 92) { - activeTab = TAB_TARGET; - initGui(); - return; - } - if (id == 93) { - activeTab = TAB_EFFECTS; - initGui(); - return; - } - if (id == 94 && hasVisualSettings) { - activeTab = TAB_VISUAL; - initGui(); - return; - } + if (id == 90) { activeTab = TAB_GENERAL; initGui(); return; } + if (id == 91) { activeTab = TAB_TYPE; initGui(); return; } + if (id == 92) { activeTab = TAB_TARGET; initGui(); return; } + if (id == 93) { activeTab = TAB_EFFECTS; initGui(); return; } + if (id == 94) { activeTab = TAB_VISUAL; initGui(); return; } + if (id == -1000) { close(); return; } - // Enabled button (bottom left) - if (id == 2) { - enabled = ((GuiNpcButton) guibutton).getValue() == 1; - initGui(); - } - - // General tab buttons - else if (id == 14) { - interruptible = ((GuiNpcButton) guibutton).getValue() == 1; - initGui(); // Refresh to show/hide dazed ticks field - } else if (id == 16) { - lockMovement = LockMovementType.fromOrdinal(((GuiNpcButton) guibutton).getValue()); - } else if (id == 17) { - // Toggle sync on/off - syncWindupWithAnimation = !syncWindupWithAnimation; - if (syncWindupWithAnimation) { - // Calculate windup ticks from animation when turning sync on - calculateWindupFromAnimation(); - } - initGui(); - } - - // Target tab - Targeting mode - else if (id == 4) { - TargetingMode[] modes = ability.getAllowedTargetingModes(); - int idx = ((GuiNpcButton) guibutton).getValue(); - if (modes != null && idx < modes.length) { - targetingMode = modes[idx]; - } else { - targetingMode = TargetingMode.values()[idx]; - } - } - - // Close button (X in top menu) - use -1000 to avoid any ID conflicts - else if (id == -1000) { - close(); - return; - } - - // Target tab - Condition buttons (50-79) - else if (id >= 50 && id < 80) { + // Condition buttons (50-80) + if (id >= 50 && id < 80) { int condIndex = (id - 50) / 10; int action = (id - 50) % 10; - if (action == 0 || action == 1) { - // Click on condition name or Edit button - open edit subgui if (condIndex < conditions.size()) { editingConditionIndex = condIndex; setSubGui(new SubGuiConditionEdit(conditions.get(condIndex))); } } else if (action == 2) { - // Delete button if (condIndex < conditions.size()) { conditions.remove(condIndex); initGui(); } } + return; } - // Add condition button - else if (id == 80) { + if (id == 80) { if (conditions.size() < 3) { editingConditionIndex = conditions.size(); setSubGui(new SubGuiConditionEdit(null)); } + return; } - // Effects tab - Telegraph - else if (id == 20) { - showTelegraph = ((GuiNpcButton) guibutton).getValue() == 1; - initGui(); - } else if (id == 22) { - editingColorId = 22; - setSubGui(new SubGuiColorSelector(windUpColor)); - } else if (id == 24) { - editingColorId = 24; - setSubGui(new SubGuiColorSelector(activeColor)); + // Clear buttons + if (id >= CLEAR_ID_START) { + FieldDef def = clearFieldMap.get(id); + if (def != null && def.hasClearAction()) { + def.getClearAction().run(); + initGui(); + } + return; } - // Effects tab - Sound buttons - else if (id == 30) { - editingSoundId = 30; - setSubGui(new GuiSoundSelection(windUpSound)); - } else if (id == 31) { - editingSoundId = 31; - setSubGui(new GuiSoundSelection(activeSound)); - } - // Sound clear buttons - else if (id == 35) { - windUpSound = ""; - initGui(); - } else if (id == 36) { - activeSound = ""; - initGui(); - } - // Animation buttons - else if (id == 32) { - editingAnimationId = 32; - setSubGui(new GuiAnimationSelection(windUpAnimationId, windUpAnimationName)); - } else if (id == 33) { - editingAnimationId = 33; - setSubGui(new GuiAnimationSelection(activeAnimationId, activeAnimationName)); - } - // Animation clear buttons - else if (id == 37) { - windUpAnimationId = -1; - windUpAnimationName = ""; - initGui(); - } else if (id == 38) { - activeAnimationId = -1; - activeAnimationName = ""; - initGui(); - } + // Declarative field buttons + if (id >= DECLARATIVE_ID_START) { + FieldDef def = buttonFieldMap.get(id); + if (def == null) return; - // Visual-specific buttons (200+) - delegate to subclass - else if (id >= 200) { - handleVisualButton(id, (GuiNpcButton) guibutton); - } - // Type-specific buttons (100-199) - delegate to subclass - else if (id >= 100) { - handleTypeButton(id, (GuiNpcButton) guibutton); + switch (def.getType()) { + case BOOLEAN: + def.setValue(((GuiNpcButton) guibutton).getValue() == 1); + initGui(); + break; + case ENUM: { + int idx = ((GuiNpcButton) guibutton).getValue(); + Class> ec = def.getEnumClass(); + if (ec != null) { + Enum[] constants = ec.getEnumConstants(); + if (idx >= 0 && idx < constants.length) def.setValue(constants[idx]); + } + initGui(); + break; + } + case STRING_ENUM: { + int idx = ((GuiNpcButton) guibutton).getValue(); + String[] values = def.getStringEnumValues(); + if (values != null && idx >= 0 && idx < values.length) def.setStringEnumValue(values[idx]); + initGui(); + break; + } + case SUB_GUI: + activeSubGuiField = def; + if (def.getSubGuiFactory() != null) setSubGui(def.getSubGuiFactory().get()); + break; + } } } @@ -783,94 +419,41 @@ public class SubGuiAbilityConfig extends SubGuiInterface implements ITextfieldLi @Override public void unFocused(GuiNpcTextField textField) { int id = textField.id; + if (id < DECLARATIVE_ID_START) return; - // General tab - if (id == 1) { - name = textField.getText(); - } else if (id == 3) { - weight = textField.getInteger(); - } + FieldDef def = textFieldMap.get(id); + if (def == null) return; - // Target tab - else if (id == 5) { - minRange = textField.getInteger(); - } else if (id == 6) { - maxRange = textField.getInteger(); - } - - // Timing (General tab) - else if (id == 10) { - cooldownTicks = textField.getInteger(); - } else if (id == 11) { - windUpTicks = textField.getInteger(); - } else if (id == 13) { - dazedTicks = textField.getInteger(); - } - - // Visual-specific fields (200+) - delegate to subclass - else if (id >= 200) { - handleVisualTextField(id, textField); - } - // Type-specific fields (100-199) - delegate to subclass - else if (id >= 100) { - handleTypeTextField(id, textField); + switch (def.getType()) { + case FLOAT: + try { def.setValue(Float.parseFloat(textField.getText())); } catch (NumberFormatException ignored) {} + break; + case INT: + try { def.setValue(Integer.parseInt(textField.getText())); } catch (NumberFormatException ignored) {} + break; + case STRING: + def.setValue(textField.getText()); + break; } } // ═══════════════════════════════════════════════════════════════════════════ - // SUBGUI CLOSED HANDLER + // SUB GUI CLOSED // ═══════════════════════════════════════════════════════════════════════════ @Override public void subGuiClosed(SubGuiInterface subgui) { - if (subgui instanceof SubGuiColorSelector) { - SubGuiColorSelector colorSelector = (SubGuiColorSelector) subgui; - int rgb = colorSelector.color & 0x00FFFFFF; - if (editingColorId == 22) { - windUpColor = 0x80000000 | rgb; - } else if (editingColorId == 24) { - activeColor = 0xC0000000 | rgb; + if (activeSubGuiField != null) { + FieldDef def = activeSubGuiField; + activeSubGuiField = null; + if (def.getSubGuiResultHandler() != null) { + def.getSubGuiResultHandler().accept(subgui); } - editingColorId = 0; initGui(); - } else if (subgui instanceof GuiSoundSelection) { - GuiSoundSelection soundSelector = (GuiSoundSelection) subgui; - if (soundSelector.selectedResource != null) { - String sound = soundSelector.selectedResource.toString(); - if (editingSoundId == 30) { - windUpSound = sound; - } else if (editingSoundId == 31) { - activeSound = sound; - } - } - editingSoundId = 0; - initGui(); - } else if (subgui instanceof GuiAnimationSelection) { - GuiAnimationSelection animSelector = (GuiAnimationSelection) subgui; - if (editingAnimationId == 32) { - if (animSelector.isBuiltInSelected()) { - // Built-in animation selected - use name, clear ID - windUpAnimationName = animSelector.selectedBuiltInName; - windUpAnimationId = -1; - } else { - // User animation selected - use ID, clear name - windUpAnimationId = animSelector.selectedAnimationId; - windUpAnimationName = ""; - } - } else if (editingAnimationId == 33) { - if (animSelector.isBuiltInSelected()) { - // Built-in animation selected - use name, clear ID - activeAnimationName = animSelector.selectedBuiltInName; - activeAnimationId = -1; - } else { - // User animation selected - use ID, clear name - activeAnimationId = animSelector.selectedAnimationId; - activeAnimationName = ""; - } - } - editingAnimationId = 0; - initGui(); - } else if (subgui instanceof SubGuiConditionEdit) { + return; + } + + if (subgui instanceof SubGuiConditionEdit) { SubGuiConditionEdit condEdit = (SubGuiConditionEdit) subgui; Condition result = condEdit.getResult(); if (result != null && editingConditionIndex >= 0) { @@ -886,178 +469,36 @@ public class SubGuiAbilityConfig extends SubGuiInterface implements ITextfieldLi } // ═══════════════════════════════════════════════════════════════════════════ - // CLOSE - Save before closing + // CLOSE / APPLY // ═══════════════════════════════════════════════════════════════════════════ @Override public void close() { - // Apply all cached values to the ability before closing applyToAbility(); - - // Notify callback that ability was saved callback.onAbilitySaved(ability); - - // Close the GUI super.close(); } - // ═══════════════════════════════════════════════════════════════════════════ - // APPLY TO ABILITY - // ═══════════════════════════════════════════════════════════════════════════ - protected void applyToAbility() { - // General - ability.setName(name); - ability.setEnabled(enabled); - ability.setWeight(weight); - ability.setLockMovement(lockMovement); - ability.setInterruptible(interruptible); - - // If sync is enabled and we have a windup animation, recalculate before saving - boolean hasWindupAnimation = windUpAnimationId >= 0 || (windUpAnimationName != null && !windUpAnimationName.isEmpty()); - if (syncWindupWithAnimation && hasWindupAnimation) { - calculateWindupFromAnimation(); - } - - // Timing - ability.setCooldownTicks(cooldownTicks); - ability.setWindUpTicks(windUpTicks); - ability.setDazedTicks(dazedTicks); - - // Target - ability.setMinRange(minRange); - ability.setMaxRange(maxRange); - ability.setTargetingMode(targetingMode); - - // Conditions + // Conditions are the only cached values - write them back ability.getConditions().clear(); - for (Condition c : conditions) { - ability.addCondition(c); - } - - // Effects - ability.setWindUpSound(windUpSound); - ability.setActiveSound(activeSound); - ability.setWindUpAnimationId(windUpAnimationId); - ability.setActiveAnimationId(activeAnimationId); - ability.setWindUpAnimationName(windUpAnimationName != null ? windUpAnimationName : ""); - ability.setActiveAnimationName(activeAnimationName != null ? activeAnimationName : ""); - - // Telegraph - ability.setShowTelegraph(showTelegraph); - ability.setWindUpColor(windUpColor); - ability.setActiveColor(activeColor); - - // Type-specific values are applied directly in handleTypeTextField and handleTypeButton + for (Condition c : conditions) ability.addCondition(c); + // All other fields write directly to ability via FieldDef lambdas } - /** - * Called when an ability is loaded from saved presets. - */ public void loadAbility(Ability loadedAbility) { if (loadedAbility == null) return; - - // Copy all values from loaded ability to current ability NBTTagCompound nbt = loadedAbility.writeNBT(); - // Keep the current typeId since we can't change types mid-edit nbt.setString("typeId", ability.getTypeId()); ability.readNBT(nbt); - // Update cached values - this.name = ability.getName() != null ? ability.getName() : ""; - this.enabled = ability.isEnabled(); - this.weight = ability.getWeight(); - this.lockMovement = ability.getLockMovement(); - this.interruptible = ability.isInterruptible(); - - this.cooldownTicks = ability.getCooldownTicks(); - this.windUpTicks = ability.getWindUpTicks(); - this.dazedTicks = ability.getDazedTicks(); - - this.minRange = ability.getMinRange(); - this.maxRange = ability.getMaxRange(); - this.targetingMode = ability.getTargetingMode(); this.conditions = new ArrayList<>(ability.getConditions()); - - this.showTelegraph = ability.isShowTelegraph(); - this.windUpColor = ability.getWindUpColor(); - this.activeColor = ability.getActiveColor(); - + this.fieldDefs = ability.getAllFieldDefinitions(); + this.hasTypeFields = hasFieldsForTab(TabTarget.TYPE); + this.hasVisualFields = hasFieldsForTab(TabTarget.VISUAL); initGui(); } - // ═══════════════════════════════════════════════════════════════════════════ - // SYNC ANIMATION - // ═══════════════════════════════════════════════════════════════════════════ - - /** - * Calculates windup ticks from the selected windup animation's total duration. - */ - private void calculateWindupFromAnimation() { - if (AnimationController.Instance == null) { - return; - } - - Animation animation = null; - // Check for built-in animation (by name) first - if (windUpAnimationName != null && !windUpAnimationName.isEmpty()) { - animation = (Animation) AnimationController.Instance.get(windUpAnimationName); - } - // Fall back to user animation (by ID) - else if (windUpAnimationId >= 0) { - 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 - // ═══════════════════════════════════════════════════════════════════════════ - - /** - * Creates a float text field for type-specific settings. - */ - protected GuiNpcTextField createFloatField(int id, int x, int y, int width, float value) { - GuiNpcTextField field = new GuiNpcTextField(id, this, fontRendererObj, x, y, width, 20, String.format("%.1f", value)); - return field; - } - - /** - * Creates an integer text field for type-specific settings. - */ - protected GuiNpcTextField createIntField(int id, int x, int y, int width, int value) { - GuiNpcTextField field = new GuiNpcTextField(id, this, fontRendererObj, x, y, width, 20, String.valueOf(value)); - field.setIntegersOnly(); - return field; - } - - /** - * Parses a float from a text field with a fallback default value. - */ - protected float parseFloat(GuiNpcTextField field, float defaultValue) { - try { - return Float.parseFloat(field.getText()); - } catch (NumberFormatException e) { - return defaultValue; - } - } - - /** - * Gets the ability being edited. - */ protected Ability getAbility() { return ability; } 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 deleted file mode 100644 index ea35797c4..000000000 --- a/src/main/java/noppes/npcs/client/gui/advanced/ability/SubGuiAbilityCharge.java +++ /dev/null @@ -1,92 +0,0 @@ -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. - */ -public class SubGuiAbilityCharge extends SubGuiAbilityConfig { - - private final AbilityCharge charge; - - public SubGuiAbilityCharge(AbilityCharge ability, IAbilityConfigCallback callback) { - super(ability, callback); - this.charge = ability; - } - - @Override - protected void initTypeTab(int startY) { - int y = startY; - int labelX = guiLeft + 8; - int fieldX = guiLeft + 85; - int col2LabelX = guiLeft + 145; - int col2FieldX = guiLeft + 205; - - // Row 1: Damage + Speed - addLabel(new GuiNpcLabel(100, "enchantment.damage", labelX, y + 5)); - addTextField(createFloatField(100, fieldX, y, 50, charge.getDamage())); - - addLabel(new GuiNpcLabel(101, "stats.speed", col2LabelX, y + 5)); - addTextField(createFloatField(101, col2FieldX, y, 50, charge.getChargeSpeed())); - - y += 24; - - // Row 2: Knockback - addLabel(new GuiNpcLabel(102, "ability.knockback", labelX, y + 5)); - addTextField(createFloatField(102, fieldX, y, 50, charge.getKnockback())); - - y += 24; - - // 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 - protected void handleTypeTextField(int id, GuiNpcTextField field) { - switch (id) { - case 100: - charge.setDamage(parseFloat(field, charge.getDamage())); - break; - case 101: - charge.setChargeSpeed(parseFloat(field, charge.getChargeSpeed())); - break; - case 102: - charge.setKnockback(parseFloat(field, charge.getKnockback())); - break; - case 104: - charge.setHitWidth(parseFloat(field, charge.getHitWidth())); - break; - } - } -} diff --git a/src/main/java/noppes/npcs/client/gui/advanced/ability/SubGuiAbilityCutter.java b/src/main/java/noppes/npcs/client/gui/advanced/ability/SubGuiAbilityCutter.java deleted file mode 100644 index a1539536d..000000000 --- a/src/main/java/noppes/npcs/client/gui/advanced/ability/SubGuiAbilityCutter.java +++ /dev/null @@ -1,141 +0,0 @@ -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. - */ -public class SubGuiAbilityCutter extends SubGuiAbilityConfig { - - private final AbilityCutter cutter; - - public SubGuiAbilityCutter(AbilityCutter ability, IAbilityConfigCallback callback) { - super(ability, callback); - this.cutter = ability; - } - - @Override - protected void initTypeTab(int startY) { - int y = startY; - int labelX = guiLeft + 8; - int fieldX = guiLeft + 85; - int col2LabelX = guiLeft + 145; - int col2FieldX = guiLeft + 205; - - // Row 1: Damage + Range - addLabel(new GuiNpcLabel(100, "enchantment.damage", labelX, y + 5)); - addTextField(createFloatField(100, fieldX, y, 50, cutter.getDamage())); - - addLabel(new GuiNpcLabel(101, "gui.range", col2LabelX, y + 5)); - addTextField(createFloatField(101, col2FieldX, y, 50, cutter.getRange())); - - y += 24; - - // Row 2: Arc Angle + Inner Radius - addLabel(new GuiNpcLabel(102, "ability.arcAngle", labelX, y + 5)); - addTextField(createFloatField(102, fieldX, y, 50, cutter.getArcAngle())); - - addLabel(new GuiNpcLabel(103, "ability.innerRadius", col2LabelX, y + 5)); - addTextField(createFloatField(103, col2FieldX, y, 50, cutter.getInnerRadius())); - - y += 24; - - // Row 3: Knockback + Sweep Speed - addLabel(new GuiNpcLabel(104, "ability.knockback", labelX, y + 5)); - addTextField(createFloatField(104, fieldX, y, 50, cutter.getKnockback())); - - addLabel(new GuiNpcLabel(105, "ability.sweepSpeed", col2LabelX, y + 5)); - addTextField(createFloatField(105, col2FieldX, y, 50, cutter.getSweepSpeed())); - - y += 24; - - // Row 4: Sweep Mode + Piercing - addLabel(new GuiNpcLabel(106, "ability.sweepMode", labelX, y + 5)); - String[] sweepModes = {"Swipe", "Spin"}; - GuiNpcButton sweepModeBtn = new GuiNpcButton(106, fieldX, y, 70, 20, sweepModes, cutter.getSweepModeEnum().ordinal()); - sweepModeBtn.setHoverText("ability.hover.sweepMode"); - addButton(sweepModeBtn); - - addLabel(new GuiNpcLabel(107, "ability.piercing", col2LabelX, y + 5)); - 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; - - // Row 5: Spin Duration (only for SPIN mode) + Effects button - if (cutter.getSweepModeEnum() == AbilityCutter.SweepMode.SPIN) { - addLabel(new GuiNpcLabel(108, "ability.duration", labelX, y + 5)); - GuiNpcTextField durationField = createIntField(108, fieldX, y, 50, cutter.getSpinDurationTicks()); - durationField.setMinMaxDefault(1, 1000, 60); - addTextField(durationField); - } - - addButton(new GuiNpcButton(150, col2LabelX, y, 80, 20, "ability.effects")); - } - - @Override - protected void handleTypeButton(int id, GuiNpcButton button) { - int value = button.getValue(); - switch (id) { - case 106: - cutter.setSweepModeEnum(AbilityCutter.SweepMode.values()[value]); - initGui(); // Refresh to show/hide duration field - break; - 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); - } - } - } - - @Override - protected void handleTypeTextField(int id, GuiNpcTextField field) { - switch (id) { - case 100: - cutter.setDamage(parseFloat(field, cutter.getDamage())); - break; - case 101: - cutter.setRange(parseFloat(field, cutter.getRange())); - break; - case 102: - cutter.setArcAngle(parseFloat(field, cutter.getArcAngle())); - break; - case 103: - cutter.setInnerRadius(parseFloat(field, cutter.getInnerRadius())); - break; - case 104: - cutter.setKnockback(parseFloat(field, cutter.getKnockback())); - break; - case 105: - cutter.setSweepSpeed(parseFloat(field, cutter.getSweepSpeed())); - break; - case 108: - cutter.setSpinDurationTicks(field.getInteger()); - break; - } - } -} 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 deleted file mode 100644 index 9d7bd63b6..000000000 --- a/src/main/java/noppes/npcs/client/gui/advanced/ability/SubGuiAbilityDash.java +++ /dev/null @@ -1,65 +0,0 @@ -package noppes.npcs.client.gui.advanced.ability; - -import kamkeel.npcs.controllers.data.ability.type.AbilityDash; -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; - -/** - * GUI for configuring Dash ability type-specific settings. - */ -public class SubGuiAbilityDash extends SubGuiAbilityConfig { - - private final AbilityDash dash; - - public SubGuiAbilityDash(AbilityDash ability, IAbilityConfigCallback callback) { - super(ability, callback); - this.dash = ability; - } - - @Override - protected void initTypeTab(int startY) { - int y = startY; - int labelX = guiLeft + 8; - int fieldX = guiLeft + 85; - int col2LabelX = guiLeft + 145; - int col2FieldX = guiLeft + 205; - - // Row 1: Dash Mode - addLabel(new GuiNpcLabel(100, "ability.mode", labelX, y + 5)); - String[] dashModes = {"Aggressive", "Defensive"}; - GuiNpcButton modeBtn = new GuiNpcButton(100, fieldX, y, 80, 20, dashModes, dash.getDashModeEnum().ordinal()); - modeBtn.setHoverText("ability.hover.dashMode"); - addButton(modeBtn); - - y += 24; - - // Row 2: Dash Distance + Dash Speed - addLabel(new GuiNpcLabel(101, "ability.dashDist", labelX, y + 5)); - addTextField(createFloatField(101, fieldX, y, 50, dash.getDashDistance())); - - addLabel(new GuiNpcLabel(102, "ability.dashSpeed", col2LabelX, y + 5)); - addTextField(createFloatField(102, col2FieldX, y, 50, dash.getDashSpeed())); - } - - @Override - protected void handleTypeButton(int id, GuiNpcButton button) { - if (id == 100) { - dash.setDashModeEnum(AbilityDash.DashMode.values()[button.getValue()]); - } - } - - @Override - protected void handleTypeTextField(int id, GuiNpcTextField field) { - switch (id) { - case 101: - dash.setDashDistance(parseFloat(field, dash.getDashDistance())); - break; - case 102: - dash.setDashSpeed(parseFloat(field, dash.getDashSpeed())); - 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 deleted file mode 100644 index 5faf662b0..000000000 --- a/src/main/java/noppes/npcs/client/gui/advanced/ability/SubGuiAbilityDisc.java +++ /dev/null @@ -1,323 +0,0 @@ -package noppes.npcs.client.gui.advanced.ability; - -import kamkeel.npcs.controllers.data.ability.AbilityEffect; -import kamkeel.npcs.controllers.data.ability.AnchorPoint; -import kamkeel.npcs.controllers.data.ability.type.AbilityDisc; -import noppes.npcs.client.gui.SubGuiColorSelector; -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 Disc ability type-specific settings. - */ -public class SubGuiAbilityDisc extends SubGuiAbilityConfig { - - private final AbilityDisc disc; - private int editingVisualColorId = 0; - - public SubGuiAbilityDisc(AbilityDisc ability, IAbilityConfigCallback callback) { - super(ability, callback); - this.disc = ability; - } - - @Override - protected boolean hasVisualSettings() { - return true; - } - - @Override - protected void initTypeTab(int startY) { - int y = startY; - int labelX = guiLeft + 8; - int fieldX = guiLeft + 85; - int col2LabelX = guiLeft + 145; - int col2FieldX = guiLeft + 205; - - // Row 1: Damage + Speed - addLabel(new GuiNpcLabel(100, "enchantment.damage", labelX, y + 5)); - addTextField(createFloatField(100, fieldX, y, 50, disc.getDamage())); - - addLabel(new GuiNpcLabel(101, "stats.speed", col2LabelX, y + 5)); - addTextField(createFloatField(101, col2FieldX, y, 50, disc.getSpeed())); - - y += 24; - - // Row 2: Disc Radius + Disc Thickness - addLabel(new GuiNpcLabel(102, "ability.discRadius", labelX, y + 5)); - addTextField(createFloatField(102, fieldX, y, 50, disc.getDiscRadius())); - - addLabel(new GuiNpcLabel(103, "ability.discThickness", col2LabelX, y + 5)); - addTextField(createFloatField(103, col2FieldX, y, 50, disc.getDiscThickness())); - - y += 24; - - // Row 3: Homing + Homing Strength (only show strength if homing) - addLabel(new GuiNpcLabel(104, "ability.homing", labelX, y + 5)); - 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); - - 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 (only show delay if boomerang) - addLabel(new GuiNpcLabel(106, "ability.boomerang", labelX, y + 5)); - 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); - - 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 (only show radius if explosive) - addLabel(new GuiNpcLabel(108, "ability.explosive", labelX, y + 5)); - 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); - - if (disc.isExplosive()) { - addLabel(new GuiNpcLabel(109, "ability.explosionRad", col2LabelX, y + 5)); - addTextField(createFloatField(109, col2FieldX, y, 50, disc.getExplosionRadius())); - } - - y += 24; - - // Row 6: Knockback + Max Distance - addLabel(new GuiNpcLabel(110, "ability.knockback", labelX, y + 5)); - addTextField(createFloatField(110, fieldX, y, 50, disc.getKnockback())); - - addLabel(new GuiNpcLabel(111, "ability.maxDist", col2LabelX, y + 5)); - addTextField(createFloatField(111, col2FieldX, y, 50, disc.getMaxDistance())); - - y += 24; - - // Row 7: Max Lifetime + Effects button - addLabel(new GuiNpcLabel(112, "ability.lifetime", labelX, y + 5)); - addTextField(createIntField(112, fieldX, y, 50, disc.getMaxLifetime())); - - addButton(new GuiNpcButton(150, col2LabelX, y, 80, 20, "ability.effects")); - } - - @Override - protected void initVisualTab(int startY) { - int y = startY; - int labelX = guiLeft + 8; - int fieldX = guiLeft + 85; - int col2LabelX = guiLeft + 180; - int col2FieldX = guiLeft + 260; - - // Row 1: Anchor Point - addLabel(new GuiNpcLabel(210, "ability.anchorPoint", labelX, y + 5)); - GuiNpcButton anchorBtn = new GuiNpcButton(210, fieldX, y, 80, 20, AnchorPoint.getDisplayNames(), disc.getAnchorPointEnum().getId()); - anchorBtn.setHoverText("ability.hover.anchorPoint"); - addButton(anchorBtn); - - y += 24; - - // Row 2: Inner Color + Outer Color - addLabel(new GuiNpcLabel(200, "ability.innerColor", labelX, y + 5)); - String innerHex = String.format("%06X", disc.getInnerColor() & 0xFFFFFF); - GuiNpcButton innerColorBtn = new GuiNpcButton(200, fieldX, y, 55, 20, innerHex); - innerColorBtn.setTextColor(disc.getInnerColor() & 0xFFFFFF); - addButton(innerColorBtn); - - addLabel(new GuiNpcLabel(201, "ability.outerColor", col2LabelX, y + 5)); - String outerHex = String.format("%06X", disc.getOuterColor() & 0xFFFFFF); - GuiNpcButton outerColorBtn = new GuiNpcButton(201, col2FieldX, y, 55, 20, outerHex); - outerColorBtn.setTextColor(disc.getOuterColor() & 0xFFFFFF); - outerColorBtn.setEnabled(disc.isOuterColorEnabled()); - addButton(outerColorBtn); - - y += 24; - - // Row 2: Outer Color Enabled + Outer Color Width - addLabel(new GuiNpcLabel(202, "ability.outerEnabled", labelX, y + 5)); - addButton(new GuiNpcButton(202, fieldX, y, 50, 20, new String[]{"gui.no", "gui.yes"}, disc.isOuterColorEnabled() ? 1 : 0)); - - addLabel(new GuiNpcLabel(203, "ability.outerWidth", col2LabelX, y + 5)); - GuiNpcTextField widthField = createFloatField(203, col2FieldX, y, 55, disc.getOuterColorWidth()); - widthField.setEnabled(disc.isOuterColorEnabled()); - addTextField(widthField); - - y += 24; - - // Row 3: Outer Color Alpha - addLabel(new GuiNpcLabel(204, "ability.outerAlpha", labelX, y + 5)); - GuiNpcTextField alphaField = createFloatField(204, fieldX, y, 55, disc.getOuterColorAlpha()); - alphaField.setEnabled(disc.isOuterColorEnabled()); - alphaField.setMinMaxDefaultFloat(0, 1, 0.5f); - addTextField(alphaField); - - y += 24; - - // Row 4: Rotation Speed - addLabel(new GuiNpcLabel(205, "ability.rotationSpeed", labelX, y + 5)); - addTextField(createFloatField(205, fieldX, y, 50, disc.getRotationSpeed())); - - y += 24; - - // Row 5: Lightning Effect Enabled - addLabel(new GuiNpcLabel(206, "ability.lightning", labelX, y + 5)); - GuiNpcButton lightningBtn = new GuiNpcButton(206, 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()) { - y += 24; - - // Row 6: Density + Radius - addLabel(new GuiNpcLabel(207, "ability.lightningDensity", labelX, y + 5)); - GuiNpcTextField densityField = new GuiNpcTextField(207, this, fontRendererObj, fieldX, y, 55, 18, String.valueOf(disc.getLightningDensity())); - densityField.setMinMaxDefaultFloat(0.01f, 5.0f, 0.15f); - addTextField(densityField); - - addLabel(new GuiNpcLabel(208, "ability.lightningRadius", col2LabelX, y + 5)); - GuiNpcTextField radiusField = new GuiNpcTextField(208, this, fontRendererObj, col2FieldX, y, 55, 18, String.valueOf(disc.getLightningRadius())); - radiusField.setMinMaxDefaultFloat(0.1f, 10.0f, 0.5f); - addTextField(radiusField); - } - } - - @Override - protected void handleTypeButton(int id, GuiNpcButton button) { - int value = button.getValue(); - 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())); - break; - } - } - - @Override - protected void handleVisualButton(int id, GuiNpcButton button) { - int value = button.getValue(); - switch (id) { - case 200: - editingVisualColorId = 200; - setSubGui(new SubGuiColorSelector(disc.getInnerColor())); - break; - case 201: - editingVisualColorId = 201; - setSubGui(new SubGuiColorSelector(disc.getOuterColor())); - break; - case 202: - disc.setOuterColorEnabled(value == 1); - initGui(); - break; - case 206: - disc.setLightningEffect(value == 1); - initGui(); - break; - case 210: - disc.setAnchorPointEnum(AnchorPoint.fromId(value)); - break; - } - } - - @Override - public void subGuiClosed(SubGuiInterface subgui) { - if (subgui instanceof SubGuiColorSelector && editingVisualColorId != 0) { - SubGuiColorSelector colorSelector = (SubGuiColorSelector) subgui; - int rgb = colorSelector.color & 0x00FFFFFF; - if (editingVisualColorId == 200) { - disc.setInnerColor(rgb); - } else if (editingVisualColorId == 201) { - disc.setOuterColor(rgb); - } - 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); - } - } - - @Override - protected void handleTypeTextField(int id, GuiNpcTextField field) { - switch (id) { - case 100: - disc.setDamage(parseFloat(field, disc.getDamage())); - break; - case 101: - disc.setSpeed(parseFloat(field, disc.getSpeed())); - break; - case 102: - disc.setDiscRadius(parseFloat(field, disc.getDiscRadius())); - break; - case 103: - disc.setDiscThickness(parseFloat(field, disc.getDiscThickness())); - break; - case 105: - disc.setHomingStrength(parseFloat(field, disc.getHomingStrength())); - break; - case 107: - disc.setBoomerangDelay(field.getInteger()); - break; - case 109: - disc.setExplosionRadius(parseFloat(field, disc.getExplosionRadius())); - break; - case 110: - disc.setKnockback(parseFloat(field, disc.getKnockback())); - break; - case 111: - disc.setMaxDistance(parseFloat(field, disc.getMaxDistance())); - break; - case 112: - disc.setMaxLifetime(field.getInteger()); - break; - } - } - - @Override - protected void handleVisualTextField(int id, GuiNpcTextField field) { - switch (id) { - case 203: - disc.setOuterColorWidth(parseFloat(field, disc.getOuterColorWidth())); - break; - case 204: - disc.setOuterColorAlpha(parseFloat(field, disc.getOuterColorAlpha())); - break; - case 205: - disc.setRotationSpeed(parseFloat(field, disc.getRotationSpeed())); - break; - case 207: - disc.setLightningDensity(parseFloat(field, disc.getLightningDensity())); - break; - case 208: - disc.setLightningRadius(parseFloat(field, disc.getLightningRadius())); - break; - } - } -} 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 deleted file mode 100644 index 49ab42e5d..000000000 --- a/src/main/java/noppes/npcs/client/gui/advanced/ability/SubGuiAbilityEnergyBeam.java +++ /dev/null @@ -1,312 +0,0 @@ -package noppes.npcs.client.gui.advanced.ability; - -import kamkeel.npcs.controllers.data.ability.AbilityEffect; -import kamkeel.npcs.controllers.data.ability.AnchorPoint; -import kamkeel.npcs.controllers.data.ability.type.AbilityEnergyBeam; -import noppes.npcs.client.gui.SubGuiColorSelector; -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 Energy Beam ability type-specific settings. - * Energy Beam is a homing head with trailing path (DBZ-style). - */ -public class SubGuiAbilityEnergyBeam extends SubGuiAbilityConfig { - - private final AbilityEnergyBeam beam; - private int editingVisualColorId = 0; - - public SubGuiAbilityEnergyBeam(AbilityEnergyBeam ability, IAbilityConfigCallback callback) { - super(ability, callback); - this.beam = ability; - } - - @Override - protected boolean hasVisualSettings() { - return true; - } - - @Override - protected void initTypeTab(int startY) { - int y = startY; - int labelX = guiLeft + 8; - int fieldX = guiLeft + 85; - int col2LabelX = guiLeft + 145; - int col2FieldX = guiLeft + 205; - - // Row 1: Damage + Speed - addLabel(new GuiNpcLabel(100, "enchantment.damage", labelX, y + 5)); - addTextField(createFloatField(100, fieldX, y, 50, beam.getDamage())); - - addLabel(new GuiNpcLabel(101, "stats.speed", col2LabelX, y + 5)); - addTextField(createFloatField(101, col2FieldX, y, 50, beam.getSpeed())); - - y += 24; - - // Row 2: Beam Width + Head Size - addLabel(new GuiNpcLabel(102, "ability.beamWidth", labelX, y + 5)); - addTextField(createFloatField(102, fieldX, y, 50, beam.getBeamWidth())); - - addLabel(new GuiNpcLabel(103, "ability.headSize", col2LabelX, y + 5)); - addTextField(createFloatField(103, col2FieldX, y, 50, beam.getHeadSize())); - - y += 24; - - // Row 3: Homing + Homing Strength (only show strength if homing) - addLabel(new GuiNpcLabel(104, "ability.homing", labelX, y + 5)); - 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); - - if (beam.isHoming()) { - addLabel(new GuiNpcLabel(105, "ability.homingStr", col2LabelX, y + 5)); - addTextField(createFloatField(105, col2FieldX, y, 50, beam.getHomingStrength())); - } - - y += 24; - - // 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", beam.isHoming() ? col2LabelX : labelX, y + 5)); - addTextField(createFloatField(107, beam.isHoming() ? col2FieldX : fieldX, y, 50, beam.getMaxDistance())); - - y += 24; - - // Row 5: Explosive + Explosion Radius (only show radius if explosive) - addLabel(new GuiNpcLabel(108, "ability.explosive", labelX, y + 5)); - 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); - - if (beam.isExplosive()) { - addLabel(new GuiNpcLabel(109, "ability.explosionRad", col2LabelX, y + 5)); - addTextField(createFloatField(109, col2FieldX, y, 50, beam.getExplosionRadius())); - } - - y += 24; - - // Row 6: Knockback + Max Lifetime - addLabel(new GuiNpcLabel(110, "ability.knockback", labelX, y + 5)); - addTextField(createFloatField(110, fieldX, y, 50, beam.getKnockback())); - - 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 - protected void initVisualTab(int startY) { - int y = startY; - int labelX = guiLeft + 8; - int fieldX = guiLeft + 85; - int col2LabelX = guiLeft + 180; - int col2FieldX = guiLeft + 260; - - // Row 1: Anchor Point - addLabel(new GuiNpcLabel(210, "ability.anchorPoint", labelX, y + 5)); - GuiNpcButton anchorBtn = new GuiNpcButton(210, fieldX, y, 80, 20, AnchorPoint.getDisplayNames(), beam.getAnchorPointEnum().getId()); - anchorBtn.setHoverText("ability.hover.anchorPoint"); - addButton(anchorBtn); - - y += 24; - - // Row 2: Inner Color + Outer Color - addLabel(new GuiNpcLabel(200, "ability.innerColor", labelX, y + 5)); - String innerHex = String.format("%06X", beam.getInnerColor() & 0xFFFFFF); - GuiNpcButton innerColorBtn = new GuiNpcButton(200, fieldX, y, 55, 20, innerHex); - innerColorBtn.setTextColor(beam.getInnerColor() & 0xFFFFFF); - addButton(innerColorBtn); - - addLabel(new GuiNpcLabel(201, "ability.outerColor", col2LabelX, y + 5)); - String outerHex = String.format("%06X", beam.getOuterColor() & 0xFFFFFF); - GuiNpcButton outerColorBtn = new GuiNpcButton(201, col2FieldX, y, 55, 20, outerHex); - outerColorBtn.setTextColor(beam.getOuterColor() & 0xFFFFFF); - outerColorBtn.setEnabled(beam.isOuterColorEnabled()); - addButton(outerColorBtn); - - y += 24; - - // Row 2: Outer Color Enabled + Outer Color Width - addLabel(new GuiNpcLabel(202, "ability.outerEnabled", labelX, y + 5)); - addButton(new GuiNpcButton(202, fieldX, y, 50, 20, new String[]{"gui.no", "gui.yes"}, beam.isOuterColorEnabled() ? 1 : 0)); - - addLabel(new GuiNpcLabel(203, "ability.outerWidth", col2LabelX, y + 5)); - GuiNpcTextField widthField = createFloatField(203, col2FieldX, y, 55, beam.getOuterColorWidth()); - widthField.setEnabled(beam.isOuterColorEnabled()); - addTextField(widthField); - - y += 24; - - // Row 3: Rotation Speed - addLabel(new GuiNpcLabel(204, "ability.outerAlpha", labelX, y + 5)); - GuiNpcTextField alphaField = createFloatField(204, fieldX, y, 55, beam.getOuterColorAlpha()); - alphaField.setEnabled(beam.isOuterColorEnabled()); - alphaField.setMinMaxDefaultFloat(0, 1, 0.5f); - addTextField(alphaField); - - addLabel(new GuiNpcLabel(205, "ability.rotationSpeed", col2LabelX, y + 5)); - addTextField(createFloatField(205, col2FieldX, y, 50, beam.getRotationSpeed())); - - y += 24; - - // Row 4: Lightning Effect Enabled (only affects head) - addLabel(new GuiNpcLabel(206, "ability.lightning", labelX, y + 5)); - GuiNpcButton lightningBtn = new GuiNpcButton(206, 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()) { - y += 24; - - // Row 5: Density + Radius - addLabel(new GuiNpcLabel(207, "ability.lightningDensity", labelX, y + 5)); - GuiNpcTextField densityField = new GuiNpcTextField(207, this, fontRendererObj, fieldX, y, 55, 18, String.valueOf(beam.getLightningDensity())); - densityField.setMinMaxDefaultFloat(0.01f, 5.0f, 0.15f); - addTextField(densityField); - - addLabel(new GuiNpcLabel(208, "ability.lightningRadius", col2LabelX, y + 5)); - GuiNpcTextField radiusField = new GuiNpcTextField(208, this, fontRendererObj, col2FieldX, y, 55, 18, String.valueOf(beam.getLightningRadius())); - radiusField.setMinMaxDefaultFloat(0.1f, 10.0f, 0.5f); - addTextField(radiusField); - } - } - - @Override - protected void handleTypeButton(int id, GuiNpcButton button) { - int value = button.getValue(); - 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())); - break; - } - } - - @Override - protected void handleVisualButton(int id, GuiNpcButton button) { - int value = button.getValue(); - switch (id) { - case 200: - editingVisualColorId = 200; - setSubGui(new SubGuiColorSelector(beam.getInnerColor())); - break; - case 201: - editingVisualColorId = 201; - setSubGui(new SubGuiColorSelector(beam.getOuterColor())); - break; - case 202: - beam.setOuterColorEnabled(value == 1); - initGui(); - break; - case 206: - beam.setLightningEffect(value == 1); - initGui(); - break; - case 210: - beam.setAnchorPointEnum(AnchorPoint.fromId(value)); - break; - } - } - - @Override - public void subGuiClosed(SubGuiInterface subgui) { - if (subgui instanceof SubGuiColorSelector && editingVisualColorId != 0) { - SubGuiColorSelector colorSelector = (SubGuiColorSelector) subgui; - int rgb = colorSelector.color & 0x00FFFFFF; - if (editingVisualColorId == 200) { - beam.setInnerColor(rgb); - } else if (editingVisualColorId == 201) { - beam.setOuterColor(rgb); - } - 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); - } - } - - @Override - protected void handleTypeTextField(int id, GuiNpcTextField field) { - switch (id) { - case 100: - beam.setDamage(parseFloat(field, beam.getDamage())); - break; - case 101: - beam.setSpeed(parseFloat(field, beam.getSpeed())); - break; - case 102: - beam.setBeamWidth(parseFloat(field, beam.getBeamWidth())); - break; - case 103: - beam.setHeadSize(parseFloat(field, beam.getHeadSize())); - break; - case 105: - beam.setHomingStrength(parseFloat(field, beam.getHomingStrength())); - break; - case 106: - beam.setHomingRange(parseFloat(field, beam.getHomingRange())); - break; - case 107: - beam.setMaxDistance(parseFloat(field, beam.getMaxDistance())); - break; - case 109: - beam.setExplosionRadius(parseFloat(field, beam.getExplosionRadius())); - break; - case 110: - beam.setKnockback(parseFloat(field, beam.getKnockback())); - break; - case 111: - beam.setMaxLifetime(field.getInteger()); - break; - } - } - - @Override - protected void handleVisualTextField(int id, GuiNpcTextField field) { - switch (id) { - case 203: - beam.setOuterColorWidth(parseFloat(field, beam.getOuterColorWidth())); - break; - case 204: - beam.setOuterColorAlpha(parseFloat(field, beam.getOuterColorAlpha())); - break; - case 205: - beam.setRotationSpeed(parseFloat(field, beam.getRotationSpeed())); - break; - case 207: - beam.setLightningDensity(parseFloat(field, beam.getLightningDensity())); - break; - case 208: - beam.setLightningRadius(parseFloat(field, beam.getLightningRadius())); - break; - } - } -} diff --git a/src/main/java/noppes/npcs/client/gui/advanced/ability/SubGuiAbilityGuard.java b/src/main/java/noppes/npcs/client/gui/advanced/ability/SubGuiAbilityGuard.java deleted file mode 100644 index 0d2ec667b..000000000 --- a/src/main/java/noppes/npcs/client/gui/advanced/ability/SubGuiAbilityGuard.java +++ /dev/null @@ -1,143 +0,0 @@ -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. - */ -public class SubGuiAbilityGuard extends SubGuiAbilityConfig { - - private final AbilityGuard guard; - - public SubGuiAbilityGuard(AbilityGuard ability, IAbilityConfigCallback callback) { - super(ability, callback); - this.guard = ability; - } - - @Override - protected void initTypeTab(int startY) { - int y = startY; - int labelX = guiLeft + 8; - int fieldX = guiLeft + 105; - int col2LabelX = guiLeft + 165; - int col2FieldX = guiLeft + 225; - - // Row 1: Duration + Damage Reduction - addLabel(new GuiNpcLabel(99, "ability.duration", labelX, y + 5)); - GuiNpcTextField durationField = createIntField(99, fieldX, y, 50, guard.getDurationTicks()); - durationField.setMinMaxDefault(1, 1000, 60); - addTextField(durationField); - - addLabel(new GuiNpcLabel(100, "ability.dmgReduce", col2LabelX, y + 5)); - addTextField(createFloatField(100, col2FieldX, y, 50, guard.getDamageReduction())); - - y += 24; - - // Row 2: Can Counter + Counter Type - addLabel(new GuiNpcLabel(101, "ability.canCounter", labelX, y + 5)); - 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.getCounterTypeEnum().ordinal()); - counterTypeButton.setHoverText("ability.hover.counterType"); - counterTypeButton.setEnabled(guard.isCanCounter()); - addButton(counterTypeButton); - - y += 24; - - // Row 3: Counter Value + Counter Chance - addLabel(new GuiNpcLabel(103, "ability.counterValue", labelX, y + 5)); - GuiNpcTextField counterValueField = createFloatField(103, fieldX, y, 50, guard.getCounterValue()); - counterValueField.setEnabled(guard.isCanCounter()); - addTextField(counterValueField); - - addLabel(new GuiNpcLabel(104, "ability.counterChance", col2LabelX, y + 5)); - GuiNpcTextField counterChanceField = createFloatField(104, col2FieldX, y, 50, guard.getCounterChance()); - counterChanceField.setEnabled(guard.isCanCounter()); - addTextField(counterChanceField); - - y += 24; - - // Row 4: Counter Sound + Counter Animation - addLabel(new GuiNpcLabel(105, "ability.counterSound", labelX, y + 5)); - GuiNpcTextField counterSoundField = new GuiNpcTextField(105, this, fontRendererObj, fieldX, y, 100, 20, guard.getCounterSound()); - counterSoundField.setEnabled(guard.isCanCounter()); - addTextField(counterSoundField); - - addLabel(new GuiNpcLabel(106, "ability.counterAnim", col2LabelX, y + 5)); - GuiNpcTextField counterAnimField = createIntField(106, col2FieldX, y, 50, guard.getCounterAnimationId()); - counterAnimField.setEnabled(guard.isCanCounter()); - addTextField(counterAnimField); - - 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 - protected void handleTypeButton(int id, GuiNpcButton button) { - switch (id) { - case 101: - guard.setCanCounter(button.getValue() == 1); - initGui(); - break; - case 102: - guard.setCounterTypeEnum(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); - } - } - } - - @Override - protected void handleTypeTextField(int id, GuiNpcTextField field) { - switch (id) { - case 99: - guard.setDurationTicks(field.getInteger()); - break; - case 100: - guard.setDamageReduction(parseFloat(field, guard.getDamageReduction())); - break; - case 103: - guard.setCounterValue(parseFloat(field, guard.getCounterValue())); - break; - case 104: - guard.setCounterChance(parseFloat(field, guard.getCounterChance())); - break; - case 105: - guard.setCounterSound(field.getText()); - break; - case 106: - guard.setCounterAnimationId(field.getInteger()); - break; - } - } -} diff --git a/src/main/java/noppes/npcs/client/gui/advanced/ability/SubGuiAbilityHazard.java b/src/main/java/noppes/npcs/client/gui/advanced/ability/SubGuiAbilityHazard.java deleted file mode 100644 index 5b8be7976..000000000 --- a/src/main/java/noppes/npcs/client/gui/advanced/ability/SubGuiAbilityHazard.java +++ /dev/null @@ -1,159 +0,0 @@ -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. - */ -public class SubGuiAbilityHazard extends SubGuiAbilityConfig { - - private final AbilityHazard hazard; - - public SubGuiAbilityHazard(AbilityHazard ability, IAbilityConfigCallback callback) { - super(ability, callback); - this.hazard = ability; - } - - @Override - protected void initTypeTab(int startY) { - int y = startY; - int labelX = guiLeft + 8; - int fieldX = guiLeft + 85; - int col2LabelX = guiLeft + 145; - int col2FieldX = guiLeft + 205; - - // Row 1: Duration + Shape - addLabel(new GuiNpcLabel(99, "ability.duration", labelX, y + 5)); - GuiNpcTextField durationField = createIntField(99, fieldX, y, 50, hazard.getDurationTicks()); - durationField.setMinMaxDefault(1, 2000, 100); - addTextField(durationField); - - addLabel(new GuiNpcLabel(100, "ability.shape", col2LabelX, y + 5)); - String[] shapes = {"Circle", "Ring", "Cone"}; - GuiNpcButton shapeBtn = new GuiNpcButton(100, col2FieldX, y, 55, 20, shapes, hazard.getShapeEnum().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"}; - GuiNpcButton placementBtn = new GuiNpcButton(101, fieldX, y, 70, 20, placements, hazard.getPlacementEnum().ordinal()); - placementBtn.setHoverText("ability.hover.placement"); - addButton(placementBtn); - - y += 24; - - // Row 2: Radius + Inner Radius - addLabel(new GuiNpcLabel(102, "ability.radius", labelX, y + 5)); - addTextField(createFloatField(102, fieldX, y, 50, hazard.getRadius())); - - addLabel(new GuiNpcLabel(103, "ability.innerRadius", col2LabelX, y + 5)); - addTextField(createFloatField(103, col2FieldX, y, 50, hazard.getInnerRadius())); - - y += 24; - - // Row 3: Damage Per Second + Damage Interval - addLabel(new GuiNpcLabel(104, "ability.dmgPerSec", labelX, y + 5)); - addTextField(createFloatField(104, fieldX, y, 50, hazard.getDamagePerSecond())); - - addLabel(new GuiNpcLabel(105, "ability.dmgInterval", col2LabelX, y + 5)); - addTextField(createIntField(105, col2FieldX, y, 50, hazard.getDamageInterval())); - - y += 24; - - // Row 4: Slowness Level + Debuff Duration - addLabel(new GuiNpcLabel(106, "ability.slownessLvl", labelX, y + 5)); - addTextField(createIntField(106, fieldX, y, 50, hazard.getSlownessLevel())); - - addLabel(new GuiNpcLabel(107, "ability.debuffDur", col2LabelX, y + 5)); - addTextField(createIntField(107, col2FieldX, y, 50, hazard.getDebuffDuration())); - - y += 24; - - // Row 5: Poison Level + Affects Caster - addLabel(new GuiNpcLabel(108, "ability.poisonLvl", labelX, y + 5)); - addTextField(createIntField(108, fieldX, y, 50, hazard.getPoisonLevel())); - - addLabel(new GuiNpcLabel(109, "ability.affectsCaster", col2LabelX, y + 5)); - 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; - - // Row 6: Effects button - addButton(new GuiNpcButton(150, labelX, y, 80, 20, "ability.effects")); - } - - @Override - protected void handleTypeButton(int id, GuiNpcButton button) { - int value = button.getValue(); - switch (id) { - case 100: - hazard.setShapeEnum(AbilityHazard.HazardShape.values()[value]); - break; - case 101: - hazard.setPlacementEnum(AbilityHazard.PlacementMode.values()[value]); - break; - 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); - } - } - } - - @Override - protected void handleTypeTextField(int id, GuiNpcTextField field) { - switch (id) { - case 99: - hazard.setDurationTicks(field.getInteger()); - break; - case 102: - hazard.setRadius(parseFloat(field, hazard.getRadius())); - break; - case 103: - hazard.setInnerRadius(parseFloat(field, hazard.getInnerRadius())); - break; - case 104: - hazard.setDamagePerSecond(parseFloat(field, hazard.getDamagePerSecond())); - break; - case 105: - hazard.setDamageInterval(field.getInteger()); - break; - case 106: - hazard.setSlownessLevel(field.getInteger()); - break; - case 107: - hazard.setDebuffDuration(field.getInteger()); - break; - case 108: - hazard.setPoisonLevel(field.getInteger()); - break; - } - } -} 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 deleted file mode 100644 index 490b4773a..000000000 --- a/src/main/java/noppes/npcs/client/gui/advanced/ability/SubGuiAbilityHeal.java +++ /dev/null @@ -1,106 +0,0 @@ -package noppes.npcs.client.gui.advanced.ability; - -import kamkeel.npcs.controllers.data.ability.type.AbilityHeal; -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; - -/** - * GUI for configuring Heal ability type-specific settings. - */ -public class SubGuiAbilityHeal extends SubGuiAbilityConfig { - - private final AbilityHeal heal; - - public SubGuiAbilityHeal(AbilityHeal ability, IAbilityConfigCallback callback) { - super(ability, callback); - this.heal = ability; - } - - @Override - protected void initTypeTab(int startY) { - int y = startY; - int labelX = guiLeft + 8; - int fieldX = guiLeft + 85; - int col2LabelX = guiLeft + 145; - int col2FieldX = guiLeft + 205; - - // Row 1: Instant Heal + Duration (only shown if not instant) - addLabel(new GuiNpcLabel(103, "dialog.instant", labelX, y + 5)); - 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)); - GuiNpcTextField durationField = createIntField(99, col2FieldX, y, 50, heal.getDurationTicks()); - durationField.setMinMaxDefault(1, 1000, 60); - addTextField(durationField); - } - - y += 24; - - // Row 2: Heal Amount + Heal Percent - addLabel(new GuiNpcLabel(100, "ability.healAmount", labelX, y + 5)); - addTextField(createFloatField(100, fieldX, y, 50, heal.getHealAmount())); - - addLabel(new GuiNpcLabel(101, "ability.healPercent", col2LabelX, y + 5)); - addTextField(createFloatField(101, col2FieldX, y, 50, heal.getHealPercent())); - - y += 24; - - // Row 3: Heal Radius - addLabel(new GuiNpcLabel(102, "ability.healRadius", labelX, y + 5)); - addTextField(createFloatField(102, fieldX, y, 50, heal.getHealRadius())); - - y += 24; - - // Row 4: Heal Self + Heal Allies - addLabel(new GuiNpcLabel(104, "ability.healSelf", labelX, y + 5)); - 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)); - 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 - protected void handleTypeButton(int id, GuiNpcButton button) { - int value = button.getValue(); - switch (id) { - case 103: - heal.setInstantHeal(value == 1); - initGui(); // Refresh to show/hide duration field - break; - case 104: - heal.setHealSelf(value == 1); - break; - case 105: - heal.setHealAllies(value == 1); - break; - } - } - - @Override - protected void handleTypeTextField(int id, GuiNpcTextField field) { - switch (id) { - case 99: - heal.setDurationTicks(field.getInteger()); - break; - case 100: - heal.setHealAmount(parseFloat(field, heal.getHealAmount())); - break; - case 101: - heal.setHealPercent(parseFloat(field, heal.getHealPercent())); - break; - case 102: - heal.setHealRadius(parseFloat(field, heal.getHealRadius())); - break; - } - } -} diff --git a/src/main/java/noppes/npcs/client/gui/advanced/ability/SubGuiAbilityHeavyHit.java b/src/main/java/noppes/npcs/client/gui/advanced/ability/SubGuiAbilityHeavyHit.java deleted file mode 100644 index 897a4af1f..000000000 --- a/src/main/java/noppes/npcs/client/gui/advanced/ability/SubGuiAbilityHeavyHit.java +++ /dev/null @@ -1,76 +0,0 @@ -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. - */ -public class SubGuiAbilityHeavyHit extends SubGuiAbilityConfig { - - private final AbilityHeavyHit heavyHit; - - public SubGuiAbilityHeavyHit(AbilityHeavyHit ability, IAbilityConfigCallback callback) { - super(ability, callback); - this.heavyHit = ability; - } - - @Override - protected void initTypeTab(int startY) { - int y = startY; - int labelX = guiLeft + 8; - int fieldX = guiLeft + 85; - int col2LabelX = guiLeft + 145; - - // Row 1: Damage + Knockback - addLabel(new GuiNpcLabel(100, "enchantment.damage", labelX, y + 5)); - addTextField(createFloatField(100, fieldX, y, 50, heavyHit.getDamage())); - - addLabel(new GuiNpcLabel(102, "ability.knockback", col2LabelX, y + 5)); - addTextField(createFloatField(102, guiLeft + 205, y, 50, heavyHit.getKnockback())); - - y += 24; - - // Row 2: Effects button - addButton(new GuiNpcButton(150, labelX, y, 80, 20, "ability.effects")); - } - - @Override - protected void handleTypeButton(int id, GuiNpcButton button) { - if (id == 150) { - setSubGui(new SubGuiAbilityEffects(heavyHit.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) { - heavyHit.setEffects(result); - } - } - } - - @Override - protected void handleTypeTextField(int id, GuiNpcTextField field) { - switch (id) { - case 100: - heavyHit.setDamage(parseFloat(field, heavyHit.getDamage())); - break; - case 102: - heavyHit.setKnockback(parseFloat(field, heavyHit.getKnockback())); - 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 deleted file mode 100644 index e5184a3bb..000000000 --- a/src/main/java/noppes/npcs/client/gui/advanced/ability/SubGuiAbilityLaserShot.java +++ /dev/null @@ -1,268 +0,0 @@ -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; -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 Laser Shot ability type-specific settings. - */ -public class SubGuiAbilityLaserShot extends SubGuiAbilityConfig { - - private final AbilityLaserShot laser; - private int editingVisualColorId = 0; - - public SubGuiAbilityLaserShot(AbilityLaserShot ability, IAbilityConfigCallback callback) { - super(ability, callback); - this.laser = ability; - } - - @Override - protected boolean hasVisualSettings() { - return true; - } - - @Override - protected void initTypeTab(int startY) { - int y = startY; - int labelX = guiLeft + 8; - int fieldX = guiLeft + 85; - int col2LabelX = guiLeft + 145; - int col2FieldX = guiLeft + 205; - - // Row 1: Damage + Laser Width - addLabel(new GuiNpcLabel(100, "enchantment.damage", labelX, y + 5)); - addTextField(createFloatField(100, fieldX, y, 50, laser.getDamage())); - - addLabel(new GuiNpcLabel(101, "ability.laserWidth", col2LabelX, y + 5)); - addTextField(createFloatField(101, col2FieldX, y, 50, laser.getLaserWidth())); - - y += 24; - - // Row 2: Expansion Speed + Linger Ticks - addLabel(new GuiNpcLabel(102, "ability.expansionSpeed", labelX, y + 5)); - addTextField(createFloatField(102, fieldX, y, 50, laser.getExpansionSpeed())); - - addLabel(new GuiNpcLabel(103, "ability.lingerTicks", col2LabelX, y + 5)); - addTextField(createIntField(103, col2FieldX, y, 50, laser.getLingerTicks())); - - y += 24; - - // Row 3: Max Distance + Max Lifetime - addLabel(new GuiNpcLabel(104, "ability.maxDist", labelX, y + 5)); - addTextField(createFloatField(104, fieldX, y, 50, laser.getMaxDistance())); - - addLabel(new GuiNpcLabel(105, "ability.lifetime", col2LabelX, y + 5)); - addTextField(createIntField(105, col2FieldX, y, 50, laser.getMaxLifetime())); - - y += 24; - - // Row 4: Explosive + Explosion Radius (only show radius if explosive) - addLabel(new GuiNpcLabel(106, "ability.explosive", labelX, y + 5)); - 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); - - if (laser.isExplosive()) { - addLabel(new GuiNpcLabel(107, "ability.explosionRad", col2LabelX, y + 5)); - addTextField(createFloatField(107, col2FieldX, y, 50, laser.getExplosionRadius())); - } - - y += 24; - - // Row 5: Knockback + Knockback Up - addLabel(new GuiNpcLabel(108, "ability.knockback", labelX, y + 5)); - addTextField(createFloatField(108, fieldX, y, 50, laser.getKnockback())); - - 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 - protected void initVisualTab(int startY) { - int y = startY; - int labelX = guiLeft + 8; - int fieldX = guiLeft + 85; - int col2LabelX = guiLeft + 180; - int col2FieldX = guiLeft + 260; - - // Row 1: Inner Color + Outer Color - addLabel(new GuiNpcLabel(200, "ability.innerColor", labelX, y + 5)); - String innerHex = String.format("%06X", laser.getInnerColor() & 0xFFFFFF); - GuiNpcButton innerColorBtn = new GuiNpcButton(200, fieldX, y, 55, 20, innerHex); - innerColorBtn.setTextColor(laser.getInnerColor() & 0xFFFFFF); - addButton(innerColorBtn); - - addLabel(new GuiNpcLabel(201, "ability.outerColor", col2LabelX, y + 5)); - String outerHex = String.format("%06X", laser.getOuterColor() & 0xFFFFFF); - GuiNpcButton outerColorBtn = new GuiNpcButton(201, col2FieldX, y, 55, 20, outerHex); - outerColorBtn.setTextColor(laser.getOuterColor() & 0xFFFFFF); - outerColorBtn.setEnabled(laser.isOuterColorEnabled()); - addButton(outerColorBtn); - - y += 24; - - // Row 2: Outer Color Enabled + Outer Color Width - addLabel(new GuiNpcLabel(202, "ability.outerEnabled", labelX, y + 5)); - addButton(new GuiNpcButton(202, fieldX, y, 50, 20, new String[]{"gui.no", "gui.yes"}, laser.isOuterColorEnabled() ? 1 : 0)); - - addLabel(new GuiNpcLabel(203, "ability.outerWidth", col2LabelX, y + 5)); - GuiNpcTextField widthField = createFloatField(203, col2FieldX, y, 55, laser.getOuterColorWidth()); - widthField.setEnabled(laser.isOuterColorEnabled()); - addTextField(widthField); - - y += 24; - - // Row 3: Lightning Effect Enabled - addLabel(new GuiNpcLabel(204, "ability.outerAlpha", labelX, y + 5)); - GuiNpcTextField alphaField = createFloatField(204, fieldX, y, 55, laser.getOuterColorAlpha()); - alphaField.setEnabled(laser.isOuterColorEnabled()); - alphaField.setMinMaxDefaultFloat(0, 1, 0.5f); - addTextField(alphaField); - - addLabel(new GuiNpcLabel(205, "ability.lightning", col2LabelX, y + 5)); - GuiNpcButton lightningBtn = new GuiNpcButton(205, col2FieldX, 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()) { - y += 24; - - // Row 4: Density + Radius - addLabel(new GuiNpcLabel(206, "ability.lightningDensity", labelX, y + 5)); - GuiNpcTextField densityField = new GuiNpcTextField(206, this, fontRendererObj, fieldX, y, 55, 18, String.valueOf(laser.getLightningDensity())); - densityField.setMinMaxDefaultFloat(0.01f, 5.0f, 0.15f); - addTextField(densityField); - - addLabel(new GuiNpcLabel(207, "ability.lightningRadius", col2LabelX, y + 5)); - GuiNpcTextField radiusField = new GuiNpcTextField(207, this, fontRendererObj, col2FieldX, y, 55, 18, String.valueOf(laser.getLightningRadius())); - radiusField.setMinMaxDefaultFloat(0.1f, 10.0f, 0.5f); - addTextField(radiusField); - } - } - - @Override - protected void handleTypeButton(int id, GuiNpcButton button) { - int value = button.getValue(); - switch (id) { - case 106: - laser.setExplosive(value == 1); - initGui(); - break; - case 150: - setSubGui(new SubGuiAbilityEffects(laser.getEffects())); - break; - } - } - - @Override - protected void handleVisualButton(int id, GuiNpcButton button) { - int value = button.getValue(); - switch (id) { - case 200: - editingVisualColorId = 200; - setSubGui(new SubGuiColorSelector(laser.getInnerColor())); - break; - case 201: - editingVisualColorId = 201; - setSubGui(new SubGuiColorSelector(laser.getOuterColor())); - break; - case 202: - laser.setOuterColorEnabled(value == 1); - initGui(); - break; - case 205: - laser.setLightningEffect(value == 1); - initGui(); - break; - } - } - - @Override - public void subGuiClosed(SubGuiInterface subgui) { - if (subgui instanceof SubGuiColorSelector && editingVisualColorId != 0) { - SubGuiColorSelector colorSelector = (SubGuiColorSelector) subgui; - int rgb = colorSelector.color & 0x00FFFFFF; - if (editingVisualColorId == 200) { - laser.setInnerColor(rgb); - } else if (editingVisualColorId == 201) { - laser.setOuterColor(rgb); - } - 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); - } - } - - @Override - protected void handleVisualTextField(int id, GuiNpcTextField field) { - switch (id) { - case 203: - laser.setOuterColorWidth(parseFloat(field, laser.getOuterColorWidth())); - break; - case 204: - laser.setOuterColorAlpha(parseFloat(field, laser.getOuterColorAlpha())); - break; - case 206: - laser.setLightningDensity(parseFloat(field, laser.getLightningDensity())); - break; - case 207: - laser.setLightningRadius(parseFloat(field, laser.getLightningRadius())); - break; - } - } - - @Override - protected void handleTypeTextField(int id, GuiNpcTextField field) { - switch (id) { - case 100: - laser.setDamage(parseFloat(field, laser.getDamage())); - break; - case 101: - laser.setLaserWidth(parseFloat(field, laser.getLaserWidth())); - break; - case 102: - laser.setExpansionSpeed(parseFloat(field, laser.getExpansionSpeed())); - break; - case 103: - laser.setLingerTicks(field.getInteger()); - break; - case 104: - laser.setMaxDistance(parseFloat(field, laser.getMaxDistance())); - break; - case 105: - laser.setMaxLifetime(field.getInteger()); - break; - case 107: - laser.setExplosionRadius(parseFloat(field, laser.getExplosionRadius())); - break; - case 108: - laser.setKnockback(parseFloat(field, laser.getKnockback())); - break; - case 109: - laser.setKnockbackUp(parseFloat(field, laser.getKnockbackUp())); - break; - } - } -} 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 deleted file mode 100644 index 7cc0f9f2f..000000000 --- a/src/main/java/noppes/npcs/client/gui/advanced/ability/SubGuiAbilityOrb.java +++ /dev/null @@ -1,294 +0,0 @@ -package noppes.npcs.client.gui.advanced.ability; - -import kamkeel.npcs.controllers.data.ability.AbilityEffect; -import kamkeel.npcs.controllers.data.ability.AnchorPoint; -import kamkeel.npcs.controllers.data.ability.type.AbilityOrb; -import noppes.npcs.client.gui.SubGuiColorSelector; -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 Orb ability type-specific settings. - */ -public class SubGuiAbilityOrb extends SubGuiAbilityConfig { - - private final AbilityOrb orb; - private int editingVisualColorId = 0; - - public SubGuiAbilityOrb(AbilityOrb ability, IAbilityConfigCallback callback) { - super(ability, callback); - this.orb = ability; - } - - @Override - protected boolean hasVisualSettings() { - return true; - } - - @Override - protected void initTypeTab(int startY) { - int y = startY; - int labelX = guiLeft + 8; - int fieldX = guiLeft + 85; - int col2LabelX = guiLeft + 145; - int col2FieldX = guiLeft + 205; - - // Row 1: Damage + Speed - addLabel(new GuiNpcLabel(100, "enchantment.damage", labelX, y + 5)); - addTextField(createFloatField(100, fieldX, y, 50, orb.getDamage())); - - addLabel(new GuiNpcLabel(101, "stats.speed", col2LabelX, y + 5)); - addTextField(createFloatField(101, col2FieldX, y, 50, orb.getOrbSpeed())); - - y += 24; - - // Row 2: Orb Size + Max Distance - addLabel(new GuiNpcLabel(102, "stats.size", labelX, y + 5)); - addTextField(createFloatField(102, fieldX, y, 50, orb.getOrbSize())); - - addLabel(new GuiNpcLabel(103, "ability.maxDist", col2LabelX, y + 5)); - addTextField(createFloatField(103, col2FieldX, y, 50, orb.getMaxDistance())); - - y += 24; - - // Row 3: Homing + Homing Strength (only show strength if homing) - addLabel(new GuiNpcLabel(104, "ability.homing", labelX, y + 5)); - 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); - - 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 (only show radius if explosive) - addLabel(new GuiNpcLabel(106, "ability.explosive", labelX, y + 5)); - 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); - - if (orb.isExplosive()) { - addLabel(new GuiNpcLabel(107, "ability.explosionRad", col2LabelX, y + 5)); - addTextField(createFloatField(107, col2FieldX, y, 50, orb.getExplosionRadius())); - } - - y += 24; - - // Row 5: Knockback + Max Lifetime - addLabel(new GuiNpcLabel(108, "ability.knockback", labelX, y + 5)); - addTextField(createFloatField(108, fieldX, y, 50, orb.getKnockback())); - - 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 - protected void initVisualTab(int startY) { - int y = startY; - int labelX = guiLeft + 8; - int fieldX = guiLeft + 85; - int col2LabelX = guiLeft + 180; - int col2FieldX = guiLeft + 260; - - // Row 1: Anchor Point - addLabel(new GuiNpcLabel(210, "ability.anchorPoint", labelX, y + 5)); - GuiNpcButton anchorBtn = new GuiNpcButton(210, fieldX, y, 80, 20, AnchorPoint.getDisplayNames(), orb.getAnchorPointEnum().getId()); - anchorBtn.setHoverText("ability.hover.anchorPoint"); - addButton(anchorBtn); - - y += 24; - - // Row 2: Inner Color + Rotation Speed - addLabel(new GuiNpcLabel(200, "ability.innerColor", labelX, y + 5)); - String innerHex = String.format("%06X", orb.getInnerColor() & 0xFFFFFF); - GuiNpcButton innerColorBtn = new GuiNpcButton(200, fieldX, y, 55, 20, innerHex); - innerColorBtn.setTextColor(orb.getInnerColor() & 0xFFFFFF); - addButton(innerColorBtn); - - addLabel(new GuiNpcLabel(205, "ability.rotationSpeed", col2LabelX, y + 5)); - addTextField(createFloatField(205, col2FieldX, y, 55, orb.getRotationSpeed())); - - y += 24; - - // Row 3: Outer Glow Enabled - addLabel(new GuiNpcLabel(202, "ability.outerEnabled", labelX, y + 5)); - addButton(new GuiNpcButton(202, fieldX, y, 50, 20, new String[]{"gui.no", "gui.yes"}, orb.isOuterColorEnabled() ? 1 : 0)); - - // Only show Outer Color and Width if Outer Glow is enabled - if (orb.isOuterColorEnabled()) { - addLabel(new GuiNpcLabel(204, "ability.outerAlpha", col2LabelX, y + 5)); - GuiNpcTextField alphaField = createFloatField(204, col2FieldX, y, 55, orb.getOuterColorAlpha()); - alphaField.setEnabled(orb.isOuterColorEnabled()); - alphaField.setMinMaxDefaultFloat(0, 1, 0.5f); - addTextField(alphaField); - - y += 24; - - // Row 4: Outer Color + Outer Width - addLabel(new GuiNpcLabel(201, "ability.outerColor", labelX, y + 5)); - String outerHex = String.format("%06X", orb.getOuterColor() & 0xFFFFFF); - GuiNpcButton outerColorBtn = new GuiNpcButton(201, fieldX, y, 55, 20, outerHex); - outerColorBtn.setTextColor(orb.getOuterColor() & 0xFFFFFF); - addButton(outerColorBtn); - - addLabel(new GuiNpcLabel(203, "ability.outerWidth", col2LabelX, y + 5)); - addTextField(createFloatField(203, col2FieldX, y, 55, orb.getOuterColorWidth())); - } - - y += 24; - - // Row 5: Lightning Effect Enabled - addLabel(new GuiNpcLabel(206, "ability.lightning", labelX, y + 5)); - GuiNpcButton lightningBtn = new GuiNpcButton(206, 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()) { - y += 24; - - // Row 61: Density + Radius - addLabel(new GuiNpcLabel(207, "ability.lightningDensity", labelX, y + 5)); - GuiNpcTextField densityField = new GuiNpcTextField(207, this, fontRendererObj, fieldX, y, 55, 18, String.valueOf(orb.getLightningDensity())); - densityField.setMinMaxDefaultFloat(0.01f, 5.0f, 0.15f); - addTextField(densityField); - - addLabel(new GuiNpcLabel(208, "ability.lightningRadius", col2LabelX, y + 5)); - GuiNpcTextField radiusField = new GuiNpcTextField(208, this, fontRendererObj, col2FieldX, y, 55, 18, String.valueOf(orb.getLightningRadius())); - radiusField.setMinMaxDefaultFloat(0.1f, 10.0f, 0.5f); - addTextField(radiusField); - } - } - - @Override - protected void handleTypeButton(int id, GuiNpcButton button) { - int value = button.getValue(); - 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())); - break; - } - } - - @Override - protected void handleVisualButton(int id, GuiNpcButton button) { - int value = button.getValue(); - switch (id) { - case 200: - editingVisualColorId = 200; - setSubGui(new SubGuiColorSelector(orb.getInnerColor())); - break; - case 201: - editingVisualColorId = 201; - setSubGui(new SubGuiColorSelector(orb.getOuterColor())); - break; - case 202: - orb.setOuterColorEnabled(value == 1); - initGui(); - break; - case 206: - orb.setLightningEffect(value == 1); - initGui(); - break; - case 210: - orb.setAnchorPointEnum(AnchorPoint.fromId(value)); - break; - } - } - - @Override - public void subGuiClosed(SubGuiInterface subgui) { - if (subgui instanceof SubGuiColorSelector && editingVisualColorId != 0) { - SubGuiColorSelector colorSelector = (SubGuiColorSelector) subgui; - int rgb = colorSelector.color & 0x00FFFFFF; - if (editingVisualColorId == 200) { - orb.setInnerColor(rgb); - } else if (editingVisualColorId == 201) { - orb.setOuterColor(rgb); - } - 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); - } - } - - @Override - protected void handleTypeTextField(int id, GuiNpcTextField field) { - switch (id) { - case 100: - orb.setDamage(parseFloat(field, orb.getDamage())); - break; - case 101: - orb.setOrbSpeed(parseFloat(field, orb.getOrbSpeed())); - break; - case 102: - orb.setOrbSize(parseFloat(field, orb.getOrbSize())); - break; - case 103: - orb.setMaxDistance(parseFloat(field, orb.getMaxDistance())); - break; - case 105: - orb.setHomingStrength(parseFloat(field, orb.getHomingStrength())); - break; - case 107: - orb.setExplosionRadius(parseFloat(field, orb.getExplosionRadius())); - break; - case 108: - orb.setKnockback(parseFloat(field, orb.getKnockback())); - break; - case 109: - orb.setMaxLifetime(field.getInteger()); - break; - } - } - - @Override - protected void handleVisualTextField(int id, GuiNpcTextField field) { - switch (id) { - case 203: - orb.setOuterColorWidth(parseFloat(field, orb.getOuterColorWidth())); - break; - case 204: - orb.setOuterColorAlpha(parseFloat(field, orb.getOuterColorAlpha())); - break; - case 205: - orb.setRotationSpeed(parseFloat(field, orb.getRotationSpeed())); - break; - case 207: - orb.setLightningDensity(parseFloat(field, orb.getLightningDensity())); - break; - case 208: - orb.setLightningRadius(parseFloat(field, orb.getLightningRadius())); - break; - } - } -} 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 deleted file mode 100644 index fe66fa242..000000000 --- a/src/main/java/noppes/npcs/client/gui/advanced/ability/SubGuiAbilityProjectile.java +++ /dev/null @@ -1,145 +0,0 @@ -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. - */ -public class SubGuiAbilityProjectile extends SubGuiAbilityConfig { - - private final AbilityProjectile projectile; - - public SubGuiAbilityProjectile(AbilityProjectile ability, IAbilityConfigCallback callback) { - super(ability, callback); - this.projectile = ability; - } - - @Override - protected void initTypeTab(int startY) { - int y = startY; - int labelX = guiLeft + 8; - int fieldX = guiLeft + 85; - int col2LabelX = guiLeft + 145; - int col2FieldX = guiLeft + 205; - - // Row 1: Damage + Speed - addLabel(new GuiNpcLabel(100, "enchantment.damage", labelX, y + 5)); - addTextField(createFloatField(100, fieldX, y, 50, projectile.getDamage())); - - addLabel(new GuiNpcLabel(101, "stats.speed", col2LabelX, y + 5)); - addTextField(createFloatField(101, col2FieldX, y, 50, projectile.getSpeed())); - - y += 24; - - // Row 2: Knockback + Projectile Type - addLabel(new GuiNpcLabel(102, "ability.knockback", labelX, y + 5)); - addTextField(createFloatField(102, fieldX, y, 50, projectile.getKnockback())); - - addLabel(new GuiNpcLabel(103, "ability.projType", col2LabelX, y + 5)); - String[] projTypes = {"fireball", "arrow", "magic"}; - int typeIdx = 0; - String currType = projectile.getProjectileType(); - for (int i = 0; i < projTypes.length; i++) { - if (projTypes[i].equals(currType)) { - typeIdx = i; - break; - } - } - addButton(new GuiNpcButton(103, col2FieldX, y, 60, 20, projTypes, typeIdx)); - - y += 24; - - // Row 3: Explosive + Explosion Radius (only show radius if explosive) - addLabel(new GuiNpcLabel(104, "ability.explosive", labelX, y + 5)); - 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); - - 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 (only show strength if homing) - addLabel(new GuiNpcLabel(106, "ability.homing", labelX, y + 5)); - 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); - - if (projectile.isHoming()) { - 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 - protected void handleTypeButton(int id, GuiNpcButton button) { - int value = button.getValue(); - switch (id) { - case 103: - String[] projTypes = {"fireball", "arrow", "magic"}; - projectile.setProjectileType(projTypes[value]); - break; - case 104: - projectile.setExplosive(value == 1); - initGui(); - break; - case 106: - projectile.setHoming(value == 1); - initGui(); - 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); - } - } - } - - @Override - protected void handleTypeTextField(int id, GuiNpcTextField field) { - switch (id) { - case 100: - projectile.setDamage(parseFloat(field, projectile.getDamage())); - break; - case 101: - projectile.setSpeed(parseFloat(field, projectile.getSpeed())); - break; - case 102: - projectile.setKnockback(parseFloat(field, projectile.getKnockback())); - break; - case 105: - projectile.setExplosionRadius(parseFloat(field, projectile.getExplosionRadius())); - break; - case 107: - projectile.setHomingStrength(parseFloat(field, projectile.getHomingStrength())); - break; - } - } -} diff --git a/src/main/java/noppes/npcs/client/gui/advanced/ability/SubGuiAbilityShockwave.java b/src/main/java/noppes/npcs/client/gui/advanced/ability/SubGuiAbilityShockwave.java deleted file mode 100644 index 48c2c5295..000000000 --- a/src/main/java/noppes/npcs/client/gui/advanced/ability/SubGuiAbilityShockwave.java +++ /dev/null @@ -1,95 +0,0 @@ -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. - */ -public class SubGuiAbilityShockwave extends SubGuiAbilityConfig { - - private final AbilityShockwave shockwave; - - public SubGuiAbilityShockwave(AbilityShockwave ability, IAbilityConfigCallback callback) { - super(ability, callback); - this.shockwave = ability; - } - - @Override - protected void initTypeTab(int startY) { - int y = startY; - int labelX = guiLeft + 8; - int fieldX = guiLeft + 85; - int col2LabelX = guiLeft + 145; - int col2FieldX = guiLeft + 205; - - // Row 1: Damage + Push Radius - addLabel(new GuiNpcLabel(100, "enchantment.damage", labelX, y + 5)); - addTextField(createFloatField(100, fieldX, y, 50, shockwave.getDamage())); - - addLabel(new GuiNpcLabel(101, "ability.pushRadius", col2LabelX, y + 5)); - addTextField(createFloatField(101, col2FieldX, y, 50, shockwave.getPushRadius())); - - y += 24; - - // Row 2: Push Strength - addLabel(new GuiNpcLabel(102, "ability.pushStrength", labelX, y + 5)); - addTextField(createFloatField(102, fieldX, y, 50, shockwave.getPushStrength())); - - y += 24; - - // Row 3: Max Targets + Effects button - addLabel(new GuiNpcLabel(104, "ability.maxTargets", labelX, y + 5)); - addTextField(createIntField(104, fieldX, 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) { - case 100: - shockwave.setDamage(parseFloat(field, shockwave.getDamage())); - break; - case 101: - shockwave.setPushRadius(parseFloat(field, shockwave.getPushRadius())); - break; - case 102: - shockwave.setPushStrength(parseFloat(field, shockwave.getPushStrength())); - break; - case 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 deleted file mode 100644 index 4e020829b..000000000 --- a/src/main/java/noppes/npcs/client/gui/advanced/ability/SubGuiAbilitySlam.java +++ /dev/null @@ -1,98 +0,0 @@ -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. - */ -public class SubGuiAbilitySlam extends SubGuiAbilityConfig { - - private final AbilitySlam slam; - - public SubGuiAbilitySlam(AbilitySlam ability, IAbilityConfigCallback callback) { - super(ability, callback); - this.slam = ability; - } - - @Override - protected void initTypeTab(int startY) { - int y = startY; - int labelX = guiLeft + 8; - int fieldX = guiLeft + 85; - int col2LabelX = guiLeft + 145; - int col2FieldX = guiLeft + 205; - - // Row 1: Damage + Radius - addLabel(new GuiNpcLabel(100, "enchantment.damage", labelX, y + 5)); - addTextField(createFloatField(100, fieldX, y, 50, slam.getDamage())); - - addLabel(new GuiNpcLabel(101, "ability.radius", col2LabelX, y + 5)); - addTextField(createFloatField(101, col2FieldX, y, 50, slam.getRadius())); - - y += 24; - - // Row 2: Knockback + Leap Speed - addLabel(new GuiNpcLabel(102, "ability.knockback", labelX, y + 5)); - addTextField(createFloatField(102, fieldX, y, 50, slam.getKnockbackStrength())); - - addLabel(new GuiNpcLabel(103, "ability.leapSpeed", col2LabelX, y + 5)); - addTextField(createFloatField(103, col2FieldX, y, 50, slam.getLeapSpeed())); - - y += 24; - - // 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 - protected void handleTypeTextField(int id, GuiNpcTextField field) { - switch (id) { - case 100: - slam.setDamage(parseFloat(field, slam.getDamage())); - break; - case 101: - slam.setRadius(parseFloat(field, slam.getRadius())); - break; - case 102: - slam.setKnockbackStrength(parseFloat(field, slam.getKnockbackStrength())); - break; - case 103: - slam.setLeapSpeed(parseFloat(field, slam.getLeapSpeed())); - break; - case 104: - slam.setLeapHeight(parseFloat(field, slam.getLeapHeight())); - break; - } - } -} 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 deleted file mode 100644 index 1561b408a..000000000 --- a/src/main/java/noppes/npcs/client/gui/advanced/ability/SubGuiAbilitySweeper.java +++ /dev/null @@ -1,219 +0,0 @@ -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; -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 Sweeper ability type-specific settings. - * Sweeper is a low rotating beam that players can jump over. - */ -public class SubGuiAbilitySweeper extends SubGuiAbilityConfig { - - private final AbilitySweeper sweeper; - private int editingVisualColorId = 0; - - public SubGuiAbilitySweeper(AbilitySweeper ability, IAbilityConfigCallback callback) { - super(ability, callback); - this.sweeper = ability; - } - - @Override - protected boolean hasVisualSettings() { - return true; - } - - @Override - protected void initTypeTab(int startY) { - int y = startY; - int labelX = guiLeft + 8; - int fieldX = guiLeft + 85; - int col2LabelX = guiLeft + 145; - int col2FieldX = guiLeft + 205; - - // Row 1: Damage + Damage Interval - addLabel(new GuiNpcLabel(100, "enchantment.damage", labelX, y + 5)); - addTextField(createFloatField(100, fieldX, y, 50, sweeper.getDamage())); - - addLabel(new GuiNpcLabel(101, "ability.dmgInterval", col2LabelX, y + 5)); - addTextField(createIntField(101, col2FieldX, y, 50, sweeper.getDamageInterval())); - - y += 24; - - // Row 2: Beam Length + Beam Width - addLabel(new GuiNpcLabel(102, "ability.beamLength", labelX, y + 5)); - addTextField(createFloatField(102, fieldX, y, 50, sweeper.getBeamLength())); - - addLabel(new GuiNpcLabel(103, "ability.beamWidth", col2LabelX, y + 5)); - addTextField(createFloatField(103, col2FieldX, y, 50, sweeper.getBeamWidth())); - - y += 24; - - // Row 3: Beam Height + Sweep Speed - addLabel(new GuiNpcLabel(104, "ability.beamHeight", labelX, y + 5)); - addTextField(createFloatField(104, fieldX, y, 50, sweeper.getBeamHeight())); - - addLabel(new GuiNpcLabel(105, "ability.sweepSpeed", col2LabelX, y + 5)); - addTextField(createFloatField(105, col2FieldX, y, 50, sweeper.getSweepSpeed())); - - y += 24; - - // Row 4: Number of Rotations + Piercing - addLabel(new GuiNpcLabel(106, "ability.rotations", labelX, y + 5)); - addTextField(createIntField(106, fieldX, y, 50, sweeper.getNumberOfRotations())); - - addLabel(new GuiNpcLabel(107, "ability.piercing", col2LabelX, y + 5)); - 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)); - 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; - - // Row 6: Effects button - addButton(new GuiNpcButton(150, labelX, y, 80, 20, "ability.effects")); - } - - @Override - protected void initVisualTab(int startY) { - int y = startY; - int labelX = guiLeft + 8; - int fieldX = guiLeft + 85; - int col2LabelX = guiLeft + 180; - int col2FieldX = guiLeft + 260; - - // Row 1: Inner Color + Outer Color - addLabel(new GuiNpcLabel(200, "ability.innerColor", labelX, y + 5)); - String innerHex = String.format("%06X", sweeper.getInnerColor() & 0xFFFFFF); - GuiNpcButton innerColorBtn = new GuiNpcButton(200, fieldX, y, 55, 20, innerHex); - innerColorBtn.setTextColor(sweeper.getInnerColor() & 0xFFFFFF); - addButton(innerColorBtn); - - addLabel(new GuiNpcLabel(201, "ability.outerColor", col2LabelX, y + 5)); - String outerHex = String.format("%06X", sweeper.getOuterColor() & 0xFFFFFF); - GuiNpcButton outerColorBtn = new GuiNpcButton(201, col2FieldX, y, 55, 20, outerHex); - outerColorBtn.setTextColor(sweeper.getOuterColor() & 0xFFFFFF); - outerColorBtn.setEnabled(sweeper.isOuterColorEnabled()); - addButton(outerColorBtn); - - y += 24; - - // Row 2: Outer Color Enabled + Outer Color Width - addLabel(new GuiNpcLabel(202, "ability.outerEnabled", labelX, y + 5)); - addButton(new GuiNpcButton(202, fieldX, y, 50, 20, new String[]{"gui.no", "gui.yes"}, sweeper.isOuterColorEnabled() ? 1 : 0)); - - addLabel(new GuiNpcLabel(203, "ability.outerWidth", col2LabelX, y + 5)); - GuiNpcTextField widthField = createFloatField(203, col2FieldX, y, 55, sweeper.getOuterColorWidth()); - widthField.setEnabled(sweeper.isOuterColorEnabled()); - addTextField(widthField); - } - - @Override - protected void handleTypeButton(int id, GuiNpcButton button) { - int value = button.getValue(); - switch (id) { - case 107: - sweeper.setPiercing(value == 1); - break; - case 108: - sweeper.setLockOnTarget(value == 1); - break; - case 150: - setSubGui(new SubGuiAbilityEffects(sweeper.getEffects())); - break; - } - } - - @Override - protected void handleVisualButton(int id, GuiNpcButton button) { - int value = button.getValue(); - switch (id) { - case 200: - editingVisualColorId = 200; - setSubGui(new SubGuiColorSelector(sweeper.getInnerColor())); - break; - case 201: - editingVisualColorId = 201; - setSubGui(new SubGuiColorSelector(sweeper.getOuterColor())); - break; - case 202: - sweeper.setOuterColorEnabled(value == 1); - initGui(); - break; - } - } - - @Override - public void subGuiClosed(SubGuiInterface subgui) { - if (subgui instanceof SubGuiColorSelector && editingVisualColorId != 0) { - SubGuiColorSelector colorSelector = (SubGuiColorSelector) subgui; - int rgb = colorSelector.color & 0x00FFFFFF; - if (editingVisualColorId == 200) { - sweeper.setInnerColor(rgb); - } else if (editingVisualColorId == 201) { - sweeper.setOuterColor(rgb); - } - 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); - } - } - - @Override - protected void handleTypeTextField(int id, GuiNpcTextField field) { - switch (id) { - case 100: - sweeper.setDamage(parseFloat(field, sweeper.getDamage())); - break; - case 101: - sweeper.setDamageInterval(field.getInteger()); - break; - case 102: - sweeper.setBeamLength(parseFloat(field, sweeper.getBeamLength())); - break; - case 103: - sweeper.setBeamWidth(parseFloat(field, sweeper.getBeamWidth())); - break; - case 104: - sweeper.setBeamHeight(parseFloat(field, sweeper.getBeamHeight())); - break; - case 105: - sweeper.setSweepSpeed(parseFloat(field, sweeper.getSweepSpeed())); - break; - case 106: - sweeper.setNumberOfRotations(field.getInteger()); - break; - } - } - - @Override - protected void handleVisualTextField(int id, GuiNpcTextField field) { - switch (id) { - case 203: - sweeper.setOuterColorWidth(parseFloat(field, sweeper.getOuterColorWidth())); - break; - } - } -} diff --git a/src/main/java/noppes/npcs/client/gui/advanced/ability/SubGuiAbilityTeleport.java b/src/main/java/noppes/npcs/client/gui/advanced/ability/SubGuiAbilityTeleport.java deleted file mode 100644 index 4b23b0ca0..000000000 --- a/src/main/java/noppes/npcs/client/gui/advanced/ability/SubGuiAbilityTeleport.java +++ /dev/null @@ -1,165 +0,0 @@ -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. - */ -public class SubGuiAbilityTeleport extends SubGuiAbilityConfig { - - private final AbilityTeleport teleport; - - public SubGuiAbilityTeleport(AbilityTeleport ability, IAbilityConfigCallback callback) { - super(ability, callback); - this.teleport = ability; - } - - @Override - protected void initTypeTab(int startY) { - int y = startY; - int labelX = guiLeft + 8; - int fieldX = guiLeft + 85; - int col2LabelX = guiLeft + 145; - int col2FieldX = guiLeft + 205; - - // Row 1: Mode - addLabel(new GuiNpcLabel(100, "ability.mode", labelX, y + 5)); - String[] modes = {"Blink", "Behind", "Single"}; - addButton(new GuiNpcButton(100, fieldX, y, 80, 20, modes, teleport.getModeEnum().ordinal())); - - y += 24; - - switch (teleport.getModeEnum()) { - case BLINK: - // Row 2: Blink Radius + Blink Count - addLabel(new GuiNpcLabel(101, "ability.blinkRadius", labelX, y + 5)); - addTextField(createFloatField(101, fieldX, y, 50, teleport.getBlinkRadius())); - - addLabel(new GuiNpcLabel(102, "ability.blinkCount", col2LabelX, y + 5)); - addTextField(createIntField(102, col2FieldX, y, 50, teleport.getBlinkCount())); - - y += 24; - - // Row 3: Blink Delay + Line of Sight - addLabel(new GuiNpcLabel(103, "ability.blinkDelay", labelX, y + 5)); - addTextField(createIntField(103, fieldX, y, 50, teleport.getBlinkDelayTicks())); - - addLabel(new GuiNpcLabel(105, "ability.lineOfSight", col2LabelX, y + 5)); - 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: - // Row 2: Blink Radius + Line of Sight - addLabel(new GuiNpcLabel(101, "ability.blinkRadius", labelX, y + 5)); - addTextField(createFloatField(101, fieldX, y, 50, teleport.getBlinkRadius())); - - addLabel(new GuiNpcLabel(105, "ability.lineOfSight", col2LabelX, y + 5)); - 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: - // Row 2: Behind Distance - addLabel(new GuiNpcLabel(104, "ability.behindDistance", labelX, y + 5)); - addTextField(createFloatField(104, fieldX, y, 50, teleport.getBehindDistance())); - y += 24; - break; - } - - // Damage + Damage Radius - addLabel(new GuiNpcLabel(106, "enchantment.damage", labelX, y + 5)); - addTextField(createFloatField(106, fieldX, y, 50, teleport.getDamage())); - - addLabel(new GuiNpcLabel(107, "ability.dmgRadius", col2LabelX, y + 5)); - addTextField(createFloatField(107, col2FieldX, y, 50, teleport.getDamageRadius())); - - y += 24; - - // Damage at Start/End - addLabel(new GuiNpcLabel(108, "ability.dmgAtStart", labelX, y + 5)); - 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)); - 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; - - // Effects button - addButton(new GuiNpcButton(150, labelX, y, 80, 20, "ability.effects")); - } - - @Override - protected void handleTypeButton(int id, GuiNpcButton button) { - int value = button.getValue(); - switch (id) { - case 100: - teleport.setModeEnum(AbilityTeleport.TeleportMode.values()[value]); - initGui(); - break; - case 105: - teleport.setRequireLineOfSight(value == 1); - break; - case 108: - teleport.setDamageAtStart(value == 1); - break; - case 109: - teleport.setDamageAtEnd(value == 1); - break; - 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); - } - } - } - - @Override - protected void handleTypeTextField(int id, GuiNpcTextField field) { - switch (id) { - case 101: - teleport.setBlinkRadius(parseFloat(field, teleport.getBlinkRadius())); - break; - case 102: - teleport.setBlinkCount(field.getInteger()); - break; - case 103: - teleport.setBlinkDelayTicks(field.getInteger()); - break; - case 104: - teleport.setBehindDistance(parseFloat(field, teleport.getBehindDistance())); - break; - case 106: - teleport.setDamage(parseFloat(field, teleport.getDamage())); - break; - case 107: - teleport.setDamageRadius(parseFloat(field, teleport.getDamageRadius())); - break; - } - } -} diff --git a/src/main/java/noppes/npcs/client/gui/advanced/ability/SubGuiAbilityTrap.java b/src/main/java/noppes/npcs/client/gui/advanced/ability/SubGuiAbilityTrap.java deleted file mode 100644 index 5c9c52558..000000000 --- a/src/main/java/noppes/npcs/client/gui/advanced/ability/SubGuiAbilityTrap.java +++ /dev/null @@ -1,126 +0,0 @@ -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. - */ -public class SubGuiAbilityTrap extends SubGuiAbilityConfig { - - private final AbilityTrap trap; - - public SubGuiAbilityTrap(AbilityTrap ability, IAbilityConfigCallback callback) { - super(ability, callback); - this.trap = ability; - } - - @Override - protected void initTypeTab(int startY) { - int y = startY; - int labelX = guiLeft + 8; - int fieldX = guiLeft + 85; - int col2LabelX = guiLeft + 145; - int col2FieldX = guiLeft + 205; - - // Row 1: Duration + Placement - addLabel(new GuiNpcLabel(99, "ability.duration", labelX, y + 5)); - GuiNpcTextField durationField = createIntField(99, fieldX, y, 50, trap.getDurationTicks()); - durationField.setMinMaxDefault(1, 2000, 200); - addTextField(durationField); - - addLabel(new GuiNpcLabel(100, "ability.placement", col2LabelX, y + 5)); - String[] placements = {"Caster", "Target", "Ahead"}; - GuiNpcButton placementBtn = new GuiNpcButton(100, col2FieldX, y, 55, 20, placements, trap.getPlacementEnum().ordinal()); - placementBtn.setHoverText("ability.hover.placement"); - addButton(placementBtn); - - y += 24; - - // Row 2: Trigger Radius - addLabel(new GuiNpcLabel(101, "ability.triggerRad", labelX, y + 5)); - addTextField(createFloatField(101, fieldX, y, 50, trap.getTriggerRadius())); - - y += 24; - - // Row 2: Damage + Damage Radius - addLabel(new GuiNpcLabel(102, "enchantment.damage", labelX, y + 5)); - addTextField(createFloatField(102, fieldX, y, 50, trap.getDamage())); - - addLabel(new GuiNpcLabel(103, "ability.dmgRadius", col2LabelX, y + 5)); - addTextField(createFloatField(103, col2FieldX, y, 50, trap.getDamageRadius())); - - y += 24; - - // Row 3: Arm Time + Max Triggers - addLabel(new GuiNpcLabel(104, "ability.armTime", labelX, y + 5)); - addTextField(createIntField(104, fieldX, y, 50, trap.getArmTime())); - - addLabel(new GuiNpcLabel(105, "ability.maxTriggers", col2LabelX, y + 5)); - addTextField(createIntField(105, col2FieldX, y, 50, trap.getMaxTriggers())); - - y += 24; - - // 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.setPlacementEnum(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); - } - } - } - - @Override - protected void handleTypeTextField(int id, GuiNpcTextField field) { - switch (id) { - case 99: - trap.setDurationTicks(field.getInteger()); - break; - case 101: - trap.setTriggerRadius(parseFloat(field, trap.getTriggerRadius())); - break; - case 102: - trap.setDamage(parseFloat(field, trap.getDamage())); - break; - case 103: - trap.setDamageRadius(parseFloat(field, trap.getDamageRadius())); - break; - case 104: - trap.setArmTime(field.getInteger()); - break; - case 105: - trap.setMaxTriggers(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 deleted file mode 100644 index b56828470..000000000 --- a/src/main/java/noppes/npcs/client/gui/advanced/ability/SubGuiAbilityVortex.java +++ /dev/null @@ -1,129 +0,0 @@ -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. - */ -public class SubGuiAbilityVortex extends SubGuiAbilityConfig { - - private final AbilityVortex vortex; - - public SubGuiAbilityVortex(AbilityVortex ability, IAbilityConfigCallback callback) { - super(ability, callback); - this.vortex = ability; - } - - @Override - protected void initTypeTab(int startY) { - int y = startY; - int labelX = guiLeft + 8; - int fieldX = guiLeft + 85; - int col2LabelX = guiLeft + 145; - int col2FieldX = guiLeft + 205; - - // Row 1: Pull Radius + Pull Strength - addLabel(new GuiNpcLabel(100, "ability.pullRadius", labelX, y + 5)); - addTextField(createFloatField(100, fieldX, y, 50, vortex.getPullRadius())); - - addLabel(new GuiNpcLabel(101, "ability.pullStrength", col2LabelX, y + 5)); - addTextField(createFloatField(101, col2FieldX, y, 50, vortex.getPullStrength())); - - y += 24; - - // Row 2: Damage + Knockback - addLabel(new GuiNpcLabel(102, "enchantment.damage", labelX, y + 5)); - addTextField(createFloatField(102, fieldX, y, 50, vortex.getDamage())); - - addLabel(new GuiNpcLabel(103, "ability.knockback", col2LabelX, y + 5)); - addTextField(createFloatField(103, col2FieldX, y, 50, vortex.getKnockback())); - - y += 24; - - // Row 3: AOE + Max Targets - addLabel(new GuiNpcLabel(104, "ability.aoe", labelX, y + 5)); - 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())); - - y += 24; - - // Row 4: Effects button - addButton(new GuiNpcButton(150, labelX, y, 80, 20, "ability.effects")); - - y += 24; - - // Row 5: Damage on Pull + Pull Damage - addLabel(new GuiNpcLabel(108, "ability.dmgOnPull", labelX, y + 5)); - 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())); - } - - @Override - protected void handleTypeButton(int id, GuiNpcButton button) { - int value = button.getValue(); - switch (id) { - case 104: - vortex.setAoe(value == 1); - break; - 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); - } - } - } - - @Override - protected void handleTypeTextField(int id, GuiNpcTextField field) { - switch (id) { - case 100: - vortex.setPullRadius(parseFloat(field, vortex.getPullRadius())); - break; - case 101: - vortex.setPullStrength(parseFloat(field, vortex.getPullStrength())); - break; - case 102: - vortex.setDamage(parseFloat(field, vortex.getDamage())); - break; - case 103: - vortex.setKnockback(parseFloat(field, vortex.getKnockback())); - break; - case 105: - vortex.setMaxTargets(field.getInteger()); - break; - case 109: - vortex.setPullDamage(parseFloat(field, vortex.getPullDamage())); - break; - } - } -}