aboutsummaryrefslogtreecommitdiff
path: root/internal/world
diff options
context:
space:
mode:
Diffstat (limited to 'internal/world')
-rw-r--r--internal/world/grid.go3
-rw-r--r--internal/world/mob.go13
-rw-r--r--internal/world/mob_rekey_test.go30
-rw-r--r--internal/world/room_migrate.go5
-rw-r--r--internal/world/room_migrate_test.go8
5 files changed, 56 insertions, 3 deletions
diff --git a/internal/world/grid.go b/internal/world/grid.go
index 9ee08d1..9773241 100644
--- a/internal/world/grid.go
+++ b/internal/world/grid.go
@@ -64,6 +64,9 @@ func BuildGrid(seed int, load func(int) (*Room, bool), include func(int) bool, e
continue
}
target := exit.Room
+ if edgeInclude != nil && !edgeInclude(rid, dir, target) {
+ continue
+ }
if include != nil && !include(target) {
continue
}
diff --git a/internal/world/mob.go b/internal/world/mob.go
index 631e3a3..afd9024 100644
--- a/internal/world/mob.go
+++ b/internal/world/mob.go
@@ -428,9 +428,9 @@ func (s *MobStore) LoadDef(id string) (*MobDef, error) {
s.mu.Unlock()
return def, nil
}
- s.mu.Unlock()
-
+ // pathIndex is writer-guarded by ReloadDefs; read it under the lock too.
path, ok := s.pathIndex[id]
+ s.mu.Unlock()
if !ok {
return nil, fmt.Errorf("read mob %s: no such mob", id)
}
@@ -455,7 +455,9 @@ func (s *MobStore) LoadDef(id string) (*MobDef, error) {
}
func (s *MobStore) AllDefIDs() map[string]bool {
- ids := make(map[string]bool)
+ s.mu.Lock()
+ defer s.mu.Unlock()
+ ids := make(map[string]bool, len(s.pathIndex))
for id := range s.pathIndex {
ids[id] = true
}
@@ -757,5 +759,10 @@ func (s *MobStore) RekeyRooms(idMap map[int]int) {
inst.WanderRooms[i] = newID
}
}
+ for i, room := range inst.DespawnRooms {
+ if newID, ok := idMap[room]; ok && newID != room {
+ inst.DespawnRooms[i] = newID
+ }
+ }
}
}
diff --git a/internal/world/mob_rekey_test.go b/internal/world/mob_rekey_test.go
new file mode 100644
index 0000000..3a0eb85
--- /dev/null
+++ b/internal/world/mob_rekey_test.go
@@ -0,0 +1,30 @@
+package world
+
+import "testing"
+
+// TestRekeyRoomsUpdatesMobDespawnRooms: DespawnRooms is a live room reference
+// (sys_triggers compares it against the owner's current room). A room rename
+// must remap it alongside RoomID/HomeRoomID/WanderRooms, or a transient mob
+// despawns while its owner never left the allowed room.
+func TestRekeyRoomsUpdatesMobDespawnRooms(t *testing.T) {
+ s := &MobStore{instances: map[string]*MobInstance{
+ "m1": {
+ InstanceID: "m1",
+ RoomID: 1,
+ HomeRoomID: 1,
+ WanderRooms: []int{1, 5},
+ DespawnRooms: []int{1, 5},
+ },
+ }}
+ s.RekeyRooms(map[int]int{1: 3, 5: 7})
+ inst := s.instances["m1"]
+ if inst.RoomID != 3 || inst.HomeRoomID != 3 {
+ t.Fatalf("room/home = %d/%d, want 3/3", inst.RoomID, inst.HomeRoomID)
+ }
+ if got := inst.WanderRooms; len(got) != 2 || got[0] != 3 || got[1] != 7 {
+ t.Fatalf("wander_rooms = %v, want [3 7]", got)
+ }
+ if got := inst.DespawnRooms; len(got) != 2 || got[0] != 3 || got[1] != 7 {
+ t.Fatalf("despawn_rooms = %v, want [3 7]", got)
+ }
+}
diff --git a/internal/world/room_migrate.go b/internal/world/room_migrate.go
index 9bc7e0f..b7840bc 100644
--- a/internal/world/room_migrate.go
+++ b/internal/world/room_migrate.go
@@ -71,7 +71,12 @@ func (r *Room) RewriteRoomIDs(idMap map[int]int) bool {
}
// Per-room local objects: on_use/on_look steps + object desc conditions.
+ // WanderRooms is a room reference on every object entry (reference or
+ // local), so remap it outside the Local branch.
for i := range r.Objects {
+ if remapIntSlice(idMap, r.Objects[i].WanderRooms) {
+ changed = true
+ }
if r.Objects[i].Local != nil {
loc := r.Objects[i].Local
if remapTriggers(idMap, loc.OnUse) {
diff --git a/internal/world/room_migrate_test.go b/internal/world/room_migrate_test.go
index f5bd972..d76436b 100644
--- a/internal/world/room_migrate_test.go
+++ b/internal/world/room_migrate_test.go
@@ -34,11 +34,16 @@ func TestRoomRewriteRoomIDs(t *testing.T) {
Mobs: []RoomMob{
{ID: "guard", WanderRooms: []int{90, 100}},
},
+ Objects: []RoomObject{
+ // A reference object's WanderRooms is a room reference too.
+ {ID: "wandering_anvil", WanderRooms: []int{15, 25}},
+ },
}
idMap := map[int]int{
10: 11, 20: 21, 40: 41, 50: 51, 60: 61,
70: 71, 80: 81, 90: 91, 100: 101, 110: 111,
+ 15: 16, 25: 26,
}
if !r.RewriteRoomIDs(idMap) {
t.Fatal("expected changed=true")
@@ -80,6 +85,9 @@ func TestRoomRewriteRoomIDs(t *testing.T) {
if got := r.Mobs[0].WanderRooms; len(got) != 2 || got[0] != 91 || got[1] != 101 {
t.Errorf("mob wander_rooms = %v, want [91 101]", got)
}
+ if got := r.Objects[0].WanderRooms; len(got) != 2 || got[0] != 16 || got[1] != 26 {
+ t.Errorf("object wander_rooms = %v, want [16 26]", got)
+ }
}
func TestRoomRewriteRoomIDsNoChange(t *testing.T) {