mirror of
https://github.com/KAMKEEL/CustomNPC-Plus.git
synced 2026-11-12 02:37:27 +00:00
ScriptHandler refactor:
- ScriptHandler now holds a list of containers - Delegated single container handling to SingleScriptHandler IScriptHandler refactor: - Moved ScriptContext/Hook logic to it - More default methods + hooked them to GuIScriptInterface
This commit is contained in:
1 parent
44f71ddb81
commit
eecb5b0b3b
4 files changed
+294
-51
No files matched your search
@@ -27,6 +27,7 @@ import noppes.npcs.constants.ScriptContext;
|
||||
import noppes.npcs.controllers.data.ForgeDataScript;
|
||||
import noppes.npcs.controllers.data.IScriptHandler;
|
||||
import noppes.npcs.controllers.data.IScriptUnit;
|
||||
import noppes.npcs.controllers.data.IScriptHandlerPacket;
|
||||
import noppes.npcs.scripted.item.ScriptCustomItem;
|
||||
import org.lwjgl.opengl.Display;
|
||||
|
||||
@@ -49,7 +50,6 @@ public class GuiScriptInterface extends GuiNPCInterface implements GuiYesNoCallb
|
||||
protected Map<Integer, GuiScriptTextArea> textAreas = new HashMap<>();
|
||||
protected GuiScreen parent;
|
||||
|
||||
public boolean singleContainer = false;
|
||||
|
||||
/** If true, uses scroll-based tab selection instead of top buttons */
|
||||
protected boolean useScrollTabs = false;
|
||||
@@ -97,6 +97,12 @@ public class GuiScriptInterface extends GuiNPCInterface implements GuiYesNoCallb
|
||||
gui.parent = parent;
|
||||
gui.singleContainer = true;
|
||||
gui.displayGuiScreen(gui);
|
||||
|
||||
// Initialize hooks from handler
|
||||
gui.hookList = new ArrayList<>(handler.getHooks());
|
||||
|
||||
|
||||
Minecraft.getMinecraft().displayGuiScreen(gui);
|
||||
return gui;
|
||||
}
|
||||
|
||||
@@ -113,6 +119,9 @@ public class GuiScriptInterface extends GuiNPCInterface implements GuiYesNoCallb
|
||||
this.guiTop += 10;
|
||||
int yoffset = (int) ((double) this.ySize * 0.02D);
|
||||
|
||||
if (hookList.isEmpty())
|
||||
hookList = new ArrayList<>(handler.getHooks());
|
||||
|
||||
// ==================== TAB BUTTONS ====================
|
||||
// Skip standard tab creation for GUIs that use custom toggle/scroll tabs
|
||||
if (!useSettingsToggle) {
|
||||
@@ -123,7 +132,8 @@ public class GuiScriptInterface extends GuiNPCInterface implements GuiYesNoCallb
|
||||
|
||||
int topXoffset = 0;
|
||||
int topYoffset = 0;
|
||||
if(!singleContainer) {
|
||||
boolean isSingle = handler.isSingleContainer();
|
||||
if (!isSingle) {
|
||||
for (int ta = 0; ta < this.handler.getScripts().size(); ++ta) {
|
||||
if (ta % 20 == 0 && ta > 0) {
|
||||
topYoffset -= 20;
|
||||
@@ -137,7 +147,7 @@ public class GuiScriptInterface extends GuiNPCInterface implements GuiYesNoCallb
|
||||
}
|
||||
}
|
||||
|
||||
if (singleContainer && getFirst() != null)
|
||||
if (isSingle && handler.getSingleScript() != null)
|
||||
this.addTopButton(
|
||||
top = new GuiMenuTopButton(1, top.xPosition + top.width + topXoffset, top.yPosition + topYoffset,
|
||||
"Script"));
|
||||
@@ -233,10 +243,7 @@ public class GuiScriptInterface extends GuiNPCInterface implements GuiYesNoCallb
|
||||
// Set the scripting language for proper syntax highlighting
|
||||
// Use the container's language if available, otherwise fall back to handler's language
|
||||
String language = (container != null) ? container.getLanguage() : this.handler.getLanguage();
|
||||
activeArea.setLanguage(language);
|
||||
|
||||
// Set the script context for context-aware hook autocomplete
|
||||
activeArea.setScriptContext(getScriptContext());
|
||||
activeArea.setLanguage(language);
|
||||
|
||||
// Set the script context for context-aware hook autocomplete
|
||||
activeArea.setScriptContext(getScriptContext());
|
||||
@@ -320,6 +327,16 @@ public class GuiScriptInterface extends GuiNPCInterface implements GuiYesNoCallb
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the script context for this GUI.
|
||||
* Override in subclasses to return a different context.
|
||||
*
|
||||
* @return The script context (default: GLOBAL, or handler's context if available)
|
||||
*/
|
||||
protected ScriptContext getScriptContext() {
|
||||
return handler.getContext();
|
||||
}
|
||||
|
||||
// ==================== RENDERING ====================
|
||||
|
||||
@Override
|
||||
@@ -418,10 +435,7 @@ public class GuiScriptInterface extends GuiNPCInterface implements GuiYesNoCallb
|
||||
this.openLink("http://www.minecraftforge.net/forum/index.php/board,122.0.html");
|
||||
}
|
||||
if (i == 10) {
|
||||
if (singleContainer)
|
||||
setHandlerUnit(null);
|
||||
else
|
||||
this.handler.getScripts().remove(this.activeTab - 1);
|
||||
handler.removeScriptUnit(this.activeTab - 1);
|
||||
this.activeTab = 0;
|
||||
}
|
||||
if (i == 101) {
|
||||
@@ -482,11 +496,6 @@ public class GuiScriptInterface extends GuiNPCInterface implements GuiYesNoCallb
|
||||
return super.getTextField(id);
|
||||
}
|
||||
|
||||
public IScriptUnit getFirst() {
|
||||
if (this.handler.getScripts().isEmpty())
|
||||
return null;
|
||||
return this.handler.getScripts().get(0);
|
||||
}
|
||||
@Override
|
||||
protected void actionPerformed(GuiButton guibutton) {
|
||||
if (guibutton.id >= 0 && guibutton.id < scriptLimit) {
|
||||
@@ -501,14 +510,15 @@ public class GuiScriptInterface extends GuiNPCInterface implements GuiYesNoCallb
|
||||
}
|
||||
|
||||
if (guibutton.id == scriptLimit) {
|
||||
if (singleContainer) {
|
||||
if (getFirst() == null)
|
||||
setHandlerUnit(new ScriptContainer(handler));
|
||||
else
|
||||
if (handler.isSingleContainer()) {
|
||||
if (handler.getSingleScript() == null) {
|
||||
handler.addScriptUnit(new ScriptContainer(handler));
|
||||
} else {
|
||||
this.setScript();
|
||||
}
|
||||
this.activeTab = 1;
|
||||
} else {
|
||||
this.handler.getScripts().add(new ScriptContainer(this.handler));
|
||||
handler.addScriptUnit(new ScriptContainer(this.handler));
|
||||
this.activeTab = this.handler.getScripts().size();
|
||||
}
|
||||
this.initGui();
|
||||
@@ -567,10 +577,7 @@ public class GuiScriptInterface extends GuiNPCInterface implements GuiYesNoCallb
|
||||
IScriptUnit container = getCurrentContainer();
|
||||
if (container == null) {
|
||||
container = new ScriptContainer(this.handler);
|
||||
if (singleContainer)
|
||||
setHandlerUnit(container);
|
||||
else
|
||||
this.handler.getScripts().add(container);
|
||||
handler.addScriptUnit(container);
|
||||
}
|
||||
|
||||
String language = container != null ? container.getLanguage() : this.handler.getLanguage();
|
||||
@@ -600,12 +607,7 @@ public class GuiScriptInterface extends GuiNPCInterface implements GuiYesNoCallb
|
||||
}
|
||||
}
|
||||
|
||||
if (singleContainer) {
|
||||
setHandlerUnit(newUnit);
|
||||
} else {
|
||||
// Replace the script unit in the list
|
||||
handler.getScripts().set(idx, newUnit);
|
||||
}
|
||||
handler.replaceScriptUnit(idx, newUnit);
|
||||
// Clear the cached text area so it recreates with new language
|
||||
textAreas.remove(idx);
|
||||
|
||||
@@ -621,10 +623,7 @@ public class GuiScriptInterface extends GuiNPCInterface implements GuiYesNoCallb
|
||||
|
||||
if (container == null) {
|
||||
container = new ScriptContainer(this.handler);
|
||||
if (singleContainer)
|
||||
setHandlerUnit(container);
|
||||
else
|
||||
this.handler.getScripts().add(container);
|
||||
handler.addScriptUnit(container);
|
||||
}
|
||||
|
||||
if (container != null) {
|
||||
|
||||
@@ -3,7 +3,10 @@ package noppes.npcs.controllers.data;
|
||||
import cpw.mods.fml.common.FMLCommonHandler;
|
||||
import cpw.mods.fml.common.eventhandler.Event;
|
||||
import noppes.npcs.constants.EnumScriptType;
|
||||
import noppes.npcs.constants.ScriptContext;
|
||||
import noppes.npcs.controllers.ScriptHookController;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.TreeMap;
|
||||
@@ -74,4 +77,89 @@ public interface IScriptHandler {
|
||||
default boolean supportsJanino() {
|
||||
return createJaninoScriptUnit() != null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the script context for autocomplete and type resolution.
|
||||
*
|
||||
* @return The script context (default: GLOBAL)
|
||||
*/
|
||||
default ScriptContext getContext() {
|
||||
return ScriptContext.GLOBAL;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the hook context identifier for this handler.
|
||||
* Used by ScriptHookController to look up available hooks.
|
||||
*
|
||||
* @return The context string (e.g., IScriptHookHandler.CONTEXT_EFFECT), or empty if none
|
||||
*/
|
||||
default String getHookContext() {
|
||||
return "";
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the list of available hooks for this handler.
|
||||
* Uses getHookContext() to look up hooks from ScriptHookController.
|
||||
*
|
||||
* @return List of hook names, or empty list if no context
|
||||
*/
|
||||
default List<String> getHooks() {
|
||||
String context = getHookContext();
|
||||
if (context == null || context.isEmpty())
|
||||
return Collections.emptyList();
|
||||
|
||||
return ScriptHookController.Instance.getAllHooks(context);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if this handler manages only a single script container.
|
||||
* Single-container handlers use simplified UI (no numbered tabs).
|
||||
*
|
||||
* @return true if this handler uses a single container
|
||||
*/
|
||||
default boolean isSingleContainer() {
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the single script unit for single-container handlers.
|
||||
* Convenience method that returns the first script or null.
|
||||
*
|
||||
* @return The single script unit, or null if none exists
|
||||
*/
|
||||
default IScriptUnit getSingleScript() {
|
||||
List<IScriptUnit> scripts = getScripts();
|
||||
return (scripts != null && !scripts.isEmpty()) ? scripts.get(0) : null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a script unit to this handler.
|
||||
* For single-container handlers, replaces the current unit.
|
||||
*/
|
||||
default void addScriptUnit(IScriptUnit unit) {
|
||||
if (unit != null)
|
||||
getScripts().add(unit);
|
||||
}
|
||||
|
||||
/**
|
||||
* Replace a script unit at the given index.
|
||||
* For single-container handlers, replaces the current unit.
|
||||
*/
|
||||
default void replaceScriptUnit(int index, IScriptUnit unit) {
|
||||
List<IScriptUnit> scripts = getScripts();
|
||||
if (index < 0 || index >= scripts.size())
|
||||
scripts.add(unit);
|
||||
else
|
||||
scripts.set(index, unit);
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove a script unit at the given index.
|
||||
* For single-container handlers, clears the unit.
|
||||
*/
|
||||
default void removeScriptUnit(int index) {
|
||||
List<IScriptUnit> scripts = getScripts();
|
||||
if (index >= 0 && index < scripts.size())
|
||||
scripts.remove(index);
|
||||
}
|
||||
}
|
||||
@@ -5,24 +5,36 @@ import noppes.npcs.config.ConfigScript;
|
||||
import noppes.npcs.controllers.ScriptController;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
public abstract class ScriptHandler implements IScriptHandler {
|
||||
public IScriptUnit container;
|
||||
public List<IScriptUnit> scripts = new ArrayList<>();
|
||||
protected String scriptLanguage = "ECMAScript";
|
||||
protected boolean enabled = false;
|
||||
protected long lastInited = -1;
|
||||
|
||||
protected boolean canRunScripts() {
|
||||
return enabled && ScriptController.HasStart && ConfigScript.ScriptingEnabled && container != null;
|
||||
return enabled && ScriptController.HasStart && ConfigScript.ScriptingEnabled && scripts != null && !scripts.isEmpty();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void callScript(String hookName, Event event) {
|
||||
if (!canRunScripts()) {
|
||||
if (!canRunScripts())
|
||||
return;
|
||||
|
||||
if (ScriptController.Instance.lastLoaded > lastInited) {
|
||||
lastInited = ScriptController.Instance.lastLoaded;
|
||||
for (IScriptUnit script : scripts) {
|
||||
if (script != null)
|
||||
script.setErrored(false);
|
||||
}
|
||||
}
|
||||
|
||||
for (IScriptUnit script : scripts) {
|
||||
if (script == null || script.hasErrored() || !script.hasCode())
|
||||
continue;
|
||||
script.run(hookName, event);
|
||||
}
|
||||
container.run(hookName, event);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -45,20 +57,11 @@ public abstract class ScriptHandler implements IScriptHandler {
|
||||
this.scriptLanguage = language;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setScripts(List<IScriptUnit> list) {
|
||||
if (list == null || list.isEmpty()) {
|
||||
container = null;
|
||||
return;
|
||||
}
|
||||
container = list.get(0);
|
||||
this.scripts = list;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<IScriptUnit> getScripts() {
|
||||
if (container == null) {
|
||||
return new ArrayList<>();
|
||||
}
|
||||
return Collections.singletonList(container);
|
||||
return this.scripts;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,153 @@
|
||||
package noppes.npcs.controllers.data;
|
||||
|
||||
import cpw.mods.fml.common.eventhandler.Event;
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import kamkeel.npcs.util.ByteBufUtils;
|
||||
import net.minecraft.nbt.NBTTagCompound;
|
||||
import net.minecraftforge.common.util.Constants;
|
||||
import noppes.npcs.config.ConfigScript;
|
||||
import noppes.npcs.controllers.ScriptController;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Base class for script handlers that manage a single script container.
|
||||
* Provides shared NBT/ByteBuf serialization and packet handling.
|
||||
*
|
||||
* Subclasses should:
|
||||
* - Store their parent object (e.g., CustomEffect, LinkedItem)
|
||||
* - Override getHookContext() to return the appropriate context string
|
||||
* - Override getContext() if needed (default is GLOBAL)
|
||||
* - Override requestData() and sendSavePacket() for packet communication
|
||||
*/
|
||||
public abstract class SingleScriptHandler extends ScriptHandler {
|
||||
public IScriptUnit container;
|
||||
|
||||
@Override
|
||||
public boolean isSingleContainer() {
|
||||
return true;
|
||||
}
|
||||
|
||||
protected boolean canRunScripts() {
|
||||
return enabled && ScriptController.HasStart && ConfigScript.ScriptingEnabled && container != null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void callScript(String hookName, Event event) {
|
||||
if (!canRunScripts()) {
|
||||
return;
|
||||
}
|
||||
container.run(hookName, event);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setScripts(List<IScriptUnit> list) {
|
||||
if (list == null || list.isEmpty()) {
|
||||
container = null;
|
||||
this.scripts = new ArrayList<>();
|
||||
} else {
|
||||
container = list.get(0);
|
||||
this.scripts = new ArrayList<>(1);
|
||||
this.scripts.add(container);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<IScriptUnit> getScripts() {
|
||||
if(container == null)
|
||||
return new ArrayList<>();
|
||||
|
||||
return Collections.singletonList(container);
|
||||
}
|
||||
|
||||
public void addScriptUnit(IScriptUnit unit) {
|
||||
this.container = unit;
|
||||
this.scripts.clear();
|
||||
if (unit != null)
|
||||
this.scripts.add(unit);
|
||||
}
|
||||
|
||||
public void replaceScriptUnit(int index, IScriptUnit unit) {
|
||||
this.container = unit;
|
||||
this.scripts.clear();
|
||||
if (unit != null)
|
||||
this.scripts.add(unit);
|
||||
}
|
||||
|
||||
public void removeScriptUnit(int index) {
|
||||
this.container = null;
|
||||
this.scripts.clear();
|
||||
}
|
||||
|
||||
/**
|
||||
* Write script data to NBT.
|
||||
* Uses standard keys: ScriptLanguage, ScriptEnabled, ScriptContent
|
||||
*/
|
||||
public NBTTagCompound writeToNBT(NBTTagCompound compound) {
|
||||
compound.setString("ScriptLanguage", scriptLanguage);
|
||||
compound.setBoolean("ScriptEnabled", enabled);
|
||||
|
||||
if (container != null) {
|
||||
compound.setTag("ScriptContent", container.writeToNBT(new NBTTagCompound()));
|
||||
}
|
||||
return compound;
|
||||
}
|
||||
|
||||
/**
|
||||
* Read script data from NBT.
|
||||
* Uses standard keys: ScriptLanguage, ScriptEnabled, ScriptContent
|
||||
*/
|
||||
public void readFromNBT(NBTTagCompound compound) {
|
||||
scriptLanguage = compound.getString("ScriptLanguage");
|
||||
enabled = compound.getBoolean("ScriptEnabled");
|
||||
|
||||
if (compound.hasKey("ScriptContent", Constants.NBT.TAG_COMPOUND)) {
|
||||
container = IScriptUnit.createFromNBT(compound.getCompoundTag("ScriptContent"), this);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Save script data from a ByteBuf packet.
|
||||
* Handles the tab/totalScripts protocol used by script packets.
|
||||
*
|
||||
* Protocol:
|
||||
* - tab == 0: Script content NBT follows
|
||||
* - tab != 0 (typically -1): Script metadata (language, enabled) follows
|
||||
*/
|
||||
public void saveScript(ByteBuf buffer) throws IOException {
|
||||
int tab = buffer.readInt();
|
||||
int totalScripts = buffer.readInt();
|
||||
|
||||
if (totalScripts == 0) {
|
||||
this.container = null;
|
||||
}
|
||||
|
||||
if (tab == 0) {
|
||||
// Script content
|
||||
NBTTagCompound tabCompound = ByteBufUtils.readNBT(buffer);
|
||||
this.container = IScriptUnit.createFromNBT(tabCompound, this);
|
||||
} else {
|
||||
// Metadata (language, enabled)
|
||||
NBTTagCompound compound = ByteBufUtils.readNBT(buffer);
|
||||
this.setLanguage(compound.getString("ScriptLanguage"));
|
||||
normalizeLanguage();
|
||||
this.setEnabled(compound.getBoolean("ScriptEnabled"));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Normalize the language to a valid one if the current language is not available.
|
||||
*/
|
||||
protected void normalizeLanguage() {
|
||||
if (!ScriptController.Instance.languages.containsKey(this.getLanguage())) {
|
||||
if (!ScriptController.Instance.languages.isEmpty()) {
|
||||
this.setLanguage((String) ScriptController.Instance.languages.keySet().toArray()[0]);
|
||||
} else {
|
||||
this.setLanguage("ECMAScript");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user