aboutsummaryrefslogtreecommitdiff
path: root/internal/game/exit_display.go
diff options
context:
space:
mode:
authorhistoria <[not public]>2026-07-07 00:22:32 -0400
committerhistoria <[not public]>2026-07-07 00:22:32 -0400
commita51f7a53aa2c487ebf94ba0363038574ae8bb590 (patch)
treeb393a8f9e4732b40f6fe8058d086bd631537ad3b /internal/game/exit_display.go
parent9292634f2f8d71a53879ff07e1330c671b207d51 (diff)
downloadthehouseoficarus-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.go56
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
+}