package world import "testing" // TestRekeyRoomsUpdatesObjStateRoomID: object lookups filter on ObjState.RoomID // while GetObjState looks up the map key, so the invariant // mapKey == ObjStateKey(st.RoomID, ...) must survive a rekey. Leaving RoomID // stale makes room objects vanish from a renamed/swapped room for the rest of // the process and lets TickObjWander create a duplicate entry for the state. func TestRekeyRoomsUpdatesObjStateRoomID(t *testing.T) { w := New(t.TempDir()) w.objStates[w.ObjStateKey(1, "anvil", 0)] = &ObjState{ RoomID: 1, DefID: "anvil", Index: 0, WanderRooms: []int{1, 5, 9}, } w.RekeyRooms(map[int]int{1: 3, 5: 7}) inst := w.GetObjState(3, "anvil", 0) if inst == nil { t.Fatal("object state lost after rekey") } if inst.RoomID != 3 { t.Fatalf("ObjState.RoomID = %d, want 3 (map key and state desynchronised)", inst.RoomID) } if got := inst.WanderRooms; len(got) != 3 || got[0] != 3 || got[1] != 7 || got[2] != 9 { t.Fatalf("WanderRooms after rekey = %v, want [3 7 9]", got) } if got := w.AllObjInstances(3); len(got) != 1 { t.Fatalf("AllObjInstances(3) = %d entries, want 1 (object invisible in renamed room)", len(got)) } if got := w.AllObjInstances(1); len(got) != 0 { t.Fatalf("AllObjInstances(1) = %d entries, want 0 (stale old room)", len(got)) } } // Regression: an object away from its home room is keyed by its current room, // so the old key-driven walk left its HomeRoomID/WanderRooms stale and a later // entry to the renamed home created a duplicate instance. func TestRekeyRoomsUpdatesAwayFromHomeObject(t *testing.T) { w := New(t.TempDir()) // Declared in home room 1, currently wandering in room 5. w.objStates[w.ObjStateKey(5, "fishing_spot", 0)] = &ObjState{ RoomID: 5, HomeRoomID: 1, DefID: "fishing_spot", Index: 0, WanderRooms: []int{1, 5}, } w.RekeyRooms(map[int]int{1: 20}) inst := w.GetObjState(5, "fishing_spot", 0) if inst == nil { t.Fatal("away object state lost after rekey") } if inst.HomeRoomID != 20 { t.Fatalf("HomeRoomID = %d, want 20", inst.HomeRoomID) } if got := inst.WanderRooms; len(got) != 2 || got[0] != 20 || got[1] != 5 { t.Fatalf("WanderRooms = %v, want [20 5]", got) } }