diff options
| author | historia <[not public]> | 2026-07-06 23:05:04 -0400 |
|---|---|---|
| committer | historia <[not public]> | 2026-07-06 23:05:04 -0400 |
| commit | 9292634f2f8d71a53879ff07e1330c671b207d51 (patch) | |
| tree | dcffadf7f697e8ad0705d787d8f599bdeeedb812 /internal/world | |
| parent | 911aae15f4e869c93239ef7c630c61e1d9d4ef3f (diff) | |
| download | thehouseoficarus-9292634f2f8d71a53879ff07e1330c671b207d51.tar.gz | |
feat: split the concept of hidden and impassable exits. add player_flag for discovered hidden exits.
Diffstat (limited to 'internal/world')
| -rw-r--r-- | internal/world/grid.go | 5 | ||||
| -rw-r--r-- | internal/world/room.go | 1 | ||||
| -rw-r--r-- | internal/world/room_test.go | 44 |
3 files changed, 49 insertions, 1 deletions
diff --git a/internal/world/grid.go b/internal/world/grid.go index 837f737..2ea897a 100644 --- a/internal/world/grid.go +++ b/internal/world/grid.go @@ -32,12 +32,15 @@ type RoomGrid struct { // are then not followed, but any coordinate already assigned to it stands. // - include, when non-nil, restricts placement to targets for which it returns // true (pass nil to place every reachable target). +// - edgeInclude, when non-nil, restricts traversal to exits for which it +// returns true (pass nil to follow every exit whose target passes include). +// It receives (fromRoomID, dir, targetRoomID) and is checked before include. // - onConflict, when non-nil, is called for each twist/overlap encountered. // // The first assignment to a room or cell always wins; conflicting placements are // skipped. In a world that passes grid validation there are no conflicts, so the // layout is unambiguous. -func BuildGrid(seed int, load func(int) (*Room, bool), include func(int) bool, onConflict func(GridConflict)) RoomGrid { +func BuildGrid(seed int, load func(int) (*Room, bool), include func(int) bool, edgeInclude func(int, ExitDir, int) bool, onConflict func(GridConflict)) RoomGrid { g := RoomGrid{ Coord: map[int][3]int{seed: {0, 0, 0}}, RoomAt: map[[3]int]int{{0, 0, 0}: seed}, diff --git a/internal/world/room.go b/internal/world/room.go index 8843b9e..29cce0b 100644 --- a/internal/world/room.go +++ b/internal/world/room.go @@ -81,6 +81,7 @@ type ExitDef struct { SetFlags map[string]any `yaml:"set_flags,omitempty"` SetPlayerFlags map[string]any `yaml:"set_player_flags,omitempty"` Hidden bool `yaml:"hidden,omitempty"` + AlwaysBlocked bool `yaml:"always_blocked,omitempty"` } func (e *ExitDef) UnmarshalYAML(value *yaml.Node) error { diff --git a/internal/world/room_test.go b/internal/world/room_test.go index e7b1718..1ad974e 100644 --- a/internal/world/room_test.go +++ b/internal/world/room_test.go @@ -4,6 +4,8 @@ import ( "os" "path/filepath" "testing" + + "gopkg.in/yaml.v3" ) func writeRoom(t *testing.T, dir string, body string) { @@ -90,3 +92,45 @@ func TestNormalizeObjectName(t *testing.T) { } } } + +func TestExitDefUnmarshalAlwaysBlocked(t *testing.T) { + y := `exits: + north: + room: 5 + always_blocked: true + south: 3 + east: + room: 7 + hidden: true +` + var room struct { + Exits map[ExitDir]ExitDef `yaml:"exits"` + } + if err := yaml.Unmarshal([]byte(y), &room); err != nil { + t.Fatalf("unmarshal: %v", err) + } + if len(room.Exits) != 3 { + t.Fatalf("expected 3 exits, got %d", len(room.Exits)) + } + n := room.Exits[North] + if !n.AlwaysBlocked { + t.Error("north exit should have AlwaysBlocked=true") + } + if n.Room != 5 { + t.Errorf("north target = %d, want 5", n.Room) + } + s := room.Exits[South] + if s.Room != 3 { + t.Errorf("south target = %d, want 3", s.Room) + } + if s.AlwaysBlocked { + t.Error("south exit should not have AlwaysBlocked") + } + e := room.Exits[East] + if !e.Hidden { + t.Error("east exit should have Hidden=true") + } + if e.AlwaysBlocked { + t.Error("east exit should not have AlwaysBlocked") + } +} |
