mirror of
https://github.com/KAMKEEL/CustomNPC-Plus.git
synced 2026-11-12 03:47:27 +00:00
Hook Context
This commit is contained in:
1 parent
f4a5bbd1f6
commit
bee4d18bc6
6 files changed
+903
-198
No files matched your search
@@ -0,0 +1,307 @@
|
||||
package noppes.npcs.controllers;
|
||||
|
||||
import cpw.mods.fml.common.eventhandler.Cancelable;
|
||||
import noppes.npcs.api.handler.IHookDefinition;
|
||||
import noppes.npcs.janino.annotations.ParamName;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
import java.lang.reflect.Parameter;
|
||||
|
||||
/**
|
||||
* Implementation of {@link IHookDefinition} with a fluent builder API.
|
||||
*
|
||||
* <h3>Usage Examples</h3>
|
||||
* <pre>{@code
|
||||
* // Full definition with class reference
|
||||
* HookDefinition.builder("onDBCTransform")
|
||||
* .eventClass(IDBCEvent.TransformEvent.class)
|
||||
* .paramNames("event")
|
||||
* .requiredImports("com.dbc.api.event.IDBCEvent")
|
||||
* .cancelable(true)
|
||||
* .build();
|
||||
*
|
||||
* // String-based (avoids classloading issues)
|
||||
* HookDefinition.builder("onDBCPowerUp")
|
||||
* .eventClass("com.dbc.api.event.IDBCEvent$PowerUpEvent")
|
||||
* .requiredImports("com.dbc.api.event.IDBCEvent")
|
||||
* .build();
|
||||
*
|
||||
* // Simple hook (backward compat, no metadata)
|
||||
* HookDefinition.simple("legacyHook");
|
||||
* }</pre>
|
||||
*/
|
||||
public class HookDefinition implements IHookDefinition {
|
||||
|
||||
private final String hookName;
|
||||
private final String eventClassName;
|
||||
private final String[] paramNames;
|
||||
private final String[] requiredImports;
|
||||
private final boolean cancelable;
|
||||
|
||||
// Cached resolved class (transient - not serialized)
|
||||
private transient Class<?> cachedEventClass;
|
||||
private transient boolean classResolutionAttempted;
|
||||
|
||||
private HookDefinition(Builder builder) {
|
||||
this.hookName = builder.hookName;
|
||||
this.eventClassName = builder.eventClassName;
|
||||
this.paramNames = builder.paramNames != null ? builder.paramNames : new String[]{"event"};
|
||||
this.requiredImports = builder.requiredImports != null ? builder.requiredImports : new String[0];
|
||||
this.cancelable = builder.cancelable;
|
||||
}
|
||||
|
||||
// ==================== IHookDefinition Implementation ====================
|
||||
|
||||
@Override
|
||||
public String hookName() {
|
||||
return hookName;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String eventClassName() {
|
||||
return eventClassName;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String[] paramNames() {
|
||||
return paramNames;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String[] requiredImports() {
|
||||
return requiredImports;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isCancelable() {
|
||||
return cancelable;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Class<?> getEventClass() {
|
||||
if (classResolutionAttempted) {
|
||||
return cachedEventClass;
|
||||
}
|
||||
|
||||
classResolutionAttempted = true;
|
||||
if (eventClassName == null || eventClassName.isEmpty()) {
|
||||
return null;
|
||||
}
|
||||
|
||||
try {
|
||||
cachedEventClass = Class.forName(eventClassName);
|
||||
} catch (ClassNotFoundException e) {
|
||||
cachedEventClass = null;
|
||||
}
|
||||
|
||||
return cachedEventClass;
|
||||
}
|
||||
|
||||
// ==================== Factory Methods ====================
|
||||
|
||||
/**
|
||||
* Create a new builder for a hook definition.
|
||||
*
|
||||
* @param hookName The hook function name
|
||||
* @return A new builder instance
|
||||
*/
|
||||
public static Builder builder(String hookName) {
|
||||
return new Builder(hookName);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a simple hook definition with just a name (no metadata).
|
||||
* For backward compatibility with legacy hook registration.
|
||||
*
|
||||
* @param hookName The hook function name
|
||||
* @return A minimal hook definition
|
||||
*/
|
||||
public static HookDefinition simple(String hookName) {
|
||||
return builder(hookName).build();
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a hook definition from an interface method.
|
||||
* Automatically extracts metadata from the method signature and annotations.
|
||||
*
|
||||
* @param hookName The hook name (may differ from method name)
|
||||
* @param method The method to extract metadata from
|
||||
* @return A hook definition with extracted metadata
|
||||
*/
|
||||
public static HookDefinition fromMethod(String hookName, Method method) {
|
||||
Builder builder = builder(hookName);
|
||||
|
||||
// Extract event type from first parameter
|
||||
if (method.getParameterCount() > 0) {
|
||||
Class<?> eventType = method.getParameterTypes()[0];
|
||||
builder.eventClass(eventType);
|
||||
|
||||
// Extract @Cancelable annotation
|
||||
if (eventType.isAnnotationPresent(Cancelable.class)) {
|
||||
builder.cancelable(true);
|
||||
}
|
||||
|
||||
// Build required imports from event type
|
||||
String importName = getImportForClass(eventType);
|
||||
if (importName != null) {
|
||||
builder.requiredImports(importName);
|
||||
}
|
||||
}
|
||||
|
||||
// Extract parameter names from @ParamName annotations
|
||||
Parameter[] params = method.getParameters();
|
||||
if (params.length > 0) {
|
||||
String[] names = new String[params.length];
|
||||
for (int i = 0; i < params.length; i++) {
|
||||
ParamName annotation = params[i].getAnnotation(ParamName.class);
|
||||
if (annotation != null) {
|
||||
names[i] = annotation.value();
|
||||
} else {
|
||||
names[i] = params[i].getType().getSimpleName().toLowerCase();
|
||||
}
|
||||
}
|
||||
builder.paramNames(names);
|
||||
}
|
||||
|
||||
return builder.build();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the import statement needed for a class.
|
||||
* For nested classes, returns the enclosing class.
|
||||
*/
|
||||
private static String getImportForClass(Class<?> clazz) {
|
||||
if (clazz == null || clazz.isPrimitive()) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// For nested classes, get the top-level enclosing class
|
||||
Class<?> enclosing = clazz;
|
||||
while (enclosing.getEnclosingClass() != null) {
|
||||
enclosing = enclosing.getEnclosingClass();
|
||||
}
|
||||
|
||||
String name = enclosing.getName();
|
||||
// Skip java.lang classes
|
||||
if (name.startsWith("java.lang.")) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return name;
|
||||
}
|
||||
|
||||
// ==================== Builder ====================
|
||||
|
||||
/**
|
||||
* Builder for creating HookDefinition instances with a fluent API.
|
||||
*/
|
||||
public static class Builder {
|
||||
private final String hookName;
|
||||
private String eventClassName;
|
||||
private String[] paramNames;
|
||||
private String[] requiredImports;
|
||||
private boolean cancelable;
|
||||
|
||||
private Builder(String hookName) {
|
||||
if (hookName == null || hookName.isEmpty()) {
|
||||
throw new IllegalArgumentException("hookName cannot be null or empty");
|
||||
}
|
||||
this.hookName = hookName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the event class by name (avoids classloading issues).
|
||||
*
|
||||
* @param className Full qualified class name (use $ for nested classes)
|
||||
* @return this builder
|
||||
*/
|
||||
public Builder eventClass(String className) {
|
||||
this.eventClassName = className;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the event class directly (convenience method).
|
||||
* The class name will be extracted automatically.
|
||||
*
|
||||
* @param clazz The event class
|
||||
* @return this builder
|
||||
*/
|
||||
public Builder eventClass(Class<?> clazz) {
|
||||
if (clazz != null) {
|
||||
this.eventClassName = clazz.getName();
|
||||
// Auto-detect cancelable
|
||||
if (clazz.isAnnotationPresent(Cancelable.class)) {
|
||||
this.cancelable = true;
|
||||
}
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set parameter names for stub generation.
|
||||
*
|
||||
* @param names Parameter names
|
||||
* @return this builder
|
||||
*/
|
||||
public Builder paramNames(String... names) {
|
||||
this.paramNames = names;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set required imports for this hook's event type.
|
||||
*
|
||||
* @param imports Fully qualified class names to import
|
||||
* @return this builder
|
||||
*/
|
||||
public Builder requiredImports(String... imports) {
|
||||
this.requiredImports = imports;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set whether the event is cancelable.
|
||||
*
|
||||
* @param cancelable true if the event can be canceled
|
||||
* @return this builder
|
||||
*/
|
||||
public Builder cancelable(boolean cancelable) {
|
||||
this.cancelable = cancelable;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Build the hook definition.
|
||||
*
|
||||
* @return A new HookDefinition instance
|
||||
*/
|
||||
public HookDefinition build() {
|
||||
return new HookDefinition(this);
|
||||
}
|
||||
}
|
||||
|
||||
// ==================== Object Methods ====================
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "HookDefinition{" +
|
||||
"hookName='" + hookName + '\'' +
|
||||
", eventClassName='" + eventClassName + '\'' +
|
||||
", cancelable=" + cancelable +
|
||||
'}';
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (this == obj) return true;
|
||||
if (!(obj instanceof HookDefinition)) return false;
|
||||
HookDefinition other = (HookDefinition) obj;
|
||||
return hookName.equals(other.hookName);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return hookName.hashCode();
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,6 @@
|
||||
package noppes.npcs.controllers;
|
||||
|
||||
import noppes.npcs.api.handler.IHookDefinition;
|
||||
import noppes.npcs.api.handler.IScriptHookHandler;
|
||||
import noppes.npcs.constants.EnumScriptType;
|
||||
import noppes.npcs.constants.ScriptContext;
|
||||
@@ -14,17 +15,33 @@ import java.util.Map;
|
||||
/**
|
||||
* Controller for managing script hooks.
|
||||
* Allows addon mods to register custom hooks that appear in script editor GUIs.
|
||||
*
|
||||
* <h3>Rich Hook Registration</h3>
|
||||
* Supports full hook definitions with metadata for proper stub generation:
|
||||
* <pre>{@code
|
||||
* ScriptHookController.Instance.registerHookDefinition("player",
|
||||
* HookDefinition.builder("onDBCTransform")
|
||||
* .eventClass(IDBCEvent.TransformEvent.class)
|
||||
* .requiredImports("com.dbc.api.event.IDBCEvent")
|
||||
* .build());
|
||||
* }</pre>
|
||||
*/
|
||||
public class ScriptHookController implements IScriptHookHandler {
|
||||
|
||||
public static ScriptHookController Instance;
|
||||
|
||||
// Built-in hooks per context
|
||||
// Built-in hooks per context (legacy string list)
|
||||
private final Map<String, List<String>> builtInHooks = new HashMap<>();
|
||||
|
||||
// Addon-registered hooks per context
|
||||
// Addon-registered hooks per context (legacy string list)
|
||||
private final Map<String, List<String>> addonHooks = new HashMap<>();
|
||||
|
||||
// Rich hook definitions per context (NEW)
|
||||
private final Map<String, Map<String, HookDefinition>> hookDefinitions = new HashMap<>();
|
||||
|
||||
// Revision counter for cache invalidation (NEW)
|
||||
private int hookRevision = 0;
|
||||
|
||||
public ScriptHookController() {
|
||||
Instance = this;
|
||||
initializeBuiltInHooks();
|
||||
@@ -36,160 +53,24 @@ public class ScriptHookController implements IScriptHookHandler {
|
||||
if (!context.hookContext.isEmpty()) {
|
||||
builtInHooks.put(context.hookContext, new ArrayList<>());
|
||||
addonHooks.put(context.hookContext, new ArrayList<>());
|
||||
hookDefinitions.put(context.hookContext, new HashMap<>());
|
||||
}
|
||||
}
|
||||
|
||||
// NPC hooks
|
||||
registerBuiltIn(ScriptContext.NPC,
|
||||
EnumScriptType.INIT.function,
|
||||
EnumScriptType.TICK.function,
|
||||
EnumScriptType.INTERACT.function,
|
||||
EnumScriptType.DIALOG.function,
|
||||
EnumScriptType.DAMAGED.function,
|
||||
EnumScriptType.KILLED.function,
|
||||
EnumScriptType.ATTACK_MELEE.function,
|
||||
EnumScriptType.ATTACK_SWING.function,
|
||||
EnumScriptType.RANGED_LAUNCHED.function,
|
||||
EnumScriptType.TARGET.function,
|
||||
EnumScriptType.COLLIDE.function,
|
||||
EnumScriptType.KILLS.function,
|
||||
EnumScriptType.DIALOG_CLOSE.function,
|
||||
EnumScriptType.TIMER.function,
|
||||
EnumScriptType.TARGET_LOST.function,
|
||||
EnumScriptType.PROJECTILE_TICK.function,
|
||||
EnumScriptType.PROJECTILE_IMPACT.function,
|
||||
EnumScriptType.ABILITY_TICK.function,
|
||||
EnumScriptType.ABILITY_EXECUTE.function,
|
||||
EnumScriptType.ABILITY_HIT.function,
|
||||
EnumScriptType.ABILITY_START.function,
|
||||
EnumScriptType.ABILITY_INTERRUPT.function,
|
||||
EnumScriptType.ABILITY_COMPLETE.function
|
||||
);
|
||||
// NPC hooks with full definitions
|
||||
initializeNpcHooks();
|
||||
|
||||
// Player hooks
|
||||
registerBuiltIn(ScriptContext.PLAYER,
|
||||
EnumScriptType.INIT.function,
|
||||
EnumScriptType.TICK.function,
|
||||
EnumScriptType.INTERACT.function,
|
||||
EnumScriptType.RIGHT_CLICK.function,
|
||||
EnumScriptType.ATTACK.function,
|
||||
EnumScriptType.ATTACKED.function,
|
||||
EnumScriptType.DAMAGED_ENTITY.function,
|
||||
EnumScriptType.DAMAGED.function,
|
||||
EnumScriptType.KILLS.function,
|
||||
EnumScriptType.KILLED.function,
|
||||
EnumScriptType.DROP.function,
|
||||
EnumScriptType.RESPAWN.function,
|
||||
EnumScriptType.BREAK_BLOCK.function,
|
||||
EnumScriptType.CHAT.function,
|
||||
EnumScriptType.LOGIN.function,
|
||||
EnumScriptType.LOGOUT.function,
|
||||
EnumScriptType.KEY_PRESSED.function,
|
||||
EnumScriptType.MOUSE_CLICKED.function,
|
||||
EnumScriptType.TOSS.function,
|
||||
EnumScriptType.PICKUP.function,
|
||||
EnumScriptType.PICKUP_XP.function,
|
||||
EnumScriptType.RANGED_CHARGE.function,
|
||||
EnumScriptType.RANGED_LAUNCHED.function,
|
||||
EnumScriptType.TIMER.function,
|
||||
EnumScriptType.START_USING_ITEM.function,
|
||||
EnumScriptType.USING_ITEM.function,
|
||||
EnumScriptType.STOP_USING_ITEM.function,
|
||||
EnumScriptType.FINISH_USING_ITEM.function,
|
||||
EnumScriptType.CONTAINER_OPEN.function,
|
||||
EnumScriptType.USE_HOE.function,
|
||||
EnumScriptType.BONEMEAL.function,
|
||||
EnumScriptType.FILL_BUCKET.function,
|
||||
EnumScriptType.JUMP.function,
|
||||
EnumScriptType.FALL.function,
|
||||
EnumScriptType.WAKE_UP.function,
|
||||
EnumScriptType.SLEEP.function,
|
||||
EnumScriptType.PLAYSOUND.function,
|
||||
EnumScriptType.LIGHTNING.function,
|
||||
EnumScriptType.CHANGED_DIM.function,
|
||||
EnumScriptType.QUEST_START.function,
|
||||
EnumScriptType.QUEST_COMPLETED.function,
|
||||
EnumScriptType.QUEST_TURNIN.function,
|
||||
EnumScriptType.FACTION_POINTS.function,
|
||||
EnumScriptType.DIALOG_OPEN.function,
|
||||
EnumScriptType.DIALOG_OPTION.function,
|
||||
EnumScriptType.DIALOG_CLOSE.function,
|
||||
EnumScriptType.SCRIPT_COMMAND.function,
|
||||
EnumScriptType.CUSTOM_GUI_CLOSED.function,
|
||||
EnumScriptType.CUSTOM_GUI_BUTTON.function,
|
||||
EnumScriptType.CUSTOM_GUI_SLOT.function,
|
||||
EnumScriptType.CUSTOM_GUI_SLOT_CLICKED.function,
|
||||
EnumScriptType.CUSTOM_GUI_SCROLL.function,
|
||||
EnumScriptType.CUSTOM_GUI_TEXTFIELD.function,
|
||||
EnumScriptType.PARTY_QUEST_COMPLETED.function,
|
||||
EnumScriptType.PARTY_QUEST_SET.function,
|
||||
EnumScriptType.PARTY_QUEST_TURNED_IN.function,
|
||||
EnumScriptType.PARTY_INVITE.function,
|
||||
EnumScriptType.PARTY_KICK.function,
|
||||
EnumScriptType.PARTY_LEAVE.function,
|
||||
EnumScriptType.PARTY_DISBAND.function,
|
||||
EnumScriptType.ANIMATION_START.function,
|
||||
EnumScriptType.ANIMATION_END.function,
|
||||
EnumScriptType.ANIMATION_FRAME_ENTER.function,
|
||||
EnumScriptType.ANIMATION_FRAME_EXIT.function,
|
||||
EnumScriptType.PROFILE_CHANGE.function,
|
||||
EnumScriptType.PROFILE_REMOVE.function,
|
||||
EnumScriptType.PROFILE_CREATE.function,
|
||||
EnumScriptType.ON_EFFECT_ADD.function,
|
||||
EnumScriptType.ON_EFFECT_TICK.function,
|
||||
EnumScriptType.ON_EFFECT_REMOVE.function
|
||||
);
|
||||
// Player hooks with full definitions
|
||||
initializePlayerHooks();
|
||||
|
||||
// Block hooks
|
||||
registerBuiltIn(ScriptContext.BLOCK,
|
||||
EnumScriptType.INIT.function,
|
||||
EnumScriptType.TICK.function,
|
||||
EnumScriptType.INTERACT.function,
|
||||
EnumScriptType.FALLEN_UPON.function,
|
||||
EnumScriptType.REDSTONE.function,
|
||||
EnumScriptType.BROKEN.function,
|
||||
EnumScriptType.EXPLODED.function,
|
||||
EnumScriptType.RAIN_FILLED.function,
|
||||
EnumScriptType.NEIGHBOR_CHANGED.function,
|
||||
EnumScriptType.CLICKED.function,
|
||||
EnumScriptType.HARVESTED.function,
|
||||
EnumScriptType.COLLIDE.function,
|
||||
EnumScriptType.TIMER.function
|
||||
);
|
||||
// Block hooks with full definitions
|
||||
initializeBlockHooks();
|
||||
|
||||
// Item hooks
|
||||
registerBuiltIn(ScriptContext.ITEM,
|
||||
EnumScriptType.INIT.function,
|
||||
EnumScriptType.TICK.function,
|
||||
EnumScriptType.TOSSED.function,
|
||||
EnumScriptType.PICKEDUP.function,
|
||||
EnumScriptType.SPAWN.function,
|
||||
EnumScriptType.INTERACT.function,
|
||||
EnumScriptType.RIGHT_CLICK.function,
|
||||
EnumScriptType.ATTACK.function,
|
||||
EnumScriptType.START_USING_ITEM.function,
|
||||
EnumScriptType.USING_ITEM.function,
|
||||
EnumScriptType.STOP_USING_ITEM.function,
|
||||
EnumScriptType.FINISH_USING_ITEM.function
|
||||
);
|
||||
// Item hooks with full definitions
|
||||
initializeItemHooks();
|
||||
|
||||
// Linked item hooks
|
||||
registerBuiltIn(ScriptContext.LINKED_ITEM,
|
||||
EnumScriptType.LINKED_ITEM_BUILD.function,
|
||||
EnumScriptType.LINKED_ITEM_VERSION.function,
|
||||
EnumScriptType.INIT.function,
|
||||
EnumScriptType.TICK.function,
|
||||
EnumScriptType.TOSSED.function,
|
||||
EnumScriptType.PICKEDUP.function,
|
||||
EnumScriptType.SPAWN.function,
|
||||
EnumScriptType.INTERACT.function,
|
||||
EnumScriptType.RIGHT_CLICK.function,
|
||||
EnumScriptType.ATTACK.function,
|
||||
EnumScriptType.START_USING_ITEM.function,
|
||||
EnumScriptType.USING_ITEM.function,
|
||||
EnumScriptType.STOP_USING_ITEM.function,
|
||||
EnumScriptType.FINISH_USING_ITEM.function
|
||||
);
|
||||
// Linked item hooks with full definitions
|
||||
initializeLinkedItemHooks();
|
||||
|
||||
// Recipe hooks
|
||||
registerBuiltIn(ScriptContext.RECIPE,
|
||||
@@ -211,6 +92,372 @@ public class ScriptHookController implements IScriptHookHandler {
|
||||
);
|
||||
}
|
||||
|
||||
private void initializeNpcHooks() {
|
||||
String ctx = ScriptContext.NPC.hookContext;
|
||||
String npcImport = "noppes.npcs.api.event.INpcEvent";
|
||||
String projImport = "noppes.npcs.api.event.IProjectileEvent";
|
||||
String abilityImport = "noppes.npcs.api.event.IAbilityEvent";
|
||||
|
||||
// Core lifecycle
|
||||
registerBuiltInDefinition(ctx, EnumScriptType.INIT.function,
|
||||
"noppes.npcs.api.event.INpcEvent$InitEvent", npcImport);
|
||||
registerBuiltInDefinition(ctx, EnumScriptType.TICK.function,
|
||||
"noppes.npcs.api.event.INpcEvent$UpdateEvent", npcImport);
|
||||
registerBuiltInDefinition(ctx, EnumScriptType.TIMER.function,
|
||||
"noppes.npcs.api.event.INpcEvent$TimerEvent", npcImport);
|
||||
|
||||
// Interaction
|
||||
registerBuiltInDefinition(ctx, EnumScriptType.INTERACT.function,
|
||||
"noppes.npcs.api.event.INpcEvent$InteractEvent", npcImport);
|
||||
registerBuiltInDefinition(ctx, EnumScriptType.DIALOG.function,
|
||||
"noppes.npcs.api.event.INpcEvent$DialogEvent", npcImport);
|
||||
registerBuiltInDefinition(ctx, EnumScriptType.DIALOG_CLOSE.function,
|
||||
"noppes.npcs.api.event.INpcEvent$DialogClosedEvent", npcImport);
|
||||
registerBuiltInDefinition(ctx, EnumScriptType.COLLIDE.function,
|
||||
"noppes.npcs.api.event.INpcEvent$CollideEvent", npcImport);
|
||||
|
||||
// Combat
|
||||
registerBuiltInDefinition(ctx, EnumScriptType.DAMAGED.function,
|
||||
"noppes.npcs.api.event.INpcEvent$DamagedEvent", npcImport);
|
||||
registerBuiltInDefinition(ctx, EnumScriptType.KILLED.function,
|
||||
"noppes.npcs.api.event.INpcEvent$DiedEvent", npcImport);
|
||||
registerBuiltInDefinition(ctx, EnumScriptType.KILLS.function,
|
||||
"noppes.npcs.api.event.INpcEvent$KilledEntityEvent", npcImport);
|
||||
registerBuiltInDefinition(ctx, EnumScriptType.ATTACK_MELEE.function,
|
||||
"noppes.npcs.api.event.INpcEvent$MeleeAttackEvent", npcImport);
|
||||
registerBuiltInDefinition(ctx, EnumScriptType.ATTACK_SWING.function,
|
||||
"noppes.npcs.api.event.INpcEvent$SwingEvent", npcImport);
|
||||
registerBuiltInDefinition(ctx, EnumScriptType.RANGED_LAUNCHED.function,
|
||||
"noppes.npcs.api.event.INpcEvent$RangedLaunchedEvent", npcImport);
|
||||
registerBuiltInDefinition(ctx, EnumScriptType.TARGET.function,
|
||||
"noppes.npcs.api.event.INpcEvent$TargetEvent", npcImport);
|
||||
registerBuiltInDefinition(ctx, EnumScriptType.TARGET_LOST.function,
|
||||
"noppes.npcs.api.event.INpcEvent$TargetLostEvent", npcImport);
|
||||
|
||||
// Projectile events
|
||||
registerBuiltInDefinition(ctx, EnumScriptType.PROJECTILE_TICK.function,
|
||||
"noppes.npcs.api.event.IProjectileEvent$UpdateEvent", projImport);
|
||||
registerBuiltInDefinition(ctx, EnumScriptType.PROJECTILE_IMPACT.function,
|
||||
"noppes.npcs.api.event.IProjectileEvent$ImpactEvent", projImport);
|
||||
|
||||
// Ability events
|
||||
registerBuiltInDefinition(ctx, EnumScriptType.ABILITY_START.function,
|
||||
"noppes.npcs.api.event.IAbilityEvent$StartEvent", abilityImport);
|
||||
registerBuiltInDefinition(ctx, EnumScriptType.ABILITY_EXECUTE.function,
|
||||
"noppes.npcs.api.event.IAbilityEvent$ExecuteEvent", abilityImport);
|
||||
registerBuiltInDefinition(ctx, EnumScriptType.ABILITY_HIT.function,
|
||||
"noppes.npcs.api.event.IAbilityEvent$HitEvent", abilityImport);
|
||||
registerBuiltInDefinition(ctx, EnumScriptType.ABILITY_TICK.function,
|
||||
"noppes.npcs.api.event.IAbilityEvent$TickEvent", abilityImport);
|
||||
registerBuiltInDefinition(ctx, EnumScriptType.ABILITY_INTERRUPT.function,
|
||||
"noppes.npcs.api.event.IAbilityEvent$InterruptEvent", abilityImport);
|
||||
registerBuiltInDefinition(ctx, EnumScriptType.ABILITY_COMPLETE.function,
|
||||
"noppes.npcs.api.event.IAbilityEvent$CompleteEvent", abilityImport);
|
||||
}
|
||||
|
||||
private void initializePlayerHooks() {
|
||||
String ctx = ScriptContext.PLAYER.hookContext;
|
||||
String playerImport = "noppes.npcs.api.event.IPlayerEvent";
|
||||
String questImport = "noppes.npcs.api.event.IQuestEvent";
|
||||
String dialogImport = "noppes.npcs.api.event.IDialogEvent";
|
||||
String factionImport = "noppes.npcs.api.event.IFactionEvent";
|
||||
String partyImport = "noppes.npcs.api.event.IPartyEvent";
|
||||
String guiImport = "noppes.npcs.api.event.ICustomGuiEvent";
|
||||
String animImport = "noppes.npcs.api.event.IAnimationEvent";
|
||||
|
||||
// Core lifecycle
|
||||
registerBuiltInDefinition(ctx, EnumScriptType.INIT.function,
|
||||
"noppes.npcs.api.event.IPlayerEvent$InitEvent", playerImport);
|
||||
registerBuiltInDefinition(ctx, EnumScriptType.TICK.function,
|
||||
"noppes.npcs.api.event.IPlayerEvent$UpdateEvent", playerImport);
|
||||
registerBuiltInDefinition(ctx, EnumScriptType.TIMER.function,
|
||||
"noppes.npcs.api.event.IPlayerEvent$TimerEvent", playerImport);
|
||||
|
||||
// Combat
|
||||
registerBuiltInDefinition(ctx, EnumScriptType.ATTACK.function,
|
||||
"noppes.npcs.api.event.IPlayerEvent$AttackEvent", playerImport);
|
||||
registerBuiltInDefinition(ctx, EnumScriptType.ATTACKED.function,
|
||||
"noppes.npcs.api.event.IPlayerEvent$AttackedEvent", playerImport);
|
||||
registerBuiltInDefinition(ctx, EnumScriptType.DAMAGED.function,
|
||||
"noppes.npcs.api.event.IPlayerEvent$DamagedEvent", playerImport);
|
||||
registerBuiltInDefinition(ctx, EnumScriptType.DAMAGED_ENTITY.function,
|
||||
"noppes.npcs.api.event.IPlayerEvent$DamagedEntityEvent", playerImport);
|
||||
registerBuiltInDefinition(ctx, EnumScriptType.KILLS.function,
|
||||
"noppes.npcs.api.event.IPlayerEvent$KilledEntityEvent", playerImport);
|
||||
registerBuiltInDefinition(ctx, EnumScriptType.KILLED.function,
|
||||
"noppes.npcs.api.event.IPlayerEvent$DiedEvent", playerImport);
|
||||
|
||||
// Interaction
|
||||
registerBuiltInDefinition(ctx, EnumScriptType.INTERACT.function,
|
||||
"noppes.npcs.api.event.IPlayerEvent$InteractEvent", playerImport);
|
||||
registerBuiltInDefinition(ctx, EnumScriptType.RIGHT_CLICK.function,
|
||||
"noppes.npcs.api.event.IPlayerEvent$RightClickEvent", playerImport);
|
||||
registerBuiltInDefinition(ctx, EnumScriptType.BREAK_BLOCK.function,
|
||||
"noppes.npcs.api.event.IPlayerEvent$BreakEvent", playerImport);
|
||||
registerBuiltInDefinition(ctx, EnumScriptType.CHAT.function,
|
||||
"noppes.npcs.api.event.IPlayerEvent$ChatEvent", playerImport);
|
||||
|
||||
// Connection
|
||||
registerBuiltInDefinition(ctx, EnumScriptType.LOGIN.function,
|
||||
"noppes.npcs.api.event.IPlayerEvent$LoginEvent", playerImport);
|
||||
registerBuiltInDefinition(ctx, EnumScriptType.LOGOUT.function,
|
||||
"noppes.npcs.api.event.IPlayerEvent$LogoutEvent", playerImport);
|
||||
registerBuiltInDefinition(ctx, EnumScriptType.RESPAWN.function,
|
||||
"noppes.npcs.api.event.IPlayerEvent$RespawnEvent", playerImport);
|
||||
|
||||
// Input
|
||||
registerBuiltInDefinition(ctx, EnumScriptType.KEY_PRESSED.function,
|
||||
"noppes.npcs.api.event.IPlayerEvent$KeyPressedEvent", playerImport);
|
||||
registerBuiltInDefinition(ctx, EnumScriptType.MOUSE_CLICKED.function,
|
||||
"noppes.npcs.api.event.IPlayerEvent$MouseClickedEvent", playerImport);
|
||||
|
||||
// Items
|
||||
registerBuiltInDefinition(ctx, EnumScriptType.PICKUP.function,
|
||||
"noppes.npcs.api.event.IPlayerEvent$PickUpEvent", playerImport);
|
||||
registerBuiltInDefinition(ctx, EnumScriptType.TOSS.function,
|
||||
"noppes.npcs.api.event.IPlayerEvent$TossEvent", playerImport);
|
||||
registerBuiltInDefinition(ctx, EnumScriptType.DROP.function,
|
||||
"noppes.npcs.api.event.IPlayerEvent$DropEvent", playerImport);
|
||||
registerBuiltInDefinition(ctx, EnumScriptType.PICKUP_XP.function,
|
||||
"noppes.npcs.api.event.IPlayerEvent$PickupXPEvent", playerImport);
|
||||
registerBuiltInDefinition(ctx, EnumScriptType.START_USING_ITEM.function,
|
||||
"noppes.npcs.api.event.IPlayerEvent$StartUsingItem", playerImport);
|
||||
registerBuiltInDefinition(ctx, EnumScriptType.USING_ITEM.function,
|
||||
"noppes.npcs.api.event.IPlayerEvent$UsingItem", playerImport);
|
||||
registerBuiltInDefinition(ctx, EnumScriptType.STOP_USING_ITEM.function,
|
||||
"noppes.npcs.api.event.IPlayerEvent$StopUsingItem", playerImport);
|
||||
registerBuiltInDefinition(ctx, EnumScriptType.FINISH_USING_ITEM.function,
|
||||
"noppes.npcs.api.event.IPlayerEvent$FinishUsingItem", playerImport);
|
||||
registerBuiltInDefinition(ctx, EnumScriptType.CONTAINER_OPEN.function,
|
||||
"noppes.npcs.api.event.IPlayerEvent$ContainerOpen", playerImport);
|
||||
|
||||
// Movement
|
||||
registerBuiltInDefinition(ctx, EnumScriptType.JUMP.function,
|
||||
"noppes.npcs.api.event.IPlayerEvent$JumpEvent", playerImport);
|
||||
registerBuiltInDefinition(ctx, EnumScriptType.FALL.function,
|
||||
"noppes.npcs.api.event.IPlayerEvent$FallEvent", playerImport);
|
||||
registerBuiltInDefinition(ctx, EnumScriptType.CHANGED_DIM.function,
|
||||
"noppes.npcs.api.event.IPlayerEvent$ChangedDimension", playerImport);
|
||||
|
||||
// World
|
||||
registerBuiltInDefinition(ctx, EnumScriptType.RANGED_CHARGE.function,
|
||||
"noppes.npcs.api.event.IPlayerEvent$RangedChargeEvent", playerImport);
|
||||
registerBuiltInDefinition(ctx, EnumScriptType.RANGED_LAUNCHED.function,
|
||||
"noppes.npcs.api.event.IPlayerEvent$RangedLaunchedEvent", playerImport);
|
||||
registerBuiltInDefinition(ctx, EnumScriptType.USE_HOE.function,
|
||||
"noppes.npcs.api.event.IPlayerEvent$UseHoeEvent", playerImport);
|
||||
registerBuiltInDefinition(ctx, EnumScriptType.BONEMEAL.function,
|
||||
"noppes.npcs.api.event.IPlayerEvent$BonemealEvent", playerImport);
|
||||
registerBuiltInDefinition(ctx, EnumScriptType.FILL_BUCKET.function,
|
||||
"noppes.npcs.api.event.IPlayerEvent$FillBucketEvent", playerImport);
|
||||
registerBuiltInDefinition(ctx, EnumScriptType.WAKE_UP.function,
|
||||
"noppes.npcs.api.event.IPlayerEvent$WakeUpEvent", playerImport);
|
||||
registerBuiltInDefinition(ctx, EnumScriptType.SLEEP.function,
|
||||
"noppes.npcs.api.event.IPlayerEvent$SleepEvent", playerImport);
|
||||
registerBuiltInDefinition(ctx, EnumScriptType.PLAYSOUND.function,
|
||||
"noppes.npcs.api.event.IPlayerEvent$SoundEvent", playerImport);
|
||||
registerBuiltInDefinition(ctx, EnumScriptType.LIGHTNING.function,
|
||||
"noppes.npcs.api.event.IPlayerEvent$LightningEvent", playerImport);
|
||||
registerBuiltInDefinition(ctx, EnumScriptType.SCRIPT_COMMAND.function,
|
||||
"noppes.npcs.api.event.ICustomNPCsEvent$ScriptedCommandEvent", "noppes.npcs.api.event.ICustomNPCsEvent");
|
||||
|
||||
// Quest events
|
||||
registerBuiltInDefinition(ctx, EnumScriptType.QUEST_START.function,
|
||||
"noppes.npcs.api.event.IQuestEvent$QuestStartEvent", questImport);
|
||||
registerBuiltInDefinition(ctx, EnumScriptType.QUEST_COMPLETED.function,
|
||||
"noppes.npcs.api.event.IQuestEvent$QuestCompletedEvent", questImport);
|
||||
registerBuiltInDefinition(ctx, EnumScriptType.QUEST_TURNIN.function,
|
||||
"noppes.npcs.api.event.IQuestEvent$QuestTurnedInEvent", questImport);
|
||||
|
||||
// Dialog events
|
||||
registerBuiltInDefinition(ctx, EnumScriptType.DIALOG_OPEN.function,
|
||||
"noppes.npcs.api.event.IDialogEvent$DialogOpen", dialogImport);
|
||||
registerBuiltInDefinition(ctx, EnumScriptType.DIALOG_OPTION.function,
|
||||
"noppes.npcs.api.event.IDialogEvent$DialogOption", dialogImport);
|
||||
registerBuiltInDefinition(ctx, EnumScriptType.DIALOG_CLOSE.function,
|
||||
"noppes.npcs.api.event.IDialogEvent$DialogClosed", dialogImport);
|
||||
|
||||
// Faction events
|
||||
registerBuiltInDefinition(ctx, EnumScriptType.FACTION_POINTS.function,
|
||||
"noppes.npcs.api.event.IFactionEvent$FactionPoints", factionImport);
|
||||
|
||||
// Custom GUI events
|
||||
registerBuiltInDefinition(ctx, EnumScriptType.CUSTOM_GUI_CLOSED.function,
|
||||
"noppes.npcs.api.event.ICustomGuiEvent$CloseEvent", guiImport);
|
||||
registerBuiltInDefinition(ctx, EnumScriptType.CUSTOM_GUI_BUTTON.function,
|
||||
"noppes.npcs.api.event.ICustomGuiEvent$ButtonEvent", guiImport);
|
||||
registerBuiltInDefinition(ctx, EnumScriptType.CUSTOM_GUI_SLOT.function,
|
||||
"noppes.npcs.api.event.ICustomGuiEvent$SlotEvent", guiImport);
|
||||
registerBuiltInDefinition(ctx, EnumScriptType.CUSTOM_GUI_SLOT_CLICKED.function,
|
||||
"noppes.npcs.api.event.ICustomGuiEvent$SlotClickEvent", guiImport);
|
||||
registerBuiltInDefinition(ctx, EnumScriptType.CUSTOM_GUI_SCROLL.function,
|
||||
"noppes.npcs.api.event.ICustomGuiEvent$ScrollEvent", guiImport);
|
||||
registerBuiltInDefinition(ctx, EnumScriptType.CUSTOM_GUI_TEXTFIELD.function,
|
||||
"noppes.npcs.api.event.ICustomGuiEvent$UnfocusedEvent", guiImport);
|
||||
|
||||
// Party events
|
||||
registerBuiltInDefinition(ctx, EnumScriptType.PARTY_QUEST_COMPLETED.function,
|
||||
"noppes.npcs.api.event.IPartyEvent$PartyQuestCompletedEvent", partyImport);
|
||||
registerBuiltInDefinition(ctx, EnumScriptType.PARTY_QUEST_SET.function,
|
||||
"noppes.npcs.api.event.IPartyEvent$PartyQuestSetEvent", partyImport);
|
||||
registerBuiltInDefinition(ctx, EnumScriptType.PARTY_QUEST_TURNED_IN.function,
|
||||
"noppes.npcs.api.event.IPartyEvent$PartyQuestTurnedInEvent", partyImport);
|
||||
registerBuiltInDefinition(ctx, EnumScriptType.PARTY_INVITE.function,
|
||||
"noppes.npcs.api.event.IPartyEvent$PartyInviteEvent", partyImport);
|
||||
registerBuiltInDefinition(ctx, EnumScriptType.PARTY_KICK.function,
|
||||
"noppes.npcs.api.event.IPartyEvent$PartyKickEvent", partyImport);
|
||||
registerBuiltInDefinition(ctx, EnumScriptType.PARTY_LEAVE.function,
|
||||
"noppes.npcs.api.event.IPartyEvent$PartyLeaveEvent", partyImport);
|
||||
registerBuiltInDefinition(ctx, EnumScriptType.PARTY_DISBAND.function,
|
||||
"noppes.npcs.api.event.IPartyEvent$PartyDisbandEvent", partyImport);
|
||||
|
||||
// Animation events
|
||||
registerBuiltInDefinition(ctx, EnumScriptType.ANIMATION_START.function,
|
||||
"noppes.npcs.api.event.IAnimationEvent$Started", animImport);
|
||||
registerBuiltInDefinition(ctx, EnumScriptType.ANIMATION_END.function,
|
||||
"noppes.npcs.api.event.IAnimationEvent$Ended", animImport);
|
||||
registerBuiltInDefinition(ctx, EnumScriptType.ANIMATION_FRAME_ENTER.function,
|
||||
"noppes.npcs.api.event.IAnimationEvent$IFrameEvent$Entered", animImport);
|
||||
registerBuiltInDefinition(ctx, EnumScriptType.ANIMATION_FRAME_EXIT.function,
|
||||
"noppes.npcs.api.event.IAnimationEvent$IFrameEvent$Exited", animImport);
|
||||
|
||||
// Profile events
|
||||
registerBuiltInDefinition(ctx, EnumScriptType.PROFILE_CHANGE.function,
|
||||
"noppes.npcs.api.event.IPlayerEvent$ProfileEvent$Changed", playerImport);
|
||||
registerBuiltInDefinition(ctx, EnumScriptType.PROFILE_REMOVE.function,
|
||||
"noppes.npcs.api.event.IPlayerEvent$ProfileEvent$Removed", playerImport);
|
||||
registerBuiltInDefinition(ctx, EnumScriptType.PROFILE_CREATE.function,
|
||||
"noppes.npcs.api.event.IPlayerEvent$ProfileEvent$Create", playerImport);
|
||||
|
||||
// Effect events (for player context)
|
||||
registerBuiltInDefinition(ctx, EnumScriptType.ON_EFFECT_ADD.function,
|
||||
"noppes.npcs.api.event.IPlayerEvent$EffectEvent$Added", playerImport);
|
||||
registerBuiltInDefinition(ctx, EnumScriptType.ON_EFFECT_TICK.function,
|
||||
"noppes.npcs.api.event.IPlayerEvent$EffectEvent$Ticked", playerImport);
|
||||
registerBuiltInDefinition(ctx, EnumScriptType.ON_EFFECT_REMOVE.function,
|
||||
"noppes.npcs.api.event.IPlayerEvent$EffectEvent$Removed", playerImport);
|
||||
}
|
||||
|
||||
private void initializeBlockHooks() {
|
||||
String ctx = ScriptContext.BLOCK.hookContext;
|
||||
String blockImport = "noppes.npcs.api.event.IBlockEvent";
|
||||
|
||||
registerBuiltInDefinition(ctx, EnumScriptType.INIT.function,
|
||||
"noppes.npcs.api.event.IBlockEvent$InitEvent", blockImport);
|
||||
registerBuiltInDefinition(ctx, EnumScriptType.TICK.function,
|
||||
"noppes.npcs.api.event.IBlockEvent$UpdateEvent", blockImport);
|
||||
registerBuiltInDefinition(ctx, EnumScriptType.INTERACT.function,
|
||||
"noppes.npcs.api.event.IBlockEvent$InteractEvent", blockImport);
|
||||
registerBuiltInDefinition(ctx, EnumScriptType.FALLEN_UPON.function,
|
||||
"noppes.npcs.api.event.IBlockEvent$EntityFallenUponEvent", blockImport);
|
||||
registerBuiltInDefinition(ctx, EnumScriptType.REDSTONE.function,
|
||||
"noppes.npcs.api.event.IBlockEvent$RedstoneEvent", blockImport);
|
||||
registerBuiltInDefinition(ctx, EnumScriptType.BROKEN.function,
|
||||
"noppes.npcs.api.event.IBlockEvent$BreakEvent", blockImport);
|
||||
registerBuiltInDefinition(ctx, EnumScriptType.EXPLODED.function,
|
||||
"noppes.npcs.api.event.IBlockEvent$ExplodedEvent", blockImport);
|
||||
registerBuiltInDefinition(ctx, EnumScriptType.RAIN_FILLED.function,
|
||||
"noppes.npcs.api.event.IBlockEvent$RainFillEvent", blockImport);
|
||||
registerBuiltInDefinition(ctx, EnumScriptType.NEIGHBOR_CHANGED.function,
|
||||
"noppes.npcs.api.event.IBlockEvent$NeighborChangedEvent", blockImport);
|
||||
registerBuiltInDefinition(ctx, EnumScriptType.CLICKED.function,
|
||||
"noppes.npcs.api.event.IBlockEvent$ClickedEvent", blockImport);
|
||||
registerBuiltInDefinition(ctx, EnumScriptType.HARVESTED.function,
|
||||
"noppes.npcs.api.event.IBlockEvent$HarvestedEvent", blockImport);
|
||||
registerBuiltInDefinition(ctx, EnumScriptType.COLLIDE.function,
|
||||
"noppes.npcs.api.event.IBlockEvent$CollidedEvent", blockImport);
|
||||
registerBuiltInDefinition(ctx, EnumScriptType.TIMER.function,
|
||||
"noppes.npcs.api.event.IBlockEvent$TimerEvent", blockImport);
|
||||
}
|
||||
|
||||
private void initializeItemHooks() {
|
||||
String ctx = ScriptContext.ITEM.hookContext;
|
||||
String itemImport = "noppes.npcs.api.event.IItemEvent";
|
||||
|
||||
registerBuiltInDefinition(ctx, EnumScriptType.INIT.function,
|
||||
"noppes.npcs.api.event.IItemEvent$InitEvent", itemImport);
|
||||
registerBuiltInDefinition(ctx, EnumScriptType.TICK.function,
|
||||
"noppes.npcs.api.event.IItemEvent$UpdateEvent", itemImport);
|
||||
registerBuiltInDefinition(ctx, EnumScriptType.TOSSED.function,
|
||||
"noppes.npcs.api.event.IItemEvent$TossedEvent", itemImport);
|
||||
registerBuiltInDefinition(ctx, EnumScriptType.PICKEDUP.function,
|
||||
"noppes.npcs.api.event.IItemEvent$PickedUpEvent", itemImport);
|
||||
registerBuiltInDefinition(ctx, EnumScriptType.SPAWN.function,
|
||||
"noppes.npcs.api.event.IItemEvent$SpawnEvent", itemImport);
|
||||
registerBuiltInDefinition(ctx, EnumScriptType.INTERACT.function,
|
||||
"noppes.npcs.api.event.IItemEvent$InteractEvent", itemImport);
|
||||
registerBuiltInDefinition(ctx, EnumScriptType.RIGHT_CLICK.function,
|
||||
"noppes.npcs.api.event.IItemEvent$RightClickEvent", itemImport);
|
||||
registerBuiltInDefinition(ctx, EnumScriptType.ATTACK.function,
|
||||
"noppes.npcs.api.event.IItemEvent$AttackEvent", itemImport);
|
||||
registerBuiltInDefinition(ctx, EnumScriptType.START_USING_ITEM.function,
|
||||
"noppes.npcs.api.event.IItemEvent$StartUsingItem", itemImport);
|
||||
registerBuiltInDefinition(ctx, EnumScriptType.USING_ITEM.function,
|
||||
"noppes.npcs.api.event.IItemEvent$UsingItem", itemImport);
|
||||
registerBuiltInDefinition(ctx, EnumScriptType.STOP_USING_ITEM.function,
|
||||
"noppes.npcs.api.event.IItemEvent$StopUsingItem", itemImport);
|
||||
registerBuiltInDefinition(ctx, EnumScriptType.FINISH_USING_ITEM.function,
|
||||
"noppes.npcs.api.event.IItemEvent$FinishUsingItem", itemImport);
|
||||
}
|
||||
|
||||
private void initializeLinkedItemHooks() {
|
||||
String ctx = ScriptContext.LINKED_ITEM.hookContext;
|
||||
String itemImport = "noppes.npcs.api.event.IItemEvent";
|
||||
String linkedImport = "noppes.npcs.api.event.ILinkedItemEvent";
|
||||
|
||||
// Linked item specific hooks
|
||||
registerBuiltInDefinition(ctx, EnumScriptType.LINKED_ITEM_BUILD.function,
|
||||
"noppes.npcs.api.event.ILinkedItemEvent$BuildEvent", linkedImport);
|
||||
registerBuiltInDefinition(ctx, EnumScriptType.LINKED_ITEM_VERSION.function,
|
||||
"noppes.npcs.api.event.ILinkedItemEvent$VersionChangeEvent", linkedImport);
|
||||
|
||||
// Standard item hooks
|
||||
registerBuiltInDefinition(ctx, EnumScriptType.INIT.function,
|
||||
"noppes.npcs.api.event.IItemEvent$InitEvent", itemImport);
|
||||
registerBuiltInDefinition(ctx, EnumScriptType.TICK.function,
|
||||
"noppes.npcs.api.event.IItemEvent$UpdateEvent", itemImport);
|
||||
registerBuiltInDefinition(ctx, EnumScriptType.TOSSED.function,
|
||||
"noppes.npcs.api.event.IItemEvent$TossedEvent", itemImport);
|
||||
registerBuiltInDefinition(ctx, EnumScriptType.PICKEDUP.function,
|
||||
"noppes.npcs.api.event.IItemEvent$PickedUpEvent", itemImport);
|
||||
registerBuiltInDefinition(ctx, EnumScriptType.SPAWN.function,
|
||||
"noppes.npcs.api.event.IItemEvent$SpawnEvent", itemImport);
|
||||
registerBuiltInDefinition(ctx, EnumScriptType.INTERACT.function,
|
||||
"noppes.npcs.api.event.IItemEvent$InteractEvent", itemImport);
|
||||
registerBuiltInDefinition(ctx, EnumScriptType.RIGHT_CLICK.function,
|
||||
"noppes.npcs.api.event.IItemEvent$RightClickEvent", itemImport);
|
||||
registerBuiltInDefinition(ctx, EnumScriptType.ATTACK.function,
|
||||
"noppes.npcs.api.event.IItemEvent$AttackEvent", itemImport);
|
||||
registerBuiltInDefinition(ctx, EnumScriptType.START_USING_ITEM.function,
|
||||
"noppes.npcs.api.event.IItemEvent$StartUsingItem", itemImport);
|
||||
registerBuiltInDefinition(ctx, EnumScriptType.USING_ITEM.function,
|
||||
"noppes.npcs.api.event.IItemEvent$UsingItem", itemImport);
|
||||
registerBuiltInDefinition(ctx, EnumScriptType.STOP_USING_ITEM.function,
|
||||
"noppes.npcs.api.event.IItemEvent$StopUsingItem", itemImport);
|
||||
registerBuiltInDefinition(ctx, EnumScriptType.FINISH_USING_ITEM.function,
|
||||
"noppes.npcs.api.event.IItemEvent$FinishUsingItem", itemImport);
|
||||
}
|
||||
|
||||
/**
|
||||
* Register a built-in hook with full definition metadata.
|
||||
*/
|
||||
private void registerBuiltInDefinition(String context, String hookName, String eventClassName, String... imports) {
|
||||
HookDefinition def = HookDefinition.builder(hookName)
|
||||
.eventClass(eventClassName)
|
||||
.requiredImports(imports)
|
||||
.build();
|
||||
|
||||
Map<String, HookDefinition> contextDefs = hookDefinitions.get(context);
|
||||
if (contextDefs == null) {
|
||||
contextDefs = new HashMap<>();
|
||||
hookDefinitions.put(context, contextDefs);
|
||||
}
|
||||
contextDefs.put(hookName, def);
|
||||
|
||||
// Also register in legacy string list
|
||||
registerBuiltIn(context, hookName);
|
||||
}
|
||||
|
||||
/**
|
||||
* Register built-in hooks for a ScriptContext.
|
||||
*/
|
||||
@@ -229,6 +476,72 @@ public class ScriptHookController implements IScriptHookHandler {
|
||||
}
|
||||
}
|
||||
|
||||
// ==================== RICH HOOK REGISTRATION (NEW API) ====================
|
||||
|
||||
@Override
|
||||
public void registerHookDefinition(String context, IHookDefinition definition) {
|
||||
if (context == null || definition == null || definition.hookName() == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
Map<String, HookDefinition> contextDefs = hookDefinitions.get(context);
|
||||
if (contextDefs == null) {
|
||||
contextDefs = new HashMap<>();
|
||||
hookDefinitions.put(context, contextDefs);
|
||||
}
|
||||
|
||||
// Store as HookDefinition (implementation)
|
||||
if (definition instanceof HookDefinition) {
|
||||
contextDefs.put(definition.hookName(), (HookDefinition) definition);
|
||||
} else {
|
||||
// Convert foreign IHookDefinition to HookDefinition
|
||||
HookDefinition def = HookDefinition.builder(definition.hookName())
|
||||
.eventClass(definition.eventClassName())
|
||||
.paramNames(definition.paramNames())
|
||||
.requiredImports(definition.requiredImports())
|
||||
.cancelable(definition.isCancelable())
|
||||
.build();
|
||||
contextDefs.put(definition.hookName(), def);
|
||||
}
|
||||
|
||||
// Also add to legacy addon hooks list for backward compatibility
|
||||
registerHook(context, definition.hookName());
|
||||
|
||||
// Increment revision for cache invalidation
|
||||
hookRevision++;
|
||||
}
|
||||
|
||||
@Override
|
||||
public IHookDefinition getHookDefinition(String context, String hookName) {
|
||||
if (context == null || hookName == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
Map<String, HookDefinition> contextDefs = hookDefinitions.get(context);
|
||||
return contextDefs != null ? contextDefs.get(hookName) : null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<IHookDefinition> getAllHookDefinitions(String context) {
|
||||
if (context == null) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
Map<String, HookDefinition> contextDefs = hookDefinitions.get(context);
|
||||
if (contextDefs == null || contextDefs.isEmpty()) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
return new ArrayList<>(contextDefs.values());
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getHookRevision() {
|
||||
return hookRevision;
|
||||
}
|
||||
|
||||
// ==================== CONVENIENCE METHODS ====================
|
||||
|
||||
/**
|
||||
* Convenience method to register a hook using ScriptContext.
|
||||
* @param context The script context
|
||||
@@ -248,7 +561,18 @@ public class ScriptHookController implements IScriptHookHandler {
|
||||
registerHook(context.hookContext, fn);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Convenience method to register a hook definition using ScriptContext.
|
||||
* @param context The script context
|
||||
* @param definition The hook definition
|
||||
*/
|
||||
public void registerHookDefinition(ScriptContext context, IHookDefinition definition) {
|
||||
registerHookDefinition(context.hookContext, definition);
|
||||
}
|
||||
|
||||
// ==================== LEGACY HOOK REGISTRATION ====================
|
||||
|
||||
@Override
|
||||
public void registerHook(String context, String functionName) {
|
||||
if (context == null || functionName == null || functionName.isEmpty()) {
|
||||
|
||||
@@ -6,9 +6,11 @@ import io.github.somehussar.janinoloader.api.script.IScriptClassBody;
|
||||
import net.minecraft.nbt.NBTTagCompound;
|
||||
import noppes.npcs.CustomNpcs;
|
||||
import noppes.npcs.NBTTags;
|
||||
import noppes.npcs.api.handler.IHookDefinition;
|
||||
import noppes.npcs.config.ConfigScript;
|
||||
import noppes.npcs.constants.EnumScriptType;
|
||||
import noppes.npcs.controllers.ScriptController;
|
||||
import noppes.npcs.controllers.ScriptHookController;
|
||||
import noppes.npcs.controllers.data.IScriptUnit;
|
||||
import noppes.npcs.janino.annotations.ParamName;
|
||||
import org.codehaus.commons.compiler.InternalCompilerException;
|
||||
@@ -52,6 +54,10 @@ public abstract class JaninoScript<T> implements IScriptUnit {
|
||||
|
||||
private final String[] defaultImports;
|
||||
|
||||
// Hook definition cache for fast lookup (NEW)
|
||||
private Map<String, IHookDefinition> hookDefinitionCache;
|
||||
private int lastHookRevision = -1;
|
||||
|
||||
protected JaninoScript(Class<T> type, String[] defaultImports, boolean isClient) {
|
||||
this.type = type;
|
||||
this.defaultImports = defaultImports != null ? defaultImports : new String[0];
|
||||
@@ -71,6 +77,79 @@ public abstract class JaninoScript<T> implements IScriptUnit {
|
||||
this(type, defaultImports, false);
|
||||
}
|
||||
|
||||
// ==================== HOOK CONTEXT (Abstract) ====================
|
||||
|
||||
/**
|
||||
* Get the hook context identifier for this script type.
|
||||
* Used to look up hook definitions from the registry.
|
||||
*
|
||||
* @return Context string, e.g., "npc", "player", "block"
|
||||
*/
|
||||
protected abstract String getHookContext();
|
||||
|
||||
// ==================== HOOK DEFINITION CACHE ====================
|
||||
|
||||
/**
|
||||
* Get hook definition from cache, rebuilding cache if revision changed.
|
||||
*
|
||||
* @param hookName The hook name to look up
|
||||
* @return The hook definition, or null if not found
|
||||
*/
|
||||
protected IHookDefinition getHookDefinition(String hookName) {
|
||||
if (ScriptHookController.Instance == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
int currentRevision = ScriptHookController.Instance.getHookRevision();
|
||||
if (hookDefinitionCache == null || currentRevision != lastHookRevision) {
|
||||
rebuildHookDefinitionCache();
|
||||
lastHookRevision = currentRevision;
|
||||
}
|
||||
|
||||
return hookDefinitionCache.get(hookName);
|
||||
}
|
||||
|
||||
/**
|
||||
* Rebuild the hook definition cache from the registry.
|
||||
*/
|
||||
private void rebuildHookDefinitionCache() {
|
||||
hookDefinitionCache = new HashMap<>();
|
||||
String context = getHookContext();
|
||||
|
||||
if (context == null || context.isEmpty() || ScriptHookController.Instance == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (IHookDefinition def : ScriptHookController.Instance.getAllHookDefinitions(context)) {
|
||||
hookDefinitionCache.put(def.hookName(), def);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all required imports from hook definitions plus default imports.
|
||||
*
|
||||
* @return Array of all import statements needed
|
||||
*/
|
||||
protected String[] collectAllImports() {
|
||||
Set<String> allImports = new LinkedHashSet<>();
|
||||
|
||||
// Add default imports first
|
||||
Collections.addAll(allImports, defaultImports);
|
||||
|
||||
// Add imports from all hook definitions for this context
|
||||
String context = getHookContext();
|
||||
if (context != null && !context.isEmpty() && ScriptHookController.Instance != null) {
|
||||
for (IHookDefinition def : ScriptHookController.Instance.getAllHookDefinitions(context)) {
|
||||
String[] imports = def.requiredImports();
|
||||
if (imports != null) {
|
||||
Collections.addAll(allImports, imports);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return allImports.toArray(new String[0]);
|
||||
}
|
||||
|
||||
protected T getUnsafe() {
|
||||
return scriptBody.get();
|
||||
}
|
||||
@@ -119,11 +198,16 @@ public abstract class JaninoScript<T> implements IScriptUnit {
|
||||
}
|
||||
|
||||
/**
|
||||
* Feed the code into the engine and compile it
|
||||
* Feed the code into the engine and compile it.
|
||||
* Rebuilds imports from hook definitions before compilation.
|
||||
*/
|
||||
public void compileScript(String code) {
|
||||
|
||||
try {
|
||||
// Rebuild imports from current hook definitions + defaults
|
||||
String[] allImports = collectAllImports();
|
||||
builder.setDefaultImports(allImports);
|
||||
|
||||
scriptBody.setScript(code);
|
||||
} catch (InternalCompilerException e ) {
|
||||
Throwable parentCause = null;
|
||||
@@ -330,65 +414,43 @@ public abstract class JaninoScript<T> implements IScriptUnit {
|
||||
return script != null && !script.isEmpty();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String generateHookStub(String hookName, Object hookData) {
|
||||
hookResolver.clearResolutionCaches();
|
||||
@Override
|
||||
public String generateHookStub(String hookName, Object hookData) {
|
||||
hookResolver.clearResolutionCaches();
|
||||
|
||||
Method method = hookResolver.getMethodForDisplayName(hookName);
|
||||
if (method != null)
|
||||
return generateMethodStub(method);
|
||||
// 1. Try interface method (existing @ScriptHook annotated methods)
|
||||
Method method = hookResolver.getMethodForDisplayName(hookName);
|
||||
if (method != null)
|
||||
return generateMethodStub(method);
|
||||
|
||||
// Fallback: try to find the event class by naming convention
|
||||
String eventType = findEventTypeForHook(hookName);
|
||||
if (eventType != null) {
|
||||
return String.format("public void %s(%s event) {\n \n}\n", hookName, eventType);
|
||||
// 2. Look up in hook definition registry (addon hooks, dynamic hooks)
|
||||
IHookDefinition def = getHookDefinition(hookName);
|
||||
if (def != null) {
|
||||
return generateStubFromDefinition(def);
|
||||
}
|
||||
|
||||
// Last resort: generic Object parameter
|
||||
// 3. Last resort: generic Object parameter
|
||||
return String.format("public void %s(Object event) {\n \n}\n", hookName);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tries to find the event type for a hook by searching API event interfaces.
|
||||
* Uses naming convention: hookName "questStart" -> event class "QuestStartEvent"
|
||||
* Generate a method stub from a hook definition.
|
||||
*
|
||||
* @param hookName The hook name (e.g., "questStart", "dialogOpen")
|
||||
* @return The usable type name (e.g., "IQuestEvent.QuestStartEvent") or null if not found
|
||||
* @param def The hook definition containing type info
|
||||
* @return Generated stub code
|
||||
*/
|
||||
private String findEventTypeForHook(String hookName) {
|
||||
if (hookName == null || hookName.isEmpty())
|
||||
return null;
|
||||
private String generateStubFromDefinition(IHookDefinition def) {
|
||||
String typeName = def.getUsableTypeName();
|
||||
String[] params = def.paramNames();
|
||||
String paramName = (params != null && params.length > 0) ? params[0] : "event";
|
||||
|
||||
// Convert hook name to expected event class name
|
||||
// questStart -> QuestStartEvent
|
||||
String expectedEventName = Character.toUpperCase(hookName.charAt(0)) + hookName.substring(1) + "Event";
|
||||
|
||||
// Search in known API event interfaces
|
||||
Class<?>[] eventInterfaces = {
|
||||
noppes.npcs.api.event.IPlayerEvent.class,
|
||||
noppes.npcs.api.event.INpcEvent.class,
|
||||
noppes.npcs.api.event.IQuestEvent.class,
|
||||
noppes.npcs.api.event.IDialogEvent.class,
|
||||
noppes.npcs.api.event.IFactionEvent.class,
|
||||
noppes.npcs.api.event.IPartyEvent.class,
|
||||
noppes.npcs.api.event.ICustomGuiEvent.class,
|
||||
noppes.npcs.api.event.IAnimationEvent.class,
|
||||
noppes.npcs.api.event.IBlockEvent.class,
|
||||
noppes.npcs.api.event.IItemEvent.class,
|
||||
noppes.npcs.api.event.IProjectileEvent.class,
|
||||
noppes.npcs.api.event.IAbilityEvent.class,
|
||||
noppes.npcs.api.event.IForgeEvent.class
|
||||
};
|
||||
|
||||
for (Class<?> eventInterface : eventInterfaces) {
|
||||
for (Class<?> nested : eventInterface.getDeclaredClasses()) {
|
||||
if (nested.getSimpleName().equals(expectedEventName)) {
|
||||
return getUsableTypeName(nested);
|
||||
}
|
||||
}
|
||||
if (typeName == null || typeName.isEmpty()) {
|
||||
return String.format("public void %s(Object %s) {\n \n}\n",
|
||||
def.hookName(), paramName);
|
||||
}
|
||||
|
||||
return null;
|
||||
return String.format("public void %s(%s %s) {\n \n}\n",
|
||||
def.hookName(), typeName, paramName);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -17,6 +17,7 @@ public class JaninoNpcScript extends JaninoScript<JaninoNpcScript.Functions> {
|
||||
/**
|
||||
* Default imports for NPC scripts.
|
||||
* These are automatically available in user code without explicit import statements.
|
||||
* Additional imports from registered hook definitions are added at compile time.
|
||||
*/
|
||||
private static final String[] DEFAULT_IMPORTS = {
|
||||
"noppes.npcs.api.event.INpcEvent",
|
||||
@@ -31,6 +32,11 @@ public class JaninoNpcScript extends JaninoScript<JaninoNpcScript.Functions> {
|
||||
super(Functions.class, DEFAULT_IMPORTS);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getHookContext() {
|
||||
return "npc";
|
||||
}
|
||||
|
||||
/**
|
||||
* Interface defining the hook methods available for NPC scripts.
|
||||
* Each method corresponds to an NPC event from ScriptHookController CONTEXT_NPC.
|
||||
|
||||
@@ -43,6 +43,7 @@ public class JaninoPlayerScript extends JaninoScript<JaninoPlayerScript.Function
|
||||
/**
|
||||
* Default imports for player scripts.
|
||||
* These are automatically available in user code without explicit import statements.
|
||||
* Additional imports from registered hook definitions are added at compile time.
|
||||
*/
|
||||
private static final String[] DEFAULT_IMPORTS = {
|
||||
"noppes.npcs.api.event.IPlayerEvent",
|
||||
@@ -61,6 +62,11 @@ public class JaninoPlayerScript extends JaninoScript<JaninoPlayerScript.Function
|
||||
super(Functions.class, DEFAULT_IMPORTS, false);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getHookContext() {
|
||||
return "player";
|
||||
}
|
||||
|
||||
/**
|
||||
* Core hook methods for player scripts.
|
||||
*
|
||||
|
||||
Reference in new issue
Block a user