mirror of
https://github.com/bryanthaboi/gen1recomp
synced 2026-10-03 16:16:38 -04:00
154 lines
7.9 KiB
Lua
154 lines
7.9 KiB
Lua
package.path = package.path .. ";./?.lua;./?/init.lua;./tools/save-editor/?.lua;./tools/save-editor/panels/?.lua"
|
|
|
|
local Fixture = {}
|
|
|
|
function Fixture.load(version, opts)
|
|
opts = opts or {}
|
|
local GameVersion = require("src.core.GameVersion")
|
|
GameVersion.set(version)
|
|
local generation = GameVersion.generation(version)
|
|
local Merge = require("src.mods.Merge")
|
|
local Gen = require("Gen")
|
|
local baseId = generation == 3 and "FR_EDITOR_BASE" or "EDITOR_BASE"
|
|
local newId = generation == 3 and "FR_EDITOR_NEW" or "EDITOR_NEW"
|
|
local lazyId = "FR_EDITOR_LAZY"
|
|
local missingId = generation == 3 and "FR_EDITOR_MISSING" or "EDITOR_MISSING"
|
|
local pair, mid = opts.pair or "editor_fixture", opts.mid or 7
|
|
local atlas = opts.atlas or "mods/editor_map_fixture/atlas.png"
|
|
local base = opts.base or {
|
|
id = baseId, width = 3, height = 2, tileset = "EDITOR_TILES", blocks = { 1, 1, 1, 1, 1, 1 },
|
|
warps = {}, midLayout = generation == 3 and {
|
|
width = 3, height = 2, pair = pair, midAt = function() return 0 end,
|
|
} or nil,
|
|
}
|
|
local data = { maps = { [baseId] = Merge.deepCopy(base) }, tilesets = {} }
|
|
if generation == 3 then data.game3Maps = { [baseId] = base }
|
|
elseif generation == 2 then Gen.bindGoldData(data) end
|
|
local source
|
|
if generation == 3 then
|
|
source = ([[return function(mod)
|
|
local function layout(pair)
|
|
return { width = 6, height = 4, pair = pair, midAt = function() return %d end }
|
|
end
|
|
mod.content.maps:patch(%q, { width = 6, height = 4, midLayout = layout(%q), pair = %q, weather = 2 })
|
|
mod.content.maps:register(%q, { id = %q, width = 6, height = 4, midLayout = layout(%q), pair = %q, warps = {} })
|
|
mod.content.maps:register(%q, { id = %q, width = 6, height = 4, pair = %q, warps = {} })
|
|
mod.content.maps:register(%q, { id = %q, width = 6, height = 4, warps = {} })
|
|
end]]):format(mid, baseId, pair, pair, newId, newId, pair, pair, lazyId, lazyId, pair, missingId, missingId)
|
|
else
|
|
source = ([[return function(mod)
|
|
local row = {}; for i = 1, 16 do row[i] = 0 end
|
|
mod.content.tilesets:register("EDITOR_TILES", {
|
|
id = "EDITOR_TILES", image = %q, tilesPerRow = 1, blocks = { row, row },
|
|
walkable = { 0 }, collision = { { 0, 0, 0, 0 }, { 0, 0, 0, 0 } }, trueColor = true,
|
|
})
|
|
mod.content.maps:patch(%q, { width = 4, height = 3, blocks = { 1,1,1,1,1,1,1,1,1,1,1,1 } })
|
|
mod.content.maps:register(%q, {
|
|
id = %q, tileset = "EDITOR_TILES", width = 4, height = 3,
|
|
blocks = { 1,1,1,1,1,1,1,1,1,1,1,1 }, warps = {}, objects = {}, signs = {},
|
|
})
|
|
mod.content.tilesets:register("EDITOR_MISSING_TILES", { image = "mods/editor_map_fixture/missing.png", blocks = { row }, walkable = {} })
|
|
mod.content.maps:register(%q, { id = %q, tileset = "EDITOR_MISSING_TILES", width = 2, height = 2, blocks = { 0,0,0,0 }, warps = {} })
|
|
end]]):format(atlas, baseId, newId, newId, missingId, missingId)
|
|
end
|
|
local files = {
|
|
["mods/editor_map_fixture/manifest.json"] = ([[{"id":"editor_map_fixture","name":"Editor map fixture","version":"1.0.0","api":2,"entry":"main.lua","games":[%q]}]]):format(version),
|
|
["mods/editor_map_fixture/main.lua"] = source,
|
|
}
|
|
local fs = {}
|
|
function fs.read(path) return files[path] end
|
|
function fs.write(path, bytes) files[path] = bytes; return true end
|
|
function fs.getInfo(path)
|
|
if files[path] then return { type = "file" } end
|
|
for key in pairs(files) do if key:sub(1, #path + 1) == path .. "/" then return { type = "directory" } end end
|
|
end
|
|
function fs.load(path) return loadstring(assert(files[path]), "@" .. path) end
|
|
function fs.getDirectoryItems(path)
|
|
local found, items = {}, {}
|
|
for key in pairs(files) do
|
|
if key:sub(1, #path + 1) == path .. "/" then
|
|
local name = key:sub(#path + 2):match("^[^/]+")
|
|
if not found[name] then found[name], items[#items + 1] = true, name end
|
|
end
|
|
end
|
|
table.sort(items)
|
|
return items
|
|
end
|
|
local loader = require("src.mods.Loader").new({ fs = fs, generation = generation, version = version })
|
|
assert(loader:load(data), table.concat(loader.errors, "; "))
|
|
assert(#loader:status().loaded == 1, "fixture mod did not load")
|
|
return data, loader, { base = baseId, new = newId, lazy = lazyId, missing = missingId, pair = pair, mid = mid }
|
|
end
|
|
|
|
if ... == "tests.engine.save_editor_custom_maps" then return Fixture end
|
|
|
|
love = require("tests.love_stub")
|
|
local T = require("tests.harness")
|
|
local Gen = require("Gen")
|
|
local Browser = require("MapBrowser")
|
|
local State = require("State")
|
|
local Kit = require("Kit")
|
|
local realImage = love.graphics.newImage
|
|
love.graphics.newImage = function(path)
|
|
if type(path) == "string" and path:find("missing.png", 1, true) then error("missing fixture image") end
|
|
return realImage(path)
|
|
end
|
|
local function state(data, version, id)
|
|
local s = State.new()
|
|
s.data, s.version, s.tab, s.mapId = data, version, "map", id
|
|
s.save = { version = version, generation = require("src.core.GameVersion").generation(version), player = { map = id, x = 1, y = 1 } }
|
|
return s
|
|
end
|
|
local function draw(s)
|
|
Kit.beginFrame(-1, -1, false, 0)
|
|
Browser.draw(s, Kit, 0, 0, 1200, 760)
|
|
Kit.endFrame()
|
|
end
|
|
|
|
for _, version in ipairs({ "red", "gold", "crystal", "firered", "emerald" }) do
|
|
local data, loader, ids = Fixture.load(version)
|
|
local maps = Gen.maps(data)
|
|
local generation = require("src.core.GameVersion").generation(version)
|
|
T.eq(maps[ids.base].width, generation == 3 and 6 or 4, version .. " mod patch reaches preview map lookup")
|
|
T.check(maps[ids.new] ~= nil, version .. " loaded mod's new map is discoverable")
|
|
if generation == 3 then
|
|
T.eq(maps[ids.base].weather, 2, version .. " existing mod patch is authoritative")
|
|
T.eq(maps[ids.base].midLayout:midAt(0, 0), 7, version .. " mod-supplied layout survives base binding")
|
|
end
|
|
local missing = state(data, version, ids.missing)
|
|
draw(missing)
|
|
T.check(type(missing.mapPreviewReason) == "string" and missing.mapPreviewReason:find("unavailable", 1, true), version .. " missing artwork is explained in the actual map panel")
|
|
if Browser.preview then
|
|
local s = state(data, version, ids.new)
|
|
if generation < 3 then
|
|
local ok, map, reason = Browser.preview(s)
|
|
T.check(ok and map.renderer and not reason, version .. " loaded custom atlas builds a terrain renderer")
|
|
T.eq(map.widthCells, 8, version .. " block dimensions use walking cells")
|
|
else
|
|
local Dataset = require("src.core.game3.dataset")
|
|
local Extract = require("src.import.gba.extract_island1")
|
|
local root = "editor-custom-map-fixture"
|
|
Extract.NATIVE_ROOT = root
|
|
Dataset.invalidateManifestCache()
|
|
local cells = {}; for i = 1, 24 do cells[i] = { mid = 7, coll = 0, elev = 0 } end
|
|
love.filesystem.write(root .. "/layouts/" .. ids.lazy .. ".mid", require("src.import.gba.native_pack").encodeMidLayout({ width = 6, height = 4, cells = cells }))
|
|
local original = data.maps[ids.new].midLayout
|
|
Browser.preview(s)
|
|
T.eq(data.maps[ids.new].midLayout, original, version .. " preview preserves supplied layout identity")
|
|
s.mapId = ids.lazy
|
|
local ok, map = Browser.preview(s)
|
|
T.check(ok and data.maps[ids.lazy].midLayout and data.maps[ids.lazy].midLayout:midAt(2, 2) == 7, version .. " gameplay API lazily attaches a mod-added native MID file")
|
|
T.check(map:inBounds(5, 3) and not map:inBounds(6, 3), version .. " native grid preserves placement bounds")
|
|
s.mapId = ids.missing
|
|
local _, grid, reason = Browser.preview(s)
|
|
T.check(grid:inBounds(5, 3) and reason:find("missing native map layout", 1, true), version .. " missing layout retains the coordinate grid")
|
|
data.maps[ids.missing].midLayout = { midAt = function() return 0 end }
|
|
local _, _, pairReason = Browser.preview(s)
|
|
T.check(pairReason:find("missing native tileset pair", 1, true), version .. " missing pair is distinguished from missing layout")
|
|
end
|
|
end
|
|
require("src.mods.Runtime").reset()
|
|
end
|
|
|
|
T.finish()
|