items executing hooks on usage

This commit is contained in:
austin 2024-09-30 16:35:58 -04:00
parent e0e90cdd1e
commit 00176449e1
12 changed files with 126 additions and 3 deletions

View File

@ -0,0 +1,14 @@
import { Engine } from "/Scripts/types/engine";
import { Hook } from "/Scripts/types/hook";
/**
* The client-wide hooks
*/
export const clientHooks: Hook[] = [
{
signal: "OPEN_VOXEL",
callback: (engine: Engine) => {
engine.classes.menuUtils.static.openVoxel()
}
}
]

View File

@ -6,6 +6,9 @@ import { Entity } from "/Scripts/types/host/entity/entity"
*/ */
export type Item = Entity export type Item = Entity
/**
* An inventory
*/
export interface Inventory { export interface Inventory {
} }

View File

@ -3,6 +3,7 @@ import { Client, NamespaceClient } from '/Scripts/client/client'
import { HookManager } from '/Scripts/engine/hooks/hook-manager' import { HookManager } from '/Scripts/engine/hooks/hook-manager'
import { SceneLoader } from '/Scripts/engine/scene/scene-loader' import { SceneLoader } from '/Scripts/engine/scene/scene-loader'
import { Engine } from '/Scripts/types/engine' import { Engine } from '/Scripts/types/engine'
import { clientHooks } from '/Scripts/client/clienthooks'
/** /**
* The core engine values * The core engine values
@ -25,5 +26,10 @@ export const ENGINE_onInit = () => {
engine.sceneLoader.engine = engine engine.sceneLoader.engine = engine
engine.hookManager.engine = engine engine.hookManager.engine = engine
//load global hooks
clientHooks.forEach(hook => {
engine.hookManager.registerGlobalHook(hook,false)
})
loggerScripts.INFO('Script Engine Initialized') loggerScripts.INFO('Script Engine Initialized')
} }

View File

@ -95,6 +95,28 @@ export class HookManager {
scene.signalHookMap[hookSignal] = sceneSignalArray scene.signalHookMap[hookSignal] = sceneSignalArray
} }
/**
* Registers a global hook
* @param hook The hook
*/
registerGlobalHook(hook: Hook, isServerScene: boolean){
const trackedHook: TrackedHook = {
...hook,
scope: isServerScene ? HookScope.SCENE_SERVER : HookScope.SCENE_CLIENT,
}
//add to flat array
this.hooks.push(trackedHook)
//add to signal array
const hookSignal: string = hook.signal
const signalArray: Array<TrackedHook> = this.signalHookMap?.[hookSignal] ? this.signalHookMap?.[hookSignal] : []
signalArray.push(trackedHook)
this.signalHookMap[hookSignal] = signalArray
loggerScripts.DEBUG('register signal hook map')
loggerScripts.DEBUG(hookSignal)
loggerScripts.DEBUG(Object.keys(this.signalHookMap) + '')
loggerScripts.DEBUG(this.signalHookMap[hookSignal] + '')
}
/** /**
* Deregisters a hook * Deregisters a hook
* @param scene The scene which introduced the hook * @param scene The scene which introduced the hook
@ -118,7 +140,8 @@ export class HookManager {
const globalHooks: Array<TrackedHook> = this.signalHookMap[signal] const globalHooks: Array<TrackedHook> = this.signalHookMap[signal]
if(!!globalHooks){ if(!!globalHooks){
globalHooks.forEach(trackedHook => { globalHooks.forEach(trackedHook => {
trackedHook.callback(...argsRaw) loggerScripts.DEBUG("Called global hook")
trackedHook.callback(this.engine, ...argsRaw)
}) })
} else { } else {
//There isn't a hook registered for this signal at the global level //There isn't a hook registered for this signal at the global level
@ -131,7 +154,8 @@ export class HookManager {
const sceneHooks: Array<TrackedHook> = scene.signalHookMap[signal] const sceneHooks: Array<TrackedHook> = scene.signalHookMap[signal]
if(!!sceneHooks){ if(!!sceneHooks){
sceneHooks.forEach(trackeHook => { sceneHooks.forEach(trackeHook => {
trackeHook.callback(...argsRaw) loggerScripts.DEBUG("Called local hook")
trackeHook.callback(this.engine, ...argsRaw)
}) })
} else { } else {
//There isn't a hook registered for this signal at the scene level //There isn't a hook registered for this signal at the scene level

View File

@ -1,3 +1,4 @@
import { Engine } from "/Scripts/types/engine";
/** /**
@ -13,6 +14,6 @@ export interface Hook {
/** /**
* The function to call when the signal is fired * The function to call when the signal is fired
*/ */
readonly callback: (...value: any) => void, readonly callback: (engine: Engine, ...value: any) => void,
} }

View File

@ -0,0 +1,11 @@
/**
* Utilities for ui menu interactions
*/
export interface MenuUtils {
/**
* Opens the voxel selection menu
*/
readonly openVoxel: () => void
}

View File

@ -1,4 +1,5 @@
import { Entity } from "/Scripts/types/host/entity/entity"; import { Entity } from "/Scripts/types/host/entity/entity";
import { MenuUtils } from "/Scripts/types/host/renderer/ui/menus";
import { TutorialUtils } from "/Scripts/types/host/renderer/ui/tutorial"; import { TutorialUtils } from "/Scripts/types/host/renderer/ui/tutorial";
import { Vector } from "/Scripts/types/spatial"; import { Vector } from "/Scripts/types/spatial";
@ -28,6 +29,10 @@ export interface StaticClasses {
*/ */
readonly serverUtils?: Class<ServerUtils>, readonly serverUtils?: Class<ServerUtils>,
/**
* Utilities for interacting with menus on client
*/
readonly menuUtils?: Class<MenuUtils>,
} }

View File

@ -857,6 +857,7 @@ Filter toolbar slots out of equip menu
Fix attack tree checks Fix attack tree checks
Disable client equip tests until can review Disable client equip tests until can review
Toolbar scrolling Toolbar scrolling
Items executing script engine hooks on usage
# TODO # TODO

View File

@ -1,5 +1,6 @@
package electrosphere.client.item; package electrosphere.client.item;
import electrosphere.client.script.ClientScriptUtils;
import electrosphere.client.ui.menu.WindowStrings; import electrosphere.client.ui.menu.WindowStrings;
import electrosphere.client.ui.menu.WindowUtils; import electrosphere.client.ui.menu.WindowUtils;
import electrosphere.client.ui.menu.ingame.MenuGeneratorsTerrainEditing; import electrosphere.client.ui.menu.ingame.MenuGeneratorsTerrainEditing;
@ -48,6 +49,14 @@ public class ItemActions {
if(shooterTree != null){ if(shooterTree != null){
shooterTree.fire(); shooterTree.fire();
} }
ClientToolbarState clientToolbarState = ClientToolbarState.getClientToolbarState(Globals.playerEntity);
Entity primaryEntity = clientToolbarState.getCurrentPrimaryItem();
if(primaryEntity != null && Globals.gameConfigCurrent.getItemMap().getItem(primaryEntity) != null){
Item data = Globals.gameConfigCurrent.getItemMap().getItem(primaryEntity);
if(data.getClientSidePrimary() != null){
ClientScriptUtils.fireSignal(data.getClientSidePrimary());
}
}
} }
} }

View File

@ -0,0 +1,22 @@
package electrosphere.client.script;
import electrosphere.engine.Globals;
import electrosphere.script.ScriptEngine;
/**
* Utilities for dealing with the scripting engine from the client's perspective
*/
public class ClientScriptUtils {
/**
* Fires a signal
* @param signalName The name of the signal
* @param args The arguments provided alongside the signal
*/
public static void fireSignal(String signalName, Object ... args){
if(Globals.scriptEngine != null && Globals.scriptEngine.isInitialized()){
Globals.scriptEngine.fireSignal(signalName, ScriptEngine.GLOBAL_SCENE, args);
}
}
}

View File

@ -0,0 +1,25 @@
package electrosphere.client.ui.menu.script;
import org.graalvm.polyglot.HostAccess.Export;
import electrosphere.client.ui.menu.WindowStrings;
import electrosphere.client.ui.menu.WindowUtils;
import electrosphere.client.ui.menu.ingame.MenuGeneratorsTerrainEditing;
import electrosphere.controls.ControlHandler.ControlsState;
import electrosphere.engine.Globals;
/**
* Utilities provided to the scripting interface that allow creating/destroying menus
*/
public class ScriptMenuUtils {
/**
* Opens the voxel selection menu
*/
@Export
public static void openVoxel(){
WindowUtils.replaceWindow(WindowStrings.VOXEL_TYPE_SELECTION,MenuGeneratorsTerrainEditing.createVoxelTypeSelectionPanel());
Globals.controlHandler.hintUpdateControlState(ControlsState.IN_GAME_MAIN_MENU);
}
}

View File

@ -13,6 +13,7 @@ import org.graalvm.polyglot.Source;
import org.graalvm.polyglot.Source.Builder; import org.graalvm.polyglot.Source.Builder;
import org.graalvm.polyglot.Value; import org.graalvm.polyglot.Value;
import electrosphere.client.ui.menu.script.ScriptMenuUtils;
import electrosphere.client.ui.menu.tutorial.TutorialMenus; import electrosphere.client.ui.menu.tutorial.TutorialMenus;
import electrosphere.engine.Globals; import electrosphere.engine.Globals;
import electrosphere.engine.Main; import electrosphere.engine.Main;
@ -92,6 +93,7 @@ public class ScriptEngine {
{"simulation",Main.class}, {"simulation",Main.class},
{"tutorialUtils",TutorialMenus.class}, {"tutorialUtils",TutorialMenus.class},
{"serverUtils",JSServerUtils.class}, {"serverUtils",JSServerUtils.class},
{"menuUtils",ScriptMenuUtils.class},
}; };
//singletons from the host that are provided to the javascript context //singletons from the host that are provided to the javascript context