diff options
| author | historia <[not public]> | 2026-07-07 00:22:32 -0400 |
|---|---|---|
| committer | historia <[not public]> | 2026-07-07 00:22:32 -0400 |
| commit | a51f7a53aa2c487ebf94ba0363038574ae8bb590 (patch) | |
| tree | b393a8f9e4732b40f6fe8058d086bd631537ad3b /internal/game/exit_display.go | |
| parent | 9292634f2f8d71a53879ff07e1330c671b207d51 (diff) | |
| download | thehouseoficarus-a51f7a53aa2c487ebf94ba0363038574ae8bb590.tar.gz | |
feat: hidden exits (and related flags) work with commands that change room ids. exit code simplified and unified between impassable and blocked exits.
Diffstat (limited to 'internal/game/exit_display.go')
| -rw-r--r-- | internal/game/exit_display.go | 56 |
1 files changed, 56 insertions, 0 deletions
diff --git a/internal/game/exit_display.go b/internal/game/exit_display.go new file mode 100644 index 0000000..4540669 --- /dev/null +++ b/internal/game/exit_display.go @@ -0,0 +1,56 @@ +package game + +import ( + "thehouseoficarus/internal/net" + "thehouseoficarus/internal/world" +) + +// exitDisplay summarizes how an exit appears to a player: whether it is listed +// at all (and traversable by the map BFS / walk pathfinder), whether movement +// is refused (and the look listing should tag it "(blocked)"), and whether the +// listing should tag it "(HIDDEN)". +// +// It is the single source of truth shared by the look listing, the standalone +// `exits` command, `look <direction>`, movement, the map connector state, the +// `verbs` command, and the walk pathfinder — replacing the per-callsite inline +// checks that previously disagreed (e.g. gods saw a "(blocked)" tag in look +// even though they can traverse and the map renders the link open). +// +// Semantics: +// - Hidden exit: visible only once discovered (gods always discover). When +// visible it is tagged "(HIDDEN)". A nil player (background render) never +// discovers, so hidden exits are absent. +// - God mode: exits are visible and never blocked (matches map rendering). +// - always_blocked: absolute — blocks movement/listing/map regardless of any +// condition. The condition is NOT evaluated when always_blocked is set. +// - condition: blocks when present and failing for this player. +type exitDisplay struct { + Visible bool + Blocked bool + TagHidden bool +} + +func (g *Game) exitDisplayState(sess *net.Session, roomID int, dir world.ExitDir, exit world.ExitDef) exitDisplay { + var ed exitDisplay + p := sessPlayer(sess) + if exit.Hidden { + // exitDiscovered already returns true for gods; nil player never discovers. + if p != nil && g.exitDiscovered(p, roomID, dir) { + ed.Visible = true + ed.TagHidden = true + } + return ed + } + ed.Visible = true + if p == nil || p.GodMode { + return ed + } + if exit.AlwaysBlocked { + ed.Blocked = true + return ed + } + if exit.Condition != nil && !g.checkCondition(sess, exit.Condition) { + ed.Blocked = true + } + return ed +} |
