diff --git a/src/main/java/noppes/npcs/client/gui/global/GuiNpcManageMagic.java b/src/main/java/noppes/npcs/client/gui/global/GuiNpcManageMagic.java index 9964ac01a..8753f0430 100644 --- a/src/main/java/noppes/npcs/client/gui/global/GuiNpcManageMagic.java +++ b/src/main/java/noppes/npcs/client/gui/global/GuiNpcManageMagic.java @@ -12,7 +12,6 @@ import noppes.npcs.client.gui.magic.SubGuiMagicEdit; import noppes.npcs.client.gui.magic.SubGuiMagicInteractionsEdit; import noppes.npcs.client.gui.util.*; import noppes.npcs.constants.EnumScrollData; -import noppes.npcs.controllers.MagicController; import noppes.npcs.controllers.data.Magic; import noppes.npcs.controllers.data.MagicCycle; import noppes.npcs.entity.EntityNPCInterface; @@ -23,26 +22,37 @@ import static noppes.npcs.client.gui.player.inventory.GuiCNPCInventory.specialIc public class GuiNpcManageMagic extends GuiNPCInterface2 implements ISubGuiListener, ICustomScrollListener, IScrollData, IGuiData { - private GuiCustomScroll leftScroll; // left scroll for cycles (viewByCycle) - private GuiCustomScroll rightScroll; // right scroll for magics + // Left scroll (for cycles) and right scroll (for magics). + private GuiCustomScroll leftScroll; // Only used in cycle view. + private GuiCustomScroll rightScroll; // Displays the magics list. + + // When true, we are in global magic view (single list with all magics). + // When false, we are in cycle view (two lists: left for cycles and right for associated magics). private boolean viewByCycle = true; + // Data maps for cycles and magics. (Keys are display names) private HashMap cycleData = new HashMap<>(); private HashMap magicData = new HashMap<>(); + // currentMagicList is the subset shown in the right scroll. + // In global view it contains all magic names; in cycle view it contains only those associated with the selected cycle. + private List currentMagicList = new ArrayList<>(); + private MagicCycle selectedCycle; private Magic selectedMagic; - // Divider/resizing variables (only used when viewByCycle is true) + // Divider/resizing variables for cycle view. private boolean isResizing = false; private int initialDragX = 0; - private int dividerOffset = 143; // initial offset from regionLeft + private int dividerOffset = 143; // Initial offset from regionLeft. private final int dividerWidth = 5; private final int minScrollWidth = 50; private int dividerLineHeight = 20; private int dividerLineYOffset = 0; - // Search strings – IDs 55 and 66 are used for search text fields + // Search strings. + // cycleSearch filters the left scroll (cycles). + // magicSearch filters the currentMagicList (right scroll). private String cycleSearch = ""; private String magicSearch = ""; @@ -56,26 +66,29 @@ public class GuiNpcManageMagic extends GuiNPCInterface2 implements ISubGuiListen super.initGui(); int y = guiTop + 5; + // Toggle button to switch between global and cycle views. addButton(new GuiToggleButton(50, guiLeft + 368, guiTop + ySize - 10, viewByCycle)); - ((GuiToggleButton) getButton(50)).setTextureOff(specialIcons).setTextureOffPos( 16, 0); - ((GuiToggleButton) getButton(50)).setIconTexture(specialIcons).setIconPos( 16, 16, 16, 0 ); + ((GuiToggleButton) getButton(50)).setTextureOff(specialIcons).setTextureOffPos(16, 0); + ((GuiToggleButton) getButton(50)).setIconTexture(specialIcons).setIconPos(16, 16, 16, 0); if (!viewByCycle) { - // Define horizontal region (similar to your quest GUI) + // --- Cycle View: Two Scrolls (cycles on left, magics on right) --- int regionLeft = guiLeft + 64; int regionRight = guiLeft + 355; int dividerX = regionLeft + dividerOffset; - // Left scroll (cycles) + // Left scroll for cycles. if (leftScroll == null) { leftScroll = new GuiCustomScroll(this, 0, 0); } leftScroll.guiLeft = regionLeft; leftScroll.guiTop = y; leftScroll.setSize(dividerX - regionLeft, 185); + // Populate the left scroll with cycle names. + leftScroll.setList(new ArrayList<>(cycleData.keySet())); this.addScroll(leftScroll); - // Right scroll (magics for selected cycle) + // Right scroll for magics. if (rightScroll == null) { rightScroll = new GuiCustomScroll(this, 1, 0); } @@ -84,29 +97,28 @@ public class GuiNpcManageMagic extends GuiNPCInterface2 implements ISubGuiListen rightScroll.setSize(regionRight - (dividerX + dividerWidth), 185); this.addScroll(rightScroll); - // Add search bars below each scroll – using text field IDs 55 and 66 + // Add search bars below each scroll. + // ID 55: cycle search; ID 66: magic search. addTextField(new GuiNpcTextField(55, this, fontRendererObj, regionLeft, y + 185 + 3, dividerX - regionLeft, 20, cycleSearch)); addTextField(new GuiNpcTextField(66, this, fontRendererObj, dividerX + dividerWidth, y + 185 + 3, regionRight - (dividerX + dividerWidth), 20, magicSearch)); - // Left side cycle management buttons (mirroring your quest GUI style) + // Left side cycle management buttons. addButton(new GuiNpcButton(10, guiLeft + 3, guiTop + 8, 58, 20, "Cycles")); getButton(10).setEnabled(false); addButton(new GuiNpcButton(4, guiLeft + 3, guiTop + 38, 58, 20, "gui.add")); addButton(new GuiNpcButton(5, guiLeft + 3, guiTop + 61, 58, 20, "gui.remove")); addButton(new GuiNpcButton(6, guiLeft + 3, guiTop + 94, 58, 20, "gui.edit")); - // Right side magic management buttons + // Right side magic management buttons. addButton(new GuiNpcButton(33, guiLeft + 358, guiTop + 8, 58, 20, "Magics")); getButton(33).setEnabled(false); - addButton(new GuiNpcButton(0, guiLeft + 358, guiTop + 38, 58, 20, "gui.add")); getButton(0).setEnabled(false); addButton(new GuiNpcButton(1, guiLeft + 358, guiTop + 61, 58, 20, "gui.remove")); getButton(1).setEnabled(false); - addButton(new GuiNpcButton(2, guiLeft + 358, guiTop + 94, 58, 20, "gui.edit")); } else { - // Default mode: one list for all magics plus one search bar + // --- Global Magic View: Single Scroll (all magics) --- if (rightScroll == null) { rightScroll = new GuiCustomScroll(this, 1, 0); } @@ -119,12 +131,28 @@ public class GuiNpcManageMagic extends GuiNPCInterface2 implements ISubGuiListen addButton(new GuiNpcButton(33, guiLeft + 358, guiTop + 8, 58, 20, "Magics")); getButton(33).setEnabled(false); - // Global magic management buttons + // Global magic management buttons. addButton(new GuiNpcButton(0, guiLeft + 358, guiTop + 38, 58, 20, "gui.add")); addButton(new GuiNpcButton(1, guiLeft + 358, guiTop + 61, 58, 20, "gui.remove")); - addButton(new GuiNpcButton(2, guiLeft + 358, guiTop + 94, 58, 20, "gui.edit")); } + + // --- Update Right Scroll List Based on View Mode --- + if (viewByCycle) { + // Global view: currentMagicList contains all magic names. + currentMagicList = new ArrayList<>(magicData.keySet()); + if (rightScroll != null) + rightScroll.setList(applyMagicSearchFilter(currentMagicList)); + } else { + // Cycle view: if a cycle is selected update the list, else clear it. + if (selectedCycle != null) { + updateMagicList(); + } else { + currentMagicList.clear(); + if (rightScroll != null) + rightScroll.setList(applyMagicSearchFilter(currentMagicList)); + } + } } @Override @@ -149,6 +177,7 @@ public class GuiNpcManageMagic extends GuiNPCInterface2 implements ISubGuiListen int regionHeight = 185; int handleTop = regionTop + (regionHeight - dividerLineHeight) / 2 + dividerLineYOffset; int handleBottom = handleTop + dividerLineHeight; + // Start resizing if clicking on the divider. if (mouseX >= dividerX && mouseX <= dividerX + dividerWidth && mouseY >= handleTop && mouseY <= handleBottom) { isResizing = true; @@ -183,7 +212,7 @@ public class GuiNpcManageMagic extends GuiNPCInterface2 implements ISubGuiListen leftScroll.setSize(dividerX - regionLeft, 185); rightScroll.guiLeft = dividerX + dividerWidth; rightScroll.setSize(regionRight - (dividerX + dividerWidth), 185); - // Update search field sizes + // Adjust search field sizes. if (getTextField(55) != null) { getTextField(55).width = dividerX - regionLeft; } @@ -209,6 +238,7 @@ public class GuiNpcManageMagic extends GuiNPCInterface2 implements ISubGuiListen @Override public void keyTyped(char c, int i) { super.keyTyped(c, i); + // --- Cycle Search (only in cycle view) --- if (!viewByCycle) { if (getTextField(55) != null && getTextField(55).isFocused()) { if (!cycleSearch.equals(getTextField(55).getText())) { @@ -218,15 +248,17 @@ public class GuiNpcManageMagic extends GuiNPCInterface2 implements ISubGuiListen } } } + // --- Magic Search: filter the currentMagicList (right scroll) --- if (getTextField(66) != null && getTextField(66).isFocused()) { if (!magicSearch.equals(getTextField(66).getText())) { magicSearch = getTextField(66).getText().toLowerCase(); rightScroll.resetScroll(); - rightScroll.setList(getMagicSearch()); + rightScroll.setList(applyMagicSearchFilter(currentMagicList)); } } } + // Returns a list of cycles filtered by the cycleSearch string. private List getCycleSearch() { if (cycleSearch.isEmpty()) { return new ArrayList<>(cycleData.keySet()); @@ -239,73 +271,88 @@ public class GuiNpcManageMagic extends GuiNPCInterface2 implements ISubGuiListen return list; } - private List getMagicSearch() { + /** + * Applies the magic search filter to the provided list. + * Returns a new list containing only magic names that match the magicSearch string. + */ + private List applyMagicSearchFilter(List list) { if (magicSearch.isEmpty()) { - return new ArrayList<>(magicData.keySet()); + return new ArrayList<>(list); } - List list = new ArrayList<>(); - for (String name : magicData.keySet()) { - if (name.toLowerCase().contains(magicSearch)) - list.add(name); + List filtered = new ArrayList<>(); + for (String name : list) { + if (name.toLowerCase().contains(magicSearch)) { + filtered.add(name); + } } - return list; + return filtered; } @Override public void actionPerformed(GuiButton button) { switch (button.id) { case 50: + // Toggle view mode. viewByCycle = !viewByCycle; selectedMagic = null; selectedCycle = null; + // Reset search strings. + cycleSearch = ""; + magicSearch = ""; + // Update currentMagicList based on the new mode. + if (viewByCycle) { + // Global view: all magics. + currentMagicList = new ArrayList<>(magicData.keySet()); + } else { + // Cycle view: start with an empty magic list. + currentMagicList.clear(); + } initGui(); return; - // Left side: Cycle management - case 4: // Add Cycle + // --- Cycle Management Buttons --- + case 4: // Add Cycle. { MagicCycle magicCycle = new MagicCycle(); magicCycle.name = "New"; + magicCycle.displayName = "New"; NBTTagCompound compound = new NBTTagCompound(); magicCycle.writeNBT(compound); PacketClient.sendClient(new MagicCycleSavePacket(compound)); } break; - case 5: // Remove Cycle + case 5: // Remove Cycle. if (selectedCycle != null) { PacketClient.sendClient(new MagicCycleRemovePacket(selectedCycle.id)); + selectedCycle = null; + if (leftScroll != null) + leftScroll.selected = -1; } break; - case 6: // Edit Cycle + case 6: // Edit Cycle. if (selectedCycle != null) { setSubGui(new SubGuiMagicCycleEdit(selectedCycle)); } break; - // Right side: Magic management (in viewByCycle) - case 0: // Add Magic - if (selectedCycle != null) { - Magic magic = new Magic(); - magic.name = "New"; - magic.displayName = "New"; - NBTTagCompound compound = new NBTTagCompound(); - magic.writeNBT(compound); - PacketClient.sendClient(new MagicSavePacket(compound)); - } + // --- Magic Management Buttons --- + case 0: // Add Magic. + Magic magic = new Magic(); + magic.name = "New"; + magic.displayName = "New"; + NBTTagCompound compound = new NBTTagCompound(); + magic.writeNBT(compound); + PacketClient.sendClient(new MagicSavePacket(compound)); break; - case 1: // Edit Magic - // Default mode buttons (global view) - case 21: - if (selectedMagic != null) { - setSubGui(new SubGuiMagicEdit(selectedMagic)); - } - break; - case 2: // Remove Magic - case 22: + case 1: // Remove Magic. if (selectedMagic != null) { PacketClient.sendClient(new MagicRemovePacket(selectedMagic.id)); } break; - case 3: // Edit Interactions - case 23: + case 2: // Edit Magic. + if (selectedMagic != null) { + setSubGui(new SubGuiMagicEdit(selectedMagic)); + } + break; + case 3: // Edit Interactions. if (selectedMagic != null) { setSubGui(new SubGuiMagicInteractionsEdit(selectedMagic)); } @@ -316,24 +363,25 @@ public class GuiNpcManageMagic extends GuiNPCInterface2 implements ISubGuiListen @Override public void customScrollClicked(int id, int index, int clickType, GuiCustomScroll scroll) { if (!viewByCycle) { - if (scroll.id == 0) { // Left scroll: cycles + if (scroll.id == 0) { // Left scroll: cycles. selectedCycle = null; String cycleName = scroll.getSelected(); - if(cycleData.containsKey(cycleName)){ + if (cycleData.containsKey(cycleName)) { MagicGetPacket.GetCycle(cycleData.get(cycleName)); } - } else if (scroll.id == 1) { // Right scroll: magics + } else if (scroll.id == 1) { // Right scroll: magics. selectedMagic = null; String magicName = scroll.getSelected(); - if(magicData.containsKey(magicName)){ + if (magicData.containsKey(magicName)) { MagicGetPacket.GetMagic(magicData.get(magicName)); } } } else { + // Global view. if (scroll.id == 1) { selectedMagic = null; String magicName = scroll.getSelected(); - if(magicData.containsKey(magicName)){ + if (magicData.containsKey(magicName)) { MagicGetPacket.GetMagic(magicData.get(magicName)); } } @@ -351,53 +399,66 @@ public class GuiNpcManageMagic extends GuiNPCInterface2 implements ISubGuiListen @Override public void setData(Vector list, HashMap data, EnumScrollData type) { - if(type == EnumScrollData.MAGIC_CYCLES){ + if (type == EnumScrollData.MAGIC_CYCLES) { + // Update cycle data and, in cycle view, update the left scroll. cycleData.clear(); - cycleData = data; + cycleData.putAll(data); if (!viewByCycle) { leftScroll.setList(new ArrayList<>(cycleData.keySet())); } } else if (type == EnumScrollData.MAGIC) { + // Update magic data (all magics remain in magicData). magicData.clear(); - magicData = data; - rightScroll.setList(new ArrayList<>(magicData.keySet())); + magicData.putAll(data); + if (!viewByCycle) { + // In cycle view, update currentMagicList based on the selected cycle. + updateMagicList(); + } else { + // In global view, currentMagicList is all magics. + currentMagicList = new ArrayList<>(magicData.keySet()); + if (rightScroll != null) + rightScroll.setList(applyMagicSearchFilter(currentMagicList)); + } } initGui(); } + /** + * In cycle view, updates the currentMagicList based on the selected cycle’s associations. + * Then applies the magic search filter to update the right scroll list. + */ + public void updateMagicList() { + currentMagicList.clear(); + if (selectedCycle != null) { + // For each magic ID associated with the cycle, add its name from magicData. + for (int magicId : selectedCycle.associations.keySet()) { + for (String magicName : magicData.keySet()) { + if (magicData.get(magicName) == magicId) { + currentMagicList.add(magicName); + break; + } + } + } + } + if (rightScroll != null) + rightScroll.setList(applyMagicSearchFilter(currentMagicList)); + } + @Override public void setSelected(String selected) {} - public void updateMagicList(){ - List magicNames = new ArrayList<>(); - if(selectedCycle == null) - return; - - for (int magicId : selectedCycle.associations.keySet()) { - for(String magicName : magicData.keySet()){ - if(magicData.containsKey(magicName) && magicData.get(magicName) == magicId){ - magicNames.add(magicName); - break; - } - } - } - - if(rightScroll != null) - rightScroll.setList(magicNames); - } - @Override public void setGuiData(NBTTagCompound compound) { - if(compound.hasKey("Magic")){ + if (compound.hasKey("Magic")) { selectedMagic = new Magic(); selectedMagic.readNBT(compound.getCompoundTag("Magic")); } else if (compound.hasKey("MagicCycle")) { selectedCycle = new MagicCycle(); selectedCycle.readNBT(compound.getCompoundTag("MagicCycle")); - + // Refresh the magic list based on the new cycle. updateMagicList(); selectedMagic = null; - if(rightScroll != null) + if (rightScroll != null) rightScroll.selected = -1; } } diff --git a/src/main/java/noppes/npcs/controllers/data/MagicCycle.java b/src/main/java/noppes/npcs/controllers/data/MagicCycle.java index 45820a375..70ae2e2e1 100644 --- a/src/main/java/noppes/npcs/controllers/data/MagicCycle.java +++ b/src/main/java/noppes/npcs/controllers/data/MagicCycle.java @@ -19,7 +19,7 @@ public class MagicCycle { public MagicCycle() {} public void readNBT(NBTTagCompound compound) { - id = compound.getInteger("CategoryID"); + id = compound.getInteger("ID"); name = compound.getString("Name"); displayName = compound.getString("DisplayName"); layout = EnumDiagramLayout.values()[compound.getInteger("Layout")]; @@ -36,8 +36,8 @@ public class MagicCycle { } public void writeNBT(NBTTagCompound compound) { - compound.setInteger("CategoryID", id); - compound.setString("Title", name); + compound.setInteger("ID", id); + compound.setString("Name", name); compound.setString("DisplayName", displayName); compound.setInteger("Layout", layout.ordinal()); NBTTagList list = new NBTTagList(); diff --git a/src/main/resources/assets/customnpcs/lang/en_US.lang b/src/main/resources/assets/customnpcs/lang/en_US.lang index 6be14a191..5c5208968 100644 --- a/src/main/resources/assets/customnpcs/lang/en_US.lang +++ b/src/main/resources/assets/customnpcs/lang/en_US.lang @@ -575,6 +575,7 @@ global.recipes=Recipes global.naturalspawn=Spawns global.linked=Linked global.customeffects=Effects +global.magic=Magic bank.slot=Slot bank.unlock=Unlock