mirror of
https://github.com/KAMKEEL/CustomNPC-Plus.git
synced 2026-11-13 19:34:09 +00:00
Merge branch 'dev' of https://github.com/KAMKEEL/CustomNPC-Plus into dev
This commit is contained in:
commit
185f06822a
11 files changed
+367
-112
No files matched your search
@@ -5,6 +5,7 @@ import kamkeel.npcs.controllers.data.ability.conditions.AbilityCondition;
|
||||
import kamkeel.npcs.controllers.data.ability.conditions.ConditionHPThreshold;
|
||||
import kamkeel.npcs.controllers.data.ability.conditions.ConditionHitCount;
|
||||
import kamkeel.npcs.controllers.data.ability.conditions.ConditionItem;
|
||||
import kamkeel.npcs.controllers.data.ability.conditions.ConditionQuestCompleted;
|
||||
import kamkeel.npcs.controllers.data.ability.type.AbilityCharge;
|
||||
import kamkeel.npcs.controllers.data.ability.type.AbilityCutter;
|
||||
import kamkeel.npcs.controllers.data.ability.type.AbilityDash;
|
||||
@@ -154,6 +155,7 @@ public class AbilityController implements IAbilityHandler {
|
||||
registerCondition(ConditionHPThreshold::new);
|
||||
registerCondition(ConditionHitCount::new);
|
||||
registerCondition(ConditionItem::new);
|
||||
registerCondition(ConditionQuestCompleted::new);
|
||||
}
|
||||
|
||||
// ═══════════════════════════════════════════════════════════════════════════
|
||||
|
||||
@@ -6,6 +6,7 @@ import kamkeel.npcs.controllers.AbilityController;
|
||||
import kamkeel.npcs.controllers.data.ability.UserType;
|
||||
import net.minecraft.entity.EntityLivingBase;
|
||||
import net.minecraft.nbt.NBTTagCompound;
|
||||
import net.minecraft.util.StatCollector;
|
||||
import noppes.npcs.LogWriter;
|
||||
import noppes.npcs.client.gui.builder.FieldDef;
|
||||
|
||||
@@ -40,6 +41,14 @@ public abstract class AbilityCondition {
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if all required fields are filled in.
|
||||
* Used to disable the Done button in SubGuiConditionEdit when incomplete.
|
||||
*/
|
||||
public boolean isConfigured() {
|
||||
return true;
|
||||
}
|
||||
|
||||
public UserType getUserType() {
|
||||
return userType;
|
||||
}
|
||||
@@ -63,10 +72,19 @@ public abstract class AbilityCondition {
|
||||
@SideOnly(Side.CLIENT)
|
||||
public abstract void getConditionDefinitions(List<FieldDef> defs);
|
||||
|
||||
/**
|
||||
* Returns a human-readable summary of this condition's configuration.
|
||||
* Used for tooltips when hovering over condition buttons.
|
||||
*/
|
||||
@SideOnly(Side.CLIENT)
|
||||
public abstract String getConditionSummary();
|
||||
|
||||
@SideOnly(Side.CLIENT)
|
||||
public final List<FieldDef> getAllDefinitions() {
|
||||
List<FieldDef> defs = new ArrayList<>();
|
||||
|
||||
defs.add(FieldDef.labelField("ability.validFor", () ->
|
||||
"\u00A7e" + StatCollector.translateToLocal("ability.userType." + getUserType().name())));
|
||||
defs.add(FieldDef.enumField("condition.filter", ConditionFilter.class, this::getFilter, this::setFilter));
|
||||
getConditionDefinitions(defs);
|
||||
return defs;
|
||||
|
||||
+7
-92
@@ -1,60 +1,8 @@
|
||||
package kamkeel.npcs.controllers.data.ability.conditions;
|
||||
|
||||
import net.minecraft.entity.EntityLivingBase;
|
||||
import net.minecraft.nbt.NBTTagCompound;
|
||||
import noppes.npcs.client.gui.builder.FieldDef;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class ConditionHPThreshold extends AbilityCondition {
|
||||
private float threshold = 0.5f; // 50%
|
||||
private boolean percent = true;
|
||||
private ThresholdType thresholdType = ThresholdType.ABOVE;
|
||||
|
||||
public enum ThresholdType {
|
||||
ABOVE {
|
||||
@Override
|
||||
public boolean test(float value, float threshold) {
|
||||
return value > threshold;
|
||||
}
|
||||
},
|
||||
BELOW {
|
||||
@Override
|
||||
public boolean test(float value, float threshold) {
|
||||
return value < threshold;
|
||||
}
|
||||
},
|
||||
EQUAL {
|
||||
@Override
|
||||
public boolean test(float value, float threshold) {
|
||||
return value == threshold;
|
||||
}
|
||||
};
|
||||
|
||||
public abstract boolean test(float value, float threshold);
|
||||
|
||||
public static ThresholdType fromOrdinal(int ordinal) {
|
||||
ThresholdType[] values = values();
|
||||
if (ordinal >= 0 && ordinal < values.length) {
|
||||
return values[ordinal];
|
||||
}
|
||||
return ABOVE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
switch (this) {
|
||||
case ABOVE:
|
||||
return "condition.hp_above";
|
||||
case BELOW:
|
||||
return "condition.hp_below";
|
||||
case EQUAL:
|
||||
return "condition.hp_equal";
|
||||
default:
|
||||
return name();
|
||||
}
|
||||
}
|
||||
}
|
||||
public class ConditionHPThreshold extends ConditionThreshold {
|
||||
|
||||
public ConditionHPThreshold() {
|
||||
this.typeId = "condition.cnpc.hp_threshold";
|
||||
@@ -62,50 +10,17 @@ public class ConditionHPThreshold extends AbilityCondition {
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean checkEntity(EntityLivingBase entity) {
|
||||
float entityHP = isPercent() ? entity.getHealth() / entity.getMaxHealth() : entity.getHealth();
|
||||
return thresholdType.test(entityHP, getThreshold());
|
||||
protected float getEntityValue(EntityLivingBase entity) {
|
||||
return entity.getHealth();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void getConditionDefinitions(List<FieldDef> defs) {
|
||||
defs.add(FieldDef.floatField("condition.threshold", this::getThreshold, this::setThreshold).min(0));
|
||||
defs.add(FieldDef.boolField("condition.percent", this::isPercent, this::setIsPercent));
|
||||
defs.add(FieldDef.enumField("condition.threshold_type", ThresholdType.class,
|
||||
this::getThresholdType, this::setThresholdType));
|
||||
protected float getEntityMaxValue(EntityLivingBase entity) {
|
||||
return entity.getMaxHealth();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeTypeNBT(NBTTagCompound nbt) {
|
||||
nbt.setFloat("threshold", threshold);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void readTypeNBT(NBTTagCompound nbt) {
|
||||
threshold = nbt.getFloat("threshold");
|
||||
}
|
||||
|
||||
public float getThreshold() {
|
||||
return threshold;
|
||||
}
|
||||
|
||||
public void setThreshold(float threshold) {
|
||||
this.threshold = Math.max(0, threshold);
|
||||
}
|
||||
|
||||
public ThresholdType getThresholdType() {
|
||||
return thresholdType;
|
||||
}
|
||||
|
||||
public void setThresholdType(ThresholdType thresholdType) {
|
||||
this.thresholdType = thresholdType;
|
||||
}
|
||||
|
||||
public boolean isPercent() {
|
||||
return percent;
|
||||
}
|
||||
|
||||
public void setIsPercent(boolean percent) {
|
||||
this.percent = percent;
|
||||
protected String getStatName() {
|
||||
return "HP";
|
||||
}
|
||||
}
|
||||
+7
-2
@@ -1,8 +1,8 @@
|
||||
package kamkeel.npcs.controllers.data.ability.conditions;
|
||||
|
||||
import kamkeel.npcs.controllers.data.ability.UserType;
|
||||
import net.minecraft.entity.EntityLivingBase;
|
||||
import net.minecraft.nbt.NBTTagCompound;
|
||||
import net.minecraft.util.StatCollector;
|
||||
import noppes.npcs.client.gui.builder.FieldDef;
|
||||
import noppes.npcs.entity.EntityNPCInterface;
|
||||
|
||||
@@ -15,7 +15,6 @@ public class ConditionHitCount extends AbilityCondition {
|
||||
public ConditionHitCount() {
|
||||
this.typeId = "condition.cnpc.hit_count";
|
||||
this.name = "condition.hit_count";
|
||||
this.userType = UserType.NPC_ONLY;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -59,6 +58,12 @@ public class ConditionHitCount extends AbilityCondition {
|
||||
defs.add(FieldDef.intField("condition.within_ticks", this::getWithinTicks, this::setWithinTicks).min(0));
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getConditionSummary() {
|
||||
String filterLabel = StatCollector.translateToLocal("condition.filter." + getFilter().name().toLowerCase());
|
||||
return "[" + filterLabel + "] Hit " + requiredHits + " times in " + withinTicks + " ticks";
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeTypeNBT(NBTTagCompound nbt) {
|
||||
nbt.setInteger("requiredHits", requiredHits);
|
||||
|
||||
@@ -4,6 +4,7 @@ import net.minecraft.entity.EntityLivingBase;
|
||||
import net.minecraft.entity.player.EntityPlayer;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.nbt.NBTTagCompound;
|
||||
import net.minecraft.util.StatCollector;
|
||||
import noppes.npcs.client.gui.builder.FieldDef;
|
||||
import noppes.npcs.entity.EntityNPCInterface;
|
||||
|
||||
@@ -149,6 +150,14 @@ public class ConditionItem extends AbilityCondition {
|
||||
// .hover("condition.hover.required_count"));
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getConditionSummary() {
|
||||
String filterLabel = StatCollector.translateToLocal("condition.filter." + getFilter().name().toLowerCase());
|
||||
String usage = usageType.name();
|
||||
String item = itemName.isEmpty() ? "None" : itemName;
|
||||
return "[" + filterLabel + "] " + usage + ": " + item;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeTypeNBT(NBTTagCompound nbt) {
|
||||
nbt.setString("itemName", itemName);
|
||||
@@ -166,6 +175,11 @@ public class ConditionItem extends AbilityCondition {
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean isConfigured() {
|
||||
return itemName != null && !itemName.isEmpty();
|
||||
}
|
||||
|
||||
public UsageType getUsageType() { return usageType; }
|
||||
public void setUsageType(UsageType usageType) { this.usageType = usageType; }
|
||||
|
||||
|
||||
+86
@@ -0,0 +1,86 @@
|
||||
package kamkeel.npcs.controllers.data.ability.conditions;
|
||||
|
||||
import kamkeel.npcs.controllers.data.ability.UserType;
|
||||
import net.minecraft.entity.EntityLivingBase;
|
||||
import net.minecraft.entity.player.EntityPlayer;
|
||||
import net.minecraft.nbt.NBTTagCompound;
|
||||
import net.minecraft.util.StatCollector;
|
||||
import noppes.npcs.client.gui.builder.FieldDef;
|
||||
import noppes.npcs.client.gui.select.GuiQuestSelection;
|
||||
import noppes.npcs.client.gui.util.SubGuiInterface;
|
||||
import noppes.npcs.controllers.QuestController;
|
||||
import noppes.npcs.controllers.data.PlayerData;
|
||||
import noppes.npcs.controllers.data.Quest;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class ConditionQuestCompleted extends AbilityCondition {
|
||||
private int questId = -1;
|
||||
|
||||
public ConditionQuestCompleted() {
|
||||
this.typeId = "condition.cnpc.quest_completed";
|
||||
this.name = "condition.quest_completed";
|
||||
this.userType = UserType.PLAYER_ONLY;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean checkEntity(EntityLivingBase entity) {
|
||||
if (!(entity instanceof EntityPlayer)) return false;
|
||||
if (questId < 0) return false;
|
||||
|
||||
EntityPlayer player = (EntityPlayer) entity;
|
||||
return PlayerData.get(player).questData.hasFinishedQuest(questId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void getConditionDefinitions(List<FieldDef> defs) {
|
||||
defs.add(FieldDef.subGuiField("condition.select_quest",
|
||||
() -> new GuiQuestSelection(questId),
|
||||
(SubGuiInterface 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));
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getConditionSummary() {
|
||||
String filterLabel = StatCollector.translateToLocal("condition.filter." + getFilter().name().toLowerCase());
|
||||
String questName = "None";
|
||||
if (questId >= 0) {
|
||||
Quest q = QuestController.Instance.quests.get(questId);
|
||||
questName = q != null ? q.title : "ID:" + questId;
|
||||
}
|
||||
return "[" + filterLabel + "] Quest: " + questName;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeTypeNBT(NBTTagCompound nbt) {
|
||||
nbt.setInteger("questId", questId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void readTypeNBT(NBTTagCompound nbt) {
|
||||
questId = nbt.getInteger("questId");
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isConfigured() {
|
||||
return questId >= 0;
|
||||
}
|
||||
|
||||
public int getQuestId() {
|
||||
return questId;
|
||||
}
|
||||
|
||||
public void setQuestId(int questId) {
|
||||
this.questId = questId;
|
||||
}
|
||||
}
|
||||
+171
@@ -0,0 +1,171 @@
|
||||
package kamkeel.npcs.controllers.data.ability.conditions;
|
||||
|
||||
import net.minecraft.entity.EntityLivingBase;
|
||||
import net.minecraft.nbt.NBTTagCompound;
|
||||
import net.minecraft.util.StatCollector;
|
||||
import noppes.npcs.client.gui.builder.FieldDef;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Abstract base for threshold-based conditions (HP, Ki, etc.).
|
||||
* Provides shared percent/flat toggle, ThresholdType enum, and FieldDef generation.
|
||||
*/
|
||||
public abstract class ConditionThreshold extends AbilityCondition {
|
||||
|
||||
public enum ThresholdType {
|
||||
ABOVE {
|
||||
@Override
|
||||
public boolean test(float value, float threshold) {
|
||||
return value >= threshold;
|
||||
}
|
||||
},
|
||||
BELOW {
|
||||
@Override
|
||||
public boolean test(float value, float threshold) {
|
||||
return value <= threshold;
|
||||
}
|
||||
},
|
||||
EQUAL {
|
||||
@Override
|
||||
public boolean test(float value, float threshold) {
|
||||
return value == threshold;
|
||||
}
|
||||
};
|
||||
|
||||
public abstract boolean test(float value, float threshold);
|
||||
|
||||
public static ThresholdType fromOrdinal(int ordinal) {
|
||||
ThresholdType[] values = values();
|
||||
if (ordinal >= 0 && ordinal < values.length) {
|
||||
return values[ordinal];
|
||||
}
|
||||
return ABOVE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
switch (this) {
|
||||
case ABOVE:
|
||||
return "condition.above";
|
||||
case BELOW:
|
||||
return "condition.below";
|
||||
case EQUAL:
|
||||
return "condition.equal";
|
||||
default:
|
||||
return name();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected float thresholdFlat = 100f;
|
||||
protected float thresholdPercent = 0.5f;
|
||||
protected boolean percent = true;
|
||||
protected ThresholdType thresholdType = ThresholdType.ABOVE;
|
||||
|
||||
/**
|
||||
* Returns the raw stat value for the entity (e.g. current HP, current Ki).
|
||||
*/
|
||||
protected abstract float getEntityValue(EntityLivingBase entity);
|
||||
|
||||
/**
|
||||
* Returns the maximum stat value for the entity (e.g. max HP, max Ki).
|
||||
* Used to compute the percentage ratio.
|
||||
*/
|
||||
protected abstract float getEntityMaxValue(EntityLivingBase entity);
|
||||
|
||||
/**
|
||||
* Returns the display name for the stat being checked (e.g. "HP", "Ki").
|
||||
* Used in getConditionSummary().
|
||||
*/
|
||||
protected abstract String getStatName();
|
||||
|
||||
@Override
|
||||
protected boolean checkEntity(EntityLivingBase entity) {
|
||||
float value;
|
||||
float threshold;
|
||||
if (percent) {
|
||||
float max = getEntityMaxValue(entity);
|
||||
value = max > 0 ? getEntityValue(entity) / max : 0;
|
||||
threshold = thresholdPercent;
|
||||
} else {
|
||||
value = getEntityValue(entity);
|
||||
threshold = thresholdFlat;
|
||||
}
|
||||
return thresholdType.test(value, threshold);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void getConditionDefinitions(List<FieldDef> defs) {
|
||||
defs.add(FieldDef.floatField("condition.threshold_flat", this::getThresholdFlat, this::setThresholdFlat)
|
||||
.min(0).visibleWhen(() -> !isPercent()));
|
||||
defs.add(FieldDef.floatField("condition.threshold_percent", this::getThresholdPercent, this::setThresholdPercent)
|
||||
.min(0).max(1).visibleWhen(this::isPercent));
|
||||
defs.add(FieldDef.boolField("condition.percent", this::isPercent, this::setIsPercent));
|
||||
defs.add(FieldDef.enumField("condition.threshold_type", ThresholdType.class,
|
||||
this::getThresholdType, this::setThresholdType));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeTypeNBT(NBTTagCompound nbt) {
|
||||
nbt.setFloat("thresholdFlat", thresholdFlat);
|
||||
nbt.setFloat("thresholdPercent", thresholdPercent);
|
||||
nbt.setBoolean("percent", percent);
|
||||
nbt.setInteger("thresholdType", thresholdType.ordinal());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void readTypeNBT(NBTTagCompound nbt) {
|
||||
thresholdFlat = nbt.getFloat("thresholdFlat");
|
||||
thresholdPercent = nbt.getFloat("thresholdPercent");
|
||||
percent = nbt.getBoolean("percent");
|
||||
thresholdType = ThresholdType.fromOrdinal(nbt.getInteger("thresholdType"));
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getConditionSummary() {
|
||||
String filterLabel = StatCollector.translateToLocal("condition.filter." + getFilter().name().toLowerCase());
|
||||
String typeName = getStatName();
|
||||
String typeLabel = StatCollector.translateToLocal(thresholdType.toString());
|
||||
String value = percent
|
||||
? String.format("%.0f%%", thresholdPercent * 100)
|
||||
: String.format("%.0f", thresholdFlat);
|
||||
return "[" + filterLabel + "] " + typeName + " " + typeLabel + " " + value;
|
||||
}
|
||||
|
||||
// ═══════════════════════════════════════════════════════════════════
|
||||
// GETTERS / SETTERS
|
||||
// ═══════════════════════════════════════════════════════════════════
|
||||
|
||||
public float getThresholdFlat() {
|
||||
return thresholdFlat;
|
||||
}
|
||||
|
||||
public void setThresholdFlat(float value) {
|
||||
this.thresholdFlat = Math.max(0, value);
|
||||
}
|
||||
|
||||
public float getThresholdPercent() {
|
||||
return thresholdPercent;
|
||||
}
|
||||
|
||||
public void setThresholdPercent(float value) {
|
||||
this.thresholdPercent = Math.max(0, Math.min(1, value));
|
||||
}
|
||||
|
||||
public boolean isPercent() {
|
||||
return percent;
|
||||
}
|
||||
|
||||
public void setIsPercent(boolean percent) {
|
||||
this.percent = percent;
|
||||
}
|
||||
|
||||
public ThresholdType getThresholdType() {
|
||||
return thresholdType;
|
||||
}
|
||||
|
||||
public void setThresholdType(ThresholdType type) {
|
||||
this.thresholdType = type;
|
||||
}
|
||||
}
|
||||
@@ -245,7 +245,9 @@ public class SubGuiAbilityConfig extends SubGuiInterface implements ITextfieldLi
|
||||
for (int i = 0; i < conditions.size() && i < MAX_CONDITIONS; i++) {
|
||||
AbilityCondition cond = conditions.get(i);
|
||||
String condName = getConditionDisplayName(cond);
|
||||
sw.addButton(new GuiNpcButton(COND_BASE + i * COND_STRIDE, L_LABEL_X, y, 140, 20, condName));
|
||||
GuiNpcButton condBtn = new GuiNpcButton(COND_BASE + i * COND_STRIDE, L_LABEL_X, y, 140, 20, condName);
|
||||
condBtn.hoverableText = cond.getConditionSummary();
|
||||
sw.addButton(condBtn);
|
||||
sw.addButton(new GuiNpcButton(COND_BASE + i * COND_STRIDE + 1, L_LABEL_X + 145, y, 40, 20, "gui.edit"));
|
||||
sw.addButton(new GuiNpcButton(COND_BASE + i * COND_STRIDE + 2, L_LABEL_X + 190, y, 20, 20, "X"));
|
||||
y += 22;
|
||||
|
||||
@@ -31,6 +31,7 @@ public class SubGuiConditionEdit extends SubGuiInterface implements ITextfieldLi
|
||||
private static final int BTN_NAMESPACE = 1;
|
||||
private static final int BTN_CANCEL = 10;
|
||||
private static final int BTN_DONE = 11;
|
||||
private static final int TF_SEARCH = 12;
|
||||
|
||||
// Left panel
|
||||
private static final int LEFT_WIDTH = 110;
|
||||
@@ -39,6 +40,8 @@ public class SubGuiConditionEdit extends SubGuiInterface implements ITextfieldLi
|
||||
// Right panel
|
||||
private static final int RIGHT_GAP = 5;
|
||||
|
||||
private String searchText = "";
|
||||
|
||||
private AbilityCondition condition;
|
||||
private AbilityCondition result;
|
||||
private String selectedTypeId;
|
||||
@@ -158,11 +161,11 @@ public class SubGuiConditionEdit extends SubGuiInterface implements ITextfieldLi
|
||||
GuiNpcTextField.unfocus();
|
||||
super.initGui();
|
||||
|
||||
int y = guiTop + 5;
|
||||
int leftX = guiLeft + LEFT_MARGIN;
|
||||
int btnY = guiTop + ySize - 26;
|
||||
|
||||
// Namespace filter button (full width at top)
|
||||
addButton(new GuiNpcButton(BTN_NAMESPACE, guiLeft + LEFT_MARGIN, y, xSize - LEFT_MARGIN * 2, 20, getNamespaceFilterLabel()));
|
||||
y += 24;
|
||||
// Namespace filter button (above left scroll only)
|
||||
addButton(new GuiNpcButton(BTN_NAMESPACE, leftX, guiTop + 5, LEFT_WIDTH, 20, getNamespaceFilterLabel()));
|
||||
|
||||
// Build filtered type list
|
||||
filteredTypeIds = getFilteredTypes();
|
||||
@@ -171,22 +174,28 @@ public class SubGuiConditionEdit extends SubGuiInterface implements ITextfieldLi
|
||||
for (String typeId : filteredTypeIds) {
|
||||
Supplier<AbilityCondition> factory = AbilityController.Instance.getConditionType(typeId);
|
||||
String displayName = factory != null ? I18n.format(factory.get().getName()) : typeId;
|
||||
if (!searchText.isEmpty() && !displayName.toLowerCase().contains(searchText.toLowerCase())) continue;
|
||||
scrollList.add(displayName);
|
||||
displayNameToTypeId.put(displayName, typeId);
|
||||
}
|
||||
|
||||
// Left panel: condition type scroll list
|
||||
int scrollHeight = ySize - 58;
|
||||
scroll = new GuiCustomScroll(this, 0);
|
||||
scroll.guiLeft = guiLeft + LEFT_MARGIN;
|
||||
scroll.guiTop = y;
|
||||
// Left panel: condition type scroll list (between namespace button and search bar)
|
||||
int scrollTop = guiTop + 29;
|
||||
int scrollBottom = btnY - 24;
|
||||
int scrollHeight = scrollBottom - scrollTop;
|
||||
if (scroll == null) {
|
||||
scroll = new GuiCustomScroll(this, 0);
|
||||
}
|
||||
scroll.guiLeft = leftX;
|
||||
scroll.guiTop = scrollTop;
|
||||
scroll.setSize(LEFT_WIDTH, scrollHeight);
|
||||
scroll.setUnsortedList(scrollList);
|
||||
|
||||
// Pre-select current condition type in scroll
|
||||
if (selectedTypeId != null) {
|
||||
for (int i = 0; i < filteredTypeIds.length; i++) {
|
||||
if (filteredTypeIds[i].equals(selectedTypeId)) {
|
||||
for (int i = 0; i < scrollList.size(); i++) {
|
||||
String typeId = displayNameToTypeId.get(scrollList.get(i));
|
||||
if (typeId != null && typeId.equals(selectedTypeId)) {
|
||||
scroll.selected = i;
|
||||
break;
|
||||
}
|
||||
@@ -194,9 +203,16 @@ public class SubGuiConditionEdit extends SubGuiInterface implements ITextfieldLi
|
||||
}
|
||||
addScroll(scroll);
|
||||
|
||||
// Right panel: condition config via FieldDef
|
||||
int rightX = guiLeft + LEFT_MARGIN + LEFT_WIDTH + RIGHT_GAP;
|
||||
// Search text field (below left scroll)
|
||||
GuiNpcTextField searchField = new GuiNpcTextField(TF_SEARCH, this, fontRendererObj, leftX, scrollBottom + 2, LEFT_WIDTH, 20, searchText);
|
||||
searchField.setHoverText("gui.search");
|
||||
addTextField(searchField);
|
||||
|
||||
// Right panel: condition config via FieldDef (full height from top to buttons)
|
||||
int rightX = leftX + LEFT_WIDTH + RIGHT_GAP;
|
||||
int rightW = xSize - LEFT_MARGIN * 2 - LEFT_WIDTH - RIGHT_GAP;
|
||||
int rightTop = guiTop + 5;
|
||||
int rightHeight = btnY - rightTop - 4;
|
||||
|
||||
List<FieldDef> fields = new ArrayList<>();
|
||||
if (condition != null) {
|
||||
@@ -205,13 +221,17 @@ public class SubGuiConditionEdit extends SubGuiInterface implements ITextfieldLi
|
||||
|
||||
builder = new AbilityFieldBuilder(this, fontRendererObj);
|
||||
builder.startIds(DECLARATIVE_ID_START, CLEAR_ID_START, LABEL_ID_START);
|
||||
builder.contentRight(rightW);
|
||||
builder.startY(5);
|
||||
builder.buildScrollWindow(fields, rightX, y, rightW, scrollHeight);
|
||||
builder.buildScrollWindow(fields, rightX, rightTop, rightW, rightHeight);
|
||||
|
||||
// Bottom buttons
|
||||
int btnY = guiTop + ySize - 26;
|
||||
addButton(new GuiNpcButton(BTN_CANCEL, guiLeft + LEFT_MARGIN, btnY, 60, 20, "gui.cancel"));
|
||||
addButton(new GuiNpcButton(BTN_DONE, guiLeft + xSize - LEFT_MARGIN - 60, btnY, 60, 20, "gui.done"));
|
||||
addButton(new GuiNpcButton(BTN_CANCEL, leftX, btnY, 60, 20, "gui.cancel"));
|
||||
GuiNpcButton doneBtn = new GuiNpcButton(BTN_DONE, guiLeft + xSize - LEFT_MARGIN - 60, btnY, 60, 20, "gui.done");
|
||||
if (condition == null || !condition.isConfigured()) {
|
||||
doneBtn.setEnabled(false);
|
||||
}
|
||||
addButton(doneBtn);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -263,6 +283,14 @@ public class SubGuiConditionEdit extends SubGuiInterface implements ITextfieldLi
|
||||
|
||||
@Override
|
||||
public void unFocused(GuiNpcTextField textField) {
|
||||
if (textField.id == TF_SEARCH) {
|
||||
String newText = textField.getText();
|
||||
if (!newText.equals(searchText)) {
|
||||
searchText = newText;
|
||||
initGui();
|
||||
}
|
||||
return;
|
||||
}
|
||||
if (textField.id < DECLARATIVE_ID_START) return;
|
||||
if (builder != null && builder.handleTextFieldEvent(textField.id, textField)) {
|
||||
initGui();
|
||||
|
||||
@@ -344,6 +344,9 @@ public class GuiFieldBuilder {
|
||||
String translated = StatCollector.translateToLocal(def.getLabel());
|
||||
int labelW = fontRenderer.getStringWidth(translated);
|
||||
int fieldX = colLLabel + labelW + labelPadding;
|
||||
// Clamp field width so it doesn't extend under the scrollbar
|
||||
int maxW = contentRight - fieldX - 15;
|
||||
if (maxW > 0 && fieldW > maxW) fieldW = maxW;
|
||||
renderFieldAt(def, colLLabel, fieldX, fieldW, y);
|
||||
}
|
||||
|
||||
|
||||
Reference in new issue
Block a user