package world // RewriteRoomIDs remaps every genuine room-ID reference in this room per idMap // (oldID -> newID): exit targets, trigger Room/Teleport/DespawnRooms, on-enter // Teleport/DespawnRooms, and mob WanderRooms. It does NOT touch author-chosen // set_flags/set_player_flags values or condition `value:` fields — those are not // structural room references (and historically the swapid regex rewrote them // incorrectly as a side effect of matching any bare integer). // // idMap is assumed to be a bijection (each old ID maps to a distinct new ID); // this holds for both swap (A<->B) and rename-to-unused (A->B). Returns whether // any field was changed. func (r *Room) RewriteRoomIDs(idMap map[int]int) bool { if r == nil || len(idMap) == 0 { return false } changed := false for dir, exit := range r.Exits { var exitChanged bool if remapInt(idMap, &exit.Room) { exitChanged = true } for i := range exit.OnTraverse { if exit.OnTraverse[i].Action != nil { if remapInt(idMap, &exit.OnTraverse[i].Action.Teleport) { exitChanged = true } if exit.OnTraverse[i].Action.SpawnMob != nil && remapIntSlice(idMap, exit.OnTraverse[i].Action.SpawnMob.DespawnRooms) { exitChanged = true } } } if exitChanged { r.Exits[dir] = exit changed = true } } for i := range r.Triggers { if remapInt(idMap, &r.Triggers[i].Room) { changed = true } for j := range r.Triggers[i].Steps { s := &r.Triggers[i].Steps[j] if remapInt(idMap, &s.Teleport) { changed = true } if s.SpawnMob != nil && remapIntSlice(idMap, s.SpawnMob.DespawnRooms) { changed = true } } } for i := range r.OnEnter { s := &r.OnEnter[i] if remapInt(idMap, &s.Teleport) { changed = true } if s.SpawnMob != nil && remapIntSlice(idMap, s.SpawnMob.DespawnRooms) { changed = true } } for i := range r.Mobs { if remapIntSlice(idMap, r.Mobs[i].WanderRooms) { changed = true } } return changed } func remapInt(idMap map[int]int, n *int) bool { if newID, ok := idMap[*n]; ok && newID != *n { *n = newID return true } return false } func remapIntSlice(idMap map[int]int, slice []int) bool { changed := false for i := range slice { if remapInt(idMap, &slice[i]) { changed = true } } return changed }