aboutsummaryrefslogtreecommitdiff
path: root/internal/world/room_migrate.go
diff options
context:
space:
mode:
authorhistoria <[not public]>2026-07-07 00:22:32 -0400
committerhistoria <[not public]>2026-07-07 00:22:32 -0400
commita51f7a53aa2c487ebf94ba0363038574ae8bb590 (patch)
treeb393a8f9e4732b40f6fe8058d086bd631537ad3b /internal/world/room_migrate.go
parent9292634f2f8d71a53879ff07e1330c671b207d51 (diff)
downloadthehouseoficarus-a51f7a53aa2c487ebf94ba0363038574ae8bb590.tar.gz
feat: hidden exits (and related flags) work with commands that change room ids. exit code simplified and unified between impassable and blocked exits.
Diffstat (limited to 'internal/world/room_migrate.go')
-rw-r--r--internal/world/room_migrate.go71
1 files changed, 71 insertions, 0 deletions
diff --git a/internal/world/room_migrate.go b/internal/world/room_migrate.go
new file mode 100644
index 0000000..6d79499
--- /dev/null
+++ b/internal/world/room_migrate.go
@@ -0,0 +1,71 @@
+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 {
+ if remapInt(idMap, &exit.Room) {
+ 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
+}