diff options
Diffstat (limited to 'internal/world/mob.go')
| -rw-r--r-- | internal/world/mob.go | 25 |
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)) } |
