Fix to Type Tab

This commit is contained in:
Kam committed 2026-02-02 20:40:17 -05:00
1 parent 0cbc30f8cb
commit d3167df1b9
36 files changed
+648 -589

No files matched your search

@@ -29,9 +29,8 @@ import noppes.npcs.scripted.NpcAPI;
import noppes.npcs.scripted.event.AbilityEvent;
import noppes.npcs.scripted.event.player.PlayerAbilityEvent;
import kamkeel.npcs.controllers.data.ability.gui.ColumnHint;
import kamkeel.npcs.controllers.data.ability.gui.FieldDef;
import kamkeel.npcs.controllers.data.ability.gui.TabTarget;
import noppes.npcs.client.gui.builder.ColumnHint;
import noppes.npcs.client.gui.builder.FieldDef;
import java.util.ArrayList;
import java.util.Collections;
@@ -40,18 +39,14 @@ import java.util.List;
import net.minecraft.entity.Entity;
import somehussar.gui.annotationHandling.GuiEditable;
@GuiEditable
public abstract class Ability implements IAbility {
// ═══════════════════════════════════════════════════════════════════
// CONFIGURATION (saved to NBT)
// ═══════════════════════════════════════════════════════════════════
@GuiEditable.Field("id")
protected String id;
@GuiEditable.Field("name")
protected String name;
@GuiEditable.Field("test")
protected String typeId; // e.g., "ability.cnpc.slam" (also used as lang key)
// Selection
@@ -352,6 +347,7 @@ public abstract class Ability implements IAbility {
* The GUI rendering engine in SubGuiAbilityConfig uses this list to
* automatically build the Type and Visual tabs.
*/
@SideOnly(Side.CLIENT)
public List<FieldDef> getFieldDefinitions() {
return Collections.emptyList();
}
@@ -365,24 +361,24 @@ public abstract class Ability implements IAbility {
// General tab
defs.add(FieldDef.stringField("gui.name", this::getName, this::setName)
.tab(TabTarget.GENERAL));
.tab("General"));
defs.add(FieldDef.intField("ability.weight", this::getWeight, this::setWeight)
.tab(TabTarget.GENERAL).range(1, 1000).column(ColumnHint.LEFT));
.tab("General").range(1, 1000).column(ColumnHint.LEFT));
defs.add(FieldDef.boolField("gui.enabled", this::isEnabled, this::setEnabled)
.tab(TabTarget.GENERAL).column(ColumnHint.RIGHT));
defs.add(FieldDef.section("ability.section.timing").tab(TabTarget.GENERAL));
.tab("General").column(ColumnHint.RIGHT));
defs.add(FieldDef.section("ability.section.timing").tab("General"));
defs.add(FieldDef.intField("ability.windUpTicks", this::getRawWindUpTicks, this::setWindUpTicks)
.tab(TabTarget.GENERAL).range(0, 1000).column(ColumnHint.LEFT)
.visibleWhen(() -> !isSyncWindupWithAnimation()));
.tab("General").range(0, 1000).column(ColumnHint.LEFT)
.visibleWhen(() -> !hasWindUpAnimation() || !isSyncWindupWithAnimation()));
defs.add(FieldDef.labelField("ability.windUpTicks", () -> getWindUpTicks() + "t")
.tab(TabTarget.GENERAL).column(ColumnHint.LEFT)
.visibleWhen(this::isSyncWindupWithAnimation));
.tab("General").column(ColumnHint.LEFT)
.visibleWhen(() -> hasWindUpAnimation() && isSyncWindupWithAnimation()));
defs.add(FieldDef.boolField("ability.syncWindup", this::isSyncWindupWithAnimation, this::setSyncWindupWithAnimation)
.tab(TabTarget.GENERAL).hover("ability.hover.sync").column(ColumnHint.RIGHT)
.tab("General").hover("ability.hover.sync").column(ColumnHint.RIGHT)
.visibleWhen(this::hasWindUpAnimation));
defs.add(FieldDef.intField("ability.cooldownTicks", this::getCooldownTicks, this::setCooldownTicks)
.tab(TabTarget.GENERAL).range(0, 10000));
defs.add(FieldDef.section("ability.section.movement").tab(TabTarget.GENERAL));
.tab("General").range(0, 10000));
defs.add(FieldDef.section("ability.section.movement").tab("General"));
defs.add(FieldDef.stringEnumField("ability.lockMovement", LockMovementType.getDisplayKeys(),
() -> this.getLockMovement().getDisplayKey(),
v -> {
@@ -391,52 +387,52 @@ public abstract class Ability implements IAbility {
if (keys[i].equals(v)) { this.setLockMovement(LockMovementType.fromOrdinal(i)); break; }
}
})
.tab(TabTarget.GENERAL).hover("ability.hover.lockMove"));
.tab("General").hover("ability.hover.lockMove"));
defs.add(FieldDef.boolField("ability.interruptible", this::isInterruptible, this::setInterruptible)
.tab(TabTarget.GENERAL).hover("ability.hover.interruptible").column(ColumnHint.LEFT));
.tab("General").hover("ability.hover.interruptible").column(ColumnHint.LEFT));
defs.add(FieldDef.intField("ability.dazedTicks", this::getDazedTicks, this::setDazedTicks)
.tab(TabTarget.GENERAL).range(0, 1000)
.tab("General").range(0, 1000)
.visibleWhen(this::isInterruptible).column(ColumnHint.RIGHT));
// Target tab
defs.add(FieldDef.intField("ability.minRange", () -> (int) getMinRange(), v -> setMinRange(v))
.tab(TabTarget.TARGET).range(0, 100).column(ColumnHint.LEFT));
.tab("Target").range(0, 100).column(ColumnHint.LEFT));
defs.add(FieldDef.intField("ability.maxRange", () -> (int) getMaxRange(), v -> setMaxRange(v))
.tab(TabTarget.TARGET).range(1, 100).column(ColumnHint.RIGHT));
.tab("Target").range(1, 100).column(ColumnHint.RIGHT));
if (!isTargetingModeLocked()) {
defs.add(FieldDef.enumField("ability.targetingMode", TargetingMode.class,
this::getTargetingMode, this::setTargetingMode)
.tab(TabTarget.TARGET).hover("ability.hover.targeting"));
.tab("Target").hover("ability.hover.targeting"));
}
// Effects tab - Sounds
defs.add(FieldDef.section("ability.section.sounds").tab(TabTarget.EFFECTS));
defs.add(FieldDef.section("ability.section.sounds").tab("Effects"));
defs.add(FieldDef.soundSubGui("ability.windUpSound", this::getWindUpSound, this::setWindUpSound)
.tab(TabTarget.EFFECTS));
.tab("Effects"));
defs.add(FieldDef.soundSubGui("ability.activeSound", this::getActiveSound, this::setActiveSound)
.tab(TabTarget.EFFECTS));
.tab("Effects"));
// Effects tab - Animations
defs.add(FieldDef.section("ability.section.animations").tab(TabTarget.EFFECTS));
defs.add(FieldDef.section("ability.section.animations").tab("Effects"));
defs.add(FieldDef.animSubGui("ability.windUpAnimation",
this::getWindUpAnimationId, this::setWindUpAnimationId,
this::getWindUpAnimationName, this::setWindUpAnimationName)
.tab(TabTarget.EFFECTS));
.tab("Effects"));
defs.add(FieldDef.animSubGui("ability.activeAnimation",
this::getActiveAnimationId, this::setActiveAnimationId,
this::getActiveAnimationName, this::setActiveAnimationName)
.tab(TabTarget.EFFECTS));
.tab("Effects"));
// Effects tab - Telegraph
TelegraphType tType = getTelegraphType();
if (tType != null && tType != TelegraphType.NONE) {
defs.add(FieldDef.section("ability.section.telegraph").tab(TabTarget.EFFECTS)
defs.add(FieldDef.section("ability.section.telegraph").tab("Effects")
.tooltip("telegraph." + tType.name().toLowerCase()));
defs.add(FieldDef.boolField("ability.showTelegraph", this::isShowTelegraph, this::setShowTelegraph)
.tab(TabTarget.EFFECTS).hover("ability.hover.showTelegraph"));
.tab("Effects").hover("ability.hover.showTelegraph"));
defs.add(FieldDef.colorSubGui("ability.windUpColor", this::getWindUpColor, this::setWindUpColor)
.tab(TabTarget.EFFECTS).visibleWhen(this::isShowTelegraph));
.tab("Effects").visibleWhen(this::isShowTelegraph));
defs.add(FieldDef.colorSubGui("ability.activeColor", this::getActiveColor, this::setActiveColor)
.tab(TabTarget.EFFECTS).visibleWhen(this::isShowTelegraph));
.tab("Effects").visibleWhen(this::isShowTelegraph));
}
return defs;
@@ -448,26 +444,17 @@ public abstract class Ability implements IAbility {
@SideOnly(Side.CLIENT)
public final List<FieldDef> getAllFieldDefinitions() {
List<FieldDef> all = new ArrayList<>(getBaseFieldDefinitions());
all.addAll(getFieldDefinitions());
List<FieldDef> typeDefs = getFieldDefinitions();
// Default tab for type-specific fields that don't explicitly set one
for (FieldDef def : typeDefs) {
if (def.getTab() == null) {
def.tab("Type");
}
}
all.addAll(typeDefs);
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.
*/
public boolean hasTypeSettings() {
return false;
}
/**
* Get the number of rows needed for type-specific settings in the GUI.
* Each row is approximately 24 pixels. Used for GUI layout.
*/
public int getTypeSettingsRowCount() {
return 0;
}
/**
* Creates the GUI for configuring this ability.
* Override this method to provide a custom GUI subclass for type-specific settings.
@@ -0,0 +1,115 @@
package kamkeel.npcs.controllers.data.ability.gui;
import cpw.mods.fml.relauncher.Side;
import cpw.mods.fml.relauncher.SideOnly;
import kamkeel.npcs.controllers.data.ability.AbilityEffect;
import net.minecraft.client.gui.FontRenderer;
import noppes.npcs.client.gui.builder.FieldDef;
import noppes.npcs.client.gui.builder.FieldType;
import noppes.npcs.client.gui.builder.GuiFieldBuilder;
import noppes.npcs.client.gui.util.GuiNPCInterface;
import noppes.npcs.client.gui.util.GuiNpcButton;
import noppes.npcs.client.gui.util.GuiNpcLabel;
import noppes.npcs.client.gui.util.GuiNpcTextField;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* Ability-specific extension of {@link GuiFieldBuilder} that handles
* the EFFECTS_LIST field type.
*/
@SideOnly(Side.CLIENT)
public class AbilityFieldBuilder extends GuiFieldBuilder {
// Effects list metadata: widgetId -> [effectIndex, action]
// action: 0=type, 1=duration(text), 2=amp, 3=delete, 4=add
private final Map<Integer, int[]> effectWidgetMeta = new HashMap<>();
public AbilityFieldBuilder(GuiNPCInterface parent, FontRenderer fontRenderer) {
super(parent, fontRenderer);
}
@Override
protected int build(List<FieldDef> fields) {
effectWidgetMeta.clear();
return super.build(fields);
}
@Override
protected int buildField(FieldDef def, int y, List<FieldDef> fields, int index) {
if (def.getType() == FieldType.EFFECTS_LIST) {
return renderEffectsList(def, y);
}
return -1; // not handled
}
@SuppressWarnings("unchecked")
private int renderEffectsList(FieldDef def, int y) {
// Section header
y += 3;
sw.addLabel(new GuiNpcLabel(labelId++, def.getLabel(), colLLabel, y + 2, 0xFFFF55));
y += 15;
List<AbilityEffect> effects = (List<AbilityEffect>) def.getValue();
if (effects == null) effects = new ArrayList<>();
String[] typeNames = AbilityEffect.EffectType.getLangKeys();
String[] ampValues = {"0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "10"};
for (int e = 0; e < effects.size() && e < 5; e++) {
AbilityEffect effect = effects.get(e);
// Type selector button
int typeIdx = effect.getType().ordinal();
GuiNpcButton typeBtn = new GuiNpcButton(widgetId, colLLabel, y, 100, 20, typeNames, typeIdx);
sw.addButton(typeBtn);
buttonFieldMap.put(widgetId, def);
effectWidgetMeta.put(widgetId, new int[]{e, 0});
widgetId++;
// Duration text field
GuiNpcTextField durField = new GuiNpcTextField(widgetId, parent, fontRenderer,
colLLabel + 104, y, 50, 20, String.valueOf(effect.getDurationTicks()));
durField.setIntegersOnly();
durField.setMinMaxDefault(1, 12000, 60);
sw.addTextField(durField);
textFieldMap.put(widgetId, def);
effectWidgetMeta.put(widgetId, new int[]{e, 1});
widgetId++;
// Amplifier selector (0-10)
GuiNpcButton ampBtn = new GuiNpcButton(widgetId, colLLabel + 158, y, 40, 20, ampValues, effect.getAmplifier());
sw.addButton(ampBtn);
buttonFieldMap.put(widgetId, def);
effectWidgetMeta.put(widgetId, new int[]{e, 2});
widgetId++;
// Delete button
GuiNpcButton delBtn = new GuiNpcButton(clearId, colLLabel + 202, y, 20, 20, "X");
sw.addButton(delBtn);
clearFieldMap.put(clearId, def);
effectWidgetMeta.put(clearId, new int[]{e, 3});
clearId++;
y += rowHeight;
}
// Add button (if < 5 effects)
if (effects.size() < 5) {
GuiNpcButton addBtn = new GuiNpcButton(widgetId, colLLabel, y, 50, 20, "gui.add");
sw.addButton(addBtn);
buttonFieldMap.put(widgetId, def);
effectWidgetMeta.put(widgetId, new int[]{effects.size(), 4});
widgetId++;
clearId++;
y += rowHeight;
}
return y;
}
public Map<Integer, int[]> getEffectWidgetMeta() { return effectWidgetMeta; }
}
@@ -0,0 +1,26 @@
package kamkeel.npcs.controllers.data.ability.gui;
import cpw.mods.fml.relauncher.Side;
import cpw.mods.fml.relauncher.SideOnly;
import kamkeel.npcs.controllers.data.ability.AbilityEffect;
import noppes.npcs.client.gui.builder.FieldDef;
import noppes.npcs.client.gui.builder.FieldType;
import java.util.List;
import java.util.function.Consumer;
import java.util.function.Supplier;
/**
* Ability-specific FieldDef factories. These create FieldDef instances
* with types that require ability-specific rendering (e.g. EFFECTS_LIST).
*/
@SideOnly(Side.CLIENT)
public class AbilityFieldDefs {
@SuppressWarnings("unchecked")
public static FieldDef effectsListField(String label, Supplier<List<AbilityEffect>> getter, Consumer<List<AbilityEffect>> setter) {
return FieldDef.custom(label, FieldType.EFFECTS_LIST,
() -> getter.get(),
v -> setter.accept((List<AbilityEffect>) v));
}
}
@@ -1,7 +0,0 @@
package kamkeel.npcs.controllers.data.ability.gui;
public enum ColumnHint {
FULL,
LEFT,
RIGHT
}
@@ -1,28 +0,0 @@
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();
}
}
@@ -1,9 +0,0 @@
package kamkeel.npcs.controllers.data.ability.gui;
public enum TabTarget {
GENERAL,
TYPE,
TARGET,
EFFECTS,
CUSTOM
}
@@ -7,8 +7,9 @@ import kamkeel.npcs.controllers.data.ability.AnchorPoint;
import kamkeel.npcs.controllers.data.ability.LockMovementType;
import kamkeel.npcs.controllers.data.ability.TargetingMode;
import kamkeel.npcs.controllers.data.ability.data.*;
import kamkeel.npcs.controllers.data.ability.gui.ColumnHint;
import kamkeel.npcs.controllers.data.ability.gui.FieldDef;
import noppes.npcs.client.gui.builder.ColumnHint;
import noppes.npcs.client.gui.builder.FieldDef;
import kamkeel.npcs.controllers.data.ability.gui.AbilityFieldDefs;
import kamkeel.npcs.controllers.data.telegraph.Telegraph;
import kamkeel.npcs.controllers.data.telegraph.TelegraphInstance;
import kamkeel.npcs.controllers.data.telegraph.TelegraphType;
@@ -66,11 +67,6 @@ public class AbilityBeamDual extends Ability {
this.activeAnimationName = "Ability_BeamDual_Active";
}
@Override
public boolean hasTypeSettings() {
return true;
}
@Override
public boolean isTargetingModeLocked() {
return true;
@@ -380,6 +376,7 @@ public class AbilityBeamDual extends Ability {
public void setAnchorPoint(int beam, int point) { getAnchorData(beam).anchorPoint = AnchorPoint.fromOrdinal(point); }
public void setAnchorPoint(int point) { getAnchorData(0).anchorPoint = AnchorPoint.fromOrdinal(point); }
@SideOnly(Side.CLIENT)
@Override
public List<FieldDef> getFieldDefinitions() {
return Arrays.asList(
@@ -408,71 +405,71 @@ public class AbilityBeamDual extends Ability {
.hover("ability.hover.explosive"),
FieldDef.floatField("gui.radius", this::getExplosionRadius, this::setExplosionRadius)
.visibleWhen(this::isExplosive),
FieldDef.effectsListField("ability.effects", this::getEffects, this::setEffects),
AbilityFieldDefs.effectsListField("ability.effects", this::getEffects, this::setEffects),
// Visual tab - Beam 1
FieldDef.enumField("ability.anchorPoint", AnchorPoint.class,
() -> getAnchorPointEnum(0), v -> setAnchorPointEnum(0, v))
.customTab("ability.tab.visual"),
FieldDef.section("ability.section.beam1").customTab("ability.tab.visual"),
.tab("ability.tab.visual"),
FieldDef.section("ability.section.beam1").tab("ability.tab.visual"),
FieldDef.colorSubGui("ability.innerColor",
() -> getInnerColor(0), v -> setInnerColor(0, v))
.customTab("ability.tab.visual"),
.tab("ability.tab.visual"),
FieldDef.boolField("ability.outerEnabled",
() -> isOuterColorEnabled(0), v -> setOuterColorEnabled(0, v))
.customTab("ability.tab.visual"),
.tab("ability.tab.visual"),
FieldDef.colorSubGui("ability.outerColor",
() -> getOuterColor(0), v -> setOuterColor(0, v))
.customTab("ability.tab.visual").visibleWhen(() -> isOuterColorEnabled(0)),
.tab("ability.tab.visual").visibleWhen(() -> isOuterColorEnabled(0)),
FieldDef.floatField("ability.outerWidth",
() -> getOuterColorWidth(0), v -> setOuterColorWidth(0, v))
.customTab("ability.tab.visual").visibleWhen(() -> isOuterColorEnabled(0)).column(ColumnHint.LEFT),
.tab("ability.tab.visual").visibleWhen(() -> isOuterColorEnabled(0)).column(ColumnHint.LEFT),
FieldDef.floatField("ability.outerAlpha",
() -> getOuterColorAlpha(0), v -> setOuterColorAlpha(0, v))
.customTab("ability.tab.visual").range(0, 1).visibleWhen(() -> isOuterColorEnabled(0)).column(ColumnHint.RIGHT),
.tab("ability.tab.visual").range(0, 1).visibleWhen(() -> isOuterColorEnabled(0)).column(ColumnHint.RIGHT),
FieldDef.floatField("ability.rotationSpeed",
() -> getRotationSpeed(0), v -> setRotationSpeed(0, v))
.customTab("ability.tab.visual"),
.tab("ability.tab.visual"),
FieldDef.boolField("ability.lightning",
() -> hasLightningEffect(0), v -> setLightningEffect(0, v))
.customTab("ability.tab.visual"),
.tab("ability.tab.visual"),
FieldDef.floatField("gui.density",
() -> getLightningDensity(0), v -> setLightningDensity(0, v))
.customTab("ability.tab.visual").range(0.01f, 5.0f).visibleWhen(() -> hasLightningEffect(0)).column(ColumnHint.LEFT),
.tab("ability.tab.visual").range(0.01f, 5.0f).visibleWhen(() -> hasLightningEffect(0)).column(ColumnHint.LEFT),
FieldDef.floatField("gui.radius",
() -> getLightningRadius(0), v -> setLightningRadius(0, v))
.customTab("ability.tab.visual").range(0.1f, 10.0f).visibleWhen(() -> hasLightningEffect(0)).column(ColumnHint.RIGHT),
.tab("ability.tab.visual").range(0.1f, 10.0f).visibleWhen(() -> hasLightningEffect(0)).column(ColumnHint.RIGHT),
// Visual tab - Beam 2
FieldDef.enumField("ability.anchorPoint", AnchorPoint.class,
() -> getAnchorPointEnum(1), v -> setAnchorPointEnum(1, v))
.customTab("ability.tab.visual"),
FieldDef.section("ability.section.beam2").customTab("ability.tab.visual"),
.tab("ability.tab.visual"),
FieldDef.section("ability.section.beam2").tab("ability.tab.visual"),
FieldDef.colorSubGui("ability.innerColor",
() -> getInnerColor(1), v -> setInnerColor(1, v))
.customTab("ability.tab.visual"),
.tab("ability.tab.visual"),
FieldDef.boolField("ability.outerEnabled",
() -> isOuterColorEnabled(1), v -> setOuterColorEnabled(1, v))
.customTab("ability.tab.visual"),
.tab("ability.tab.visual"),
FieldDef.colorSubGui("ability.outerColor",
() -> getOuterColor(1), v -> setOuterColor(1, v))
.customTab("ability.tab.visual").visibleWhen(() -> isOuterColorEnabled(1)),
.tab("ability.tab.visual").visibleWhen(() -> isOuterColorEnabled(1)),
FieldDef.floatField("ability.outerWidth",
() -> getOuterColorWidth(1), v -> setOuterColorWidth(1, v))
.customTab("ability.tab.visual").visibleWhen(() -> isOuterColorEnabled(1)).column(ColumnHint.LEFT),
.tab("ability.tab.visual").visibleWhen(() -> isOuterColorEnabled(1)).column(ColumnHint.LEFT),
FieldDef.floatField("ability.outerAlpha",
() -> getOuterColorAlpha(1), v -> setOuterColorAlpha(1, v))
.customTab("ability.tab.visual").range(0, 1).visibleWhen(() -> isOuterColorEnabled(1)).column(ColumnHint.RIGHT),
.tab("ability.tab.visual").range(0, 1).visibleWhen(() -> isOuterColorEnabled(1)).column(ColumnHint.RIGHT),
FieldDef.floatField("ability.rotationSpeed",
() -> getRotationSpeed(1), v -> setRotationSpeed(1, v))
.customTab("ability.tab.visual"),
.tab("ability.tab.visual"),
FieldDef.boolField("ability.lightning",
() -> hasLightningEffect(1), v -> setLightningEffect(1, v))
.customTab("ability.tab.visual"),
.tab("ability.tab.visual"),
FieldDef.floatField("gui.density",
() -> getLightningDensity(1), v -> setLightningDensity(1, v))
.customTab("ability.tab.visual").range(0.01f, 5.0f).visibleWhen(() -> hasLightningEffect(1)).column(ColumnHint.LEFT),
.tab("ability.tab.visual").range(0.01f, 5.0f).visibleWhen(() -> hasLightningEffect(1)).column(ColumnHint.LEFT),
FieldDef.floatField("gui.radius",
() -> getLightningRadius(1), v -> setLightningRadius(1, v))
.customTab("ability.tab.visual").range(0.1f, 10.0f).visibleWhen(() -> hasLightningEffect(1)).column(ColumnHint.RIGHT)
.tab("ability.tab.visual").range(0.1f, 10.0f).visibleWhen(() -> hasLightningEffect(1)).column(ColumnHint.RIGHT)
);
}
@@ -16,9 +16,9 @@ import net.minecraft.util.Vec3;
import net.minecraft.world.World;
import noppes.npcs.entity.EntityNPCInterface;
import kamkeel.npcs.controllers.data.ability.gui.ColumnHint;
import kamkeel.npcs.controllers.data.ability.gui.FieldDef;
import kamkeel.npcs.controllers.data.ability.gui.TabTarget;
import noppes.npcs.client.gui.builder.ColumnHint;
import noppes.npcs.client.gui.builder.FieldDef;
import kamkeel.npcs.controllers.data.ability.gui.AbilityFieldDefs;
import noppes.npcs.api.ability.type.IAbilityCharge;
import java.util.Arrays;
@@ -59,11 +59,6 @@ public class AbilityCharge extends Ability implements IAbilityCharge {
this.activeSound = "mob.zombie.attack";
}
@Override
public boolean hasTypeSettings() {
return true;
}
@Override
public boolean isTargetingModeLocked() {
return true;
@@ -401,6 +396,7 @@ public class AbilityCharge extends Ability implements IAbilityCharge {
this.hitWidth = hitWidth;
}
@SideOnly(Side.CLIENT)
@Override
public List<FieldDef> getFieldDefinitions() {
return Arrays.asList(
@@ -408,7 +404,7 @@ public class AbilityCharge extends Ability implements IAbilityCharge {
FieldDef.floatField("ability.chargeSpeed", this::getChargeSpeed, this::setChargeSpeed).column(ColumnHint.RIGHT),
FieldDef.floatField("ability.knockback", this::getKnockback, this::setKnockback).column(ColumnHint.LEFT),
FieldDef.floatField("ability.hitWidth", this::getHitWidth, this::setHitWidth).column(ColumnHint.RIGHT),
FieldDef.effectsListField("ability.effects", this::getEffects, this::setEffects)
AbilityFieldDefs.effectsListField("ability.effects", this::getEffects, this::setEffects)
);
}
}
@@ -13,9 +13,12 @@ import noppes.npcs.entity.EntityNPCInterface;
import noppes.npcs.api.ability.type.IAbilityCutter;
import kamkeel.npcs.controllers.data.ability.gui.ColumnHint;
import kamkeel.npcs.controllers.data.ability.gui.FieldDef;
import kamkeel.npcs.controllers.data.ability.gui.TabTarget;
import noppes.npcs.client.gui.builder.ColumnHint;
import noppes.npcs.client.gui.builder.FieldDef;
import kamkeel.npcs.controllers.data.ability.gui.AbilityFieldDefs;
import cpw.mods.fml.relauncher.Side;
import cpw.mods.fml.relauncher.SideOnly;
import java.util.Arrays;
import java.util.HashSet;
@@ -74,11 +77,6 @@ public class AbilityCutter extends Ability implements IAbilityCutter {
this.activeAnimationName = "Ability_Cutter_Active";
}
@Override
public boolean hasTypeSettings() {
return true;
}
@Override
public boolean isTargetingModeLocked() {
return true;
@@ -317,6 +315,7 @@ public class AbilityCutter extends Ability implements IAbilityCutter {
return currentRotation;
}
@SideOnly(Side.CLIENT)
@Override
public List<FieldDef> getFieldDefinitions() {
return Arrays.asList(
@@ -334,7 +333,7 @@ public class AbilityCutter extends Ability implements IAbilityCutter {
.visibleWhen(() -> this.getSweepModeEnum() == SweepMode.SPIN),
FieldDef.boolField("ability.piercing", this::isPiercing, this::setPiercing)
.hover("ability.hover.piercing"),
FieldDef.effectsListField("ability.effects", this::getEffects, this::setEffects)
AbilityFieldDefs.effectsListField("ability.effects", this::getEffects, this::setEffects)
);
}
}
@@ -14,9 +14,8 @@ import net.minecraft.util.Vec3;
import net.minecraft.world.World;
import noppes.npcs.entity.EntityNPCInterface;
import kamkeel.npcs.controllers.data.ability.gui.ColumnHint;
import kamkeel.npcs.controllers.data.ability.gui.FieldDef;
import kamkeel.npcs.controllers.data.ability.gui.TabTarget;
import noppes.npcs.client.gui.builder.ColumnHint;
import noppes.npcs.client.gui.builder.FieldDef;
import noppes.npcs.api.ability.type.IAbilityDash;
import java.util.Arrays;
@@ -112,11 +111,6 @@ public class AbilityDash extends Ability implements IAbilityDash {
this.activeSound = "mob.endermen.portal";
}
@Override
public boolean hasTypeSettings() {
return true;
}
@Override
public boolean isTargetingModeLocked() {
return true;
@@ -356,6 +350,7 @@ public class AbilityDash extends Ability implements IAbilityDash {
return chosenDirection;
}
@SideOnly(Side.CLIENT)
@Override
public List<FieldDef> getFieldDefinitions() {
return Arrays.asList(
@@ -17,8 +17,9 @@ import net.minecraft.entity.EntityLivingBase;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.util.Vec3;
import net.minecraft.world.World;
import kamkeel.npcs.controllers.data.ability.gui.ColumnHint;
import kamkeel.npcs.controllers.data.ability.gui.FieldDef;
import noppes.npcs.client.gui.builder.ColumnHint;
import noppes.npcs.client.gui.builder.FieldDef;
import kamkeel.npcs.controllers.data.ability.gui.AbilityFieldDefs;
import noppes.npcs.api.ability.type.IAbilityDisc;
import java.util.Arrays;
@@ -66,11 +67,6 @@ public class AbilityDisc extends Ability implements IAbilityDisc {
this.activeAnimationName = "Ability_Disc_Active";
}
@Override
public boolean hasTypeSettings() {
return true;
}
@Override
public boolean isTargetingModeLocked() {
return true;
@@ -276,6 +272,7 @@ public class AbilityDisc extends Ability implements IAbilityDisc {
return lifespanData.maxLifetime > 0 ? Math.min(lifespanData.maxLifetime, 100) : 100;
}
@SideOnly(Side.CLIENT)
@Override
public List<FieldDef> getFieldDefinitions() {
return Arrays.asList(
@@ -303,30 +300,30 @@ public class AbilityDisc extends Ability implements IAbilityDisc {
.hover("ability.hover.explosive"),
FieldDef.floatField("gui.radius", this::getExplosionRadius, this::setExplosionRadius)
.visibleWhen(this::isExplosive),
FieldDef.effectsListField("ability.effects", this::getEffects, this::setEffects),
AbilityFieldDefs.effectsListField("ability.effects", this::getEffects, this::setEffects),
// Visual tab
FieldDef.enumField("ability.anchorPoint", AnchorPoint.class, this::getAnchorPointEnum, this::setAnchorPointEnum)
.customTab("ability.tab.visual"),
FieldDef.section("ability.section.colors").customTab("ability.tab.visual"),
.tab("ability.tab.visual"),
FieldDef.section("ability.section.colors").tab("ability.tab.visual"),
FieldDef.colorSubGui("ability.innerColor", this::getInnerColor, this::setInnerColor)
.customTab("ability.tab.visual"),
.tab("ability.tab.visual"),
FieldDef.boolField("ability.outerEnabled", this::isOuterColorEnabled, this::setOuterColorEnabled)
.customTab("ability.tab.visual"),
.tab("ability.tab.visual"),
FieldDef.colorSubGui("ability.outerColor", this::getOuterColor, this::setOuterColor)
.customTab("ability.tab.visual").visibleWhen(this::isOuterColorEnabled),
.tab("ability.tab.visual").visibleWhen(this::isOuterColorEnabled),
FieldDef.floatField("ability.outerWidth", this::getOuterColorWidth, this::setOuterColorWidth)
.customTab("ability.tab.visual").visibleWhen(this::isOuterColorEnabled).column(ColumnHint.LEFT),
.tab("ability.tab.visual").visibleWhen(this::isOuterColorEnabled).column(ColumnHint.LEFT),
FieldDef.floatField("ability.outerAlpha", this::getOuterColorAlpha, this::setOuterColorAlpha)
.customTab("ability.tab.visual").range(0, 1).visibleWhen(this::isOuterColorEnabled).column(ColumnHint.RIGHT),
FieldDef.section("ability.section.effects").customTab("ability.tab.visual"),
.tab("ability.tab.visual").range(0, 1).visibleWhen(this::isOuterColorEnabled).column(ColumnHint.RIGHT),
FieldDef.section("ability.section.effects").tab("ability.tab.visual"),
FieldDef.floatField("ability.rotationSpeed", this::getRotationSpeed, this::setRotationSpeed)
.customTab("ability.tab.visual"),
.tab("ability.tab.visual"),
FieldDef.boolField("ability.lightning", this::hasLightningEffect, this::setLightningEffect)
.customTab("ability.tab.visual"),
.tab("ability.tab.visual"),
FieldDef.floatField("gui.density", this::getLightningDensity, this::setLightningDensity)
.customTab("ability.tab.visual").range(0.01f, 5.0f).visibleWhen(this::hasLightningEffect).column(ColumnHint.LEFT),
.tab("ability.tab.visual").range(0.01f, 5.0f).visibleWhen(this::hasLightningEffect).column(ColumnHint.LEFT),
FieldDef.floatField("gui.radius", this::getLightningRadius, this::setLightningRadius)
.customTab("ability.tab.visual").range(0.1f, 10.0f).visibleWhen(this::hasLightningEffect).column(ColumnHint.RIGHT)
.tab("ability.tab.visual").range(0.1f, 10.0f).visibleWhen(this::hasLightningEffect).column(ColumnHint.RIGHT)
);
}
}
@@ -7,8 +7,9 @@ import kamkeel.npcs.controllers.data.ability.AnchorPoint;
import kamkeel.npcs.controllers.data.ability.LockMovementType;
import kamkeel.npcs.controllers.data.ability.TargetingMode;
import kamkeel.npcs.controllers.data.ability.data.*;
import kamkeel.npcs.controllers.data.ability.gui.ColumnHint;
import kamkeel.npcs.controllers.data.ability.gui.FieldDef;
import noppes.npcs.client.gui.builder.ColumnHint;
import noppes.npcs.client.gui.builder.FieldDef;
import kamkeel.npcs.controllers.data.ability.gui.AbilityFieldDefs;
import kamkeel.npcs.controllers.data.telegraph.Telegraph;
import kamkeel.npcs.controllers.data.telegraph.TelegraphInstance;
import kamkeel.npcs.controllers.data.telegraph.TelegraphType;
@@ -36,7 +37,7 @@ public class AbilityDiscDual extends Ability {
private int boomerangDelay = 40;
// Dual properties
private boolean dualFire= true;
private boolean dualFire = true;
private int dualFireDelay = 10;
// Energy data classes
@@ -74,11 +75,6 @@ public class AbilityDiscDual extends Ability {
this.activeAnimationName = "Ability_DiscDual_Active";
}
@Override
public boolean hasTypeSettings() {
return true;
}
@Override
public boolean isTargetingModeLocked() {
return true;
@@ -389,6 +385,7 @@ public class AbilityDiscDual extends Ability {
public void setAnchorPoint(int orb, int point) { getAnchorData(orb).anchorPoint = AnchorPoint.fromOrdinal(point); }
public void setAnchorPoint(int point) { getAnchorData(0).anchorPoint = AnchorPoint.fromOrdinal(point); }
@SideOnly(Side.CLIENT)
@Override
public List<FieldDef> getFieldDefinitions() {
return Arrays.asList(
@@ -420,71 +417,71 @@ public class AbilityDiscDual extends Ability {
.hover("ability.hover.explosive"),
FieldDef.floatField("gui.radius", this::getExplosionRadius, this::setExplosionRadius)
.visibleWhen(this::isExplosive),
FieldDef.effectsListField("ability.effects", this::getEffects, this::setEffects),
AbilityFieldDefs.effectsListField("ability.effects", this::getEffects, this::setEffects),
// Visual tab - Disc 1
FieldDef.enumField("ability.anchorPoint", AnchorPoint.class,
() -> getAnchorPointEnum(0), v -> setAnchorPointEnum(0, v))
.customTab("ability.tab.visual"),
FieldDef.section("ability.section.disc1").customTab("ability.tab.visual"),
.tab("ability.tab.visual"),
FieldDef.section("ability.section.disc1").tab("ability.tab.visual"),
FieldDef.colorSubGui("ability.innerColor",
() -> getInnerColor(0), v -> setInnerColor(0, v))
.customTab("ability.tab.visual"),
.tab("ability.tab.visual"),
FieldDef.boolField("ability.outerEnabled",
() -> isOuterColorEnabled(0), v -> setOuterColorEnabled(0, v))
.customTab("ability.tab.visual"),
.tab("ability.tab.visual"),
FieldDef.colorSubGui("ability.outerColor",
() -> getOuterColor(0), v -> setOuterColor(0, v))
.customTab("ability.tab.visual").visibleWhen(() -> isOuterColorEnabled(0)),
.tab("ability.tab.visual").visibleWhen(() -> isOuterColorEnabled(0)),
FieldDef.floatField("ability.outerWidth",
() -> getOuterColorWidth(0), v -> setOuterColorWidth(0, v))
.customTab("ability.tab.visual").visibleWhen(() -> isOuterColorEnabled(0)).column(ColumnHint.LEFT),
.tab("ability.tab.visual").visibleWhen(() -> isOuterColorEnabled(0)).column(ColumnHint.LEFT),
FieldDef.floatField("ability.outerAlpha",
() -> getOuterColorAlpha(0), v -> setOuterColorAlpha(0, v))
.customTab("ability.tab.visual").range(0, 1).visibleWhen(() -> isOuterColorEnabled(0)).column(ColumnHint.RIGHT),
.tab("ability.tab.visual").range(0, 1).visibleWhen(() -> isOuterColorEnabled(0)).column(ColumnHint.RIGHT),
FieldDef.floatField("ability.rotationSpeed",
() -> getRotationSpeed(0), v -> setRotationSpeed(0, v))
.customTab("ability.tab.visual"),
.tab("ability.tab.visual"),
FieldDef.boolField("ability.lightning",
() -> hasLightningEffect(0), v -> setLightningEffect(0, v))
.customTab("ability.tab.visual"),
.tab("ability.tab.visual"),
FieldDef.floatField("gui.density",
() -> getLightningDensity(0), v -> setLightningDensity(0, v))
.customTab("ability.tab.visual").range(0.01f, 5.0f).visibleWhen(() -> hasLightningEffect(0)).column(ColumnHint.LEFT),
.tab("ability.tab.visual").range(0.01f, 5.0f).visibleWhen(() -> hasLightningEffect(0)).column(ColumnHint.LEFT),
FieldDef.floatField("gui.radius",
() -> getLightningRadius(0), v -> setLightningRadius(0, v))
.customTab("ability.tab.visual").range(0.1f, 10.0f).visibleWhen(() -> hasLightningEffect(0)).column(ColumnHint.RIGHT),
.tab("ability.tab.visual").range(0.1f, 10.0f).visibleWhen(() -> hasLightningEffect(0)).column(ColumnHint.RIGHT),
// Visual tab - Disc 2
FieldDef.enumField("ability.anchorPoint", AnchorPoint.class,
() -> getAnchorPointEnum(1), v -> setAnchorPointEnum(1, v))
.customTab("ability.tab.visual"),
FieldDef.section("ability.section.disc2").customTab("ability.tab.visual"),
.tab("ability.tab.visual"),
FieldDef.section("ability.section.disc2").tab("ability.tab.visual"),
FieldDef.colorSubGui("ability.innerColor",
() -> getInnerColor(1), v -> setInnerColor(1, v))
.customTab("ability.tab.visual"),
.tab("ability.tab.visual"),
FieldDef.boolField("ability.outerEnabled",
() -> isOuterColorEnabled(1), v -> setOuterColorEnabled(1, v))
.customTab("ability.tab.visual"),
.tab("ability.tab.visual"),
FieldDef.colorSubGui("ability.outerColor",
() -> getOuterColor(1), v -> setOuterColor(1, v))
.customTab("ability.tab.visual").visibleWhen(() -> isOuterColorEnabled(1)),
.tab("ability.tab.visual").visibleWhen(() -> isOuterColorEnabled(1)),
FieldDef.floatField("ability.outerWidth",
() -> getOuterColorWidth(1), v -> setOuterColorWidth(1, v))
.customTab("ability.tab.visual").visibleWhen(() -> isOuterColorEnabled(1)).column(ColumnHint.LEFT),
.tab("ability.tab.visual").visibleWhen(() -> isOuterColorEnabled(1)).column(ColumnHint.LEFT),
FieldDef.floatField("ability.outerAlpha",
() -> getOuterColorAlpha(1), v -> setOuterColorAlpha(1, v))
.customTab("ability.tab.visual").range(0, 1).visibleWhen(() -> isOuterColorEnabled(1)).column(ColumnHint.RIGHT),
.tab("ability.tab.visual").range(0, 1).visibleWhen(() -> isOuterColorEnabled(1)).column(ColumnHint.RIGHT),
FieldDef.floatField("ability.rotationSpeed",
() -> getRotationSpeed(1), v -> setRotationSpeed(1, v))
.customTab("ability.tab.visual"),
.tab("ability.tab.visual"),
FieldDef.boolField("ability.lightning",
() -> hasLightningEffect(1), v -> setLightningEffect(1, v))
.customTab("ability.tab.visual"),
.tab("ability.tab.visual"),
FieldDef.floatField("gui.density",
() -> getLightningDensity(1), v -> setLightningDensity(1, v))
.customTab("ability.tab.visual").range(0.01f, 5.0f).visibleWhen(() -> hasLightningEffect(1)).column(ColumnHint.LEFT),
.tab("ability.tab.visual").range(0.01f, 5.0f).visibleWhen(() -> hasLightningEffect(1)).column(ColumnHint.LEFT),
FieldDef.floatField("gui.radius",
() -> getLightningRadius(1), v -> setLightningRadius(1, v))
.customTab("ability.tab.visual").range(0.1f, 10.0f).visibleWhen(() -> hasLightningEffect(1)).column(ColumnHint.RIGHT)
.tab("ability.tab.visual").range(0.1f, 10.0f).visibleWhen(() -> hasLightningEffect(1)).column(ColumnHint.RIGHT)
);
}
@@ -17,8 +17,9 @@ import net.minecraft.entity.EntityLivingBase;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.util.Vec3;
import net.minecraft.world.World;
import kamkeel.npcs.controllers.data.ability.gui.ColumnHint;
import kamkeel.npcs.controllers.data.ability.gui.FieldDef;
import noppes.npcs.client.gui.builder.ColumnHint;
import noppes.npcs.client.gui.builder.FieldDef;
import kamkeel.npcs.controllers.data.ability.gui.AbilityFieldDefs;
import noppes.npcs.api.ability.type.IAbilityEnergyBeam;
import java.util.Arrays;
@@ -63,11 +64,6 @@ public class AbilityEnergyBeam extends Ability implements IAbilityEnergyBeam {
this.activeAnimationName = "Ability_Beam_Active";
}
@Override
public boolean hasTypeSettings() {
return true;
}
@Override
public boolean isTargetingModeLocked() {
return true;
@@ -279,6 +275,7 @@ public class AbilityEnergyBeam extends Ability implements IAbilityEnergyBeam {
return lifespanData.maxLifetime > 0 ? Math.min(lifespanData.maxLifetime, 100) : 100;
}
@SideOnly(Side.CLIENT)
@Override
public List<FieldDef> getFieldDefinitions() {
return Arrays.asList(
@@ -303,30 +300,30 @@ public class AbilityEnergyBeam extends Ability implements IAbilityEnergyBeam {
.hover("ability.hover.explosive"),
FieldDef.floatField("gui.radius", this::getExplosionRadius, this::setExplosionRadius)
.visibleWhen(this::isExplosive),
FieldDef.effectsListField("ability.effects", this::getEffects, this::setEffects),
AbilityFieldDefs.effectsListField("ability.effects", this::getEffects, this::setEffects),
// Visual tab
FieldDef.enumField("ability.anchorPoint", AnchorPoint.class, this::getAnchorPointEnum, this::setAnchorPointEnum)
.customTab("ability.tab.visual"),
FieldDef.section("ability.section.colors").customTab("ability.tab.visual"),
.tab("ability.tab.visual"),
FieldDef.section("ability.section.colors").tab("ability.tab.visual"),
FieldDef.colorSubGui("ability.innerColor", this::getInnerColor, this::setInnerColor)
.customTab("ability.tab.visual"),
.tab("ability.tab.visual"),
FieldDef.boolField("ability.outerEnabled", this::isOuterColorEnabled, this::setOuterColorEnabled)
.customTab("ability.tab.visual"),
.tab("ability.tab.visual"),
FieldDef.colorSubGui("ability.outerColor", this::getOuterColor, this::setOuterColor)
.customTab("ability.tab.visual").visibleWhen(this::isOuterColorEnabled),
.tab("ability.tab.visual").visibleWhen(this::isOuterColorEnabled),
FieldDef.floatField("ability.outerWidth", this::getOuterColorWidth, this::setOuterColorWidth)
.customTab("ability.tab.visual").visibleWhen(this::isOuterColorEnabled).column(ColumnHint.LEFT),
.tab("ability.tab.visual").visibleWhen(this::isOuterColorEnabled).column(ColumnHint.LEFT),
FieldDef.floatField("ability.outerAlpha", this::getOuterColorAlpha, this::setOuterColorAlpha)
.customTab("ability.tab.visual").range(0, 1).visibleWhen(this::isOuterColorEnabled).column(ColumnHint.RIGHT),
FieldDef.section("ability.section.effects").customTab("ability.tab.visual"),
.tab("ability.tab.visual").range(0, 1).visibleWhen(this::isOuterColorEnabled).column(ColumnHint.RIGHT),
FieldDef.section("ability.section.effects").tab("ability.tab.visual"),
FieldDef.floatField("ability.rotationSpeed", this::getRotationSpeed, this::setRotationSpeed)
.customTab("ability.tab.visual"),
.tab("ability.tab.visual"),
FieldDef.boolField("ability.lightning", this::hasLightningEffect, this::setLightningEffect)
.customTab("ability.tab.visual"),
.tab("ability.tab.visual"),
FieldDef.floatField("gui.density", this::getLightningDensity, this::setLightningDensity)
.customTab("ability.tab.visual").range(0.01f, 5.0f).visibleWhen(this::hasLightningEffect).column(ColumnHint.LEFT),
.tab("ability.tab.visual").range(0.01f, 5.0f).visibleWhen(this::hasLightningEffect).column(ColumnHint.LEFT),
FieldDef.floatField("gui.radius", this::getLightningRadius, this::setLightningRadius)
.customTab("ability.tab.visual").range(0.1f, 10.0f).visibleWhen(this::hasLightningEffect).column(ColumnHint.RIGHT)
.tab("ability.tab.visual").range(0.1f, 10.0f).visibleWhen(this::hasLightningEffect).column(ColumnHint.RIGHT)
);
}
}
@@ -13,9 +13,12 @@ import noppes.npcs.entity.EntityNPCInterface;
import noppes.npcs.api.ability.type.IAbilityGuard;
import kamkeel.npcs.controllers.data.ability.gui.ColumnHint;
import kamkeel.npcs.controllers.data.ability.gui.FieldDef;
import kamkeel.npcs.controllers.data.ability.gui.TabTarget;
import noppes.npcs.client.gui.builder.ColumnHint;
import noppes.npcs.client.gui.builder.FieldDef;
import kamkeel.npcs.controllers.data.ability.gui.AbilityFieldDefs;
import cpw.mods.fml.relauncher.Side;
import cpw.mods.fml.relauncher.SideOnly;
import java.util.Arrays;
import java.util.List;
@@ -74,11 +77,6 @@ public class AbilityGuard extends Ability implements IAbilityGuard {
this.allowedBy = UserType.NPC_ONLY;
}
@Override
public boolean hasTypeSettings() {
return true;
}
@Override
public boolean isTargetingModeLocked() {
return true;
@@ -298,6 +296,7 @@ public class AbilityGuard extends Ability implements IAbilityGuard {
this.counterAnimationId = counterAnimationId;
}
@SideOnly(Side.CLIENT)
@Override
public List<FieldDef> getFieldDefinitions() {
return Arrays.asList(
@@ -315,7 +314,7 @@ public class AbilityGuard extends Ability implements IAbilityGuard {
.visibleWhen(this::isCanCounter),
FieldDef.intField("gui.animation", this::getCounterAnimationId, this::setCounterAnimationId)
.visibleWhen(this::isCanCounter),
FieldDef.effectsListField("ability.effects", this::getEffects, this::setEffects)
AbilityFieldDefs.effectsListField("ability.effects", this::getEffects, this::setEffects)
);
}
}
@@ -16,9 +16,12 @@ import noppes.npcs.entity.EntityNPCInterface;
import noppes.npcs.api.ability.type.IAbilityHazard;
import kamkeel.npcs.controllers.data.ability.gui.ColumnHint;
import kamkeel.npcs.controllers.data.ability.gui.FieldDef;
import kamkeel.npcs.controllers.data.ability.gui.TabTarget;
import noppes.npcs.client.gui.builder.ColumnHint;
import noppes.npcs.client.gui.builder.FieldDef;
import kamkeel.npcs.controllers.data.ability.gui.AbilityFieldDefs;
import cpw.mods.fml.relauncher.Side;
import cpw.mods.fml.relauncher.SideOnly;
import java.util.Arrays;
import java.util.HashSet;
@@ -111,11 +114,6 @@ public class AbilityHazard extends Ability implements IAbilityHazard {
this.telegraphType = TelegraphType.CIRCLE;
}
@Override
public boolean hasTypeSettings() {
return true;
}
@Override
public boolean isTargetingModeLocked() {
return true;
@@ -631,6 +629,7 @@ public class AbilityHazard extends Ability implements IAbilityHazard {
return zoneZ;
}
@SideOnly(Side.CLIENT)
@Override
public List<FieldDef> getFieldDefinitions() {
return Arrays.asList(
@@ -651,7 +650,7 @@ public class AbilityHazard extends Ability implements IAbilityHazard {
FieldDef.intField("ability.poisonLevel", this::getPoisonLevel, this::setPoisonLevel),
FieldDef.boolField("ability.affectsCaster", this::isAffectsCaster, this::setAffectsCaster)
.hover("ability.hover.affectsCaster"),
FieldDef.effectsListField("ability.effects", this::getEffects, this::setEffects)
AbilityFieldDefs.effectsListField("ability.effects", this::getEffects, this::setEffects)
);
}
}
@@ -11,11 +11,13 @@ import net.minecraft.util.AxisAlignedBB;
import net.minecraft.world.World;
import noppes.npcs.entity.EntityNPCInterface;
import kamkeel.npcs.controllers.data.ability.gui.ColumnHint;
import kamkeel.npcs.controllers.data.ability.gui.FieldDef;
import kamkeel.npcs.controllers.data.ability.gui.TabTarget;
import noppes.npcs.client.gui.builder.ColumnHint;
import noppes.npcs.client.gui.builder.FieldDef;
import noppes.npcs.api.ability.type.IAbilityHeal;
import cpw.mods.fml.relauncher.Side;
import cpw.mods.fml.relauncher.SideOnly;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
@@ -57,11 +59,6 @@ public class AbilityHeal extends Ability implements IAbilityHeal {
this.showTelegraph = false;
}
@Override
public boolean hasTypeSettings() {
return true;
}
@Override
public boolean isTargetingModeLocked() {
return true;
@@ -283,6 +280,7 @@ public class AbilityHeal extends Ability implements IAbilityHeal {
this.instantHeal = instantHeal;
}
@SideOnly(Side.CLIENT)
@Override
public List<FieldDef> getFieldDefinitions() {
return Arrays.asList(
@@ -1,5 +1,7 @@
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;
@@ -7,9 +9,9 @@ import kamkeel.npcs.controllers.data.telegraph.TelegraphType;
import net.minecraft.entity.EntityLivingBase;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.world.World;
import kamkeel.npcs.controllers.data.ability.gui.ColumnHint;
import kamkeel.npcs.controllers.data.ability.gui.FieldDef;
import kamkeel.npcs.controllers.data.ability.gui.TabTarget;
import noppes.npcs.client.gui.builder.ColumnHint;
import noppes.npcs.client.gui.builder.FieldDef;
import kamkeel.npcs.controllers.data.ability.gui.AbilityFieldDefs;
import noppes.npcs.api.ability.type.IAbilityHeavyHit;
import noppes.npcs.entity.EntityNPCInterface;
@@ -42,11 +44,6 @@ public class AbilityHeavyHit extends Ability implements IAbilityHeavyHit {
this.activeAnimationName = "Ability_HeavyHit_Active";
}
@Override
public boolean hasTypeSettings() {
return true;
}
@Override
public boolean isTargetingModeLocked() {
return true;
@@ -109,12 +106,13 @@ public class AbilityHeavyHit extends Ability implements IAbilityHeavyHit {
this.knockback = knockback;
}
@SideOnly(Side.CLIENT)
@Override
public List<FieldDef> getFieldDefinitions() {
return Arrays.asList(
FieldDef.floatField("enchantment.damage", this::getDamage, this::setDamage).column(ColumnHint.LEFT),
FieldDef.floatField("ability.knockback", this::getKnockback, this::setKnockback).column(ColumnHint.RIGHT),
FieldDef.effectsListField("ability.effects", this::getEffects, this::setEffects)
AbilityFieldDefs.effectsListField("ability.effects", this::getEffects, this::setEffects)
);
}
}
@@ -7,8 +7,9 @@ import kamkeel.npcs.controllers.data.ability.AnchorPoint;
import kamkeel.npcs.controllers.data.ability.LockMovementType;
import kamkeel.npcs.controllers.data.ability.TargetingMode;
import kamkeel.npcs.controllers.data.ability.data.*;
import kamkeel.npcs.controllers.data.ability.gui.ColumnHint;
import kamkeel.npcs.controllers.data.ability.gui.FieldDef;
import noppes.npcs.client.gui.builder.ColumnHint;
import noppes.npcs.client.gui.builder.FieldDef;
import kamkeel.npcs.controllers.data.ability.gui.AbilityFieldDefs;
import kamkeel.npcs.controllers.data.telegraph.TelegraphType;
import kamkeel.npcs.entity.EntityAbilityLaser;
import kamkeel.npcs.util.AnchorPointHelper;
@@ -61,11 +62,6 @@ public class AbilityLaserShot extends Ability implements IAbilityLaserShot {
this.activeAnimationName = "Ability_Laser_Active";
}
@Override
public boolean hasTypeSettings() {
return true;
}
@Override
public boolean isTargetingModeLocked() {
return false;
@@ -250,6 +246,7 @@ public class AbilityLaserShot extends Ability implements IAbilityLaserShot {
return false; // Laser has no charging, spawns at active phase
}
@SideOnly(Side.CLIENT)
@Override
public List<FieldDef> getFieldDefinitions() {
return Arrays.asList(
@@ -266,23 +263,23 @@ public class AbilityLaserShot extends Ability implements IAbilityLaserShot {
FieldDef.section("ability.section.explosive"),
FieldDef.boolField("gui.enabled", this::isExplosive, this::setExplosive).hover("ability.hover.explosive"),
FieldDef.floatField("gui.radius", this::getExplosionRadius, this::setExplosionRadius).visibleWhen(this::isExplosive),
FieldDef.effectsListField("ability.effects", this::getEffects, this::setEffects),
AbilityFieldDefs.effectsListField("ability.effects", this::getEffects, this::setEffects),
// Visual tab
FieldDef.section("ability.section.colors").customTab("ability.tab.visual"),
FieldDef.colorSubGui("ability.innerColor", this::getInnerColor, this::setInnerColor).customTab("ability.tab.visual"),
FieldDef.boolField("ability.outerEnabled", this::isOuterColorEnabled, this::setOuterColorEnabled).customTab("ability.tab.visual"),
FieldDef.section("ability.section.colors").tab("ability.tab.visual"),
FieldDef.colorSubGui("ability.innerColor", this::getInnerColor, this::setInnerColor).tab("ability.tab.visual"),
FieldDef.boolField("ability.outerEnabled", this::isOuterColorEnabled, this::setOuterColorEnabled).tab("ability.tab.visual"),
FieldDef.colorSubGui("ability.outerColor", this::getOuterColor, this::setOuterColor)
.customTab("ability.tab.visual").visibleWhen(this::isOuterColorEnabled),
.tab("ability.tab.visual").visibleWhen(this::isOuterColorEnabled),
FieldDef.floatField("ability.outerWidth", this::getOuterColorWidth, this::setOuterColorWidth)
.customTab("ability.tab.visual").visibleWhen(this::isOuterColorEnabled).column(ColumnHint.LEFT),
.tab("ability.tab.visual").visibleWhen(this::isOuterColorEnabled).column(ColumnHint.LEFT),
FieldDef.floatField("ability.outerAlpha", this::getOuterColorAlpha, this::setOuterColorAlpha)
.customTab("ability.tab.visual").range(0, 1).visibleWhen(this::isOuterColorEnabled).column(ColumnHint.RIGHT),
FieldDef.section("ability.section.effects").customTab("ability.tab.visual"),
FieldDef.boolField("ability.lightning", this::hasLightningEffect, this::setLightningEffect).customTab("ability.tab.visual"),
.tab("ability.tab.visual").range(0, 1).visibleWhen(this::isOuterColorEnabled).column(ColumnHint.RIGHT),
FieldDef.section("ability.section.effects").tab("ability.tab.visual"),
FieldDef.boolField("ability.lightning", this::hasLightningEffect, this::setLightningEffect).tab("ability.tab.visual"),
FieldDef.floatField("gui.density", this::getLightningDensity, this::setLightningDensity)
.customTab("ability.tab.visual").range(0.01f, 5.0f).visibleWhen(this::hasLightningEffect).column(ColumnHint.LEFT),
.tab("ability.tab.visual").range(0.01f, 5.0f).visibleWhen(this::hasLightningEffect).column(ColumnHint.LEFT),
FieldDef.floatField("gui.radius", this::getLightningRadius, this::setLightningRadius)
.customTab("ability.tab.visual").range(0.1f, 10.0f).visibleWhen(this::hasLightningEffect).column(ColumnHint.RIGHT)
.tab("ability.tab.visual").range(0.1f, 10.0f).visibleWhen(this::hasLightningEffect).column(ColumnHint.RIGHT)
);
}
}
@@ -17,8 +17,9 @@ import net.minecraft.entity.EntityLivingBase;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.util.Vec3;
import net.minecraft.world.World;
import kamkeel.npcs.controllers.data.ability.gui.ColumnHint;
import kamkeel.npcs.controllers.data.ability.gui.FieldDef;
import noppes.npcs.client.gui.builder.ColumnHint;
import noppes.npcs.client.gui.builder.FieldDef;
import kamkeel.npcs.controllers.data.ability.gui.AbilityFieldDefs;
import noppes.npcs.api.ability.type.IAbilityOrb;
import java.util.Arrays;
@@ -62,11 +63,6 @@ public class AbilityOrb extends Ability implements IAbilityOrb {
this.activeAnimationName = "Ability_Orb_Active";
}
@Override
public boolean hasTypeSettings() {
return true;
}
@Override
public boolean isTargetingModeLocked() {
return true;
@@ -415,6 +411,7 @@ public class AbilityOrb extends Ability implements IAbilityOrb {
return lifespanData.maxLifetime > 0 ? Math.min(lifespanData.maxLifetime, 100) : 100;
}
@SideOnly(Side.CLIENT)
@Override
public List<FieldDef> getFieldDefinitions() {
return Arrays.asList(
@@ -431,26 +428,28 @@ public class AbilityOrb extends Ability implements IAbilityOrb {
FieldDef.section("ability.section.explosive"),
FieldDef.boolField("gui.enabled", this::isExplosive, this::setExplosive).hover("ability.hover.explosive"),
FieldDef.floatField("gui.radius", this::getExplosionRadius, this::setExplosionRadius).visibleWhen(this::isExplosive),
FieldDef.effectsListField("ability.effects", this::getEffects, this::setEffects),
AbilityFieldDefs.effectsListField("ability.effects", this::getEffects, this::setEffects),
// Visual tab
FieldDef.enumField("ability.anchorPoint", AnchorPoint.class, this::getAnchorPointEnum, this::setAnchorPointEnum)
.customTab("ability.tab.visual"),
FieldDef.section("ability.section.colors").customTab("ability.tab.visual"),
FieldDef.colorSubGui("ability.innerColor", this::getInnerColor, this::setInnerColor).customTab("ability.tab.visual"),
FieldDef.boolField("ability.outerEnabled", this::isOuterColorEnabled, this::setOuterColorEnabled).customTab("ability.tab.visual"),
.tab("ability.tab.visual"),
FieldDef.section("ability.section.colors").tab("ability.tab.visual"),
FieldDef.colorSubGui("ability.innerColor", this::getInnerColor, this::setInnerColor).tab("ability.tab.visual"),
FieldDef.boolField("ability.outerEnabled", this::isOuterColorEnabled, this::setOuterColorEnabled).tab("ability.tab.visual"),
FieldDef.colorSubGui("ability.outerColor", this::getOuterColor, this::setOuterColor)
.customTab("ability.tab.visual").visibleWhen(this::isOuterColorEnabled),
.tab("ability.tab.visual").visibleWhen(this::isOuterColorEnabled),
FieldDef.floatField("ability.outerWidth", this::getOuterColorWidth, this::setOuterColorWidth)
.customTab("ability.tab.visual").visibleWhen(this::isOuterColorEnabled).column(ColumnHint.LEFT),
.tab("ability.tab.visual").visibleWhen(this::isOuterColorEnabled).column(ColumnHint.LEFT),
FieldDef.floatField("ability.outerAlpha", this::getOuterColorAlpha, this::setOuterColorAlpha)
.customTab("ability.tab.visual").range(0, 1).visibleWhen(this::isOuterColorEnabled).column(ColumnHint.RIGHT),
FieldDef.section("ability.section.effects").customTab("ability.tab.visual"),
FieldDef.floatField("ability.rotationSpeed", this::getRotationSpeed, this::setRotationSpeed).customTab("ability.tab.visual"),
FieldDef.boolField("ability.lightning", this::hasLightningEffect, this::setLightningEffect).customTab("ability.tab.visual"),
.tab("ability.tab.visual").range(0, 1).visibleWhen(this::isOuterColorEnabled).column(ColumnHint.RIGHT),
FieldDef.section("ability.section.effects").tab("ability.tab.visual"),
FieldDef.floatField("ability.rotationSpeed", this::getRotationSpeed, this::setRotationSpeed).tab("ability.tab.visual"),
FieldDef.boolField("ability.lightning", this::hasLightningEffect, this::setLightningEffect).tab("ability.tab.visual"),
FieldDef.floatField("gui.density", this::getLightningDensity, this::setLightningDensity)
.customTab("ability.tab.visual").range(0.01f, 5.0f).visibleWhen(this::hasLightningEffect).column(ColumnHint.LEFT),
.tab("ability.tab.visual").range(0.01f, 5.0f).visibleWhen(this::hasLightningEffect).column(ColumnHint.LEFT),
FieldDef.floatField("gui.radius", this::getLightningRadius, this::setLightningRadius)
.customTab("ability.tab.visual").range(0.1f, 10.0f).visibleWhen(this::hasLightningEffect).column(ColumnHint.RIGHT)
.tab("ability.tab.visual").range(0.1f, 10.0f).visibleWhen(this::hasLightningEffect).column(ColumnHint.RIGHT)
);
}
}
@@ -7,8 +7,9 @@ import kamkeel.npcs.controllers.data.ability.AnchorPoint;
import kamkeel.npcs.controllers.data.ability.LockMovementType;
import kamkeel.npcs.controllers.data.ability.TargetingMode;
import kamkeel.npcs.controllers.data.ability.data.*;
import kamkeel.npcs.controllers.data.ability.gui.ColumnHint;
import kamkeel.npcs.controllers.data.ability.gui.FieldDef;
import noppes.npcs.client.gui.builder.ColumnHint;
import noppes.npcs.client.gui.builder.FieldDef;
import kamkeel.npcs.controllers.data.ability.gui.AbilityFieldDefs;
import kamkeel.npcs.controllers.data.telegraph.Telegraph;
import kamkeel.npcs.controllers.data.telegraph.TelegraphInstance;
import kamkeel.npcs.controllers.data.telegraph.TelegraphType;
@@ -65,11 +66,6 @@ public class AbilityOrbDual extends Ability {
this.activeAnimationName = "Ability_BeamDual_Active";
}
@Override
public boolean hasTypeSettings() {
return true;
}
@Override
public boolean isTargetingModeLocked() {
return true;
@@ -460,6 +456,7 @@ public class AbilityOrbDual extends Ability {
public void setAnchorPoint(int orb, int point) { getAnchorData(orb).anchorPoint = AnchorPoint.fromOrdinal(point); }
public void setAnchorPoint(int point) { getAnchorData(0).anchorPoint = AnchorPoint.fromOrdinal(point); }
@SideOnly(Side.CLIENT)
@Override
public List<FieldDef> getFieldDefinitions() {
return Arrays.asList(
@@ -480,71 +477,71 @@ public class AbilityOrbDual extends Ability {
FieldDef.section("ability.section.explosive"),
FieldDef.boolField("gui.enabled", this::isExplosive, this::setExplosive).hover("ability.hover.explosive"),
FieldDef.floatField("gui.radius", this::getExplosionRadius, this::setExplosionRadius).visibleWhen(this::isExplosive),
FieldDef.effectsListField("ability.effects", this::getEffects, this::setEffects),
AbilityFieldDefs.effectsListField("ability.effects", this::getEffects, this::setEffects),
// Visual tab - Orb 1
FieldDef.enumField("ability.anchorPoint", AnchorPoint.class,
() -> getAnchorPointEnum(0), v -> setAnchorPointEnum(0, v))
.customTab("ability.tab.visual"),
FieldDef.section("ability.section.orb1").customTab("ability.tab.visual"),
.tab("ability.tab.visual"),
FieldDef.section("ability.section.orb1").tab("ability.tab.visual"),
FieldDef.colorSubGui("ability.innerColor",
() -> getInnerColor(0), v -> setInnerColor(0, v))
.customTab("ability.tab.visual"),
.tab("ability.tab.visual"),
FieldDef.boolField("ability.outerEnabled",
() -> isOuterColorEnabled(0), v -> setOuterColorEnabled(0, v))
.customTab("ability.tab.visual"),
.tab("ability.tab.visual"),
FieldDef.colorSubGui("ability.outerColor",
() -> getOuterColor(0), v -> setOuterColor(0, v))
.customTab("ability.tab.visual").visibleWhen(() -> isOuterColorEnabled(0)),
.tab("ability.tab.visual").visibleWhen(() -> isOuterColorEnabled(0)),
FieldDef.floatField("ability.outerWidth",
() -> getOuterColorWidth(0), v -> setOuterColorWidth(0, v))
.customTab("ability.tab.visual").visibleWhen(() -> isOuterColorEnabled(0)).column(ColumnHint.LEFT),
.tab("ability.tab.visual").visibleWhen(() -> isOuterColorEnabled(0)).column(ColumnHint.LEFT),
FieldDef.floatField("ability.outerAlpha",
() -> getOuterColorAlpha(0), v -> setOuterColorAlpha(0, v))
.customTab("ability.tab.visual").range(0, 1).visibleWhen(() -> isOuterColorEnabled(0)).column(ColumnHint.RIGHT),
.tab("ability.tab.visual").range(0, 1).visibleWhen(() -> isOuterColorEnabled(0)).column(ColumnHint.RIGHT),
FieldDef.floatField("ability.rotationSpeed",
() -> getRotationSpeed(0), v -> setRotationSpeed(0, v))
.customTab("ability.tab.visual"),
.tab("ability.tab.visual"),
FieldDef.boolField("ability.lightning",
() -> hasLightningEffect(0), v -> setLightningEffect(0, v))
.customTab("ability.tab.visual"),
.tab("ability.tab.visual"),
FieldDef.floatField("gui.density",
() -> getLightningDensity(0), v -> setLightningDensity(0, v))
.customTab("ability.tab.visual").range(0.01f, 5.0f).visibleWhen(() -> hasLightningEffect(0)).column(ColumnHint.LEFT),
.tab("ability.tab.visual").range(0.01f, 5.0f).visibleWhen(() -> hasLightningEffect(0)).column(ColumnHint.LEFT),
FieldDef.floatField("gui.radius",
() -> getLightningRadius(0), v -> setLightningRadius(0, v))
.customTab("ability.tab.visual").range(0.1f, 10.0f).visibleWhen(() -> hasLightningEffect(0)).column(ColumnHint.RIGHT),
.tab("ability.tab.visual").range(0.1f, 10.0f).visibleWhen(() -> hasLightningEffect(0)).column(ColumnHint.RIGHT),
// Visual tab - Orb 2
FieldDef.enumField("ability.anchorPoint", AnchorPoint.class,
() -> getAnchorPointEnum(1), v -> setAnchorPointEnum(1, v))
.customTab("ability.tab.visual"),
FieldDef.section("ability.section.orb2").customTab("ability.tab.visual"),
.tab("ability.tab.visual"),
FieldDef.section("ability.section.orb2").tab("ability.tab.visual"),
FieldDef.colorSubGui("ability.innerColor",
() -> getInnerColor(1), v -> setInnerColor(1, v))
.customTab("ability.tab.visual"),
.tab("ability.tab.visual"),
FieldDef.boolField("ability.outerEnabled",
() -> isOuterColorEnabled(1), v -> setOuterColorEnabled(1, v))
.customTab("ability.tab.visual"),
.tab("ability.tab.visual"),
FieldDef.colorSubGui("ability.outerColor",
() -> getOuterColor(1), v -> setOuterColor(1, v))
.customTab("ability.tab.visual").visibleWhen(() -> isOuterColorEnabled(1)),
.tab("ability.tab.visual").visibleWhen(() -> isOuterColorEnabled(1)),
FieldDef.floatField("ability.outerWidth",
() -> getOuterColorWidth(1), v -> setOuterColorWidth(1, v))
.customTab("ability.tab.visual").visibleWhen(() -> isOuterColorEnabled(1)).column(ColumnHint.LEFT),
.tab("ability.tab.visual").visibleWhen(() -> isOuterColorEnabled(1)).column(ColumnHint.LEFT),
FieldDef.floatField("ability.outerAlpha",
() -> getOuterColorAlpha(1), v -> setOuterColorAlpha(1, v))
.customTab("ability.tab.visual").range(0, 1).visibleWhen(() -> isOuterColorEnabled(1)).column(ColumnHint.RIGHT),
.tab("ability.tab.visual").range(0, 1).visibleWhen(() -> isOuterColorEnabled(1)).column(ColumnHint.RIGHT),
FieldDef.floatField("ability.rotationSpeed",
() -> getRotationSpeed(1), v -> setRotationSpeed(1, v))
.customTab("ability.tab.visual"),
.tab("ability.tab.visual"),
FieldDef.boolField("ability.lightning",
() -> hasLightningEffect(1), v -> setLightningEffect(1, v))
.customTab("ability.tab.visual"),
.tab("ability.tab.visual"),
FieldDef.floatField("gui.density",
() -> getLightningDensity(1), v -> setLightningDensity(1, v))
.customTab("ability.tab.visual").range(0.01f, 5.0f).visibleWhen(() -> hasLightningEffect(1)).column(ColumnHint.LEFT),
.tab("ability.tab.visual").range(0.01f, 5.0f).visibleWhen(() -> hasLightningEffect(1)).column(ColumnHint.LEFT),
FieldDef.floatField("gui.radius",
() -> getLightningRadius(1), v -> setLightningRadius(1, v))
.customTab("ability.tab.visual").range(0.1f, 10.0f).visibleWhen(() -> hasLightningEffect(1)).column(ColumnHint.RIGHT)
.tab("ability.tab.visual").range(0.1f, 10.0f).visibleWhen(() -> hasLightningEffect(1)).column(ColumnHint.RIGHT)
);
}
@@ -1,5 +1,7 @@
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,9 +14,9 @@ import noppes.npcs.entity.EntityNPCInterface;
import noppes.npcs.api.ability.type.IAbilityProjectile;
import kamkeel.npcs.controllers.data.ability.gui.ColumnHint;
import kamkeel.npcs.controllers.data.ability.gui.FieldDef;
import kamkeel.npcs.controllers.data.ability.gui.TabTarget;
import noppes.npcs.client.gui.builder.ColumnHint;
import noppes.npcs.client.gui.builder.FieldDef;
import kamkeel.npcs.controllers.data.ability.gui.AbilityFieldDefs;
import java.util.Arrays;
import java.util.List;
@@ -49,11 +51,6 @@ public class AbilityProjectile extends Ability implements IAbilityProjectile {
this.showTelegraph = false;
}
@Override
public boolean hasTypeSettings() {
return true;
}
@Override
public boolean isTargetingModeLocked() {
return true;
@@ -253,6 +250,7 @@ public class AbilityProjectile extends Ability implements IAbilityProjectile {
this.homingStrength = homingStrength;
}
@SideOnly(Side.CLIENT)
@Override
public List<FieldDef> getFieldDefinitions() {
return Arrays.asList(
@@ -266,7 +264,7 @@ public class AbilityProjectile extends Ability implements IAbilityProjectile {
FieldDef.section("ability.section.explosive"),
FieldDef.boolField("gui.enabled", this::isExplosive, this::setExplosive).hover("ability.hover.explosive"),
FieldDef.floatField("gui.radius", this::getExplosionRadius, this::setExplosionRadius).visibleWhen(this::isExplosive),
FieldDef.effectsListField("ability.effects", this::getEffects, this::setEffects)
AbilityFieldDefs.effectsListField("ability.effects", this::getEffects, this::setEffects)
);
}
}
@@ -1,5 +1,7 @@
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,9 +13,9 @@ import net.minecraft.util.DamageSource;
import net.minecraft.world.World;
import noppes.npcs.entity.EntityNPCInterface;
import kamkeel.npcs.controllers.data.ability.gui.ColumnHint;
import kamkeel.npcs.controllers.data.ability.gui.FieldDef;
import kamkeel.npcs.controllers.data.ability.gui.TabTarget;
import noppes.npcs.client.gui.builder.ColumnHint;
import noppes.npcs.client.gui.builder.FieldDef;
import kamkeel.npcs.controllers.data.ability.gui.AbilityFieldDefs;
import noppes.npcs.api.ability.type.IAbilityShockwave;
import java.util.Arrays;
@@ -43,11 +45,6 @@ public class AbilityShockwave extends Ability implements IAbilityShockwave {
this.activeSound = "random.explode";
}
@Override
public boolean hasTypeSettings() {
return true;
}
@Override
public boolean isTargetingModeLocked() {
return true;
@@ -168,6 +165,7 @@ public class AbilityShockwave extends Ability implements IAbilityShockwave {
this.maxTargets = maxTargets;
}
@SideOnly(Side.CLIENT)
@Override
public List<FieldDef> getFieldDefinitions() {
return Arrays.asList(
@@ -176,7 +174,7 @@ public class AbilityShockwave extends Ability implements IAbilityShockwave {
FieldDef.floatField("gui.radius", this::getPushRadius, this::setPushRadius).column(ColumnHint.LEFT),
FieldDef.floatField("gui.strength", this::getPushStrength, this::setPushStrength).column(ColumnHint.RIGHT),
FieldDef.intField("ability.maxTargets", this::getMaxTargets, this::setMaxTargets),
FieldDef.effectsListField("ability.effects", this::getEffects, this::setEffects)
AbilityFieldDefs.effectsListField("ability.effects", this::getEffects, this::setEffects)
);
}
}
@@ -18,9 +18,9 @@ import noppes.npcs.entity.EntityNPCInterface;
import noppes.npcs.api.ability.type.IAbilitySlam;
import somehussar.gui.annotationHandling.GuiEditable;
import kamkeel.npcs.controllers.data.ability.gui.ColumnHint;
import kamkeel.npcs.controllers.data.ability.gui.FieldDef;
import kamkeel.npcs.controllers.data.ability.gui.TabTarget;
import noppes.npcs.client.gui.builder.ColumnHint;
import noppes.npcs.client.gui.builder.FieldDef;
import kamkeel.npcs.controllers.data.ability.gui.AbilityFieldDefs;
import java.util.Arrays;
import java.util.List;
@@ -33,7 +33,6 @@ import java.util.List;
* - Landing: When NPC hits ground, deal AOE damage
* - RECOVERY: Landing recovery animation
*/
@GuiEditable
public class AbilitySlam extends Ability implements IAbilitySlam {
// Type-specific config
@@ -67,11 +66,6 @@ public class AbilitySlam extends Ability implements IAbilitySlam {
this.activeAnimationName = "Ability_Slam_Active";
}
@Override
public boolean hasTypeSettings() {
return true;
}
/**
* Slam can be AOE_SELF (jump in place) or AOE_TARGET (leap to target).
*/
@@ -579,6 +573,7 @@ public class AbilitySlam extends Ability implements IAbilitySlam {
this.leapHeight = leapHeight;
}
@SideOnly(Side.CLIENT)
@Override
public List<FieldDef> getFieldDefinitions() {
return Arrays.asList(
@@ -588,7 +583,7 @@ public class AbilitySlam extends Ability implements IAbilitySlam {
FieldDef.section("ability.section.leap"),
FieldDef.floatField("gui.speed", this::getLeapSpeed, this::setLeapSpeed).column(ColumnHint.LEFT),
FieldDef.floatField("gui.height", this::getLeapHeight, this::setLeapHeight).column(ColumnHint.RIGHT),
FieldDef.effectsListField("ability.effects", this::getEffects, this::setEffects)
AbilityFieldDefs.effectsListField("ability.effects", this::getEffects, this::setEffects)
);
}
}
@@ -1,11 +1,14 @@
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.ColumnHint;
import kamkeel.npcs.controllers.data.ability.gui.FieldDef;
import noppes.npcs.client.gui.builder.ColumnHint;
import noppes.npcs.client.gui.builder.FieldDef;
import kamkeel.npcs.controllers.data.ability.gui.AbilityFieldDefs;
import kamkeel.npcs.controllers.data.telegraph.Telegraph;
import kamkeel.npcs.controllers.data.telegraph.TelegraphInstance;
import kamkeel.npcs.controllers.data.telegraph.TelegraphType;
@@ -61,11 +64,6 @@ public class AbilitySweeper extends Ability implements IAbilitySweeper {
this.showTelegraph = true;
}
@Override
public boolean hasTypeSettings() {
return true;
}
@Override
public boolean isTargetingModeLocked() {
return true;
@@ -200,9 +198,11 @@ public class AbilitySweeper extends Ability implements IAbilitySweeper {
public boolean isOuterColorEnabled() { return colorData.outerColorEnabled; }
public void setOuterColorEnabled(boolean outerColorEnabled) { colorData.outerColorEnabled = outerColorEnabled; }
@SideOnly(Side.CLIENT)
@Override
public List<FieldDef> getFieldDefinitions() {
return Arrays.asList(
FieldDef.floatField("enchantment.damage", this::getDamage, this::setDamage).column(ColumnHint.LEFT),
FieldDef.intField("ability.damageInterval", this::getDamageInterval, this::setDamageInterval).column(ColumnHint.RIGHT),
FieldDef.section("ability.section.beam"),
@@ -215,17 +215,18 @@ public class AbilitySweeper extends Ability implements IAbilitySweeper {
.hover("ability.hover.piercing").column(ColumnHint.LEFT),
FieldDef.boolField("ability.lockTarget", this::isLockOnTarget, this::setLockOnTarget)
.hover("ability.hover.lockTarget").column(ColumnHint.RIGHT),
FieldDef.effectsListField("ability.effects", this::getEffects, this::setEffects),
AbilityFieldDefs.effectsListField("ability.effects", this::getEffects, this::setEffects),
// Visual tab
FieldDef.section("ability.section.colors").customTab("ability.tab.visual"),
FieldDef.section("ability.section.colors").tab("ability.tab.visual"),
FieldDef.colorSubGui("ability.innerColor", this::getInnerColor, this::setInnerColor)
.customTab("ability.tab.visual"),
.tab("ability.tab.visual"),
FieldDef.boolField("ability.outerEnabled", this::isOuterColorEnabled, this::setOuterColorEnabled)
.customTab("ability.tab.visual"),
.tab("ability.tab.visual"),
FieldDef.colorSubGui("ability.outerColor", this::getOuterColor, this::setOuterColor)
.customTab("ability.tab.visual").visibleWhen(this::isOuterColorEnabled),
.tab("ability.tab.visual").visibleWhen(this::isOuterColorEnabled),
FieldDef.floatField("ability.outerWidth", this::getOuterColorWidth, this::setOuterColorWidth)
.customTab("ability.tab.visual").visibleWhen(this::isOuterColorEnabled)
.tab("ability.tab.visual").visibleWhen(this::isOuterColorEnabled)
);
}
}
@@ -16,9 +16,12 @@ import noppes.npcs.entity.EntityNPCInterface;
import noppes.npcs.api.ability.type.IAbilityTeleport;
import kamkeel.npcs.controllers.data.ability.gui.ColumnHint;
import kamkeel.npcs.controllers.data.ability.gui.FieldDef;
import kamkeel.npcs.controllers.data.ability.gui.TabTarget;
import noppes.npcs.client.gui.builder.ColumnHint;
import noppes.npcs.client.gui.builder.FieldDef;
import kamkeel.npcs.controllers.data.ability.gui.AbilityFieldDefs;
import cpw.mods.fml.relauncher.Side;
import cpw.mods.fml.relauncher.SideOnly;
import java.util.Arrays;
import java.util.List;
@@ -82,11 +85,6 @@ public class AbilityTeleport extends Ability implements IAbilityTeleport {
this.activeSound = "mob.endermen.portal";
}
@Override
public boolean hasTypeSettings() {
return true;
}
@Override
public boolean isTargetingModeLocked() {
return true;
@@ -559,6 +557,7 @@ public class AbilityTeleport extends Ability implements IAbilityTeleport {
this.damageRadius = damageRadius;
}
@SideOnly(Side.CLIENT)
@Override
public List<FieldDef> getFieldDefinitions() {
return Arrays.asList(
@@ -581,7 +580,7 @@ public class AbilityTeleport extends Ability implements IAbilityTeleport {
.hover("ability.hover.dmgAtStart").column(ColumnHint.LEFT),
FieldDef.boolField("ability.damageAtEnd", this::isDamageAtEnd, this::setDamageAtEnd)
.hover("ability.hover.dmgAtEnd").column(ColumnHint.RIGHT),
FieldDef.effectsListField("ability.effects", this::getEffects, this::setEffects)
AbilityFieldDefs.effectsListField("ability.effects", this::getEffects, this::setEffects)
);
}
}
@@ -14,9 +14,12 @@ import noppes.npcs.entity.EntityNPCInterface;
import noppes.npcs.api.ability.type.IAbilityTrap;
import kamkeel.npcs.controllers.data.ability.gui.ColumnHint;
import kamkeel.npcs.controllers.data.ability.gui.FieldDef;
import kamkeel.npcs.controllers.data.ability.gui.TabTarget;
import noppes.npcs.client.gui.builder.ColumnHint;
import noppes.npcs.client.gui.builder.FieldDef;
import kamkeel.npcs.controllers.data.ability.gui.AbilityFieldDefs;
import cpw.mods.fml.relauncher.Side;
import cpw.mods.fml.relauncher.SideOnly;
import java.util.Arrays;
import java.util.HashSet;
@@ -83,11 +86,6 @@ public class AbilityTrap extends Ability implements IAbilityTrap {
this.telegraphType = TelegraphType.CIRCLE;
}
@Override
public boolean hasTypeSettings() {
return true;
}
@Override
public boolean isTargetingModeLocked() {
return true;
@@ -469,6 +467,7 @@ public class AbilityTrap extends Ability implements IAbilityTrap {
return armed;
}
@SideOnly(Side.CLIENT)
@Override
public List<FieldDef> getFieldDefinitions() {
return Arrays.asList(
@@ -485,7 +484,7 @@ public class AbilityTrap extends Ability implements IAbilityTrap {
FieldDef.floatField("enchantment.damage", this::getDamage, this::setDamage).column(ColumnHint.LEFT),
FieldDef.floatField("gui.radius", this::getDamageRadius, this::setDamageRadius).column(ColumnHint.RIGHT),
FieldDef.floatField("ability.knockback", this::getKnockback, this::setKnockback),
FieldDef.effectsListField("ability.effects", this::getEffects, this::setEffects)
AbilityFieldDefs.effectsListField("ability.effects", this::getEffects, this::setEffects)
);
}
}
@@ -10,11 +10,14 @@ import net.minecraft.util.AxisAlignedBB;
import net.minecraft.world.World;
import noppes.npcs.entity.EntityNPCInterface;
import kamkeel.npcs.controllers.data.ability.gui.ColumnHint;
import kamkeel.npcs.controllers.data.ability.gui.FieldDef;
import kamkeel.npcs.controllers.data.ability.gui.TabTarget;
import noppes.npcs.client.gui.builder.ColumnHint;
import noppes.npcs.client.gui.builder.FieldDef;
import kamkeel.npcs.controllers.data.ability.gui.AbilityFieldDefs;
import noppes.npcs.api.ability.type.IAbilityVortex;
import cpw.mods.fml.relauncher.Side;
import cpw.mods.fml.relauncher.SideOnly;
import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
@@ -61,11 +64,6 @@ public class AbilityVortex extends Ability implements IAbilityVortex {
this.activeSound = "mob.ghast.fireball";
}
@Override
public boolean hasTypeSettings() {
return true;
}
@Override
public boolean isTargetingModeLocked() {
return true;
@@ -302,6 +300,7 @@ public class AbilityVortex extends Ability implements IAbilityVortex {
this.pullDamage = pullDamage;
}
@SideOnly(Side.CLIENT)
@Override
public List<FieldDef> getFieldDefinitions() {
return Arrays.asList(
@@ -320,7 +319,7 @@ public class AbilityVortex extends Ability implements IAbilityVortex {
.hover("ability.hover.dmgOnPull"),
FieldDef.floatField("enchantment.damage", this::getPullDamage, this::setPullDamage)
.visibleWhen(this::isDamageOnPull),
FieldDef.effectsListField("ability.effects", this::getEffects, this::setEffects)
AbilityFieldDefs.effectsListField("ability.effects", this::getEffects, this::setEffects)
);
}
}
@@ -3,10 +3,9 @@ package noppes.npcs.client.gui.advanced;
import kamkeel.npcs.controllers.data.ability.Ability;
import kamkeel.npcs.controllers.data.ability.AbilityEffect;
import kamkeel.npcs.controllers.data.ability.Condition;
import kamkeel.npcs.controllers.data.ability.gui.FieldDef;
import kamkeel.npcs.controllers.data.ability.gui.FieldDefinitionsBuilder;
import kamkeel.npcs.controllers.data.ability.gui.FieldType;
import kamkeel.npcs.controllers.data.ability.gui.TabTarget;
import kamkeel.npcs.controllers.data.ability.gui.AbilityFieldBuilder;
import noppes.npcs.client.gui.builder.FieldDef;
import noppes.npcs.client.gui.builder.FieldType;
import net.minecraft.client.gui.GuiButton;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.util.StatCollector;
@@ -36,6 +35,12 @@ public class SubGuiAbilityConfig extends SubGuiInterface implements ITextfieldLi
private static final int TAB_EFFECTS = 3;
// Custom tabs start at index 4
// Tab name strings (matching FieldDef.tab() values)
private static final String TAB_NAME_GENERAL = "General";
private static final String TAB_NAME_TYPE = "Type";
private static final String TAB_NAME_TARGET = "Target";
private static final String TAB_NAME_EFFECTS = "Effects";
private static final int L_LABEL_X = 5;
private static final int ROW_H = 24;
@@ -49,7 +54,7 @@ public class SubGuiAbilityConfig extends SubGuiInterface implements ITextfieldLi
private List<Condition> conditions;
private int editingConditionIndex = -1;
private FieldDefinitionsBuilder builder;
private AbilityFieldBuilder builder;
private FieldDef activeSubGuiField = null;
// Scroll position preservation per tab
@@ -71,9 +76,14 @@ public class SubGuiAbilityConfig extends SubGuiInterface implements ITextfieldLi
private void discoverCustomTabs() {
customTabNames = new ArrayList<>();
for (FieldDef def : fieldDefs) {
if (def.getTab() == TabTarget.CUSTOM && def.getCustomTabName() != null
&& !customTabNames.contains(def.getCustomTabName())) {
customTabNames.add(def.getCustomTabName());
String tab = def.getTab();
if (tab != null
&& !TAB_NAME_GENERAL.equals(tab)
&& !TAB_NAME_TYPE.equals(tab)
&& !TAB_NAME_TARGET.equals(tab)
&& !TAB_NAME_EFFECTS.equals(tab)
&& !customTabNames.contains(tab)) {
customTabNames.add(tab);
}
}
tabScrollY = new float[4 + customTabNames.size()];
@@ -125,40 +135,39 @@ public class SubGuiAbilityConfig extends SubGuiInterface implements ITextfieldLi
GuiMenuTopButton closeBtn = new GuiMenuTopButton(-1000, guiLeft + xSize - 22, guiTop - 17, "X");
addTopButton(closeBtn);
// Scroll window
// Build scroll window dimensions
int swX = guiLeft + 4;
int swY = guiTop + 5;
int swW = xSize - 8;
int swH = ySize - 10;
GuiScrollWindow sw = new GuiScrollWindow(this, swX, swY, swW, swH, 0);
sw.backgroundColor = 0x88000000;
addScrollableGui(0, sw);
int y = 5;
int labelCounter = LABEL_ID_START;
// General tab: type label at top
// General tab: type label at top — need to reserve space before building
if (activeTab == TAB_GENERAL) {
sw.addLabel(new GuiNpcLabel(labelCounter++, "gui.type", 5, y + 5, 0xFFFFFF));
sw.addLabel(new GuiNpcLabel(labelCounter++, ability.getTypeId(), 55, y + 5, 0xFFFFFF));
y += ROW_H;
}
// Build declarative fields using the builder
// Build declarative fields into an auto-created scroll window
List<FieldDef> tabFields = getVisibleFieldsForTab(activeTab);
builder = new FieldDefinitionsBuilder(this, sw, fontRendererObj)
.startIds(DECLARATIVE_ID_START, CLEAR_ID_START, labelCounter)
.startY(y);
builder = new AbilityFieldBuilder(this, fontRendererObj);
builder.startIds(DECLARATIVE_ID_START, CLEAR_ID_START, labelCounter);
builder.startY(y);
y = builder.build(tabFields);
GuiScrollWindow sw = builder.buildScrollWindow(tabFields, swX, swY, swW, swH);
// Conditions on target tab
if (activeTab == TAB_TARGET) {
y = renderConditions(sw, y, builder.getNextLabelId());
// General tab: add type label at top of scroll window
if (activeTab == TAB_GENERAL) {
sw.addLabel(new GuiNpcLabel(builder.getNextLabelId(), "gui.type", 5, 5 + 5, 0xFFFFFF));
sw.addLabel(new GuiNpcLabel(builder.getNextLabelId() + 1, ability.getTypeId(), 55, 5 + 5, 0xFFFFFF));
}
sw.maxScrollY = Math.max(y - swH, 0);
// Conditions on target tab — appended after field defs
if (activeTab == TAB_TARGET) {
int condY = renderConditions(sw, builder.getLastBuildY(), builder.getNextLabelId());
sw.maxScrollY = Math.max(condY - swH, 0);
}
// Restore scroll position
if (activeTab < tabScrollY.length) {
@@ -171,33 +180,27 @@ public class SubGuiAbilityConfig extends SubGuiInterface implements ITextfieldLi
private List<FieldDef> getVisibleFieldsForTab(int tabIndex) {
List<FieldDef> result = new ArrayList<>();
String tabName;
if (tabIndex >= 4) {
// Custom tab — match by custom tab name
int customIndex = tabIndex - 4;
if (customIndex >= 0 && customIndex < customTabNames.size()) {
String tabName = customTabNames.get(customIndex);
for (FieldDef def : fieldDefs) {
if (def.getTab() == TabTarget.CUSTOM
&& tabName.equals(def.getCustomTabName())
&& def.isVisible()) {
result.add(def);
}
}
tabName = customTabNames.get(customIndex);
} else {
return result;
}
} else {
// Fixed tab
TabTarget target;
switch (tabIndex) {
case TAB_GENERAL: target = TabTarget.GENERAL; break;
case TAB_TYPE: target = TabTarget.TYPE; break;
case TAB_TARGET: target = TabTarget.TARGET; break;
case TAB_EFFECTS: target = TabTarget.EFFECTS; break;
default: target = TabTarget.TYPE; break;
case TAB_GENERAL: tabName = TAB_NAME_GENERAL; break;
case TAB_TYPE: tabName = TAB_NAME_TYPE; break;
case TAB_TARGET: tabName = TAB_NAME_TARGET; break;
case TAB_EFFECTS: tabName = TAB_NAME_EFFECTS; break;
default: tabName = TAB_NAME_TYPE; break;
}
for (FieldDef def : fieldDefs) {
if (def.getTab() == target && def.isVisible()) {
result.add(def);
}
}
for (FieldDef def : fieldDefs) {
if (tabName.equals(def.getTab()) && def.isVisible()) {
result.add(def);
}
}
@@ -0,0 +1,11 @@
package noppes.npcs.client.gui.builder;
import cpw.mods.fml.relauncher.Side;
import cpw.mods.fml.relauncher.SideOnly;
@SideOnly(Side.CLIENT)
public enum ColumnHint {
FULL,
LEFT,
RIGHT
}
@@ -1,26 +1,29 @@
package kamkeel.npcs.controllers.data.ability.gui;
package noppes.npcs.client.gui.builder;
import kamkeel.npcs.controllers.data.ability.AbilityEffect;
import cpw.mods.fml.relauncher.Side;
import cpw.mods.fml.relauncher.SideOnly;
import noppes.npcs.controllers.AnimationController;
import noppes.npcs.controllers.data.Animation;
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.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.
* Declarative field definition for GUI rendering.
* Built via static factories and chaining methods.
* Client-side only — never instantiate or reference on the server.
*/
@SideOnly(Side.CLIENT)
public class FieldDef {
private final String label;
private final FieldType type;
private TabTarget tab = TabTarget.TYPE;
private String customTabName = null;
private String tab = null;
private ColumnHint column = ColumnHint.FULL;
private Supplier<Object> getter;
private Consumer<Object> setter;
@@ -112,14 +115,6 @@ public class FieldDef {
return def;
}
@SuppressWarnings("unchecked")
public static FieldDef effectsListField(String label, Supplier<List<AbilityEffect>> getter, Consumer<List<AbilityEffect>> setter) {
FieldDef def = new FieldDef(label, FieldType.EFFECTS_LIST);
def.getter = () -> getter.get();
def.setter = v -> setter.accept((List<AbilityEffect>) v);
return def;
}
public static FieldDef subGuiField(String label, Supplier<SubGuiInterface> factory, Consumer<SubGuiInterface> resultHandler) {
FieldDef def = new FieldDef(label, FieldType.SUB_GUI);
def.subGuiFactory = factory;
@@ -127,6 +122,18 @@ public class FieldDef {
return def;
}
/**
* Creates a FieldDef with a custom FieldType. Used by extension code
* (e.g. AbilityFieldDefs) to create fields with types like EFFECTS_LIST
* that the base GuiFieldBuilder does not handle.
*/
public static FieldDef custom(String label, FieldType type, Supplier<Object> getter, Consumer<Object> setter) {
FieldDef def = new FieldDef(label, type);
def.getter = getter;
def.setter = setter;
return def;
}
// ═══════════════════════════════════════════════════════════════════
// CONVENIENCE FACTORIES (SUB_GUI wrappers)
// ═══════════════════════════════════════════════════════════════════
@@ -172,7 +179,14 @@ public class FieldDef {
String name = nameGetter.get();
if (name != null && !name.isEmpty()) return name;
int id = idGetter.get();
return id >= 0 ? "ID: " + id : "gui.none";
if (id >= 0) {
Animation anim = AnimationController.Instance != null
? (Animation) AnimationController.Instance.get(id) : null;
String animName = anim != null ? anim.getName() : "";
return animName != null && !animName.isEmpty()
? "(ID: " + id + ") " + animName : "ID: " + id;
}
return "gui.none";
})
.clearable(() -> { idSetter.accept(-1); nameSetter.accept(""); });
}
@@ -181,14 +195,8 @@ public class FieldDef {
// CHAINING METHODS
// ═══════════════════════════════════════════════════════════════════
public FieldDef tab(TabTarget tab) {
this.tab = tab;
return this;
}
public FieldDef customTab(String tabName) {
this.tab = TabTarget.CUSTOM;
this.customTabName = tabName;
public FieldDef tab(String tabName) {
this.tab = tabName;
return this;
}
@@ -244,8 +252,7 @@ public class FieldDef {
public String getLabel() { return label; }
public FieldType getType() { return type; }
public TabTarget getTab() { return tab; }
public String getCustomTabName() { return customTabName; }
public String getTab() { return tab; }
public ColumnHint getColumn() { return column; }
public boolean isVisible() { return visibleWhen.getAsBoolean(); }
public boolean isEnabled() { return enabledWhen.getAsBoolean(); }
@@ -1,5 +1,9 @@
package kamkeel.npcs.controllers.data.ability.gui;
package noppes.npcs.client.gui.builder;
import cpw.mods.fml.relauncher.Side;
import cpw.mods.fml.relauncher.SideOnly;
@SideOnly(Side.CLIENT)
public enum FieldType {
FLOAT,
INT,
@@ -1,62 +1,68 @@
package kamkeel.npcs.controllers.data.ability.gui;
package noppes.npcs.client.gui.builder;
import kamkeel.npcs.controllers.data.ability.AbilityEffect;
import cpw.mods.fml.relauncher.Side;
import cpw.mods.fml.relauncher.SideOnly;
import net.minecraft.client.gui.FontRenderer;
import net.minecraft.client.gui.GuiScreen;
import net.minecraft.util.StatCollector;
import noppes.npcs.client.gui.util.GuiNPCInterface;
import noppes.npcs.client.gui.util.GuiNpcButton;
import noppes.npcs.client.gui.util.GuiNpcButtonYesNo;
import noppes.npcs.client.gui.util.GuiNpcLabel;
import noppes.npcs.client.gui.util.GuiNpcTextField;
import noppes.npcs.client.gui.util.GuiScrollWindow;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* Reusable builder that converts a list of {@link FieldDef} into positioned
* General-purpose builder that converts a list of {@link FieldDef} into positioned
* GUI widgets inside a {@link GuiScrollWindow}.
* <p>
* Supports 1-column and 2-column layouts. Subclasses can override {@link #buildField}
* to handle custom field types.
*/
public class FieldDefinitionsBuilder {
@SideOnly(Side.CLIENT)
public class GuiFieldBuilder {
// Layout defaults
private int contentRight = 330;
private int colLLabel = 5;
private int colLField = 75;
private int colLWidth = 70;
private int colRLabel = 178;
private int colRField = 248;
private int colRWidth = 70;
private int rowHeight = 24;
private int labelPadding = 8;
// Layout defaults (2-column mode)
protected int contentRight = 330;
protected int colLLabel = 5;
protected int colLField = 75;
protected int colLWidth = 70;
protected int colRLabel = 178;
protected int colRField = 248;
protected int colRWidth = 70;
protected int rowHeight = 24;
protected int labelPadding = 8;
// Column mode
protected int columnCount = 2;
// Dependencies
private final GuiScreen parent;
private final GuiScrollWindow sw;
private final FontRenderer fontRenderer;
protected final GuiNPCInterface parent;
protected GuiScrollWindow sw;
protected final FontRenderer fontRenderer;
// Scroll window ID
protected int scrollWindowId = 0;
// ID counters
private int widgetId;
private int clearId;
private int labelId;
protected int widgetId;
protected int clearId;
protected int labelId;
// Starting Y
private int startY = 5;
protected int startY = 5;
protected int lastBuildY = 0;
// Output maps
private final Map<Integer, FieldDef> buttonFieldMap = new HashMap<>();
private final Map<Integer, FieldDef> textFieldMap = new HashMap<>();
private final Map<Integer, FieldDef> clearFieldMap = new HashMap<>();
protected final Map<Integer, FieldDef> buttonFieldMap = new HashMap<>();
protected final Map<Integer, FieldDef> textFieldMap = new HashMap<>();
protected final Map<Integer, FieldDef> clearFieldMap = new HashMap<>();
// Effects list metadata: widgetId -> [effectIndex, action]
// action: 0=type, 1=duration(text), 2=amp, 3=delete, 4=add
private final Map<Integer, int[]> effectWidgetMeta = new HashMap<>();
public FieldDefinitionsBuilder(GuiScreen parent, GuiScrollWindow sw, FontRenderer fontRenderer) {
public GuiFieldBuilder(GuiNPCInterface parent, FontRenderer fontRenderer) {
this.parent = parent;
this.sw = sw;
this.fontRenderer = fontRenderer;
}
@@ -64,32 +70,58 @@ public class FieldDefinitionsBuilder {
// CONFIG CHAINING
// ═══════════════════════════════════════════════════════════════════
public FieldDefinitionsBuilder contentRight(int v) { this.contentRight = v; return this; }
public FieldDefinitionsBuilder startIds(int widget, int clear, int label) {
public GuiFieldBuilder scrollWindowId(int id) { this.scrollWindowId = id; return this; }
public GuiFieldBuilder columns(int count) { this.columnCount = Math.max(1, Math.min(2, count)); return this; }
public GuiFieldBuilder contentRight(int v) { this.contentRight = v; return this; }
public GuiFieldBuilder startIds(int widget, int clear, int label) {
this.widgetId = widget; this.clearId = clear; this.labelId = label; return this;
}
public FieldDefinitionsBuilder startY(int y) { this.startY = y; return this; }
public FieldDefinitionsBuilder rowHeight(int h) { this.rowHeight = h; return this; }
public GuiFieldBuilder startY(int y) { this.startY = y; return this; }
public GuiFieldBuilder rowHeight(int h) { this.rowHeight = h; return this; }
// ═══════════════════════════════════════════════════════════════════
// BUILD
// ═══════════════════════════════════════════════════════════════════
/**
* Creates a {@link GuiScrollWindow} at the given position/size, builds all fields into it,
* and sets maxScrollY automatically. The returned window is ready to use.
*/
public GuiScrollWindow buildScrollWindow(List<FieldDef> fields, int x, int y, int width, int height) {
this.sw = new GuiScrollWindow(parent, x, y, width, height, 0);
sw.backgroundColor = 0x88000000;
// Register with parent first — this calls initGui() which clears widget lists,
// so we must add widgets AFTER this point
parent.addScrollableGui(scrollWindowId, sw);
int finalY = build(fields);
sw.maxScrollY = Math.max(finalY - height, 0);
return sw;
}
/**
* Processes all fields and adds widgets to the scroll window.
* @return the final Y position after all fields
*/
public int build(List<FieldDef> fields) {
protected int build(List<FieldDef> fields) {
buttonFieldMap.clear();
textFieldMap.clear();
clearFieldMap.clear();
effectWidgetMeta.clear();
int y = startY;
for (int i = 0; i < fields.size(); i++) {
FieldDef def = fields.get(i);
// Let subclasses handle custom types; returns -1 if not handled
int customResult = buildField(def, y, fields, i);
if (customResult >= 0) {
// Subclass handled it, check if index was advanced
int newIndex = getLastHandledIndex();
if (newIndex > i) i = newIndex;
y = customResult;
continue;
}
// Section header
if (def.getType() == FieldType.SECTION_HEADER) {
y += 3;
@@ -102,14 +134,9 @@ public class FieldDefinitionsBuilder {
continue;
}
// Effects list renders its own multi-row block
if (def.getType() == FieldType.EFFECTS_LIST) {
y = renderEffectsList(def, y);
continue;
}
// Two-column pair: LEFT followed by RIGHT
if (def.getColumn() == ColumnHint.LEFT
// Two-column pair: LEFT followed by RIGHT (only in 2-column mode)
if (columnCount == 2
&& def.getColumn() == ColumnHint.LEFT
&& i + 1 < fields.size()
&& fields.get(i + 1).getColumn() == ColumnHint.RIGHT
&& fields.get(i + 1).getType() != FieldType.SECTION_HEADER) {
@@ -132,15 +159,29 @@ public class FieldDefinitionsBuilder {
}
}
lastBuildY = y;
return y;
}
/**
* Hook for subclasses to handle custom field types (e.g. EFFECTS_LIST).
* Return the new Y position if handled, or -1 if not handled (base class will process it).
* If handling advances the field index, call {@link #setLastHandledIndex(int)}.
*/
protected int buildField(FieldDef def, int y, List<FieldDef> fields, int index) {
return -1;
}
private int lastHandledIndex = -1;
protected void setLastHandledIndex(int index) { this.lastHandledIndex = index; }
protected int getLastHandledIndex() { return lastHandledIndex; }
// ═══════════════════════════════════════════════════════════════════
// FIELD RENDERING
// ═══════════════════════════════════════════════════════════════════
@SuppressWarnings({"unchecked", "rawtypes"})
private void renderFieldAt(FieldDef def, int labelX, int fieldX, int fieldW, int y) {
protected void renderFieldAt(FieldDef def, int labelX, int fieldX, int fieldW, int y) {
sw.addLabel(new GuiNpcLabel(labelId++, def.getLabel(), labelX, y + 5, 0xFFFFFF));
String hover = def.getHoverText() != null ? def.getHoverText() : def.getTooltip();
@@ -193,9 +234,6 @@ public class FieldDefinitionsBuilder {
case BOOLEAN: {
boolean bVal = def.getValue() instanceof Boolean ? (Boolean) def.getValue() : false;
GuiNpcButtonYesNo btn = new GuiNpcButtonYesNo(widgetId, fieldX, y, fieldW, 20, bVal);
if ("gui.enabled".equals(def.getLabel()) && def.getTab() == TabTarget.GENERAL) {
btn.setTextColor(bVal ? 0x00FF00 : 0xFF0000);
}
if (!def.isEnabled()) btn.setEnabled(false);
if (hover != null) btn.setHoverText(hover);
sw.addButton(btn);
@@ -261,79 +299,15 @@ public class FieldDefinitionsBuilder {
clearId++;
break;
}
default:
// Unknown type — skip, incrementing IDs to stay in sync
widgetId++;
clearId++;
break;
}
}
// ═══════════════════════════════════════════════════════════════════
// EFFECTS LIST RENDERING
// ═══════════════════════════════════════════════════════════════════
@SuppressWarnings("unchecked")
private int renderEffectsList(FieldDef def, int y) {
// Section header
y += 3;
sw.addLabel(new GuiNpcLabel(labelId++, def.getLabel(), colLLabel, y + 2, 0xFFFF55));
y += 15;
List<AbilityEffect> effects = (List<AbilityEffect>) def.getValue();
if (effects == null) effects = new ArrayList<>();
String[] typeNames = AbilityEffect.EffectType.getLangKeys();
String[] ampValues = {"0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "10"};
for (int e = 0; e < effects.size() && e < 5; e++) {
AbilityEffect effect = effects.get(e);
// Type selector button
int typeIdx = effect.getType().ordinal();
GuiNpcButton typeBtn = new GuiNpcButton(widgetId, colLLabel, y, 100, 20, typeNames, typeIdx);
sw.addButton(typeBtn);
buttonFieldMap.put(widgetId, def);
effectWidgetMeta.put(widgetId, new int[]{e, 0});
widgetId++;
// Duration text field
GuiNpcTextField durField = new GuiNpcTextField(widgetId, parent, fontRenderer,
colLLabel + 104, y, 50, 20, String.valueOf(effect.getDurationTicks()));
durField.setIntegersOnly();
durField.setMinMaxDefault(1, 12000, 60);
sw.addTextField(durField);
textFieldMap.put(widgetId, def);
effectWidgetMeta.put(widgetId, new int[]{e, 1});
widgetId++;
// Amplifier selector (0-10)
GuiNpcButton ampBtn = new GuiNpcButton(widgetId, colLLabel + 158, y, 40, 20, ampValues, effect.getAmplifier());
sw.addButton(ampBtn);
buttonFieldMap.put(widgetId, def);
effectWidgetMeta.put(widgetId, new int[]{e, 2});
widgetId++;
// Delete button
GuiNpcButton delBtn = new GuiNpcButton(clearId, colLLabel + 202, y, 20, 20, "X");
sw.addButton(delBtn);
clearFieldMap.put(clearId, def);
effectWidgetMeta.put(clearId, new int[]{e, 3});
clearId++;
y += rowHeight;
}
// Add button (if < 5 effects)
if (effects.size() < 5) {
GuiNpcButton addBtn = new GuiNpcButton(widgetId, colLLabel, y, 50, 20, "gui.add");
sw.addButton(addBtn);
buttonFieldMap.put(widgetId, def);
effectWidgetMeta.put(widgetId, new int[]{effects.size(), 4});
widgetId++;
clearId++;
y += rowHeight;
}
return y;
}
private int getFullFieldWidth(FieldDef def) {
protected int getFullFieldWidth(FieldDef def) {
switch (def.getType()) {
case FLOAT:
case INT: return 60;
@@ -354,6 +328,7 @@ public class FieldDefinitionsBuilder {
public Map<Integer, FieldDef> getButtonFieldMap() { return buttonFieldMap; }
public Map<Integer, FieldDef> getTextFieldMap() { return textFieldMap; }
public Map<Integer, FieldDef> getClearFieldMap() { return clearFieldMap; }
public Map<Integer, int[]> getEffectWidgetMeta() { return effectWidgetMeta; }
public GuiScrollWindow getScrollWindow() { return sw; }
public int getLastBuildY() { return lastBuildY; }
public int getNextLabelId() { return labelId; }
}
@@ -55,7 +55,6 @@ public class GuiAnimationSelection extends SubGuiInterface implements ICustomScr
* Constructor for selecting by name (built-in) or ID (user).
*/
public GuiAnimationSelection(int animationId, String animationName) {
drawDefaultBackground = false;
title = "";
setBackground("menubg.png");
xSize = 220;
@@ -39,7 +39,6 @@ public class GuiSoundSelection extends SubGuiInterface implements ICustomScrollL
public static HashMap<String, List<String>> cachedDomains = new HashMap<>();
public GuiSoundSelection(String sound) {
drawDefaultBackground = false;
title = "";
setBackground("menubg.png");
xSize = 366;
@@ -104,8 +104,10 @@ public class GuiCustomScroll extends GuiScreen {
GL11.glTranslatef(guiLeft, guiTop, 0.0F);
GL11.glColor4f(1.0F, 1.0F, 1.0F, 1.0F);
if (selectable)
if (selectable && !hasSubGUI)
hover = getMouseOver(i, j);
else if (hasSubGUI)
hover = -1;
drawItems();
@@ -97,6 +97,11 @@ public class GuiScrollWindow extends GuiScreen implements ITextfieldListener, IC
}
public void mouseClicked(int i, int j, int k) {
// Ignore clicks outside the visible scroll window area
if (i < xPos || i > xPos + clipWidth || j < yPos || j > yPos + clipHeight) {
return;
}
i = i - xPos;
j = (int) (j - yPos + scrollY);
@@ -246,6 +251,12 @@ public class GuiScrollWindow extends GuiScreen implements ITextfieldListener, IC
}
GL11.glPopMatrix();
// Draw hover texts in screen space (after scissor/translation are undone)
// so tooltips are not clipped and are positioned correctly
if (isMouseOver(mouseX, mouseY)) {
drawHoverTexts(mouseX, mouseY);
}
}
public void drawScreen(int mouseX, int mouseY, float partialTicks, int mouseScroll) {
@@ -275,8 +286,18 @@ public class GuiScrollWindow extends GuiScreen implements ITextfieldListener, IC
}
for (GuiNpcButton button : buttons.values()) {
button.updateSubGUI(subGui);
}
}
/**
* Draws hover texts for buttons in screen space (called after GL scissor/translate are undone).
* Hover state was already computed during drawComponents with scroll-local coords.
*/
private void drawHoverTexts(int mouseX, int mouseY) {
boolean subGui = parent.hasSubGui();
for (GuiNpcButton button : buttons.values()) {
if (!button.hoverableText.isEmpty()) {
button.drawHover(i, j, subGui);
button.drawHover(mouseX, mouseY, subGui);
}
}
}