mirror of
https://github.com/bryanthaboi/gen1recomp
synced 2026-10-07 09:27:38 -04:00
195 lines
7.2 KiB
Lua
195 lines
7.2 KiB
Lua
local Store = require("src.box.Store")
|
|
local Records = {}
|
|
|
|
function Records.boxes(save, generation)
|
|
if generation == 3 then
|
|
return save.storage and save.storage.boxes or {}
|
|
end
|
|
return save.boxes or (save.box and { save.box }) or {}
|
|
end
|
|
|
|
function Records.list(save, generation, box)
|
|
local row = Records.boxes(save, generation)[box]
|
|
if type(row) ~= "table" then return {} end
|
|
return generation == 3 and (row.mons or {}) or row
|
|
end
|
|
|
|
function Records.at(save, generation, ref)
|
|
if type(ref) ~= "table" then return nil end
|
|
local list = ref.where == "party" and (save.party or {})
|
|
or Records.list(save, generation, ref.box)
|
|
return list[ref.index] or list[tostring(ref.index)]
|
|
end
|
|
|
|
function Records.candidates(save, generation)
|
|
local out = {}
|
|
for i, mon in ipairs(save.party or {}) do
|
|
out[#out + 1] = { where = "party", index = i, mon = mon, source = "Party" }
|
|
end
|
|
local count, size = generation == 1 and 12 or 14, generation == 3 and 30 or 20
|
|
for b = 1, count do
|
|
local row = Records.boxes(save, generation)[b]
|
|
local name = generation == 3 and row and row.name
|
|
or save.boxNames and save.boxNames[b] or "BOX " .. b
|
|
for i = 1, size do
|
|
local mon = Records.list(save, generation, b)[i]
|
|
or Records.list(save, generation, b)[tostring(i)]
|
|
if type(mon) == "table" then
|
|
out[#out + 1] = { where = "box", box = b, index = i, mon = mon, source = name }
|
|
end
|
|
end
|
|
end
|
|
return out
|
|
end
|
|
|
|
function Records.key(ref)
|
|
return table.concat({ ref.where or "box", ref.box or 0, ref.index or ref.slot or 0 }, ":")
|
|
end
|
|
|
|
function Records.identity(generation, mon)
|
|
if generation == 3 then
|
|
if type(mon.personality) ~= "number" then return nil end
|
|
return "3|" .. mon.personality .. "|" .. tostring(mon.otId or 0) .. "|" .. tostring(mon.otSecretId or 0)
|
|
end
|
|
if type(mon.dvs) ~= "table" or mon.otId == nil then return nil end
|
|
local dvs = mon.dvs
|
|
local ot = mon.otName or mon.ot
|
|
if ot == nil then ot = require("src.core.TrainerIdentity").monName(mon) end
|
|
return table.concat({ generation, mon.otId, ot or "",
|
|
dvs.attack or 0, dvs.defense or 0, dvs.speed or 0, dvs.special or 0 }, "|")
|
|
end
|
|
|
|
local function catalog(version)
|
|
return require("src.box.Catalog").get(version)
|
|
end
|
|
|
|
function Records.enterBox(version, generation, mon)
|
|
if type(mon) ~= "table" then return mon end
|
|
if generation == 2 then
|
|
require("src.core.gen2.Boxes").enterBox(mon, catalog(version))
|
|
elseif generation == 3 then
|
|
pcall(require("src.core.game3.storage").fullHealMon, mon, { version = version })
|
|
end
|
|
return mon
|
|
end
|
|
|
|
function Records.leaveBox(version, generation, mon)
|
|
if type(mon) ~= "table" then return mon end
|
|
if generation == 1 then
|
|
local data = catalog(version)
|
|
require("src.pokemon.Stats").ensure(data.pokemon and data.pokemon[mon.species], mon)
|
|
elseif generation == 2 then
|
|
mon.status, mon.statusTurns = nil, nil
|
|
if mon.isEgg then mon.hp = 0 else mon.hp = mon.maxHp or mon.hp end
|
|
end
|
|
return mon
|
|
end
|
|
|
|
function Records.registerReceived(save, generation, mon)
|
|
if mon.isEgg then return end
|
|
if generation == 3 then
|
|
save.dex = save.dex or {}
|
|
require("src.core.game3.dex").handleSetPokedexFlag(save.dex, mon.species, true, mon.personality)
|
|
else
|
|
save.pokedex = save.pokedex or {}
|
|
local dex = save.pokedex
|
|
dex.seen = dex.seen or {}
|
|
local key = generation == 2 and "caught" or "owned"
|
|
dex[key] = dex[key] or {}
|
|
dex.seen[mon.species], dex[key][mon.species] = true, true
|
|
if generation == 2 and mon.species == "UNOWN" then
|
|
local Unown = require("src.core.gen2.Unown")
|
|
local letter = Unown.monLetter(mon)
|
|
save.unownDex = save.unownDex or {}
|
|
local found = false
|
|
for _, value in ipairs(save.unownDex) do if value == letter then found = true end end
|
|
if letter and not found then save.unownDex[#save.unownDex + 1] = letter end
|
|
end
|
|
end
|
|
end
|
|
|
|
function Records.remove(save, generation, refs)
|
|
local nextSave = Store.copy(save)
|
|
local seen, party = {}, false
|
|
for _, ref in ipairs(refs) do
|
|
local key = Records.key(ref)
|
|
if seen[key] or not Records.at(nextSave, generation, ref) then return nil, "A selected Pokémon is missing." end
|
|
seen[key] = true
|
|
local mon = Records.at(nextSave, generation, ref)
|
|
local mail = tonumber(mon.mail)
|
|
if generation == 3 and mail and mail ~= 255 then return nil, "Remove held mail before depositing." end
|
|
if generation == 2 and (require("src.core.gen2.Mail").monHoldsMail(mon)
|
|
or ref.where == "party" and nextSave.mail and nextSave.mail.party
|
|
and nextSave.mail.party[ref.index]) then return nil, "Remove held mail before depositing." end
|
|
local list
|
|
if ref.where == "party" then list, party = nextSave.party, true
|
|
else
|
|
if generation ~= 3 and not nextSave.boxes then
|
|
nextSave.boxes = { nextSave.box or {} }; nextSave.box = nil
|
|
end
|
|
list = Records.list(nextSave, generation, ref.box)
|
|
end
|
|
list[ref.index], list[tostring(ref.index)] = nil, nil
|
|
end
|
|
local function compact(list)
|
|
local keys, values = {}, {}
|
|
for key, value in pairs(list) do
|
|
if type(value) == "table" then keys[#keys + 1] = tonumber(key) end
|
|
end
|
|
table.sort(keys)
|
|
for _, key in ipairs(keys) do values[#values + 1] = list[key] or list[tostring(key)] end
|
|
for key in pairs(list) do list[key] = nil end
|
|
for i, value in ipairs(values) do list[i] = value end
|
|
return keys
|
|
end
|
|
if party then
|
|
local oldSlots = compact(nextSave.party)
|
|
if generation == 2 and nextSave.mail and type(nextSave.mail.party) == "table" then
|
|
local oldMail, nextMail = nextSave.mail.party, {}
|
|
for index, oldIndex in ipairs(oldSlots) do nextMail[index] = oldMail[oldIndex] end
|
|
nextSave.mail.party = nextMail
|
|
end
|
|
local healthy = 0
|
|
for _, mon in ipairs(nextSave.party) do
|
|
if not mon.isEgg and (tonumber(mon.hp) or 0) > 0 then healthy = healthy + 1 end
|
|
end
|
|
if healthy == 0 then return nil, "Keep at least one Pokémon able to battle in the party." end
|
|
end
|
|
if generation < 3 then
|
|
for _, list in pairs(nextSave.boxes or {}) do compact(list) end
|
|
end
|
|
return nextSave
|
|
end
|
|
|
|
function Records.insert(save, generation, box, entries)
|
|
local count, capacity = generation == 1 and 12 or 14, generation == 3 and 30 or 20
|
|
if type(box) ~= "number" or box < 1 or box > count or box ~= math.floor(box) then
|
|
return nil, "Choose a valid destination PC box."
|
|
end
|
|
local nextSave = Store.copy(save)
|
|
local boxes
|
|
if generation == 3 then
|
|
nextSave.storage = nextSave.storage or { currentBox = 1, boxes = {} }
|
|
nextSave.storage.boxes = nextSave.storage.boxes or {}
|
|
boxes = nextSave.storage.boxes
|
|
boxes[box] = boxes[box] or { name = "BOX " .. box, mons = {} }
|
|
boxes[box].mons = boxes[box].mons or {}
|
|
else
|
|
nextSave.boxes = nextSave.boxes or { nextSave.box or {} }
|
|
nextSave.box = nil
|
|
boxes = nextSave.boxes
|
|
boxes[box] = boxes[box] or {}
|
|
end
|
|
local list = generation == 3 and boxes[box].mons or boxes[box]
|
|
for _, entry in ipairs(entries) do
|
|
local free
|
|
for i = 1, capacity do if not (list[i] or list[tostring(i)]) then free = i; break end end
|
|
if not free then return nil, "That PC box does not have enough room." end
|
|
list[free] = Store.copy(entry.mon)
|
|
Records.registerReceived(nextSave, generation, list[free])
|
|
end
|
|
return nextSave
|
|
end
|
|
|
|
return Records
|