Keep client-only sub-GUI types out of Ability's method descriptors

The magic editor field was built with lambdas inside Ability.getAllDefinitions.
subGuiField is generic, so those lambdas took SubGuiAbilityMagic as their
descriptor type. @SideOnly strips the annotated method on a server but not the
synthetic lambdas it generates, so anything reflecting over Ability's declared
methods - Nashorn's adapter generator when a script touches an ability - hit
NoClassDefFoundError. Building the field in the client class keeps the type out
of Ability entirely.
This commit is contained in:
KAMKEEL committed 2026-08-11 04:44:14 -04:00
1 parent c79f5998d6
commit dedbe94cd8
2 files changed
+28 -13

No files matched your search

@@ -840,19 +840,7 @@ public abstract class Ability implements IAbility, IAbilityAction {
return sb.toString();
}).tab("General"));
defs.add(FieldDef.subGuiField("ability.magic.editor",
() -> new SubGuiAbilityMagic(magicData.copy()),
gui -> {
MagicData result = ((SubGuiAbilityMagic) gui).magicData;
magicData.getMagics().clear();
for (Map.Entry<Integer, MagicEntry> e : result.getMagics().entrySet()) {
magicData.getMagics().put(e.getKey(), e.getValue());
}
})
.buttonLabel(() -> magicData.isEmpty()
? StatCollector.translateToLocal("ability.magic.usesCaster")
: magicData.getMagics().size() + " Magic(s)")
.tab("General"));
defs.add(SubGuiAbilityMagic.createMagicField(magicData));
}
// ── Target tab ───────────────────────────────────────────────
@@ -1,6 +1,8 @@
package noppes.npcs.client.gui.advanced;
import net.minecraft.client.gui.GuiButton;
import net.minecraft.util.StatCollector;
import noppes.npcs.client.gui.builder.FieldDef;
import noppes.npcs.client.gui.util.GuiCustomScroll;
import noppes.npcs.client.gui.util.GuiNpcButton;
import noppes.npcs.client.gui.util.GuiNpcLabel;
@@ -11,6 +13,7 @@ import noppes.npcs.client.gui.util.SubGuiInterface;
import noppes.npcs.controllers.MagicController;
import noppes.npcs.controllers.data.Magic;
import noppes.npcs.controllers.data.MagicData;
import noppes.npcs.controllers.data.MagicEntry;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
@@ -36,6 +39,30 @@ public class SubGuiAbilityMagic extends SubGuiInterface implements ICustomScroll
private GuiNpcTextField splitField;
/**
* Builds the ability editor's magic field.
* <p>
* This lives here rather than in Ability because the lambdas below carry this class in
* their method descriptors. Ability is a both-side class, and anything reflecting over its
* declared methods on a server - Nashorn's adapter generator, for one - would resolve those
* descriptors and fail to find this client-only type.
*/
public static FieldDef createMagicField(MagicData magicData) {
return FieldDef.subGuiField("ability.magic.editor",
() -> new SubGuiAbilityMagic(magicData.copy()),
gui -> {
MagicData result = ((SubGuiAbilityMagic) gui).magicData;
magicData.getMagics().clear();
for (Map.Entry<Integer, MagicEntry> e : result.getMagics().entrySet()) {
magicData.getMagics().put(e.getKey(), e.getValue());
}
})
.buttonLabel(() -> magicData.isEmpty()
? StatCollector.translateToLocal("ability.magic.usesCaster")
: magicData.getMagics().size() + " Magic(s)")
.tab("General");
}
public SubGuiAbilityMagic(MagicData data) {
this.magicData = data;
setBackground("menubg.png");