diff options
| author | historia <[not public]> | 2026-07-09 22:15:54 -0400 |
|---|---|---|
| committer | historia <[not public]> | 2026-07-09 22:15:54 -0400 |
| commit | ecba7f726f70b37126d852c38c7e3eec7b04d730 (patch) | |
| tree | 9129215c6e5015336fde1116395336d82bb952d1 /internal/world/room_migrate.go | |
| parent | b3d4c616f59ad2519f3a0b77e3b47d6571cd2486 (diff) | |
| download | thehouseoficarus-ecba7f726f70b37126d852c38c7e3eec7b04d730.tar.gz | |
feat: old standalone trigger systems completely unified into trigger->condition->action system
Diffstat (limited to 'internal/world/room_migrate.go')
| -rw-r--r-- | internal/world/room_migrate.go | 162 |
1 files changed, 135 insertions, 27 deletions
diff --git a/internal/world/room_migrate.go b/internal/world/room_migrate.go index 946417f..d609c6a 100644 --- a/internal/world/room_migrate.go +++ b/internal/world/room_migrate.go @@ -1,66 +1,174 @@ package world +import ( + "thehouseoficarus/internal/behavior" +) + // 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). +// (oldID -> newID): exit targets; every Step.Teleport and Step.SpawnMob +// .DespawnRooms inside on_enter/on_exit/on_flag_change/on_global_flag_change/ +// on_traverse/on_use/on_look/on_kill blocks; every Condition.Room anywhere in +// the room (exits, descriptions, trigger conditions, per-step conditions, +// including nested all_of/any_of); 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. // // 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. +// 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 + + // Exit targets + their on_traverse steps + exit/desc conditions. 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 remapTriggers(idMap, exit.OnTraverse) { + exitChanged = true + } + if exit.Condition != nil && remapCondition(idMap, exit.Condition) { + exitChanged = true } if exitChanged { r.Exits[dir] = exit changed = true } } - for i := range r.Triggers { - if remapInt(idMap, &r.Triggers[i].Room) { + + // Every trigger-shaped block on the room shares the Step list + Condition + // structure. Remap their steps and conditions uniformly. + for i := range r.OnEnter { + c := false + if remapStepList(idMap, r.OnEnter[i].Steps) { + c = true + } + if remapCondition(idMap, r.OnEnter[i].Condition) { + c = true + } + changed = changed || c + } + for i := range r.OnExit { + c := false + if remapStepList(idMap, r.OnExit[i].Steps) { + c = true + } + if remapCondition(idMap, r.OnExit[i].Condition) { + c = true + } + changed = changed || c + } + for i := range r.OnFlagChange { + c := false + if remapStepList(idMap, r.OnFlagChange[i].Steps) { + c = true + } + if remapCondition(idMap, r.OnFlagChange[i].Condition) { + c = true + } + changed = changed || c + } + for i := range r.OnGlobalFlagChange { + c := false + if remapStepList(idMap, r.OnGlobalFlagChange[i].Steps) { + c = true + } + if remapCondition(idMap, r.OnGlobalFlagChange[i].Condition) { + c = true + } + changed = changed || c + } + + // Conditional room descriptions carry a Condition. + for i := range r.Description { + if remapCondition(idMap, r.Description[i].Condition) { changed = true } - for j := range r.Triggers[i].Steps { - s := &r.Triggers[i].Steps[j] - if remapInt(idMap, &s.Teleport) { + } + + // Per-room local objects: on_use/on_look steps + object desc conditions. + for i := range r.Objects { + if r.Objects[i].Local != nil { + loc := r.Objects[i].Local + if remapTriggers(idMap, loc.OnUse) { changed = true } - if s.SpawnMob != nil && remapIntSlice(idMap, s.SpawnMob.DespawnRooms) { + if remapTriggers(idMap, loc.OnLook) { changed = true } + for j := range loc.Description { + if remapCondition(idMap, loc.Description[j].Condition) { + changed = true + } + } } } - for i := range r.OnEnter { - s := &r.OnEnter[i] + + for i := range r.Mobs { + if remapIntSlice(idMap, r.Mobs[i].WanderRooms) { + changed = true + } + } + return changed +} + +// remapTriggers remaps step fields across a []behavior.Trigger (each trigger's +// Steps + per-step Condition + trigger-level Condition). +func remapTriggers(idMap map[int]int, list []behavior.Trigger) bool { + changed := false + for i := range list { + c := false + if remapStepList(idMap, list[i].Steps) { + c = true + } + if remapCondition(idMap, list[i].Condition) { + c = true + } + changed = changed || c + } + return changed +} + +// remapStepList remaps Step.Teleport and Step.SpawnMob.DespawnRooms plus every +// step's per-step Condition.Room across a single Trigger's Steps. +func remapStepList(idMap map[int]int, steps []behavior.Step) bool { + changed := false + for i := range steps { + s := &steps[i] if remapInt(idMap, &s.Teleport) { changed = true } if s.SpawnMob != nil && remapIntSlice(idMap, s.SpawnMob.DespawnRooms) { changed = true } + if remapCondition(idMap, s.Condition) { + changed = true + } } - for i := range r.Mobs { - if remapIntSlice(idMap, r.Mobs[i].WanderRooms) { + return changed +} + +// remapCondition walks a Condition tree and remaps any Room field (a +// structural room reference) it finds, recursing into AllOf/AnyOf. +func remapCondition(idMap map[int]int, c *behavior.Condition) bool { + if c == nil { + return false + } + changed := false + if c.Room != 0 && remapInt(idMap, &c.Room) { + changed = true + } + for i := range c.AllOf { + if remapCondition(idMap, &c.AllOf[i]) { + changed = true + } + } + for i := range c.AnyOf { + if remapCondition(idMap, &c.AnyOf[i]) { changed = true } } |
