1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
|
package game
import (
"testing"
"thehouseoficarus/internal/behavior"
"thehouseoficarus/internal/net"
"thehouseoficarus/internal/player"
"thehouseoficarus/internal/world"
)
func TestDiscoveredExitFlagKey(t *testing.T) {
key := discoveredExitFlag(2001, world.North)
if key != "hidden_exit_2001_north" {
t.Errorf("unexpected flag key: %q", key)
}
key = discoveredExitFlag(100, world.Down)
if key != "hidden_exit_100_down" {
t.Errorf("unexpected flag key: %q", key)
}
}
func TestExitDiscoveredUndiscovered(t *testing.T) {
p := &player.Player{}
if g := (&Game{}).exitDiscovered(p, 42, world.East); g {
t.Error("expected undiscovered to be false")
}
}
func TestExitDiscoveredAfterMark(t *testing.T) {
g := &Game{GlobalFlags: NewGlobalFlagStore()}
p := &player.Player{}
roomID := 42
dir := world.East
flagKey := discoveredExitFlag(roomID, dir)
if g.exitDiscovered(p, roomID, dir) {
t.Error("should not be discovered before marking")
}
g.markExitDiscovered(p, roomID, dir)
if !g.exitDiscovered(p, roomID, dir) {
t.Error("should be discovered after marking")
}
if getPlayerFlagInt(p, flagKey) == 0 {
t.Error("flag should be set after marking")
}
}
func TestExitDiscoveredGodMode(t *testing.T) {
p := &player.Player{GodMode: true}
if !(&Game{}).exitDiscovered(p, 99, world.South) {
t.Error("god mode should always see exits as discovered")
}
}
func TestExitDiscoveredDifferentRoom(t *testing.T) {
g := &Game{GlobalFlags: NewGlobalFlagStore()}
p := &player.Player{}
g.markExitDiscovered(p, 10, world.North)
if g.exitDiscovered(p, 10, world.East) {
t.Error("discovering north should not mark east as discovered")
}
if g.exitDiscovered(p, 20, world.North) {
t.Error("discovering room 10 north should not mark room 20 north")
}
}
func TestExitDisplayState(t *testing.T) {
g := &Game{GlobalFlags: NewGlobalFlagStore()}
const roomID = 7
dir := world.North
// {player_flag: open} — passes when "open" is set, fails otherwise.
openCond := &behavior.Condition{PlayerFlag: "open"}
hiddenDiscoveredSess := sessWithFlags(map[string]any{discoveredExitFlag(roomID, dir): 1})
openSess := sessWithFlags(map[string]any{"open": true})
closedSess := sessWithFlags(map[string]any{})
godSess := sessWithFlags(map[string]any{})
assertDisp := func(name string, sess *net.Session, exit world.ExitDef, wantVisible, wantBlocked, wantTagHidden bool) {
t.Helper()
ed := g.exitDisplayState(sess, roomID, dir, exit)
if ed.Visible != wantVisible || ed.Blocked != wantBlocked || ed.TagHidden != wantTagHidden {
t.Errorf("%s: got {Visible:%v Blocked:%v TagHidden:%v}, want {Visible:%v Blocked:%v TagHidden:%v}",
name, ed.Visible, ed.Blocked, ed.TagHidden, wantVisible, wantBlocked, wantTagHidden)
}
}
// Plain open exit: visible, not blocked, not hidden.
assertDisp("plain", openSess, world.ExitDef{Room: 1}, true, false, false)
// Hidden + undiscovered: absent.
assertDisp("hidden-undiscovered", closedSess, world.ExitDef{Room: 1, Hidden: true}, false, false, false)
// Hidden + discovered: visible, tagged hidden, not blocked.
assertDisp("hidden-discovered", hiddenDiscoveredSess, world.ExitDef{Room: 1, Hidden: true}, true, false, true)
// Hidden + god: god discovers — visible, tagged hidden.
godSess.Player.GodMode = true
assertDisp("hidden-god", godSess, world.ExitDef{Room: 1, Hidden: true}, true, false, true)
godSess.Player.GodMode = false
// always_blocked (non-god): visible, blocked, condition ignored.
assertDisp("always-blocked", closedSess, world.ExitDef{Room: 1, AlwaysBlocked: true}, true, true, false)
// always_blocked + a PASSING condition still blocks (condition not evaluated).
assertDisp("always-blocked-over-passing-cond", openSess, world.ExitDef{Room: 1, AlwaysBlocked: true, Condition: openCond}, true, true, false)
// always_blocked + god: not blocked (god bypass).
godSess.Player.GodMode = true
assertDisp("always-blocked-god", godSess, world.ExitDef{Room: 1, AlwaysBlocked: true}, true, false, false)
godSess.Player.GodMode = false
// Condition failing (no always_blocked): blocked.
assertDisp("cond-failing", closedSess, world.ExitDef{Room: 1, Condition: openCond}, true, true, false)
// Condition passing: not blocked.
assertDisp("cond-passing", openSess, world.ExitDef{Room: 1, Condition: openCond}, true, false, false)
// Condition failing + god: not blocked (god bypass).
godSess.Player.GodMode = true
assertDisp("cond-failing-god", godSess, world.ExitDef{Room: 1, Condition: openCond}, true, false, false)
godSess.Player.GodMode = false
// nil session (background render): non-hidden visible & not blocked;
// hidden absent (no player to have discovered it).
assertDisp("nil-sess-plain", nil, world.ExitDef{Room: 1}, true, false, false)
assertDisp("nil-sess-hidden", nil, world.ExitDef{Room: 1, Hidden: true}, false, false, false)
}
|