mirror of
https://github.com/KAMKEEL/CustomNPC-Plus.git
synced 2026-11-13 06:37:34 +00:00
Fix Instanced Abilities Reloading per Usage
This commit is contained in:
1 parent
2ba2372bde
commit
54e0ca6510
8 files changed
+144
-18
No files matched your search
@@ -11,6 +11,7 @@ import noppes.npcs.controllers.data.IScriptHandler;
|
||||
import noppes.npcs.controllers.data.IScriptUnit;
|
||||
import noppes.npcs.scripted.NpcAPI;
|
||||
|
||||
import javax.script.Bindings;
|
||||
import javax.script.Compilable;
|
||||
import javax.script.CompiledScript;
|
||||
import javax.script.ScriptContext;
|
||||
@@ -52,10 +53,39 @@ public class ScriptContainer implements IScriptUnit {
|
||||
*/
|
||||
private String language = null;
|
||||
|
||||
/**
|
||||
* Per-instance bindings for variable isolation. When non-null, this container
|
||||
* is an instance scope sharing a template's engine. All eval/lookup uses these
|
||||
* bindings instead of the engine's default ENGINE_SCOPE.
|
||||
*/
|
||||
private Bindings instanceBindings = null;
|
||||
|
||||
public ScriptContainer(IScriptHandler handler) {
|
||||
this.handler = handler;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a lightweight instance scope that shares this container's engine
|
||||
* but has its own isolated Bindings for variable state.
|
||||
* The template's engine is initialized if needed.
|
||||
*
|
||||
* @param instanceHandler the script handler for the instance
|
||||
*/
|
||||
public ScriptContainer createInstanceScope(IScriptHandler instanceHandler) {
|
||||
if (this.engine == null) {
|
||||
this.setEngine(this.getLanguage());
|
||||
}
|
||||
ScriptContainer instance = new ScriptContainer(instanceHandler);
|
||||
instance.script = this.script;
|
||||
instance.scripts = new ArrayList<>(this.scripts);
|
||||
instance.console = this.console;
|
||||
instance.language = this.language;
|
||||
instance.engine = this.engine;
|
||||
instance.currentScriptLanguage = this.currentScriptLanguage;
|
||||
instance.instanceBindings = this.engine.createBindings();
|
||||
return instance;
|
||||
}
|
||||
|
||||
public void readFromNBT(NBTTagCompound compound) {
|
||||
String prevScript = this.script;
|
||||
this.script = compound.getString("Script");
|
||||
@@ -205,20 +235,33 @@ public class ScriptContainer implements IScriptUnit {
|
||||
engine.getContext().setWriter(pw);
|
||||
engine.getContext().setErrorWriter(pw);
|
||||
|
||||
engine.put("API", NpcAPI.Instance());
|
||||
HashMap<String, Object> engineEntries = new HashMap<>(NpcAPI.engineObjects);
|
||||
for (Map.Entry<String, Object> objectEntry : engineEntries.entrySet()) {
|
||||
engine.put(objectEntry.getKey(), objectEntry.getValue());
|
||||
// Populate bindings with API objects
|
||||
if (instanceBindings != null) {
|
||||
instanceBindings.put("API", NpcAPI.Instance());
|
||||
HashMap<String, Object> engineEntries = new HashMap<>(NpcAPI.engineObjects);
|
||||
for (Map.Entry<String, Object> objectEntry : engineEntries.entrySet()) {
|
||||
instanceBindings.put(objectEntry.getKey(), objectEntry.getValue());
|
||||
}
|
||||
} else {
|
||||
engine.put("API", NpcAPI.Instance());
|
||||
HashMap<String, Object> engineEntries = new HashMap<>(NpcAPI.engineObjects);
|
||||
for (Map.Entry<String, Object> objectEntry : engineEntries.entrySet()) {
|
||||
engine.put(objectEntry.getKey(), objectEntry.getValue());
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
if (!evaluated) {
|
||||
this.cachedFunctions.clear();
|
||||
engine.eval(getFullCode());
|
||||
if (instanceBindings != null) {
|
||||
engine.eval(getFullCode(), instanceBindings);
|
||||
} else {
|
||||
engine.eval(getFullCode());
|
||||
}
|
||||
evaluated = true;
|
||||
}
|
||||
if (engine.getFactory().getLanguageName().equals("lua")) {
|
||||
Object ob = engine.get(type);
|
||||
Object ob = instanceBindings != null ? instanceBindings.get(type) : engine.get(type);
|
||||
if (ob != null) {
|
||||
if (luaCoerce == null) {
|
||||
luaCoerce = Class.forName("org.luaj.vm2.lib.jse.CoerceJavaToLua").getMethod("coerce", Object.class);
|
||||
@@ -230,8 +273,14 @@ public class ScriptContainer implements IScriptUnit {
|
||||
}
|
||||
} else {
|
||||
if (!this.cachedFunctions.containsKey(type)) {
|
||||
ScriptObjectMirror global = (ScriptObjectMirror) engine.getBindings(ScriptContext.ENGINE_SCOPE);
|
||||
ScriptObjectMirror func = (ScriptObjectMirror) global.get(type);
|
||||
ScriptObjectMirror func;
|
||||
if (instanceBindings != null) {
|
||||
Object val = instanceBindings.get(type);
|
||||
func = val instanceof ScriptObjectMirror ? (ScriptObjectMirror) val : null;
|
||||
} else {
|
||||
ScriptObjectMirror global = (ScriptObjectMirror) engine.getBindings(ScriptContext.ENGINE_SCOPE);
|
||||
func = (ScriptObjectMirror) global.get(type);
|
||||
}
|
||||
this.cachedFunctions.put(type, func);
|
||||
}
|
||||
ScriptObjectMirror func = this.cachedFunctions.get(type);
|
||||
@@ -280,6 +329,8 @@ public class ScriptContainer implements IScriptUnit {
|
||||
|
||||
public void setEngine(String scriptLanguage) {
|
||||
if (!Objects.equals(scriptLanguage, this.currentScriptLanguage)) {
|
||||
// Instance scopes share the template's engine — never create a new one
|
||||
if (instanceBindings != null) return;
|
||||
this.currentScriptLanguage = scriptLanguage;
|
||||
if (ConfigScript.ScriptingECMA6 && scriptLanguage.equals("ECMAScript")) {
|
||||
System.setProperty("nashorn.args", "--language=es6");
|
||||
|
||||
Reference in new issue
Block a user