diff options
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 +} |
