mirror of
https://github.com/bryanthaboi/gen1recomp.git
synced 2026-08-26 07:21:22 +02:00
Add Gen 2 party reorder API parity
This commit is contained in:
@@ -30,6 +30,7 @@ local MapOverview = require("src.world.MapOverview")
|
||||
local Bike = require("src.world.gen2.Bike")
|
||||
local FieldMoves = require("src.world.gen2.FieldMoves")
|
||||
local Permissions = require("src.world.gen2.Permissions")
|
||||
local Mail = require("src.core.gen2.Mail")
|
||||
|
||||
local WorldAPI = {}
|
||||
WorldAPI.__index = WorldAPI
|
||||
@@ -49,6 +50,11 @@ local FIELD_ACTIONS = {
|
||||
{ id = "teleport", move = "TELEPORT" },
|
||||
}
|
||||
|
||||
local function validPartySlot(party, slot)
|
||||
return type(slot) == "number" and slot == math.floor(slot)
|
||||
and party[slot] ~= nil
|
||||
end
|
||||
|
||||
function WorldAPI.new(game, modId)
|
||||
return setmetatable({ game = game, modId = modId }, WorldAPI)
|
||||
end
|
||||
@@ -68,6 +74,32 @@ function WorldAPI:current()
|
||||
facing = p and p.facing }
|
||||
end
|
||||
|
||||
-- Keep the public party-ordering contract identical across generations.
|
||||
-- Gen 2 stores mail by party slot, so it must move with the Pokemon just as
|
||||
-- the native PartyMenu's SwitchPartyMons path does.
|
||||
function WorldAPI:canReorderParty()
|
||||
local world, game = self:overworld(), self.game
|
||||
local party = game and game.save and game.save.party or {}
|
||||
return #party > 1 and world ~= nil and world:acceptsMenuInput()
|
||||
end
|
||||
|
||||
function WorldAPI:reorderParty(fromSlot, toSlot)
|
||||
local world, game = self:overworld(), self.game
|
||||
if not world then return nil, NO_OVERWORLD end
|
||||
if not world:acceptsMenuInput() then return nil, "world is busy" end
|
||||
local party = game.save and game.save.party or {}
|
||||
if not validPartySlot(party, fromSlot)
|
||||
or not validPartySlot(party, toSlot) then
|
||||
return nil, "invalid party slot"
|
||||
end
|
||||
if fromSlot ~= toSlot then
|
||||
party[fromSlot], party[toSlot] = party[toSlot], party[fromSlot]
|
||||
Mail.swapSlots(game.save, fromSlot, toSlot)
|
||||
require("src.core.Sound").play(game.data, "Sfx_SwitchPokemon")
|
||||
end
|
||||
return true
|
||||
end
|
||||
|
||||
local function itemLabel(game, id)
|
||||
local def = game and game.data and game.data.items
|
||||
and game.data.items[id]
|
||||
|
||||
@@ -0,0 +1,59 @@
|
||||
-- Gen 2 parity for the public party-ordering contract. The fixture also
|
||||
-- carries slot-based mail because a reorder must move that state with its mon.
|
||||
|
||||
package.path = "./?.lua;./?/init.lua;" .. package.path
|
||||
love = love or require("tests.love_stub")
|
||||
|
||||
local T = require("tests.harness").suite("mod world party reorder gen2")
|
||||
local WorldAPI = require("src.world.gen2.WorldAPI")
|
||||
|
||||
local first = { species = "CHIKORITA" }
|
||||
local second = { species = "CYNDAQUIL" }
|
||||
local firstMail = { message = "FIRST" }
|
||||
local secondMail = { message = "SECOND" }
|
||||
local world = { map = { id = "NEW_BARK_TOWN" }, accepts = true }
|
||||
function world:acceptsMenuInput() return self.accepts end
|
||||
|
||||
local game = {
|
||||
data = { audio = { sfx = {} } },
|
||||
save = {
|
||||
party = { first, second },
|
||||
mail = { party = { firstMail, secondMail }, box = {} },
|
||||
},
|
||||
world = world,
|
||||
}
|
||||
local api = WorldAPI.new(game, "fixture")
|
||||
|
||||
T.check(api:canReorderParty(), "idle free roam allows party reordering")
|
||||
|
||||
local Sound = require("src.core.Sound")
|
||||
local realPlay, played = Sound.play
|
||||
Sound.play = function(_, name) played = name end
|
||||
T.check(api:reorderParty(1, 2) == true, "valid slots reorder")
|
||||
Sound.play = realPlay
|
||||
T.check(game.save.party[1] == second and game.save.party[2] == first,
|
||||
"the live party is swapped")
|
||||
T.check(game.save.mail.party[1] == secondMail
|
||||
and game.save.mail.party[2] == firstMail,
|
||||
"slot-based mail follows its Pokemon")
|
||||
T.eq(played, "Sfx_SwitchPokemon", "the native Gen 2 swap sound is used")
|
||||
|
||||
local value, err = api:reorderParty(1.5, 2)
|
||||
T.check(value == nil and err == "invalid party slot",
|
||||
"non-integer slots are rejected")
|
||||
value, err = api:reorderParty("1", 2)
|
||||
T.check(value == nil and err == "invalid party slot",
|
||||
"string slots are rejected")
|
||||
|
||||
world.accepts = false
|
||||
T.check(not api:canReorderParty(), "busy free roam blocks reordering")
|
||||
value, err = api:reorderParty(1, 2)
|
||||
T.check(value == nil and err == "world is busy",
|
||||
"reordering refuses while the world owns input")
|
||||
|
||||
game.world = nil
|
||||
value, err = api:reorderParty(1, 2)
|
||||
T.check(value == nil and err == "no overworld",
|
||||
"reordering outside the overworld fails closed")
|
||||
|
||||
T.finish()
|
||||
Reference in New Issue
Block a user