mirror of
https://github.com/bryanthaboi/gen1recomp
synced 2026-09-29 23:14:53 -04:00
114 lines
3.4 KiB
Lua
114 lines
3.4 KiB
Lua
local VoidFill = {}
|
|
|
|
VoidFill.MODES = { "map", "trees", "water", "black" }
|
|
VoidFill.LABELS = { map = "MAP", trees = "TREES", water = "WATER", black = "BLACK" }
|
|
|
|
VoidFill.mode = "map"
|
|
|
|
function VoidFill.normalize(mode)
|
|
for _, m in ipairs(VoidFill.MODES) do
|
|
if m == mode then return m end
|
|
end
|
|
return "map"
|
|
end
|
|
|
|
function VoidFill.setMode(mode)
|
|
mode = VoidFill.normalize(mode)
|
|
if mode ~= VoidFill.mode then
|
|
VoidFill.mode = mode
|
|
VoidFill.invalidate()
|
|
end
|
|
return VoidFill.mode
|
|
end
|
|
|
|
function VoidFill.cycle(mode, dir)
|
|
mode = VoidFill.normalize(mode)
|
|
local n = #VoidFill.MODES
|
|
local at = 1
|
|
for i, m in ipairs(VoidFill.MODES) do
|
|
if m == mode then at = i end
|
|
end
|
|
dir = (dir and dir < 0) and -1 or 1
|
|
return VoidFill.MODES[((at - 1 + dir) % n) + 1]
|
|
end
|
|
|
|
function VoidFill.label(mode)
|
|
return VoidFill.LABELS[VoidFill.normalize(mode)]
|
|
end
|
|
|
|
function VoidFill.invalidate()
|
|
VoidFill._borders = {}
|
|
local FieldView = package.loaded["src.core.game3.field_view"]
|
|
if FieldView then FieldView._nativeDirty = true end
|
|
end
|
|
|
|
VoidFill.PRIMARY = "general"
|
|
-- pokefirered/include/fieldmap.h:8
|
|
VoidFill.PRIMARY_MIDS = 640
|
|
VoidFill.SOURCES = { trees = "FR_PALLET_TOWN", water = "FR_CINNABAR_ISLAND" }
|
|
VoidFill._borders = {}
|
|
|
|
function VoidFill.primaryFor(pair)
|
|
if type(pair) ~= "string" then return nil end
|
|
local okV, Versions = pcall(require, "src.import.gba.versions")
|
|
local spec = okV and Versions and Versions.TILESET_PAIRS and Versions.TILESET_PAIRS[pair]
|
|
if spec and spec.primary then return spec.primary end
|
|
return pair:match("^(.-)__")
|
|
end
|
|
|
|
function VoidFill.layoutFor(mapId)
|
|
local Runtime = package.loaded["src.core.game3.runtime"]
|
|
local game = Runtime and Runtime._game
|
|
if not game then return nil, true end
|
|
local Map = package.loaded["src.core.game3.map"]
|
|
if not (Map and Map.ensureMidLayout) then return nil, true end
|
|
return Map.ensureMidLayout(game, mapId)
|
|
end
|
|
|
|
function VoidFill.borderFromLayout(layout)
|
|
if type(layout) ~= "table" or type(layout.borderMids) ~= "table" then return nil end
|
|
if VoidFill.primaryFor(layout.pair) ~= VoidFill.PRIMARY then return nil end
|
|
local w, h = layout.borderWidth or 0, layout.borderHeight or 0
|
|
if w < 1 or h < 1 then return nil end
|
|
local mids = {}
|
|
for i = 1, w * h do
|
|
local mid = layout.borderMids[i]
|
|
if type(mid) ~= "number" or mid < 0 or mid >= VoidFill.PRIMARY_MIDS then return nil end
|
|
mids[i] = mid
|
|
end
|
|
return { w = w, h = h, mids = mids }
|
|
end
|
|
|
|
function VoidFill.borderFor(mode)
|
|
mode = VoidFill.normalize(mode)
|
|
local mapId = VoidFill.SOURCES[mode]
|
|
if not mapId then return nil end
|
|
local b = VoidFill._borders[mode]
|
|
if b ~= nil then return b or nil end
|
|
local layout, pending = VoidFill.layoutFor(mapId)
|
|
if pending then return nil end
|
|
b = VoidFill.borderFromLayout(layout)
|
|
VoidFill._borders[mode] = b or false
|
|
return b
|
|
end
|
|
|
|
-- pokefirered/src/fieldmap.c:39
|
|
function VoidFill.fillAt(mode, cx, cy, hasMid, primary)
|
|
mode = VoidFill.normalize(mode or VoidFill.mode)
|
|
if mode == "map" then return nil end
|
|
if mode == "black" then return false end
|
|
if primary ~= VoidFill.PRIMARY then return nil end
|
|
local b = VoidFill.borderFor(mode)
|
|
if not b then return nil end
|
|
if hasMid then
|
|
for _, mid in ipairs(b.mids) do
|
|
if not hasMid(mid) then return nil end
|
|
end
|
|
end
|
|
local bx = (cx or 0) % b.w
|
|
local by = (cy or 0) % b.h
|
|
return b.mids[by * b.w + bx + 1]
|
|
end
|
|
|
|
return VoidFill
|