aboutsummaryrefslogtreecommitdiff
path: root/internal/world
diff options
context:
space:
mode:
Diffstat (limited to 'internal/world')
-rw-r--r--internal/world/mob.go24
-rw-r--r--internal/world/world.go59
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
+ }
+}