diff options
Diffstat (limited to 'internal/game')
| -rw-r--r-- | internal/game/cmd_inspect.go | 12 | ||||
| -rw-r--r-- | internal/game/sys_triggers.go | 103 |
2 files changed, 43 insertions, 72 deletions
diff --git a/internal/game/cmd_inspect.go b/internal/game/cmd_inspect.go index 2c1b611..446d06e 100644 --- a/internal/game/cmd_inspect.go +++ b/internal/game/cmd_inspect.go @@ -90,18 +90,6 @@ func (g *Game) executeInspect(sess *net.Session, args []string, rawInput string) if len(room.OnExit) > 0 { sess.WriteLine(fmt.Sprintf("\nOn-Exit Triggers: %d", len(room.OnExit))) } - if len(room.OnFlagChange) > 0 { - sess.WriteLine(fmt.Sprintf("\nOn-Flag-Change Triggers: %d", len(room.OnFlagChange))) - for _, t := range room.OnFlagChange { - sess.WriteLine(fmt.Sprintf(" player flag %q (%d steps)", t.OnPlayerFlag, len(t.Steps))) - } - } - if len(room.OnGlobalFlagChange) > 0 { - sess.WriteLine(fmt.Sprintf("\nOn-Global-Flag-Change Triggers: %d", len(room.OnGlobalFlagChange))) - for _, t := range room.OnGlobalFlagChange { - sess.WriteLine(fmt.Sprintf(" global flag %q (%d steps)", t.OnGlobalFlag, len(t.Steps))) - } - } sess.WriteLine("\n--- Global Flags ---") allFlags := g.GlobalFlags.All() diff --git a/internal/game/sys_triggers.go b/internal/game/sys_triggers.go index a1955e7..683b3e0 100644 --- a/internal/game/sys_triggers.go +++ b/internal/game/sys_triggers.go @@ -474,10 +474,10 @@ func expandTemplate(tmpl string, playerName string, flagValue any) string { return s } -// ---- Flag-change trigger index (replaces the old TriggerStore) ---- +// ---- Flag-change trigger index ---- // -// All on_player_flag / on_global_flag triggers (room-embedded and global-file) -// are indexed by flag name and listen everywhere. Room scoping is opt-in via +// All on_player_flag / on_global_flag triggers are global file-backed +// triggers (stored in data/triggers/). Room scoping is opt-in via // the trigger's Condition.Room. type flagTriggerIndex struct { @@ -513,46 +513,55 @@ func (fi *flagTriggerIndex) addGlobalFlag(t *behavior.Trigger) { } // loadGlobalTriggers loads file-backed triggers from dataDir/triggers (one -// Trigger per yaml file; the filename stem is the trigger id). +// Trigger per yaml file; the filename stem is the trigger id). Triggers are +// organised in player_flag/ and global_flag/ subdirectories. func (g *Game) loadGlobalTriggers(dataDir string) error { dir := filepath.Join(dataDir, "triggers") if _, err := os.Stat(dir); os.IsNotExist(err) { return nil } - entries, err := os.ReadDir(dir) - if err != nil { - return err - } - for _, entry := range entries { - if entry.IsDir() { - continue - } - path := filepath.Join(dir, entry.Name()) - ext := strings.ToLower(filepath.Ext(path)) - if ext != ".yaml" && ext != ".yml" { - continue - } - data, err := os.ReadFile(path) + // Scan subdirectories as well as flat files in the root. + var walkDir func(p string) error + walkDir = func(p string) error { + entries, err := os.ReadDir(p) if err != nil { - continue - } - var t behavior.Trigger - if err := yamlUnmarshal(data, &t); err != nil { - return fmt.Errorf("trigger %q: %w", path, err) + return err } - stem := strings.TrimSuffix(entry.Name(), ext) - if t.OnPlayerFlag != "" { - tc := copyTrigger(t) - tc.DedupKey = "file:" + stem - g.flagIndex.addPlayerFlag(tc) - } - if t.OnGlobalFlag != "" { - tc := copyTrigger(t) - tc.DedupKey = "file:" + stem - g.flagIndex.addGlobalFlag(tc) + for _, entry := range entries { + full := filepath.Join(p, entry.Name()) + if entry.IsDir() { + if err := walkDir(full); err != nil { + return err + } + continue + } + ext := strings.ToLower(filepath.Ext(entry.Name())) + if ext != ".yaml" && ext != ".yml" { + continue + } + data, err := os.ReadFile(full) + if err != nil { + continue + } + var t behavior.Trigger + if err := yamlUnmarshal(data, &t); err != nil { + return fmt.Errorf("trigger %q: %w", full, err) + } + stem := strings.TrimSuffix(entry.Name(), ext) + if t.OnPlayerFlag != "" { + tc := copyTrigger(t) + tc.DedupKey = "file:" + stem + g.flagIndex.addPlayerFlag(tc) + } + if t.OnGlobalFlag != "" { + tc := copyTrigger(t) + tc.DedupKey = "file:" + stem + g.flagIndex.addGlobalFlag(tc) + } } + return nil } - return nil + return walkDir(dir) } func copyTrigger(t behavior.Trigger) *behavior.Trigger { @@ -560,35 +569,9 @@ func copyTrigger(t behavior.Trigger) *behavior.Trigger { return &tcopy } -// seedRoomFlagTriggers indexes the on_flag_change / on_global_flag_change -// blocks of every room. -func (g *Game) seedRoomFlagTriggers() { - roomIndex := g.World.RoomIndex() - for id := range roomIndex { - room, err := g.World.LoadRoom(id) - if err != nil { - continue - } - for i := range room.OnFlagChange { - t := room.OnFlagChange[i] - if t.OnPlayerFlag != "" { - t.DedupKey = fmt.Sprintf("room:%d:on_flag_change:%d", id, i) - g.flagIndex.addPlayerFlag(&room.OnFlagChange[i]) - } - } - for i := range room.OnGlobalFlagChange { - if room.OnGlobalFlagChange[i].OnGlobalFlag != "" { - room.OnGlobalFlagChange[i].DedupKey = fmt.Sprintf("room:%d:on_global_flag_change:%d", id, i) - g.flagIndex.addGlobalFlag(&room.OnGlobalFlagChange[i]) - } - } - } -} - func (g *Game) loadAllFlagTriggers() { g.flagIndex.clear() _ = g.loadGlobalTriggers(g.DataDir) - g.seedRoomFlagTriggers() } // firePlayerFlagTriggers starts sequences for every on_flag_change trigger |
