diff options
| author | historia <[not public]> | 2026-10-05 17:05:14 -0400 |
|---|---|---|
| committer | historia <[not public]> | 2026-10-05 17:05:14 -0400 |
| commit | e42952469dadfb3535633c66c881050ac128703c (patch) | |
| tree | a78f7396b72cdbd6fa4f6c454c830f40cf2ad0cb /internal/world/world.go | |
| parent | 90ad8c0c33b519d5830c69d4128bdc984b5e9de8 (diff) | |
| download | thehouseoficarus-e42952469dadfb3535633c66c881050ac128703c.tar.gz | |
fix: gather verbs, walk oom, admin path bypass, roulette refund
Diffstat (limited to 'internal/world/world.go')
| -rw-r--r-- | internal/world/world.go | 55 |
1 files changed, 17 insertions, 38 deletions
diff --git a/internal/world/world.go b/internal/world/world.go index 10ceb08..c9e1559 100644 --- a/internal/world/world.go +++ b/internal/world/world.go @@ -6,7 +6,6 @@ import ( "math" "os" "path/filepath" - "strconv" "strings" "sync" @@ -252,46 +251,26 @@ func (w *World) RekeyRooms(idMap map[int]int) { for newID := range movedSeeded { w.seeded[newID] = true } - type objKeyMove struct { - oldKey, newKey string - st *ObjState - newID int - } - var moves []objKeyMove - for k, st := range w.objStates { - roomStr, _, ok := strings.Cut(k, ":") - if !ok { - continue - } - roomID, err := strconv.Atoi(roomStr) - if err != nil { - continue - } - newID, ok := idMap[roomID] - if !ok || newID == roomID { - continue + // Rebuild the object-state map from every state, not only states whose + // current-room key is in idMap. An object away from its home room is keyed + // by the current room, so keying the walk on the map key leaves its + // HomeRoomID and WanderRooms stale; a later entry to the renamed home then + // fails homeObjStateLocked and creates a duplicate instance. Rebuilding the + // map also preserves the invariant mapKey == ObjStateKey(st.RoomID, ...). + rekeyed := make(map[string]*ObjState, len(w.objStates)) + for _, st := range w.objStates { + if newID, ok := idMap[st.RoomID]; ok && newID != st.RoomID { + st.RoomID = newID } - newKey := fmt.Sprintf("%d:%s", newID, k[len(roomStr)+1:]) - moves = append(moves, objKeyMove{k, newKey, st, newID}) - } - for _, m := range moves { - delete(w.objStates, m.oldKey) - } - for _, m := range moves { - // Keep the package invariant mapKey == ObjStateKey(st.RoomID, ...): - // object lookups filter on st.RoomID while GetObjState looks up the - // key, so a rekey that leaves RoomID stale makes the object vanish - // from the renamed room (and TickObjWander then creates a second - // entry for the same state). Remap wander rooms like MobStore does. - m.st.RoomID = m.newID - if mapped, ok := idMap[m.st.HomeRoomID]; ok && mapped != m.st.HomeRoomID { - m.st.HomeRoomID = mapped + if newID, ok := idMap[st.HomeRoomID]; ok && newID != st.HomeRoomID { + st.HomeRoomID = newID } - for i, room := range m.st.WanderRooms { - if mapped, ok := idMap[room]; ok && mapped != room { - m.st.WanderRooms[i] = mapped + for i, room := range st.WanderRooms { + if newID, ok := idMap[room]; ok && newID != room { + st.WanderRooms[i] = newID } } - w.objStates[m.newKey] = m.st + rekeyed[w.ObjStateKey(st.RoomID, st.DefID, st.Index)] = st } + w.objStates = rekeyed } |
