diff --git a/_datafiles/world/default/mobs/frostfang/scripts/2-guard.js b/_datafiles/world/default/mobs/frostfang/scripts/2-guard.js index 9efd35c2..3f9a3021 100644 --- a/_datafiles/world/default/mobs/frostfang/scripts/2-guard.js +++ b/_datafiles/world/default/mobs/frostfang/scripts/2-guard.js @@ -38,3 +38,30 @@ function onIdle(mob, room) { return false; } + + + +function onPath(mob, room, eventDetails) { + + if ( eventDetails.status == "waypoint" ) { + + if ( UtilDiceRoll(1, 5) == 1 ) { + + + if ( modules.follow ) { + + followingActors = modules.follow.GetFollowers(mob); + + for( var i in followingActors ) { + mob.Command("sayto "+followingActors[i].ShorthandId()+" Why are you following me? Leave me be."); + mob.Command("follow lose"); + break; + } + + } + + + } + } + +} \ No newline at end of file diff --git a/_datafiles/world/default/mobs/frostfang/scripts/26-frostfang_citizen-locketsadness.js b/_datafiles/world/default/mobs/frostfang/scripts/26-frostfang_citizen-locketsadness.js index 598825c3..1402233b 100644 --- a/_datafiles/world/default/mobs/frostfang/scripts/26-frostfang_citizen-locketsadness.js +++ b/_datafiles/world/default/mobs/frostfang/scripts/26-frostfang_citizen-locketsadness.js @@ -152,6 +152,10 @@ function onIdle(mob, room) { mob.Command("emote sniffles a bit, holding back tears."); return true; default: // 1, 3 + if ( UtilDiceRoll(1, 10) == 1 ) { + mob.Command("pathto 274"); // look around the bushes area + return true; + } return false; } diff --git a/internal/plugins/plugincallbacks.go b/internal/plugins/plugincallbacks.go index af248ff5..6da7b0ce 100644 --- a/internal/plugins/plugincallbacks.go +++ b/internal/plugins/plugincallbacks.go @@ -8,8 +8,9 @@ import ( ) type PluginCallbacks struct { - userCommands map[string]usercommands.CommandAccess - mobCommands map[string]mobcommands.CommandAccess + userCommands map[string]usercommands.CommandAccess + mobCommands map[string]mobcommands.CommandAccess + scriptCommands map[string]map[string]any iacHandler func(uint64, []byte) bool onLoad func() @@ -19,8 +20,9 @@ type PluginCallbacks struct { func newPluginCallbacks() PluginCallbacks { return PluginCallbacks{ - userCommands: map[string]usercommands.CommandAccess{}, - mobCommands: map[string]mobcommands.CommandAccess{}, + userCommands: map[string]usercommands.CommandAccess{}, + mobCommands: map[string]mobcommands.CommandAccess{}, + scriptCommands: map[string]map[string]any{}, } } diff --git a/internal/plugins/plugins.go b/internal/plugins/plugins.go index 7479501f..4d725073 100644 --- a/internal/plugins/plugins.go +++ b/internal/plugins/plugins.go @@ -15,6 +15,7 @@ import ( "github.com/GoMudEngine/GoMud/internal/configs" "github.com/GoMudEngine/GoMud/internal/mobcommands" "github.com/GoMudEngine/GoMud/internal/mudlog" + "github.com/GoMudEngine/GoMud/internal/scripting" "github.com/GoMudEngine/GoMud/internal/usercommands" "github.com/GoMudEngine/GoMud/internal/util" "gopkg.in/yaml.v2" @@ -228,6 +229,16 @@ func (p *Plugin) ExportFunction(stringId string, f any) { p.exportedFunctions[stringId] = f } +// Registers a UserCommand and callback +func (p *Plugin) AddScriptingFunction(funcName string, scriptFunc any) { + + if _, ok := p.Callbacks.scriptCommands[p.name]; !ok { + p.Callbacks.scriptCommands[p.name] = map[string]any{} + } + + p.Callbacks.scriptCommands[p.name][funcName] = scriptFunc +} + // Registers a UserCommand and callback func (p *Plugin) AddUserCommand(command string, handlerFunc usercommands.UserCommand, allowWhenDowned bool, isAdminOnly bool) { @@ -421,6 +432,12 @@ func Load(dataFilesPath string) { mobcommands.RegisterCommand(cmd, info.Func, info.AllowedWhenDowned) } + for nameSpace, funcMap := range p.Callbacks.scriptCommands { + for cmd, funcRef := range funcMap { + scripting.AddModlueFunction(nameSpace, cmd, funcRef) + } + } + // Check for config.yaml override and set missing values accordingly OLPath := util.FilePath(`data-overlays`, `/`, `config.yaml`) if b, err := p.files.ReadFile(OLPath); err == nil { diff --git a/internal/scripting/module_func.go b/internal/scripting/module_func.go new file mode 100644 index 00000000..4dec2bd0 --- /dev/null +++ b/internal/scripting/module_func.go @@ -0,0 +1,20 @@ +package scripting + +import ( + "github.com/dop251/goja" +) + +var ( + moduleFunctions = map[string]map[string]any{} +) + +func AddModlueFunction(namespace string, name string, funcRef any) { + if _, ok := moduleFunctions[namespace]; !ok { + moduleFunctions[namespace] = map[string]any{} + } + moduleFunctions[namespace][name] = funcRef +} + +func setModuleFunctions(vm *goja.Runtime) { + vm.Set("modules", moduleFunctions) +} diff --git a/internal/scripting/scripting.go b/internal/scripting/scripting.go index ed7c8e44..a82db794 100644 --- a/internal/scripting/scripting.go +++ b/internal/scripting/scripting.go @@ -100,6 +100,7 @@ func setAllScriptingFunctions(vm *goja.Runtime) { setSpellFunctions(vm) setItemFunctions(vm) setUtilFunctions(vm) + setModuleFunctions(vm) } func PruneVMs(forceClear ...bool) { diff --git a/modules/README.md b/modules/README.md index dd117e4b..aa75044f 100644 --- a/modules/README.md +++ b/modules/README.md @@ -24,6 +24,7 @@ Extract any modules into this folder. * Add/Over-write existing template files (See `modules/auctions`) * Add/Over-write help files (See `modules/auctions`) * Add/Over-write user or mob commands (See `modules/auctions`) +* Add functions for scripting (See `modules/follow`) * Save/Load their own data (See `modules/leaderboards`) * Track their own config values (See `modules/leaderboards`) * Modify help menu items, command aliases, help aliases (See `modules/leaderboards`) diff --git a/modules/follow/follow.go b/modules/follow/follow.go index 7043d181..8162273e 100644 --- a/modules/follow/follow.go +++ b/modules/follow/follow.go @@ -10,6 +10,7 @@ import ( "github.com/GoMudEngine/GoMud/internal/parties" "github.com/GoMudEngine/GoMud/internal/plugins" "github.com/GoMudEngine/GoMud/internal/rooms" + "github.com/GoMudEngine/GoMud/internal/scripting" "github.com/GoMudEngine/GoMud/internal/users" "github.com/GoMudEngine/GoMud/internal/util" ) @@ -55,6 +56,13 @@ func init() { f.plug.AddUserCommand(`follow`, f.followUserCommand, true, false) f.plug.AddMobCommand(`follow`, f.followMobCommand, true) + // + // Register any scripting functions + // + // Will be available in scripts as: + // module.follow.GetFollowers() + f.plug.AddScriptingFunction("GetFollowers", f.Scripting_GetFollowers) + events.RegisterListener(events.RoomChange{}, f.roomChangeHandler) events.RegisterListener(events.PlayerDespawn{}, f.playerDespawnHandler) events.RegisterListener(events.MobIdle{}, f.idleMobHandler, events.First) @@ -79,6 +87,18 @@ type FollowModule struct { followers map[followId]followId // key => who's following someone. value => who's being followed } +// Intended to be invoked by a script. +func (f *FollowModule) Scripting_GetFollowers(targetActor scripting.ScriptActor) []*scripting.ScriptActor { + + results := []*scripting.ScriptActor{} + + for _, f := range f.getFollowers(followId{mobInstanceId: targetActor.InstanceId()}) { + results = append(results, scripting.GetActor(f.userId, f.mobInstanceId)) + } + + return results +} + // Get all followeres attached to a target func (f *FollowModule) isFollowing(followCheck followId) bool { _, ok := f.followers[followCheck]