mirror of
https://github.com/KAMKEEL/CustomNPC-Plus.git
synced 2026-11-12 18:57:32 +00:00
Keep client-only sub-GUI types out of condition and zone descriptors
Same leak as the ability magic editor: @SideOnly strips the annotated method on a server but not the synthetic lambdas it generates, so ConditionHasEffect, ConditionQuestCompleted, AbilityTrap and AbilityZone all shipped methods whose descriptors named a client-only GUI class. Each field is now built in the GUI class it belongs to.
This commit is contained in:
1 parent
466b49db5e
commit
677d50fa03
8 files changed
+104
-49
No files matched your search
+7
-19
@@ -34,27 +34,15 @@ public class ConditionHasEffect extends AbilityCondition {
|
||||
return CustomEffectController.getInstance().hasEffect(player, effectId, effectIndex);
|
||||
}
|
||||
|
||||
public void setEffect(int effectId, int effectIndex) {
|
||||
this.effectId = effectId;
|
||||
this.effectIndex = effectIndex;
|
||||
}
|
||||
|
||||
@SideOnly(Side.CLIENT)
|
||||
@Override
|
||||
public void getConditionDefinitions(List<FieldDef> defs) {
|
||||
defs.add(FieldDef.subGuiField("condition.select_effect",
|
||||
() -> new SubGuiCustomEffectSelect(effectId, effectIndex),
|
||||
gui -> {
|
||||
SubGuiCustomEffectSelect sel = (SubGuiCustomEffectSelect) gui;
|
||||
if (sel.getSelectedEffectId() >= 0) {
|
||||
effectId = sel.getSelectedEffectId();
|
||||
effectIndex = sel.getSelectedIndex();
|
||||
}
|
||||
})
|
||||
.buttonLabel(() -> {
|
||||
if (effectId < 0) return "None";
|
||||
CustomEffect effect = getEffect();
|
||||
return effect != null ? effect.getName() : "ID:" + effectId;
|
||||
})
|
||||
.clearable(() -> {
|
||||
effectId = -1;
|
||||
effectIndex = 0;
|
||||
}));
|
||||
defs.add(SubGuiCustomEffectSelect.createSelectField(this));
|
||||
}
|
||||
|
||||
@SideOnly(Side.CLIENT)
|
||||
@@ -74,7 +62,7 @@ public class ConditionHasEffect extends AbilityCondition {
|
||||
return effectId >= 0;
|
||||
}
|
||||
|
||||
private CustomEffect getEffect() {
|
||||
public CustomEffect getEffect() {
|
||||
HashMap<Integer, CustomEffect> map = CustomEffectController.getInstance().getEffectMap(effectIndex);
|
||||
return map != null ? map.get(effectId) : null;
|
||||
}
|
||||
|
||||
+1
-14
@@ -38,20 +38,7 @@ public class ConditionQuestCompleted extends AbilityCondition {
|
||||
@SideOnly(Side.CLIENT)
|
||||
@Override
|
||||
public void getConditionDefinitions(List<FieldDef> defs) {
|
||||
defs.add(FieldDef.subGuiField("condition.select_quest",
|
||||
() -> new GuiQuestSelection(questId),
|
||||
gui -> {
|
||||
GuiQuestSelection sel = (GuiQuestSelection) gui;
|
||||
if (sel.selectedQuest != null) {
|
||||
questId = sel.selectedQuest.id;
|
||||
}
|
||||
})
|
||||
.buttonLabel(() -> {
|
||||
if (questId < 0) return "None";
|
||||
Quest q = QuestController.Instance.quests.get(questId);
|
||||
return q != null ? q.title : "ID:" + questId;
|
||||
})
|
||||
.clearable(() -> questId = -1));
|
||||
defs.add(GuiQuestSelection.createConditionField(this));
|
||||
}
|
||||
|
||||
@SideOnly(Side.CLIENT)
|
||||
|
||||
@@ -300,14 +300,7 @@ public class AbilityTrap extends AbilityZone implements IAbilityTrap {
|
||||
@SideOnly(Side.CLIENT)
|
||||
@Override
|
||||
protected void addPresetFieldDef(List<FieldDef> defs) {
|
||||
defs.add(FieldDef.subGuiField("gui.applyPreset",
|
||||
SubGuiTrapPresetSelector::new,
|
||||
gui -> {
|
||||
SubGuiTrapPresetSelector selector = (SubGuiTrapPresetSelector) gui;
|
||||
if (selector.selectedPreset != null) {
|
||||
applyTrapPresetDefaults(selector.selectedPreset);
|
||||
}
|
||||
}));
|
||||
defs.add(SubGuiTrapPresetSelector.createPresetField(this::applyTrapPresetDefaults));
|
||||
}
|
||||
|
||||
@SideOnly(Side.CLIENT)
|
||||
|
||||
@@ -690,14 +690,7 @@ public abstract class AbilityZone extends Ability {
|
||||
|
||||
@SideOnly(Side.CLIENT)
|
||||
protected void addPresetFieldDef(List<FieldDef> defs) {
|
||||
defs.add(FieldDef.subGuiField("gui.applyPreset",
|
||||
SubGuiZonePresetSelector::new,
|
||||
gui -> {
|
||||
SubGuiZonePresetSelector selector = (SubGuiZonePresetSelector) gui;
|
||||
if (selector.selectedPreset != null) {
|
||||
applyPresetDefaults(selector.selectedPreset);
|
||||
}
|
||||
}));
|
||||
defs.add(SubGuiZonePresetSelector.createPresetField(this::applyPresetDefaults));
|
||||
}
|
||||
|
||||
@SideOnly(Side.CLIENT)
|
||||
|
||||
@@ -4,6 +4,7 @@ import cpw.mods.fml.relauncher.Side;
|
||||
import cpw.mods.fml.relauncher.SideOnly;
|
||||
import net.minecraft.client.gui.GuiButton;
|
||||
import net.minecraft.util.StatCollector;
|
||||
import noppes.npcs.client.gui.builder.FieldDef;
|
||||
import noppes.npcs.client.gui.util.GuiNpcButton;
|
||||
import noppes.npcs.client.gui.util.SubGuiInterface;
|
||||
|
||||
@@ -12,6 +13,25 @@ public class SubGuiTrapPresetSelector extends SubGuiInterface {
|
||||
|
||||
public String selectedPreset = null;
|
||||
|
||||
/**
|
||||
* Builds the trap editor's preset field.
|
||||
* <p>
|
||||
* This lives here rather than in AbilityTrap because the lambda below carries this class in
|
||||
* its method descriptor. AbilityTrap is a both-side class, and @SideOnly does not strip the
|
||||
* synthetic lambda methods it generates - so anything reflecting over its declared methods
|
||||
* on a server would resolve that descriptor and fail to find this client-only type.
|
||||
*/
|
||||
public static FieldDef createPresetField(java.util.function.Consumer<String> applyPreset) {
|
||||
return FieldDef.subGuiField("gui.applyPreset",
|
||||
SubGuiTrapPresetSelector::new,
|
||||
gui -> {
|
||||
SubGuiTrapPresetSelector selector = (SubGuiTrapPresetSelector) gui;
|
||||
if (selector.selectedPreset != null) {
|
||||
applyPreset.accept(selector.selectedPreset);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private static final String[] PRESET_NAMES = {"HIDDEN", "VENOM", "EXPLOSIVE", "CURSED", "SHOCK", "SNARE"};
|
||||
private static final String[] PRESET_LABELS = {
|
||||
"ability.preset.hidden", "ability.preset.venom", "ability.preset.explosive",
|
||||
|
||||
@@ -4,6 +4,7 @@ import cpw.mods.fml.relauncher.Side;
|
||||
import cpw.mods.fml.relauncher.SideOnly;
|
||||
import net.minecraft.client.gui.GuiButton;
|
||||
import net.minecraft.util.StatCollector;
|
||||
import noppes.npcs.client.gui.builder.FieldDef;
|
||||
import noppes.npcs.client.gui.util.GuiNpcButton;
|
||||
import noppes.npcs.client.gui.util.SubGuiInterface;
|
||||
|
||||
@@ -12,6 +13,25 @@ public class SubGuiZonePresetSelector extends SubGuiInterface {
|
||||
|
||||
public String selectedPreset = null;
|
||||
|
||||
/**
|
||||
* Builds the zone editor's preset field.
|
||||
* <p>
|
||||
* This lives here rather than in AbilityZone because the lambda below carries this class in
|
||||
* its method descriptor. AbilityZone is a both-side class, and @SideOnly does not strip the
|
||||
* synthetic lambda methods it generates - so anything reflecting over its declared methods
|
||||
* on a server would resolve that descriptor and fail to find this client-only type.
|
||||
*/
|
||||
public static FieldDef createPresetField(java.util.function.Consumer<String> applyPreset) {
|
||||
return FieldDef.subGuiField("gui.applyPreset",
|
||||
SubGuiZonePresetSelector::new,
|
||||
gui -> {
|
||||
SubGuiZonePresetSelector selector = (SubGuiZonePresetSelector) gui;
|
||||
if (selector.selectedPreset != null) {
|
||||
applyPreset.accept(selector.selectedPreset);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private static final String[] PRESET_NAMES = {"DEFAULT", "TOXIC", "INFERNO", "ARCANE", "ELECTRIC", "FROST"};
|
||||
private static final String[] PRESET_LABELS = {
|
||||
"ability.preset.default", "ability.preset.toxic", "ability.preset.inferno",
|
||||
|
||||
@@ -3,6 +3,8 @@ package noppes.npcs.client.gui.advanced;
|
||||
import cpw.mods.fml.relauncher.Side;
|
||||
import cpw.mods.fml.relauncher.SideOnly;
|
||||
import net.minecraft.client.gui.GuiButton;
|
||||
import kamkeel.npcs.controllers.data.ability.conditions.ConditionHasEffect;
|
||||
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.GuiNpcTextField;
|
||||
@@ -25,6 +27,31 @@ import java.util.Map;
|
||||
@SideOnly(Side.CLIENT)
|
||||
public class SubGuiCustomEffectSelect extends SubGuiInterface implements ICustomScrollListener, ITextfieldListener {
|
||||
|
||||
/**
|
||||
* Builds the condition editor's effect-select field.
|
||||
* <p>
|
||||
* This lives here rather than in ConditionHasEffect because the lambdas below carry this
|
||||
* class in their method descriptors. The condition is a both-side class, and @SideOnly does
|
||||
* not strip the synthetic lambda methods it generates - so anything reflecting over its
|
||||
* declared methods on a server would resolve those descriptors and fail to find this type.
|
||||
*/
|
||||
public static FieldDef createSelectField(ConditionHasEffect condition) {
|
||||
return FieldDef.subGuiField("condition.select_effect",
|
||||
() -> new SubGuiCustomEffectSelect(condition.getEffectId(), condition.getEffectIndex()),
|
||||
gui -> {
|
||||
SubGuiCustomEffectSelect sel = (SubGuiCustomEffectSelect) gui;
|
||||
if (sel.getSelectedEffectId() >= 0) {
|
||||
condition.setEffect(sel.getSelectedEffectId(), sel.getSelectedIndex());
|
||||
}
|
||||
})
|
||||
.buttonLabel(() -> {
|
||||
if (condition.getEffectId() < 0) return "None";
|
||||
CustomEffect effect = condition.getEffect();
|
||||
return effect != null ? effect.getName() : "ID:" + condition.getEffectId();
|
||||
})
|
||||
.clearable(() -> condition.setEffect(-1, 0));
|
||||
}
|
||||
|
||||
private GuiCustomScroll scroll;
|
||||
private final HashMap<String, Integer> displayNameToId = new HashMap<>();
|
||||
private final HashMap<String, Integer> allDisplayNameToId = new HashMap<>();
|
||||
|
||||
@@ -2,6 +2,8 @@ package noppes.npcs.client.gui.select;
|
||||
|
||||
import com.google.common.collect.Lists;
|
||||
import net.minecraft.client.gui.GuiButton;
|
||||
import kamkeel.npcs.controllers.data.ability.conditions.ConditionQuestCompleted;
|
||||
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;
|
||||
@@ -27,6 +29,31 @@ public class GuiQuestSelection extends SubGuiInterface implements ICustomScrollL
|
||||
private QuestCategory selectedCategory;
|
||||
public Quest selectedQuest;
|
||||
|
||||
/**
|
||||
* Builds the condition editor's quest-select field.
|
||||
* <p>
|
||||
* This lives here rather than in ConditionQuestCompleted because the lambdas below carry
|
||||
* this class in their method descriptors. The condition is a both-side class, and @SideOnly
|
||||
* does not strip the synthetic lambda methods it generates - so anything reflecting over its
|
||||
* declared methods on a server would resolve those descriptors and fail to find this type.
|
||||
*/
|
||||
public static FieldDef createConditionField(ConditionQuestCompleted condition) {
|
||||
return FieldDef.subGuiField("condition.select_quest",
|
||||
() -> new GuiQuestSelection(condition.getQuestId()),
|
||||
gui -> {
|
||||
GuiQuestSelection sel = (GuiQuestSelection) gui;
|
||||
if (sel.selectedQuest != null) {
|
||||
condition.setQuestId(sel.selectedQuest.id);
|
||||
}
|
||||
})
|
||||
.buttonLabel(() -> {
|
||||
if (condition.getQuestId() < 0) return "None";
|
||||
Quest q = QuestController.Instance.quests.get(condition.getQuestId());
|
||||
return q != null ? q.title : "ID:" + condition.getQuestId();
|
||||
})
|
||||
.clearable(() -> condition.setQuestId(-1));
|
||||
}
|
||||
|
||||
private GuiSelectionListener listener;
|
||||
private String catSearch = "";
|
||||
private String questSearch = "";
|
||||
|
||||
Reference in new issue
Block a user