aboutsummaryrefslogtreecommitdiff
path: root/internal/world/mob.go
diff options
context:
space:
mode:
Diffstat (limited to 'internal/world/mob.go')
-rw-r--r--internal/world/mob.go25
1 files changed, 25 insertions, 0 deletions
diff --git a/internal/world/mob.go b/internal/world/mob.go
index afd9024..4441108 100644
--- a/internal/world/mob.go
+++ b/internal/world/mob.go
@@ -747,7 +747,14 @@ func (s *MobStore) RekeyRooms(idMap map[int]int) {
}
s.mu.Lock()
defer s.mu.Unlock()
+ // A seeded instance's key embeds its home room (SeedMobs builds
+ // "<def>_<room>_<i>"). Leaving the old key in place would make SeedMobs
+ // create a duplicate instance for the renamed room and would let a
+ // recycled ID skip seeding entirely, so the map is rebuilt with the
+ // rewritten keys.
+ rekeyed := make(map[string]*MobInstance, len(s.instances))
for _, inst := range s.instances {
+ oldHome := inst.HomeRoomID
if newID, ok := idMap[inst.RoomID]; ok && newID != inst.RoomID {
inst.RoomID = newID
}
@@ -764,5 +771,23 @@ func (s *MobStore) RekeyRooms(idMap map[int]int) {
inst.DespawnRooms[i] = newID
}
}
+ if inst.HomeRoomID != oldHome {
+ inst.InstanceID = rekeySeededInstanceID(inst.InstanceID, inst.DefID, oldHome, inst.HomeRoomID)
+ }
+ rekeyed[inst.InstanceID] = inst
+ }
+ s.instances = rekeyed
+}
+
+// rekeySeededInstanceID rewrites the room component of a seeded instance ID
+// ("<def>_<oldRoom>_<suffix>"). IDs that do not match the seeded shape (a
+// transient or test instance) are returned unchanged. The DefID prefix is
+// stripped by string match rather than parsed because a mob def ID may itself
+// contain underscores.
+func rekeySeededInstanceID(instanceID, defID string, oldRoom, newRoom int) string {
+ prefix := fmt.Sprintf("%s_%d_", defID, oldRoom)
+ if !strings.HasPrefix(instanceID, prefix) {
+ return instanceID
}
+ return fmt.Sprintf("%s_%d_%s", defID, newRoom, strings.TrimPrefix(instanceID, prefix))
}