70 lines
2.7 KiB
Lua
70 lines
2.7 KiB
Lua
-- Make a first 18x18 layout from the exit links preserved in the legacy saves.
|
|
-- Some old test rooms share the same one-way exit, so a grid cannot represent
|
|
-- every such link at once. Those rooms are still placed, but isolated, rather
|
|
-- than silently overwriting a room that already occupies that neighbour.
|
|
function seedWorldFromLegacyExits(world)
|
|
local available = {}
|
|
for _, name in ipairs(world:listRoomNames()) do available[name] = true end
|
|
local legacy = {}
|
|
for name in pairs(available) do
|
|
local raw = readFromSource("rooms/_pre_migration_backup/" .. name .. ".sav")
|
|
if raw then
|
|
local ok, save = pcall(TSerial.unpack, raw)
|
|
if ok and type(save) == "table" then legacy[name] = save.exits or {} end
|
|
end
|
|
end
|
|
|
|
world.rooms, world.roomByName = {}, {}
|
|
local root = available.start and "start" or world:listRoomNames()[1]
|
|
if not root then return { placed = 0, links = 0, conflicts = 0 } end
|
|
world:_putRoom(root, 9, 11)
|
|
local queue, queued = { root }, { [root] = true }
|
|
local directions = {
|
|
top = { x = 0, y = -1 }, right = { x = 1, y = 0 },
|
|
bottom = { x = 0, y = 1 }, left = { x = -1, y = 0 },
|
|
}
|
|
local order = { "top", "right", "bottom", "left" }
|
|
local links, conflicts = 0, 0
|
|
local index = 1
|
|
while index <= #queue do
|
|
local name = queue[index]
|
|
local source = world:roomLocation(name)
|
|
for _, exit in ipairs(order) do
|
|
local target = legacy[name] and legacy[name][exit]
|
|
target = target and tostring(target)
|
|
local direction = directions[exit]
|
|
if target and available[target] then
|
|
local x, y = source.x + direction.x, source.y + direction.y
|
|
local occupied, known = world:roomAt(x, y), world:roomLocation(target)
|
|
if world:isInBounds(x, y) and (not occupied or occupied == target) and (not known or (known.x == x and known.y == y)) then
|
|
if not known then world:_putRoom(target, x, y) end
|
|
links = links + 1
|
|
if not queued[target] then table.insert(queue, target); queued[target] = true end
|
|
else
|
|
conflicts = conflicts + 1
|
|
end
|
|
end
|
|
end
|
|
index = index + 1
|
|
end
|
|
|
|
-- Keep every migrated room visible/selectable without creating accidental
|
|
-- exits between the disconnected legacy variants.
|
|
for _, name in ipairs(world:listRoomNames()) do
|
|
if not world:roomLocation(name) then
|
|
local placed = false
|
|
for y = 1, world.height do
|
|
for x = 1, world.width do
|
|
if not world:roomAt(x, y) then
|
|
local nearby = false
|
|
for dy = -1, 1 do for dx = -1, 1 do if world:roomAt(x + dx, y + dy) then nearby = true end end end
|
|
if not nearby then world:_putRoom(name, x, y); placed = true; break end
|
|
end
|
|
end
|
|
if placed then break end
|
|
end
|
|
end
|
|
end
|
|
world:save()
|
|
return { placed = #world.rooms, links = links, conflicts = conflicts }
|
|
end
|