package world import ( "testing" "thehouseoficarus/internal/behavior" ) func TestRoomRewriteRoomIDs(t *testing.T) { r := &Room{ Exits: map[ExitDir]ExitDef{ North: { Room: 10, OnTraverse: []behavior.Trigger{{ Condition: &behavior.Condition{Room: 60}, // projectile, ensures trigger-condition Room remaps too Steps: []behavior.Step{{ SetGlobalFlags: map[string]any{"last": 10}, Teleport: 110, }}, }}, Condition: &behavior.Condition{Room: 40}, }, South: {Room: 99}, }, OnEnter: []behavior.Trigger{{ Condition: &behavior.Condition{Room: 20}, Steps: []behavior.Step{{ Teleport: 70, SpawnMob: &behavior.SpawnMobConfig{DespawnRooms: []int{80}}, }}, }}, OnExit: []behavior.Trigger{{ Steps: []behavior.Step{{Teleport: 50}}, }}, Mobs: []RoomMob{ {ID: "guard", WanderRooms: []int{90, 100}}, }, } idMap := map[int]int{ 10: 11, 20: 21, 40: 41, 50: 51, 60: 61, 70: 71, 80: 81, 90: 91, 100: 101, 110: 111, } if !r.RewriteRoomIDs(idMap) { t.Fatal("expected changed=true") } if got := r.Exits[North].Room; got != 11 { t.Errorf("exit north room = %d, want 11", got) } if got := r.Exits[South].Room; got != 99 { t.Errorf("exit south room = %d, want 99 (unchanged)", got) } // Author set_flags values are NOT structural room references and must not remap. if v := r.Exits[North].OnTraverse[0].Steps[0].SetGlobalFlags["last"]; v != 10 { t.Errorf("set_global_flags value remapped: got %v, want 10", v) } if got := r.Exits[North].OnTraverse[0].Steps[0].Teleport; got != 111 { t.Errorf("on_traverse teleport = %d, want 111", got) } // Exit-level condition Room remaps. if got := r.Exits[North].Condition.Room; got != 41 { t.Errorf("exit condition room = %d, want 41", got) } // Trigger-level + per-step Condition.Room remaps. if got := r.Exits[North].OnTraverse[0].Condition.Room; got != 61 { t.Errorf("on_traverse trigger condition room = %d, want 61", got) } if got := r.OnEnter[0].Condition.Room; got != 21 { t.Errorf("on_enter trigger condition room = %d, want 21", got) } if got := r.OnEnter[0].Steps[0].Teleport; got != 71 { t.Errorf("on_enter teleport = %d, want 71", got) } if got := r.OnEnter[0].Steps[0].SpawnMob.DespawnRooms; len(got) != 1 || got[0] != 81 { t.Errorf("on_enter despawn_rooms = %v, want [81]", got) } if got := r.OnExit[0].Steps[0].Teleport; got != 51 { t.Errorf("on_exit teleport = %d, want 51", got) } if got := r.Mobs[0].WanderRooms; len(got) != 2 || got[0] != 91 || got[1] != 101 { t.Errorf("mob wander_rooms = %v, want [91 101]", got) } } func TestRoomRewriteRoomIDsNoChange(t *testing.T) { r := &Room{ Exits: map[ExitDir]ExitDef{North: {Room: 5}}, } if r.RewriteRoomIDs(map[int]int{99: 100}) { t.Error("expected changed=false when no references match") } if r.Exits[North].Room != 5 { t.Errorf("exit room = %d, want 5 (untouched)", r.Exits[North].Room) } } func TestRoomRewriteRoomIDsSwapRoundTrips(t *testing.T) { r := &Room{Exits: map[ExitDir]ExitDef{ North: {Room: 10}, South: {Room: 20}, }} swap := map[int]int{10: 20, 20: 10} r.RewriteRoomIDs(swap) if r.Exits[North].Room != 20 || r.Exits[South].Room != 10 { t.Errorf("after swap: north=%d south=%d, want north=20 south=10", r.Exits[North].Room, r.Exits[South].Room) } r.RewriteRoomIDs(swap) if r.Exits[North].Room != 10 || r.Exits[South].Room != 20 { t.Errorf("after double swap: north=%d south=%d, want north=10 south=20", r.Exits[North].Room, r.Exits[South].Room) } } func TestRoomRewriteRoomIDsIdempotentRename(t *testing.T) { r := &Room{Exits: map[ExitDir]ExitDef{North: {Room: 10}}} rename := map[int]int{10: 11} r.RewriteRoomIDs(rename) if r.Exits[North].Room != 11 { t.Fatalf("after rename: room=%d, want 11", r.Exits[North].Room) } if r.RewriteRoomIDs(rename) { t.Error("expected changed=false on second pass of a rename idMap") } }