aboutsummaryrefslogtreecommitdiff
path: root/internal
diff options
context:
space:
mode:
authorhistoria <[not public]>2026-07-07 16:24:27 -0400
committerhistoria <[not public]>2026-07-07 16:24:27 -0400
commitab2597b22ccdb71116992aec78080d9858358d04 (patch)
tree8beae4060c2831c4a68f92b682b5350cfa1d0afb /internal
parent3f30fa3eec9c2e2acf9a984ccefb9529a25e688a (diff)
downloadthehouseoficarus-ab2597b22ccdb71116992aec78080d9858358d04.tar.gz
rename flags to global_flags (differentiate from player_flags)
Diffstat (limited to 'internal')
-rw-r--r--internal/admin/api_global_flags.go (renamed from internal/admin/api_flags.go)6
-rw-r--r--internal/admin/server.go2
-rw-r--r--internal/behavior/behavior.go4
-rw-r--r--internal/game/act.go7
-rw-r--r--internal/game/act_room.go10
-rw-r--r--internal/game/act_steal.go2
-rw-r--r--internal/game/act_talk.go8
-rw-r--r--internal/game/cmd_inspect.go8
-rw-r--r--internal/game/cmd_move.go8
-rw-r--r--internal/game/cmd_registry.go2
-rw-r--r--internal/game/cmd_room_insert.go4
-rw-r--r--internal/game/cmd_room_remove.go4
-rw-r--r--internal/game/cmd_setglobalflag.go (renamed from internal/game/cmd_setflag.go)8
-rw-r--r--internal/game/condition_test.go22
-rw-r--r--internal/game/core_flagstore.go30
-rw-r--r--internal/game/exit_discovery_test.go6
-rw-r--r--internal/game/game.go10
-rw-r--r--internal/game/map_test.go16
-rw-r--r--internal/game/sys_triggers.go20
-rw-r--r--internal/player/player.go4
-rw-r--r--internal/world/grid_test.go4
-rw-r--r--internal/world/insert_remove.go2
-rw-r--r--internal/world/room.go6
-rw-r--r--internal/world/room_migrate_test.go6
-rw-r--r--internal/world/trigger.go8
-rw-r--r--internal/world/trigger_store.go68
26 files changed, 138 insertions, 137 deletions
diff --git a/internal/admin/api_flags.go b/internal/admin/api_global_flags.go
index e2594f3..ab286ad 100644
--- a/internal/admin/api_flags.go
+++ b/internal/admin/api_global_flags.go
@@ -2,13 +2,13 @@ package admin
import "net/http"
-func (s *AdminServer) handleFlags(w http.ResponseWriter, r *http.Request) {
+func (s *AdminServer) handleGlobalFlags(w http.ResponseWriter, r *http.Request) {
if r.Method != http.MethodGet {
http.Error(w, "method not allowed", http.StatusMethodNotAllowed)
return
}
writeJSON(w, map[string]any{
- "flags": []any{},
- "note": "world flags are in-memory only",
+ "global_flags": []any{},
+ "note": "global flags are in-memory only",
})
}
diff --git a/internal/admin/server.go b/internal/admin/server.go
index 17835db..f06b7cf 100644
--- a/internal/admin/server.go
+++ b/internal/admin/server.go
@@ -167,7 +167,7 @@ func NewServer(cfg *config.Config, useTLS bool, accountStore *player.AccountStor
apiMux.HandleFunc("/api/courses/", s.handleCourseByID)
apiMux.HandleFunc("/api/players", s.handlePlayers)
apiMux.HandleFunc("/api/dashboard", s.handleDashboard)
- apiMux.HandleFunc("/api/flags", s.handleFlags)
+ apiMux.HandleFunc("/api/global_flags", s.handleGlobalFlags)
apiMux.HandleFunc("/api/tools", s.handleTools)
apiMux.HandleFunc("/api/search", s.handleSearch)
apiMux.HandleFunc("/api/undo/state", s.handleUndoState)
diff --git a/internal/behavior/behavior.go b/internal/behavior/behavior.go
index 7d8ce8f..ec9fc7c 100644
--- a/internal/behavior/behavior.go
+++ b/internal/behavior/behavior.go
@@ -43,7 +43,7 @@ type TalkOption struct {
}
type NodeAction struct {
- SetFlags map[string]any `yaml:"set_flags"`
+ SetGlobalFlags map[string]any `yaml:"set_global_flags"`
SetPlayerFlags map[string]any `yaml:"set_player_flags"`
GiveItem string `yaml:"give_item"`
TakeItem string `yaml:"take_item"`
@@ -143,7 +143,7 @@ func (c *ShopConfig) FindItem(itemID string) *ShopItem {
}
type Condition struct {
- Flag string `yaml:"flag"`
+ GlobalFlag string `yaml:"global_flag"`
Value any `yaml:"value"`
Not bool `yaml:"not"`
PlayerFlag string `yaml:"player_flag"`
diff --git a/internal/game/act.go b/internal/game/act.go
index f2ea121..ddeed04 100644
--- a/internal/game/act.go
+++ b/internal/game/act.go
@@ -297,8 +297,8 @@ func (g *Game) checkCondition(sess *net.Session, c *behavior.Condition) bool {
return flagMatches(present, val, c.Value, c.Not)
}
- if c.Flag != "" {
- val, present := g.Flags.Get(c.Flag)
+ if c.GlobalFlag != "" {
+ val, present := g.GlobalFlags.Get(c.GlobalFlag)
return flagMatches(present, val, c.Value, c.Not)
}
if c.HasItem != "" {
@@ -318,7 +318,8 @@ func (g *Game) checkCondition(sess *net.Session, c *behavior.Condition) bool {
return true
}
-// flagMatches evaluates a flag/player_flag condition.
+// flagMatches evaluates a global_flag/player_flag condition. The name is
+// historical; it evaluates both flag types.
//
// If the condition specifies no `value`, the flag matches when it is present
// and truthy (so `{player_flag: x}` means "x is set" and
diff --git a/internal/game/act_room.go b/internal/game/act_room.go
index ddca261..da74d6e 100644
--- a/internal/game/act_room.go
+++ b/internal/game/act_room.go
@@ -161,8 +161,8 @@ func (g *Game) fireEnterStep(seq *enterSeq, step world.EnterStep) {
}
}
}
- if len(step.SetFlags) > 0 || len(step.SetPlayerFlags) > 0 {
- g.applyFlagMutations(p, step.SetFlags, step.SetPlayerFlags)
+ if len(step.SetGlobalFlags) > 0 || len(step.SetPlayerFlags) > 0 {
+ g.applyFlagMutations(p, step.SetGlobalFlags, step.SetPlayerFlags)
g.AccountStore.SaveCharacter(p)
}
if step.SpawnMob != nil {
@@ -229,10 +229,10 @@ func (g *Game) isCharLive(name string, sess *net.Session) bool {
return g.loggedInChars[name] == sess
}
-// applyFlagMutations sets world and player flags, shared by on_enter steps and
+// applyFlagMutations sets global and player flags, shared by on_enter steps and
// exit traversal.
-func (g *Game) applyFlagMutations(p *player.Player, setFlags, setPlayerFlags map[string]any) {
- g.Flags.SetAll(setFlags)
+func (g *Game) applyFlagMutations(p *player.Player, setGlobalFlags, setPlayerFlags map[string]any) {
+ g.GlobalFlags.SetAll(setGlobalFlags)
if len(setPlayerFlags) > 0 {
for k, v := range setPlayerFlags {
g.setPlayerFlag(p, k, v)
diff --git a/internal/game/act_steal.go b/internal/game/act_steal.go
index b5c1210..0aae6d1 100644
--- a/internal/game/act_steal.go
+++ b/internal/game/act_steal.go
@@ -47,7 +47,7 @@ var stallGuardTalk = &behavior.TalkConfig{
},
"fight": {
Messages: []string{"Then defend yourself!"},
- Action: &behavior.NodeAction{SetFlags: map[string]any{"guard_hostile": true}},
+ Action: &behavior.NodeAction{SetGlobalFlags: map[string]any{"guard_hostile": true}},
Options: []behavior.TalkOption{{Text: "(The guard attacks!)"}},
},
},
diff --git a/internal/game/act_talk.go b/internal/game/act_talk.go
index 7cfdf7c..ca6054c 100644
--- a/internal/game/act_talk.go
+++ b/internal/game/act_talk.go
@@ -60,8 +60,8 @@ func (g *Game) startTalk(sess *net.Session, p *player.Player, obj *object.Object
func (g *Game) handleNodeAction(sess *net.Session, na *behavior.NodeAction) (intercepted bool) {
g.applyNodeAction(sess, na)
- if v, ok := g.Flags.Get("guard_hostile"); ok && v != nil {
- g.Flags.Delete("guard_hostile")
+ if v, ok := g.GlobalFlags.Get("guard_hostile"); ok && v != nil {
+ g.GlobalFlags.Delete("guard_hostile")
p := sess.Player
if p != nil && p.Action != nil {
if td, ok := p.Action.Data.(*behavior.TalkData); ok && td.StealGuard {
@@ -348,8 +348,8 @@ func (g *Game) applyNodeAction(sess *net.Session, na *behavior.NodeAction) {
g.AccountStore.SaveCharacter(p)
}
- for k, v := range na.SetFlags {
- g.Flags.Set(k, v)
+ for k, v := range na.SetGlobalFlags {
+ g.GlobalFlags.Set(k, v)
}
for k, v := range na.SetPlayerFlags {
g.setPlayerFlag(p, k, v)
diff --git a/internal/game/cmd_inspect.go b/internal/game/cmd_inspect.go
index 62392b7..7488591 100644
--- a/internal/game/cmd_inspect.go
+++ b/internal/game/cmd_inspect.go
@@ -92,8 +92,8 @@ func (g *Game) executeInspect(sess *net.Session, args []string, rawInput string)
sess.WriteLine(fmt.Sprintf("\nRoom Triggers: %d", len(room.Triggers)))
for _, trigger := range room.Triggers {
kind := ""
- if trigger.OnFlag != "" {
- kind = fmt.Sprintf("world flag %q", trigger.OnFlag)
+ if trigger.OnGlobalFlag != "" {
+ kind = fmt.Sprintf("global flag %q", trigger.OnGlobalFlag)
} else if trigger.OnPlayerFlag != "" {
kind = fmt.Sprintf("player flag %q", trigger.OnPlayerFlag)
}
@@ -101,8 +101,8 @@ func (g *Game) executeInspect(sess *net.Session, args []string, rawInput string)
}
}
- sess.WriteLine("\n--- World Flags ---")
- allFlags := g.Flags.All()
+ sess.WriteLine("\n--- Global Flags ---")
+ allFlags := g.GlobalFlags.All()
if len(allFlags) == 0 {
sess.WriteLine(" (none)")
} else {
diff --git a/internal/game/cmd_move.go b/internal/game/cmd_move.go
index f236d67..2f27eed 100644
--- a/internal/game/cmd_move.go
+++ b/internal/game/cmd_move.go
@@ -67,7 +67,7 @@ func (g *Game) doMove(sess *net.Session, dir string, multiplier float64) {
}
}
- p.MovePendingFlags = exitDef.SetFlags
+ p.MovePendingGlobalFlags = exitDef.SetGlobalFlags
p.MovePendingPlayerFlags = exitDef.SetPlayerFlags
inCombat := g.Combat.Get(p.Name) != nil
@@ -132,7 +132,7 @@ func (g *Game) moveTicks(p *player.Player, multiplier float64) int {
func (g *Game) completeMove(sess *net.Session, p *player.Player) {
exitDir := p.MoveDirection
targetID := p.MoveTarget
- pendingFlags := p.MovePendingFlags
+ pendingGlobalFlags := p.MovePendingGlobalFlags
pendingPlayerFlags := p.MovePendingPlayerFlags
p.ClearMoveState()
@@ -163,8 +163,8 @@ func (g *Game) completeMove(sess *net.Session, p *player.Player) {
if p.EnterSeqRoom != 0 && p.EnterSeqRoom == oldRoom {
p.EnterSeqRoom = 0
}
- if len(pendingFlags) > 0 || len(pendingPlayerFlags) > 0 {
- g.applyFlagMutations(p, pendingFlags, pendingPlayerFlags)
+ if len(pendingGlobalFlags) > 0 || len(pendingPlayerFlags) > 0 {
+ g.applyFlagMutations(p, pendingGlobalFlags, pendingPlayerFlags)
}
g.AccountStore.SaveCharacter(p)
diff --git a/internal/game/cmd_registry.go b/internal/game/cmd_registry.go
index 462bf53..e2c34aa 100644
--- a/internal/game/cmd_registry.go
+++ b/internal/game/cmd_registry.go
@@ -150,7 +150,7 @@ var commandRegistry = map[string]commandDef{
"goto": {(*Game).executeGoto, ClassInstant},
"summon": {(*Game).executeSummon, ClassInstant},
"dig": {(*Game).executeDig, ClassInstant},
- "setflag": {(*Game).executeSetFlag, ClassInstant},
+ "setglobalflag": {(*Game).executeSetGlobalFlag, ClassInstant},
"setplayerflag": {(*Game).executeSetPlayerFlag, ClassInstant},
"reload": {(*Game).executeReload, ClassInstant},
"shutdown": {(*Game).executeShutdown, ClassInstant},
diff --git a/internal/game/cmd_room_insert.go b/internal/game/cmd_room_insert.go
index b72591f..713c5ee 100644
--- a/internal/game/cmd_room_insert.go
+++ b/internal/game/cmd_room_insert.go
@@ -138,7 +138,7 @@ func (g *Game) roomInsert(sess *net.Session, args []string) {
Room: newID,
Condition: exitDef.Condition,
BlockedMessage: exitDef.BlockedMessage,
- SetFlags: exitDef.SetFlags,
+ SetGlobalFlags: exitDef.SetGlobalFlags,
SetPlayerFlags: exitDef.SetPlayerFlags,
Hidden: exitDef.Hidden,
AlwaysBlocked: exitDef.AlwaysBlocked,
@@ -158,7 +158,7 @@ func (g *Game) roomInsert(sess *net.Session, args []string) {
Room: newID,
Condition: targetExit.Condition,
BlockedMessage: targetExit.BlockedMessage,
- SetFlags: targetExit.SetFlags,
+ SetGlobalFlags: targetExit.SetGlobalFlags,
SetPlayerFlags: targetExit.SetPlayerFlags,
Hidden: targetExit.Hidden,
AlwaysBlocked: targetExit.AlwaysBlocked,
diff --git a/internal/game/cmd_room_remove.go b/internal/game/cmd_room_remove.go
index 78c1234..28433ff 100644
--- a/internal/game/cmd_room_remove.go
+++ b/internal/game/cmd_room_remove.go
@@ -171,7 +171,7 @@ func (g *Game) roomRemove(sess *net.Session, args []string) {
Room: cID,
Condition: aExit.Condition,
BlockedMessage: aExit.BlockedMessage,
- SetFlags: aExit.SetFlags,
+ SetGlobalFlags: aExit.SetGlobalFlags,
SetPlayerFlags: aExit.SetPlayerFlags,
Hidden: aExit.Hidden,
AlwaysBlocked: aExit.AlwaysBlocked,
@@ -191,7 +191,7 @@ func (g *Game) roomRemove(sess *net.Session, args []string) {
Room: aID,
Condition: cOppExit.Condition,
BlockedMessage: cOppExit.BlockedMessage,
- SetFlags: cOppExit.SetFlags,
+ SetGlobalFlags: cOppExit.SetGlobalFlags,
SetPlayerFlags: cOppExit.SetPlayerFlags,
Hidden: cOppExit.Hidden,
AlwaysBlocked: cOppExit.AlwaysBlocked,
diff --git a/internal/game/cmd_setflag.go b/internal/game/cmd_setglobalflag.go
index a18c635..1ac5080 100644
--- a/internal/game/cmd_setflag.go
+++ b/internal/game/cmd_setglobalflag.go
@@ -7,13 +7,13 @@ import (
"thehouseoficarus/internal/net"
)
-func (g *Game) executeSetFlag(sess *net.Session, args []string, rawInput string) {
+func (g *Game) executeSetGlobalFlag(sess *net.Session, args []string, rawInput string) {
if !g.checkAdmin(sess) {
sess.WriteLine("Unknown command.")
return
}
if len(args) == 0 {
- sess.WriteLine("Usage: setflag <flag_name> [value]")
+ sess.WriteLine("Usage: setglobalflag <flag_name> [value]")
return
}
name := args[0]
@@ -33,6 +33,6 @@ func (g *Game) executeSetFlag(sess *net.Session, args []string, rawInput string)
}
}
}
- g.Flags.Set(name, value)
- sess.WriteLine(fmt.Sprintf("Flag '%s' set to %v.", name, value))
+ g.GlobalFlags.Set(name, value)
+ sess.WriteLine(fmt.Sprintf("Global flag '%s' set to %v.", name, value))
}
diff --git a/internal/game/condition_test.go b/internal/game/condition_test.go
index f365f2e..f7a5dc6 100644
--- a/internal/game/condition_test.go
+++ b/internal/game/condition_test.go
@@ -39,7 +39,7 @@ func TestIsTruthy(t *testing.T) {
}
func TestCheckConditionPlayerFlagTruthy(t *testing.T) {
- g := &Game{Flags: NewFlagStore()}
+ g := &Game{GlobalFlags: NewGlobalFlagStore()}
set := sessWithFlags(map[string]any{"x": true})
unset := sessWithFlags(map[string]any{})
@@ -73,7 +73,7 @@ func TestCheckConditionPlayerFlagTruthy(t *testing.T) {
}
func TestCheckConditionValueComparisonPreserved(t *testing.T) {
- g := &Game{Flags: NewFlagStore()}
+ g := &Game{GlobalFlags: NewGlobalFlagStore()}
sess := sessWithFlags(map[string]any{"n": 1})
if !g.checkCondition(sess, &behavior.Condition{PlayerFlag: "n", Value: 1}) {
@@ -87,24 +87,24 @@ func TestCheckConditionValueComparisonPreserved(t *testing.T) {
}
}
-func TestCheckConditionWorldFlag(t *testing.T) {
- g := &Game{Flags: NewFlagStore()}
- g.Flags.Set("gate_open", true)
+func TestCheckConditionGlobalFlag(t *testing.T) {
+ g := &Game{GlobalFlags: NewGlobalFlagStore()}
+ g.GlobalFlags.Set("gate_open", true)
sess := sessWithFlags(map[string]any{})
- if !g.checkCondition(sess, &behavior.Condition{Flag: "gate_open"}) {
- t.Error("world flag truthy check should pass")
+ if !g.checkCondition(sess, &behavior.Condition{GlobalFlag: "gate_open"}) {
+ t.Error("global flag truthy check should pass")
}
- if g.checkCondition(sess, &behavior.Condition{Flag: "gate_open", Not: true}) {
+ if g.checkCondition(sess, &behavior.Condition{GlobalFlag: "gate_open", Not: true}) {
t.Error("negated world flag should fail when set")
}
- if g.checkCondition(sess, &behavior.Condition{Flag: "missing"}) {
+ if g.checkCondition(sess, &behavior.Condition{GlobalFlag: "missing"}) {
t.Error("missing world flag should not pass")
}
}
func TestResolveObjDescPresence(t *testing.T) {
- g := &Game{Flags: NewFlagStore()}
+ g := &Game{GlobalFlags: NewGlobalFlagStore()}
def := &object.ObjectDef{
Description: behavior.DescList{
@@ -140,7 +140,7 @@ func TestResolveObjDescPresence(t *testing.T) {
}
func TestRoomDescriptionSelection(t *testing.T) {
- g := &Game{Flags: NewFlagStore()}
+ g := &Game{GlobalFlags: NewGlobalFlagStore()}
room := &world.Room{
Description: behavior.DescList{
{Text: "crowd", Condition: &behavior.Condition{PlayerFlag: "done", Not: true}},
diff --git a/internal/game/core_flagstore.go b/internal/game/core_flagstore.go
index ecefccf..18578b7 100644
--- a/internal/game/core_flagstore.go
+++ b/internal/game/core_flagstore.go
@@ -2,37 +2,37 @@ package game
import "sync"
-// FlagChangeCallback is invoked when a world flag value actually changes
+// GlobalFlagChangeCallback is invoked when a global flag value actually changes
// (old value differs from new, or new flag is created with a truthy value).
-type FlagChangeCallback func(name string, value any)
+type GlobalFlagChangeCallback func(name string, value any)
-// FlagStore holds world flags — shared mutable state visible to all players
-// (e.g. opened doors, quest state). Player-specific flags live on
-// *player.Player.Flags instead. FlagStore is safe for concurrent use.
-type FlagStore struct {
+// GlobalFlagStore holds global flags — shared mutable state visible to all
+// players (e.g. opened doors, quest state). Player-specific flags live on
+// *player.Player.Flags instead. GlobalFlagStore is safe for concurrent use.
+type GlobalFlagStore struct {
mu sync.Mutex
flags map[string]any
- callbacks []FlagChangeCallback
+ callbacks []GlobalFlagChangeCallback
}
-func NewFlagStore() *FlagStore {
- return &FlagStore{flags: make(map[string]any)}
+func NewGlobalFlagStore() *GlobalFlagStore {
+ return &GlobalFlagStore{flags: make(map[string]any)}
}
-func (f *FlagStore) OnChange(cb FlagChangeCallback) {
+func (f *GlobalFlagStore) OnChange(cb GlobalFlagChangeCallback) {
f.mu.Lock()
defer f.mu.Unlock()
f.callbacks = append(f.callbacks, cb)
}
-func (f *FlagStore) Get(name string) (any, bool) {
+func (f *GlobalFlagStore) Get(name string) (any, bool) {
f.mu.Lock()
defer f.mu.Unlock()
v, ok := f.flags[name]
return v, ok
}
-func (f *FlagStore) Set(name string, value any) {
+func (f *GlobalFlagStore) Set(name string, value any) {
f.mu.Lock()
old, existed := f.flags[name]
f.flags[name] = value
@@ -46,7 +46,7 @@ func (f *FlagStore) Set(name string, value any) {
}
}
-func (f *FlagStore) SetAll(m map[string]any) {
+func (f *GlobalFlagStore) SetAll(m map[string]any) {
f.mu.Lock()
changed := make(map[string]any)
for k, v := range m {
@@ -66,13 +66,13 @@ func (f *FlagStore) SetAll(m map[string]any) {
}
}
-func (f *FlagStore) Delete(name string) {
+func (f *GlobalFlagStore) Delete(name string) {
f.mu.Lock()
defer f.mu.Unlock()
delete(f.flags, name)
}
-func (f *FlagStore) All() map[string]any {
+func (f *GlobalFlagStore) All() map[string]any {
f.mu.Lock()
defer f.mu.Unlock()
out := make(map[string]any, len(f.flags))
diff --git a/internal/game/exit_discovery_test.go b/internal/game/exit_discovery_test.go
index 3c0b360..4bf1023 100644
--- a/internal/game/exit_discovery_test.go
+++ b/internal/game/exit_discovery_test.go
@@ -28,7 +28,7 @@ func TestExitDiscoveredUndiscovered(t *testing.T) {
}
func TestExitDiscoveredAfterMark(t *testing.T) {
- g := &Game{Flags: NewFlagStore()}
+ g := &Game{GlobalFlags: NewGlobalFlagStore()}
p := &player.Player{}
roomID := 42
dir := world.East
@@ -54,7 +54,7 @@ func TestExitDiscoveredGodMode(t *testing.T) {
}
func TestExitDiscoveredDifferentRoom(t *testing.T) {
- g := &Game{Flags: NewFlagStore()}
+ g := &Game{GlobalFlags: NewGlobalFlagStore()}
p := &player.Player{}
g.markExitDiscovered(p, 10, world.North)
@@ -67,7 +67,7 @@ func TestExitDiscoveredDifferentRoom(t *testing.T) {
}
func TestExitDisplayState(t *testing.T) {
- g := &Game{Flags: NewFlagStore()}
+ g := &Game{GlobalFlags: NewGlobalFlagStore()}
const roomID = 7
dir := world.North
diff --git a/internal/game/game.go b/internal/game/game.go
index bf7bdc2..b9fb0af 100644
--- a/internal/game/game.go
+++ b/internal/game/game.go
@@ -44,13 +44,13 @@ type Deps struct {
}
// Game is the central orchestrator: it owns the data stores (via the embedded
-// Deps), the shared mutable game state (flags, combat tracker, command queue,
+// Deps), the shared mutable game state (global flags, combat tracker, command queue,
// safespots), and the per-session runtime bookkeeping.
type Game struct {
Deps
Hub *net.Hub
- Flags *FlagStore
+ GlobalFlags *GlobalFlagStore
Combat *combat.Tracker
TriggerStore *world.TriggerStore
queue *CommandQueue
@@ -88,7 +88,7 @@ func New(dataDir string, colorConfig *config.ColorsConfig, valConfig config.Vali
ColorConfig: colorConfig,
DataDir: dataDir,
},
- Flags: NewFlagStore(),
+ GlobalFlags: NewGlobalFlagStore(),
Combat: combat.NewTracker(),
TriggerStore: world.NewTriggerStore(),
queue: NewCommandQueue(),
@@ -127,8 +127,8 @@ func (g *Game) SetHub(hub *net.Hub) {
}
}
})
- g.Flags.OnChange(func(name string, value any) {
- g.TriggerStore.FireWorld(name, value)
+ g.GlobalFlags.OnChange(func(name string, value any) {
+ g.TriggerStore.FireGlobal(name, value)
})
}
diff --git a/internal/game/map_test.go b/internal/game/map_test.go
index 159214c..2fe9c1e 100644
--- a/internal/game/map_test.go
+++ b/internal/game/map_test.go
@@ -29,10 +29,10 @@ func writeTempRoom(t *testing.T, dir string, id int, body string) {
// links draw a bar, one-way links draw a directional arrow, outward-blocked
// links draw a blocked 'X', and links with no traversable direction draw 'X'.
func TestMapConnectorGlyphs(t *testing.T) {
- const condEast = "name: One\nexits:\n east:\n room: 2\n condition:\n flag: gate_open\n"
- const condSouth = "name: Three\nexits:\n south:\n room: 2\n condition:\n flag: gate_open\n"
- const condNE = "name: One\nexits:\n northeast:\n room: 2\n condition:\n flag: gate_open\n"
- const condSE = "name: One\nexits:\n southeast:\n room: 2\n condition:\n flag: gate_open\n"
+ const condEast = "name: One\nexits:\n east:\n room: 2\n condition:\n global_flag: gate_open\n"
+ const condSouth = "name: Three\nexits:\n south:\n room: 2\n condition:\n global_flag: gate_open\n"
+ const condNE = "name: One\nexits:\n northeast:\n room: 2\n condition:\n global_flag: gate_open\n"
+ const condSE = "name: One\nexits:\n southeast:\n room: 2\n condition:\n global_flag: gate_open\n"
cases := []struct {
name string
@@ -161,9 +161,9 @@ func TestMapConnectorGlyphs(t *testing.T) {
writeTempRoom(t, dir, 4, tc.room4)
}
- g := &Game{Deps: Deps{World: world.New(dir)}, Flags: NewFlagStore()}
+ g := &Game{Deps: Deps{World: world.New(dir)}, GlobalFlags: NewGlobalFlagStore()}
if tc.flagOpen {
- g.Flags.Set("gate_open", true)
+ g.GlobalFlags.Set("gate_open", true)
}
sess := &net.Session{Player: &player.Player{Flags: map[string]any{}}}
@@ -401,7 +401,7 @@ func TestMap3DDisconnectedComponent(t *testing.T) {
writeTempRoom(t, dir, 3, "name: Tower Two Base\nexits:\n up: 4\n west: 2\n")
writeTempRoom(t, dir, 4, "name: Tower Two\nexits:\n down: 3\n")
- g := &Game{Deps: Deps{World: world.New(dir)}, Flags: NewFlagStore()}
+ g := &Game{Deps: Deps{World: world.New(dir)}, GlobalFlags: NewGlobalFlagStore()}
mg := mapGlyphsForPlayer(false)
// Player has only visited tower 1. Tower 2 should appear but dimmed (unvisited).
@@ -426,7 +426,7 @@ func TestMap3DDifferentZExcluded(t *testing.T) {
writeTempRoom(t, dir, 1, "name: Ground\nexits:\n up: 2\n")
writeTempRoom(t, dir, 2, "name: Upper\nexits:\n down: 1\n")
- g := &Game{Deps: Deps{World: world.New(dir)}, Flags: NewFlagStore()}
+ g := &Game{Deps: Deps{World: world.New(dir)}, GlobalFlags: NewGlobalFlagStore()}
mg := mapGlyphsForPlayer(false)
sess := &net.Session{Player: &player.Player{
Stats: player.PlayerStats{RoomsVisited: map[int]bool{1: true, 2: true}},
diff --git a/internal/game/sys_triggers.go b/internal/game/sys_triggers.go
index 7c77fc9..b542fdd 100644
--- a/internal/game/sys_triggers.go
+++ b/internal/game/sys_triggers.go
@@ -13,7 +13,7 @@ import (
func (g *Game) TriggerSeqTick() {
g.processPlayerTriggerSequences()
- g.processWorldTriggerSequences()
+ g.processGlobalTriggerSequences()
}
func (g *Game) TransientMobTick() {
@@ -106,8 +106,8 @@ func (g *Game) processPlayerTriggerSequences() {
}
}
-func (g *Game) processWorldTriggerSequences() {
- seqs := g.TriggerStore.SnapshotWorldSeqs()
+func (g *Game) processGlobalTriggerSequences() {
+ seqs := g.TriggerStore.SnapshotGlobalSeqs()
for _, seq := range seqs {
seq.Wait--
if seq.Wait > 0 {
@@ -125,11 +125,11 @@ func (g *Game) processWorldTriggerSequences() {
}
for _, step := range jobs {
- g.executeWorldTriggerStep(&step, seq.RoomID, seq.FlagValue)
+ g.executeGlobalTriggerStep(&step, seq.RoomID, seq.FlagValue)
}
if len(seq.Steps) == 0 {
- g.TriggerStore.RemoveWorldSeq(seq.TriggerID)
+ g.TriggerStore.RemoveGlobalSeq(seq.TriggerID)
}
}
}
@@ -161,8 +161,8 @@ func (g *Game) executeTriggerStep(sess *net.Session, p *player.Player, step *wor
}
}
}
- if len(step.SetFlags) > 0 {
- g.Flags.SetAll(step.SetFlags)
+ if len(step.SetGlobalFlags) > 0 {
+ g.GlobalFlags.SetAll(step.SetGlobalFlags)
}
if len(step.SetPlayerFlags) > 0 {
for k, v := range step.SetPlayerFlags {
@@ -204,7 +204,7 @@ func (g *Game) executeTriggerStep(sess *net.Session, p *player.Player, step *wor
}
}
-func (g *Game) executeWorldTriggerStep(step *world.TriggerStep, roomID int, flagValue any) {
+func (g *Game) executeGlobalTriggerStep(step *world.TriggerStep, roomID int, flagValue any) {
if step.Broadcast != "" && g.Hub != nil {
msg := expandTemplate(step.Broadcast, "", flagValue)
broadcastSpec := g.resolveColor(nil, "broadcast")
@@ -225,8 +225,8 @@ func (g *Game) executeWorldTriggerStep(step *world.TriggerStep, roomID int, flag
}
}
}
- if len(step.SetFlags) > 0 {
- g.Flags.SetAll(step.SetFlags)
+ if len(step.SetGlobalFlags) > 0 {
+ g.GlobalFlags.SetAll(step.SetGlobalFlags)
}
if step.SpawnMob != nil {
g.spawnWorldTriggerMob(step.SpawnMob, roomID)
diff --git a/internal/player/player.go b/internal/player/player.go
index 72eb455..65026e7 100644
--- a/internal/player/player.go
+++ b/internal/player/player.go
@@ -183,7 +183,7 @@ type Player struct {
MoveTicks int `yaml:"-"`
MoveDirection string `yaml:"-"`
MoveTarget int `yaml:"-"`
- MovePendingFlags map[string]any `yaml:"-"`
+ MovePendingGlobalFlags map[string]any `yaml:"-"`
MovePendingPlayerFlags map[string]any `yaml:"-"`
VisualTickCurrent int `yaml:"-"`
AutotriggerMod string `yaml:"-"`
@@ -219,7 +219,7 @@ func (p *Player) ClearMoveState() {
p.MoveTicks = 0
p.MoveDirection = ""
p.MoveTarget = 0
- p.MovePendingFlags = nil
+ p.MovePendingGlobalFlags = nil
p.MovePendingPlayerFlags = nil
}
diff --git a/internal/world/grid_test.go b/internal/world/grid_test.go
index 04d749c..9c2c7c6 100644
--- a/internal/world/grid_test.go
+++ b/internal/world/grid_test.go
@@ -117,11 +117,11 @@ func TestBuildGridConflictsHypotheticalInsert(t *testing.T) {
copy.Exits = make(map[ExitDir]ExitDef, len(r.Exits))
for k, v := range r.Exits {
if id == 1 && k == East {
- copy.Exits[k] = ExitDef{Room: 5, Condition: v.Condition, BlockedMessage: v.BlockedMessage, SetFlags: v.SetFlags, SetPlayerFlags: v.SetPlayerFlags, Hidden: v.Hidden, AlwaysBlocked: v.AlwaysBlocked}
+ copy.Exits[k] = ExitDef{Room: 5, Condition: v.Condition, BlockedMessage: v.BlockedMessage, SetGlobalFlags: v.SetGlobalFlags, SetPlayerFlags: v.SetPlayerFlags, Hidden: v.Hidden, AlwaysBlocked: v.AlwaysBlocked}
continue
}
if id == 2 && k == West {
- copy.Exits[k] = ExitDef{Room: 5, Condition: v.Condition, BlockedMessage: v.BlockedMessage, SetFlags: v.SetFlags, SetPlayerFlags: v.SetPlayerFlags, Hidden: v.Hidden, AlwaysBlocked: v.AlwaysBlocked}
+ copy.Exits[k] = ExitDef{Room: 5, Condition: v.Condition, BlockedMessage: v.BlockedMessage, SetGlobalFlags: v.SetGlobalFlags, SetPlayerFlags: v.SetPlayerFlags, Hidden: v.Hidden, AlwaysBlocked: v.AlwaysBlocked}
continue
}
copy.Exits[k] = v
diff --git a/internal/world/insert_remove.go b/internal/world/insert_remove.go
index 0811587..c55427c 100644
--- a/internal/world/insert_remove.go
+++ b/internal/world/insert_remove.go
@@ -20,7 +20,7 @@ func RewirePreserving(src ExitDef, newTarget int) ExitDef {
Room: newTarget,
Condition: src.Condition,
BlockedMessage: src.BlockedMessage,
- SetFlags: src.SetFlags,
+ SetGlobalFlags: src.SetGlobalFlags,
SetPlayerFlags: src.SetPlayerFlags,
Hidden: src.Hidden,
AlwaysBlocked: src.AlwaysBlocked,
diff --git a/internal/world/room.go b/internal/world/room.go
index 29cce0b..2da40fb 100644
--- a/internal/world/room.go
+++ b/internal/world/room.go
@@ -78,7 +78,7 @@ type ExitDef struct {
Room int `yaml:"room"`
Condition *behavior.Condition `yaml:"condition,omitempty"`
BlockedMessage string `yaml:"blocked_message,omitempty"`
- SetFlags map[string]any `yaml:"set_flags,omitempty"`
+ SetGlobalFlags map[string]any `yaml:"set_global_flags,omitempty"`
SetPlayerFlags map[string]any `yaml:"set_player_flags,omitempty"`
Hidden bool `yaml:"hidden,omitempty"`
AlwaysBlocked bool `yaml:"always_blocked,omitempty"`
@@ -135,7 +135,7 @@ type EnterStep struct {
Message string `yaml:"message"`
Condition *behavior.Condition `yaml:"condition"`
Delay int `yaml:"delay"`
- SetFlags map[string]any `yaml:"set_flags"`
+ SetGlobalFlags map[string]any `yaml:"set_global_flags"`
SetPlayerFlags map[string]any `yaml:"set_player_flags"`
Broadcast string `yaml:"broadcast"`
BroadcastGlobal string `yaml:"broadcast_global"`
@@ -151,7 +151,7 @@ type EnterStep struct {
// non-zero field means it needs per-tick scheduling rather than synchronous
// printing).
func (e EnterStep) IsTimed() bool {
- return e.Delay > 0 || len(e.SetFlags) > 0 || len(e.SetPlayerFlags) > 0 ||
+ return e.Delay > 0 || len(e.SetGlobalFlags) > 0 || len(e.SetPlayerFlags) > 0 ||
e.Message != "" || e.Broadcast != "" || e.BroadcastGlobal != "" ||
e.SpawnMob != nil || e.DespawnMob != "" || e.GiveItem != "" ||
e.TakeItem != "" || e.Teleport != 0 || e.Heal != 0
diff --git a/internal/world/room_migrate_test.go b/internal/world/room_migrate_test.go
index b035172..5696a36 100644
--- a/internal/world/room_migrate_test.go
+++ b/internal/world/room_migrate_test.go
@@ -5,7 +5,7 @@ import "testing"
func TestRoomRewriteRoomIDs(t *testing.T) {
r := &Room{
Exits: map[ExitDir]ExitDef{
- North: {Room: 10, SetFlags: map[string]any{"last": 10}},
+ North: {Room: 10, SetGlobalFlags: map[string]any{"last": 10}},
South: {Room: 99},
},
Triggers: []TriggerDef{
@@ -43,8 +43,8 @@ func TestRoomRewriteRoomIDs(t *testing.T) {
// Author set_flags values are NOT structural room references and must not
// be remapped (the old swapid regex wrongly rewrote these).
- if v := r.Exits[North].SetFlags["last"]; v != 10 {
- t.Errorf("set_flags value remapped: got %v, want 10", v)
+ if v := r.Exits[North].SetGlobalFlags["last"]; v != 10 {
+ t.Errorf("set_global_flags value remapped: got %v, want 10", v)
}
if r.Triggers[0].Room != 31 {
diff --git a/internal/world/trigger.go b/internal/world/trigger.go
index 8e74ff7..e31a5f9 100644
--- a/internal/world/trigger.go
+++ b/internal/world/trigger.go
@@ -7,7 +7,7 @@ import (
type TriggerDef struct {
ID string `yaml:"id"`
OnPlayerFlag string `yaml:"on_player_flag"`
- OnFlag string `yaml:"on_flag"`
+ OnGlobalFlag string `yaml:"on_global_flag"`
Value any `yaml:"value"`
Room int `yaml:"room"`
Steps []TriggerStep `yaml:"steps"`
@@ -15,14 +15,14 @@ type TriggerDef struct {
func (t *TriggerDef) IsPlayerFlagTrigger() bool { return t.OnPlayerFlag != "" }
-func (t *TriggerDef) IsWorldFlagTrigger() bool { return t.OnFlag != "" }
+func (t *TriggerDef) IsGlobalFlagTrigger() bool { return t.OnGlobalFlag != "" }
type TriggerStep struct {
Delay int `yaml:"delay"`
Message string `yaml:"message"`
Broadcast string `yaml:"broadcast"`
BroadcastGlobal string `yaml:"broadcast_global"`
- SetFlags map[string]any `yaml:"set_flags"`
+ SetGlobalFlags map[string]any `yaml:"set_global_flags"`
SetPlayerFlags map[string]any `yaml:"set_player_flags"`
SpawnMob *SpawnMobConfig `yaml:"spawn_mob"`
GiveItem string `yaml:"give_item"`
@@ -54,7 +54,7 @@ func (s *SpawnMobConfig) UnmarshalYAML(value *yaml.Node) error {
}
func (t TriggerStep) IsTimed() bool {
- return t.Delay > 0 || len(t.SetFlags) > 0 || len(t.SetPlayerFlags) > 0 ||
+ return t.Delay > 0 || len(t.SetGlobalFlags) > 0 || len(t.SetPlayerFlags) > 0 ||
t.Message != "" || t.Broadcast != "" || t.BroadcastGlobal != "" ||
t.SpawnMob != nil || t.GiveItem != "" || t.TakeItem != "" ||
t.Teleport != 0 || t.Heal != 0 || t.DespawnMob != ""
diff --git a/internal/world/trigger_store.go b/internal/world/trigger_store.go
index b5fac5b..e18ae80 100644
--- a/internal/world/trigger_store.go
+++ b/internal/world/trigger_store.go
@@ -14,12 +14,12 @@ type TriggerStore struct {
mu sync.Mutex
globalByPlayerFlag map[string][]*TriggerDef
- globalByWorldFlag map[string][]*TriggerDef
+ globalByGlobalFlag map[string][]*TriggerDef
roomByPlayerFlag map[int]map[string][]*TriggerDef
- roomByWorldFlag map[int]map[string][]*TriggerDef
+ roomByGlobalFlag map[int]map[string][]*TriggerDef
playerSeqs map[string]*PlayerTriggerSeq
- worldSeqs map[string]*WorldTriggerSeq
+ globalSeqs map[string]*GlobalTriggerSeq
}
type PlayerTriggerSeq struct {
@@ -32,7 +32,7 @@ type PlayerTriggerSeq struct {
FlagValue any
}
-type WorldTriggerSeq struct {
+type GlobalTriggerSeq struct {
TriggerID string
RoomID int
Steps []TriggerStep
@@ -43,11 +43,11 @@ type WorldTriggerSeq struct {
func NewTriggerStore() *TriggerStore {
return &TriggerStore{
globalByPlayerFlag: make(map[string][]*TriggerDef),
- globalByWorldFlag: make(map[string][]*TriggerDef),
+ globalByGlobalFlag: make(map[string][]*TriggerDef),
roomByPlayerFlag: make(map[int]map[string][]*TriggerDef),
- roomByWorldFlag: make(map[int]map[string][]*TriggerDef),
+ roomByGlobalFlag: make(map[int]map[string][]*TriggerDef),
playerSeqs: make(map[string]*PlayerTriggerSeq),
- worldSeqs: make(map[string]*WorldTriggerSeq),
+ globalSeqs: make(map[string]*GlobalTriggerSeq),
}
}
@@ -55,9 +55,9 @@ func (ts *TriggerStore) ClearTriggers() {
ts.mu.Lock()
defer ts.mu.Unlock()
ts.globalByPlayerFlag = make(map[string][]*TriggerDef)
- ts.globalByWorldFlag = make(map[string][]*TriggerDef)
+ ts.globalByGlobalFlag = make(map[string][]*TriggerDef)
ts.roomByPlayerFlag = make(map[int]map[string][]*TriggerDef)
- ts.roomByWorldFlag = make(map[int]map[string][]*TriggerDef)
+ ts.roomByGlobalFlag = make(map[int]map[string][]*TriggerDef)
}
func (ts *TriggerStore) LoadGlobal(dataDir string) error {
@@ -110,13 +110,13 @@ func (ts *TriggerStore) SeedRoomTriggers(roomID int, triggers []TriggerDef) {
ts.roomByPlayerFlag[roomID][t.OnPlayerFlag] = append(
ts.roomByPlayerFlag[roomID][t.OnPlayerFlag], t)
}
- if t.IsWorldFlagTrigger() {
- if ts.roomByWorldFlag[roomID] == nil {
- ts.roomByWorldFlag[roomID] = make(map[string][]*TriggerDef)
+ if t.IsGlobalFlagTrigger() {
+ if ts.roomByGlobalFlag[roomID] == nil {
+ ts.roomByGlobalFlag[roomID] = make(map[string][]*TriggerDef)
}
t.Room = roomID
- ts.roomByWorldFlag[roomID][t.OnFlag] = append(
- ts.roomByWorldFlag[roomID][t.OnFlag], t)
+ ts.roomByGlobalFlag[roomID][t.OnGlobalFlag] = append(
+ ts.roomByGlobalFlag[roomID][t.OnGlobalFlag], t)
}
}
}
@@ -128,9 +128,9 @@ func (ts *TriggerStore) addGlobal(t *TriggerDef) {
ts.globalByPlayerFlag[t.OnPlayerFlag] = append(
ts.globalByPlayerFlag[t.OnPlayerFlag], t)
}
- if t.IsWorldFlagTrigger() {
- ts.globalByWorldFlag[t.OnFlag] = append(
- ts.globalByWorldFlag[t.OnFlag], t)
+ if t.IsGlobalFlagTrigger() {
+ ts.globalByGlobalFlag[t.OnGlobalFlag] = append(
+ ts.globalByGlobalFlag[t.OnGlobalFlag], t)
}
}
@@ -184,23 +184,23 @@ func (ts *TriggerStore) FirePlayerInRoom(playerName string, roomID int, flagName
return started
}
-func (ts *TriggerStore) FireWorld(flagName string, flagValue any) []*WorldTriggerSeq {
+func (ts *TriggerStore) FireGlobal(flagName string, flagValue any) []*GlobalTriggerSeq {
ts.mu.Lock()
defer ts.mu.Unlock()
- var started []*WorldTriggerSeq
+ var started []*GlobalTriggerSeq
- for _, t := range ts.globalByWorldFlag[flagName] {
+ for _, t := range ts.globalByGlobalFlag[flagName] {
if !ts.valueMatches(t.Value, flagValue) {
continue
}
- seq := ts.startWorldSeqLocked(t, flagValue)
+ seq := ts.startGlobalSeqLocked(t, flagValue)
if seq != nil {
started = append(started, seq)
}
}
- for roomID, roomFlags := range ts.roomByWorldFlag {
+ for roomID, roomFlags := range ts.roomByGlobalFlag {
for _, t := range roomFlags[flagName] {
if !ts.valueMatches(t.Value, flagValue) {
continue
@@ -208,7 +208,7 @@ func (ts *TriggerStore) FireWorld(flagName string, flagValue any) []*WorldTrigge
if t.Room == 0 {
t.Room = roomID
}
- seq := ts.startWorldSeqLocked(t, flagValue)
+ seq := ts.startGlobalSeqLocked(t, flagValue)
if seq != nil {
started = append(started, seq)
}
@@ -238,12 +238,12 @@ func (ts *TriggerStore) startPlayerSeqLocked(playerName string, t *TriggerDef, r
return seq
}
-func (ts *TriggerStore) startWorldSeqLocked(t *TriggerDef, flagValue any) *WorldTriggerSeq {
+func (ts *TriggerStore) startGlobalSeqLocked(t *TriggerDef, flagValue any) *GlobalTriggerSeq {
key := t.ID
- if _, exists := ts.worldSeqs[key]; exists {
+ if _, exists := ts.globalSeqs[key]; exists {
return nil
}
- seq := &WorldTriggerSeq{
+ seq := &GlobalTriggerSeq{
TriggerID: t.ID,
RoomID: t.Room,
Steps: make([]TriggerStep, len(t.Steps)),
@@ -253,7 +253,7 @@ func (ts *TriggerStore) startWorldSeqLocked(t *TriggerDef, flagValue any) *World
if len(seq.Steps) > 0 {
seq.Wait = seq.Steps[0].Delay
}
- ts.worldSeqs[key] = seq
+ ts.globalSeqs[key] = seq
return seq
}
@@ -274,11 +274,11 @@ func (ts *TriggerStore) SnapshotPlayerSeqs() []*PlayerTriggerSeq {
return out
}
-func (ts *TriggerStore) SnapshotWorldSeqs() []*WorldTriggerSeq {
+func (ts *TriggerStore) SnapshotGlobalSeqs() []*GlobalTriggerSeq {
ts.mu.Lock()
defer ts.mu.Unlock()
- out := make([]*WorldTriggerSeq, 0, len(ts.worldSeqs))
- for _, s := range ts.worldSeqs {
+ out := make([]*GlobalTriggerSeq, 0, len(ts.globalSeqs))
+ for _, s := range ts.globalSeqs {
out = append(out, s)
}
return out
@@ -291,10 +291,10 @@ func (ts *TriggerStore) RemovePlayerSeq(playerName, triggerID string) {
delete(ts.playerSeqs, key)
}
-func (ts *TriggerStore) RemoveWorldSeq(triggerID string) {
+func (ts *TriggerStore) RemoveGlobalSeq(triggerID string) {
ts.mu.Lock()
defer ts.mu.Unlock()
- delete(ts.worldSeqs, triggerID)
+ delete(ts.globalSeqs, triggerID)
}
func (ts *TriggerStore) AllGlobalTriggers() []*TriggerDef {
@@ -304,7 +304,7 @@ func (ts *TriggerStore) AllGlobalTriggers() []*TriggerDef {
for _, triggers := range ts.globalByPlayerFlag {
out = append(out, triggers...)
}
- for _, triggers := range ts.globalByWorldFlag {
+ for _, triggers := range ts.globalByGlobalFlag {
out = append(out, triggers...)
}
return out
@@ -340,7 +340,7 @@ func (ts *TriggerStore) AllRoomTriggers() map[int][]*TriggerDef {
out[roomID] = append(out[roomID], triggers...)
}
}
- for roomID, byFlag := range ts.roomByWorldFlag {
+ for roomID, byFlag := range ts.roomByGlobalFlag {
for _, triggers := range byFlag {
out[roomID] = append(out[roomID], triggers...)
}