diff options
Diffstat (limited to 'internal/world')
| -rw-r--r-- | internal/world/mob.go | 24 | ||||
| -rw-r--r-- | internal/world/world.go | 59 |
2 files changed, 83 insertions, 0 deletions
diff --git a/internal/world/mob.go b/internal/world/mob.go index f33b2f9..a794bdd 100644 --- a/internal/world/mob.go +++ b/internal/world/mob.go @@ -722,3 +722,27 @@ func (s *MobStore) SeedMobs(roomID int, entries []RoomMob) { s.instances[instID] = inst } } + +// RekeyRooms remaps every live mob instance's RoomID and HomeRoomID per +// idMap (oldID -> newID), including wander rooms. Uses delete-all-then- +// set-all so a swap cannot clobber an entry mid-rekey. +func (s *MobStore) RekeyRooms(idMap map[int]int) { + if len(idMap) == 0 { + return + } + s.mu.Lock() + defer s.mu.Unlock() + for _, inst := range s.instances { + if newID, ok := idMap[inst.RoomID]; ok && newID != inst.RoomID { + inst.RoomID = newID + } + if newID, ok := idMap[inst.HomeRoomID]; ok && newID != inst.HomeRoomID { + inst.HomeRoomID = newID + } + for i, room := range inst.WanderRooms { + if newID, ok := idMap[room]; ok && newID != room { + inst.WanderRooms[i] = newID + } + } + } +} diff --git a/internal/world/world.go b/internal/world/world.go index b582faf..c5d0841 100644 --- a/internal/world/world.go +++ b/internal/world/world.go @@ -4,6 +4,7 @@ import ( "fmt" "os" "path/filepath" + "strconv" "strings" "sync" @@ -175,3 +176,61 @@ func (w *World) ClearRoomState(roomID int) { } } } + +// RekeyRooms remaps room-keyed runtime state per idMap (oldID -> newID): +// ground items, seeded markers, and object-state keys ("roomID:..."). +// Uses delete-all-then-set-all so a swap cannot clobber an entry mid-rekey. +func (w *World) RekeyRooms(idMap map[int]int) { + if len(idMap) == 0 { + return + } + w.mu.Lock() + defer w.mu.Unlock() + movedGround := make(map[int][]*groundEntry, len(w.groundItems)) + for roomID, entries := range w.groundItems { + if newID, ok := idMap[roomID]; ok && newID != roomID { + movedGround[newID] = entries + delete(w.groundItems, roomID) + } + } + for newID, entries := range movedGround { + w.groundItems[newID] = entries + } + movedSeeded := make(map[int]bool, len(w.seeded)) + for roomID := range w.seeded { + if newID, ok := idMap[roomID]; ok && newID != roomID { + movedSeeded[newID] = true + delete(w.seeded, roomID) + } + } + for newID := range movedSeeded { + w.seeded[newID] = true + } + type objKeyMove struct { + oldKey, newKey string + st *ObjState + } + 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 + } + newKey := fmt.Sprintf("%d:%s", newID, k[len(roomStr)+1:]) + moves = append(moves, objKeyMove{k, newKey, st}) + } + for _, m := range moves { + delete(w.objStates, m.oldKey) + } + for _, m := range moves { + w.objStates[m.newKey] = m.st + } +} |
