From 1372127266e2e9d3757fa8e083748cf99d9de45a Mon Sep 17 00:00:00 2001 From: bigguy345 Date: Mon, 12 Jan 2026 03:56:22 +0200 Subject: [PATCH] GuiScript now extends GuiScriptInterface + Full screen support --- .../noppes/npcs/client/gui/GuiScript.java | 329 ++++++++++-------- .../client/gui/script/GuiScriptInterface.java | 129 ++++--- 2 files changed, 259 insertions(+), 199 deletions(-) diff --git a/src/main/java/noppes/npcs/client/gui/GuiScript.java b/src/main/java/noppes/npcs/client/gui/GuiScript.java index e710eef23..a8017222d 100644 --- a/src/main/java/noppes/npcs/client/gui/GuiScript.java +++ b/src/main/java/noppes/npcs/client/gui/GuiScript.java @@ -4,7 +4,6 @@ import kamkeel.npcs.network.packets.request.script.NPCScriptPacket; import net.minecraft.client.gui.GuiButton; import net.minecraft.client.gui.GuiConfirmOpenLink; import net.minecraft.client.gui.GuiYesNo; -import net.minecraft.client.gui.GuiYesNoCallback; import net.minecraft.nbt.NBTTagCompound; import net.minecraft.nbt.NBTTagList; import net.minecraft.server.MinecraftServer; @@ -12,44 +11,77 @@ import net.minecraft.util.StatCollector; import noppes.npcs.NoppesStringUtils; import noppes.npcs.client.NoppesUtil; import noppes.npcs.client.gui.script.GuiNPCEventScripts; +import noppes.npcs.client.gui.script.GuiScriptInterface; import noppes.npcs.client.gui.util.*; import noppes.npcs.controllers.ScriptContainer; import noppes.npcs.controllers.ScriptController; import noppes.npcs.controllers.data.DataScript; import noppes.npcs.entity.EntityNPCInterface; -import java.util.ArrayList; -import java.util.Date; -import java.util.HashMap; -import java.util.Iterator; -import java.util.List; -import java.util.Map; +import java.util.*; -public class GuiScript extends GuiNPCInterface implements IGuiData, GuiYesNoCallback, ICustomScrollListener, IJTextAreaListener, ITextChangeListener { +/** + * NPC Script GUI - extends GuiScriptInterface but with unique behavior: + * - Uses scroll-based tab selection instead of top buttons + * - Shows settings/script toggle + * - Uses DataScript with getNPCScript(index) access pattern + * - Has console filtering by hook type + */ +public class GuiScript extends GuiScriptInterface { public boolean showScript = false; - private int activeTab = 0; public DataScript script; - public Map> languages = new HashMap>(); - + private static int activeConsole = 0; - boolean loaded = false; - - private Map textAreas = new HashMap<>(); public GuiScript(EntityNPCInterface npc) { - super(npc); - script = npc.script; - drawDefaultBackground = true; - closeOnEsc = true; - xSize = 420; - - setBackground("menubg.png"); + super(); + this.npc = npc; + this.script = npc.script; + this.handler = script; + this.useScrollTabs = true; + this.useSettingsToggle = true; + + // Initialize hook list for NPC scripts + hookList.add("script.init"); + hookList.add("script.update"); + hookList.add("script.interact"); + hookList.add("dialog.dialog"); + hookList.add("script.damaged"); + hookList.add("script.killed"); + hookList.add("script.attack"); + hookList.add("script.target"); + hookList.add("script.collide"); + hookList.add("script.kills"); + hookList.add("script.dialog_closed"); + hookList.add("script.timer"); + hookList.add("script.targetLost"); + hookList.add("script.projectileTick"); + hookList.add("script.projectileImpact"); + NPCScriptPacket.Get(); } + + @Override + protected ScriptContext getScriptContext() { + return ScriptContext.NPC; + } + + @Override + protected int getActiveScriptIndex() { + return this.activeTab; + } + + @Override + protected ScriptContainer getCurrentContainer() { + return script.getNPCScript(activeTab); + } + @Override public void initGui() { super.initGui(); - guiTop += 10; + this.guiTop += 10; + + // ==================== TOP BUTTONS ==================== GuiMenuTopButton top; addTopButton(top = new GuiMenuTopButton(13, guiLeft + 4, guiTop - 17, "script.scripts")); addTopButton(new GuiMenuTopButton(16, guiLeft + (xSize - 102), guiTop - 17, "eventscript.eventScripts")); @@ -59,51 +91,86 @@ public class GuiScript extends GuiNPCInterface implements IGuiData, GuiYesNoCall top.active = !showScript; addTopButton(new GuiMenuTopButton(15, top, "gui.website")); - List list = new ArrayList(); - list.add("script.init"); - list.add("script.update"); - list.add("script.interact"); - list.add("dialog.dialog"); - list.add("script.damaged"); - list.add("script.killed"); - list.add("script.attack"); - list.add("script.target"); - list.add("script.collide"); - list.add("script.kills"); - list.add("script.dialog_closed"); - list.add("script.timer"); - list.add("script.targetLost"); - list.add("script.projectileTick"); - list.add("script.projectileImpact"); - if (showScript) { + initScriptView(); + } else { + initSettingsView(); + } + } + + private void initScriptView() { + ScriptContainer container = getCurrentContainer(); + + // ==================== CALCULATE VIEWPORT BOUNDS ==================== + int editorX, editorY, editorWidth, editorHeight; + + if (isFullscreen) { + // Fullscreen: viewport fills screen with configured padding + FullscreenConfig.paddingTop = 30; + FullscreenConfig.paddingBottom = 20; + FullscreenConfig.paddingLeft = 20; + FullscreenConfig.paddingRight = 20; + editorX = FullscreenConfig.paddingLeft; + editorY = FullscreenConfig.paddingTop; + editorWidth = this.width - FullscreenConfig.paddingLeft - FullscreenConfig.paddingRight; + editorHeight = this.height - FullscreenConfig.paddingTop - FullscreenConfig.paddingBottom; + } else { + // Normal: fixed layout with hooks on left + editorX = guiLeft + 74; + editorY = guiTop + 4; + editorWidth = 239; + editorHeight = 208; + } + + // ==================== HOOKS SCROLL (hidden in fullscreen) ==================== + if (!isFullscreen) { addLabel(new GuiNpcLabel(0, "script.hooks", guiLeft + 4, guiTop + 5)); + GuiCustomScroll hooks = new GuiCustomScroll(this, 1); hooks.setSize(68, 198); hooks.guiLeft = guiLeft + 4; hooks.guiTop = guiTop + 14; - hooks.setUnsortedList(list); + hooks.setUnsortedList(hookList); hooks.selected = activeTab; addScroll(hooks); + } - ScriptContainer container = script.getNPCScript(activeTab); + // ==================== SCRIPT TEXT AREA ==================== + int idx = getActiveScriptIndex(); + GuiScriptTextArea activeArea = getActiveScriptArea(); + if (activeArea == null) { + activeArea = new GuiScriptTextArea(this, 2, editorX, editorY, editorWidth, editorHeight, + container == null ? "" : container.script); + activeArea.setListener(this); + this.closeOnEsc(activeArea::closeOnEsc); + textAreas.put(idx, activeArea); + } else { + activeArea.init(editorX, editorY, editorWidth, editorHeight, + container == null ? "" : container.script); + } - int idx = this.activeTab; - GuiScriptTextArea activeArea = getActiveScriptArea(); - if (activeArea == null) { - activeArea = new GuiScriptTextArea(this, 2, guiLeft + 74, guiTop + 4, 239, 208, - container == null ? "" : container.script); - activeArea.setListener(this); - this.closeOnEsc(activeArea::closeOnEsc); - textAreas.put(idx, activeArea); - } else { - activeArea.init(guiLeft + 74, guiTop + 4, 239, 208, container == null ? "" : container.script); + activeArea.setLanguage(script.getLanguage()); + activeArea.setScriptContext(getScriptContext()); + + // Setup fullscreen key binding + GuiScriptTextArea.KEYS.FULLSCREEN.setTask(e -> { + if (e.isPress()) { + toggleFullscreen(); } + }); + + activeArea.enableCodeHighlighting(); + addTextField(activeArea); + + // Initialize fullscreen button + int scrollbarOffset = activeArea.hasVerticalScrollbar() ? -8 : -2; + fullscreenButton.initGui(editorX + editorWidth, editorY, scrollbarOffset); + // ==================== RIGHT PANEL BUTTONS (hidden in fullscreen) ==================== + if (!isFullscreen) { addButton(new GuiNpcButton(102, guiLeft + 315, guiTop + 4, 50, 20, "gui.clear")); addButton(new GuiNpcButton(101, guiLeft + 366, guiTop + 4, 50, 20, "gui.paste")); addButton(new GuiNpcButton(100, guiLeft + 315, guiTop + 25, 50, 20, "gui.copy")); - addButton(new GuiNpcButton(107, guiLeft + 315, guiTop + 70, 80, 20, "script.loadscript")); GuiCustomScroll scroll = new GuiCustomScroll(this, 0).setUnselectable(); @@ -113,74 +180,49 @@ public class GuiScript extends GuiNPCInterface implements IGuiData, GuiYesNoCall if (container != null) scroll.setList(container.scripts); addScroll(scroll); - } else { - addLabel(new GuiNpcLabel(0, "script.console", guiLeft + 4, guiTop + 16)); - getTopButton(14).active = true; - addTextField(new GuiNpcTextArea(2, this, guiLeft + 4, guiTop + 26, 226, 186, getConsoleText())); - getTextField(2).canEdit = false; - addButton(new GuiNpcButton(100, guiLeft + 232, guiTop + 170, 56, 20, "gui.copy")); - addButton(new GuiNpcButton(102, guiLeft + 232, guiTop + 192, 56, 20, "gui.clear")); - - List l = new ArrayList(); - l.add("All"); - l.addAll(list); - addButton(new GuiNpcButton(105, guiLeft + 60, guiTop + 4, 80, 20, l.toArray(new String[l.size()]), activeConsole)); - - addLabel(new GuiNpcLabel(1, "script.language", guiLeft + 232, guiTop + 30)); - addButton(new GuiNpcButton(103, guiLeft + 294, guiTop + 25, 80, 20, languages.keySet().toArray(new String[languages.keySet().size()]), getScriptIndex())); - getButton(103).enabled = languages.size() > 0; - - addLabel(new GuiNpcLabel(2, "gui.enabled", guiLeft + 232, guiTop + 53)); - addButton(new GuiNpcButton(104, guiLeft + 294, guiTop + 48, 50, 20, new String[]{"gui.no", "gui.yes"}, script.enabled ? 1 : 0)); - - if (MinecraftServer.getServer() != null) - addButton(new GuiNpcButton(106, guiLeft + 232, guiTop + 71, 150, 20, "script.openfolder")); } } + + private void initSettingsView() { + addLabel(new GuiNpcLabel(0, "script.console", guiLeft + 4, guiTop + 16)); + getTopButton(14).active = true; + + GuiNpcTextArea consoleArea = new GuiNpcTextArea(2, this, guiLeft + 4, guiTop + 26, 226, 186, getConsoleText()); + consoleArea.canEdit = false; + addTextField(consoleArea); + + addButton(new GuiNpcButton(100, guiLeft + 232, guiTop + 170, 56, 20, "gui.copy")); + addButton(new GuiNpcButton(102, guiLeft + 232, guiTop + 192, 56, 20, "gui.clear")); - private GuiScriptTextArea getActiveScriptArea() { - if (this.activeTab > 0) { - int idx = this.activeTab; - if (idx >= 0 && idx < textAreas.size()) - return textAreas.get(idx); - } - return null; + List consoleOptions = new ArrayList<>(); + consoleOptions.add("All"); + consoleOptions.addAll(hookList); + addButton(new GuiNpcButton(105, guiLeft + 60, guiTop + 4, 80, 20, + consoleOptions.toArray(new String[0]), activeConsole)); + + addLabel(new GuiNpcLabel(1, "script.language", guiLeft + 232, guiTop + 30)); + addButton(new GuiNpcButton(103, guiLeft + 294, guiTop + 25, 80, 20, + languages.keySet().toArray(new String[0]), getScriptIndex())); + getButton(103).enabled = languages.size() > 0; + + addLabel(new GuiNpcLabel(2, "gui.enabled", guiLeft + 232, guiTop + 53)); + addButton(new GuiNpcButton(104, guiLeft + 294, guiTop + 48, 50, 20, + new String[]{"gui.no", "gui.yes"}, script.enabled ? 1 : 0)); + + if (MinecraftServer.getServer() != null) + addButton(new GuiNpcButton(106, guiLeft + 232, guiTop + 71, 150, 20, "script.openfolder")); } @Override - public GuiNpcTextField getTextField(int id) { - if (id == 2) { - GuiScriptTextArea area = getActiveScriptArea(); - if (area != null) - return area; - } - return super.getTextField(id); - } - - private int getScriptIndex() { - int i = 0; - for (String language : languages.keySet()) { - if (language.equalsIgnoreCase(script.scriptLanguage)) - return i; - i++; - } - return 0; - } - - private String getConsoleText() { + protected String getConsoleText() { Map map = this.script.getOldConsoleText(); StringBuilder builder = new StringBuilder(); - Iterator var3 = map.entrySet().iterator(); - - while (var3.hasNext()) { - Map.Entry entry = (Map.Entry) var3.next(); - builder.insert(0, new Date((Long) entry.getKey()) + (String) entry.getValue() + "\n"); + for (Map.Entry entry : map.entrySet()) { + builder.insert(0, new Date(entry.getKey()) + entry.getValue() + "\n"); } - return builder.toString(); } - @Override public void confirmClicked(boolean result, int id) { NoppesUtil.openGUI(player, this); @@ -205,8 +247,6 @@ public class GuiScript extends GuiNPCInterface implements IGuiData, GuiYesNoCall } } } - - displayGuiScreen(this); } @@ -222,8 +262,7 @@ public class GuiScript extends GuiNPCInterface implements IGuiData, GuiYesNoCall initGui(); } if (guibutton.id == 15) { - GuiConfirmOpenLink guiyesno = new GuiConfirmOpenLink(this, "https://kamkeel.github.io/CustomNPC-Plus/", 0, true); - mc.displayGuiScreen(guiyesno); + displayGuiScreen(new GuiConfirmOpenLink(this, "https://kamkeel.github.io/CustomNPC-Plus/", 0, true)); } if (guibutton.id == 16) { close(); @@ -236,12 +275,12 @@ public class GuiScript extends GuiNPCInterface implements IGuiData, GuiYesNoCall NoppesStringUtils.setClipboardContents(getTextField(2).getText()); } if (guibutton.id == 101) { - GuiYesNo guiyesno = new GuiYesNo(this, StatCollector.translateToLocal("gui.paste"), StatCollector.translateToLocal("gui.sure"), 101); - displayGuiScreen(guiyesno); + displayGuiScreen(new GuiYesNo(this, StatCollector.translateToLocal("gui.paste"), + StatCollector.translateToLocal("gui.sure"), 101)); } if (guibutton.id == 102) { - GuiYesNo guiyesno = new GuiYesNo(this, StatCollector.translateToLocal("gui.clear"), StatCollector.translateToLocal("gui.sure"), 102); - displayGuiScreen(guiyesno); + displayGuiScreen(new GuiYesNo(this, StatCollector.translateToLocal("gui.clear"), + StatCollector.translateToLocal("gui.sure"), 102)); } if (guibutton.id == 103) { script.scriptLanguage = ((GuiNpcButton) guibutton).displayString; @@ -254,21 +293,20 @@ public class GuiScript extends GuiNPCInterface implements IGuiData, GuiYesNoCall initGui(); } if (guibutton.id == 106) { - // TODO: Uses ScriptController.Instance.dir (shared script repository); this GUI is gated behind the scripter tool - // and CustomNpcsPermissions.TOOL_SCRIPTER so only authorized editors touch the controller-backed scripts. NoppesUtil.openFolder(ScriptController.Instance.dir); } if (guibutton.id == 107) { - ScriptContainer container = script.getNPCScript(activeTab); + ScriptContainer container = getCurrentContainer(); if (container == null) script.setNPCScript(activeTab, container = new ScriptContainer(this.script)); setSubGui(new GuiScriptList(languages.get(script.scriptLanguage), container)); } } - private void setScript() { + @Override + protected void setScript() { if (showScript) { - ScriptContainer container = script.getNPCScript(activeTab); + ScriptContainer container = getCurrentContainer(); if (container == null) script.setNPCScript(activeTab, container = new ScriptContainer(this.script)); String text = getTextField(2).getText(); @@ -277,23 +315,31 @@ public class GuiScript extends GuiNPCInterface implements IGuiData, GuiYesNoCall container.script = text; } } + + @Override + public void mouseClicked(int mouseX, int mouseY, int mouseButton) { + // Check if click is within autocomplete menu bounds and consume it if so + GuiScriptTextArea activeArea = getActiveScriptArea(); + boolean isOverAutocomplete = activeArea != null + && activeArea.isPointOnAutocompleteMenu(mouseX, mouseY); + if (isOverAutocomplete) { + activeArea.mouseClicked(mouseX, mouseY, mouseButton); + return; + } + + // Check fullscreen button when in script view + if (showScript && !isOverAutocomplete + && fullscreenButton.mouseClicked(mouseX, mouseY, mouseButton)) { + return; + } + + super.mouseClicked(mouseX, mouseY, mouseButton); + } @Override public void setGuiData(NBTTagCompound compound) { script.readFromNBT(compound); - NBTTagList data = compound.getTagList("Languages", 10); - Map> languages = new HashMap>(); - for (int i = 0; i < data.tagCount(); i++) { - NBTTagCompound comp = data.getCompoundTagAt(i); - List scripts = new ArrayList(); - NBTTagList list = comp.getTagList("Scripts", 8); - for (int j = 0; j < list.tagCount(); j++) { - scripts.add(list.getStringTagAt(j)); - } - languages.put(comp.getString("Language"), scripts); - } - this.languages = languages; - initGui(); + loadLanguagesData(compound); loaded = true; } @@ -313,20 +359,5 @@ public class GuiScript extends GuiNPCInterface implements IGuiData, GuiYesNoCall initGui(); } } - - public void textUpdate(String text) { - ScriptContainer container = script.getNPCScript(activeTab); - if (container != null) - container.script = text; - } - - @Override - public void saveText(String text) { - ScriptContainer container = script.getNPCScript(activeTab); - if (container != null) - container.script = text; - initGui(); - } - } diff --git a/src/main/java/noppes/npcs/client/gui/script/GuiScriptInterface.java b/src/main/java/noppes/npcs/client/gui/script/GuiScriptInterface.java index 765f29f60..1df897ecc 100644 --- a/src/main/java/noppes/npcs/client/gui/script/GuiScriptInterface.java +++ b/src/main/java/noppes/npcs/client/gui/script/GuiScriptInterface.java @@ -41,14 +41,20 @@ public class GuiScriptInterface extends GuiNPCInterface implements GuiYesNoCallb protected int activeTab = 0; public IScriptHandler handler; public Map> languages = new HashMap(); - private int scriptLimit = 1; + protected int scriptLimit = 1; public List hookList = new ArrayList(); protected boolean loaded = false; - private Map textAreas = new HashMap<>(); + protected Map textAreas = new HashMap<>(); protected GuiScreen parent; - public boolean singleContainer = false; + public boolean singleContainer = false; + + /** If true, uses scroll-based tab selection instead of top buttons */ + protected boolean useScrollTabs = false; + + /** If true, shows settings/script toggle instead of numbered tabs */ + protected boolean useSettingsToggle = false; // ==================== FULLSCREEN MODE ==================== /** Whether the editor viewport is currently in fullscreen mode */ @@ -94,48 +100,54 @@ public class GuiScriptInterface extends GuiNPCInterface implements GuiYesNoCallb int yoffset = (int) ((double) this.ySize * 0.02D); // ==================== TAB BUTTONS ==================== - GuiMenuTopButton top; - int topButtonsX = isFullscreen && activeTab != 0 ? FullscreenConfig.paddingLeft : this.guiLeft + 4; - int topButtonsY = isFullscreen && activeTab != 0 ? FullscreenConfig.paddingTop - 20 : this.guiTop - 17; - this.addTopButton(top = new GuiMenuTopButton(0, topButtonsX, topButtonsY, "gui.settings")); + // Skip standard tab creation for GUIs that use custom toggle/scroll tabs + if (!useSettingsToggle) { + GuiMenuTopButton top; + int topButtonsX = isFullscreen && activeTab != 0 ? FullscreenConfig.paddingLeft : this.guiLeft + 4; + int topButtonsY = isFullscreen && activeTab != 0 ? FullscreenConfig.paddingTop - 20 : this.guiTop - 17; + this.addTopButton(top = new GuiMenuTopButton(0, topButtonsX, topButtonsY, "gui.settings")); - int topXoffset = 0; - int topYoffset = 0; - if(!singleContainer) { - for (int ta = 0; ta < this.handler.getScripts().size(); ++ta) { - if (ta % 20 == 0 && ta > 0) { - topYoffset -= 20; - topXoffset -= top.width + 20 * 22; + int topXoffset = 0; + int topYoffset = 0; + if(!singleContainer) { + for (int ta = 0; ta < this.handler.getScripts().size(); ++ta) { + if (ta % 20 == 0 && ta > 0) { + topYoffset -= 20; + topXoffset -= top.width + 20 * 22; + } + this.addTopButton(top = new GuiMenuTopButton(ta + 1, top.xPosition + top.width + topXoffset, + top.yPosition + topYoffset, ta + 1 + "")); + topXoffset = 0; + topYoffset = 0; + scriptLimit = ta + 2; } - this.addTopButton(top = new GuiMenuTopButton(ta + 1, top.xPosition + top.width + topXoffset, - top.yPosition + topYoffset, ta + 1 + "")); - topXoffset = 0; - topYoffset = 0; - scriptLimit = ta + 2; } + + if (singleContainer && getFirst() != null) + this.addTopButton( + top = new GuiMenuTopButton(1, top.xPosition + top.width + topXoffset, top.yPosition + topYoffset, + "Script")); + else if (this.handler.getScripts().size() < 100) + this.addTopButton(new GuiMenuTopButton(scriptLimit, top.xPosition + top.width, top.yPosition, "+")); + + + top = this.getTopButton(this.activeTab); + if (top == null) { + this.activeTab = 0; + top = this.getTopButton(0); + } + top.active = true; } - if (singleContainer && getFirst() != null) - this.addTopButton( - top = new GuiMenuTopButton(1, top.xPosition + top.width + topXoffset, top.yPosition + topYoffset, - "Script")); - else if (this.handler.getScripts().size() < 100) - this.addTopButton(new GuiMenuTopButton(scriptLimit, top.xPosition + top.width, top.yPosition, "+")); - - - top = this.getTopButton(this.activeTab); - if (top == null) { - this.activeTab = 0; - top = this.getTopButton(0); - } - top.active = true; - // ==================== SCRIPT EDITOR TAB (activeTab > 0) ==================== - if (this.activeTab > 0) { - initScriptEditorTab(yoffset); - } else { - // ==================== SETTINGS TAB (activeTab == 0) ==================== - initSettingsTab(yoffset); + // Skip for GUIs that handle their own view initialization (useSettingsToggle) + if (!useSettingsToggle) { + if (this.activeTab > 0) { + initScriptEditorTab(yoffset); + } else { + // ==================== SETTINGS TAB (activeTab == 0) ==================== + initSettingsTab(yoffset); + } } this.xSize = 420; @@ -147,7 +159,7 @@ public class GuiScriptInterface extends GuiNPCInterface implements GuiYesNoCallb * Handles both normal and fullscreen modes. */ private void initScriptEditorTab(int yoffset) { - ScriptContainer container = (ScriptContainer) this.handler.getScripts().get(this.activeTab - 1); + ScriptContainer container = getCurrentContainer(); // ==================== CALCULATE VIEWPORT BOUNDS ==================== int editorX, editorY, editorWidth, editorHeight; @@ -191,7 +203,7 @@ public class GuiScriptInterface extends GuiNPCInterface implements GuiYesNoCallb } // ==================== SCRIPT TEXT AREA ==================== - int idx = this.activeTab - 1; + int idx = getActiveScriptIndex(); GuiScriptTextArea activeArea = getActiveScriptArea(); if (activeArea == null) { activeArea = new GuiScriptTextArea(this, 2, editorX, editorY, editorWidth, editorHeight, @@ -390,11 +402,28 @@ public class GuiScriptInterface extends GuiNPCInterface implements GuiYesNoCallb } public GuiScriptTextArea getActiveScriptArea() { - if (this.activeTab > 0) { - int idx = this.activeTab - 1; - if (idx >= 0 && idx < textAreas.size()) - return textAreas.get(idx); - } + int idx = getActiveScriptIndex(); + if (idx >= 0 && textAreas.containsKey(idx)) + return textAreas.get(idx); + return null; + } + + /** + * Get the current script index for text area storage. + * Override in subclasses with different tab logic. + */ + protected int getActiveScriptIndex() { + return this.activeTab - 1; + } + + /** + * Get the current script container. + * Override in subclasses with different container access patterns. + */ + protected ScriptContainer getCurrentContainer() { + int idx = getActiveScriptIndex(); + if (idx >= 0 && idx < this.handler.getScripts().size()) + return this.handler.getScripts().get(idx); return null; } @@ -500,8 +529,8 @@ public class GuiScriptInterface extends GuiNPCInterface implements GuiYesNoCallb } protected void setScript() { - if (this.activeTab > 0) { - ScriptContainer container = (ScriptContainer) this.handler.getScripts().get(this.activeTab - 1); + if (this.activeTab > 0 || useScrollTabs) { + ScriptContainer container = getCurrentContainer(); if (container == null) { container = new ScriptContainer(this.handler); if (singleContainer) @@ -644,7 +673,7 @@ public class GuiScriptInterface extends GuiNPCInterface implements GuiYesNoCallb } public void textUpdate(String text) { - ScriptContainer container = (ScriptContainer) this.handler.getScripts().get(this.activeTab - 1); + ScriptContainer container = getCurrentContainer(); if (container != null) { container.script = text; } @@ -655,7 +684,7 @@ public class GuiScriptInterface extends GuiNPCInterface implements GuiYesNoCallb @Override //NEVER USED public void saveText(String text) { - ScriptContainer container = handler.getScripts().get(activeTab ); //activeTab - 1? + ScriptContainer container = getCurrentContainer(); if (container != null) container.script = text; initGui();