diff --git a/src/main/java/noppes/npcs/controllers/data/DataScript.java b/src/main/java/noppes/npcs/controllers/data/DataScript.java index 014959919..6e07223a8 100644 --- a/src/main/java/noppes/npcs/controllers/data/DataScript.java +++ b/src/main/java/noppes/npcs/controllers/data/DataScript.java @@ -19,6 +19,7 @@ import noppes.npcs.constants.EnumScriptType; import noppes.npcs.controllers.ScriptContainer; import noppes.npcs.controllers.ScriptController; import noppes.npcs.entity.EntityNPCInterface; +import noppes.npcs.janino.impl.JaninoNpcScript; import noppes.npcs.scripted.NpcAPI; import noppes.npcs.scripted.ScriptWorld; import noppes.npcs.scripted.constants.EntityType; @@ -312,4 +313,8 @@ public class DataScript implements IScriptHandler { public Collection getNPCScripts() { return this.scripts.values(); } + @Override + public IScriptUnit createJaninoScriptUnit() { + return new JaninoNpcScript(); + } } diff --git a/src/main/java/noppes/npcs/janino/JaninoScript.java b/src/main/java/noppes/npcs/janino/JaninoScript.java index a5e1f3274..0f9d5c9f1 100644 --- a/src/main/java/noppes/npcs/janino/JaninoScript.java +++ b/src/main/java/noppes/npcs/janino/JaninoScript.java @@ -11,6 +11,8 @@ import noppes.npcs.config.ConfigScript; import noppes.npcs.constants.EnumScriptType; import noppes.npcs.controllers.ScriptController; import noppes.npcs.controllers.data.IScriptUnit; +import noppes.npcs.janino.annotations.ParamName; +import noppes.npcs.janino.annotations.ScriptHook; import org.codehaus.commons.compiler.InternalCompilerException; import org.codehaus.commons.compiler.Sandbox; diff --git a/src/main/java/noppes/npcs/janino/annotations/ParamName.java b/src/main/java/noppes/npcs/janino/annotations/ParamName.java new file mode 100644 index 000000000..6b1e9ec25 --- /dev/null +++ b/src/main/java/noppes/npcs/janino/annotations/ParamName.java @@ -0,0 +1,20 @@ +package noppes.npcs.janino.annotations; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + * Specifies the parameter name and type to use when generating method stubs. + * Applied to interface method parameters to preserve their names and types in generated code. + */ +@Retention(RetentionPolicy.RUNTIME) +@Target(ElementType.PARAMETER) +public @interface ParamName { + /** The parameter name (e.g., "event") */ + String value(); + + /** The fully qualified type name (e.g., "noppes.npcs.api.event.INpcEvent.InitEvent") */ + String type() default ""; +} diff --git a/src/main/java/noppes/npcs/janino/ScriptHook.java b/src/main/java/noppes/npcs/janino/annotations/ScriptHook.java similarity index 94% rename from src/main/java/noppes/npcs/janino/ScriptHook.java rename to src/main/java/noppes/npcs/janino/annotations/ScriptHook.java index 1b1ba598b..d4720b5d8 100644 --- a/src/main/java/noppes/npcs/janino/ScriptHook.java +++ b/src/main/java/noppes/npcs/janino/annotations/ScriptHook.java @@ -1,4 +1,4 @@ -package noppes.npcs.janino; +package noppes.npcs.janino.annotations; import noppes.npcs.constants.EnumScriptType; diff --git a/src/main/java/noppes/npcs/janino/impl/JaninoNpcScript.java b/src/main/java/noppes/npcs/janino/impl/JaninoNpcScript.java new file mode 100644 index 000000000..b41e2aac8 --- /dev/null +++ b/src/main/java/noppes/npcs/janino/impl/JaninoNpcScript.java @@ -0,0 +1,120 @@ +package noppes.npcs.janino.impl; + +import noppes.npcs.api.event.IAbilityEvent; +import noppes.npcs.api.event.INpcEvent; +import noppes.npcs.api.event.IProjectileEvent; +import noppes.npcs.constants.EnumScriptType; +import noppes.npcs.janino.JaninoScript; +import noppes.npcs.janino.annotations.ParamName; +import noppes.npcs.janino.annotations.ScriptHook; + +/** + * Janino (Java) script implementation for NPC events. + * This allows NPCs to use compiled Java code instead of ECMAScript. + */ +public class JaninoNpcScript extends JaninoScript { + + public JaninoNpcScript() { + super(Functions.class, (builder) -> builder + .setDefaultImports( + "noppes.npcs.api.*", + "noppes.npcs.api.entity.*", + "noppes.npcs.api.event.*", + "noppes.npcs.api.handler.*", + "noppes.npcs.api.handler.data.*", + "noppes.npcs.api.item.*", + "noppes.npcs.api.ability.*" + ) + ); + } + + /** + * Interface defining the hook methods available for NPC scripts. + * Each method corresponds to an NPC event from ScriptHookController CONTEXT_NPC. + * Methods are annotated with @ScriptHook to map them to their EnumScriptType. + */ + public interface Functions { + // Core lifecycle events + @ScriptHook(EnumScriptType.INIT) + default void init(@ParamName("event") INpcEvent.InitEvent event) {} + + @ScriptHook(EnumScriptType.TICK) + default void tick(@ParamName("event") INpcEvent.UpdateEvent event) {} + + + // Interaction events + @ScriptHook(EnumScriptType.INTERACT) + default void interact(@ParamName("event") INpcEvent.InteractEvent event) {} + + @ScriptHook(EnumScriptType.DIALOG) + default void dialog(@ParamName("event") INpcEvent.DialogEvent event) {} + + @ScriptHook(EnumScriptType.DIALOG_CLOSE) + default void dialogClose(@ParamName("event") INpcEvent.DialogClosedEvent event) {} + + + // Combat events - damage + @ScriptHook(EnumScriptType.DAMAGED) + default void damaged(@ParamName("event") INpcEvent.DamagedEvent event) {} + + @ScriptHook(EnumScriptType.KILLED) + default void killed(@ParamName("event") INpcEvent.DiedEvent event) {} + + @ScriptHook(EnumScriptType.KILLS) + default void kills(@ParamName("event") INpcEvent.KilledEntityEvent event) {} + + + // Combat events - attacks + @ScriptHook(EnumScriptType.ATTACK_MELEE) + default void meleeAttack(@ParamName("event") INpcEvent.MeleeAttackEvent event) {} + + @ScriptHook(EnumScriptType.ATTACK_SWING) + default void meleeSwing(@ParamName("event") INpcEvent.SwingEvent event) {} + + @ScriptHook(EnumScriptType.RANGED_LAUNCHED) + default void rangedLaunched(@ParamName("event") INpcEvent.RangedLaunchedEvent event) {} + + + // Targeting events + @ScriptHook(EnumScriptType.TARGET) + default void target(@ParamName("event") INpcEvent.TargetEvent event) {} + + @ScriptHook(EnumScriptType.TARGET_LOST) + default void targetLost(@ParamName("event") INpcEvent.TargetLostEvent event) {} + + // Other NPC events + @ScriptHook(EnumScriptType.COLLIDE) + default void collide(@ParamName("event") INpcEvent.CollideEvent event) {} + + @ScriptHook(EnumScriptType.TIMER) + default void timer(@ParamName("event") INpcEvent.TimerEvent event) {} + + + // Projectile events + @ScriptHook(EnumScriptType.PROJECTILE_TICK) + default void projectileTick(@ParamName("event") IProjectileEvent.UpdateEvent event) {} + + @ScriptHook(EnumScriptType.PROJECTILE_IMPACT) + default void projectileImpact(@ParamName("event") IProjectileEvent.ImpactEvent event) {} + + + // Ability events + @ScriptHook(EnumScriptType.ABILITY_START) + default void abilityStart(@ParamName("event") IAbilityEvent.StartEvent event) {} + + @ScriptHook(EnumScriptType.ABILITY_EXECUTE) + default void abilityExecute(@ParamName("event") IAbilityEvent.ExecuteEvent event) {} + + @ScriptHook(EnumScriptType.ABILITY_HIT) + default void abilityHit(@ParamName("event") IAbilityEvent.HitEvent event) {} + + @ScriptHook(EnumScriptType.ABILITY_TICK) + default void abilityTick(@ParamName("event") IAbilityEvent.TickEvent event) {} + + @ScriptHook(EnumScriptType.ABILITY_INTERRUPT) + default void abilityInterrupt(@ParamName("event") IAbilityEvent.InterruptEvent event) {} + + @ScriptHook(EnumScriptType.ABILITY_COMPLETE) + default void abilityComplete(@ParamName("event") IAbilityEvent.CompleteEvent event) {} + } +}