Add safe touch party reordering

This commit is contained in:
AverageConsumer
2026-08-03 14:49:58 +02:00
parent 7245de023a
commit 178e39932a
2 changed files with 39 additions and 5 deletions
+2
View File
@@ -86,6 +86,8 @@ handheld and the fork is not distributed as a PC replacement.
- **Swipe left or right** across the lower screen to move between the map, - **Swipe left or right** across the lower screen to move between the map,
party, steps, field tools, area information and guide pages. party, steps, field tools, area information and guide pages.
- **Tap the visible buttons and list entries** to use touch controls. - **Tap the visible buttons and list entries** to use touch controls.
- On **PARTY**, tap one Pokémon and then another to swap their positions while
the overworld is idle. Battles, dialogue, movement and menus lock reordering.
- Battles, menus, dialogue choices and other prompts automatically replace - Battles, menus, dialogue choices and other prompts automatically replace
the normal page when they need input, then return to it afterward. the normal page when they need input, then return to it afterward.
+37 -5
View File
@@ -104,6 +104,15 @@ local function pageWindow(index, count)
return first, math.min(4, math.max(0, count - first + 1)) return first, math.min(4, math.max(0, count - first + 1))
end end
local function partySlotAt(x, y, count)
if y < 23 or y >= 140 then return nil end
local col = x >= 81 and x < 156 and 1 or x >= 3 and x < 78 and 0 or nil
if col == nil then return nil end
local row = math.floor((y - 23) / 39)
local slot = row * 2 + col + 1
return slot <= (count or 0) and slot or nil
end
local function pcListKind(state) local function pcListKind(state)
return state and PC_LIST_KINDS[state.kind] and state.kind or nil return state and PC_LIST_KINDS[state.kind] and state.kind or nil
end end
@@ -296,6 +305,9 @@ assert(pageSwipeAllowed("active", nil)
and not pageSwipeAllowed("active", {}), "disabled screen swipe gate") and not pageSwipeAllowed("active", {}), "disabled screen swipe gate")
assert(pagedIndex(1, 9, 1) == 5 and pagedIndex(9, 9, 1) == 9 assert(pagedIndex(1, 9, 1) == 5 and pagedIndex(9, 9, 1) == 9
and pagedIndex(5, 9, -1) == 1, "touch list paging") and pagedIndex(5, 9, -1) == 1, "touch list paging")
assert(partySlotAt(3, 23, 6) == 1 and partySlotAt(81, 23, 6) == 2
and partySlotAt(81, 101, 5) == nil and partySlotAt(79, 23, 6) == nil,
"party touch slots")
do do
local first, count = pageWindow(6, 9) local first, count = pageWindow(6, 9)
assert(first == 5 and count == 4 assert(first == 5 and count == 4
@@ -600,6 +612,7 @@ return function(mod)
local pendingFly = nil local pendingFly = nil
local pendingAction = nil local pendingAction = nil
local fieldChoice = nil local fieldChoice = nil
local partyMoveFrom = nil
local choiceTop = nil local choiceTop = nil
local choiceReadyAt = 0 local choiceReadyAt = 0
local choiceNudgeUntil = 0 local choiceNudgeUntil = 0
@@ -1373,7 +1386,8 @@ return function(mod)
end end
local function drawNormalParty() local function drawNormalParty()
drawParty(partyData(), "PARTY", false) drawParty(partyData(), partyMoveFrom and "MOVE WHERE?" or "PARTY", false,
nil, partyMoveFrom)
end end
local function drawFieldChoice() local function drawFieldChoice()
@@ -2381,10 +2395,24 @@ return function(mod)
mod.save:set("steps", steps) mod.save:set("steps", steps)
dirty = true dirty = true
mod.log:info("step counter reset") mod.log:info("step counter reset")
elseif page == "PARTY" and y >= 23 then elseif page == "PARTY" then
local col, row = x >= 81 and 1 or 0, math.floor((y - 23) / 39) local party = game.save.party or {}
local mon = game.save.party[row * 2 + col + 1] local slot = partySlotAt(x, y, #party)
if mon then local mon = slot and party[slot]
if mon and mod.world and mod.world.canReorderParty
and mod.world:canReorderParty() then
if not partyMoveFrom then
partyMoveFrom = slot
else
local from = partyMoveFrom
partyMoveFrom = nil
local ok, err = mod.world:reorderParty(from, slot)
if not ok then
mod.log:warn("party reorder rejected: %s", tostring(err))
end
end
dirty = true
elseif mon then
local ok, err = pcall(function() local ok, err = pcall(function()
require("src.core.Sound").playCry(game.data, mon.species) require("src.core.Sound").playCry(game.data, mon.species)
end) end)
@@ -2637,6 +2665,10 @@ return function(mod)
refreshBattle() refreshBattle()
if page == "TOOLS" or pendingAction then refreshTools() end if page == "TOOLS" or pendingAction then refreshTools() end
local mode, top = screenState() local mode, top = screenState()
if partyMoveFrom and (page ~= "PARTY" or not mod.world
or not mod.world.canReorderParty or not mod.world:canReorderParty()) then
partyMoveFrom, dirty = nil, true
end
local learn = screenById("MoveLearnMenu") local learn = screenById("MoveLearnMenu")
local currentPcList = pcList() local currentPcList = pcList()
local currentChoice = dialogueChoice() local currentChoice = dialogueChoice()