From 437a8ef8c5912ba3faca5762846ab5bbe1edbaeb Mon Sep 17 00:00:00 2001 From: bryanthaboi Date: Fri, 25 Sep 2026 05:46:24 -0400 Subject: [PATCH 1/6] gen3 link battle and union room fixes --- src/core/game3/battle/init.lua | 3 +-- src/core/game3/battle/ui.lua | 9 +++++++++ src/core/game3/link/union_room.lua | 14 +++++++++++++- tests/game3_link_battle_test.lua | 2 ++ tests/game3_link_relay_union_test.lua | 16 +++++++++++++++- 5 files changed, 40 insertions(+), 4 deletions(-) diff --git a/src/core/game3/battle/init.lua b/src/core/game3/battle/init.lua index fcfc6274..fcbaa3d2 100644 --- a/src/core/game3/battle/init.lua +++ b/src/core/game3/battle/init.lua @@ -1219,8 +1219,7 @@ local function refuse_link_item(input) if not (input and st and st.link) then return false end if Ui._mode ~= "menu" or not input:wasPressed("a") then return false end if Commands.MENU[Ui._menuIndex or 1] ~= "BAG" then return false end - -- pokefirered/src/battle_message.c:251 - Ui.push(BattleText.get("STRINGID_ITEMSCANTBEUSEDNOW")) + Ui.refuseItems() return true end diff --git a/src/core/game3/battle/ui.lua b/src/core/game3/battle/ui.lua index 45baa7f2..a1605e94 100644 --- a/src/core/game3/battle/ui.lua +++ b/src/core/game3/battle/ui.lua @@ -435,7 +435,16 @@ local function restore_action_menu() if Message and Message.open then Message.reset() end end +-- pokefirered/src/battle_main.c:3182 BattleScript_ActionSelectionItemsCantBeUsed +function Ui.refuseItems() + Ui._selCmd = nil + Ui._selReturn = "menu" + Ui._mode = "selmsg" + Ui.push(BattleText.get("STRINGID_ITEMSCANTBEUSEDNOW")) +end + local function open_battle_bag() + if Ui._st and Ui._st.link then return Ui.refuseItems() end local BagMenu = require("src.ui.game3.bag_menu") local Runtime = package.loaded["src.core.game3.runtime"] local session = Ui._session diff --git a/src/core/game3/link/union_room.lua b/src/core/game3/link/union_room.lua index edcc5863..aa210a49 100644 --- a/src/core/game3/link/union_room.lua +++ b/src/core/game3/link/union_room.lua @@ -1924,6 +1924,8 @@ local function partnerSig(list) end -- pokefirered/src/union_room.c:2781 +Union.GONE_GRACE_SECONDS = 1.5 + function Union.syncPlaza() local plaza = link().clientCall("plaza") if type(plaza) ~= "table" then return false end @@ -1958,9 +1960,19 @@ function Union.syncPlaza() end end local changed, fresh = false, false + local now = Union.clock() for slot = 1, Union.MAX_LEADERS do local p = Union.players[slot] - if p and not p.gone and not leaders[p.id] then p.gone = true end + if p and leaders[p.id] then + p.missingSince = nil + elseif p and not p.gone then + if present[p.id] then + p.gone = true + else + p.missingSince = p.missingSince or now + if now - p.missingSince >= Union.GONE_GRACE_SECONDS then p.gone = true end + end + end end for _, m in ipairs(members) do if leaders[m.id] then diff --git a/tests/game3_link_battle_test.lua b/tests/game3_link_battle_test.lua index 33f0cac5..6277667a 100644 --- a/tests/game3_link_battle_test.lua +++ b/tests/game3_link_battle_test.lua @@ -847,6 +847,8 @@ check(Battle._refuseLinkItem(fakeInput), "A on BAG in a link battle is refused a local after = Ui.log() or {} check(#after > before and tostring(after[#after]):find("can't be used", 1, true) ~= nil, "and the refusal prints sText_ItemsCantBeUsedNow") +eq(Ui._mode, "selmsg", "shown as a selection message so it stays on screen") +eq(Ui._selReturn, "menu", "then returns to the action menu") Ui._mode = "menu" Ui._menuIndex = 1 eq(Battle._refuseLinkItem(fakeInput), false, "FIGHT is not touched by the rule") diff --git a/tests/game3_link_relay_union_test.lua b/tests/game3_link_relay_union_test.lua index 1bc846d4..0ac39354 100644 --- a/tests/game3_link_relay_union_test.lua +++ b/tests/game3_link_relay_union_test.lua @@ -206,10 +206,24 @@ eq(Union.leaderObj(1).state, 1, "the leader is shown") eq(Union.avatarData().leader_coords[1][1], 4, "leader slot 1 sits at sUnionRoomPlayerCoords[0]") print("[test] 3. refreshes are throttled like the cart, departures fly out") +local realClock = Union.clock +local fakeNow = 1000 +Union.clock = function() return fakeNow end +local blueRow = table.remove(Client._plaza.members, 2) +run(1) +check(Union.players[2] and not Union.players[2].gone, "a member missing for a moment is not gone yet") +table.insert(Client._plaza.members, 2, blueRow) +run(1) +fakeNow = fakeNow + Union.GONE_GRACE_SECONDS + 1 +run(1) +check(Union.players[2] and not Union.players[2].gone, "and a blip that comes back never flies out") table.remove(Client._plaza.members, 2) run(1) +fakeNow = fakeNow + Union.GONE_GRACE_SECONDS +run(1) +Union.clock = realClock eq(Union.playerCount(), 2, "not refreshed on the next frame") -check(Union.players[2] and Union.players[2].gone, "BLUE is marked gone") +check(Union.players[2] and Union.players[2].gone, "BLUE is marked gone once the grace runs out") local frames = 0 while Union.playerCount() == 2 and frames < Union.REFRESH_FRAMES + 5 do run(1) From f8c95b8e8aad7713fd10b725b92a20b29abf6915 Mon Sep 17 00:00:00 2001 From: bryanthaboi Date: Fri, 25 Sep 2026 07:11:42 -0400 Subject: [PATCH 2/6] CLOSES #2347, CLOSES #2384, CLOSES #2456, CLOSES #2460, CLOSES #2461, CLOSES #2468, CLOSES #2470, CLOSES #2471, CLOSES #2472, CLOSES #2473 --- conf.lua | 1 + main.lua | 7 + src/core/FixedStep.lua | 42 ++- src/core/Game.lua | 2 +- src/core/Game2.lua | 4 +- src/core/Game3.lua | 2 +- src/core/Input.lua | 7 +- src/core/PadHints.lua | 73 +++++ src/core/PresentSync.lua | 2 - src/core/SaveData.lua | 20 +- src/core/game3/battle/engine.lua | 7 +- src/core/game3/battle/switch_seq.lua | 95 ++++--- src/core/game3/collision.lua | 22 +- src/core/game3/connections.lua | 117 ++++++++ src/core/game3/dex.lua | 59 ++++ src/core/game3/doors.lua | 4 +- src/core/game3/field.lua | 20 +- src/core/game3/field_moves.lua | 16 +- src/core/game3/itemfinder.lua | 57 +--- src/core/game3/map.lua | 123 ++++----- src/core/game3/objects.lua | 102 +++---- src/core/game3/trainer_sight.lua | 2 + src/debug/SwitchDiagnostics.lua | 26 ++ src/import/CacheContract.lua | 64 ++++- src/import/RomExtractor.lua | 16 +- src/import/gba/extract_island1.lua | 28 +- src/import/gba/extract_map_events.lua | 2 +- src/import/gba/map_tree.lua | 3 +- src/import/gba/versions.lua | 2 +- src/mods/Gen3Compat.lua | 17 +- src/render/PaletteFX.lua | 12 +- src/render/TileRenderer.lua | 134 +++++++++- src/save_convert/GenSave.lua | 19 +- src/save_convert/MapContext.lua | 35 +++ src/save_convert/SaveConvert.lua | 9 +- src/ui/ShopMenu.lua | 69 +++-- src/ui/game3/boot.lua | 11 +- src/ui/game3/party_menu.lua | 16 +- src/world/OverworldController.lua | 49 +++- src/world/PikachuFollower.lua | 132 +++++---- tests/drivers/blues_house_bug11_test.lua | 34 ++- tests/drivers/game3_cut_grass_2470.lua | 127 +++++++++ .../game3_ghost_trainer_sight_2460.lua | 129 +++++++++ tests/drivers/game3_import_dex_count_2461.lua | 102 +++++++ tests/drivers/game3_importer_round2.lua | 7 +- .../drivers/game3_pad_battle_text_bug2452.lua | 109 ++++++++ tests/drivers/game3_pewter_guide_bug2472.lua | 164 ++++++++++++ tests/drivers/game3_shift_exp_2473.lua | 154 +++++++++++ tests/drivers/game3_six_island_water_path.lua | 88 ++++++ tests/drivers/gen1_mart_sell_glyph_test.lua | 2 +- tests/drivers/mart_clerk_typing_bug2384.lua | 126 +++++++++ tests/drivers/mart_price_text_bug2291.lua | 6 +- .../overworld_fast_forward_bug2471.lua | 111 ++++++++ tests/drivers/pikachu_cadence_bug424_test.lua | 28 +- tests/drivers/pikachu_thunder_flash_2347.lua | 204 +++++++++++--- tests/drivers/route.lua | 23 +- tests/drivers/route_shop_buy_sell_bug2291.lua | 4 +- tests/drivers/shop_test.lua | 6 +- .../crystal_map_name_sign_speed_bug1994.lua | 18 +- tests/engine/fast_forward_rate_bug2471.lua | 91 +++++++ tests/engine/game3_trainer_sight_test.lua | 74 +++++ tests/engine/gen3_dex_summary_2461.lua | 75 ++++++ tests/engine/gen3_dex_summary_keys_2461.lua | 23 ++ tests/engine/mart_bag_full_bug2162.lua | 17 ++ tests/engine/mart_clerk_typing_bug2384.lua | 252 ++++++++++++++++++ tests/engine/mart_list_box_bug1887.lua | 10 + tests/engine/mart_price_text_bug2291.lua | 11 + tests/engine/mart_quantity_cap_bug1981.lua | 8 +- tests/engine/pad_hints_bug2452_test.lua | 172 ++++++++++++ .../engine/pikachu_thunderbolt_flash_2347.lua | 109 +++++++- tests/engine/present_sync_logic.lua | 11 +- tests/engine/save_editor_options_2388.lua | 102 +++++++ .../save_export_same_map_moved_2468.lua | 130 +++++++++ tests/engine/save_import_retry_bug420.lua | 2 +- tests/engine/save_map_context_bug889.lua | 1 + tests/fixture_data/map_window.lua | 1 + tests/game3_battle_exp_participants_test.lua | 115 ++++++++ tests/game3_battle_switch_and_faint_test.lua | 12 +- tests/game3_compat_connections_view_test.lua | 45 ++++ tests/game3_connection_list_test.lua | 114 ++++++++ tests/game3_cut_grass_mow_test.lua | 87 ++++++ tests/game3_multi_connection_test.lua | 171 ++++++++++++ tests/game3_objects_flag_sync_test.lua | 89 +++++++ tests/parity_yellow_pikapic_pose_2347.lua | 181 +++++++++++++ tests/run_tests.lua | 27 +- tests/save_convert_tests.lua | 4 +- tests/save_convert_yellow_bug838_test.lua | 1 + tools/make_yellow_manifest.py | 7 + tools/rom_manifest_yellow.json | 104 ++++++++ 89 files changed, 4416 insertions(+), 500 deletions(-) create mode 100644 src/core/PadHints.lua create mode 100644 src/core/game3/connections.lua create mode 100644 tests/drivers/game3_cut_grass_2470.lua create mode 100644 tests/drivers/game3_ghost_trainer_sight_2460.lua create mode 100644 tests/drivers/game3_import_dex_count_2461.lua create mode 100644 tests/drivers/game3_pad_battle_text_bug2452.lua create mode 100644 tests/drivers/game3_pewter_guide_bug2472.lua create mode 100644 tests/drivers/game3_shift_exp_2473.lua create mode 100644 tests/drivers/game3_six_island_water_path.lua create mode 100644 tests/drivers/mart_clerk_typing_bug2384.lua create mode 100644 tests/drivers/overworld_fast_forward_bug2471.lua create mode 100644 tests/engine/fast_forward_rate_bug2471.lua create mode 100644 tests/engine/gen3_dex_summary_2461.lua create mode 100644 tests/engine/gen3_dex_summary_keys_2461.lua create mode 100644 tests/engine/mart_clerk_typing_bug2384.lua create mode 100644 tests/engine/pad_hints_bug2452_test.lua create mode 100644 tests/engine/save_editor_options_2388.lua create mode 100644 tests/engine/save_export_same_map_moved_2468.lua create mode 100644 tests/game3_compat_connections_view_test.lua create mode 100644 tests/game3_connection_list_test.lua create mode 100644 tests/game3_cut_grass_mow_test.lua create mode 100644 tests/game3_multi_connection_test.lua create mode 100644 tests/parity_yellow_pikapic_pose_2347.lua diff --git a/conf.lua b/conf.lua index 71cfc6c5..74c9f021 100644 --- a/conf.lua +++ b/conf.lua @@ -132,6 +132,7 @@ function love.conf(t) t.accelerometerjoystick = false else t.window.resizable = true + pcall(function() require("src.core.PadHints").apply(osName) end) if os.getenv("POKEPORT_BACKGROUND") == "1" and osName == "OS X" then pcall(function() local ffi = require("ffi") diff --git a/main.lua b/main.lua index 88c657d9..4dd9ba50 100644 --- a/main.lua +++ b/main.lua @@ -16,6 +16,7 @@ end local editorMode = os.getenv("POKEPORT_EDITOR") == "1" or POKEPORT_EDITOR_MODE == true local SwitchDiagnostics = require("src.debug.SwitchDiagnostics") +local PadHints = require("src.core.PadHints") local LaunchOptions = require("src.core.LaunchOptions") local NxDisplay = require("src.core.NxDisplay") local PlatformHooks = require("src.core.PlatformHooks") @@ -991,6 +992,7 @@ end function love.gamepadpressed(joystick, button) SwitchDiagnostics.onJoystickEvent("gamepadpressed", joystick, button) + if PadHints.windowMinimized() then return end if editorMode then if EditorApp and EditorApp.gamepadpressed then return EditorApp.gamepadpressed(joystick, button) @@ -1032,6 +1034,7 @@ end function love.gamepadaxis(joystick, axis, value) SwitchDiagnostics.onJoystickEvent("gamepadaxis", joystick, axis, { value = value }) + if PadHints.windowMinimized() then value = 0 end if editorMode then if EditorApp and EditorApp.gamepadaxis then return EditorApp.gamepadaxis(joystick, axis, value) @@ -1052,6 +1055,7 @@ end function love.joystickpressed(joystick, button) SwitchDiagnostics.onJoystickEvent("joystickpressed", joystick, button) + if PadHints.windowMinimized() then return end if editorMode then if EditorApp and EditorApp.joystickpressed then return EditorApp.joystickpressed(joystick, button) @@ -1092,6 +1096,7 @@ end function love.joystickaxis(joystick, axis, value) SwitchDiagnostics.onJoystickEvent("joystickaxis", joystick, axis, { value = value }) + if PadHints.windowMinimized() then value = 0 end if editorMode then if EditorApp and EditorApp.joystickaxis then return EditorApp.joystickaxis(joystick, axis, value) @@ -1112,6 +1117,7 @@ end function love.joystickhat(joystick, hat, direction) SwitchDiagnostics.onJoystickEvent("joystickhat", joystick, hat, { direction = direction }) + if PadHints.windowMinimized() then direction = "c" end if editorMode then if EditorApp and EditorApp.joystickhat then return EditorApp.joystickhat(joystick, hat, direction) @@ -1150,6 +1156,7 @@ end -- direction's key-up can be delivered to the OS instead of the game while -- unfocused, so reset input on either transition rather than trust it. function love.focus(f) + SwitchDiagnostics.onFocus(f) if editorMode or TouchEditor then return end if Studio then if Studio.focus then Studio.focus(f) end diff --git a/src/core/FixedStep.lua b/src/core/FixedStep.lua index b501c1ef..9d8017c6 100644 --- a/src/core/FixedStep.lua +++ b/src/core/FixedStep.lua @@ -6,11 +6,9 @@ local FixedStep = {} FixedStep.GB_HZ = 4194304 / 70224 FixedStep.STEP = 1 / 60 --- Hard ceiling on catch-up debt (seconds of logic time drained in one --- rendered frame). 0.25s = 15 GB steps. Game:update may lower this for the --- current speed target but must never raise it: a hitch at high multipliers --- cannot dump unbounded steps and starve input / spiral the frame. FixedStep.MAX_ACCUM = 0.25 +FixedStep.WORK_FRACTION = 0.75 +FixedStep.clock = nil local MAX_ACCUM = FixedStep.MAX_ACCUM local SMOOTH_FRAMES = 4 local SMOOTH_MAX = 1 / 60 * 2.5 @@ -71,23 +69,34 @@ function FixedStep:init(callback) self.phasedFor = nil end --- The anti-spiral clamp is the steps-per-frame ceiling. Game:update sets --- maxAccum to the current speed's one-frame budget, hard-capped at MAX_ACCUM --- so high fast-forward cannot turn a hitch into input starvation. FixedStep.maxAccum = MAX_ACCUM --- Compute the live catch-up ceiling for a logic-speed multiplier. --- Always ≤ MAX_ACCUM; at least two steps so ordinary vsync wobble can recover. -function FixedStep.catchupLimit(speed) +function FixedStep.catchupLimit(speed, dt) speed = tonumber(speed) or 1 if speed < 1 then speed = 1 end - local target = speed * FixedStep.STEP * 1.5 - local floor = FixedStep.STEP * 2 + local step = FixedStep.STEP + local frame = tonumber(dt) or step + if frame ~= frame or frame < step or frame > SMOOTH_MAX then frame = step end + local target = speed * frame * 1.5 + local floor = step * 2 if target < floor then target = floor end - if target > MAX_ACCUM then target = MAX_ACCUM end return target end +local function workBudget(self, dt) + local base = self.refreshPeriod or self.STEP + local frame = dt + if frame < base then frame = base end + if frame > self.STEP * 2 then frame = math.max(base, self.STEP * 2) end + return frame * FixedStep.WORK_FRACTION +end + +local function workClock() + if FixedStep.clock then return FixedStep.clock end + local timer = love and love.timer + return timer and timer.getTime or nil +end + function FixedStep:update(dt, speed) -- A hitch's oversized dt lands on the frame AFTER discardCatchup was -- called (the hitch itself already ran inside the current step); absorb @@ -109,6 +118,7 @@ function FixedStep:update(dt, speed) -- Pathological wall-clock stalls: do not let dt alone exceed the catch-up -- ceiling before speed is applied (speed amplify would just hit the clamp). if dt > MAX_ACCUM then dt = MAX_ACCUM end + local frameDt = dt local period = self.refreshPeriod local snapped = false if period and dt > 0 then @@ -140,9 +150,15 @@ function FixedStep:update(dt, speed) self.accum = self.accum - self.accum % self.STEP + target end self.accum = math.min(self.accum + dt * speed, self.maxAccum or MAX_ACCUM) + local clock = speed > 1 and workClock() or nil + local deadline = clock and (clock() + workBudget(self, frameDt)) or nil while self.accum >= self.STEP - STEP_EPS do self.accum = self.accum - self.STEP self.callback(self.STEP) + if deadline and self.accum >= self.STEP - STEP_EPS and clock() >= deadline then + self.accum = self.accum % self.STEP + break + end end end diff --git a/src/core/Game.lua b/src/core/Game.lua index b4409285..e75225b2 100644 --- a/src/core/Game.lua +++ b/src/core/Game.lua @@ -404,7 +404,7 @@ function Game:update(dt) -- Give the accumulator room for one full frame at the current speed, -- or the anti-spiral clamp quietly caps every level above ~15X. local speed = self:logicSpeed() - FixedStep.maxAccum = FixedStep.catchupLimit(speed) + FixedStep.maxAccum = FixedStep.catchupLimit(speed, dt) FixedStep:update(dt, speed) -- Audio runs off real time at a fixed 60Hz regardless of game speed or -- display refresh, so fades and chip synthesis keep their intended tempo diff --git a/src/core/Game2.lua b/src/core/Game2.lua index bd24dd25..420540af 100644 --- a/src/core/Game2.lua +++ b/src/core/Game2.lua @@ -1311,12 +1311,12 @@ function Game2:update(dt) -- pokegold engine/menus/intro_menu.asm:848 IntroSequence: boot cinema runs on the same clock as the overworld local speed = self:logicSpeed() if self.phase == "boot" then - FixedStep.maxAccum = FixedStep.catchupLimit(speed) + FixedStep.maxAccum = FixedStep.catchupLimit(speed, dt) FixedStep:update(dt, speed) return end if not self.world or not self.world.map then return end - FixedStep.maxAccum = FixedStep.catchupLimit(speed) + FixedStep.maxAccum = FixedStep.catchupLimit(speed, dt) FixedStep:update(dt, speed) end diff --git a/src/core/Game3.lua b/src/core/Game3.lua index 3176dd0b..3abc41d3 100644 --- a/src/core/Game3.lua +++ b/src/core/Game3.lua @@ -633,7 +633,7 @@ end function Game3:update(dt) local speed = self:logicSpeed() - FixedStep.maxAccum = FixedStep.catchupLimit(speed) + FixedStep.maxAccum = FixedStep.catchupLimit(speed, dt) FixedStep:update(dt, speed) self._audioAccum = (self._audioAccum or 0) + dt local STEP = 1 / 60 diff --git a/src/core/Input.lua b/src/core/Input.lua index 13b36d25..859ca8ce 100644 --- a/src/core/Input.lua +++ b/src/core/Input.lua @@ -2,6 +2,7 @@ -- `down` = held this frame; `pressed` = edge, consumed per fixed step. local GamepadMap = require("src.core.GamepadMap") +local PadHints = require("src.core.PadHints") local Input = {} @@ -361,16 +362,20 @@ function Input:pollPads() self.padSuppress = suppress end local backDown = nil + local minimized = nil for i = 1, #list do local e = list[i] local down = anyPadDown(pads, e.button) local sources = self.sources[e.btn] local held = sources ~= nil and sources[e.source] == true if not down then suppress[e.button] = nil end + if down and not held and minimized == nil then + minimized = PadHints.windowMinimized() + end if held and not down then release(self, e.btn, e.source) notePadRepair("release", e.button) - elseif down and not held and not mute and not suppress[e.button] + elseif down and not held and not mute and not minimized and not suppress[e.button] and not self.padActions[e.button] then if e.chord and backDown == nil then backDown = self.state.select == true or anyPadDown(pads, "back") diff --git a/src/core/PadHints.lua b/src/core/PadHints.lua new file mode 100644 index 00000000..9a6eb8ca --- /dev/null +++ b/src/core/PadHints.lua @@ -0,0 +1,73 @@ +local PadHints = {} + +PadHints.BACKGROUND_HINT = "SDL_JOYSTICK_ALLOW_BACKGROUND_EVENTS" + +function PadHints.apply(osName, ffiLike, getenv) + if osName ~= "Windows" then return false end + getenv = getenv or os.getenv + local okEnv, flag = pcall(getenv, "POKEPORT_PAD_BACKGROUND") + if okEnv and flag == "0" then return false end + local ok, set = pcall(function() + local ffi = ffiLike or require("ffi") + pcall(ffi.cdef, "int SDL_SetHint(const char *name, const char *value);") + local sdl = ffi.load("SDL2") + return sdl.SDL_SetHint(PadHints.BACKGROUND_HINT, "1") + end) + return ok and set ~= nil and set ~= 0 +end + +function PadHints.windowMinimized() + local win = love and love.window + if not win then return false end + if win.isMinimized then + local ok, v = pcall(win.isMinimized) + if ok then return v == true end + end + if win.isVisible then + local ok, v = pcall(win.isVisible) + if ok then return v == false end + end + return false +end + +function PadHints.hasFocus() + local win = love and love.window + if not (win and win.hasFocus) then return nil end + local ok, v = pcall(win.hasFocus) + if ok then return v end + return nil +end + +local fgReady = nil + +function PadHints.foreground(osName, ffiLike) + if osName ~= "Windows" then return nil end + if fgReady == false then return nil end + local ok, owner = pcall(function() + local ffi = ffiLike or require("ffi") + if not fgReady then + pcall(ffi.cdef, [[ + void *GetForegroundWindow(void); + unsigned long GetWindowThreadProcessId(void *hwnd, unsigned long *pid); + unsigned long GetCurrentProcessId(void); + ]]) + fgReady = true + end + local hwnd = ffi.C.GetForegroundWindow() + if hwnd == nil then return "none" end + local pid = ffi.new("unsigned long[1]") + ffi.C.GetWindowThreadProcessId(hwnd, pid) + return pid[0] == ffi.C.GetCurrentProcessId() and "ours" or "other" + end) + if not ok then + fgReady = false + return nil + end + return owner +end + +function PadHints._resetForTests() + fgReady = nil +end + +return PadHints diff --git a/src/core/PresentSync.lua b/src/core/PresentSync.lua index 8091392d..7ff9ba1f 100644 --- a/src/core/PresentSync.lua +++ b/src/core/PresentSync.lua @@ -8,8 +8,6 @@ -- unknown rates fail closed. -- 3. Fallback cascade — ungated / failed / abandoned waits force FrameCap -- immediately; logic never snaps to panel Hz unless sync is confirmed. --- 4. (FixedStep) catch-up debt is hard-capped so speed multipliers cannot --- spiral into input-starving multi-frame dumps. local PresentSync = {} diff --git a/src/core/SaveData.lua b/src/core/SaveData.lua index ee7522b4..cc9473a0 100644 --- a/src/core/SaveData.lua +++ b/src/core/SaveData.lua @@ -1163,11 +1163,8 @@ function SaveData.slotSummary(save) local gen3 = save.generation == 3 or (vinfo and vinfo.generation == 3) or (save.engine == "game3") or false local dexCount = 0 if gen3 then - local dex = save.dex or save.pokedex or {} - local owned = dex.owned or dex.caught or {} - for _, has in pairs(owned) do - if has then dexCount = dexCount + 1 end - end + local okD, Dex = pcall(require, "src.core.game3.dex") + dexCount = okD and Dex and Dex.summaryCount and Dex.summaryCount(save) or 0 elseif gen2 then for _, has in pairs((save.pokedex and save.pokedex.caught) or {}) do if has then dexCount = dexCount + 1 end @@ -1422,7 +1419,18 @@ local function writeSlotIn(key, slotId, saveTable) end if type(saveTable) ~= "table" then return false, "missing save table" end local main, bak, tmp = slotNames(key, slotId) - local encoded = SaveSerializer.encode(saveTable) + local vinfo = type(saveTable.version) == "string" and GameVersion.info(saveTable.version) + or type(key) == "string" and GameVersion.info(key) + local gen3 = saveTable.engine == "game3" or saveTable.generation == 3 + or (vinfo and vinfo.generation == 3) or false + local body = saveTable + if not gen3 and saveTable.options ~= nil then + body = {} + for k, v in pairs(saveTable) do + if k ~= "options" then body[k] = v end + end + end + local encoded = SaveSerializer.encode(body) local fs = persistFs(nil) ensureParentDir(fs, main) if fs.getInfo(main) then diff --git a/src/core/game3/battle/engine.lua b/src/core/game3/battle/engine.lua index 72351bf2..a92faa35 100644 --- a/src/core/game3/battle/engine.lua +++ b/src/core/game3/battle/engine.lua @@ -1949,7 +1949,12 @@ function Engine.performSwitch(st, adapter, side, slot, opts) end local foe = (side == "player") and st.enemy or st.player if side == "player" then - State.trackParticipant(st, st.enemy, slot) + if opts.isShift or opts.reason == "shift" then + -- pokefirered/src/battle_script_commands.c:5945 + State.resetSentPokes(st) + else + State.trackParticipant(st, st.enemy, slot) + end elseif st.player then -- pokefirered/src/battle_util.c:254 State.opponentSwitchInResetSentPokes(st, nb) diff --git a/src/core/game3/battle/switch_seq.lua b/src/core/game3/battle/switch_seq.lua index 6f72fc9e..89f66a7c 100644 --- a/src/core/game3/battle/switch_seq.lua +++ b/src/core/game3/battle/switch_seq.lua @@ -159,8 +159,9 @@ local function switch_in_text(st, battler) return BattleText.get(BattleText.SWITCHINMON, SwitchSeq.switchInFill(st, battler)) end -local function apply_entry_triggers(st, side, pushMsg) +local function apply_entry_triggers(st, side, pushMsg, opts) if not st then return end + opts = opts or {} local b = st[side] if not b or not b.mon or (tonumber(b.mon.hp) or 0) <= 0 then return end @@ -168,7 +169,7 @@ local function apply_entry_triggers(st, side, pushMsg) local sideState = (side == "player") and st.playerSide or st.enemySide local hazards = sideState and sideState.hazards or {} local spikesLayers = tonumber(hazards.spikes or hazards.SPIKES) or 0 - if spikesLayers > 0 and b and b.mon then + if not opts.noSpikes and spikesLayers > 0 and b and b.mon then local isFlying = (b.type1 == 2 or b.type2 == 2 or b.type1 == "FLYING" or b.type2 == "FLYING") local hasLevitate = (b.ability == "LEVITATE" or b.ability == 26) if not isFlying and not hasLevitate then @@ -186,7 +187,7 @@ local function apply_entry_triggers(st, side, pushMsg) end -- Ability: Intimidate (ability 22 or "INTIMIDATE") - if (b.ability == 22 or b.ability == "INTIMIDATE") and (tonumber(b.mon.hp) or 0) > 0 then + if not opts.noIntimidate and (b.ability == 22 or b.ability == "INTIMIDATE") and (tonumber(b.mon.hp) or 0) > 0 then local oppSide = (side == "player") and "enemy" or "player" local opp = st[oppSide] if opp and opp.mon and (tonumber(opp.mon.hp) or 0) > 0 then @@ -232,24 +233,45 @@ local function switch_out_effects(st, battler) capture_events(function(ad) Engine.switchOutEffects(st, ad, battler) end) end +local function fallback_entry(st, sides, pushMsg, opts) + opts = opts or {} + local deferred = opts.deferred or {} + if not opts.deferIntimidate and #deferred == 0 then + for _, side in ipairs(sides) do apply_entry_triggers(st, side, pushMsg) end + return + end + for _, side in ipairs(sides) do apply_entry_triggers(st, side, pushMsg, { noIntimidate = true }) end + if opts.deferIntimidate then return end + for _, side in ipairs(deferred) do apply_entry_triggers(st, side, pushMsg, { noSpikes = true }) end + for _, side in ipairs(sides) do apply_entry_triggers(st, side, pushMsg, { noSpikes = true }) end +end + -- pokefirered/src/battle_script_commands.c:4960 -local function engine_entry_events(st, sides) +local function engine_entry_events(st, sides, opts) + opts = opts or {} local Engine = package.loaded["src.core.game3.battle.engine"] if not (Engine and Engine.switchInEffects and battle_adapter()) then return nil end return capture_events(function(ad) for _, side in ipairs(sides) do local b = st and ((type(side) == "number") and State.battler(st, side) or st[side]) if b and b.mon and (tonumber(b.mon.hp) or 0) > 0 then - Engine.switchInEffects(st, ad, b, { spikes = true }) + Engine.switchInEffects(st, ad, b, { spikes = true, deferIntimidate = opts.deferIntimidate }) + end + end + if opts.deferred and not opts.deferIntimidate then + local Abilities = require("src.core.game3.battle.abilities") + -- pokefirered/src/battle_util.c:1209 + for _ = 1, 4 do + if not (Abilities.runIntimidate(ad) or Abilities.runTrace(ad)) then break end end end end) end -local function headless_entry(st, sides) - local evs = engine_entry_events(st, sides) +local function headless_entry(st, sides, opts) + local evs = engine_entry_events(st, sides, opts) if evs == nil then - for _, side in ipairs(sides) do apply_entry_triggers(st, side, SwitchSeq._pushMsg) end + fallback_entry(st, sides, SwitchSeq._pushMsg, opts) return end for _, e in ipairs(evs) do @@ -442,7 +464,7 @@ function SwitchSeq.beginEventSwitchIn(st, side, opts) return true end ---- Retail Shift sequence: Player recalls active mon -> Enemy sends out replacement FIRST -> Player sends out replacement SECOND. +-- pokefirered/data/battle_scripts_1.s:2856 function SwitchSeq.beginShiftSwitch(st, playerSlot, enemySlot, opts) opts = opts or {} SwitchSeq.reset() @@ -459,38 +481,39 @@ function SwitchSeq.beginShiftSwitch(st, playerSlot, enemySlot, opts) switch_out_effects(st, oldBattler) State.syncBattlerToParty(st.player, st.playerParty) State.wipeVolatilesAndStages(st.player) - st.enemy = State.makeBattler(st.foeParty[enemySlot], "enemy", { partyIndex = enemySlot, st = st }) - if SwitchSeq._pushMsg then SwitchSeq._pushMsg(switch_in_text(st, st.enemy)) end st.player = State.makeBattler(st.playerParty[playerSlot], "player", { partyIndex = playerSlot, st = st, state = st }) - State.opponentSwitchInResetSentPokes(st, st.enemy) - State.trackParticipant(st, st.enemy, playerSlot) - Anim.syncDisplayFromState(st) if SwitchSeq._pushMsg then SwitchSeq._pushMsg(switch_in_text(st, st.player)) end - headless_entry(st, { "enemy", "player" }) + headless_entry(st, { "player" }, { deferIntimidate = true }) + -- pokefirered/src/battle_script_commands.c:5945 + State.resetSentPokes(st) + st.enemy = State.makeBattler(st.foeParty[enemySlot], "enemy", { partyIndex = enemySlot, st = st }) + -- pokefirered/src/battle_util.c:254 + State.opponentSwitchInResetSentPokes(st, st.enemy) + Anim.syncDisplayFromState(st) + if SwitchSeq._pushMsg then SwitchSeq._pushMsg(switch_in_text(st, st.enemy)) end + headless_entry(st, { "enemy" }, { deferred = { "player" } }) finish() return false end local steps = { - -- 1. Player recall { kind = "msg", data = { text = withdrawMsg } }, { kind = "withdraw", data = { side = "player" } }, - -- 2. Enemy sendout first (retail FRLG order) - { kind = "swap_data", data = { side = "enemy", newSlot = enemySlot, isShift = true, reason = "shift" } }, - { kind = "msg_sendout", data = { side = "enemy" } }, - { kind = "sendout_enemy", data = { slot = enemySlot } }, - { kind = "shiny_check", data = { side = "enemy" } }, - { kind = "cry", data = { side = "enemy" } }, - { kind = "healthbox", data = { side = "enemy" } }, - -- 3. Player sendout second { kind = "swap_data", data = { side = "player", newSlot = playerSlot, isShift = true, reason = "shift" } }, { kind = "msg_sendout", data = { side = "player" } }, { kind = "sendout_player", data = { slot = playerSlot } }, { kind = "shiny_check", data = { side = "player" } }, { kind = "cry", data = { side = "player" } }, { kind = "healthbox", data = { side = "player" } }, - -- 4. Entry abilities and hazards in speed order - { kind = "entry_triggers", data = { sides = { "enemy", "player" } } }, + { kind = "entry_triggers", data = { side = "player", deferIntimidate = true } }, + -- pokefirered/data/battle_scripts_1.s:2874 + { kind = "swap_data", data = { side = "enemy", newSlot = enemySlot, reason = "shift" } }, + { kind = "msg_sendout", data = { side = "enemy" } }, + { kind = "sendout_enemy", data = { slot = enemySlot } }, + { kind = "shiny_check", data = { side = "enemy" } }, + { kind = "cry", data = { side = "enemy" } }, + { kind = "healthbox", data = { side = "enemy" } }, + { kind = "entry_triggers", data = { side = "enemy", deferred = { "player" } } }, } SwitchSeq._steps = steps @@ -591,16 +614,22 @@ local function run_step(step) return end switch_out_effects(st, st and st[side]) + local isShift = d.isShift or d.reason == "shift" if side == "player" then if st and st.player then - if not d.isShift and d.reason ~= "shift" then + if not isShift then State.trackParticipant(st, st.enemy, st.player.partyIndex or 1) end State.syncBattlerToParty(st.player, st.playerParty) State.wipeVolatilesAndStages(st.player, { batonPass = d.batonPass }) end st.player = State.makeBattler(st.playerParty[newSlot], "player", { partyIndex = newSlot, st = st }) - State.trackParticipant(st, st.enemy, newSlot) + if isShift then + -- pokefirered/src/battle_script_commands.c:5945 + State.resetSentPokes(st) + else + State.trackParticipant(st, st.enemy, newSlot) + end else if st and st.enemy then State.syncBattlerToParty(st.enemy, st.foeParty) @@ -608,9 +637,6 @@ local function run_step(step) end st.enemy = State.makeBattler(st.foeParty[newSlot], "enemy", { partyIndex = newSlot, st = st, state = st }) State.opponentSwitchInResetSentPokes(st, st.enemy) - if d.isShift or d.reason == "shift" then - st.enemy.participants = {} - end end Anim.syncDisplayFromState(st) advance() @@ -753,11 +779,10 @@ local function run_step(step) end) sides = sorted end - local evs = engine_entry_events(st, sides) + local entryOpts = { deferIntimidate = d.deferIntimidate, deferred = d.deferred } + local evs = engine_entry_events(st, sides, entryOpts) if evs == nil then - for _, sSide in ipairs(sides) do - apply_entry_triggers(st, sSide, SwitchSeq._pushMsg) - end + fallback_entry(st, sides, SwitchSeq._pushMsg, entryOpts) elseif #evs > 0 then local AnimSeq = require("src.core.game3.battle.anim_seq") local Ui = require("src.core.game3.battle.ui") diff --git a/src/core/game3/collision.lua b/src/core/game3/collision.lua index 07dbef53..75869365 100644 --- a/src/core/game3/collision.lua +++ b/src/core/game3/collision.lua @@ -2,6 +2,7 @@ -- Built from mapDef.blocks + tileset.collision (Gen2 COLL_* quads baked from -- FRLG metatile attrs at extract). Does not call World:step / Player:tryMove. +local Connections = require("src.core.game3.connections") local Collision = {} local DELTA = { @@ -582,8 +583,7 @@ function Collision.connectionLanding(destDef, conn, dir, fromCx, fromCy) else return nil end - x = math.max(0, math.min(destW - 1, x)) - y = math.max(0, math.min(destH - 1, y)) + if x < 0 or y < 0 or x >= destW or y >= destH then return nil end return x, y end @@ -614,17 +614,17 @@ function Collision.tryConnection(game, fromX, fromY, dir, run) local mapDef = Collision._mapDef if not mapDef or type(mapDef.connections) ~= "table" then return false end - local conn = mapDef.connections[dir] - or mapDef.connections[DIR_CONN[dir] or ""] - if not conn then return false end - local destMap = conn.map or conn.mapId - if type(destMap) ~= "string" then return false end - local data = game and game.data and game.data.maps - local destDef = data and data[destMap] - if not destDef then return false end + if not data then return false end local Map = require("src.core.game3.map") - if Map.ensureMidLayout then Map.ensureMidLayout(game, destMap, destDef) end + -- pokefirered/src/fieldmap.c:673 + local conn, destDef = Connections.incoming(mapDef, DIR_CONN[dir], fromX, fromY, function(id) + local def = data[id] + if def and Map.ensureMidLayout then Map.ensureMidLayout(game, id, def) end + return def + end) + if not conn then return false end + local destMap = conn.map local lx, ly = Collision.connectionLanding(destDef, conn, dir, fromX, fromY) if not lx then return false end diff --git a/src/core/game3/connections.lua b/src/core/game3/connections.lua new file mode 100644 index 00000000..37d5f15f --- /dev/null +++ b/src/core/game3/connections.lua @@ -0,0 +1,117 @@ +local Connections = {} + +local CARDINAL = { + north = "north", south = "south", west = "west", east = "east", + up = "north", down = "south", left = "west", right = "east", +} + +function Connections.cardinal(dir) + return CARDINAL[dir] +end + +local function entry(dir, c) + local d = CARDINAL[dir] + local map = type(c) == "table" and (c.map or c.mapId) or c + if not d or type(map) ~= "string" then return nil end + return { dir = d, map = map, offset = type(c) == "table" and tonumber(c.offset) or 0 } +end + +function Connections.each(def) + local out = {} + local conns = def and def.connections + if type(conns) ~= "table" then return out end + local n = #conns + for i = 1, n do + local c = conns[i] + local e = type(c) == "table" and entry(c.dir or c.direction, c) + if e then out[#out + 1] = e end + end + local keyed = {} + for k, c in pairs(conns) do + if type(k) == "string" then + local e = entry(k, c) + if e then keyed[#keyed + 1] = { k = k, e = e } end + end + end + table.sort(keyed, function(a, b) return a.k < b.k end) + for _, kv in ipairs(keyed) do out[#out + 1] = kv.e end + return out +end + +function Connections.sizeOf(def) + local L = def and def.midLayout + if L and L.width and L.height then return L.width, L.height end + return (tonumber(def and def.width) or 0) * 2, (tonumber(def and def.height) or 0) * 2 +end + +local function vertical(dir) + return dir == "north" or dir == "south" +end + +-- pokefirered/src/fieldmap.c:724 +local function coordInIncoming(coord, srcMax, destMax, offset) + local lo = math.max(offset, 0) + if destMax + offset < srcMax then srcMax = destMax + offset end + return lo <= coord and coord <= srcMax +end + +-- pokefirered/src/fieldmap.c:686 +function Connections.incoming(def, dir, x, y, destDefOf) + dir = CARDINAL[dir] + if not dir then return nil end + local srcW, srcH = Connections.sizeOf(def) + for _, c in ipairs(Connections.each(def)) do + if c.dir == dir then + local destDef = destDefOf(c.map) + if destDef then + local w, h = Connections.sizeOf(destDef) + local hit + if vertical(dir) then + hit = coordInIncoming(x, srcW, w, c.offset) + else + hit = coordInIncoming(y, srcH, h, c.offset) + end + if hit then return c, destDef end + end + end + end + return nil +end + +-- pokefirered/src/fieldmap.c:745 +function Connections.localPos(n, x, y, srcW, srcH) + local w, h = Connections.sizeOf(n.def) + local off = tonumber(n.offset) or 0 + local lx, ly + if n.dir == "north" then + lx, ly = x - off, h + y + elseif n.dir == "south" then + lx, ly = x - off, y - srcH + elseif n.dir == "west" then + lx, ly = w + x, y - off + elseif n.dir == "east" then + lx, ly = x - srcW, y - off + else + return nil + end + local along = vertical(n.dir) and lx or ly + local span = vertical(n.dir) and w or h + if along < 0 or along >= span then return nil end + return lx, ly +end + +-- pokefirered/src/fieldmap.c:761 +function Connections.atPos(list, x, y, srcW, srcH) + for _, n in ipairs(list or {}) do + local dir = n.dir + local skip = (dir == "north" and y >= 0) or (dir == "south" and y < srcH) + or (dir == "west" and x >= 0) or (dir == "east" and x < srcW) + if not skip and n.def then + local lx, ly = Connections.localPos(n, x, y, srcW, srcH) + if lx then return n, lx, ly end + end + end + return nil +end + +return Connections diff --git a/src/core/game3/dex.lua b/src/core/game3/dex.lua index fbebf608..27c1ebcc 100644 --- a/src/core/game3/dex.lua +++ b/src/core/game3/dex.lua @@ -242,6 +242,65 @@ function Dex.countOwned(dex, mode) return Dex.countCaught(dex, mode) end +local function keyed(t, id) + if type(t) ~= "table" then return nil end + local v = t[id] + if v == nil then v = t[tostring(id)] end + if v == nil then v = t[string.format("0x%X", id)] end + return v +end + +-- pokefirered/src/event_data.c:107 +function Dex.nationalEnabled(save) + if type(save) ~= "table" then return false end + local dex = type(save.dex) == "table" and save.dex or {} + if dex.national == true or dex.nationalUnlocked == true or dex.isNationalUnlocked == true + or save.national_dex_unlocked == true then + return true + end + local flag = keyed(save.flags, 0x840) + if flag == true or (type(save.flags) == "table" and save.flags.FLAG_SYS_NATIONAL_DEX == true) then + return true + end + local var = keyed(save.vars, 0x404E) + if var == nil and type(save.vars) == "table" then var = save.vars.VAR_NATIONAL_DEX end + return tonumber(var) == 0x6258 +end + +-- pokefirered/src/main_menu.c:643 +function Dex.summaryCount(save) + if type(save) ~= "table" then return 0 end + local dex = type(save.dex) == "table" and save.dex + or type(save.pokedex) == "table" and save.pokedex or {} + local national = Dex.nationalEnabled(save) + local counted, n = {}, 0 + for _, key in ipairs({ "caught", "owned" }) do + for sp, on in pairs(type(dex[key]) == "table" and dex[key] or {}) do + local id = tonumber(sp) + if not id and type(sp) == "string" then + local ok, res = pcall(resolve_species_id, sp) + id = ok and tonumber(res) or nil + end + if id and on and on ~= 0 and not counted[id] + and id >= 1 and (national or id <= Dex.KANTO_MAX) then + counted[id] = true + n = n + 1 + end + end + end + local ci = type(save.modData) == "table" and type(save.modData.cartImport) == "table" + and save.modData.cartImport + local maxNat = national and Dex.NATIONAL_MAX or Dex.KANTO_MAX + for _, nat in ipairs(ci and type(ci.dexOwned) == "table" and ci.dexOwned or {}) do + nat = tonumber(nat) + if nat and nat >= 1 and nat <= maxNat and not (nat <= Dex.HOST_MAX and counted[nat]) then + if nat <= Dex.HOST_MAX then counted[nat] = true end + n = n + 1 + end + end + return n +end + --- Split for returnToHost: hostUpdates (1–251) + national sidecar (252+). function Dex.splitForHost(dex) local hostSeen, hostCaught = {}, {} diff --git a/src/core/game3/doors.lua b/src/core/game3/doors.lua index 8621eeb2..8ec4401e 100644 --- a/src/core/game3/doors.lua +++ b/src/core/game3/doors.lua @@ -133,8 +133,8 @@ local function resolveLayout(mapId) end end - if Map and Map.neighbors then - for _, n in pairs(Map.neighbors) do + if Map and Map.neighborList then + for _, n in ipairs(Map.neighborList) do if n.def and n.def.midLayout then if norm(n.map or n.mapId) == key then return n.def.midLayout, n.def.pair diff --git a/src/core/game3/field.lua b/src/core/game3/field.lua index 28987fe7..fc1a96c3 100644 --- a/src/core/game3/field.lua +++ b/src/core/game3/field.lua @@ -474,6 +474,7 @@ function Field.useItemfinder(session, showOWMessage) width = layout and layout.width, height = layout and layout.height, neighbors = Map.neighbors, + neighborList = Map.neighborList, eventsFor = function(id) return get_map_bg_events(game, id) end, }) @@ -995,14 +996,21 @@ function Field.executeFieldMove(payload) local Map = require("src.core.game3.map") local def = Map.currentDef() local layout = def and def.midLayout - if layout and layout.midAt and layout.setMidAt then - local Collision = require("src.core.game3.collision") + if layout then local FieldMoves = require("src.core.game3.field_moves") + local w, h = layout.width or 0, layout.height or 0 + local Collision = require("src.core.game3.collision") + -- pokefirered/src/fldeff_rocksmash.c:31 + local elev = P.elevation or 0 FieldMoves.mowGrass3x3(P.cellX, P.cellY, function(x, y) return layout:midAt(x, y) end, - function(x, y, mid) layout:setMidAt(x, y, mid) end, - function(x, y) return Collision.isGrass(x, y) end) - local okFv, FieldView = pcall(require, "src.core.game3.field_view") - if okFv and FieldView then FieldView._nativeDirty = true end + function(x, y, mid) Field.setMetatile(x, y, mid, false) end, + function(x, y) + -- pokefirered/src/fldeff_cut.c:219 + return x >= 0 and y >= 0 and x < w and y < h and layout:elevAt(x, y) == elev + and Collision.isGrass(x, y) + end) + -- pokefirered/src/field_effect_helpers.c:313 + if not Collision.isGrass(P.cellX, P.cellY) then FieldEffects.clearTallGrass() end end FieldEffects.startCutGrass(P.cellX, P.cellY, function() Field.locked = false diff --git a/src/core/game3/field_moves.lua b/src/core/game3/field_moves.lua index dc6abf33..be04f8c6 100644 --- a/src/core/game3/field_moves.lua +++ b/src/core/game3/field_moves.lua @@ -106,6 +106,8 @@ FieldMoves.CUT_GRASS_METATILES = { [0x300] = 0x310, -- FuchsiaCity: SafariZoneTreeTopLeft_Grass -> SafariZoneTreeTopLeft_Mowed [0x301] = 0x311, -- FuchsiaCity: SafariZoneTreeTopMiddle_Grass -> SafariZoneTreeTopMiddle_Mowed [0x302] = 0x312, -- FuchsiaCity: SafariZoneTreeTopRight_Grass -> SafariZoneTreeTopRight_Mowed + -- pokefirered/include/constants/metatile_labels.h:295 + [0x284] = 0x281, } -- Metatile terrain / collision behaviors @@ -757,7 +759,8 @@ end -- `getMetatileFn(x, y)`: returns numeric metatileId -- `setMetatileFn(x, y, newMetatileId)`: applies new metatileId -- Returns count of cut tiles -function FieldMoves.mowGrass3x3(cx, cy, getMetatileFn, setMetatileFn, isGrassFn) +-- pokefirered/src/fldeff_cut.c:200 +function FieldMoves.mowGrass3x3(cx, cy, getMetatileFn, setMetatileFn, sameElevationFn) if not getMetatileFn or not setMetatileFn then return 0 end local count = 0 @@ -765,13 +768,10 @@ function FieldMoves.mowGrass3x3(cx, cy, getMetatileFn, setMetatileFn, isGrassFn) for dx = -1, 1 do local x = cx + dx local y = cy + dy - local mid = getMetatileFn(x, y) - if mid then - local newMid = FieldMoves.CUT_GRASS_METATILES[mid] - if not newMid and isGrassFn and isGrassFn(x, y) then - -- Default flat-ground replacement in general tileset - newMid = 0x001 - end + if not sameElevationFn or sameElevationFn(x, y) then + local mid = getMetatileFn(x, y) + -- pokefirered/src/fldeff_cut.c:237 + local newMid = mid and FieldMoves.CUT_GRASS_METATILES[mid] if newMid then setMetatileFn(x, y, newMid) count = count + 1 diff --git a/src/core/game3/itemfinder.lua b/src/core/game3/itemfinder.lua index bdfe10df..53852380 100644 --- a/src/core/game3/itemfinder.lua +++ b/src/core/game3/itemfinder.lua @@ -1,3 +1,4 @@ +local Connections = require("src.core.game3.connections") local Itemfinder = {} local SE_ITEMFINDER = 65 @@ -36,54 +37,22 @@ local function hidden_item_at_pos(events, x, y, flagSet) return false end -local function neighbor(neighbors, a, b) - return neighbors and (neighbors[a] or neighbors[b]) -end - -local function layout_size(def) - local L = def and def.midLayout - if L then return L.width or 0, L.height or 0 end - return (tonumber(def and def.width) or 0) * 2, (tonumber(def and def.height) or 0) * 2 +local function neighbor_list(opts) + if opts.neighborList then return opts.neighborList end + local list = {} + for k, n in pairs(opts.neighbors or {}) do + local dir = Connections.cardinal(n.dir or k) + if dir then + list[#list + 1] = { dir = dir, map = n.map, mapId = n.mapId, def = n.def, offset = n.offset } + end + end + return list end -- pokefirered/src/fieldmap.c:761, src/itemfinder.c:312 local function connected_hidden_item(opts, lx, ly) - local curW, curH = opts.width, opts.height - local n = opts.neighbors - local conn, cx, cy - if ly < 0 then - conn = neighbor(n, "north", "up") - if conn then - local w, h = layout_size(conn.def) - local off = tonumber(conn.offset) or 0 - if lx - off >= 0 and lx - off < w then cx, cy = lx - off, h + ly end - end - end - if not cx and ly >= curH then - conn = neighbor(n, "south", "down") - if conn then - local w = layout_size(conn.def) - local off = tonumber(conn.offset) or 0 - if lx - off >= 0 and lx - off < w then cx, cy = lx - off, ly - curH end - end - end - if not cx and lx < 0 then - conn = neighbor(n, "west", "left") - if conn then - local w, h = layout_size(conn.def) - local off = tonumber(conn.offset) or 0 - if ly - off >= 0 and ly - off < h then cx, cy = w + lx, ly - off end - end - end - if not cx and lx >= curW then - conn = neighbor(n, "east", "right") - if conn then - local _, h = layout_size(conn.def) - local off = tonumber(conn.offset) or 0 - if ly - off >= 0 and ly - off < h then cx, cy = lx - curW, ly - off end - end - end - if not cx then return false end + local conn, cx, cy = Connections.atPos(neighbor_list(opts), lx, ly, opts.width, opts.height) + if not conn then return false end return hidden_item_at_pos(opts.eventsFor(conn.map or conn.mapId), cx, cy, opts.flagSet) end diff --git a/src/core/game3/map.lua b/src/core/game3/map.lua index 6998d392..61c8cacb 100644 --- a/src/core/game3/map.lua +++ b/src/core/game3/map.lua @@ -4,11 +4,13 @@ local MapIds = require("src.core.game3.map_ids") local ModRuntime = require("src.mods.Runtime") +local Connections = require("src.core.game3.connections") local Map = {} Map.current = nil Map._announced = nil Map.neighbors = {} +Map.neighborList = {} Map._loadedLayouts = {} Map._def = nil Map._currentDef = nil @@ -32,33 +34,34 @@ end function Map.loadNeighborsDepth1(game, primaryDef) Map.neighbors = {} + Map.neighborList = {} if not primaryDef or type(primaryDef.connections) ~= "table" then return Map.neighbors end local data = game and game.data and game.data.maps if not data then return Map.neighbors end - for dir, conn in pairs(primaryDef.connections) do - local mid = type(conn) == "table" and conn.map or conn - if type(mid) == "string" and data[mid] then + -- pokefirered/src/fieldmap.c:129 + for _, conn in ipairs(Connections.each(primaryDef)) do + local mid = conn.map + if data[mid] then local def = data[mid] Map.ensureMidLayout(game, mid, def) - Map.neighbors[dir] = { + local n = { + dir = conn.dir, map = mid, mapId = mid, def = def, - offset = type(conn) == "table" and (conn.offset or 0) or 0, + offset = conn.offset, } + Map.neighborList[#Map.neighborList + 1] = n + Map.neighbors[conn.dir] = Map.neighbors[conn.dir] or n Map._loadedLayouts[mid] = true end end return Map.neighbors end -local function cell_size(def) - local L = def and def.midLayout - if L and L.width and L.height then return L.width or 0, L.height or 0 end - return (tonumber(def and def.width) or 0) * 2, (tonumber(def and def.height) or 0) * 2 -end +local cell_size = Connections.sizeOf Map.world = {} Map._worldRoot = nil @@ -86,21 +89,22 @@ function Map.computeWorld(maps, rootId, hops, reachW, reachH, ensure) local cur = queue[qi] qi = qi + 1 local curW, curH = cell_size(cur.def) - for dir, conn in pairs(cur.def.connections or {}) do - local destId = type(conn) == "table" and conn.map or conn - local destDef = type(destId) == "string" and maps[destId] or nil + for _, conn in ipairs(Connections.each(cur.def)) do + local dir = conn.dir + local destId = conn.map + local destDef = maps[destId] if destDef and destDef ~= rootDef and not placed[destId] then - local offset = (type(conn) == "table" and tonumber(conn.offset) or 0) or 0 + local offset = conn.offset ensure(destId, destDef) local destW, destH = cell_size(destDef) local ox, oy - if dir == "north" or dir == "up" then + if dir == "north" then ox, oy = offset, -destH - elseif dir == "south" or dir == "down" then + elseif dir == "south" then ox, oy = offset, curH - elseif dir == "west" or dir == "left" then + elseif dir == "west" then ox, oy = -destW, offset - elseif dir == "east" or dir == "right" then + elseif dir == "east" then ox, oy = curW, offset end if ox then @@ -153,28 +157,12 @@ end function Map.overscanSlices() local slices = {} - for dir, n in pairs(Map.neighbors) do - slices[#slices + 1] = { dir = dir, mapId = n.map or n.mapId, offset = n.offset } + for _, n in ipairs(Map.neighborList or {}) do + slices[#slices + 1] = { dir = n.dir, mapId = n.map or n.mapId, offset = n.offset } end return slices end -local function neighborFor(cardinal) - local n = Map.neighbors - if not n then return nil end - -- Dataset keys are north/south/west/east; some callers use up/down/left/right. - if cardinal == "north" or cardinal == "up" then - return n.north or n.up - elseif cardinal == "south" or cardinal == "down" then - return n.south or n.down - elseif cardinal == "west" or cardinal == "left" then - return n.west or n.left - elseif cardinal == "east" or cardinal == "right" then - return n.east or n.right - end - return n[cardinal] -end - --- Resolve a cell in current-map space, sampling connected neighbors when OOB -- (pret VMap connection fill). Returns mid, sourcePair. OOB with no neighbor -- falls through to primary border tiling. @@ -199,40 +187,44 @@ function Map.worldMidAt(cx, cy, primaryDef) return layout:midAt(cx, cy), primaryPair end - if cy < 0 then - local n = neighborFor("north") - if n then - local offset = tonumber(n.offset) or 0 - local L = n.def and n.def.midLayout - local nh = L and L.height or 0 - local mid, pair = fromNeighbor(n, cx - offset, nh + cy) - if mid ~= nil then return mid, pair end - end - elseif cy >= h then - local n = neighborFor("south") - if n then - local offset = tonumber(n.offset) or 0 - local mid, pair = fromNeighbor(n, cx - offset, cy - h) - if mid ~= nil then return mid, pair end + local list = Map.neighborList or {} + local function fromDir(dir) + for i = #list, 1, -1 do + local n = list[i] + if n.dir == dir and n.def and n.def.midLayout then + local L = n.def.midLayout + local offset = tonumber(n.offset) or 0 + local nx, ny + if dir == "north" then + nx, ny = cx - offset, (L.height or 0) + cy + elseif dir == "south" then + nx, ny = cx - offset, cy - h + elseif dir == "west" then + nx, ny = (L.width or 0) + cx, cy - offset + else + nx, ny = cx - w, cy - offset + end + local mid, pair = fromNeighbor(n, nx, ny) + if mid ~= nil then return mid, pair end + end end end + -- pokefirered/src/fieldmap.c:129 + if cy < 0 then + local mid, pair = fromDir("north") + if mid ~= nil then return mid, pair end + elseif cy >= h then + local mid, pair = fromDir("south") + if mid ~= nil then return mid, pair end + end + if cx < 0 then - local n = neighborFor("west") - if n then - local offset = tonumber(n.offset) or 0 - local L = n.def and n.def.midLayout - local nw = L and L.width or 0 - local mid, pair = fromNeighbor(n, nw + cx, cy - offset) - if mid ~= nil then return mid, pair end - end + local mid, pair = fromDir("west") + if mid ~= nil then return mid, pair end elseif cx >= w then - local n = neighborFor("east") - if n then - local offset = tonumber(n.offset) or 0 - local mid, pair = fromNeighbor(n, cx - w, cy - offset) - if mid ~= nil then return mid, pair end - end + local mid, pair = fromDir("east") + if mid ~= nil then return mid, pair end end for _, entry in ipairs(Map.world) do @@ -335,6 +327,7 @@ function Map.load(mod, game, mapId, opts) Map.loadNeighborsDepth1(game, def) else Map.neighbors = {} + Map.neighborList = {} end local world = host_world(game) diff --git a/src/core/game3/objects.lua b/src/core/game3/objects.lua index c542ce09..bfe75e68 100644 --- a/src/core/game3/objects.lua +++ b/src/core/game3/objects.lua @@ -420,6 +420,48 @@ local function resolveContextualMapObjects(mapId) end end +-- src/event_object_movement.c:1312 +local function spawnFromTemplate(def, mapId) + local eo = newEventObject(def) + if eo.localId > 0 then + applyPerm(eo, mapId) + local tmt = Objects._templateMt[eo.localId] + if tmt then + Objects.setTrainerMovementType(eo, tmt) + -- src/event_object_movement.c:1569 + eo.invisible = tmt == MOVEMENT_TYPE_INVISIBLE + local face = ({ [7] = "up", [8] = "down", [9] = "left", [10] = "right" })[tmt] + if face then eo.facing = face end + end + end + return eo +end + +-- src/event_object_movement.c:1651 +local function respawnFromTemplate(lid) + local tpl + for _, def in ipairs(Objects._defs or {}) do + if tonumber(def.localId or def.index) == lid then tpl = def end + end + if not tpl then return nil end + local eo = spawnFromTemplate(tpl, Objects._mapId) + eo.hidden, eo.visible = false, true + if eo.def then eo.def.hidden = false end + local present = Objects._byId[lid] ~= nil + if not present then + for _, id in ipairs(Objects._order) do + if id == lid then present = true break end + end + end + Objects._byId[lid] = eo + Objects._tracks[lid] = nil + if not present then Objects._order[#Objects._order + 1] = lid end + if ModRuntime.wants("world.npc_spawned") then + ModRuntime.emit("world.npc_spawned", { mapId = Objects._mapId, npcId = lid, runtime = eo }) + end + return eo +end + --- Spawn EventObjects from mapDef.objects (extract / content). function Objects.loadMap(game, mapId, mapDef) local sameMap = Objects._mapId == mapId @@ -456,17 +498,8 @@ function Objects.loadMap(game, mapId, mapDef) resolveContextualMapObjects(mapId) local announce = ModRuntime.wants("world.npc_spawned") for _, def in ipairs(Objects._defs) do - local eo = newEventObject(def) + local eo = spawnFromTemplate(def, mapId) if eo.localId > 0 then - applyPerm(eo, mapId) - local tmt = Objects._templateMt[eo.localId] - if tmt then - Objects.setTrainerMovementType(eo, tmt) - -- src/event_object_movement.c:1569 - eo.invisible = tmt == MOVEMENT_TYPE_INVISIBLE - local face = ({ [7] = "up", [8] = "down", [9] = "left", [10] = "right" })[tmt] - if face then eo.facing = face end - end Objects._byId[eo.localId] = eo Objects._order[#Objects._order + 1] = eo.localId if announce then @@ -662,7 +695,7 @@ local function beginStep(eo, tx, ty) eo.animClock = 0 end -local function finishStep(eo, game) +local function finishStep(eo, game, ctx) eo.cellX = eo.targetX eo.cellY = eo.targetY eo.px = eo.cellX * CELL @@ -673,11 +706,13 @@ local function finishStep(eo, game) if eo.def then eo.def.x, eo.def.y = eo.cellX, eo.cellY end + if ctx then return end local Coll = Collision() local curElev = Coll and Coll.elevationAt and Coll.elevationAt(eo.cellX, eo.cellY) if curElev and curElev ~= 0 and curElev ~= 15 then eo.elevation = curElev end + -- src/trainer_see.c:94 if eo.sight and eo.sight > 0 and not eo.scriptBusy and not eo.frozen then local okTs, TrainerSight = pcall(require, "src.core.game3.trainer_sight") if okTs and TrainerSight and TrainerSight.check then @@ -716,7 +751,7 @@ local function stepOffset(frames, progress, cells) return math.floor(cells * CELL * math.min(progress, frames) / frames) end -local function tickMotion(eo, game) +local function tickMotion(eo, game, ctx) Objects.updateElevation(eo) if not eo.moving then return false end eo.progress = eo.progress + 1 @@ -728,7 +763,7 @@ local function tickMotion(eo, game) eo.px = eo.cellX * CELL + (dx > 0 and off or dx < 0 and -off or 0) eo.py = eo.cellY * CELL + (dy > 0 and off or dy < 0 and -off or 0) if eo.progress >= frames then - finishStep(eo, game) + finishStep(eo, game, ctx) return true end return false @@ -1339,7 +1374,7 @@ function Objects.tickPool(pool, game, ctx) eo.bowFrames = eo.bowFrames - 1 if eo.bowFrames <= 0 then eo.bowFrames = nil end end - tickMotion(eo, game) + tickMotion(eo, game, ctx or pool) idleTick(eo, game, ctx) end end @@ -1394,30 +1429,8 @@ end function Objects.addObject(localId) localId = tonumber(localId) or 0 local eo = Objects._byId[localId] - if eo then - if eo.hidden then - -- src/event_object_movement.c:1569 - eo.invisible = Objects.templateMovementType(localId) == MOVEMENT_TYPE_INVISIBLE - end - applyPerm(eo, Objects._mapId) - eo.hidden = false - eo.visible = true - if eo.def then eo.def.hidden = false end - return true - end - -- Respawn from template defs. - for _, def in ipairs(Objects._defs or {}) do - if tonumber(def.localId or def.index) == localId then - eo = newEventObject(def) - applyPerm(eo, Objects._mapId) - eo.hidden = false - eo.visible = true - Objects._byId[localId] = eo - Objects._order[#Objects._order + 1] = localId - return true - end - end - return false + if eo and not eo.hidden then return true end + return respawnFromTemplate(localId) ~= nil end --- Re-evaluate hide flags after sidecar load / setflag mid-map. @@ -1449,7 +1462,6 @@ end Objects.inCameraView = inCameraView --- pret FlagClear/FlagSet on an object template hide flag. --- clearflag after removeobject must bring the NPC back at perm coords. -- src/scrcmd.c:558 function Objects.syncFlagVisibility(flagId, hidden, force) flagId = tonumber(flagId) or 0 @@ -1465,15 +1477,9 @@ function Objects.syncFlagVisibility(flagId, hidden, force) eo.visible = false if eo.def then eo.def.hidden = true end end - else - if eo.hidden then - -- src/event_object_movement.c:1569 - eo.invisible = Objects.templateMovementType(lid) == MOVEMENT_TYPE_INVISIBLE - end - applyPerm(eo, Objects._mapId) - eo.hidden = false - eo.visible = true - if eo.def then eo.def.hidden = false end + elseif eo.hidden then + -- src/event_object_movement.c:1792 + respawnFromTemplate(lid) end end end diff --git a/src/core/game3/trainer_sight.lua b/src/core/game3/trainer_sight.lua index c41d694c..48ffae4a 100644 --- a/src/core/game3/trainer_sight.lua +++ b/src/core/game3/trainer_sight.lua @@ -379,6 +379,8 @@ function TrainerSight.check(game, specificTrainer) if specificTrainer then local eo = specificTrainer + -- src/trainer_see.c:94 + if Objs.find(eo.localId) ~= eo then return false end if eo.visible and not eo.hidden and not eo.scriptBusy and not eo.frozen then local sight = tonumber(eo.sight or (eo.def and (eo.def.sight or eo.def.trainerRange))) or 0 if sight > 0 and TrainerSight.isTrainerType(eo) diff --git a/src/debug/SwitchDiagnostics.lua b/src/debug/SwitchDiagnostics.lua index 55de37d9..0e33244c 100644 --- a/src/debug/SwitchDiagnostics.lua +++ b/src/debug/SwitchDiagnostics.lua @@ -198,6 +198,14 @@ function SwitchDiagnostics.onPadReconcile() SwitchDiagnostics.maybeFlush(true) end +local function osName() + local sys = love and love.system + if not (sys and sys.getOS) then return nil end + local ok, name = pcall(sys.getOS) + if ok then return name end + return nil +end + function SwitchDiagnostics.onJoystickEvent(kind, joystick, button, extra) if not SwitchDiagnostics.isEnabled() then return end local payload = { button = button } @@ -209,9 +217,27 @@ function SwitchDiagnostics.onJoystickEvent(kind, joystick, button, extra) if extra then for k, v in pairs(extra) do payload[k] = v end end + local PadHints = require("src.core.PadHints") + payload.hf = tostring(PadHints.hasFocus()) + local fg = PadHints.foreground(osName()) + if fg then payload.fg = fg end SwitchDiagnostics.onEvent(kind, payload) end +function SwitchDiagnostics.onFocus(f) + if not SwitchDiagnostics.isEnabled() then return end + local PadHints = require("src.core.PadHints") + local payload = { + f = tostring(f), + hasFocus = tostring(PadHints.hasFocus()), + visible = tostring(not PadHints.windowMinimized()), + } + local fg = PadHints.foreground(osName()) + if fg then payload.fg = fg end + SwitchDiagnostics.onEvent("focus", payload) + SwitchDiagnostics.maybeFlush(true) +end + function SwitchDiagnostics.logLuaError(msg) local filesystem = fs() if not filesystem then return nil end diff --git a/src/import/CacheContract.lua b/src/import/CacheContract.lua index dbedaacd..7d08be04 100644 --- a/src/import/CacheContract.lua +++ b/src/import/CacheContract.lua @@ -19,10 +19,11 @@ CacheContract.VERSION_FORMAT = { silver = "rom-cache-v12:", crystal = "rom-cache-v12-crystal4:", -- engine/overworld/map_sprites.asm:181, engine/battle/animations.asm:2600 - yellow = "rom-cache-v12-yellow1:", + -- data/pikachu/pikachu_pic_animation.asm:340 + yellow = "rom-cache-v12-yellow2:", -- v8: M4A tracks retain reachable patterns and explicit entry offsets. - firered = "rom-cache-v16-firered:", - leafgreen = "rom-cache-v1-leafgreen:", + firered = "rom-cache-v17-firered:", + leafgreen = "rom-cache-v2-leafgreen:", } CacheContract.MARKER_PATH = "rom-cache.complete" @@ -49,6 +50,63 @@ CacheContract.VERSION_REQUIRED_FILES = { "assets/generated/battle/trainers/jessie_james.png", "assets/generated/battle/profoakb.png", "assets/generated/pikachu/pikapic_1.png", + "assets/generated/pikachu/pikapic_2.png", + "assets/generated/pikachu/pikapic_3.png", + "assets/generated/pikachu/pikapic_4.png", + "assets/generated/pikachu/pikapic_5.png", + "assets/generated/pikachu/pikapic_6.png", + "assets/generated/pikachu/pikapic_7.png", + "assets/generated/pikachu/pikapic_8.png", + "assets/generated/pikachu/pikapic_9.png", + "assets/generated/pikachu/pikapic_10.png", + "assets/generated/pikachu/pikapic_11.png", + "assets/generated/pikachu/pikapic_12.png", + "assets/generated/pikachu/pikapic_13.png", + "assets/generated/pikachu/pikapic_14.png", + "assets/generated/pikachu/pikapic_15.png", + "assets/generated/pikachu/pikapic_16.png", + "assets/generated/pikachu/pikapic_17.png", + "assets/generated/pikachu/pikapic_18.png", + "assets/generated/pikachu/pikapic_19.png", + "assets/generated/pikachu/pikapic_20.png", + "assets/generated/pikachu/pikapic_21.png", + "assets/generated/pikachu/pikapic_22.png", + "assets/generated/pikachu/pikapic_23.png", + "assets/generated/pikachu/pikapic_24.png", + "assets/generated/pikachu/pikapic_25.png", + "assets/generated/pikachu/pikapic_26.png", + "assets/generated/pikachu/pikapic_27.png", + "assets/generated/pikachu/pikapic_28.png", + "assets/generated/pikachu/gfx_e4841.png", + "assets/generated/pikachu/gfx_e4ce0.png", + "assets/generated/pikachu/gfx_e4e70.png", + "assets/generated/pikachu/gfx_e50af.png", + "assets/generated/pikachu/gfx_e52fe.png", + "assets/generated/pikachu/gfx_e5541.png", + "assets/generated/pikachu/gfx_e5794.png", + "assets/generated/pikachu/gfx_e59ed.png", + "assets/generated/pikachu/gfx_e5c4d.png", + "assets/generated/pikachu/gfx_e5e90.png", + "assets/generated/pikachu/gfx_e6020.png", + "assets/generated/pikachu/gfx_e61b0.png", + "assets/generated/pikachu/gfx_e63f7.png", + "assets/generated/pikachu/gfx_e6646.png", + "assets/generated/pikachu/gfx_e682f.png", + "assets/generated/pikachu/gfx_e69bf.png", + "assets/generated/pikachu/gfx_e6b4f.png", + "assets/generated/pikachu/gfx_e6cdf.png", + "assets/generated/pikachu/gfx_e6e6f.png", + "assets/generated/pikachu/gfx_e6fff.png", + "assets/generated/pikachu/gfx_e718f.png", + "assets/generated/pikachu/gfx_e731f.png", + "assets/generated/pikachu/gfx_e74af.png", + "assets/generated/pikachu/gfx_e763f.png", + "assets/generated/pikachu/gfx_e7863.png", + "assets/generated/pikachu/gfx_e79f3.png", + "assets/generated/pikachu/gfx_e7b83.png", + "assets/generated/pikachu/gfx_e7d13.png", + "assets/generated/pikachu/gfx_f0b64.png", + "assets/generated/pikachu/gfx_f0d82.png", "assets/generated/minigame/surf_1a.png", "assets/generated/minigame/surf_1b.png", "assets/generated/minigame/surf_1c.png", diff --git a/src/import/RomExtractor.lua b/src/import/RomExtractor.lua index 484d8b3e..8fe06d6e 100644 --- a/src/import/RomExtractor.lua +++ b/src/import/RomExtractor.lua @@ -2137,10 +2137,7 @@ function RomExtractor:extractField() -- (PikaAnimTilemap_1, column order) paints. Scripts 18/22/23/24 have no -- compressed base and take PikaPicAnimBGFrames_5 -> PikaAnimTilemap_9, -- which is ROW order over a raw 25-tile sheet, hence no columns flag. - -- Script 26 shares script 11's base. The pikaframe overlays each script - -- draws ON TOP of the base are a second full pose out of the same blob and - -- stay unripped: PikachuFollower.picLift stands in for their motion - -- (#561, still on #407's stand-in). + -- Script 26 shares script 11's base. local PIKAPIC_BASE = { "Pic_e4000", "Pic_e411c", "Pic_e4272", "Pic_e4383", "Pic_e458b", "Pic_e467b", "Pic_e476e", "Pic_e49d1", "Pic_e4b39", "Pic_e4c3e", @@ -2158,6 +2155,17 @@ function RomExtractor:extractField() self:writeCompressedPic(label, path) end end + -- data/pikachu/pikachu_pic_animation.asm:340 + for _, label in ipairs({ + "GFX_e4841", "GFX_e4ce0", "GFX_e4e70", "GFX_e50af", "GFX_e52fe", + "GFX_e5541", "GFX_e5794", "GFX_e59ed", "GFX_e5c4d", "GFX_e5e90", + "GFX_e6020", "GFX_e61b0", "GFX_e63f7", "GFX_e6646", "GFX_e682f", + "GFX_e69bf", "GFX_e6b4f", "GFX_e6cdf", "GFX_e6e6f", "GFX_e6fff", + "GFX_e718f", "GFX_e731f", "GFX_e74af", "GFX_e763f", "GFX_e7863", + "GFX_e79f3", "GFX_e7b83", "GFX_e7d13", "GFX_f0b64", "GFX_f0d82", + }) do + self:raw2bpp(label, 40, 40, "pikachu/" .. label:lower() .. ".png") + end end self:raw1bpp("LedgeHoppingShadow", 8, 8, diff --git a/src/import/gba/extract_island1.lua b/src/import/gba/extract_island1.lua index 3c3b3eb9..5916d385 100644 --- a/src/import/gba/extract_island1.lua +++ b/src/import/gba/extract_island1.lua @@ -443,7 +443,7 @@ function Extract.run(imports, cache, progressCb) for _, mapId in ipairs(mapOrder) do local conns = romConns[mapId] or {} local fixed = {} - for dir, c in pairs(conns) do + for _, c in ipairs(conns) do local dest = c.map if (not dest or dest:match("^g%d+_m%d+$")) and c.mapGroup ~= nil then dest = MapCatalog.mapIdFor(c.mapGroup, c.mapNum) or dest @@ -451,7 +451,7 @@ function Extract.run(imports, cache, progressCb) dest = MapCatalog.resolve(dest) or dest end if dest then - fixed[dir] = { map = dest, offset = tonumber(c.offset) or 0 } + fixed[#fixed + 1] = { dir = c.dir, map = dest, offset = tonumber(c.offset) or 0 } end end connections[mapId] = fixed @@ -533,13 +533,9 @@ function Extract.run(imports, cache, progressCb) for _, mapId in ipairs(mapOrder) do local conns = connections[mapId] or {} cl[#cl + 1] = (" %s = {\n"):format(mapId) - local dirs = {} - for dir in pairs(conns) do dirs[#dirs + 1] = dir end - table.sort(dirs) - for _, dir in ipairs(dirs) do - local c = conns[dir] - cl[#cl + 1] = (" %s = { map = %q, offset = %d },\n"):format( - dir, c.map, tonumber(c.offset) or 0) + for _, c in ipairs(conns) do + cl[#cl + 1] = (" { dir = %q, map = %q, offset = %d },\n"):format( + c.dir, c.map, tonumber(c.offset) or 0) end cl[#cl + 1] = " },\n" end @@ -1844,7 +1840,7 @@ local function _dormant_quantize_run(imports, cache, progressCb) for _, mapId in ipairs(mapOrder) do local conns = romConns[mapId] or {} local fixed = {} - for dir, c in pairs(conns) do + for _, c in ipairs(conns) do local dest = c.map if (not dest or dest:match("^g%d+_m%d+$")) and c.mapGroup ~= nil then dest = MapCatalog.mapIdFor(c.mapGroup, c.mapNum) or dest @@ -1852,7 +1848,7 @@ local function _dormant_quantize_run(imports, cache, progressCb) dest = MapCatalog.resolve(dest) or dest end if dest then - fixed[dir] = { map = dest, offset = tonumber(c.offset) or 0 } + fixed[#fixed + 1] = { dir = c.dir, map = dest, offset = tonumber(c.offset) or 0 } end end connections[mapId] = fixed @@ -1885,13 +1881,9 @@ local function _dormant_quantize_run(imports, cache, progressCb) for _, mapId in ipairs(mapOrder) do local conns = connections[mapId] or {} cl[#cl + 1] = (" %s = {\n"):format(mapId) - local dirs = {} - for dir in pairs(conns) do dirs[#dirs + 1] = dir end - table.sort(dirs) - for _, dir in ipairs(dirs) do - local c = conns[dir] - cl[#cl + 1] = (" %s = { map = %q, offset = %d },\n"):format( - dir, c.map, tonumber(c.offset) or 0) + for _, c in ipairs(conns) do + cl[#cl + 1] = (" { dir = %q, map = %q, offset = %d },\n"):format( + c.dir, c.map, tonumber(c.offset) or 0) end cl[#cl + 1] = " },\n" end diff --git a/src/import/gba/extract_map_events.lua b/src/import/gba/extract_map_events.lua index 3926aed9..03f01cbd 100644 --- a/src/import/gba/extract_map_events.lua +++ b/src/import/gba/extract_map_events.lua @@ -351,7 +351,7 @@ function ExtractMapEvents.parseConnections(rom, connectionsPtr) local dirName = CONN_DIR[direction] local destMap = Versions.frMapFor(mapGroup, mapNum) if dirName and destMap then - out[dirName] = { map = destMap, offset = offset } + out[#out + 1] = { dir = dirName, map = destMap, offset = offset } end end return out diff --git a/src/import/gba/map_tree.lua b/src/import/gba/map_tree.lua index 5421fa87..ae70336a 100644 --- a/src/import/gba/map_tree.lua +++ b/src/import/gba/map_tree.lua @@ -149,7 +149,8 @@ function MapTree.parseConnections(rom, connectionsPtr, groupsData) local maps = groupsData.groups[mapGroup].maps pretName = maps and maps[mapNum + 1] end - out[dirName] = { + out[#out + 1] = { + dir = dirName, mapGroup = mapGroup, mapNum = mapNum, offset = offset, diff --git a/src/import/gba/versions.lua b/src/import/gba/versions.lua index 770c7843..52f3a311 100644 --- a/src/import/gba/versions.lua +++ b/src/import/gba/versions.lua @@ -43,7 +43,7 @@ Versions.ROM_SIZE = 16777216 -- v115: LeafGreen profiles, edition-specific title assets and Deoxys stats. -- v121: chrome/fonts/japanese_{normal,small}_* and japanese_widths.lua, the -- cart's Japanese fonts, for text a Japanese translation mod prints. -Versions.CACHE_VERSION = 125 +Versions.CACHE_VERSION = 126 Versions.NATIVE_VERSION = 6 Versions.OW_VERSION = 3 Versions.ANIM_VERSION = 1 diff --git a/src/mods/Gen3Compat.lua b/src/mods/Gen3Compat.lua index 377f8c10..ead6c18a 100644 --- a/src/mods/Gen3Compat.lua +++ b/src/mods/Gen3Compat.lua @@ -903,6 +903,7 @@ COVERAGE["src.core.Game"] = { -- ------- src.world.Map local MapView = {} +local connViews = setmetatable({}, { __mode = "k" }) local function collision() return package.loaded["src.core.game3.collision"] @@ -919,7 +920,21 @@ function MapView.__index(self, key) if key == "widthCells" then return def and def.width end if key == "heightCells" then return def and def.height end if key == "warps" then return def and def.warps end - if key == "connections" then return def and def.connections end + if key == "connections" then + if not def then return nil end + local hit = connViews[def] + if hit and hit.src == def.connections then return hit.view end + local list = require("src.core.game3.connections").each(def) + local view = setmetatable(list, { __index = function(t, dir) + if type(dir) ~= "string" then return nil end + for i = 1, #t do + if t[i].dir == dir then return t[i] end + end + return nil + end }) + connViews[def] = { src = def.connections, view = view } + return view + end return nil end diff --git a/src/render/PaletteFX.lua b/src/render/PaletteFX.lua index 44c5523d..7a8b6a8f 100644 --- a/src/render/PaletteFX.lua +++ b/src/render/PaletteFX.lua @@ -73,8 +73,8 @@ function PaletteFX.darkObp(colors, group) end -- the same shift folded into a baked 8-group world palette array (ADVANCED) -local function darkGroups(groups) - if not (groups and darkWorld) then return groups end +local function darkGroups(groups, lit) + if lit or not (groups and darkWorld) then return groups end local out = {} for i = 1, #groups do out[i] = PaletteFX.permute(groups[i], PaletteFX.DARK_BGP) @@ -716,11 +716,11 @@ end -- slot swapped to the current town/route (Route 6's north end uses -- Saffron's roof colors while the player stands in its top 2 cell rows, -- like pokered's wYCoord check -- data is Game.data, for the map lookup) -function PaletteFX.worldGroupColors(data, tileset, mapId, playerCellY) +function PaletteFX.worldGroupColors(data, tileset, mapId, playerCellY, lit) local w = PaletteFX.worldPack() local base = w and w.groupColors[tileset] if not base then return nil end - if not w.roofGroup[tileset] then return darkGroups(base) end + if not w.roofGroup[tileset] then return darkGroups(base, lit) end local roofMapId = mapId if mapId == ROUTE_6_SAFFRON.mapId and playerCellY and playerCellY < ROUTE_6_SAFFRON.cellYBelow then @@ -728,7 +728,7 @@ function PaletteFX.worldGroupColors(data, tileset, mapId, playerCellY) end local roofMap = data and data.maps and data.maps[roofMapId] local roof = roofMap and w.roofByMapIndex[roofMap.index] - if not roof then return darkGroups(base) end + if not roof then return darkGroups(base, lit) end local out = {} for i = 1, 8 do out[i] = base[i] end -- LoadTownPalette only overwrites W2_BgPaletteData + $32, i.e. colors 1 @@ -738,7 +738,7 @@ function PaletteFX.worldGroupColors(data, tileset, mapId, playerCellY) -- material's 2 middle shades are town-specific local base4 = base[ROOF_GROUP + 1] out[ROOF_GROUP + 1] = { base4[1], roof[1], roof[2], base4[4] } - return darkGroups(out) + return darkGroups(out, lit) end -- an overworld sprite's resolved 4-color OBJ palette (ColorOverworldSprite), diff --git a/src/render/TileRenderer.lua b/src/render/TileRenderer.lua index 9ba00136..fe41cf26 100644 --- a/src/render/TileRenderer.lua +++ b/src/render/TileRenderer.lua @@ -185,11 +185,11 @@ TileRenderer.recolorSample = recolorSample -- the 8 shifted variants of one tile (built once per sheet + tile id [+ -- gbcKey, when `colors` recolors it for RED++ -- see buildAnim]) local shiftVariants = {} -local function getShiftVariants(tilesetImagePath, perRow, tile, colors, gbcKey) +local function getShiftVariants(tilesetImagePath, perRow, tile, colors, gbcKey, own) local key = tilesetImagePath .. "#" .. tile .. (gbcKey or "") - if shiftVariants[key] ~= nil then return shiftVariants[key] end + if not own and shiftVariants[key] ~= nil then return shiftVariants[key] end if not (love.image and love.image.newImageData) then - shiftVariants[key] = false + if not own then shiftVariants[key] = false end return false end local id = Assets.imageData(tilesetImagePath) @@ -207,14 +207,14 @@ local function getShiftVariants(tilesetImagePath, perRow, tile, colors, gbcKey) end out[o + 1] = love.graphics.newImage(v) end - shiftVariants[key] = out + if not own then shiftVariants[key] = out end return out end local frameImages = {} -local function getFrameImages(paths, colors, gbcKey) +local function getFrameImages(paths, colors, gbcKey, own) local key = table.concat(paths, "|") .. (gbcKey or "") - if frameImages[key] ~= nil then return frameImages[key] end + if not own and frameImages[key] ~= nil then return frameImages[key] end local out = {} for i, path in ipairs(paths) do local ok, img = pcall(function() @@ -234,12 +234,12 @@ local function getFrameImages(paths, colors, gbcKey) return love.graphics.newImage(out2) end) if not ok then - frameImages[key] = false + if not own then frameImages[key] = false end return false end out[i] = img end - frameImages[key] = out + if not own then frameImages[key] = out end return out end @@ -359,14 +359,14 @@ local function buildAnim(spec, tilesetImagePath, perRow, quads, gbc) local sequence = {} for i, offset in ipairs(offsets) do sequence[i] = offset + 1 end return { tiles = tiles, textures = textures, sequence = sequence, - period = period } + period = period, spec = gbc and spec or nil } elseif spec.kind == "frames" then local sequence = spec.sequence if not (spec.images and sequence and #sequence > 0) then return nil end local textures = getFrameImages(spec.images, colors, gbc and gbc.key) if not textures then return nil end return { tiles = tiles, textures = textures, sequence = sequence, - period = period } + period = period, spec = gbc and spec or nil } elseif spec.kind == "toggle" then if gbc then return nil end local image = getToggleImage(spec, tilesetImagePath, perRow) @@ -407,12 +407,24 @@ local function gbcKeyFor(mapId) return "#gbc:" .. mapId .. PaletteFX.darkKey() end -local function getGbcAtlas(imagePath, tilesetId, mapId, perRow, data) +local function bgpGroupColors(data, tilesetId, mapId, bgp) + local groupColors = PaletteFX.worldGroupColors(data, tilesetId, mapId, nil, bgp ~= nil) + if groupColors and bgp then + local shade = {} + for i = 0, 3 do shade[i] = math.floor(bgp / (4 ^ i)) % 4 end + local shaded = {} + for i = 1, #groupColors do shaded[i] = PaletteFX.permute(groupColors[i], shade) end + groupColors = shaded + end + return groupColors +end + +local function getGbcAtlas(imagePath, tilesetId, mapId, perRow, data, bgp) local key = imagePath .. gbcKeyFor(mapId) - if gbcAtlasCache[key] ~= nil then return gbcAtlasCache[key] or nil end + if not bgp and gbcAtlasCache[key] ~= nil then return gbcAtlasCache[key] or nil end local img = false if love.image and love.image.newImageData then - local groupColors = PaletteFX.worldGroupColors(data, tilesetId, mapId, nil) + local groupColors = bgpGroupColors(data, tilesetId, mapId, bgp) if groupColors then local src = Assets.imageData(imagePath) local iw, ih = src:getDimensions() @@ -458,6 +470,7 @@ local function getGbcAtlas(imagePath, tilesetId, mapId, perRow, data) img = love.graphics.newImage(out) end end + if bgp then return img or nil end gbcAtlasCache[key] = img return img or nil end @@ -881,6 +894,90 @@ end local function safeRelease(o) if o and o.release then pcall(o.release, o) end end +local EMPTY = {} + +-- engine/pikachu/pikachu_pic_animation.asm:845 +function TileRenderer:bgpImage(byte) + if not (byte and self.gbcAtlas and self.data) then return nil end + local base = self.baseImage or self.image + if byte == 0xE4 and not PaletteFX.darkWorld() then return base end + self.bgpImages = self.bgpImages or {} + local img = self.bgpImages[byte] + if img == nil then + local ts = self.map.tileset + local ok, made = pcall(getGbcAtlas, ts.image, ts.id, self.map.id, + ts.tilesPerRow, self.data, byte) + img = ok and made or false + self.bgpImages[byte] = img + if img then pcall(self.bakeBgpAnims, self, byte) end + end + return img or nil +end + +function TileRenderer:bakeBgpAnims(byte) + local ctx = self.gbcCtx + if not (ctx and self.anims) then return end + local groupColors = bgpGroupColors(self.data, ctx.tilesetId, ctx.mapId, byte) + if not groupColors then return end + for _, anim in ipairs(self.anims) do + local spec = anim.spec + local group = spec and PaletteFX.worldGroupAt(ctx.tilesetId, ctx.mapId, anim.tiles[1]) + local colors = group and groupColors[group + 1] + if colors then + local textures + if spec.kind == "hshift" then + textures = getShiftVariants(ctx.imagePath, ctx.perRow, anim.tiles[1], + colors, nil, true) + else + textures = getFrameImages(spec.images, colors, nil, true) + end + if textures then + anim.bgpTextures = anim.bgpTextures or {} + anim.bgpTextures[byte] = textures + end + end + end +end + +function TileRenderer:setBgp(byte) + if byte == self.curBgp and byte ~= nil then return true end + local before = self.image + if self.curBgp then + self.bgpBorders[self.curBgp] = self.borderFill + self.image = self.baseImage + self.borderFill, self.borderFillMode = self.baseBorder, self.baseBorderMode + self.baseImage, self.baseBorder, self.baseBorderMode = nil, nil, nil + self.curBgp = nil + for _, anim in ipairs(self.anims or EMPTY) do + if anim.baseTextures then + anim.textures, anim.baseTextures = anim.baseTextures, nil + end + end + end + local shown = false + local img = self:bgpImage(byte) + if img and img == self.image then + shown = true + elseif img then + self.bgpBorders = self.bgpBorders or {} + self.baseImage = self.image + self.baseBorder, self.baseBorderMode = self.borderFill, self.borderFillMode + self.image = img + self.borderFill = self.bgpBorders[byte] + self.borderFillMode = self.borderFill and self.baseBorderMode or nil + self.bgpBorders[byte] = nil + self.curBgp = byte + for _, anim in ipairs(self.anims or EMPTY) do + local textures = anim.bgpTextures and anim.bgpTextures[byte] + if textures then + anim.baseTextures, anim.textures = anim.textures, textures + end + end + shown = true + end + if self.winBatch and self.image ~= before then self.winBatch:setTexture(self.image) end + return shown +end -- Release only the GPU objects this instance built and uniquely owns: the -- two SpriteBatches, the border-fill image and its quad, the per-tile @@ -890,6 +987,9 @@ end -- them. Used by :rebuild before it swaps in fresh batches, and by -- :release on eviction. function TileRenderer:releaseBatches() + if self.curBgp then self:setBgp(nil) end + for _, img in pairs(self.bgpBorders or {}) do safeRelease(img) end + self.bgpBorders = nil safeRelease(self.winBatch); self.winBatch = nil safeRelease(self.borderFill); self.borderFill = nil safeRelease(self.borderQuad); self.borderQuad = nil @@ -928,6 +1028,14 @@ function TileRenderer:release() self.image = nil self.gbcAtlas = nil end + for _, img in pairs(self.bgpImages or {}) do safeRelease(img) end + self.bgpImages = nil + for _, anim in ipairs(self.anims or {}) do + for _, textures in pairs(anim.bgpTextures or {}) do + for _, img in ipairs(textures) do safeRelease(img) end + end + anim.bgpTextures = nil + end self.anims = nil end diff --git a/src/save_convert/GenSave.lua b/src/save_convert/GenSave.lua index 518a6a6f..a8d89686 100644 --- a/src/save_convert/GenSave.lua +++ b/src/save_convert/GenSave.lua @@ -1123,10 +1123,12 @@ function GenSave.encode(save, data, template) for b = 7, 12 do encodeBoxRegion(O.box7 + (b - 7) * BOX_REGION_SIZE, boxes[b] or {}) end -- map + position + local px = math.floor(tonumber(save.player and save.player.x) or 0) + local py = math.floor(tonumber(save.player and save.player.y) or 0) if save.player and save.player.map then setByte(buf, O.curMap, cw.mapsIndex[save.player.map] or 0) - setByte(buf, O.yCoord, save.player.y or 0) - setByte(buf, O.xCoord, save.player.x or 0) + setByte(buf, O.yCoord, py) + setByte(buf, O.xCoord, px) end if save.lastOutdoor and save.lastOutdoor.id then setByte(buf, O.lastMap, cw.mapsIndex[save.lastOutdoor.id] or 0) @@ -1137,10 +1139,10 @@ function GenSave.encode(save, data, template) -- zero-filled one boots into a garbled map on a silent hang (#889). -- -- Rebuilt when there is no template at all (a save that began as a New Game - -- in this port), and when the template was saved on a DIFFERENT map than the - -- one the player is standing on now -- an imported save that has since been - -- played carries the old map's header, which is just as unbootable. A - -- template still on its own map keeps its bytes untouched: they are the + -- in this port), and when the template was saved on a DIFFERENT map or cell + -- than the one the player is standing on now -- an imported save that has + -- since been played carries a stale map window, which is just as unbootable. + -- A template still on its own cell keeps its bytes untouched: they are the -- game's own, including live NPC positions, and preserving them is what -- makes import -> export byte-identical. local mapId = save.player and save.player.map @@ -1151,10 +1153,11 @@ function GenSave.encode(save, data, template) -- map has no index at all rather than trusting a stale template local index = cw.mapsIndex[mapId] rebuild = index == nil or u8(src, O.curMap) ~= bit.band(index, 0xFF) + or u8(src, O.yCoord) ~= bit.band(py, 0xFF) + or u8(src, O.xCoord) ~= bit.band(px, 0xFF) end if rebuild then - local ctx, why = MapContext.build(data, mapId, - (save.player and save.player.x) or 0, (save.player and save.player.y) or 0) + local ctx, why = MapContext.build(data, mapId, px, py) -- home/overworld.asm:2016 (#1691) if not ctx then error(("this save cannot be exported: %s"):format(tostring(why)), 0) diff --git a/src/save_convert/MapContext.lua b/src/save_convert/MapContext.lua index 7289dbe2..ee133ea4 100644 --- a/src/save_convert/MapContext.lua +++ b/src/save_convert/MapContext.lua @@ -57,6 +57,10 @@ local O = { currentMapHeight2 = 557, currentMapWidth2 = 558, tilesetHeader = 564, -- wTilesetBank .. wGrassTile (11) + grassRate = 1424, -- ram/wram.asm:2408 wGrassRate + grassMons = 1425, + waterRate = 1453, + waterMons = 1454, } MapContext.OFFSETS = O @@ -66,6 +70,7 @@ local MAX_OBJECT_EVENTS = 16 local CONNECTION_STRUCT = 11 -- map_connection_struct (macros/ram.asm) local SPRITE_STRUCT = 16 -- one wSpriteStateData1/2 entry local NUM_SPRITE_STRUCTS = 16 +local NUM_WILDMONS = 10 -- wOverworldMap, the tile-block map the view pointer indexes. Recovered from -- the event_displacement formula below applied to a real save's coordinates, @@ -227,6 +232,36 @@ function MapContext.build(data, mapId, x, y) writes[O.mapMusicSoundID] = { id } writes[O.mapMusicROMBank] = { song.bank % 256 } + -- engine/overworld/wild_mons.asm:1 + if type(data.encounters) ~= "table" then + return nil, "no wild encounter data (re-import the ROM)" + end + local enc = data.encounters[mapId] + local pokemon = data.pokemon or {} + local function wildRows(t) + local out = {} + for i = 1, NUM_WILDMONS do + local slot = t.slots and t.slots[i] + local def = slot and pokemon[slot.species] + if not (slot and def and def.index) then return nil end + out[#out + 1] = (tonumber(slot.level) or 0) % 256 + out[#out + 1] = def.index % 256 + end + return out + end + for _, kind in ipairs({ "grass", "water" }) do + local t = type(enc) == "table" and enc[kind] or nil + local rate = t and tonumber(t.rate) or 0 + writes[O[kind .. "Rate"]] = { rate % 256 } + if rate ~= 0 then + local rows = wildRows(t) + if not rows then + return nil, ("bad %s wild data for %s (re-import the ROM)"):format(kind, tostring(mapId)) + end + writes[O[kind .. "Mons"]] = rows + end + end + -- Player position within its block, and the upper-left corner of the view. -- The pointer is the same expression the warp_to tables are assembled with -- (macros/coords.asm event_displacement). diff --git a/src/save_convert/SaveConvert.lua b/src/save_convert/SaveConvert.lua index 26493ed4..ad5277b6 100644 --- a/src/save_convert/SaveConvert.lua +++ b/src/save_convert/SaveConvert.lua @@ -94,6 +94,7 @@ local DATA_MODULES = { -- rebuild the current map's engine state on export (#889) tilesets = { "data.generated.tilesets", "data/generated/tilesets.lua" }, audio = { "data.generated.audio", "data/generated/audio.lua" }, + encounters = { "data.generated.encounters", "data/generated/encounters.lua" }, charmap = { "src.save_convert.data.charmap", "src/save_convert/data/charmap.lua" }, eventFlags = { "src.save_convert.data.event_flags", "src/save_convert/data/event_flags.lua" }, toggleObjects = { "src.save_convert.data.toggle_objects", "src/save_convert/data/toggle_objects.lua" }, @@ -253,14 +254,6 @@ local function defaultsSave() defeatedTrainers = {}, repelSteps = 0, modData = {}, - options = { - textSpeed = 3, animations = true, battleStyle = "shift", - battleLayout = "og", - ruleset = "gen1_faithful", musicVol = 7, sfxVol = 7, pikaVol = 7, - musicFilter = 0, - speed = 1, colors = "gbc", tilt = 0, - videoMode = "windowed", mods = {}, - }, } end diff --git a/src/ui/ShopMenu.lua b/src/ui/ShopMenu.lua index c966e366..4a8c4a48 100644 --- a/src/ui/ShopMenu.lua +++ b/src/ui/ShopMenu.lua @@ -28,12 +28,31 @@ local function anythingElse(game) Strings("Is there anything\nelse I can do?")) end +-- engine/events/pokemart.asm:131-133 +local function say(game, menu, text, after) + local box + box = TextBox.new(game, text, nil, { stay = { onShown = function() + if game.stack:top() == box then game.stack:pop() end + menu.footer = text + if after then after() end + end } }) + game.stack:push(box) +end + +-- engine/events/pokemart.asm:199-206 +local function backToMenu(game, menu) + say(game, menu, anythingElse(game), function() + -- engine/events/pokemart.asm:10 + menu.index, menu.hollowIndex = 1, nil + end) +end + -- .returnToMainPokemartMenu -- pokered engine/events/pokemart.asm:199-206 local function refuse(game, menu, list, text, under) game.stack:push(TextBox.new(game, text, function() if under and game.stack:top() == under then game.stack:pop() end if list then list:close() end - menu.footer = anythingElse(game) + backToMenu(game, menu) end)) end @@ -62,12 +81,12 @@ local function buy(game, stock, menu) itemBox = true, money = function() return game.save.money end, footer = greet, - onCancel = function() menu.footer = anythingElse(game) end, + onCancel = function() backToMenu(game, menu) end, onChoose = function(item) -- home/list_menu.asm:105-110, 523-528 if item.cancel then list:close() - menu.footer = anythingElse(game) + backToMenu(game, menu) return end -- home/list_menu.asm:89-91 @@ -126,7 +145,8 @@ local function buy(game, stock, menu) game.stack:push(qtyBox) end, }) - game.stack:push(list) + -- engine/events/pokemart.asm:131-150 + say(game, menu, greet, function() game.stack:push(list) end) end -- home/list_menu.asm:472-477 @@ -168,7 +188,7 @@ local function sell(game, menu) itemBox = true, money = function() return game.save.money end, footer = greet, - onCancel = function() menu.footer = anythingElse(game) end, + onCancel = function() backToMenu(game, menu) end, onSelectKey = function(item, l) -- swap_items.asm:19-22 if not item or item.cancel then return end @@ -186,7 +206,7 @@ local function sell(game, menu) -- home/list_menu.asm:105-110, 523-528 if item.cancel then list:close() - menu.footer = anythingElse(game) + backToMenu(game, menu) return end -- home/list_menu.asm:89-91 @@ -245,7 +265,8 @@ local function sell(game, menu) game.stack:push(qtyBox) end, }) - game.stack:push(list) + -- engine/events/pokemart.asm:50-52 + say(game, menu, greet, function() game.stack:push(list) end) end -- MONEY_BOX 11,0 (data/text_boxes.asm:35) over the greeting PrintText left @@ -281,21 +302,39 @@ function ShopMenu.new(game, stock, onQuit) -- keepOpen: the mart menu stays underneath its list so closing the -- list lands back here; only QUIT (or B) leaves and fires onQuit local menu + -- engine/menus/text_box.asm:176 + local function chosen(fn) + return function() + menu.hollowIndex = menu.index + fn() + end + end -- engine/events/pokemart.asm:220 .done, reached by QUIT and by B alike local function farewell() game.stack:push(TextBox.new(game, - txt(game, "_PokemartThankYouText", "Thank you!"), onQuit)) + txt(game, "_PokemartThankYouText", "Thank you!"), function() + if game.stack:top() == menu then game.stack:pop() end + if onQuit then onQuit() end + end)) end menu = Menu.new(game, { - { label = Strings("BUY"), keepOpen = true, onSelect = function() buy(game, stock, menu) end }, - { label = Strings("SELL"), keepOpen = true, onSelect = function() sell(game, menu) end }, - { label = Strings("QUIT"), onSelect = farewell }, + { label = Strings("BUY"), keepOpen = true, + onSelect = chosen(function() buy(game, stock, menu) end) }, + { label = Strings("SELL"), keepOpen = true, + onSelect = chosen(function() sell(game, menu) end) }, + { label = Strings("QUIT"), keepOpen = true, onSelect = chosen(farewell) }, -- data/text_boxes.asm:34 - }, { tx = 0, ty = 0, tw = 11, th = 7 }) - menu.onCancel = farewell - menu.footer = txt(game, "_PokemartGreetingText", - Strings("Hi there!\nMay I help you?")) + }, { tx = 0, ty = 0, tw = 11, th = 7, keepOnCancel = true }) + menu.onCancel = chosen(farewell) + -- home/text_script.asm:141-150 + function menu:enter() + self.hidden = true + say(game, self, txt(game, "_PokemartGreetingText", + Strings("Hi there!\nMay I help you?")), + function() self.hidden = false end) + end menu.draw = function(self) + if self.hidden then return end drawClerk(self) Menu.draw(self) end diff --git a/src/ui/game3/boot.lua b/src/ui/game3/boot.lua index 3750ed1f..d080fcf5 100644 --- a/src/ui/game3/boot.lua +++ b/src/ui/game3/boot.lua @@ -159,16 +159,7 @@ function Boot.continueInfoFromSave(save) local store = { flags = type(save.flags) == "table" and save.flags or {} } local pt = type(save.playTime) == "table" and save.playTime or type(save.playtime) == "table" and save.playtime or {} - local dex = type(save.dex) == "table" and save.dex or {} - local caught = dex.caught or dex.owned or {} - local counted, n = {}, 0 - for sp, on in pairs(caught) do - local id = tonumber(sp) - if id and on and on ~= 0 and not counted[id] and (dex.national or id <= 151) then - counted[id] = true - n = n + 1 - end - end + local n = require("src.core.game3.dex").summaryCount(save) local name = tostring(save.name or save.playerName or "") return { name = FrlgFont.truncate(name, 7), diff --git a/src/ui/game3/party_menu.lua b/src/ui/game3/party_menu.lua index 73b6dc58..18ac8702 100644 --- a/src/ui/game3/party_menu.lua +++ b/src/ui/game3/party_menu.lua @@ -1657,7 +1657,19 @@ function PartyMenu.handleInput(input) local fx, fy = P.cellX + d[1], P.cellY + d[2] local facingObj = Objects.at(fx, fy) local isWater = Collision.isWater and Collision.isWater(fx, fy) - local isGrass = Collision.isGrass and Collision.isGrass(fx, fy) + -- pokefirered/src/fldeff_cut.c:140 + local function hasCuttableGrass3x3(px, py) + if not Collision.isGrass then return false end + -- pokefirered/src/fldeff_rocksmash.c:31 + local elev = P.elevation + for y = py - 1, py + 1 do + for x = px - 1, px + 1 do + local e = Collision.elevationAt and Collision.elevationAt(x, y) + if (elev == nil or e == elev) and Collision.isGrass(x, y) then return true end + end + end + return false + end local mapDef = Map.currentDef() -- pokefirered/src/party_menu.c:4118 local facingBeh = Collision.behavior and Collision.behavior(fx, fy) @@ -1671,7 +1683,7 @@ function PartyMenu.handleInput(input) isFacingWaterfall = FieldMoves.isWaterfallBehavior(facingBeh), facing = P.facing, isSurfing = P.surfing == true, - hasCuttableGrass = isGrass or (Collision.isGrass and Collision.isGrass(P.cellX, P.cellY)), + hasCuttableGrass = hasCuttableGrass3x3(P.cellX, P.cellY), mapType = mapDef and mapDef.mapType, isCave = mapHeaderFlag(mapDef, "cave"), canEscapeRope = mapHeaderFlag(mapDef, "allowEscaping"), diff --git a/src/world/OverworldController.lua b/src/world/OverworldController.lua index 99dfd3c0..f5928395 100644 --- a/src/world/OverworldController.lua +++ b/src/world/OverworldController.lua @@ -5868,6 +5868,30 @@ function OverworldState:drawWorld() PaletteFX.setShadeMap((self.dark and not battleOverWorld) and PaletteFX.DARK_BGP or self:poisonShadeMap()) end + local tiles = self.map and self.map.renderer + self.boltBaked = nil + if tiles and tiles.setBgp then + local e = self.emote + -- engine/pikachu/pikachu_pic_animation.asm:790 + local prebake = e and e.boltAt and not e.boltDone and (e.boltT or 0) > e.boltAt + local bolt = e and not battleOverWorld and e.bgp or nil + local neighbors = self.neighbors + for i = 1, neighbors and #neighbors or 0 do + local r = neighbors[i].map.renderer + if r and r.setBgp then + if prebake then + r:bgpImage(0xC0) + r:bgpImage(0xE4) + end + r:setBgp(bolt) + end + end + if prebake then + tiles:bgpImage(0xC0) + tiles:bgpImage(0xE4) + end + self.boltBaked = tiles:setBgp(bolt) and bolt or nil + end -- advance the water/flower tile animation (runs under dialogs too). -- TileRenderer.tick uses wall-clock 60Hz steps so display refresh rate -- does not speed or slow the cycle (issue #4). @@ -6439,28 +6463,27 @@ function OverworldState:drawUI() -- TalkToPikachu's picture box (engine/pikachu/pikachu_pic_animation.asm -- PlacePikapicTextBoxBorder: TextBoxBorder at (6,5) with b,c = 5,5, so a -- 7x7 box holding the 5x5 pic at (7,6) -- PikaAnimTilemap_1). The - -- script's base frame is ripped as pikachu/pikapic_N.png (#561) but the - -- pikaframe overlays on top of it are not, so PikachuFollower - -- .picLift lifts the base on the runs that draw the alternate pose, and the -- script's own duration times the beat (#407, #424). Palette zone -- PAL_PIKACHU_PORTRAIT covers (7,6)-(11,10) via sgbPalettes above. if self.emote and self.emote.pikaPic then require("src.render.Font").drawBox(6, 5, 7, 7) - -- one image per path, cached: this draws every frame of the hold, and - -- a mod skin can move the path between talks - if self.pikaPicPath ~= self.emote.pikaPic then - local ok, loaded = pcall(love.graphics.newImage, self.emote.pikaPic) - self.pikaPicImg = ok and loaded or nil - self.pikaPicPath = self.emote.pikaPic + local path, lift = require("src.world.PikachuFollower").picFrame(self.emote) + self.pikaPicImgs = self.pikaPicImgs or {} + local img = path and self.pikaPicImgs[path] + if path and img == nil then + local ok, loaded = pcall(love.graphics.newImage, path) + img = ok and loaded or false + self.pikaPicImgs[path] = img end - local img = self.pikaPicImg + self.pikaPicDrawn = img and path or nil if img then love.graphics.setColor(1, 1, 1, 1) local w, h = img:getDimensions() - local lift = require("src.world.PikachuFollower").picLift(self.emote) love.graphics.draw(img, math.floor(56 + (40 - w) / 2), - math.floor(48 + (40 - h) / 2) - lift) + math.floor(48 + (40 - h) / 2) - (lift or 0)) end + else + self.pikaPicDrawn = nil end -- engine/gfx/screen_effects.asm:1-12 @@ -6483,7 +6506,7 @@ function OverworldState:drawUI() -- engine/pikachu/pikachu_pic_animation.asm:847 local bolt = self.emote and self.emote.bgp - if bolt and bolt ~= 0xE4 and Game and Game.renderer + if bolt and bolt ~= 0xE4 and Game and Game.renderer and self.boltBaked ~= bolt and (self:bakedWorldColors() or not PaletteFX.shader()) then Game.renderer.screenVeil = BOLT_WHITE_VEIL end diff --git a/src/world/PikachuFollower.lua b/src/world/PikachuFollower.lua index 7168ebd3..8101e7e3 100644 --- a/src/world/PikachuFollower.lua +++ b/src/world/PikachuFollower.lua @@ -735,11 +735,7 @@ end -- and voiced PCM clip, and raise the framed Pikachu picture the original -- puts over the map (pikaemotion_pikapic -> pikachu_pic_animation.asm -- PlacePikapicTextBoxBorder), drawn by OverworldController:drawUI. Each --- script's BASE 5x5 frame is ripped as pikachu/pikapic_N.png (#561); the --- pikaframe overlays it alternates with are a second full-body pose out of --- the same blob and are still unported, so picLift below stands in for --- their motion and the battle front pic covers caches built before the --- rip (#407). +-- script's BASE 5x5 frame is ripped as pikachu/pikapic_N.png (#561). -- --------------------------------------------------------------------- -- PikachuEmotionTable, reduced to each entry's bubble + pikaemotion_pcm @@ -804,6 +800,7 @@ local MODIFIER_EMOTIONS = { 18, 21, 23, 24, 25 } -- third of even the shortest script (#424). local PIKAPIC_TICK = 3 local PIKAPIC_LIFT = 4 -- px the stand-in pic rises on an overlay run +local PIKAPIC_DIR = "assets/generated/pikachu/" -- pikaemotion_pikapic's script id per emotion: emotion N takes -- PikaPicAnimScript N, except the four listed here (data/pikachu/ @@ -821,11 +818,9 @@ PikachuFollower.THUNDERBOLT_ROW = THUNDERBOLT_ROW -- Per script: pikapic_setduration's tick count, and for the scripts whose -- overlay is a whole second pose, that frameset's run lengths in ticks -- (data/pikachu/pikachu_pic_objects.asm PikaPicAnimBGFrames_*, which script --- N reaches as frameset N+5, or N+6 from script 10 up). The list alternates --- pikaframedelay (the base pic alone) and pikaframe (the overlay) starting --- with a delay, so a frameset that opens on a pikaframe opens with a zero --- here; the frameset restarts until pikapic_looptofinish runs the duration --- out. Scripts 1, 2, 3, 5, 6, 8 and 9 are left without a list on purpose: +-- N reaches as frameset N+5, or N+6 from script 10 up). The frameset +-- restarts until pikapic_looptofinish runs the duration out. +-- Scripts 1, 2, 3, 5, 6, 8 and 9 are left without a list on purpose: -- their overlays (PikaAnimTilemap_14 to _22) only paint a few tiles over a -- pic that otherwise stands still, so with no tiles to paint the port has -- nothing to show for them and must not bob the whole picture instead. @@ -836,29 +831,50 @@ local PIKAPIC = { [4] = { dur = 70, seq = { 8, 8, 20, 8 } }, [5] = { dur = 32 }, [6] = { dur = 50 }, - [7] = { dur = 58, seq = { 0, 8, 2, 8, 2, 8 } }, + [7] = { dur = 58, seq = { 8, 2, 8, 2, 8 }, + poses = { "e4841", false, "e4841", false, "e4841" } }, [8] = { dur = 44 }, [9] = { dur = 56 }, - [10] = { dur = 56, seq = { 8, 11, 5 } }, - [11] = { dur = 100, seq = { 20, 8, 20, 8 } }, - [12] = { dur = 50, seq = { 13, 12, 100, 8 } }, - [13] = { dur = 50, seq = { 5, 5, 5, 5, 100 } }, - [14] = { dur = 40, seq = { 2, 2, 2, 2 } }, - [15] = { dur = 50, seq = { 5, 5, 5, 5 } }, - [16] = { dur = 32, seq = { 0, 8, 100 } }, - [17] = { dur = 100, seq = { 10, 3, 3, 3, 100 } }, - [18] = { dur = 32, seq = { 3, 100, 8, 8 } }, - [19] = { dur = 44, seq = { 0, 6, 6, 6, 6 } }, - [20] = { dur = 50, seq = { 8, 12, 8, 12 } }, - [21] = { dur = 40, seq = { 8, 104 } }, - [22] = { dur = 40, seq = { 8, 100 } }, - [23] = { dur = 70, seq = { 16, 16, 16, 16 } }, - [24] = { dur = 60, seq = { 6, 6, 6, 6, 100 } }, - [25] = { dur = 50, seq = { 6, 106 }, bolt = 13 }, - [26] = { dur = 100, seq = { 20, 8, 20, 116 } }, - [27] = { dur = 30, seq = { 4, 100 } }, - [28] = { dur = 64, seq = { 12, 12, 12, 100 } }, + [10] = { dur = 56, seq = { 8, 3, 5, 3, 5 }, + poses = { false, "e4ce0", "e4e70", "e4ce0", false } }, + [11] = { dur = 100, seq = { 20, 8, 20, 8 }, + poses = { false, "e50af", false, "e50af" } }, + [12] = { dur = 50, seq = { 13, 12, 100, 8 }, + poses = { false, "e52fe", false, "e52fe" } }, + [13] = { dur = 50, seq = { 5, 5, 5, 5, 100 }, + poses = { false, "e5541", false, "e5541", false } }, + [14] = { dur = 40, seq = { 2, 2, 2, 2 }, + poses = { false, "e5794", false, "e5794" } }, + [15] = { dur = 50, seq = { 5, 5, 5, 5 }, + poses = { false, "e59ed", false, "e59ed" } }, + [16] = { dur = 32, seq = { 8, 100 }, + poses = { "e5c4d", false } }, + [17] = { dur = 100, seq = { 10, 3, 3, 3, 100 }, + poses = { false, "e5e90", false, "e5e90", false } }, + [18] = { dur = 32, seq = { 3, 100, 8, 8 }, + poses = { false, "e61b0", false, "e61b0" } }, + [19] = { dur = 44, seq = { 6, 6, 6, 6 }, + poses = { "e63f7", false, "e63f7", false } }, + [20] = { dur = 50, seq = { 8, 12, 8, 12 }, + poses = { false, "e6646", false, "e6646" } }, + [21] = { dur = 40, seq = { 8, 2, 1, 1, 100 }, + poses = { false, "e682f", "e69bf", "e6b4f", "e6cdf" } }, + [22] = { dur = 40, seq = { 8, 100 }, + poses = { false, "e6fff" } }, + [23] = { dur = 70, seq = { 16, 16, 16, 16 }, + poses = { false, "e731f", false, "e731f" } }, + [24] = { dur = 60, seq = { 6, 6, 6, 6, 100 }, + poses = { false, "e763f", false, "e763f", false } }, + [25] = { dur = 50, seq = { 6, 6, 100 }, + poses = { false, "e7863", "e79f3" }, bolt = 13 }, + [26] = { dur = 100, seq = { 20, 8, 20, 8, 8, 100 }, + poses = { false, "e50af", false, "e50af", "e7b83", "e7d13" } }, + [27] = { dur = 30, seq = { 4, 100 }, + poses = { false, "f0b64" } }, + [28] = { dur = 64, seq = { 12, 12, 12, 100 }, + poses = { false, "f0d82", false, "f0d82" } }, } +PikachuFollower.PIKAPIC = PIKAPIC local function moodEmotion(save) local mood = save.pikachuMood or 128 @@ -953,19 +969,22 @@ function playEmotion(game, ow, npc, emotion, opts) -- data/pikachu/pikachu_emotions.asm local function pikapic() - local Sprites = require("src.pokemon.Sprites") local script = PIKAPIC_SCRIPT[emotion] or emotion - local pic = "assets/generated/pikachu/pikapic_" .. script .. ".png" - if not require("src.render.Assets").exists(pic) then - pic = Sprites.path(game.data, "PIKACHU", "front", - { kind = "overworld" }) - end + local pic = PIKAPIC_DIR .. "pikapic_" .. script .. ".png" local anim = PIKAPIC[script] or PIKAPIC[1] local hold = anim.dur * PIKAPIC_TICK + local poses + if anim.poses then + poses = {} + for i = 1, #anim.seq do + local id = anim.poses[i] + poses[i] = id and (PIKAPIC_DIR .. "gfx_" .. id .. ".png") or false + end + end ow.emote = { npc = npc, frames = hold, bubble = false, pikaPic = pic, - pikaSeq = anim.seq, pikaTotal = hold, skippable = opts.skippable, - onDone = done, + pikaSeq = anim.seq, pikaPoses = poses, pikaTotal = hold, + skippable = opts.skippable, onDone = done, } if anim.bolt then -- engine/pikachu/pikachu_pic_animation.asm:520 @@ -1016,24 +1035,37 @@ function playEmotion(game, ow, npc, emotion, opts) return cry() end --- Where the framed pic sits this frame. The overlay a pikaframe run draws --- is a second full-body pose (PikaAnimTilemap_23 and up replace all 5x5 --- tiles) out of gfx/pikachu/unknown_*, which the cache does not carry, so --- the port lifts the one pic it has for the length of those runs -- the jump --- the happy emotions make inside the box (#424, still on #407's stand-in). -function PikachuFollower.picLift(emote) +local function frameRun(emote) local seq = emote and emote.pikaSeq - if not seq then return 0 end + if not seq then return nil end local loop = 0 for _, run in ipairs(seq) do loop = loop + run end - if loop <= 0 then return 0 end + if loop <= 0 then return nil end local elapsed = math.max(0, (emote.pikaTotal or 0) - (emote.frames or 0)) local tick = math.floor(elapsed / PIKAPIC_TICK) % loop for i, run in ipairs(seq) do - if tick < run then return i % 2 == 0 and PIKAPIC_LIFT or 0 end + if tick < run then return i end tick = tick - run end - return 0 + return nil +end + +function PikachuFollower.picLift(emote) + if emote and emote.pikaPoses then return 0 end + local i = frameRun(emote) + return (i and i % 2 == 0) and PIKAPIC_LIFT or 0 +end + +-- engine/pikachu/pikachu_pic_animation.asm:359 +function PikachuFollower.picFrame(emote) + if not emote then return nil, 0 end + if emote.pikaBlankAt and (emote.frames or 0) <= emote.pikaBlankAt then + return nil, 0 + end + local poses = emote.pikaPoses + if not poses then return emote.pikaPic, PikachuFollower.picLift(emote) end + local i = frameRun(emote) + return (i and poses[i]) or emote.pikaPic, 0 end -- engine/pikachu/pikachu_pic_animation.asm:790 @@ -1066,7 +1098,9 @@ function PikachuFollower.tickBolt(game, ow, emote) -- engine/pikachu/pikachu_pic_animation.asm:802 if Sound.moveSfxBusy() and k < strobe + THUNDERBOLT_SOUND_CAP then return end emote.boltDone = true - emote.frames = PIKAPIC_TICK + 1 + -- engine/pikachu/pikachu_pic_animation.asm:136-147 + emote.pikaBlankAt = PIKAPIC_TICK + emote.frames = 2 * PIKAPIC_TICK + 1 end -- Bill's House has three map-scripted Yellow companion beats diff --git a/tests/drivers/blues_house_bug11_test.lua b/tests/drivers/blues_house_bug11_test.lua index b28341dc..cc43b859 100644 --- a/tests/drivers/blues_house_bug11_test.lua +++ b/tests/drivers/blues_house_bug11_test.lua @@ -69,13 +69,27 @@ return function(game) check(game.save.inventory["0"] == 1, "seeded unknown item '0' in bag") -- open the clerk's BUY/SELL/QUIT menu exactly as the mart interaction does + local Menu = require("src.ui.Menu") + local ListMenu = require("src.ui.ListMenu") + local TextBox = require("src.render.TextBox") + local function waitTop(pred) + for _ = 1, 600 do + local top = game.stack:top() + if top and pred(top) then return top end + U.wait(1) + end + end Screens.push(game, "ShopMenu", {}) - U.wait(4) + local shop = waitTop(function(t) + return getmetatable(t) == Menu and not t.hidden + end) + check(shop ~= nil, "clerk menu up after the greeting") + U.wait(2) U.tap(game, "down") -- BUY -> SELL U.wait(4) U.tap(game, "a") -- open the SELL list - U.wait(6) - local sellList = game.stack:top() + local sellList = waitTop(function(t) return getmetatable(t) == ListMenu end) + U.wait(2) check(sellList and sellList.items ~= nil, "SELL list opened") U.shot(game, DIR .. "/bh_2_sell_list.png") @@ -88,7 +102,6 @@ return function(game) check(item ~= nil, "bogus '0' row present in sell list") if item then sellList.index = idx - local footerBefore = sellList.footer -- Invoke the real onChoose the ListMenu would call on A. Before the -- fix this throws at math.floor(def.price/2) with def=nil; we catch -- it so the run reports the crash instead of hanging on love's error @@ -101,9 +114,15 @@ return function(game) check(true, "selling '0' did not crash") -- nothing may be sold: the guard returns before any QuantityBox check(game.save.inventory["0"] == 1, "unknown item still in bag (not sold)") - check(sellList.footer ~= footerBefore - and tostring(sellList.footer):find("price") ~= nil, - "sell footer shows the unsellable message") + local box = game.stack:top() + local said = {} + if getmetatable(box) == TextBox then + for _, page in ipairs(box.pages) do + for _, line in ipairs(page) do said[#said + 1] = line end + end + end + check(table.concat(said, " "):find("price") ~= nil, + "clerk says the unsellable line") end U.wait(4) U.shot(game, DIR .. "/bh_3_sell_choose.png") @@ -112,4 +131,5 @@ return function(game) U.log("RESULT", ("pass=%d fail=%d"):format(pass, fail)) if fail == 0 then U.log("RESULT", "ALL PASS") else U.log("RESULT", "HAS FAILURES") end + love.event.quit(fail == 0 and 0 or 1) end diff --git a/tests/drivers/game3_cut_grass_2470.lua b/tests/drivers/game3_cut_grass_2470.lua new file mode 100644 index 00000000..fc3e7f60 --- /dev/null +++ b/tests/drivers/game3_cut_grass_2470.lua @@ -0,0 +1,127 @@ +local U = require("tests.drivers.util") +local DIR = os.getenv("POKEPORT_SHOT_DIR") or "/tmp/game3_cut_grass_2470" +local failures = 0 +local function result(ok, label) + print((ok and "PASS " or "FAIL ") .. label) + if not ok then failures = failures + 1 end + return ok +end +local function finish() + result(failures == 0, "game3_cut_grass_2470") + love.event.quit(failures == 0 and 0 or 1) +end + +return function(game) + for _ = 1, 600 do + if game.phase == "boot" and game.boot then break end + U.wait(1) + end + if not result(game.phase == "boot" and game.boot ~= nil, "boot_ready") then return finish() end + game:_handleBootAction({ action = "new_game", name = "RED" }) + U.wait(180) + local Runtime = require("src.core.game3.runtime") + local Map = require("src.core.game3.map") + local Player = require("src.core.game3.player") + local Collision = require("src.core.game3.collision") + local Field = require("src.core.game3.field") + local FieldMoves = require("src.core.game3.field_moves") + local Party = require("src.core.game3.party") + local Objects = require("src.core.game3.objects") + require("src.core.game3.encounters").onStep = function() return nil end + require("src.core.game3.trainer_sight").check = function() return false end + local session = Runtime.getSession() + if not result(session ~= nil, "new_game_reached_field") then return finish() end + session.party = {} + Party.giveMon(session, 29, 20) + local mon = session.party[1] + + local function place(map, x, y) + Map.load(Runtime._mod, game, map, { x = x, y = y, facing = "down" }) + Player.surfing, Player.biking = false, false + U.wait(60) + return Map.current == map and Player.cellX == x and Player.cellY == y + end + local function layout() return Map.currentDef().midLayout end + local function findPatch(map) + if Map.current ~= map then place(map, 0, 0) end + local L = game.data.maps[map].midLayout + for y = 1, L.height - 2 do + for x = 1, L.width - 2 do + local ok = true + for dy = -1, 1 do + for dx = -1, 1 do + local cx, cy = x + dx, y + dy + if L:midAt(cx, cy) ~= 0x00D or L:elevAt(cx, cy) ~= 3 or Objects.at(cx, cy) then ok = false end + end + end + if ok then return x, y end + end + end + end + local function cut() + local store = { flags = {}, vars = {} } + require("src.core.game3.scripting.flags").setFlag(store, nil, FieldMoves.BADGE_FLAGS.CUT, true) + local res = FieldMoves.cutFromMenu({ mon = mon, party = session.party, store = store, + hasCuttableGrass = Collision.isGrass(Player.cellX, Player.cellY) }) + if not result(res and res.ok and res.action == "cut_grass", "party_menu_picks_cut_grass") then return false end + Field.executeFieldMove(res) + for _ = 1, 600 do + if not Field.locked then break end + U.wait(1) + end + U.wait(20) + return not Field.locked + end + local function all3x3(cx, cy, fn) + for dy = -1, 1 do + for dx = -1, 1 do + if not fn(cx + dx, cy + dy) then return false end + end + end + return true + end + + local MAP = "FR_ROUTE_1" + local x, y = findPatch(MAP) + if not result(x ~= nil, "route1_grass_patch_found") then return finish() end + print(("[driver] %s grass patch centre (%d,%d)"):format(MAP, x, y)) + if not result(place(MAP, x, y), "placed_in_grass") then return finish() end + result(all3x3(x, y, function(cx, cy) return Collision.isGrass(cx, cy) end), "3x3_is_grass_before") + result(U.still(game, DIR .. "/2470_route1_grass_before_cut.png"), "shot_before") + result(cut(), "cut_finished") + local L = layout() + result(all3x3(x, y, function(cx, cy) return L:midAt(cx, cy) == 0x001 end), "3x3_mowed_to_plain_mowed") + result(all3x3(x, y, function(cx, cy) return not Collision.isGrass(cx, cy) end), "3x3_no_longer_grass") + result(require("src.core.game3.field_effects")._fx == nil, "tall_grass_overlay_gone_from_player") + result(U.still(game, DIR .. "/2470_route1_grass_mowed.png"), "shot_mowed") + + place(MAP, x, y) + L = layout() + result(all3x3(x, y, function(cx, cy) return L:midAt(cx, cy) == 0x00D and Collision.isGrass(cx, cy) end), + "grass_grows_back_on_reload") + + local VF = "FR_VIRIDIAN_FOREST" + local vf = game.data.maps[VF] and game.data.maps[VF].midLayout + local tx, ty + if vf then + for yy = 1, vf.height - 2 do + for xx = 1, vf.width - 2 do + if not tx and vf:midAt(xx, yy) == 0x284 and vf:elevAt(xx, yy) == 3 + and vf:midAt(xx, yy - 1) == 0x00D and vf:elevAt(xx, yy - 1) == 3 then + tx, ty = xx, yy + end + end + end + end + if tx then + print(("[driver] %s 0x284 at (%d,%d)"):format(VF, tx, ty)) + if result(place(VF, tx, ty - 1), "placed_above_huge_tree_grass") then + result(cut(), "forest_cut_finished") + result(layout():midAt(tx, ty) == 0x281, "viridian_forest_0x284_mowed_to_0x281") + result(U.still(game, DIR .. "/2470_viridian_forest_huge_tree_mowed.png"), "shot_forest") + end + else + result(false, "viridian_forest_0x284_cell_found") + end + finish() +end diff --git a/tests/drivers/game3_ghost_trainer_sight_2460.lua b/tests/drivers/game3_ghost_trainer_sight_2460.lua new file mode 100644 index 00000000..0a02bf90 --- /dev/null +++ b/tests/drivers/game3_ghost_trainer_sight_2460.lua @@ -0,0 +1,129 @@ +local U = require("tests.drivers.util") +local DIR = os.getenv("POKEPORT_SHOT_DIR") or "/tmp/bug2460" + +local failures = 0 +local function result(ok, label) + print((ok and "PASS " or "FAIL ") .. label) + if not ok then failures = failures + 1 end + return ok +end + +local function finish() + if failures == 0 then + print("PASS game3_ghost_trainer_sight_2460") + love.event.quit(0) + else + print("FAIL game3_ghost_trainer_sight_2460 failures=" .. failures) + love.event.quit(1) + end +end + +return function(game) + for _ = 1, 600 do + if game.phase == "boot" and game.boot then break end + U.wait(1) + end + game:_handleBootAction({ action = "new_game", name = "RED" }) + U.wait(180) + + local Runtime = require("src.core.game3.runtime") + local Map = require("src.core.game3.map") + local Party = require("src.core.game3.party") + local Objects = require("src.core.game3.objects") + local Player = require("src.core.game3.player") + local Field = require("src.core.game3.field") + local Ghosts = require("src.core.game3.ghosts") + local TrainerSight = require("src.core.game3.trainer_sight") + local Battle = package.loaded["src.core.game3.battle"] or require("src.core.game3.battle") + + local session = Runtime.getSession() + if not result(session ~= nil, "new game reached the field") then return finish() end + session.party = {} + Party.giveMon(session, 7, 40) + + local engaged = {} + local allowReal = false + local realEngage = TrainerSight.engage + TrainerSight.engage = function(g, eo, dist) + engaged[#engaged + 1] = { eo = eo, dist = dist, live = Objects.find(eo and eo.localId) == eo, + script = eo and eo.scriptKey } + print(string.format("[2460] engage lid=%s dist=%s live=%s script=%s", tostring(eo and eo.localId), + tostring(dist), tostring(engaged[#engaged].live), tostring(eo and eo.scriptKey))) + if allowReal then return realEngage(g, eo, dist) end + end + + local function place(mapId, x, y, facing) + Map.load(nil, game, mapId, { x = x, y = y, facing = facing }) + game.session.x, game.session.y, game.session.facing = x, y, facing + U.wait(20) + end + + local function ghostTrainers() + local list = {} + for mapId, pool in pairs(Ghosts._pools or {}) do + for _, lid in ipairs(pool.order or {}) do + local eo = pool.byId[lid] + if eo and (tonumber(eo.sight) or 0) > 0 and TrainerSight.isTrainerType(eo) then + list[#list + 1] = { mapId = mapId, eo = eo } + end + end + end + return list + end + + local function dwell(label, mapId, spots, frames, needCover) + engaged = {} + local cover, pools = 0, 0 + for _, s in ipairs(spots) do + place(mapId, s[1], s[2], s[3]) + local list = ghostTrainers() + pools = math.max(pools, #list) + for _ = 1, frames do + U.wait(1) + if Player.cellX ~= s[1] or Player.cellY ~= s[2] then Player.reset(s[1], s[2], s[3]) end + for _, t in ipairs(ghostTrainers()) do + if not t.eo.hidden and TrainerSight.checkLineOfSight(t.eo, Player, game) then + cover = cover + 1 + end + end + end + end + print(string.format("[2460] %s: %d neighbor-map trainers ticking, %d frames a ghost cone covered the player", + label, pools, cover)) + result(pools > 0, label .. ": neighbor-map trainers are loaded and ticking") + if needCover then + result(cover > 0, label .. ": a neighbor-map trainer's local cone lined up with the player") + end + result(#engaged == 0, label .. ": no neighbor-map trainer engaged (engages=" .. #engaged .. ")") + result(not Field.locked and not (Battle.isActive and Battle.isActive()), label .. ": field unlocked, no battle") + end + + place("FR_VERMILION_CITY", 28, 12, "up") + U.still(game, DIR .. "/2460_01_vermilion_under_dave_ghost.png") + dwell("Vermilion vs Route 11 Dave", "FR_VERMILION_CITY", + { { 28, 12, "up" }, { 29, 14, "up" }, { 28, 14, "up" } }, 400, true) + U.still(game, DIR .. "/2460_02_vermilion_mart_no_engage.png") + + dwell("Fuchsia vs Route 17/18 bikers", "FR_FUCHSIA_CITY", + { { 11, 17, "up" }, { 11, 19, "up" }, { 4, 20, "up" } }, 400, true) + U.still(game, DIR .. "/2460_03_fuchsia_no_engage.png") + + engaged = {} + allowReal = true + place("FR_ROUTE_11", 28, 12, "up") + local dave = Objects.find(4) + result(dave ~= nil and dave.sight == 1 and TrainerSight.isTrainerType(dave), + "control: Route 11 Dave (localId 4) loaded as a current-map trainer") + local spotted = false + for _ = 1, 1200 do + if #engaged > 0 then spotted = true break end + U.wait(1) + end + result(spotted and engaged[1].live and engaged[1].eo == dave and engaged[1].dist == 1, + "control: Dave on Route 11 still spots the player after a pacing step") + if spotted then + U.wait(10) + U.still(game, DIR .. "/2460_04_route11_dave_spots_player.png") + end + return finish() +end diff --git a/tests/drivers/game3_import_dex_count_2461.lua b/tests/drivers/game3_import_dex_count_2461.lua new file mode 100644 index 00000000..e57169cc --- /dev/null +++ b/tests/drivers/game3_import_dex_count_2461.lua @@ -0,0 +1,102 @@ +local U = require("tests.drivers.util") +local DIR = os.getenv("POKEPORT_SHOT_DIR") or "/tmp/game3_import_dex_count_2461" + +local failures = 0 +local function result(ok, label) + print((ok and "PASS " or "FAIL ") .. label) + if not ok then failures = failures + 1 end + return ok +end +local function finish() + print((failures == 0 and "PASS" or "FAIL") .. " import_dex_count_2461 failures=" .. failures) + love.event.quit(failures == 0 and 0 or 1) +end + +local function unrle(s) + local out = {} + for tok in s:gmatch("%S+") do + local k, n = tok:match("^([ZF])(%x+)$") + if k then + out[#out + 1] = string.rep(k == "Z" and "\0" or "\255", tonumber(n, 16)) + else + out[#out + 1] = (tok:gsub("%x%x", function(h) return string.char(tonumber(h, 16)) end)) + end + end + return table.concat(out) +end + +return function(game) + for _ = 1, 900 do + if game.phase == "boot" and game.boot then break end + U.wait(1) + end + + local GameVersion = require("src.core.GameVersion") + local SaveData = require("src.core.SaveData") + local SaveSerializer = require("src.core.SaveSerializer") + local SaveFileIO = require("src.import.SaveFileIO") + local Boot = require("src.ui.game3.boot") + local Dex = require("src.core.game3.dex") + local version = GameVersion.get() + local cart = unrle(require("tests.fixture_data.gen3_saves").images.fr_rich_game) + love.filesystem.write("picked_cart_2461.sav", cart) + local ok, slotId = SaveFileIO.importToSlot("picked_cart_2461.sav", version) + love.filesystem.remove("picked_cart_2461.sav") + if not result(ok == true, "the FireRed cart imports into " .. version .. " (" .. tostring(slotId) .. ")") then + return finish() + end + + local meta + for _, row in ipairs(SaveData.listSlots(version)) do + if row.id == slotId then meta = row.meta end + end + print("launcher meta dexCount=" .. tostring(meta and meta.dexCount) .. " badges=" .. tostring(meta and meta.badges) + .. " time=" .. tostring(meta and meta.timeText)) + result(meta and meta.dexCount == 5, "launcher card shows 5 caught for the fresh import") + result(meta and meta.badges == 2, "launcher card shows 2 badges") + + local raw = SaveSerializer.decode(SaveData.readSlotSource(version, slotId) or "") + local info = raw and Boot.continueInfoFromSave(raw) + result(info and info.dexCount == 5, "CONTINUE window counts 5 caught before the first load") + if info then + Boot.setHasContinue(game.boot, true) + Boot.setContinueInfo(game.boot, info) + end + + local function phase() return game.boot and game.boot.phase end + local n = 0 + while phase() ~= "title" and n < 1200 do + U.tap(game, "start") + U.wait(30) + n = n + 30 + end + for _ = 1, 20 do + if phase() ~= "title" then break end + U.wait(60) + U.tap(game, "start") + U.wait(2) + end + for _ = 1, 600 do + if phase() == "menu" and (game.boot.fadeT or 0) == 0 then break end + U.wait(1) + end + U.wait(4) + print("boot phase=" .. tostring(phase()) .. " game.phase=" .. tostring(game.phase)) + if result(phase() == "menu", "main menu with CONTINUE is up") then + U.still(game, DIR .. "/2461_continue_dex_5.png") + end + + game:_handleBootAction({ action = "continue" }) + local Runtime = require("src.core.game3.runtime") + local s + for _ = 1, 900 do + s = Runtime.getSession() + if s and game.phase ~= "quest_log" and game.phase ~= "boot" then break end + if game.phase == "quest_log" then U.tap(game, "b") end + U.wait(4) + end + s = Runtime.getSession() + if not result(s ~= nil, "CONTINUE reached the field") then return finish() end + result(Dex.countCaught(s.dex, "kanto") == 5, "in-game Kanto dex count is 5 (matches the launcher)") + finish() +end diff --git a/tests/drivers/game3_importer_round2.lua b/tests/drivers/game3_importer_round2.lua index 7d52e92c..b5a82612 100644 --- a/tests/drivers/game3_importer_round2.lua +++ b/tests/drivers/game3_importer_round2.lua @@ -31,14 +31,15 @@ local function find_edge_item(game) table.sort(names) for _, id in ipairs(names) do local def = maps[id] - for dir, conn in pairs(def.connections or {}) do - local nid = type(conn) == "table" and conn.map or conn + for _, conn in ipairs(require("src.core.game3.connections").each(def)) do + local dir = conn.dir + local nid = conn.map local ndef = maps[nid] if ndef and (dir == "north" or dir == "up") then for _, ev in ipairs(ndef.bgEvents or {}) do if is_hidden(ev) and not ev.underfoot then local L = Map.ensureMidLayout(game, nid, ndef) - local off = tonumber(type(conn) == "table" and conn.offset) or 0 + local off = tonumber(conn.offset) or 0 local fromBottom = L and (L.height - 1 - ev.y) if fromBottom and fromBottom <= 2 then return id, nid, ev, ev.x + off, fromBottom diff --git a/tests/drivers/game3_pad_battle_text_bug2452.lua b/tests/drivers/game3_pad_battle_text_bug2452.lua new file mode 100644 index 00000000..7c0cca04 --- /dev/null +++ b/tests/drivers/game3_pad_battle_text_bug2452.lua @@ -0,0 +1,109 @@ +local U = require("tests.drivers.util") +local DIR = os.getenv("POKEPORT_SHOT_DIR") or "/tmp/game3_pad_battle_text_bug2452" + +return function(game) + local fails = 0 + local function result(ok, label) + print((ok and "PASS " or "FAIL ") .. label) + if not ok then fails = fails + 1 end + end + + for _ = 1, 600 do + if game.phase == "boot" and game.boot then break end + U.wait(1) + end + game:_handleBootAction({ action = "new_game", name = "RED" }) + U.wait(180) + + local Runtime = require("src.core.game3.runtime") + local Party = require("src.core.game3.party") + local BattleBridge = require("src.core.game3.battle_bridge") + local Battle = require("src.core.game3.battle") + local Ui = require("src.core.game3.battle.ui") + local session = Runtime.getSession() + session.party = {} + Party.giveMon(session, 6, 50) + + local ok, err = BattleBridge.startWild(Runtime._mod, game, { species = 16, level = 45 }, { fade = false }) + result(ok == true, "2452_wild_battle_started " .. tostring(err or "")) + if not ok then love.event.quit(1) return end + + local physical = {} + local pad = { + isGamepad = function() return true end, + isGamepadDown = function(_, button) return physical[button] == true end, + getGamepadAxis = function() return 0 end, + getName = function() return "Xbox Controller" end, + getGUID = function() return "030000005e040000" end, + getID = function() return 1 end, + isConnected = function() return true end, + } + + local input = game.input + local edges = 0 + local origStep = input.step + input.step = function(self, ...) + local r = origStep(self, ...) + if self.pressed and self.pressed.a then edges = edges + 1 end + return r + end + + local win = love.window + local origMin, origFocus = win.isMinimized, win.hasFocus + local minimized, focused = false, true + win.isMinimized = function() return minimized end + win.hasFocus = function() return focused end + + local function padA() + local before = edges + physical.a = true + love.gamepadpressed(pad, "a") + U.wait(2) + physical.a = false + love.gamepadreleased(pad, "a") + U.wait(12) + return edges - before + end + + local function atCommand() + return Battle.isActive() and Battle._phase == "command" and Ui._mode == "menu" + end + + local presses, doubles = 0, 0 + for _ = 1, 300 do + if atCommand() then break end + if Ui.dialogPending and Ui.dialogPending() then + focused = (presses % 2 == 1) + local n = padA() + presses = presses + 1 + if n ~= 1 then doubles = doubles + 1 end + else + U.wait(1) + end + end + focused = true + result(atCommand(), "2452_battle_text_advanced_on_pad_a") + result(presses > 0, "2452_pad_presses_used " .. presses) + result(doubles == 0, "2452_one_edge_per_pad_press") + U.still(game, DIR .. "/2452_command_menu_after_pad_a.png") + + local sawText = false + for i = 1, 600 do + if Ui.dialogPending and Ui.dialogPending() then sawText = true break end + if i % 20 == 1 then U.tap(game, "a") else U.wait(1) end + end + if sawText then + minimized = true + local dropped = padA() + result(dropped == 0, "2452_minimized_pad_press_dropped") + minimized = false + local landed = padA() + result(landed == 1, "2452_restored_pad_press_lands") + else + result(false, "2452_no_text_after_fight") + end + + input.step = origStep + win.isMinimized, win.hasFocus = origMin, origFocus + love.event.quit(fails == 0 and 0 or 1) +end diff --git a/tests/drivers/game3_pewter_guide_bug2472.lua b/tests/drivers/game3_pewter_guide_bug2472.lua new file mode 100644 index 00000000..20696f6f --- /dev/null +++ b/tests/drivers/game3_pewter_guide_bug2472.lua @@ -0,0 +1,164 @@ +local U = require("tests.drivers.util") +local DIR = os.getenv("POKEPORT_SHOT_DIR") or "/tmp/bug2472" + +local PEWTER = "FR_PEWTER_CITY" +local GYM_GUIDE, GYM_X, GYM_Y = 5, 42, 20 +local MUSEUM_GUIDE, MUSEUM_X, MUSEUM_Y = 2, 33, 17 + +local failures = 0 +local function result(ok, label) + print((ok and "PASS " or "FAIL ") .. label) + if not ok then failures = failures + 1 end + return ok +end + +local function finish() + if failures == 0 then + print("PASS game3_pewter_guide_bug2472") + love.event.quit(0) + else + print("FAIL game3_pewter_guide_bug2472 failures=" .. failures) + love.event.quit(1) + end +end + +return function(game) + for _ = 1, 600 do + if game.phase == "boot" and game.boot then break end + U.wait(1) + end + game:_handleBootAction({ action = "new_game", name = "RED" }) + U.wait(180) + + local Runtime = require("src.core.game3.runtime") + local Map = require("src.core.game3.map") + local Space = require("src.core.game3.scripting.space") + local Party = require("src.core.game3.party") + local Objects = require("src.core.game3.objects") + local Player = require("src.core.game3.player") + local Field = require("src.core.game3.field") + local Message = package.loaded["src.ui.game3.message"] or require("src.ui.game3.message") + local Choice = require("src.ui.game3.choice") + + local session = Runtime.getSession() + if not result(session ~= nil, "new game reached the field") then return finish() end + session.party = {} + Party.giveMon(session, 4, 12) + + local function vmBusy() + return Space.vm and Space.vm.isRunning and Space.vm:isRunning() + end + local function msgOpen() + return Message.isOpen and Message.isOpen() + end + + Map.load(nil, game, PEWTER, { x = GYM_X - 1, y = GYM_Y, facing = "right" }) + game.session.x, game.session.y, game.session.facing = GYM_X - 1, GYM_Y, "right" + U.wait(30) + + local bounds = Objects._bounds + if not result(bounds and bounds.w > 0 and bounds.h > 0, "Pewter layout bounds known") then return finish() end + local function inBounds(x, y) + return x >= 0 and y >= 0 and x < bounds.w and y < bounds.h + end + + local function escort(lid, label, answerNo) + local worst, lastPage + local started = false + for _ = 1, 3000 do + local eo = Objects.find(lid) + if eo and not eo.hidden and not inBounds(eo.cellX, eo.cellY) then + worst = worst or string.format("guide (%d,%d)", eo.cellX, eo.cellY) + end + if not inBounds(Player.cellX, Player.cellY) then + worst = worst or string.format("player (%d,%d)", Player.cellX, Player.cellY) + end + if vmBusy() or Field.locked then started = true end + if started and not vmBusy() and not msgOpen() and not Field.locked then break end + if Choice.isOpen and Choice.isOpen() then + print("[2472] yes/no open, answering " .. (answerNo and "NO" or "YES")) + if answerNo then Choice.cursor = 2 end + U.tap(game, "a") + elseif msgOpen() then + local page = Message.currentPage and Message.currentPage() + if page and page ~= lastPage then + print("[2472] " .. label .. " text: " .. tostring(page):gsub("\n", " ")) + lastPage = page + end + if answerNo and tostring(page):find("MUSEUM?", 1, true) then + for _ = 1, 120 do + if Choice.isOpen() then break end + U.wait(1) + end + end + if not Choice.isOpen() then U.tap(game, "a") end + end + U.wait(2) + end + result(started, label .. ": script ran") + result(not vmBusy() and not Field.locked, label .. ": script finished and field unlocked") + result(worst == nil, label .. ": guide and player stayed inside the map" .. (worst and (" (left at " .. worst .. ")") or "")) + return Player.cellX, Player.cellY + end + + local function atTemplate(lid, x, y, label, before, face) + local eo = Objects.find(lid) + result(eo ~= nil and eo.visible and not eo.hidden, label .. ": guide visible again") + result(eo ~= nil and eo.cellX == x and eo.cellY == y, + string.format("%s: guide back on template (%d,%d), got (%s,%s)", label, x, y, + tostring(eo and eo.cellX), tostring(eo and eo.cellY))) + if face then + result(eo ~= nil and eo.facing == face, label .. ": template facing " .. face .. ", got " .. tostring(eo and eo.facing)) + end + result(eo ~= before, label .. ": guide is a respawned object") + return eo + end + + local guide = Objects.find(GYM_GUIDE) + if not result(guide ~= nil and guide.cellX == GYM_X and guide.cellY == GYM_Y and not guide.hidden, + "gym guide spawned at (42,20)") then return finish() end + U.still(game, DIR .. "/2472_01_gym_guide_at_spawn.png") + + U.tap(game, "a") + local px1, py1 = escort(GYM_GUIDE, "gym escort 1", false) + print(string.format("[2472] escort 1 left the player at (%d,%d)", px1, py1)) + result(px1 < 20, "gym escort 1 brought the player to the gym side of town") + local after = Objects.find(GYM_GUIDE) + result(not (after and not after.hidden and after.cellX == 7 and after.cellY == 19), + "no stale gym guide left standing at the exit cell (7,19)") + U.still(game, DIR .. "/2472_02_gym_escort_done_guide_gone.png") + guide = atTemplate(GYM_GUIDE, GYM_X, GYM_Y, "gym guide", guide, "down") + + Player.reset(GYM_X - 1, GYM_Y, "right") + U.wait(20) + U.still(game, DIR .. "/2472_03_gym_guide_back_at_spawn.png") + U.tap(game, "a") + local px2, py2 = escort(GYM_GUIDE, "gym escort 2", false) + result(px2 == px1 and py2 == py1, + string.format("gym escort 2 ends where escort 1 did (%d,%d vs %d,%d)", px2, py2, px1, py1)) + atTemplate(GYM_GUIDE, GYM_X, GYM_Y, "gym guide after replay", guide, "down") + + Player.reset(MUSEUM_X, MUSEUM_Y + 1, "up") + U.wait(20) + local museum = Objects.find(MUSEUM_GUIDE) + if not result(museum ~= nil and museum.cellX == MUSEUM_X and museum.cellY == MUSEUM_Y and not museum.hidden, + "museum guide spawned at (33,17)") then return finish() end + U.tap(game, "a") + local mx1, my1 = escort(MUSEUM_GUIDE, "museum escort 1", true) + print(string.format("[2472] museum escort 1 left the player at (%d,%d)", mx1, my1)) + result(mx1 ~= MUSEUM_X or my1 ~= MUSEUM_Y + 1, "museum escort 1 moved the player") + museum = atTemplate(MUSEUM_GUIDE, MUSEUM_X, MUSEUM_Y, "museum guide", museum, nil) + U.still(game, DIR .. "/2472_04_museum_escort_done.png") + + Player.reset(MUSEUM_X, MUSEUM_Y + 1, "up") + U.wait(20) + local m = Objects.find(MUSEUM_GUIDE) + if m then m.facing = "down" end + U.tap(game, "a") + local mx2, my2 = escort(MUSEUM_GUIDE, "museum escort 2", true) + result(mx2 == mx1 and my2 == my1, + string.format("museum escort 2 ends where escort 1 did (%d,%d vs %d,%d)", mx2, my2, mx1, my1)) + atTemplate(MUSEUM_GUIDE, MUSEUM_X, MUSEUM_Y, "museum guide after replay", museum, nil) + + return finish() +end diff --git a/tests/drivers/game3_shift_exp_2473.lua b/tests/drivers/game3_shift_exp_2473.lua new file mode 100644 index 00000000..7aa5f0f0 --- /dev/null +++ b/tests/drivers/game3_shift_exp_2473.lua @@ -0,0 +1,154 @@ +local U = require("tests.drivers.util") +local DIR = os.getenv("POKEPORT_SHOT_DIR") or "/tmp/game3_shift_exp_2473" + +return function(game) + local fails = 0 + local function result(ok, label) + print((ok and "PASS " or "FAIL ") .. label) + if not ok then fails = fails + 1 end + end + + for _ = 1, 600 do + if game.phase == "boot" and game.boot then break end + U.wait(1) + end + game:_handleBootAction({ action = "new_game", name = "RED" }) + U.wait(180) + + local Runtime = require("src.core.game3.runtime") + local Party = require("src.core.game3.party") + local Options = require("src.core.game3.options") + local BattleBridge = require("src.core.game3.battle_bridge") + local Battle = require("src.core.game3.battle") + local Anim = require("src.core.game3.battle.anim") + local SwitchSeq = require("src.core.game3.battle.switch_seq") + local Ui = require("src.core.game3.battle.ui") + local session = Runtime.getSession() + session.party = {} + Party.giveMon(session, 4, 30) + Party.giveMon(session, 7, 20) + Options.ensure(session).battleStyle = 0 + result(Options.battleStyle(session) == "shift", "battle style is shift") + + local ok, err = BattleBridge.start(Runtime._mod, game, + { trainerId = 326, party = { { species = 16, level = 5 }, { species = 19, level = 5 } } }, + { wild = false, trainerId = 326, fade = false }) + result(ok == true, "trainer battle started " .. tostring(err or "")) + if not ok then love.event.quit(1) return end + + local f, lastTap = 0, 0 + local function at_command() + return Battle.isActive() and Battle._phase == "command" and Ui._mode == "menu" + end + + local shiftOrder, goShot, participantsAfter = nil, false, nil + local function watch_shift() + if not SwitchSeq.busy() or shiftOrder then return end + local steps = SwitchSeq._steps or {} + local order = {} + for _, s in ipairs(steps) do + if s.kind == "swap_data" then order[#order + 1] = s.data and s.data.side end + end + if #order == 2 then shiftOrder = order end + end + + local function pump(stop, limit) + for _ = 1, limit or 6000 do + f = f + 1 + watch_shift() + if stop() then return true end + local cur = SwitchSeq.busy() and SwitchSeq._steps and SwitchSeq._steps[SwitchSeq._i] + local bst = Battle.getState() + if not goShot and cur and cur.kind == "sendout_player" and bst + and bst.enemy and (tonumber(bst.enemy.mon.hp) or 0) <= 0 then + U.wait(10) + U.still(game, DIR .. "/2473_mon2_out_before_foe.png") + goShot = true + end + local PM = package.loaded["src.ui.game3.party_menu"] + if PM and PM.isOpen and PM.isOpen() then + U.wait(20) + PM.cursor = 2 + U.tap(game, "a") + U.wait(12) + U.tap(game, "a") + U.wait(12) + elseif Ui.choiceActive and Ui.choiceActive() then + U.wait(8) + U.tap(game, "a") + U.wait(8) + elseif Ui.dialogPending and Ui.dialogPending() and f - lastTap >= 14 then + lastTap = f + U.tap(game, "a") + else + U.wait(1) + end + end + return stop() + end + + result(pump(at_command), "reached command menu vs foe 1") + local st = Battle.getState() + if not st then love.event.quit(1) return end + for _, m in ipairs(st.foeParty or {}) do + m.moves = { 150, 0, 0, 0 } + m.pp = { 40, 0, 0, 0 } + m.hp = 1 + end + st.enemy.mon.hp = 1 + local ep = Anim.present("enemy") + if ep then ep.displayHp = 1 end + + local function attack() + local mon = st.player.mon + mon.moves[1] = 129 + mon.pp = mon.pp or {} + mon.pp[1] = 20 + Ui._pendingCommand = { kind = "move", move = 129, slot = 1, user = "player" } + Ui._mode = "none" + end + + attack() + result(pump(function() return Battle._phase == "shift_prompt" end), "shift prompt offered after foe 1 fainted") + result(pump(function() return at_command() and st.player.partyIndex == 2 end), "shift switched to party slot 2") + result(shiftOrder ~= nil and shiftOrder[1] == "player" and shiftOrder[2] == "enemy", + "player swap runs before enemy send-out (" .. table.concat(shiftOrder or {}, ",") .. ")") + result(goShot, "shot 2473_mon2_out_before_foe.png") + participantsAfter = {} + for pi in pairs(st.enemy.participants or {}) do participantsAfter[#participantsAfter + 1] = pi end + table.sort(participantsAfter) + result(#participantsAfter == 1 and participantsAfter[1] == 2, + "foe 2 sent mons = {" .. table.concat(participantsAfter, ",") .. "}") + + local expA = tonumber(st.playerParty[1].exp) or 0 + local expB = tonumber(st.playerParty[2].exp) or 0 + st.enemy.mon.hp = 1 + ep = Anim.present("enemy") + if ep then ep.displayHp = 1 end + attack() + local expShot = false + result(pump(function() + if not expShot then + for _, t in ipairs(Ui.log()) do + if tostring(t):find("gained", 1, true) and (tonumber(st.playerParty[2].exp) or 0) > expB then + U.wait(90) + U.still(game, DIR .. "/2473_only_mon2_gains_exp.png") + expShot = true + break + end + end + end + return not Battle.isActive() + end, 9000), "battle ended after foe 2 fainted") + local party = session.party + local aNow = tonumber(party[1] and party[1].exp) or 0 + local bNow = tonumber(party[2] and party[2].exp) or 0 + print(string.format(" exp A %d -> %d, B %d -> %d", expA, aNow, expB, bNow)) + result(aNow == expA, "switched-out mon 1 gained no EXP for foe 2") + result(bNow > expB, "mon 2 gained EXP for foe 2") + result(expShot, "shot 2473_only_mon2_gains_exp.png") + for _, t in ipairs(Ui.log()) do print(" log: " .. tostring(t):gsub("\n", " ")) end + + print(string.format("shift exp 2473 driver: %d failure(s)", fails)) + love.event.quit(fails == 0 and 0 or 1) +end diff --git a/tests/drivers/game3_six_island_water_path.lua b/tests/drivers/game3_six_island_water_path.lua new file mode 100644 index 00000000..884bb054 --- /dev/null +++ b/tests/drivers/game3_six_island_water_path.lua @@ -0,0 +1,88 @@ +local U = require("tests.drivers.util") +local DIR = os.getenv("POKEPORT_SHOT_DIR") or "/tmp/game3_six_island_water_path" +local failures = 0 +local function result(ok, label) + print((ok and "PASS " or "FAIL ") .. label) + if not ok then failures = failures + 1 end + return ok +end +local function finish() + result(failures == 0, "game3_six_island_water_path") + love.event.quit(failures == 0 and 0 or 1) +end + +return function(game) + for _ = 1, 600 do + if game.phase == "boot" and game.boot then break end + U.wait(1) + end + if not result(game.phase == "boot" and game.boot ~= nil, "boot_ready") then return finish() end + game:_handleBootAction({ action = "new_game", name = "RED" }) + U.wait(180) + local Runtime = require("src.core.game3.runtime") + local Map = require("src.core.game3.map") + local Player = require("src.core.game3.player") + require("src.core.game3.encounters").onStep = function() return nil end + require("src.core.game3.trainer_sight").check = function() return false end + if not result(Runtime.getSession() ~= nil, "new_game_reached_field") then return finish() end + local WP = "FR_SIX_ISLAND_WATER_PATH" + + local function setup(map, x, y, facing) + Map.load(Runtime._mod, game, map, { x = x, y = y, facing = facing }) + Player.surfing, Player.elevation = false, 3 + U.wait(60) + return result(Map.current == map and Player.cellX == x and Player.cellY == y, "setup_" .. map .. "_" .. y) + end + local function step(dir) + local oldMap, x, y = Map.current, Player.cellX, Player.cellY + for _ = 1, 24 do + U.hold(game, dir, 1) + if Player.moving or Map.current ~= oldMap then break end + end + for _ = 1, 48 do + if not Player.moving then break end + U.wait(1) + end + return not Player.moving and (Map.current ~= oldMap or Player.cellX ~= x or Player.cellY ~= y) + end + local function at(map, x, y, label) + local session = Runtime.getSession() + return result(Map.current == map and Player.cellX == x and Player.cellY == y + and session.map == map and session.x == x and session.y == y, label) + end + local function drawsWest(row, sourceMap, sx, sy, label) + local mid, _, void = Map.worldMidAt(-1, row, Map.currentDef()) + local src = game.data.maps[sourceMap].midLayout + return result(mid ~= nil and not void and mid == src:midAt(sx, sy), label) + end + + if not setup("FR_SIX_ISLAND", 23, 12, "right") then return finish() end + if not result(step("right"), "six_island_east_step") then return finish() end + if not at(WP, 0, 52, "six_island_east_lands_on_water_path") then return finish() end + result(#Map.neighborList == 3, "water_path_has_three_west_neighbors") + drawsWest(52, "FR_SIX_ISLAND", 23, 12, "water_path_row52_draws_six_island") + U.wait(30) + result(U.still(game, DIR .. "/2456_water_path_six_island_west.png"), "shot_six_island_west") + if not result(step("left"), "water_path_west_step_row52") then return finish() end + at("FR_SIX_ISLAND", 23, 12, "water_path_row52_back_to_six_island") + + if setup(WP, 0, 10, "left") then + drawsWest(10, "FR_SIX_ISLAND_GREEN_PATH", 71, 10, "water_path_row10_draws_green_path") + U.wait(30) + result(U.still(game, DIR .. "/2456_water_path_green_path_west.png"), "shot_green_path_west") + result(step("left"), "water_path_west_step_row10") + at("FR_SIX_ISLAND_GREEN_PATH", 71, 10, "water_path_row10_to_green_path") + end + + if setup(WP, 0, 90, "left") then + drawsWest(90, "FR_SIX_ISLAND_RUIN_VALLEY", 47, 10, "water_path_row90_draws_ruin_valley") + result(step("left"), "water_path_west_step_row90") + at("FR_SIX_ISLAND_RUIN_VALLEY", 47, 10, "water_path_row90_to_ruin_valley") + end + + if setup(WP, 0, 48, "left") then + result(step("left"), "water_path_west_step_row48") + at("FR_SIX_ISLAND", 23, 8, "water_path_row48_to_six_island") + end + finish() +end diff --git a/tests/drivers/gen1_mart_sell_glyph_test.lua b/tests/drivers/gen1_mart_sell_glyph_test.lua index 4a59d101..f752deaf 100644 --- a/tests/drivers/gen1_mart_sell_glyph_test.lua +++ b/tests/drivers/gen1_mart_sell_glyph_test.lua @@ -77,7 +77,7 @@ return function(game) U.tap(game, "a") U.wait(20) end - list = waitForList(60) + list = waitForList(300) if list then break end closeAll() end diff --git a/tests/drivers/mart_clerk_typing_bug2384.lua b/tests/drivers/mart_clerk_typing_bug2384.lua new file mode 100644 index 00000000..3d047e18 --- /dev/null +++ b/tests/drivers/mart_clerk_typing_bug2384.lua @@ -0,0 +1,126 @@ +-- home/text_script.asm:141-150 +-- engine/events/pokemart.asm:7-19 +-- engine/events/pokemart.asm:131-133 +-- engine/events/pokemart.asm:199-206 +-- engine/events/pokemart.asm:220-222 +-- engine/menus/text_box.asm:168-176 +return function(game) + local U = dofile("tests/drivers/util.lua") + local DIR = os.getenv("POKEPORT_SHOT_DIR") or os.getenv("SHOT_DIR") or "/tmp/shots" + local Menu = require("src.ui.Menu") + local ListMenu = require("src.ui.ListMenu") + local TextBox = require("src.render.TextBox") + + local failures = 0 + local function check(label, ok) + if not ok then failures = failures + 1 end + U.log(ok and "PASS" or "FAIL", label) + return ok + end + local function top() return game.stack:top() end + local function states() return game.stack.states or {} end + local function waitFor(pred, frames) + for _ = 1, frames or 600 do + if pred() then return true end + U.wait(1) + end + return pred() + end + local function typing(first) + local t = top() + if getmetatable(t) ~= TextBox or not t.stay or t.done then return false end + local page = t.pages and t.pages[1] or {} + if page[1] ~= first then return false end + local line = t.shown and t.shown[1] + return line ~= nil and #line >= 3 and #line < #page[1] + end + local function onStack(cls) + for _, s in ipairs(states()) do + if getmetatable(s) == cls then return s end + end + return nil + end + local function finish() + U.log(failures == 0 and "PASS mart_clerk_typing_bug2384" + or ("FAIL mart_clerk_typing_bug2384 (" .. failures .. " failures)")) + love.event.quit(failures == 0 and 0 or 1) + U.wait(600) + end + + local ok, err = pcall(function() + game.save.money = 3000 + game.save.options = game.save.options or {} + game.save.options.textSpeed = 3 + U.teleport(game, "PEWTER_MART", 2, 5, "left") + U.wait(20) + local ow = top() + + U.tap(game, "a") + if not check("the greeting types in an empty box", + waitFor(function() return typing("Hi there!") end, 120)) then return end + local menu = onStack(Menu) + check("BUY/SELL/QUIT is on the stack but hidden", menu ~= nil and menu.hidden == true) + U.still(game, DIR .. "/2384_greeting_typing.png") + + if not check("BUY/SELL/QUIT comes up after the greeting", + waitFor(function() return top() == menu end, 300)) then return end + check("the menu is drawn now", menu.hidden == false) + check("filled cursor on BUY", menu.index == 1 and menu.hollowIndex == nil) + U.wait(4) + U.still(game, DIR .. "/2384_menu_filled_cursor.png") + + U.tap(game, "a") + if not check("Take your time. types before the list", + waitFor(function() return typing("Take your time.") end, 60)) then return end + check("BUY goes hollow", menu.hollowIndex == 1) + check("no list while the lead-in types", onStack(ListMenu) == nil) + U.still(game, DIR .. "/2384_take_your_time_typing.png") + + if not check("the buy list opens after the lead-in", + waitFor(function() return getmetatable(top()) == ListMenu end, 300)) then return end + U.wait(6) + check("BUY stays hollow while the list is up", menu.hollowIndex == 1) + U.still(game, DIR .. "/2384_buy_list_hollow_buy.png") + + U.tap(game, "b") + if not check("anything-else types after the list closes", + waitFor(function() return typing("Is there anything") end, 60)) then return end + check("BUY still hollow while it types", menu.hollowIndex == 1) + U.still(game, DIR .. "/2384_anything_else_typing.png") + + if not check("back on BUY/SELL/QUIT", + waitFor(function() return top() == menu end, 300)) then return end + check("cursor reset to BUY and filled", menu.index == 1 and menu.hollowIndex == nil) + U.wait(4) + U.still(game, DIR .. "/2384_back_on_buy.png") + + U.tap(game, "down") + U.wait(4) + U.tap(game, "down") + U.wait(4) + check("cursor on QUIT", menu.index == 3) + U.tap(game, "a") + local bye + if not check("Thank you! goes up", waitFor(function() + local t = top() + if getmetatable(t) == TextBox and not t.stay then bye = t return true end + return false + end, 30)) then return end + local s = states() + check("the mart menu stays under Thank you!", s[#s - 1] == menu) + check("QUIT is hollow under Thank you!", menu.hollowIndex == 3) + waitFor(function() return bye.done end, 300) + U.wait(4) + U.still(game, DIR .. "/2384_thank_you.png") + + U.tap(game, "a") + check("the mart closes back to the overworld", + waitFor(function() return top() == ow end, 60)) + check("no mart screen left", onStack(Menu) == nil and onStack(ListMenu) == nil) + end) + if not ok then + failures = failures + 1 + U.log("FAIL driver error:", tostring(err)) + end + finish() +end diff --git a/tests/drivers/mart_price_text_bug2291.lua b/tests/drivers/mart_price_text_bug2291.lua index bd4e299b..334930e2 100644 --- a/tests/drivers/mart_price_text_bug2291.lua +++ b/tests/drivers/mart_price_text_bug2291.lua @@ -58,7 +58,7 @@ return function(game) local menu = top() U.tap(game, "a") - if not check("BUY opens the list", waitFor(function() return topIs(ListMenu) end, 60)) then return end + if not check("BUY opens the list", waitFor(function() return topIs(ListMenu) end, 300)) then return end local list = top() local itemId = list.items[list.index].value local def = game.data.items[itemId] @@ -109,12 +109,12 @@ return function(game) check("NO buys nothing", game.save.money == 3000) U.tap(game, "b") - if not check("B returns to BUY/SELL/QUIT", waitFor(function() return top() == menu end, 30)) then return end + if not check("B returns to BUY/SELL/QUIT", waitFor(function() return top() == menu end, 300)) then return end U.wait(4) U.tap(game, "down") U.wait(4) U.tap(game, "a") - if not check("SELL opens the sell list", waitFor(function() return topIs(ListMenu) end, 60)) then return end + if not check("SELL opens the sell list", waitFor(function() return topIs(ListMenu) end, 300)) then return end local sellList = top() for _ = 1, 20 do local row = sellList.items[sellList.index] diff --git a/tests/drivers/overworld_fast_forward_bug2471.lua b/tests/drivers/overworld_fast_forward_bug2471.lua new file mode 100644 index 00000000..2b3a586e --- /dev/null +++ b/tests/drivers/overworld_fast_forward_bug2471.lua @@ -0,0 +1,111 @@ +local U = require("tests.drivers.util") +local FixedStep = require("src.core.FixedStep") + +local SHOT_DIR = os.getenv("POKEPORT_SHOT_DIR") or "/tmp/pokeport-shots" + +return function(game) + local failed = false + local function expect(cond, label) + print((cond and "PASS " or "FAIL ") .. label) + if not cond then failed = true end + end + + local pos + local gen = "gen" .. tostring(require("src.core.GameVersion").generation()) + + if gen == "gen1" then + U.newGame(game) + U.teleport(game, "PALLET_TOWN", 8, 6, "down") + pos = function() + local p = game.overworld and game.overworld.player + return p and p.cellX, p and p.cellY + end + elseif gen == "gen2" then + U.wait(60) + if game.world and game.world.map then + game.world:warpToMapId("NEW_BARK_TOWN", 5, 6, "down") + U.wait(120) + end + pos = function() + local p = game.world and game.world.player + return p and p.cellX, p and p.cellY + end + else + for _ = 1, 900 do + if game.phase == "boot" and game.boot then break end + U.wait(1) + end + game:_handleBootAction({ action = "new_game", name = "RED" }) + U.wait(240) + pos = function() + local s = game.session + return s and s.x, s and s.y + end + end + local x0, y0 = pos() + expect(x0 ~= nil, gen .. "_2471_overworld_reached") + if x0 == nil then love.event.quit(1) return end + + local counted = 0 + local orig = FixedStep.callback + FixedStep.callback = function(dt) + counted = counted + 1 + return orig(dt) + end + + local function stepsPerUpdate(speed, updates) + game.speedOverride = speed + counted = 0 + for _ = 1, updates do game:update(1 / 60) end + game.speedOverride = 1 + return counted / updates + end + + local function walk(speed, dir, updates) + local ax, ay = pos() + game.speedOverride = speed + for _ = 1, updates do + table.insert(game.input.pressQueue, dir) + game.input.state[dir] = true + game:update(1 / 60) + end + game.input.state[dir] = false + game.speedOverride = 1 + for _ = 1, 60 do game:update(1 / 60) end + local bx, by = pos() + return math.abs((bx or ax) - ax) + math.abs((by or ay) - ay) + end + + local s10 = stepsPerUpdate(10, 30) + local s200 = stepsPerUpdate(200, 30) + print(("[2471] %s logic steps per rendered frame: 10X=%.1f 200X=%.1f"):format(gen, s10, s200)) + expect(math.abs(s10 - 10) < 0.5, gen .. "_2471_10x_runs_10_steps_a_frame") + expect(s200 > 60, gen .. "_2471_200x_not_capped_at_15") + + local best, bestDir = -1, nil + for _, dir in ipairs({ "left", "right", "down", "up" }) do + local sx, sy = pos() + local cells10 = walk(10, dir, 1) + local back = ({ left = "right", right = "left", up = "down", down = "up" })[dir] + for _ = 1, 120 do + local cx, cy = pos() + if cx == sx and cy == sy then break end + walk(1, back, 1) + end + local cells200 = walk(200, dir, 1) + print(("[2471] %s %s: 10X moved %d cells, 200X moved %d cells in one frame") + :format(gen, dir, cells10, cells200)) + if cells200 - cells10 > best then best, bestDir = cells200 - cells10, dir end + if cells200 >= 3 and cells200 > cells10 * 2 then break end + for _ = 1, 200 do + local cx, cy = pos() + if cx == sx and cy == sy then break end + walk(4, back, 1) + end + end + expect(best >= 2, gen .. "_2471_200x_moves_more_cells_than_10x_" .. tostring(bestDir)) + FixedStep.callback = orig + + U.still(game, SHOT_DIR .. "/2471_" .. gen .. "_after_200x_frame.png") + love.event.quit(failed and 1 or 0) +end diff --git a/tests/drivers/pikachu_cadence_bug424_test.lua b/tests/drivers/pikachu_cadence_bug424_test.lua index 0cb9263e..49a9eba0 100644 --- a/tests/drivers/pikachu_cadence_bug424_test.lua +++ b/tests/drivers/pikachu_cadence_bug424_test.lua @@ -22,6 +22,9 @@ return function(game) for _, r in ipairs(results) do U.log(r.ok and "PASS" or "FAIL", r.label) end end local function idleForever() + local failed = false + for _, r in ipairs(results) do if not r.ok then failed = true end end + love.event.quit(failed and 1 or 0) while true do coroutine.yield() end end @@ -37,7 +40,10 @@ return function(game) -- follower and every count below would read as the bug. game.save.flags = game.save.flags or {} game.save.flags.EVENT_GOT_STARTER = true + game.save.flags.EVENT_BATTLED_RIVAL_IN_OAKS_LAB = true + game.save.pikachuInBall = false game.save.party = { Pokemon.new(game.data, "PIKACHU", 20) } + require("src.battle.BattleState").stampOT(game.save, game.save.party[1]) game.save.onBike = false local frames = 0 @@ -261,8 +267,12 @@ return function(game) U.tap(game, "a") U.wait(1) + for _ = 1, 600 do + if ow.emote and ow.emote.pikaPic then break end + U.wait(1) + end local emote = ow.emote - if not check("the A press raised the framed pikapic", emote ~= nil) then + if not check("the A press raised the framed pikapic", emote ~= nil and emote.pikaPic ~= nil) then report() idleForever() end @@ -275,12 +285,12 @@ return function(game) local lifted, grounded, liftShot = 0, 0, nil for _ = 1, 60 do if not ow.emote then break end - local lift = PikachuFollower.picLift(ow.emote) - if lift > 0 then + local path = PikachuFollower.picFrame(ow.emote) + if path and path:find("gfx_e6646", 1, true) then lifted = lifted + 1 if not liftShot then - liftShot = SHOT_DIR .. "/bug424_pikapic_lift.png" - if U.shot(game, liftShot) then U.log("captured", liftShot) + liftShot = SHOT_DIR .. "/bug424_pikapic_pose_e6646.png" + if U.still(game, liftShot) then U.log("captured", liftShot) else liftShot = nil end end else @@ -288,9 +298,9 @@ return function(game) end step(1) end - check("the pic sits on the box floor for part of the beat", grounded > 0) - check("and rises off it for another part", lifted > 0) - U.log("of the first 60 frames the pic was up for", lifted, "and down for", + check("the base pic shows for part of the beat", grounded > 0) + check("and PikaAnimTilemap_34's GFX_e6646 pose for another part", lifted > 0) + U.log("of the first 60 frames the pose was up for", lifted, "and the base for", grounded) local leftWhenCut = ow.emote and ow.emote.frames or 0 @@ -309,7 +319,7 @@ return function(game) U.log("Hold Down: Pikachu should walk up to the ledge lip and WAIT there,") U.log("then clear both cells in one motion on your next step, at walking") U.log("speed. Let go and count the first glance: about a second, not half.") - U.log("Face it, press A: the framed pic hops inside the box for the whole") + U.log("Face it, press A: the framed pic swaps to the hearts pose and back for the whole") U.log("beat, and A or B cuts the beat off early.") idleForever() diff --git a/tests/drivers/pikachu_thunder_flash_2347.lua b/tests/drivers/pikachu_thunder_flash_2347.lua index 8196e585..4bb7ddfb 100644 --- a/tests/drivers/pikachu_thunder_flash_2347.lua +++ b/tests/drivers/pikachu_thunder_flash_2347.lua @@ -163,15 +163,36 @@ return function(game) check("2347_talk1_pikapic_25", pic:find("pikapic_25", 1, true) ~= nil) local emote = ow.emote check("2347_talk1_bolt_spec", emote and emote.boltAt == 45) - local bgpSeq, shadeSeq, frames = {}, {}, 0 + local bgpSeq, poseSeq, doneSeq, frames = {}, {}, {}, 0 local prebolt = 0 - while ow.emote == emote and frames < 900 do + local function poseName(e) + local path, lift = PikachuFollower.picFrame(e) + if (lift or 0) ~= 0 then return "lifted" end + return path and path:match("([^/]+)%.png$") or false + end + local PROBE = (os.getenv("TMPDIR") or "/tmp/") .. "2347_probe.png" + local function drawnShade() + U.still(game, PROBE) + os.remove(PROBE) + return PaletteFX.shadeMap() + end + local darkDuringPre, whiteDrawn, litTail + while ow.emote == emote and frames < 1500 do U.wait(1) frames = frames + 1 if ow.emote ~= emote then break end bgpSeq[#bgpSeq + 1] = emote.bgp or false - shadeSeq[#bgpSeq] = PaletteFX.shadeMap() or false + poseSeq[#bgpSeq] = poseName(emote) + doneSeq[#bgpSeq] = emote.boltDone and true or false if not emote.bgp then prebolt = prebolt + 1 end + local k = (emote.boltT or 0) - emote.boltAt - 2 + if darkDuringPre == nil and not emote.bgp and frames > 10 then + darkDuringPre = isDarkMap(drawnShade()) + elseif whiteDrawn == nil and emote.bgp == 0xC0 then + whiteDrawn = isBoltMap(drawnShade()) + elseif litTail == nil and k >= 81 and not emote.boltDone then + litTail = drawnShade() == nil + end end local strobeOk, seen = true, 0 local first @@ -190,28 +211,35 @@ return function(game) end U.log("prebolt frames", prebolt, "strobe start", tostring(first), "total", frames) check("2347_talk1_strobe_alternates_4f", first ~= nil and strobeOk and seen == 80) - local whiteDrawn, darkDuringPre = false, false - for i = 1, #bgpSeq do - if isBoltMap(shadeSeq[i]) then whiteDrawn = true end - if first and i < first and isDarkMap(shadeSeq[i]) then darkDuringPre = true end - end - check("2347_talk1_prebolt_dark", darkDuringPre) - check("2347_talk1_strobe_white_drawn", whiteDrawn) - local litTail = first and #bgpSeq > first + 82 - if litTail then - for i = first + 82, #bgpSeq do - if shadeSeq[i] then litTail = false end + check("2347_talk1_prebolt_dark", darkDuringPre == true) + check("2347_talk1_strobe_white_drawn", whiteDrawn == true) + check("2347_talk1_lit_tail_while_box_up", litTail == true) + local boltPose, sawE7863, blank = first ~= nil, false, 0 + for i = 1, #poseSeq do + if poseSeq[i] == "gfx_e7863" then sawE7863 = true end + if first and i >= first then + if poseSeq[i] == false then blank = blank + 1 + elseif blank > 0 or poseSeq[i] ~= "gfx_e79f3" then boltPose = false end end end - check("2347_talk1_lit_tail_while_box_up", litTail and true or false) + U.log("pose at strobe start", tostring(first and poseSeq[first]), "blank close frames", blank) + check("2347_talk1_e7863_before_bolt", sawE7863) + check("2347_talk1_bolt_pose", boltPose) + local closeSeq = {} + for i = 1, #poseSeq do + if doneSeq[i] then closeSeq[#closeSeq + 1] = tostring(poseSeq[i]) end + end + U.log("close frames", table.concat(closeSeq, ",")) + check("2347_talk1_empty_box_at_close", + table.concat(closeSeq, ",") == "gfx_e79f3,gfx_e79f3,gfx_e79f3,false,false,false") check("2347_talk1_thunderbolt_sound", moveSounds[1] == "Battle_2F") check("2347_talk1_music_muted", ducks == 1) U.wait(6) - check("2347_talk1_dark_after_close", isDarkMap(PaletteFX.shadeMap())) + check("2347_talk1_dark_after_close", ow.emote == nil and isDarkMap(drawnShade())) check("2347_modifier_survives_talk", game.save.pikachuEmotionModifier == 5) if not check("2347_talk2_emote", startTalk("2347_talk2")) then quit() end - U.shot(game, SHOT_DIR .. "/2347_02_bolt_bubble.png") + U.still(game, SHOT_DIR .. "/2347_02_bolt_bubble.png") for _ = 1, 200 do if ow.emote and ow.emote.pikaPic then break end U.wait(1) @@ -219,28 +247,36 @@ return function(game) emote = ow.emote check("2347_talk2_replays_bolt", emote and emote.boltAt ~= nil) U.wait(20) - U.shot(game, SHOT_DIR .. "/2347_03_pikapic_prebolt.png") + U.still(game, SHOT_DIR .. "/2347_03_pikapic_prebolt.png") for _ = 1, 200 do if emote.bgp == 0xC0 then break end U.wait(1) end - U.shot(game, SHOT_DIR .. "/2347_04_strobe_white.png") + local function drawn() + return tostring(ow.pikaPicDrawn):match("([^/]+)%.png$") + end + U.still(game, SHOT_DIR .. "/2347_04_strobe_white.png") + check("2347_talk2_c0_draws_e79f3", emote.bgp == 0xC0 and drawn() == "gfx_e79f3") for _ = 1, 200 do if emote.bgp == 0xE4 then break end U.wait(1) end - U.shot(game, SHOT_DIR .. "/2347_05_strobe_lit.png") + U.still(game, SHOT_DIR .. "/2347_05_strobe_lit.png") + check("2347_talk2_e4_draws_e79f3", emote.bgp == 0xE4 and drawn() == "gfx_e79f3") for _ = 1, 400 do - if emote.boltDone or ow.emote ~= emote then break end + if (emote.boltT or 0) - emote.boltAt > 2 + 80 or ow.emote ~= emote then break end U.wait(1) end - if ow.emote == emote then U.shot(game, SHOT_DIR .. "/2347_06_lit_tail.png") end - for _ = 1, 200 do + if ow.emote == emote and not emote.boltDone then + U.still(game, SHOT_DIR .. "/2347_06_lit_tail.png") + check("2347_talk2_tail_draws_e79f3", drawn() == "gfx_e79f3") + end + for _ = 1, 1500 do if ow.emote ~= emote then break end U.wait(1) end U.wait(10) - U.shot(game, SHOT_DIR .. "/2347_07_after_close_dark.png") + U.still(game, SHOT_DIR .. "/2347_07_after_close_dark.png") for _ = 1, 3 do stepAndBack() @@ -256,7 +292,7 @@ return function(game) U.wait(1) end U.wait(20) - U.shot(game, SHOT_DIR .. "/2347_08_after_steps_mood_talk.png") + U.still(game, SHOT_DIR .. "/2347_08_after_steps_mood_talk.png") check("2347_talk3_no_bolt", ow.emote and ow.emote.pikaPic and not ow.emote.boltAt and true or false) for _ = 1, 600 do @@ -278,22 +314,126 @@ return function(game) U.wait(1) end emote = ow.emote - local veiled = false - for _ = 1, 400 do + local tiles = ow.map.renderer + local darkAtlas = tiles.image + local function atlasFor(byte) + local imgs = tiles.bgpImages or {} + return imgs[byte] and tiles.image == imgs[byte] and tiles.curBgp == byte + and tiles.baseImage == darkAtlas + end + local shotC0, shotE4 = false, false + local litOnE4, c0Atlas, veilOnC0 = true, true, false + for _ = 1, 1500 do if ow.emote ~= emote then break end U.wait(1) - local v = game.renderer and game.renderer.screenVeil - if emote.bgp == 0xC0 and v and v[1] == 1 then - if not veiled then U.shot(game, SHOT_DIR .. "/2347_09_baked_strobe_white.png") end - veiled = true + if ow.emote ~= emote then break end + if emote.bgp == 0xC0 and not shotC0 then + shotC0 = true + U.still(game, SHOT_DIR .. "/2347_09_baked_strobe_white.png") + local v = game.renderer and game.renderer.screenVeil + if v then veilOnC0 = true end + if not atlasFor(0xC0) then c0Atlas = false end + check("2347_baked_c0_draws_e79f3", drawn() == "gfx_e79f3") + elseif emote.bgp == 0xE4 and shotC0 and not shotE4 then + shotE4 = true + U.still(game, SHOT_DIR .. "/2347_10_baked_strobe_lit.png") + if not atlasFor(0xE4) then litOnE4 = false end + check("2347_baked_e4_draws_e79f3", drawn() == "gfx_e79f3") end end - check("2347_baked_white_veil", veiled) + check("2347_baked_strobe_seen", shotC0 and shotE4) + check("2347_baked_lit_atlas", shotE4 and litOnE4) + check("2347_baked_c0_atlas", shotC0 and c0Atlas) + check("2347_baked_no_white_veil", shotC0 and not veilOnC0) + U.wait(10) + U.still(game, SHOT_DIR .. "/2347_11_baked_after_close_dark.png") + check("2347_baked_dark_after_close", ow.emote == nil and tiles.image == darkAtlas + and tiles.curBgp == nil and tiles.baseImage == nil and ow.dark == true) end else U.log("SKIP 2347_baked (no gbc atlas in this cache)") end + if PaletteFX.mode == "redpp" then + U.teleport(game, "PALLET_TOWN", 11, 11, "down") + U.wait(20) + ow = game.overworld + npc = follower() + local tiles = ow.map.renderer + local renderers = { tiles } + for _, nb in ipairs(ow.neighbors or {}) do + if nb.map.renderer and nb.map.renderer.gbcAtlas then + renderers[#renderers + 1] = nb.map.renderer + end + end + check("2347_outdoor_lit", ow.dark ~= true and ow:bakedWorldColors()) + check("2347_outdoor_neighbors_baked", #renderers >= 2) + local animated = 0 + for _, a in ipairs(tiles.anims or {}) do + if a.spec then animated = animated + 1 end + end + check("2347_outdoor_water_flower_anims", animated >= 2) + local function allOn(byte) + for _, r in ipairs(renderers) do + local img = r.bgpImages and r.bgpImages[byte] + if not (img and r.image == img and r.curBgp == byte) then return false end + for _, a in ipairs(r.anims or {}) do + if a.spec and not (a.bgpTextures and a.textures == a.bgpTextures[byte]) then + return false + end + end + end + return true + end + local function allBase() + for _, r in ipairs(renderers) do + if r.curBgp ~= nil or r.baseImage ~= nil then return false end + for _, a in ipairs(r.anims or {}) do + if a.baseTextures then return false end + for _, t in pairs(a.bgpTextures or {}) do + if a.textures == t then return false end + end + end + end + return true + end + PikachuFollower.onMoveLearned(game.save, pika, "THUNDERBOLT") + if npc then PikachuFollower.talk(game, ow, npc, function() end) end + for _ = 1, 200 do + if ow.emote and ow.emote.pikaPic then break end + U.wait(1) + end + emote = ow.emote + if check("2347_outdoor_emote", emote ~= nil) then + local onC0, onE4, sawC0, sawE4 = nil, nil, 0, 0 + local last + for _ = 1, 2000 do + if ow.emote ~= emote then break end + U.wait(1) + if ow.emote ~= emote then break end + local bgp = emote.bgp + if bgp ~= last and (bgp == 0xC0 and sawC0 < 3 or bgp == 0xE4 and sawE4 < 3) then + if bgp == 0xC0 then + sawC0 = sawC0 + 1 + U.still(game, SHOT_DIR .. "/2347_12_outdoor_strobe_white_" .. sawC0 .. ".png") + onC0 = (onC0 ~= false) and allOn(0xC0) + else + sawE4 = sawE4 + 1 + U.still(game, SHOT_DIR .. "/2347_13_outdoor_strobe_lit_" .. sawE4 .. ".png") + onE4 = (onE4 ~= false) and allBase() + end + end + last = bgp + end + check("2347_outdoor_strobe_seen", sawC0 == 3 and sawE4 == 3) + check("2347_outdoor_c0_every_renderer_and_anim", onC0 == true) + check("2347_outdoor_e4_lit_base", onE4 == true) + U.wait(6) + U.still(game, SHOT_DIR .. "/2347_14_outdoor_after_close.png") + check("2347_outdoor_base_after_close", ow.emote == nil and allBase()) + end + end + Sound.playMove, Music.duckForFanfare = realPlayMove, realDuck quit() end diff --git a/tests/drivers/route.lua b/tests/drivers/route.lua index 08dd35a1..3668acd3 100644 --- a/tests/drivers/route.lua +++ b/tests/drivers/route.lua @@ -2403,13 +2403,14 @@ local function sellItem(id) press("a") U.wait(10) end - pressUntil(isList, "a", 20) - sold = ((G.save.inventory or {})[id] or 0) == 0 + pressUntil(function() return isList() or isMenu() end, "a", 20) + sold =((G.save.inventory or {})[id] or 0) == 0 end -- back out of the sell list to the BUY/SELL menu - for _ = 1, 10 do + for _ = 1, 60 do if isMenu() then break end - press("b") + local t = top() + if not (t and t.stay) then press("b") end U.wait(6) end return sold @@ -2526,10 +2527,16 @@ end -- shopping spree that empties the wallet and then sits on the "not enough -- money" footer forever. B is the only safe key once a shop screen is up. local function closeShop() - for _ = 1, 40 do - if not (isList() or isQty() or isChoice() or isMenu()) then return true end - press("b") - U.wait(6) + for _ = 1, 80 do + local t = top() + if t and t.stay then + U.wait(6) + elseif not (isList() or isQty() or isChoice() or isMenu()) then + return true + else + press("b") + U.wait(6) + end end return false end diff --git a/tests/drivers/route_shop_buy_sell_bug2291.lua b/tests/drivers/route_shop_buy_sell_bug2291.lua index cfaab989..744bd9b9 100644 --- a/tests/drivers/route_shop_buy_sell_bug2291.lua +++ b/tests/drivers/route_shop_buy_sell_bug2291.lua @@ -78,9 +78,9 @@ return function(game) check("route buyItem paid 600", game.save.money == money0 - 600) check("route buyItem leaves the buy list on top", R.isList()) - for _ = 1, 10 do + for _ = 1, 60 do if R.isMenu() then break end - U.tap(game, "b") + if R.isList() then U.tap(game, "b") end U.wait(6) end if not check("back on the BUY/SELL menu", R.isMenu()) then return end diff --git a/tests/drivers/shop_test.lua b/tests/drivers/shop_test.lua index a5853b46..a9fd87f1 100644 --- a/tests/drivers/shop_test.lua +++ b/tests/drivers/shop_test.lua @@ -39,7 +39,11 @@ return function(game) U.wait(20) check(tag .. " menu", mash("a", function() return topIs(Menu) end)) U.tap(game, "a") -- BUY - U.wait(8) + for _ = 1, 300 do + if topIs(ListMenu) then break end + U.wait(1) + end + U.wait(4) check(tag .. " list", topIs(ListMenu)) U.shot(game, ("%s/%s_0_list.png"):format(DIR, tag)) U.tap(game, "a") -- first item diff --git a/tests/engine/crystal_map_name_sign_speed_bug1994.lua b/tests/engine/crystal_map_name_sign_speed_bug1994.lua index b601d6ad..7e34fbe2 100644 --- a/tests/engine/crystal_map_name_sign_speed_bug1994.lua +++ b/tests/engine/crystal_map_name_sign_speed_bug1994.lua @@ -85,24 +85,16 @@ if check(one.mapSign ~= nil, "the sign comes up at 1X") then end -- ../pokecrystal/engine/overworld/events.asm:177-191 +FixedStep.clock = function() return 0 end for _, speed in ipairs({ 1, 4, 10, 20, 200 }) do local w = raise(gameAt(speed)) local frame, steps, maxPerFrame = renderedFramesToClear(w, speed, 2000) eq(frame, 122, ("%dX: the sign clears on rendered frame 122"):format(speed)) - if speed <= 10 then - eq(steps, 122 * speed, - ("%dX: under the catch-up cap the logic ran %d steps"):format(speed, speed * 122)) - else - check(maxPerFrame <= 15 and steps < 122 * speed, - ("%dX: FixedStep pinned at %d steps a frame, %d in all (nominal would be %d)") - :format(speed, maxPerFrame, steps, 122 * speed)) - end + eq(steps, 122 * speed, + ("%dX: the logic ran %d steps"):format(speed, speed * 122)) + eq(maxPerFrame, speed, ("%dX: %d steps a rendered frame"):format(speed, speed)) end - -local capped = raise(gameAt(200)) -local _, _, perFrame = renderedFramesToClear(capped, 200, 2000) -check(perFrame >= 14 and perFrame <= 15, - ("200X: the capped regime really ran ~15 steps a frame (%d)"):format(perFrame)) +FixedStep.clock = nil local hidden = raise(gameAt(1)) for _ = 1, 3 do Sign.frame(hidden) end diff --git a/tests/engine/fast_forward_rate_bug2471.lua b/tests/engine/fast_forward_rate_bug2471.lua new file mode 100644 index 00000000..5a8f3255 --- /dev/null +++ b/tests/engine/fast_forward_rate_bug2471.lua @@ -0,0 +1,91 @@ +package.path = "./?.lua;./?/init.lua;" .. package.path + +local T = require("tests.harness") +local check, eq = T.check, T.eq +love = love or require("tests.love_stub") + +local FixedStep = require("src.core.FixedStep") +local GameSpeed = require("src.core.GameSpeed") +local STEP = FixedStep.STEP + +local function run(speed, fps, frames, clock, period) + local now = 0 + local steps, maxPerFrame, maxAccum = 0, 0, 0 + FixedStep.refreshPeriod = period + FixedStep:init(function() + steps = steps + 1 + if clock == "ms" then now = now + 0.001 end + end) + FixedStep.clock = function() return now end + local dt = 1 / fps + for _ = 1, frames do + local before = steps + FixedStep.maxAccum = FixedStep.catchupLimit(speed, dt) + FixedStep:update(dt, speed) + if clock == "ms" then now = now + 0.004 end + if steps - before > maxPerFrame then maxPerFrame = steps - before end + if FixedStep.accum > maxAccum then maxAccum = FixedStep.accum end + end + FixedStep.clock = nil + FixedStep.refreshPeriod = nil + return steps, maxPerFrame, maxAccum +end + +for _, speed in ipairs(GameSpeed.LEVELS) do + local steps = run(speed, 60, 60, "frozen") + check(math.abs(steps - 60 * speed) <= 1, + ("%dX at 60fps: %d logic steps a second (want %d)"):format(speed, steps, 60 * speed)) + local slow = run(speed, 30, 30, "frozen") + check(math.abs(slow - 60 * speed) <= 1, + ("%dX at 30fps: %d logic steps a second (want %d)"):format(speed, slow, 60 * speed)) + local mid = run(speed, 45, 45, "frozen") + check(math.abs(mid - 60 * speed) <= 1, + ("%dX at 45fps: %d logic steps a second (want %d)"):format(speed, mid, 60 * speed)) +end + +local fast = run(200, 60, 60, "frozen") +local ten = run(10, 60, 60, "frozen") +check(fast >= ten * 15, + ("200X runs far more logic than 10X on a fast frame (%d vs %d)"):format(fast, ten)) + +local steps, perFrame, carried = run(200, 60, 60, "ms", 1 / 60) +check(perFrame >= 11 and perFrame <= 14, + ("200X on a slow device stops at the frame budget (%d steps a frame)"):format(perFrame)) +check(carried < STEP, + ("the unpaid debt is dropped, not carried (max accum %.4f)"):format(carried)) +check(steps >= 60 * 11, + ("and still runs as fast as the device allows (%d steps)"):format(steps)) + +local oneX = run(1, 60, 60, "ms", 1 / 60) +eq(oneX, 60, "1X ignores the work budget") + +local function hitchBurst(speed, hitch) + local n = 0 + FixedStep.refreshPeriod = nil + FixedStep.clock = function() return 0 end + FixedStep:init(function() n = n + 1 end) + for _ = 1, 30 do + FixedStep.maxAccum = FixedStep.catchupLimit(speed, 1 / 60) + FixedStep:update(1 / 60, speed) + end + n = 0 + FixedStep.maxAccum = FixedStep.catchupLimit(speed, hitch) + FixedStep:update(hitch, speed) + FixedStep.clock = nil + return n +end + +for _, speed in ipairs({ 1, 2, 4, 10 }) do + local cap = math.max(2, math.floor(speed * 1.5 + 1e-9)) + for _, hitch in ipairs({ 0.05, 0.1, 0.25, 1.0 }) do + local n = hitchBurst(speed, hitch) + check(n <= cap, + ("%dX: a %.0fms hitch is not repaid as a burst (%d steps, max %d)"):format(speed, hitch * 1000, n, cap)) + end +end +eq(hitchBurst(1, 0.25), 2, "1X after a 250ms hitch runs 2 steps, like before the budget") + +FixedStep:init(function() end) +FixedStep.maxAccum = FixedStep.MAX_ACCUM + +T.finish("fast forward rate bug 2471") diff --git a/tests/engine/game3_trainer_sight_test.lua b/tests/engine/game3_trainer_sight_test.lua index 48caefec..97112b2a 100644 --- a/tests/engine/game3_trainer_sight_test.lua +++ b/tests/engine/game3_trainer_sight_test.lua @@ -454,6 +454,80 @@ check(pacer.moving == false and pacer.cellX == 40 and pacer.cellY == 13, "Traine resetField() +print("[test] 11. Neighbor-map pool trainers never engage (Route 11 Dave seen from Vermilion)") +Objects.clear() +local engagedBy = {} +local realEngage = TrainerSight.engage +TrainerSight.engage = function(_, e, dist) engagedBy[#engagedBy + 1] = { eo = e, dist = dist } end +local ghostPool = Objects.spawnFromDefs({ + { localId = 4, x = 29, y = 11, movementType = 0x08, trainerType = 1, sight = 1, + scriptKey = "trainer_battle_01", elevation = 3 }, +}, { midLayout = { width = 36, height = 10 } }, "FR_ROUTE_11") +local dave = ghostPool.byId[4] +check(dave ~= nil and dave.sight == 1 and TrainerSight.isTrainerType(dave), "ghost Dave spawned as a sight-1 trainer") +Player.reset(29, 13, "up") +Player.elevation = 3 +dave.moving, dave.progress, dave.targetX, dave.targetY, dave.facing = true, 0, 29, 12, "down" +local ghostCtx = { + ox = 48, oy = 10, + canEnter = function() return false end, + blocks = function() return true end, +} +for _ = 1, 20 do Objects.tickPool(ghostPool, dummyGame, ghostCtx) end +check(dave.cellX == 29 and dave.cellY == 12 and not dave.moving, "ghost Dave finished his step onto local (29,12)") +check(TrainerSight.checkLineOfSight(dave, Player, dummyGame) == true, + "ghost-local cone lines up with the current-map player cell") +check(#engagedBy == 0 and not Field.locked, "ghost step completion never engages") +check(TrainerSight.check(dummyGame, dave) == false and #engagedBy == 0, + "TrainerSight.check refuses an object outside the current map") + +resetField() +dave.cellY, dave.py, dave.homeY = 11, 11 * 16, 11 +dave.moving, dave.progress, dave.targetX, dave.targetY, dave.facing = true, 0, 29, 12, "down" +Objects._byId[4] = dave +Objects._order = { 4 } +Player.reset(29, 13, "up") +Player.elevation = 3 +for _ = 1, 20 do + Objects.update(dummyGame) + if #engagedBy > 0 then break end +end +check(#engagedBy == 1 and engagedBy[1].eo == dave and engagedBy[1].dist == 1, + "control: the same trainer on the current map engages at dist 1 after its step") +TrainerSight.engage = realEngage +Objects.clear() +resetField() + +print("[test] 12. Pool step completion skips sight and current-map elevation even without the identity guard") +local realCheck, realElevAt = TrainerSight.check, Collision.elevationAt +local checkCalls = 0 +TrainerSight.check = function() checkCalls = checkCalls + 1 return false end +Collision.elevationAt = function() return 7 end +local pool2 = Objects.spawnFromDefs({ + { localId = 4, x = 29, y = 11, movementType = 0x08, trainerType = 1, sight = 1, + scriptKey = "trainer_battle_01", elevation = 3 }, +}, { midLayout = { width = 36, height = 10 } }, "FR_ROUTE_11") +local ghost = pool2.byId[4] +Player.reset(29, 13, "up") +Player.elevation = 3 +for _, ctxArg in ipairs({ ghostCtx, false }) do + ghost.cellX, ghost.cellY, ghost.px, ghost.py, ghost.homeY = 29, 11, 29 * 16, 11 * 16, 11 + ghost.elevation = 3 + ghost.moving, ghost.progress, ghost.targetX, ghost.targetY, ghost.facing = true, 0, 29, 12, "down" + local stepped = false + for _ = 1, 20 do + Objects.tickPool(pool2, dummyGame, ctxArg or nil) + if not ghost.moving then stepped = true break end + end + local label = ctxArg and "ctx" or "nil ctx" + check(stepped and ghost.cellY == 12, label .. ": ghost finished its step") + check(ghost.elevation == 3, label .. ": ghost elevation not read from the current map, got " .. tostring(ghost.elevation)) +end +check(checkCalls == 0, "pool step never calls TrainerSight.check, got " .. checkCalls) +TrainerSight.check, Collision.elevationAt = realCheck, realElevAt +Objects.clear() +resetField() + if failed > 0 then print(string.format("\n%d FAILURE(S)", failed)) os.exit(1) diff --git a/tests/engine/gen3_dex_summary_2461.lua b/tests/engine/gen3_dex_summary_2461.lua new file mode 100644 index 00000000..36d3d1e4 --- /dev/null +++ b/tests/engine/gen3_dex_summary_2461.lua @@ -0,0 +1,75 @@ +package.path = "./?.lua;./?/init.lua;" .. package.path + +local T = require("tests.harness") +local eq = T.eq +love = love or require("tests.love_stub") + +local SaveConvert = require("src.save_convert.SaveConvert") +local SaveData = require("src.core.SaveData") +local Boot = require("src.ui.game3.boot") +local Dex = require("src.core.game3.dex") +local F = require("tests.fixture_data.gen3_saves") + +local function unrle(s) + local out = {} + for tok in s:gmatch("%S+") do + local k, n = tok:match("^([ZF])(%x+)$") + if k then + out[#out + 1] = string.rep(k == "Z" and "\0" or "\255", tonumber(n, 16)) + else + out[#out + 1] = (tok:gsub("%x%x", function(h) return string.char(tonumber(h, 16)) end)) + end + end + return table.concat(out) +end + +local function launcherCount(save) + local _, meta = SaveData.slotSummary(save) + return meta and meta.dexCount +end + +for _, name in ipairs({ "fr_rich_game", "lg_rich_game" }) do + local ver = name:sub(1, 2) == "fr" and "firered" or "leafgreen" + local save = assert(SaveConvert.importSav(unrle(F.images[name]), ver, ver)) + eq(#save.modData.cartImport.dexOwned, 8, name .. " cart owns 8 species") + eq(Dex.nationalEnabled(save), false, name .. " national dex off") + eq(launcherCount(save), 5, name .. " launcher counts the imported Kanto dex") + eq(Boot.continueInfoFromSave(save).dexCount, 5, name .. " CONTINUE counts the imported Kanto dex") + save.dex.national = true + eq(launcherCount(save), 8, name .. " launcher counts the imported national dex") + eq(Boot.continueInfoFromSave(save).dexCount, 8, name .. " CONTINUE counts the imported national dex") +end + +do + local save = { + engine = "game3", version = "firered", name = "RED", + dex = { seen = {}, owned = { [1] = true, [4] = true, [277] = true }, caught = { [1] = true, [4] = true, [277] = true }, national = false }, + flags = {}, vars = {}, + } + eq(launcherCount(save), 2, "native save before national dex counts Kanto only") + eq(Boot.continueInfoFromSave(save).dexCount, 2, "CONTINUE native save counts Kanto only") + save.flags[0x840] = true + save.vars[0x404E] = 0x6258 + eq(launcherCount(save), 3, "native save with FLAG_SYS_NATIONAL_DEX counts national") + eq(Boot.continueInfoFromSave(save).dexCount, 3, "CONTINUE native save with national flag counts national") + save.flags, save.vars = {}, {} + save.dex.nationalUnlocked = true + eq(launcherCount(save), 3, "dex.nationalUnlocked counts national") + save.dex.nationalUnlocked = nil + save.flags = { ["2112"] = true } + eq(Dex.nationalEnabled(save), true, "string-keyed national flag") + save.flags = {} + save.dex.owned, save.dex.caught = { ["1"] = true, ["150"] = true }, {} + eq(launcherCount(save), 2, "string-keyed dex entries count") +end + +do + local save = { + engine = "game3", version = "firered", + dex = { seen = {}, owned = { [25] = true }, caught = { [25] = true } }, + modData = { cartImport = { dexOwned = { 25, 26 } } }, + } + eq(Dex.summaryCount(save), 2, "cart list and merged dex do not double count") +end + +T.finish("gen3_dex_summary_2461") diff --git a/tests/engine/gen3_dex_summary_keys_2461.lua b/tests/engine/gen3_dex_summary_keys_2461.lua new file mode 100644 index 00000000..fdd146e4 --- /dev/null +++ b/tests/engine/gen3_dex_summary_keys_2461.lua @@ -0,0 +1,23 @@ +package.path = "./?.lua;./?/init.lua;" .. package.path + +local T = require("tests.harness") +local eq = T.eq +love = love or require("tests.love_stub") + +local Dex = require("src.core.game3.dex") + +do + local save = { dex = { caught = { [1] = true, [4] = true, NOT_A_SPECIES_2461 = true, [200] = true } } } + eq(Dex.nationalEnabled(save), false, "national dex off") + eq(Dex.summaryCount(save), 2, "unresolvable string key is not counted on the Kanto gate") + save.dex.national = true + eq(Dex.summaryCount(save), 3, "unresolvable string key is not counted on the national gate") +end + +do + local save = { dex = { owned = { ["7"] = true, ["152"] = true } } } + eq(Dex.summaryCount(save), 1, "numeric string keys still honour the Kanto gate") +end + +T.finish("gen3_dex_summary_keys_2461") +if T.failures > 0 then os.exit(1) end diff --git a/tests/engine/mart_bag_full_bug2162.lua b/tests/engine/mart_bag_full_bug2162.lua index 92c900f3..1abd9e93 100644 --- a/tests/engine/mart_bag_full_bug2162.lua +++ b/tests/engine/mart_bag_full_bug2162.lua @@ -73,6 +73,10 @@ local function newGame(money, ballCount) constants = {}, }, save = { money = money, inventory = {}, bagOrder = {} }, + input = { + wasPressed = function() return false end, + isDown = function() return false end, + }, } if ballCount then game.save.inventory.POKE_BALL = ballCount @@ -93,9 +97,18 @@ local function newGame(money, ballCount) return game, events, stack end +local function drain(game) + for _ = 1, 600 do + local top = game.stack:top() + if not (top and top.stay and not top.stayShown) then return end + top:update(1 / 60) + end +end + local function buyOne(game, stack) local menu = ShopMenu.new(game, { "POKE_BALL" }, function() end) menu.items[1].onSelect() + drain(game) local list = stack[#stack] list.onChoose({ value = "POKE_BALL" }) local qty = stack[#stack] @@ -137,6 +150,7 @@ for _, case in ipairs({ game.stack:pop() box.onDone() + drain(game) eq(stack[#stack], nil, case.name .. ": A closes the list") eq(menu.footer, ANYTHING, case.name .. ": the mart menu asks again") eq(game.save.money, case.money, case.name .. ": money is still untouched") @@ -151,6 +165,7 @@ do game.save.bagOrder = { "BICYCLE" } local menu = ShopMenu.new(game, { "POKE_BALL" }, function() end) menu.items[2].onSelect() + drain(game) local list = stack[#stack] list.onChoose({ value = "BICYCLE" }) local box = stack[#stack] @@ -158,6 +173,7 @@ do eq(stack[#stack - 1], list, "unsellable: the sell list is still under it") game.stack:pop() box.onDone() + drain(game) eq(stack[#stack], nil, "unsellable: A closes the sell list") eq(menu.footer, ANYTHING, "unsellable: the mart menu asks again") end @@ -172,6 +188,7 @@ do check(getmetatable(box) == TextBox, "empty bag: only a text box is pushed") game.stack:pop() box.onDone() + drain(game) eq(menu.footer, ANYTHING, "empty bag: the mart menu asks again") end diff --git a/tests/engine/mart_clerk_typing_bug2384.lua b/tests/engine/mart_clerk_typing_bug2384.lua new file mode 100644 index 00000000..370f4141 --- /dev/null +++ b/tests/engine/mart_clerk_typing_bug2384.lua @@ -0,0 +1,252 @@ +-- home/text_script.asm:141-150 +-- engine/events/pokemart.asm:7-19 +-- engine/events/pokemart.asm:131-133 +-- engine/events/pokemart.asm:199-206 +-- engine/events/pokemart.asm:220-222 +-- engine/menus/text_box.asm:168-176 + +package.path = "./?.lua;./?/init.lua;" .. package.path + +local T = require("tests.harness") +local check, eq = T.check, T.eq +love = love or require("tests.love_stub") + +local function chars(text) + local out = {} + for s in tostring(text):gmatch("[%z\1-\127\194-\244][\128-\191]*") do + out[#out + 1] = s + end + return out +end + +local drawn = {} +local realFont = package.loaded["src.render.Font"] +package.loaded["src.render.Font"] = { + BORDER = { tl = 1, tr = 2, bl = 3, br = 4, h = 5, v = 6 }, + draw = function(text) drawn[#drawn + 1] = { "draw", tostring(text) } end, + drawCode = function(code) drawn[#drawn + 1] = { "code", code } end, + drawBox = function(tx, ty, tw, th) drawn[#drawn + 1] = { "box", tx, ty, tw, th } end, + width = function(text) return #chars(text) * 8 end, + split = chars, + spansFitting = function(spans, pixels) + return math.min(#spans, math.floor(pixels / 8)) + end, + encode = chars, + advanceOf = function() return 8 end, +} + +local RELOAD = { + "src.ui.QuantityBox", "src.ui.ShopMenu", "src.ui.ListMenu", + "src.ui.ChoiceBox", "src.ui.Menu", "src.ui.Theme", "src.render.TextBox", +} +for _, m in ipairs(RELOAD) do package.loaded[m] = nil end + +local ShopMenu = require("src.ui.ShopMenu") +local TextBox = require("src.render.TextBox") +local ListMenu = require("src.ui.ListMenu") +local Theme = require("src.ui.Theme") + +local HI = "Hi there!\nMay I help you?" +local TAKE = "Take your time." +local SELL = "What would you\nlike to sell?" +local ELSE = "Is there anything\nelse I can do?" +local THANKS = "Thank you!" + +local function newGame() + local states, pressed = {}, {} + local game = { + data = { + items = { POKE_BALL = { name = "POKe BALL", price = 200 } }, + text = { + _PokemartGreetingText = HI, + _PokemartBuyingGreetingText = TAKE, + _PokemonSellingGreetingText = SELL, + _PokemartAnythingElseText = ELSE, + _PokemartThankYouText = THANKS, + }, + constants = {}, + }, + save = { money = 3000, inventory = { POKE_BALL = 3 }, bagOrder = { "POKE_BALL" }, + options = { textSpeed = 3 } }, + input = { + wasPressed = function(_, b) return pressed[b] == true end, + isDown = function() return false end, + }, + } + game.stack = { + states = states, + push = function(_, s) + states[#states + 1] = s + if type(s.enter) == "function" then s:enter() end + end, + pop = function() return table.remove(states) end, + top = function() return states[#states] end, + } + local function frame(btn) + for k in pairs(pressed) do pressed[k] = nil end + if btn then pressed[btn] = true end + local top = states[#states] + if top then top:update(1 / 60) end + for k in pairs(pressed) do pressed[k] = nil end + end + return game, states, frame +end + +local function until_(frame, pred) + for _ = 1, 600 do + if pred() then return true end + frame() + end + return pred() +end + +local function drewText(fn, text) + drawn = {} + fn() + for _, c in ipairs(drawn) do + if c[1] == "draw" and c[2] == text then return true end + end + return false +end + +local function drewBox(fn, tx, ty, tw, th) + drawn = {} + fn() + for _, c in ipairs(drawn) do + if c[1] == "box" and c[2] == tx and c[3] == ty and c[4] == tw and c[5] == th then + return true + end + end + return false +end + +local function cursorGlyph(menu) + drawn = {} + menu:draw() + local last + for _, c in ipairs(drawn) do + if c[1] == "code" then last = c[2] end + end + return last +end + +local function isSay(s, text) + return getmetatable(s) == TextBox and s.stay ~= nil + and table.concat(chars(s.pages and s.pages[1] and s.pages[1][1] or "")) + == (tostring(text):match("^[^\n]*")) +end + +do + local game, states, frame = newGame() + local menu = ShopMenu.new(game, { "POKE_BALL" }, function() end) + game.stack:push(menu) + local greet = states[#states] + check(isSay(greet, HI), "greeting: a typing text box goes up first") + eq(greet.done, false, "greeting: it is not instant") + eq(menu.hidden, true, "greeting: BUY/SELL/QUIT is not up yet") + check(not drewText(function() menu:draw() end, "BUY"), "greeting: no BUY row drawn") + check(not drewBox(function() menu:draw() end, 11, 0, 9, 3), "greeting: no MONEY box drawn") + for _ = 1, 6 do frame() end + local typed = greet.shown[1] and #greet.shown[1] or 0 + check(typed > 0 and typed < #chars("Hi there!"), "greeting: typing mid-line") + check(until_(frame, function() return states[#states] == menu end), + "greeting: the menu takes over once the text is done") + eq(menu.hidden, false, "greeting: BUY/SELL/QUIT is up") + eq(menu.footer, HI, "greeting: the line stays in the box under the menu") + check(drewText(function() menu:draw() end, "BUY"), "greeting: BUY drawn") + eq(cursorGlyph(menu), Theme.cursor, "greeting: filled cursor on BUY") +end + +do + local game, states, frame = newGame() + local menu = ShopMenu.new(game, { "POKE_BALL" }, function() end) + game.stack:push(menu) + until_(frame, function() return states[#states] == menu end) + frame("a") + eq(menu.hollowIndex, 1, "BUY: the chosen row goes hollow") + eq(cursorGlyph(menu), Theme.cursorHollow, "BUY: hollow glyph drawn") + local say = states[#states] + check(isSay(say, TAKE), "BUY: Take your time. types before the list") + eq(say.done, false, "BUY: the lead-in is typing") + eq(states[#states - 1], menu, "BUY: BUY/SELL/QUIT stays under the lead-in") + check(until_(frame, function() return getmetatable(states[#states]) == ListMenu end), + "BUY: the list opens after the lead-in") + local list = states[#states] + eq(list.footer, TAKE, "BUY: the list keeps the lead-in in its box") + eq(menu.hollowIndex, 1, "BUY: BUY stays hollow under the list") + + frame("b") + local back = states[#states] + check(isSay(back, ELSE), "B on the list: anything-else types") + eq(back.done, false, "B on the list: it is typing") + eq(menu.hollowIndex, 1, "B on the list: still hollow while it types") + check(until_(frame, function() return states[#states] == menu end), + "B on the list: back to BUY/SELL/QUIT") + eq(menu.index, 1, "back: cursor on BUY") + eq(menu.hollowIndex, nil, "back: cursor filled again") + eq(menu.footer, ELSE, "back: anything-else stays in the box") +end + +do + local game, states, frame = newGame() + local menu = ShopMenu.new(game, { "POKE_BALL" }, function() end) + game.stack:push(menu) + until_(frame, function() return states[#states] == menu end) + frame("down") + frame("a") + eq(menu.hollowIndex, 2, "SELL: the chosen row goes hollow") + check(isSay(states[#states], SELL), "SELL: the sell lead-in types first") + check(until_(frame, function() return getmetatable(states[#states]) == ListMenu end), + "SELL: the list opens after the lead-in") + local list = states[#states] + list.index = #list.items + frame("a") + check(isSay(states[#states], ELSE), "CANCEL: anything-else types") + check(until_(frame, function() return states[#states] == menu end), + "CANCEL: back to BUY/SELL/QUIT") + eq(menu.index, 1, "CANCEL: the cursor resets to BUY, not SELL") + eq(menu.hollowIndex, nil, "CANCEL: filled again") +end + +for _, case in ipairs({ { name = "QUIT", keys = { "down", "down", "a" }, row = 3 }, + { name = "B", keys = { "b" }, row = 1 } }) do + local game, states, frame = newGame() + local quits = 0 + local menu = ShopMenu.new(game, { "POKE_BALL" }, function() quits = quits + 1 end) + game.stack:push(menu) + until_(frame, function() return states[#states] == menu end) + for _, k in ipairs(case.keys) do frame(k) end + local bye = states[#states] + check(getmetatable(bye) == TextBox, case.name .. ": Thank you! is up") + eq(states[#states - 1], menu, case.name .. ": the menu stays under Thank you!") + eq(menu.hollowIndex, case.row, case.name .. ": the chosen row is hollow") + eq(quits, 0, case.name .. ": onQuit waits for the text") + until_(frame, function() return bye.done end) + frame("a") + eq(#states, 0, case.name .. ": the box and the menu close together") + eq(quits, 1, case.name .. ": onQuit fires once") +end + +do + local game, states, frame = newGame() + game.save.inventory, game.save.bagOrder = {}, {} + local menu = ShopMenu.new(game, { "POKE_BALL" }, function() end) + game.stack:push(menu) + until_(frame, function() return states[#states] == menu end) + frame("down") + frame("a") + local empty = states[#states] + check(getmetatable(empty) == TextBox and not empty.stay, "empty bag: the refusal prompt is up") + until_(frame, function() return empty.done end) + frame("a") + check(isSay(states[#states], ELSE), "empty bag: anything-else types after the refusal") + check(until_(frame, function() return states[#states] == menu end), + "empty bag: back to BUY/SELL/QUIT") + eq(menu.index, 1, "empty bag: cursor on BUY") +end + +package.loaded["src.render.Font"] = realFont +for _, m in ipairs(RELOAD) do package.loaded[m] = nil end +require("src.ui.Screens").invalidate() + +T.finish() diff --git a/tests/engine/mart_list_box_bug1887.lua b/tests/engine/mart_list_box_bug1887.lua index 8ec4fe54..b92f8d33 100644 --- a/tests/engine/mart_list_box_bug1887.lua +++ b/tests/engine/mart_list_box_bug1887.lua @@ -65,6 +65,14 @@ game = { }, } +local function drain() + for _ = 1, 600 do + local top = game.stack:top() + if not (top and top.stay and not top.stayShown) then return end + top:update(1 / 60) + end +end + local function openList(which) game.stack.states = {} local menu = ShopMenu.new(game, { "POKE_BALL", "GREAT_BALL" }, function() end) @@ -73,6 +81,7 @@ local function openList(which) pressed = "a" menu:update(1 / 60) pressed = nil + drain() return menu, game.stack:top() end @@ -129,6 +138,7 @@ do pressed = "a" list:update(1 / 60) pressed = nil + drain() eq(game.stack:top(), menu, "A on CANCEL returns to the mart menu") end diff --git a/tests/engine/mart_price_text_bug2291.lua b/tests/engine/mart_price_text_bug2291.lua index fd19d972..b4ce4434 100644 --- a/tests/engine/mart_price_text_bug2291.lua +++ b/tests/engine/mart_price_text_bug2291.lua @@ -93,6 +93,14 @@ local function newGame(money) return game, stack, frame end +local function drain(game) + for _ = 1, 600 do + local top = game.stack:top() + if not (top and top.stay and not top.stayShown) then return end + top:update(1 / 60) + end +end + local function flat(box) local out = {} for _, page in ipairs(box.pages or {}) do @@ -105,6 +113,7 @@ do local game, stack, frame = newGame(3000) local menu = ShopMenu.new(game, { "POKE_BALL" }, function() end) menu.items[1].onSelect() + drain(game) local list = stack[#stack] list.index = 1 list.onChoose({ value = "POKE_BALL" }) @@ -161,6 +170,7 @@ do local game, stack = newGame(3000) local menu = ShopMenu.new(game, { "POKE_BALL" }, function() end) menu.items[1].onSelect() + drain(game) local list = stack[#stack] list.onChoose({ value = "POKE_BALL" }) local qty = stack[#stack] @@ -185,6 +195,7 @@ do game.save.bagOrder = { "POKE_BALL" } local menu = ShopMenu.new(game, { "POKE_BALL" }, function() end) menu.items[2].onSelect() + drain(game) local list = stack[#stack] list.index = 1 list.onChoose(list.items[1]) diff --git a/tests/engine/mart_quantity_cap_bug1981.lua b/tests/engine/mart_quantity_cap_bug1981.lua index 72ab711f..08a2f5d7 100644 --- a/tests/engine/mart_quantity_cap_bug1981.lua +++ b/tests/engine/mart_quantity_cap_bug1981.lua @@ -133,15 +133,17 @@ do }, save = { money = 100, inventory = {}, bagOrder = {} }, stack = { push = function(_, s) pushed[#pushed + 1] = s end, - pop = function() end }, + pop = function() end, + top = function() return pushed[#pushed] end }, } local menu = ShopMenu.new(game, { "POKE_BALL" }, function() end) menu.items[1].onSelect() - local list = pushed[1] + pushed[1].stay.onShown() + local list = pushed[2] if check(list ~= nil and list.onChoose ~= nil, "BUY pushes the item list") then local before = list.footer list.onChoose({ value = "POKE_BALL" }) - local qty = pushed[2] + local qty = pushed[3] if check(qty ~= nil, "choosing an item opens the quantity menu") then eq(qty.max, 99, "wMaxItemQuantity is 99, not floor(money / price)") eq(qty.unitPrice, 200, "the unit price rides along for the total") diff --git a/tests/engine/pad_hints_bug2452_test.lua b/tests/engine/pad_hints_bug2452_test.lua new file mode 100644 index 00000000..60811846 --- /dev/null +++ b/tests/engine/pad_hints_bug2452_test.lua @@ -0,0 +1,172 @@ +package.path = "./?.lua;./?/init.lua;" .. package.path +if not _G.love then _G.love = require("tests.love_stub") end + +local T = require("tests.harness") +local check, eq = T.check, T.eq + +local PadHints = require("src.core.PadHints") + +local function fakeFfi(opts) + opts = opts or {} + local calls = {} + local ffi = { + cdef = function() end, + load = function(name) + calls[#calls + 1] = { "load", name } + if opts.loadThrows then error("no SDL2 here") end + return { + SDL_SetHint = function(name2, value) + calls[#calls + 1] = { "hint", name2, value } + return 1 + end, + } + end, + } + return ffi, calls +end + +local function env(values) + return function(k) return values[k] end +end + +local ffi, calls = fakeFfi() +check(PadHints.apply("Windows", ffi, env({})), "Windows sets the hint") +eq(calls[1] and calls[1][2], "SDL2", "the hint goes through SDL2.dll") +eq(calls[2] and calls[2][2], "SDL_JOYSTICK_ALLOW_BACKGROUND_EVENTS", "hint name") +eq(calls[2] and calls[2][3], "1", "hint value") + +for _, name in ipairs({ "OS X", "Linux", "Android", "iOS", "NX" }) do + local f, c = fakeFfi() + check(not PadHints.apply(name, f, env({})), name .. " leaves the hint alone") + eq(#c, 0, name .. " never touches SDL") +end + +local f0, c0 = fakeFfi() +check(not PadHints.apply("Windows", f0, env({ POKEPORT_PAD_BACKGROUND = "0" })), + "POKEPORT_PAD_BACKGROUND=0 opts out") +eq(#c0, 0, "and never loads SDL2") + +local f1, c1 = fakeFfi() +check(PadHints.apply("Windows", f1, env({ POKEPORT_PAD_BACKGROUND = "1" })), + "POKEPORT_PAD_BACKGROUND=1 still sets it") +eq(#c1, 2, "one load and one hint") + +local fThrow = fakeFfi({ loadThrows = true }) +local okThrow, result = pcall(PadHints.apply, "Windows", fThrow, env({})) +check(okThrow, "a throwing ffi.load is swallowed") +check(result == false, "and reports the hint as unset") + +local savedWindow = love.window +local minimized, focused = false, true +love.window = { + isMinimized = function() return minimized end, + isVisible = function() return not minimized end, + hasFocus = function() return focused end, +} +check(not PadHints.windowMinimized(), "a shown window is not minimized") +minimized = true +check(PadHints.windowMinimized(), "a minimized window is") +minimized = false +focused = false +check(not PadHints.windowMinimized(), "losing focus alone does not count as minimized") +love.window = { isVisible = function() return false end } +check(PadHints.windowMinimized(), "isVisible false is the fallback") +love.window = { isMinimized = function() error("boom") end } +check(not PadHints.windowMinimized(), "a throwing window query reads as shown") +love.window = nil +check(not PadHints.windowMinimized(), "no window module reads as shown") + +local Input = require("src.core.Input") +local physical = {} +local pad = { + isGamepad = function() return true end, + isGamepadDown = function(_, button) return physical[button] == true end, + getGamepadAxis = function() return 0 end, + getName = function() return "Xbox Controller" end, + getGUID = function() return "030000005e040000" end, + isConnected = function() return true end, +} +local savedJoystick = love.joystick +love.joystick = { + getJoystickCount = function() return 1 end, + getJoysticks = function() return { pad } end, +} +minimized, focused = false, false +love.window = { + isMinimized = function() return minimized end, + isVisible = function() return not minimized end, + hasFocus = function() return focused end, +} + +Input:init() +Input:applyBindings(nil) +Input:reset() +Input:step() + +physical.a = true +Input:step() +check(Input:wasPressed("a"), "unfocused but shown: the pad A press still lands") +physical.a = false +Input:step() +check(not Input:isDown("a"), "and releases") + +minimized = true +physical.a = true +Input:step() +check(not Input:wasPressed("a"), "minimized: a pad press is dropped") +check(not Input:isDown("a"), "and never held") +physical.a = false +Input:step() +minimized = false +Input:step() +physical.a = true +Input:step() +check(Input:wasPressed("a"), "restored: the next press lands") +physical.a = false +Input:step() + +local SwitchDiagnostics = require("src.debug.SwitchDiagnostics") +local savedSystem = love.system +love.system = { getOS = function() return "OS X" end } +SwitchDiagnostics._resetForTests() +love.filesystem.write("switch-debug.txt", "") +focused = false +SwitchDiagnostics.onFocus(false) +SwitchDiagnostics.onJoystickEvent("gamepadpressed", pad, "a") +focused = true +SwitchDiagnostics.onFocus(true) +SwitchDiagnostics.maybeFlush(true, 100) +local log = love.filesystem.read("switch.log") or "" +check(log:find("focus f=false hasFocus=false visible=true", 1, true) ~= nil, + "focus loss lands in the ring with hasFocus and visible") +check(log:find("focus f=true hasFocus=true visible=true", 1, true) ~= nil, + "focus gain lands in the ring") +check(log:find("gamepadpressed button=a guid=030000005e040000 hf=false", 1, true) ~= nil, + "joystick lines carry hf=") +check(not log:find("fg=", 1, true), "fg= is Windows only") + +eq(PadHints.foreground("OS X"), nil, "foreground probe is Windows only") +PadHints._resetForTests() +local fgFfi = { + cdef = function() end, + C = { + GetForegroundWindow = function() return {} end, + GetWindowThreadProcessId = function(_, pid) pid[0] = 42 end, + GetCurrentProcessId = function() return 42 end, + }, + new = function() return {} end, +} +eq(PadHints.foreground("Windows", fgFfi), "ours", "our foreground window reads ours") +fgFfi.C.GetCurrentProcessId = function() return 7 end +eq(PadHints.foreground("Windows", fgFfi), "other", "another process reads other") +PadHints._resetForTests() +eq(PadHints.foreground("Windows", { cdef = function() end, C = {} }), nil, + "a missing user32 export is swallowed") + +love.filesystem.remove("switch-debug.txt") +love.filesystem.remove("switch.log") +SwitchDiagnostics._resetForTests() +PadHints._resetForTests() +love.window, love.joystick, love.system = savedWindow, savedJoystick, savedSystem + +T.finish("pad hints bug 2452") diff --git a/tests/engine/pikachu_thunderbolt_flash_2347.lua b/tests/engine/pikachu_thunderbolt_flash_2347.lua index 20106d60..128bc75c 100644 --- a/tests/engine/pikachu_thunderbolt_flash_2347.lua +++ b/tests/engine/pikachu_thunderbolt_flash_2347.lua @@ -28,10 +28,7 @@ Sound.moveSfxBusy = function() end Music.duckForFanfare = function(src) ducks[#ducks + 1] = src end local realExists = Assets.exists -Assets.exists = function(path) - if path:find("pikapic_", 1, true) then return true end - return realExists(path) -end +Assets.exists = function() return false end local tbAnim = { sound = "Battle_2F", pitch = 32, tempo = 128 } local game = { @@ -60,7 +57,8 @@ local function newOw() end local function runPress(ow, pressAt) - local log = { frames = 0, bgp = {}, skippableAt = {} } + local log = { frames = 0, bgp = {}, skippableAt = {}, pics = {}, lifts = {}, + close = {} } local guard = 0 while ow.emote and guard < 2000 do guard = guard + 1 @@ -71,8 +69,14 @@ local function runPress(ow, pressAt) log.frames = log.frames + 1 if e.pikaPic then log.pic = log.pic or e + local path, lift = PikachuFollower.picFrame(e) + log.pics[#log.bgp + 1] = path and path:match("([^/]+)%.png$") or false + log.lifts[#log.bgp + 1] = lift log.bgp[#log.bgp + 1] = e.bgp or false log.skippableAt[#log.skippableAt + 1] = e.skippable and true or false + if e.boltDone and e.frames > 0 then + log.close[#log.close + 1] = tostring(log.pics[#log.pics]) + end end if (e.skippable and pressed) or e.frames <= 0 then local done = e.onDone @@ -122,6 +126,33 @@ for i = pre + 81, #log.bgp do if log.bgp[i] ~= 0xE4 then tailLit = false end end check(tailLit, "the lit %11100100 BGP holds until the box closes") + +eq(log.pic.pikaPic, "assets/generated/pikachu/pikapic_25.png", + "the base pic is the cache rip even when Assets.exists says no (no fallback)") +local function runOf(from, to, want) + for i = from, to do + if log.pics[i] ~= want or log.lifts[i] ~= 0 then return false end + end + return true +end +check(runOf(1, 17, "pikapic_25"), "ticks 0-5: the base frown Pic_e77cf alone (pikaframedelay 6)") +check(runOf(18, 35, "gfx_e7863"), "ticks 6-11: PikaAnimTilemap_9 draws GFX_e7863") +check(runOf(36, pre, "gfx_e79f3"), "tick 12 on: PikaAnimTilemap_10 draws GFX_e79f3") +local strobePose = true +for i = pre + 1, pre + 80 do + if log.pics[i] ~= "gfx_e79f3" or log.lifts[i] ~= 0 then strobePose = false end +end +check(strobePose, "the Thunderbolt pose GFX_e79f3 holds through every strobe frame, unlifted") +local tailPose, blank = true, 0 +for i = pre + 81, #log.pics do + if log.pics[i] == false then blank = blank + 1 + elseif blank > 0 or log.pics[i] ~= "gfx_e79f3" then tailPose = false end +end +check(tailPose, "and through the lit tail") +check(blank >= 1, "the box is emptied before it closes (.RunPikapic PlacePikapicTextBoxBorder)") +eq(table.concat(log.close, ",", 1, math.min(#log.close, 6)) .. "|" .. #log.close, + "gfx_e79f3,gfx_e79f3,gfx_e79f3,false,false,false|6", + "PlacePikapicTextBoxBorder: the pose stays up for the first Delay3, the empty box for the second") eq(log.skippableAt[45], true, "A/B can still cut the pic before the bolt") eq(log.skippableAt[46], false, "the bolt itself is not skippable") check(not ducks[1].isPlaying(), "the mute releases once the box closes") @@ -134,7 +165,7 @@ eq(ow.emote and ow.emote.bubble, 4, "a second talk inside the window replays Pik busyFrames = 30 log = runPress(ow) eq(#moveCalls, 1, "the second talk bolts again") -eq(#log.bgp - (46 + 80), 30 + 4, "WaitForSoundToFinish holds the box until the sound ends") +eq(#log.bgp - (46 + 80), 30 + 7, "WaitForSoundToFinish holds the box until the sound ends") moveCalls, ducks = {}, {} ow = newOw() @@ -153,6 +184,72 @@ log = runPress(ow) eq(#moveCalls, 0, "a plain mood talk has no bolt") check(log.pic == nil or log.pic.boltAt == nil, "and no bolt spec") +local function poseAt(e, tick) + e.frames = e.pikaTotal - tick * 3 + local path, lift = PikachuFollower.picFrame(e) + return path and path:match("([^/]+)%.png$") or false, lift +end +game.save.pikachuHappiness, game.save.pikachuMood = 255, 255 +ow = newOw() +PikachuFollower.talk(game, ow, newNpc(), function() end) +local e20 = ow.emote +check(e20 and e20.pikaPoses ~= nil, "emotion 20 plays PikaPicAnimBGFrames_26 from ripped poses") +if e20 and e20.pikaPoses then + eq(poseAt(e20, 0), "pikapic_20", "script 20 opens on its base pic (pikaframedelay 8)") + eq(poseAt(e20, 8), "gfx_e6646", "tick 8: PikaAnimTilemap_34 draws GFX_e6646") + eq(poseAt(e20, 20), "pikapic_20", "tick 20: back to the base") + eq(poseAt(e20, 28), "gfx_e6646", "tick 28: the pose again") + eq(poseAt(e20, 40), "pikapic_20", "tick 40: the frameset restarts at pikaframeend") + local _, lift = poseAt(e20, 8) + eq(lift, 0, "a ripped pose is drawn in place, not lifted") + eq(PikachuFollower.picLift(e20), 0, "picLift stays 0 for a pose script") +end + +local P = PikachuFollower.PIKAPIC +local function fakeEmote(script) + local a = P[script] + local poses + if a.poses then + poses = {} + for i = 1, #a.seq do + poses[i] = a.poses[i] and ("assets/generated/pikachu/gfx_" .. a.poses[i] .. ".png") or false + end + end + return { pikaPic = "assets/generated/pikachu/pikapic_" .. script .. ".png", + pikaSeq = a.seq, pikaPoses = poses, pikaTotal = a.dur * 3, frames = a.dur * 3 } +end +local e21 = fakeEmote(21) +eq(poseAt(e21, 8), "gfx_e682f", "script 21 tick 8: PikaAnimTilemap_9 -> GFX_e682f") +eq(poseAt(e21, 10), "gfx_e69bf", "script 21 tick 10: PikaAnimTilemap_10 -> GFX_e69bf") +eq(poseAt(e21, 11), "gfx_e6b4f", "script 21 tick 11: PikaAnimTilemap_11 -> GFX_e6b4f") +eq(poseAt(e21, 12), "gfx_e6cdf", "script 21 tick 12: PikaAnimTilemap_12 -> GFX_e6cdf") +local e26 = fakeEmote(26) +eq(poseAt(e26, 56), "gfx_e7b83", "script 26 tick 56: GFX_e7b83") +eq(poseAt(e26, 64), "gfx_e7d13", "script 26 tick 64: GFX_e7d13 holds") +local e7 = fakeEmote(7) +eq(poseAt(e7, 0), "gfx_e4841", "script 7 opens on PikaAnimTilemap_20 (GFX_e4841)") +eq(poseAt(e7, 8), "pikapic_7", "script 7 tick 8: base") +local e4 = fakeEmote(4) +local p4, l4 = poseAt(e4, 8) +check(p4 == "pikapic_4" and l4 > 0, "script 4 (20-tile GFX_e444b overlay) keeps the picLift stand-in") + +local CacheContract = require("src.import.CacheContract") +local required = {} +for _, path in ipairs(CacheContract.VERSION_REQUIRED_FILES.yellow or {}) do required[path] = true end +local listed, missing = 0, {} +for script, a in pairs(P) do + for _, id in ipairs(a.poses or {}) do + if id then + local path = "assets/generated/pikachu/gfx_" .. id .. ".png" + if required[path] then listed = listed + 1 else missing[#missing + 1] = script .. ":" .. id end + end + end + if a.poses then eq(#a.poses, #a.seq, "script " .. script .. " has one pose slot per run") end +end +check(listed > 0, "the frameset table names ripped poses") +check(#missing == 0, "every pose the frameset table draws is a required yellow cache file " + .. table.concat(missing, ",")) + Sound.playMove, Sound.playPikaCry, Sound.playCry = realPlayMove, realPikaCry, realCry Sound.moveSfxBusy, Music.duckForFanfare = realBusy, realDuck Assets.exists = realExists diff --git a/tests/engine/present_sync_logic.lua b/tests/engine/present_sync_logic.lua index 79a89754..b5809c3c 100644 --- a/tests/engine/present_sync_logic.lua +++ b/tests/engine/present_sync_logic.lua @@ -125,13 +125,18 @@ FixedStep.maxAccum = FixedStep.catchupLimit(2) FixedStep:update(1 / 60, 2) T.eq(steps, 2, "and 2X runs two") --- Catch-up debt hard ceiling: high speed cannot raise maxAccum past MAX_ACCUM. T.eq(FixedStep.catchupLimit(1), FixedStep.STEP * 2, "1X catch-up floor is two steps") T.eq(FixedStep.catchupLimit(4), 4 * FixedStep.STEP * 1.5, "4X catch-up matches one frame of target work") -T.eq(FixedStep.catchupLimit(200), FixedStep.MAX_ACCUM, - "200X catch-up is hard-capped at MAX_ACCUM (no input-starving spiral)") +T.eq(FixedStep.catchupLimit(200), 200 * FixedStep.STEP * 1.5, + "200X catch-up scales with speed") +T.check(FixedStep.catchupLimit(200) > FixedStep.MAX_ACCUM, + "200X catch-up is not pinned at MAX_ACCUM") +T.eq(FixedStep.catchupLimit(4, 1 / 30), 4 * (1 / 30) * 1.5, + "a 30fps frame buys two frames of target work") +T.eq(FixedStep.catchupLimit(4, 1 / 240), 4 * FixedStep.STEP * 1.5, + "a short frame keeps the one-step floor") FixedStep.refreshPeriod = nil love.window.getVSync, love.window.setVSync = nil, nil diff --git a/tests/engine/save_editor_options_2388.lua b/tests/engine/save_editor_options_2388.lua new file mode 100644 index 00000000..d7fbe58a --- /dev/null +++ b/tests/engine/save_editor_options_2388.lua @@ -0,0 +1,102 @@ +package.path = package.path .. ";./?.lua;./?/init.lua;./tools/save-editor/?.lua" + .. ";./tools/save-editor/panels/?.lua" + +love = require("tests.love_stub") + +local passed, failed = 0, 0 +local function check(cond, msg) + if cond then + passed = passed + 1 + else + failed = failed + 1 + print("FAIL: " .. msg) + end +end +local function eq(a, b, msg) + check(a == b, msg .. string.format(" (got %s, want %s)", tostring(a), tostring(b))) +end + +local SaveData = require("src.core.SaveData") +local SaveSerializer = require("src.core.SaveSerializer") +local SessionLifecycle = require("src.core.SessionLifecycle") +local FsIo = require("tests.fs_io") +local Ops = require("Ops") +local App = require("App") + +local fs = love.filesystem + +do + local opts = SaveData.loadOptions() + opts.battleLayout, opts.battleFit, opts.battleHud, opts.battleBg = "wide", "fixed", "extended", "world" + opts.colors, opts.tilt = "og", 2 + SaveData.saveOptions(opts) + local slotId = SaveData.createSlot("red") + check(slotId ~= nil, "a red slot is created") + SaveData.setActiveSlot("red", slotId) + local before = fs.read("options.lua") + check(type(before) == "string" and before:find("wide", 1, true) ~= nil, "options.lua holds WIDE before the edit") + local save = SaveData.newGame() + save.player.name = "ASH" + save.options = { battleLayout = "og", battleBg = "white", colors = "gbc", tilt = 0, videoMode = "windowed" } + check(SaveData.writeSlot("red", slotId, save) == true, "writeSlot writes the slot") + eq(save.options.battleLayout, "og", "writeSlot leaves the caller's table alone") + local slotBody = SaveData.readSlotSource("red", slotId) + check(slotBody ~= nil, "the slot reads back") + local slotTable = slotBody and SaveSerializer.decode(slotBody) + check(slotTable ~= nil and slotTable.options == nil, "writeSlot strips options from a gen1 slot") + eq(fs.read("options.lua"), before, "writeSlot does not touch options.lua") + + local tmpBase = os.tmpname() + local tmpPath = tmpBase .. "-options-2388.lua" + local f = io.open(tmpPath, "wb") + f:write(slotBody) + f:close() + App.load(tmpPath, { version = "red", slotId = slotId, embedded = true, onClose = function() end }) + local s = App.getState() + check(s ~= nil and s.loadError == false, "the editor opens the slot") + Ops.addMoney(s, 10) + s.save.pokedex = s.save.pokedex or {} + s.save.pokedex.owned = s.save.pokedex.owned or {} + s.save.pokedex.owned.PIKACHU = true + s.dirty = true + App.save() + eq(fs.read("options.lua"), before, "App.save leaves options.lua byte-identical") + pcall(SessionLifecycle.endEditorSession, { version = "red", app = App }) + eq(fs.read("options.lua"), before, "closing the editor leaves options.lua byte-identical") + + local rf = io.open(tmpPath, "rb") + local edited = rf and rf:read("*a") or "" + if rf then rf:close() end + local editedTable = SaveSerializer.decode(edited) + check(editedTable ~= nil, "the edited slot decodes") + check(editedTable and editedTable.options == nil, "the edited slot has no options key") + check(editedTable and editedTable.pokedex and editedTable.pokedex.owned + and editedTable.pokedex.owned.PIKACHU == true, "the dex edit landed") + + check(SaveData.writeSlot("red", slotId, editedTable) == true, "the edited slot writes back") + local loaded = SaveData.load("red") + check(loaded ~= nil, "the edited slot loads") + eq(loaded and loaded.options and loaded.options.battleLayout, "wide", "battle layout stays WIDE after an edit") + eq(loaded and loaded.options and loaded.options.battleBg, "world", "battle bg stays WORLD after an edit") + eq(loaded and loaded.options and loaded.options.battleHud, "extended", "battle hud stays EXTENDED after an edit") + eq(loaded and loaded.options and loaded.options.colors, "og", "colors stay OG after an edit") + eq(fs.read("options.lua") and SaveSerializer.decode(fs.read("options.lua")).battleLayout, "wide", + "options.lua still says WIDE after the load") + + os.remove(tmpPath) + os.remove(tmpBase) + for _, bak in ipairs(FsIo.globPrefix(tmpPath .. ".bak-")) do os.remove(bak) end +end + +do + local slotId = SaveData.createSlot("firered") + if slotId then + local save = { engine = "game3", version = "firered", name = "RED", options = { textSpeed = 1, frameType = 3 } } + check(SaveData.writeSlot("firered", slotId, save) == true, "writeSlot writes a firered slot") + local back = SaveSerializer.decode(SaveData.readSlotSource("firered", slotId) or "") + eq(back and back.options and back.options.frameType, 3, "a gen3 slot keeps its in-save options block") + end +end + +print(string.format("save editor options 2388: %d passed, %d failed", passed, failed)) +if failed > 0 then os.exit(1) end diff --git a/tests/engine/save_export_same_map_moved_2468.lua b/tests/engine/save_export_same_map_moved_2468.lua new file mode 100644 index 00000000..1de997d7 --- /dev/null +++ b/tests/engine/save_export_same_map_moved_2468.lua @@ -0,0 +1,130 @@ +-- home/overworld.asm:1809 +package.path = "./?.lua;./?/init.lua;" .. package.path + +local T = require("tests.modkit") +local MapContext = require("src.save_convert.MapContext") +local GenSave = require("src.save_convert.GenSave") + +local O = MapContext.OFFSETS +local SAVE = GenSave.OFFSETS +local stampMapWindow = loadfile("tests/fixture_data/map_window.lua")() + +GenSave.setCharmap(loadfile("src/save_convert/data/charmap.lua")()) + +local GRASS = {} +for i = 1, 10 do + GRASS[i] = { level = 2 + i, species = (i % 2 == 1) and "FIXMON_A" or "FIXMON_C" } +end +local WATER = {} +for i = 1, 10 do WATER[i] = { level = 20 + i, species = "FIXMON_B" } end + +local function fixtureData() + local maps = {} + for id, map in pairs(dofile("tests/fixture_data/maps.lua")) do + local copy = {} + for k, v in pairs(map) do copy[k] = v end + maps[id] = copy + end + local data = { + maps = maps, + pokemon = dofile("tests/fixture_data/pokemon.lua"), + moves = dofile("tests/fixture_data/moves.lua"), + items = dofile("tests/fixture_data/items.lua"), + encounters = { + FIX_TOWN = { grass = { rate = 25, slots = GRASS }, water = { rate = 5, slots = WATER } }, + }, + } + data = stampMapWindow(data, "FIX_TOWN") + data.maps.FIX_TOWN.sram.objects = { + 0x0E, 0, 0, + 1, 0x01, 0x14, 0x15, 0xFF, 0xD0, 0x05, + } + return data +end + +local data = fixtureData() + +local function newSave(x, y) + return { + player = { name = "RED", rival = "BLUE", map = "FIX_TOWN", x = x, y = y }, + money = 3000, inventory = {}, pokedex = { seen = {}, owned = {} }, + flags = {}, party = {}, boxes = {}, + } +end + +local function mainByte(bytes, off) return bytes:byte(SAVE.mainData + off + 1) end + +do + local ctx = assert(MapContext.build(data, "FIX_TOWN", 7, 4)) + T.eq(ctx.writes[O.grassRate][1], 25, "wGrassRate is the map's grass rate") + T.eq(#ctx.writes[O.grassMons], 20, "wGrassMons is 10 level/species rows") + T.eq(ctx.writes[O.grassMons][1], 3, "grass slot 1 level") + T.eq(ctx.writes[O.grassMons][2], 1, "grass slot 1 species index") + T.eq(ctx.writes[O.grassMons][4], 3, "grass slot 2 species index") + T.eq(ctx.writes[O.waterRate][1], 5, "wWaterRate is the map's water rate") + T.eq(ctx.writes[O.waterMons][1], 21, "water slot 1 level") + T.eq(ctx.writes[O.waterMons][2], 2, "water slot 1 species index") + T.eq(O.grassRate, 0xD886 - 0xD2F6, "wGrassRate offset matches the Yellow sym") + T.eq(O.waterMons, 0xD8A4 - 0xD2F6, "wWaterMons offset matches the Yellow sym") + T.eq(O.grassRate, 0xD887 - 0xD2F7, "wGrassRate offset matches the Red sym") + T.eq(O.waterMons, 0xD8A5 - 0xD2F7, "wWaterMons offset matches the Red sym") +end + +do + local d = fixtureData() + d.encounters = {} + local ctx = assert(MapContext.build(d, "FIX_TOWN", 7, 4)) + T.eq(ctx.writes[O.grassRate][1], 0, "a map with no wild data writes grass rate 0") + T.eq(ctx.writes[O.waterRate][1], 0, "a map with no wild data writes water rate 0") + T.eq(ctx.writes[O.grassMons], nil, "no grass rows when the rate is 0") + d.encounters = nil + local none, why = MapContext.build(d, "FIX_TOWN", 7, 4) + T.eq(none, nil, "a data set with no encounter table refuses the build") + T.eq(type(why) == "string" and why:find("re%-import") ~= nil, true, "and says to re-import the ROM") +end + +do + local fresh = GenSave.encode(newSave(7, 4), data, nil) + T.eq(mainByte(fresh, O.grassRate), 25, "a templateless export carries the grass rate") + T.eq(mainByte(fresh, O.grassMons + 1), 1, "a templateless export carries the grass mons") + T.eq(mainByte(fresh, O.waterRate), 5, "a templateless export carries the water rate") + T.eq(GenSave.mainChecksumValid(fresh), true, "wild data sits inside a valid checksum") + + local tpl = {} + for i = 1, #fresh do tpl[i] = fresh:sub(i, i) end + tpl[SAVE.spriteData + 17] = string.char(0x77) + tpl[SAVE.mainData + O.grassRate + 1] = string.char(0x44) + local template = table.concat(tpl) + + local same = GenSave.encode(newSave(7, 4), data, template) + T.eq(same:byte(SAVE.spriteData + 17), 0x77, "an unmoved template keeps its live sprite window") + T.eq(mainByte(same, O.grassRate), 0x44, "an unmoved template keeps its own wild data") + + local moved = GenSave.encode(newSave(9, 6), data, template) + local ctx = assert(MapContext.build(data, "FIX_TOWN", 9, 6)) + local view = ctx.writes[O.viewPointer] + T.eq(mainByte(moved, O.yCoord), 6, "moved export writes the new y") + T.eq(mainByte(moved, O.xCoord), 9, "moved export writes the new x") + T.eq(mainByte(moved, O.viewPointer), view[1], "moved export rebuilds the view pointer (lo)") + T.eq(mainByte(moved, O.viewPointer + 1), view[2], "moved export rebuilds the view pointer (hi)") + T.eq(mainByte(moved, O.yBlockCoord), 0, "moved export rebuilds wYBlockCoord") + T.eq(mainByte(moved, O.xBlockCoord), 1, "moved export rebuilds wXBlockCoord") + for i = 1, 512 do + if moved:byte(SAVE.spriteData + i) ~= ctx.spriteData[i] then + T.eq(moved:byte(SAVE.spriteData + i), ctx.spriteData[i], ("moved export sprite byte %d"):format(i)) + break + end + end + T.eq(moved:byte(SAVE.spriteData + 17), ctx.spriteData[17], "moved export drops the stale sprite window") + T.eq(mainByte(moved, O.grassRate), 25, "moved export reloads the grass rate") + T.eq(GenSave.mainChecksumValid(moved), true, "moved export checksum is valid") + + local frac = GenSave.encode(newSave(7.4, 4.9), data, template) + T.eq(frac:byte(SAVE.spriteData + 17), 0x77, "fractional coords floor onto the template's own spot") + T.eq(mainByte(frac, O.yCoord), 4, "fractional y floors") + T.eq(mainByte(frac, O.xCoord), 7, "fractional x floors") + local movedX = GenSave.encode(newSave(8, 4), data, template) + T.eq(mainByte(movedX, O.xBlockCoord), 0, "an x-only move rebuilds the window too") +end + +T.finish("save_export_same_map_moved_2468") diff --git a/tests/engine/save_import_retry_bug420.lua b/tests/engine/save_import_retry_bug420.lua index f638e91e..60abe0f8 100644 --- a/tests/engine/save_import_retry_bug420.lua +++ b/tests/engine/save_import_retry_bug420.lua @@ -136,7 +136,7 @@ local SaveConvert = require("src.save_convert.SaveConvert") -- The audio entry is single-quoted on purpose: gate_meta_coverage.lua treats a -- double-quoted registry name anywhere in the test corpus as that registry's -- unit test, and this suite is not the mod audio registry's. -local GENERATED = { "pokemon", "moves", "items", "maps", "tilesets", 'audio' } +local GENERATED = { "pokemon", "moves", "items", "maps", "tilesets", 'audio', 'encounters' } local function prefixes() local seen = {} diff --git a/tests/engine/save_map_context_bug889.lua b/tests/engine/save_map_context_bug889.lua index f0b9f6f3..455fcd45 100644 --- a/tests/engine/save_map_context_bug889.lua +++ b/tests/engine/save_map_context_bug889.lua @@ -66,6 +66,7 @@ local function fixtureData() moves = dofile("tests/fixture_data/moves.lua"), items = dofile("tests/fixture_data/items.lua"), tilesets = { [maps.FIX_TOWN.tileset] = { header = TILESET_HEADER } }, + encounters = {}, audio = { -- Song ids are computed from the header address -- (constants/music_constants.asm): (address - $4000) / 3. diff --git a/tests/fixture_data/map_window.lua b/tests/fixture_data/map_window.lua index 59d21281..964c4f44 100644 --- a/tests/fixture_data/map_window.lua +++ b/tests/fixture_data/map_window.lua @@ -26,5 +26,6 @@ return function(data, mapId) data.audio.mapSongs[mapId] = data.audio.mapSongs[mapId] or "Music_Fixture" data.audio.songs.Music_Fixture = data.audio.songs.Music_Fixture or { address = 0x4000 + 3 * 0xBD, bank = 2 } + data.encounters = data.encounters or {} return data end diff --git a/tests/game3_battle_exp_participants_test.lua b/tests/game3_battle_exp_participants_test.lua index f07e095f..5cd33eef 100644 --- a/tests/game3_battle_exp_participants_test.lua +++ b/tests/game3_battle_exp_participants_test.lua @@ -101,6 +101,121 @@ do check(awards2[1].amount > awards1[1].amount, "p3 receives full undivided EXP for e2") end +print("\n=== 2b. Live shift step list: player swaps before enemy, only new mon earns EXP ===") +do + local Adapter = require("src.core.game3.battle.adapter") + local p1 = Damage.ensureStats({ species = 1, level = 10, hp = 30, maxHp = 30, exp = 1000 }) + local p2 = Damage.ensureStats({ species = 4, level = 10, hp = 30, maxHp = 30, exp = 1000 }) + local e1 = Damage.ensureStats({ species = 16, level = 10, hp = 0, maxHp = 30, exp = 1000 }) + local e2 = Damage.ensureStats({ species = 19, level = 10, hp = 30, maxHp = 30, exp = 1000 }) + + local st = State.new({ + playerParty = { p1, p2 }, + foeParty = { e1, e2 }, + foeMon = e1, + wild = false, + }) + local ad = Adapter.new(st, function() end) + + eq(SwitchSeq.beginShiftSwitch(st, 2, 2, { headless = false }), true, "live shift builds a step list") + local swaps = {} + for _, step in ipairs(SwitchSeq._steps or {}) do + if step.kind == "swap_data" then swaps[#swaps + 1] = step.data end + end + eq(#swaps, 2, "shift step list has two swap_data rows") + eq(swaps[1].side, "player", "player swap_data runs before the enemy send-out") + eq(swaps[2].side, "enemy", "enemy swap_data runs second") + SwitchSeq.reset() + + for _, d in ipairs(swaps) do + Engine.performSwitch(st, ad, d.side, d.newSlot, + { reason = d.reason or "switch", isShift = d.isShift }) + end + eq(st.player.partyIndex, 2, "p2 is active after live shift") + eq(st.enemy.partyIndex, 2, "e2 is active after live shift") + eq(st.enemy.participants[1], nil, "withdrawn p1 is NOT participant on e2 (live path)") + eq(st.enemy.participants[2], true, "p2 is participant on e2 (live path)") + + local awards = Experience.awardFoe(st, st.enemy, { trainer = true }) + eq(#awards, 1, "only p2 receives EXP for e2 (live path)") + eq(awards[1].partyIndex, 2, "live-path award goes to p2") +end + +print("\n=== 2d. Shift switch-in effects: player Spikes before the enemy send-out, Intimidate hits the new foe ===") +do + local Adapter = require("src.core.game3.battle.adapter") + local Hazards = require("src.core.game3.battle.effects.hazards") + local p1 = Damage.ensureStats({ species = 1, level = 10, hp = 30, maxHp = 30, exp = 1000 }) + local p2 = Damage.ensureStats({ species = 58, level = 10, hp = 32, maxHp = 32, exp = 1000, ability = 22 }) + local e1 = Damage.ensureStats({ species = 16, level = 10, hp = 0, maxHp = 30, exp = 1000 }) + local e2 = Damage.ensureStats({ species = 19, level = 10, hp = 30, maxHp = 30, exp = 1000, ability = 50 }) + + local st = State.new({ + playerParty = { p1, p2 }, + foeParty = { e1, e2 }, + foeMon = e1, + wild = false, + }) + st.trainerClassName, st.trainerName = "YOUNGSTER", "BEN" + local savedAd = Battle._adapter + Battle._adapter = Adapter.new(st, function() end) + Hazards.set(st.playerSide, 1) + local log = {} + SwitchSeq.beginShiftSwitch(st, 2, 2, { headless = true, pushMsg = function(text) + log[#log + 1] = tostring(text):lower() + end }) + Battle._adapter = savedAd + + local spikesAt, sentAt, intimAt + for i, t in ipairs(log) do + if t:find("spikes") then spikesAt = spikesAt or i end + if t:find("sent") then sentAt = sentAt or i end + if t:find("cuts") then intimAt = intimAt or i end + end + check(spikesAt ~= nil and sentAt ~= nil and intimAt ~= nil, "spikes, send-out and Intimidate messages pushed") + check(spikesAt < sentAt, "player Spikes resolve before the enemy sends out") + eq(st.player.mon.hp, 28, "player took 1/8 Spikes damage") + check(intimAt > sentAt, "Intimidate resolves after the new foe is out") + eq(st.enemy.stages.attack, -1, "new foe's attack cut by the shifted-in Intimidate") + + eq(SwitchSeq.beginShiftSwitch(st, 1, 2, { headless = false }), true, "live shift builds a step list") + local entry, enemySwap = {}, nil + for i, step in ipairs(SwitchSeq._steps or {}) do + if step.kind == "entry_triggers" then entry[#entry + 1] = { i = i, d = step.data } end + if step.kind == "swap_data" and step.data.side == "enemy" then enemySwap = { i = i, d = step.data } end + end + SwitchSeq.reset() + eq(#entry, 2, "two entry_triggers steps") + eq(entry[1].d.side, "player", "first entry step is the player's") + check(entry[1].d.deferIntimidate, "player entry step defers Intimidate") + check(entry[1].i < enemySwap.i, "player entry step runs before the enemy swap_data") + eq(entry[2].d.side, "enemy", "second entry step is the enemy's") + check(entry[2].i > enemySwap.i, "enemy entry step runs after the enemy swap_data") + eq(enemySwap.d.reason, "shift", "enemy swap_data keeps reason shift") +end + +print("\n=== 2c. Shift performSwitch resets sent mons even when the enemy swaps first ===") +do + local Adapter = require("src.core.game3.battle.adapter") + local p1 = Damage.ensureStats({ species = 1, level = 10, hp = 30, maxHp = 30, exp = 1000 }) + local p2 = Damage.ensureStats({ species = 4, level = 10, hp = 30, maxHp = 30, exp = 1000 }) + local e1 = Damage.ensureStats({ species = 16, level = 10, hp = 0, maxHp = 30, exp = 1000 }) + local e2 = Damage.ensureStats({ species = 19, level = 10, hp = 30, maxHp = 30, exp = 1000 }) + + local st = State.new({ + playerParty = { p1, p2 }, + foeParty = { e1, e2 }, + foeMon = e1, + wild = false, + }) + local ad = Adapter.new(st, function() end) + Engine.performSwitch(st, ad, "enemy", 2, { reason = "switch" }) + eq(st.enemy.participants[1], true, "p1 tracked on e2 while still active") + Engine.performSwitch(st, ad, "player", 2, { reason = "shift", isShift = true }) + eq(st.enemy.participants[1], nil, "shift switch drops p1 from e2's sent mons") + eq(st.enemy.participants[2], true, "shift switch leaves only p2 on e2") +end + print("\n=== 3. Enemy AI switch resets participant tracking ===") do local p1 = Damage.ensureStats({ species = 1, level = 10, hp = 30, maxHp = 30, exp = 1000 }) diff --git a/tests/game3_battle_switch_and_faint_test.lua b/tests/game3_battle_switch_and_faint_test.lua index e77e452f..1640fcb4 100644 --- a/tests/game3_battle_switch_and_faint_test.lua +++ b/tests/game3_battle_switch_and_faint_test.lua @@ -399,8 +399,8 @@ do eq(st.player.partyIndex, 2, "player active slot is 2") eq(st.enemy.partyIndex, 2, "enemy active slot is 2") check(logged[1]:find("that's enough!"), "step 1: player recall message") - check(logged[2]:find("sent\nout"), "step 2: enemy sendout message (BEFORE player sendout)") - check(logged[3]:find("Go!"), "step 3: player sendout message (AFTER enemy sendout)") + check(logged[2]:find("Go!"), "step 2: player sendout message (BEFORE enemy sendout)") + check(logged[3]:find("sent\nout"), "step 3: enemy sendout message (AFTER player sendout)") -- Non-headless step ordering test SwitchSeq.beginShiftSwitch(st, 2, 2, { headless = false, pushMsg = pushMsg }) @@ -419,16 +419,16 @@ do local iWithdraw = find_step("withdraw") local iEnemySend = find_step("sendout_enemy") local iPlayerSend = find_step("sendout_player") - local iEntryTriggers = find_step("entry_triggers") + local iEntryTriggers = find_step("entry_triggers", iEnemySend) check(iWithdraw ~= nil, "has withdraw step") check(iEnemySend ~= nil, "has sendout_enemy step") check(iPlayerSend ~= nil, "has sendout_player step") check(iEntryTriggers ~= nil, "has entry_triggers step") - check(iWithdraw < iEnemySend, "player withdraws BEFORE enemy sends out") - check(iEnemySend < iPlayerSend, "enemy sends out BEFORE player sends out (retail FRLG)") - check(iPlayerSend < iEntryTriggers, "entry triggers fire AFTER both mons placed on field") + check(iWithdraw < iPlayerSend, "player withdraws BEFORE player sends out") + check(iPlayerSend < iEnemySend, "player sends out BEFORE enemy sends out (retail FRLG)") + check(iEnemySend < iEntryTriggers, "entry triggers fire AFTER the enemy send-out") end print("\n--- Testing SwitchSeq.beginTrainerSlideIn ---") diff --git a/tests/game3_compat_connections_view_test.lua b/tests/game3_compat_connections_view_test.lua new file mode 100644 index 00000000..ec2f5eda --- /dev/null +++ b/tests/game3_compat_connections_view_test.lua @@ -0,0 +1,45 @@ +package.path = "./?.lua;./?/init.lua;" .. package.path + +require("src.core.GameVersion").set("firered") + +local failures = 0 +local function check(ok, label) + print((ok and "PASS " or "FAIL ") .. label) + if not ok then failures = failures + 1 end +end + +local Gen3Compat = require("src.mods.Gen3Compat") + +local def = { + id = "FR_SIX_ISLAND_WATER_PATH", width = 20, height = 70, + connections = { + { dir = "west", map = "FR_SIX_ISLAND_GREEN_PATH", offset = 0 }, + { dir = "west", map = "FR_SIX_ISLAND", offset = 40 }, + { dir = "west", map = "FR_SIX_ISLAND_RUIN_VALLEY", offset = 80 }, + { dir = "north", map = "FR_SIX_ISLAND_POKEMON_CENTER", offset = 0 }, + }, +} +local game = { data = { maps = { FR_SIX_ISLAND_WATER_PATH = def } } } +Gen3Compat.bind(function() return game end) + +local view = Gen3Compat.mapView("FR_SIX_ISLAND_WATER_PATH") +local conns = view.connections +check(type(conns) == "table" and #conns == 4, "four ordered connections") + +local seen = 0 +for _ in pairs(conns) do seen = seen + 1 end +check(seen == 4, "pairs() yields each connection once (got " .. seen .. ")") + +check(conns.west and conns.west.map == "FR_SIX_ISLAND_GREEN_PATH", "direction name resolves to the first entry") +check(conns.north and conns.north.map == "FR_SIX_ISLAND_POKEMON_CENTER", "single-entry direction resolves") +check(conns.south == nil, "missing direction is nil") +check(conns[1].map == "FR_SIX_ISLAND_GREEN_PATH" and conns[3].map == "FR_SIX_ISLAND_RUIN_VALLEY", "ROM order kept") + +check(rawequal(view.connections, conns), "view is cached per def") +check(rawequal(Gen3Compat.mapView("FR_SIX_ISLAND_WATER_PATH").connections, conns), "cache is shared across views") + +def.connections = { { dir = "east", map = "FR_SIX_ISLAND", offset = 0 } } +local fresh = view.connections +check(not rawequal(fresh, conns) and #fresh == 1 and fresh.east ~= nil, "replaced connections rebuild the view") + +os.exit(failures == 0 and 0 or 1) diff --git a/tests/game3_connection_list_test.lua b/tests/game3_connection_list_test.lua new file mode 100644 index 00000000..2e91c5c0 --- /dev/null +++ b/tests/game3_connection_list_test.lua @@ -0,0 +1,114 @@ +package.path = "./?.lua;./?/init.lua;" .. package.path +require("src.core.GameVersion").set("firered") + +local ExtractMapEvents = require("src.import.gba.extract_map_events") +local MapTree = require("src.import.gba.map_tree") +local Versions = require("src.import.gba.versions") + +local failures = 0 +local function check(ok, label) + print((ok and "PASS " or "FAIL ") .. label) + if not ok then failures = failures + 1 end +end + +local function fakeRom(bytes) + local rom = { bytes = bytes } + function rom:get(off) return self.bytes[off + 1] or 0 end + function rom:u32(off) + return self:get(off) + self:get(off + 1) * 256 + + self:get(off + 2) * 65536 + self:get(off + 3) * 16777216 + end + function rom:ptrOffset(p) + if p < 0x08000000 or p >= 0x0A000000 then return nil end + return p - 0x08000000 + end + return rom +end + +local function putU32(bytes, off, v) + if v < 0 then v = v + 0x100000000 end + for i = 0, 3 do + bytes[off + i + 1] = math.floor(v / 256 ^ i) % 256 + end +end + +local ENTRIES = { + { dirByte = 3, offset = 0, group = 3, num = 0 }, + { dirByte = 3, offset = 40, group = 3, num = 1 }, + { dirByte = 3, offset = 80, group = 3, num = 2 }, + { dirByte = 4, offset = -12, group = 3, num = 19 }, +} + +local bytes = {} +for i = 1, 0x100 do bytes[i] = 0 end +local HEADER, LIST = 0x10, 0x40 +putU32(bytes, HEADER, #ENTRIES) +putU32(bytes, HEADER + 4, 0x08000000 + LIST) +for i, e in ipairs(ENTRIES) do + local base = LIST + (i - 1) * 12 + bytes[base + 1] = e.dirByte + putU32(bytes, base + 4, e.offset) + bytes[base + 9] = e.group + bytes[base + 10] = e.num +end +local rom = fakeRom(bytes) + +print("[test] 1. ExtractMapEvents.parseConnections keeps every entry in ROM order") +local list = ExtractMapEvents.parseConnections(rom, 0x08000000 + HEADER) +check(#list == 4, "four connections survive (got " .. #list .. ")") +local wantDir = { "west", "west", "west", "east" } +for i, e in ipairs(ENTRIES) do + local c = list[i] or {} + check(c.dir == wantDir[i], ("entry %d dir %s"):format(i, tostring(c.dir))) + check(c.offset == e.offset, ("entry %d offset %s"):format(i, tostring(c.offset))) + check(c.map == Versions.frMapFor(e.group, e.num), + ("entry %d map %s"):format(i, tostring(c.map))) +end +check(list.west == nil and list.east == nil, "no direction-keyed fields") + +print("[test] 2. MapTree.parseConnections keeps every entry in ROM order") +local tree = MapTree.parseConnections(rom, 0x08000000 + HEADER, nil) +check(#tree == 4, "four census connections survive (got " .. #tree .. ")") +for i, e in ipairs(ENTRIES) do + local c = tree[i] or {} + check(c.dir == wantDir[i] and c.offset == e.offset + and c.mapGroup == e.group and c.mapNum == e.num, + ("census entry %d is %s %s %s:%s"):format(i, tostring(c.dir), + tostring(c.offset), tostring(c.mapGroup), tostring(c.mapNum))) +end + +print("[test] 3. an imported cache carries Water Path's three west entries") +local Cache = require("tests.game3_cache") +local root = Cache.root("connections.lua") +if not root then + print("[skip] cache section: " .. tostring(Cache.reason)) +else + local ok, conns = pcall(dofile, root .. "/connections.lua") + check(ok and type(conns) == "table", "connections.lua loads") + local wp = ok and conns.FR_SIX_ISLAND_WATER_PATH or {} + local want = { + { "west", "FR_SIX_ISLAND_GREEN_PATH", 0 }, + { "west", "FR_SIX_ISLAND", 40 }, + { "west", "FR_SIX_ISLAND_RUIN_VALLEY", 80 }, + } + check(#wp == 3, "Water Path has three connections (got " .. #wp .. ")") + for i, w in ipairs(want) do + local c = wp[i] or {} + check(c.dir == w[1] and c.map == w[2] and c.offset == w[3], + ("Water Path entry %d is %s %s %s"):format(i, tostring(c.dir), + tostring(c.map), tostring(c.offset))) + end + local six = ok and conns.FR_SIX_ISLAND or {} + check(#six == 1 and six[1].dir == "east" + and six[1].map == "FR_SIX_ISLAND_WATER_PATH" and six[1].offset == -40, + "Six Island keeps its one east connection") + local total = 0 + for _, entries in pairs(ok and conns or {}) do total = total + #entries end + check(total == 116, "every ROM connection is in the cache (got " .. total .. ")") +end + +if failures > 0 then + print(("game3_connection_list_test: %d failure(s)"):format(failures)) + os.exit(1) +end +print("game3_connection_list_test: all passed") diff --git a/tests/game3_cut_grass_mow_test.lua b/tests/game3_cut_grass_mow_test.lua new file mode 100644 index 00000000..37e4095e --- /dev/null +++ b/tests/game3_cut_grass_mow_test.lua @@ -0,0 +1,87 @@ +package.path = "./?.lua;./?/init.lua;" .. package.path + +require("src.core.GameVersion").set("firered") + +local failures = 0 +local function check(ok, label) + print((ok and "PASS " or "FAIL ") .. label) + if not ok then failures = failures + 1 end +end + +package.loaded["src.core.game3.field_move_show_mon"] = { start = function(_, _, fn) fn() end } +package.loaded["src.core.game3.quest_log_recorder"] = { event = function() end, location = function() end } + +local FieldMoves = require("src.core.game3.field_moves") +local LayoutNative = require("src.core.game3.layout_native") +local FieldEffects = require("src.core.game3.field_effects") +local Audio = require("src.core.game3.audio") +local Field = require("src.core.game3.field") +local Map = require("src.core.game3.map") +local Player = require("src.core.game3.player") + +check(FieldMoves.CUT_GRASS_METATILES[0x284] == 0x281, "Viridian Forest HugeTreeTopMiddle_Grass mows to 0x281") +check(LayoutNative.setMidAt == nil, "LayoutNative has no setMidAt, writes go through applyOverride") + +local function grid(w, h, fill, coll) + local cells = {} + for y = 0, h - 1 do + for x = 0, w - 1 do + cells[y * w + x + 1] = { mid = fill(x, y), coll = coll or 0, elev = 3 } + end + end + return LayoutNative.fromDecoded({ width = w, height = h, cells = cells }, "FR_CUT_TEST", "cut_test") +end + +local L = grid(5, 5, function() return 0x00D end) +L.cells[1 * 5 + 1 + 1] = { mid = 0x00D, coll = 0, elev = 4 } +L.cells[3 * 5 + 3 + 1] = { mid = 0x284, coll = 0, elev = 3 } +L.cells[1 * 5 + 3 + 1] = { mid = 0x3FF, coll = 0, elev = 3 } +local n = FieldMoves.mowGrass3x3(2, 2, + function(x, y) return L:midAt(x, y) end, + function(x, y, mid) L:applyOverride(x, y, mid, 0, L:elevAt(x, y)) end, + function(x, y) return L:elevAt(x, y) == 3 end) +check(n == 7, "seven cells mowed (got " .. n .. ")") +check(L:midAt(2, 2) == 0x001 and L:midAt(1, 3) == 0x001, "plain grass becomes Plain_Mowed") +check(L:midAt(3, 3) == 0x281, "0x284 becomes 0x281") +check(L:midAt(1, 1) == 0x00D, "grass at another elevation is left alone") +check(L:midAt(3, 1) == 0x3FF, "unmapped metatile is left alone") +check(L:midAt(0, 0) == 0x00D, "cells outside the 3x3 are untouched") + +local def = { id = "FR_CUT_TEST", pair = "cut_test", width = 3, height = 3, connections = {}, objects = {}, warps = {} } +def.midLayout = grid(6, 6, function(x) return x == 5 and 0x001 or 0x00D end, 0x18) +def.midLayout.cells[1 * 6 + 1 + 1] = { mid = 0x284, coll = 0, elev = 3 } +def.midLayout.cells[2 * 6 + 0 + 1] = { mid = 0x3FF, coll = 0x18, elev = 0 } +local game = { data = { maps = { FR_CUT_TEST = def } }, save = {} } +local session = { map = "FR_CUT_TEST", flags = {}, vars = {} } +Field._game, Field._session = game, session +Map._def, Map.current = def, "FR_CUT_TEST" +Player.cellX, Player.cellY, Player.elevation = 0, 2, 3 +Audio.playSe = function() end +require("src.core.game3.collision").bindMap(game, "FR_CUT_TEST", def) +local grassCb = 0 +FieldEffects.startCutGrass = function(_, _, cb) grassCb = grassCb + 1; if cb then cb() end end +local events = {} +local ModRuntime = require("src.mods.Runtime") +local wants, emit = ModRuntime.wants, ModRuntime.emit +ModRuntime.wants = function(name) return name == "world.block_replaced" or wants(name) end +ModRuntime.emit = function(name, ev) if name == "world.block_replaced" then events[#events + 1] = ev else return emit(name, ev) end end + +Field.executeFieldMove({ action = "cut_grass", mon = {} }) +ModRuntime.wants, ModRuntime.emit = wants, emit + +local count = 0 +for _ in pairs(def.midLayout.overrides) do count = count + 1 end +check(count == 4, "edge cut writes the four in-bounds grass cells at the player's elevation (got " .. count .. ")") +check(def.midLayout:midAt(1, 1) == 0x284, "table id on a non-grass cell is left alone") +check(def.midLayout:midAt(0, 2) == 0x3FF, "player's elevation-0 cell does not drive the cut elevation") +check(def.midLayout:midAt(0, 1) == 0x001 and def.midLayout:midAt(1, 3) == 0x001, "field branch mows through Field.setMetatile") +check(def.midLayout.overrides[2 * 1024 - 1] == nil and def.midLayout.overrides[1 * 1024 - 1] == nil, + "no write outside the map") +check(#events == 4, "every mowed cell raises world.block_replaced") +check(Field.metatileOverrideAt("FR_CUT_TEST", 1, 2) ~= nil, "override is recorded for the map") +check(grassCb == 1 and Field.locked == false, "leaf animation runs and unlocks the field") + +Field.clearMetatiles(def.midLayout) +check(def.midLayout:midAt(1, 2) == 0x00D, "map reload grows the grass back") + +os.exit(failures == 0 and 0 or 1) diff --git a/tests/game3_multi_connection_test.lua b/tests/game3_multi_connection_test.lua new file mode 100644 index 00000000..9066d28c --- /dev/null +++ b/tests/game3_multi_connection_test.lua @@ -0,0 +1,171 @@ +package.path = "./?.lua;./?/init.lua;" .. package.path + +local Connections = require("src.core.game3.connections") +local Map = require("src.core.game3.map") +local Collision = require("src.core.game3.collision") +local Itemfinder = require("src.core.game3.itemfinder") + +local failures = 0 +local function check(ok, label) + print((ok and "PASS " or "FAIL ") .. label) + if not ok then failures = failures + 1 end +end + +local function layout(tag, w, h) + local L = { width = w, height = h, pair = tag } + function L:midAt(x, y) return tag .. ":" .. x .. "," .. y end + function L:collAt() return 0 end + return L +end + +local function def(tag, w, h, conns) + return { id = tag, midLayout = layout(tag, w, h), pair = tag, connections = conns or {} } +end + +local maps = { + SRC = def("SRC", 24, 100, { + { dir = "west", map = "GREEN", offset = 0 }, + { dir = "west", map = "SIX", offset = 40 }, + { dir = "west", map = "RUIN", offset = 80 }, + { dir = "north", map = "TOP", offset = 0 }, + }), + GREEN = def("GREEN", 72, 20), + SIX = def("SIX", 24, 30, { { dir = "east", map = "SRC", offset = -40 } }), + RUIN = def("RUIN", 48, 40), + TOP = def("TOP", 24, 10), + KEYED = def("KEYED", 10, 10, { east = { map = "SIX", offset = 2 }, left = { map = "GREEN", offset = 0 } }), +} +local game = { data = { maps = maps } } + +local each = Connections.each(maps.SRC) +check(#each == 4 and each[1].map == "GREEN" and each[2].map == "SIX" and each[3].map == "RUIN" + and each[4].dir == "north", "list form keeps ROM order") +local keyed = Connections.each(maps.KEYED) +check(#keyed == 2 and keyed[1].dir == "east" and keyed[1].offset == 2 + and keyed[2].dir == "west" and keyed[2].map == "GREEN", "keyed form still resolves") + +local function destOf(id) return maps[id] end +for _, row in ipairs({ { 10, "GREEN" }, { 50, "SIX" }, { 90, "RUIN" } }) do + local c = Connections.incoming(maps.SRC, "left", 0, row[1], destOf) + check(c and c.map == row[2], "incoming west row " .. row[1] .. " -> " .. row[2]) +end +check(Connections.incoming(maps.SRC, "west", 0, 30, destOf) == nil, "incoming gap row 30 has no connection") +check(Connections.incoming(maps.SRC, "east", 23, 10, destOf) == nil, "incoming east with no east connection") +local c20 = Connections.incoming(maps.SRC, "west", 0, 20, destOf) +check(c20 and c20.map == "GREEN", "incoming bound is inclusive like fieldmap.c:724") + +Map.loadNeighborsDepth1(game, maps.SRC) +check(#Map.neighborList == 4, "neighborList has every connection") +check(Map.neighbors.west and Map.neighbors.west.map == "GREEN", "neighbors[dir] keeps the first entry") +check(Map.worldMidAt(-1, 10, maps.SRC) == "GREEN:71,10", "west row 10 draws Green Path") +check(Map.worldMidAt(-1, 50, maps.SRC) == "SIX:23,10", "west row 50 draws Six Island") +check(Map.worldMidAt(-3, 95, maps.SRC) == "RUIN:45,15", "west row 95 draws Ruin Valley") +local _, _, void = Map.worldMidAt(-1, 30, maps.SRC) +check(void == true, "west gap row draws border") + +local world = Map.computeWorld(maps, "SRC", 1, nil, nil) +local placed = {} +for _, e in ipairs(world) do placed[e.id] = e end +check(placed.GREEN and placed.GREEN.ox == -72 and placed.GREEN.oy == 0, "computeWorld places Green Path") +check(placed.SIX and placed.SIX.ox == -24 and placed.SIX.oy == 40, "computeWorld places Six Island") +check(placed.RUIN and placed.RUIN.ox == -48 and placed.RUIN.oy == 80, "computeWorld places Ruin Valley") + +local conn = Connections.incoming(maps.SRC, "west", 0, 50, destOf) +local lx, ly = Collision.connectionLanding(maps.SIX, conn, "left", 0, 50) +check(lx == 23 and ly == 10, "landing on Six Island at (23,10)") +check(Collision.connectionLanding(maps.SIX, conn, "left", 0, 70) == nil, "landing outside the span is refused, not clamped") +local back = Connections.incoming(maps.SIX, "right", 23, 10, destOf) +local bx, by = Collision.connectionLanding(maps.SRC, back, "right", 23, 10) +check(back and back.map == "SRC" and bx == 0 and by == 50, "Six Island east lands on the source at row 50") + +local n, nx, ny = Connections.atPos(Map.neighborList, -2, 45, 24, 100) +check(n and n.map == "SIX" and nx == 22 and ny == 5, "atPos resolves the covering west connection") +check(Connections.atPos(Map.neighborList, -2, 75, 24, 100) == nil, "atPos gap row has none") + +local events = { + SIX = { { type = "hidden_item", x = 22, y = 5 } }, + GREEN = {}, + RUIN = { { type = "hidden_item", x = 47, y = 1 } }, +} +local scan = Itemfinder.scan({ + px = 1, py = 46, events = {}, flagSet = function() return false end, + width = 24, height = 100, neighborList = Map.neighborList, + eventsFor = function(id) return events[id] or {} end, +}) +check(scan ~= nil, "itemfinder sees a hidden item on the middle west connection") +local scanRuin = Itemfinder.scan({ + px = 1, py = 84, events = {}, flagSet = function() return false end, + width = 24, height = 100, neighborList = Map.neighborList, + eventsFor = function(id) return events[id] or {} end, +}) +check(scanRuin ~= nil, "itemfinder sees a hidden item on the last west connection") + +check(Map.worldMidAt(2, -2, maps.SRC) == "TOP:2,8", "north row draws the north connection") + +require("src.core.GameVersion").set("firered") +local Cache = require("tests.game3_cache") +if not Cache.mount("connections.lua", { native = true }) then + print("[skip] game3_multi_connection_test cache section: " .. tostring(Cache.reason)) + os.exit(failures == 0 and 0 or 1) +end + +local Dataset = require("src.core.game3.dataset") +local Player = require("src.core.game3.player") +local Runtime = require("src.core.game3.runtime") +local Field = require("src.core.game3.field") +local Ghosts = require("src.core.game3.ghosts") +local Space = require("src.core.game3.scripting.space") +local rgame = { data = {}, save = {}, session = { flags = {}, vars = {} } } +Dataset.hydrate(rgame) +Runtime.session = rgame.session +Field._game, Field._session, Field.running = rgame, rgame.session, true +Space.runEnterScripts = function() end +Space.vm = nil + +local function setup(map, x, y, dir) + Ghosts.clear() + Map.load(nil, rgame, map, { x = x, y = y, facing = dir }) + rgame.session = Runtime.getSession() + rgame.session.x, rgame.session.y = Player.cellX, Player.cellY + Field.locked = false + Player.surfing, Player.elevation = false, 3 +end +local function finishStep() + Player._onStepDone = function() end + for _ = 1, 32 do + if not Player.moving then break end + Player.tick(rgame) + end +end + +local WP = "FR_SIX_ISLAND_WATER_PATH" +local wpDef = rgame.data.maps[WP] +local west = {} +for _, c in ipairs(Connections.each(wpDef)) do + if c.dir == "west" then west[#west + 1] = c.map .. "@" .. c.offset end +end +check(table.concat(west, " ") == "FR_SIX_ISLAND_GREEN_PATH@0 FR_SIX_ISLAND@40 FR_SIX_ISLAND_RUIN_VALLEY@80", + "cache Water Path west connections in ROM order") + +setup("FR_SIX_ISLAND", 23, 12, "right") +check(Player.tryMove("right", rgame, false) == "connection", "Six Island east crosses") +finishStep() +check(Map.current == WP and Player.cellX == 0 and Player.cellY == 52, "Six Island east lands on Water Path (0,52)") +check(#Map.neighborList == 3, "Water Path loads all three west neighbors") +local mid, _, void = Map.worldMidAt(-1, 52, wpDef) +check(mid ~= nil and not void and mid == rgame.data.maps.FR_SIX_ISLAND.midLayout:midAt(23, 12), + "Water Path west of row 52 draws Six Island") + +for _, r in ipairs({ + { 52, "FR_SIX_ISLAND", 23, 12 }, + { 10, "FR_SIX_ISLAND_GREEN_PATH", 71, 10 }, + { 90, "FR_SIX_ISLAND_RUIN_VALLEY", 47, 10 }, +}) do + setup(WP, 0, r[1], "left") + check(Player.tryMove("left", rgame, false) == "connection", "Water Path row " .. r[1] .. " crosses west") + finishStep() + check(Map.current == r[2] and Player.cellX == r[3] and Player.cellY == r[4], + "Water Path row " .. r[1] .. " lands on " .. r[2]) +end + +os.exit(failures == 0 and 0 or 1) diff --git a/tests/game3_objects_flag_sync_test.lua b/tests/game3_objects_flag_sync_test.lua index 9f755b2a..87e1d994 100644 --- a/tests/game3_objects_flag_sync_test.lua +++ b/tests/game3_objects_flag_sync_test.lua @@ -179,6 +179,95 @@ check(Objects.find(AIDE).visible, "mid-map setflag leaves the in-view aide drawn Space.bundle, Space.vm, Space.store = saved.bundle, saved.vm, saved.store Space.mapId, Space.active = saved.mapId, saved.active +local PEWTER = "FR_PEWTER_CITY" +local GYM_GUIDE, MUSEUM_GUIDE = 5, 2 +local FLAG_HIDE_GYM_GUIDE, FLAG_HIDE_MUSEUM_GUIDE = 0x2E, 0x2F +local function pewterDef() + return { + midLayout = { width = 50, height = 40 }, + objects = { + { localId = MUSEUM_GUIDE, graphicsId = 30, x = 33, y = 17, movementType = 8, flag = FLAG_HIDE_MUSEUM_GUIDE }, + { localId = GYM_GUIDE, graphicsId = 30, x = 42, y = 20, movementType = 8, flag = FLAG_HIDE_GYM_GUIDE }, + }, + } +end +local function freshPewter() + Objects.reset() + Objects.loadMap(nil, PEWTER, pewterDef()) +end +local function strand(lid, x, y, facing) + local eo = Objects.find(lid) + eo.cellX, eo.cellY, eo.targetX, eo.targetY = x, y, x, y + eo.px, eo.py = x * 16, y * 16 + eo.facing = facing + eo.frozen, eo.scriptBusy = true, true + if eo.def then eo.def.x, eo.def.y = x, y end + Objects._tracks[lid] = { done = false } + return eo +end +local function atTemplate(lid, x, y, label) + local eo = Objects.find(lid) + check(eo and eo.visible and not eo.hidden, label .. ": visible") + check(eo and eo.cellX == x and eo.cellY == y, label .. string.format(": at template (%d,%d), got (%s,%s)", + x, y, tostring(eo and eo.cellX), tostring(eo and eo.cellY))) + check(eo and eo.homeX == x and eo.homeY == y and eo.px == x * 16 and eo.py == y * 16, label .. ": home/px reset") + check(eo and eo.facing == "down", label .. ": template facing down, got " .. tostring(eo and eo.facing)) + check(eo and not eo.moving and not eo.frozen and not eo.scriptBusy, label .. ": idle") + check(Objects._tracks[lid] == nil, label .. ": no stale track") +end + +print("[test] 8. removeobject + clearflag respawns the Pewter gym guide at his template cell") +freshPewter() +placePlayer(15, 18) +local stale = strand(GYM_GUIDE, 7, 19, "left") +Objects.removeObject(GYM_GUIDE) +Objects.syncFlagVisibility(FLAG_HIDE_GYM_GUIDE, false) +atTemplate(GYM_GUIDE, 42, 20, "gym guide") +check(Objects.find(GYM_GUIDE) ~= stale, "gym guide is a fresh object") + +print("[test] 9. museum guide sibling") +freshPewter() +placePlayer(20, 17) +strand(MUSEUM_GUIDE, 24, 15, "up") +Objects.removeObject(MUSEUM_GUIDE) +Objects.syncFlagVisibility(FLAG_HIDE_MUSEUM_GUIDE, false) +atTemplate(MUSEUM_GUIDE, 33, 17, "museum guide") + +print("[test] 10. removeobject + addobject respawns from the template too") +freshPewter() +placePlayer(15, 18) +strand(GYM_GUIDE, 7, 19, "left") +Objects.removeObject(GYM_GUIDE) +check(Objects.addObject(GYM_GUIDE), "addobject ok") +atTemplate(GYM_GUIDE, 42, 20, "addobject gym guide") +local n = 0 +for _, id in ipairs(Objects._order) do if id == GYM_GUIDE then n = n + 1 end end +check(n == 1, "gym guide listed once in draw order") + +print("[test] 11. a perm row still places the respawn (Oak's lab shape)") +freshPewter() +placePlayer(15, 18) +strand(GYM_GUIDE, 7, 19, "left") +Objects.removeObject(GYM_GUIDE) +Objects.setObjectXY(GYM_GUIDE, 6, 3) +Objects.setMovementType(GYM_GUIDE, 8) +Objects.syncFlagVisibility(FLAG_HIDE_GYM_GUIDE, false) +local permEo = Objects.find(GYM_GUIDE) +check(permEo.visible and permEo.cellX == 6 and permEo.cellY == 3 and permEo.facing == "down", + "perm row wins over the template") + +print("[test] 12. clearflag leaves an active object where it is") +freshPewter() +placePlayer(15, 18) +local live = strand(GYM_GUIDE, 16, 18, "left") +live.frozen, live.scriptBusy = false, false +Objects._tracks[GYM_GUIDE] = nil +Objects.rememberPerm(PEWTER, GYM_GUIDE, { x = 6, y = 3, movementType = 7 }) +Objects.syncFlagVisibility(FLAG_HIDE_GYM_GUIDE, false) +check(Objects.find(GYM_GUIDE) == live and live.cellX == 16 and live.cellY == 18 and live.facing == "left", + "active gym guide untouched by clearflag") +check(Objects.addObject(GYM_GUIDE) and Objects.find(GYM_GUIDE) == live, "addobject on an active object is a no-op") + if failed > 0 then print("[test] FAILED " .. failed) os.exit(1) diff --git a/tests/parity_yellow_pikapic_pose_2347.lua b/tests/parity_yellow_pikapic_pose_2347.lua new file mode 100644 index 00000000..f5712758 --- /dev/null +++ b/tests/parity_yellow_pikapic_pose_2347.lua @@ -0,0 +1,181 @@ +package.path = "./?.lua;./?/init.lua;" .. package.path + +local CacheContract = require("src.import.CacheContract") + +local LABELS = { + "e4841", "e4ce0", "e4e70", "e50af", "e52fe", "e5541", "e5794", "e59ed", + "e5c4d", "e5e90", "e6020", "e61b0", "e63f7", "e6646", "e682f", "e69bf", + "e6b4f", "e6cdf", "e6e6f", "e6fff", "e718f", "e731f", "e74af", "e763f", + "e7863", "e79f3", "e7b83", "e7d13", "f0b64", "f0d82", +} + +local function skip(why) + print("[skip] parity_yellow_pikapic_pose_2347: " .. why) + os.exit(0) +end + +local function readAll(path) + local f = io.open(path, "rb") + if not f then return nil end + local data = f:read("*a") + f:close() + return data +end + +local required = {} +for _, path in ipairs(CacheContract.VERSION_REQUIRED_FILES.yellow) do + required[path] = true +end +local missingContract = {} +for _, label in ipairs(LABELS) do + local path = "assets/generated/pikachu/gfx_" .. label .. ".png" + if not required[path] then missingContract[#missingContract + 1] = path end +end +if #missingContract > 0 then + error("VERSION_REQUIRED_FILES.yellow is missing " .. table.concat(missingContract, " ")) +end + +local function cacheRoot() + local env = os.getenv("YELLOW_CACHE") + if env and env ~= "" then return env end + local home = os.getenv("HOME") or "" + local identity = os.getenv("POKEPORT_IDENTITY") + local names = {} + if identity and identity ~= "" then names[#names + 1] = identity end + names[#names + 1] = "pokemon-love2d" + for _, name in ipairs(names) do + for _, base in ipairs({ home .. "/Library/Application Support/LOVE", home .. "/.local/share/love" }) do + local root = base .. "/" .. name .. "/yellow" + local marker = readAll(root .. "/rom-cache.complete") + if marker and marker:sub(1, #CacheContract.VERSION_FORMAT.yellow) + == CacheContract.VERSION_FORMAT.yellow then + return root + end + end + end +end + +local root = cacheRoot() +if not root then skip("no current Yellow cache") end +local PRET = "../pokeyellow/gfx/pikachu" +if not readAll(PRET .. "/unknown_e79f3.png") then skip("no ../pokeyellow checkout") end + +local okFfi, ffi = pcall(require, "ffi") +if not okFfi then skip("no ffi") end +pcall(ffi.cdef, [[ +int uncompress(uint8_t *dest, unsigned long *destLen, const uint8_t *source, unsigned long sourceLen); +]]) +local zlib +for _, name in ipairs({ "z", "libz.so.1", "libz.1.dylib" }) do + local ok, lib = pcall(ffi.load, name) + if ok then zlib = lib break end +end +if not zlib then skip("no zlib") end + +local function be32(s, i) + local a, b, c, d = s:byte(i, i + 3) + return ((a * 256 + b) * 256 + c) * 256 + d +end + +local function paeth(a, b, c) + local p = a + b - c + local pa, pb, pc = math.abs(p - a), math.abs(p - b), math.abs(p - c) + if pa <= pb and pa <= pc then return a end + if pb <= pc then return b end + return c +end + +local function decodeShades(path) + local data = assert(readAll(path), path) + assert(data:sub(1, 8) == "\137PNG\r\n\26\n", path .. " is not a png") + local pos, idat = 9, {} + local width, height, depth, colorType, interlace + while pos <= #data do + local len = be32(data, pos) + local kind = data:sub(pos + 4, pos + 7) + local body = data:sub(pos + 8, pos + 7 + len) + if kind == "IHDR" then + width, height = be32(body, 1), be32(body, 5) + depth, colorType, interlace = body:byte(9), body:byte(10), body:byte(13) + elseif kind == "IDAT" then + idat[#idat + 1] = body + end + pos = pos + 12 + len + end + assert(interlace == 0, path .. " is interlaced") + local channels = ({ [0] = 1, [2] = 3, [4] = 2, [6] = 4 })[colorType] + assert(channels and (colorType == 0 or depth == 8), + ("%s: unsupported png type %d depth %d"):format(path, colorType, depth)) + local bitsPerPixel = channels * depth + local stride = math.ceil(width * bitsPerPixel / 8) + local bpp = math.max(1, bitsPerPixel / 8) + local src = table.concat(idat) + local outLen = height * (stride + 1) + local out = ffi.new("uint8_t[?]", outLen) + local destLen = ffi.new("unsigned long[1]", outLen) + assert(zlib.uncompress(out, destLen, src, #src) == 0, path .. ": inflate failed") + local rows, prev = {}, {} + for x = 1, stride do prev[x] = 0 end + for y = 0, height - 1 do + local base = y * (stride + 1) + local filter = out[base] + local row = {} + for x = 1, stride do + local raw = out[base + x] + local left = x > bpp and row[x - bpp] or 0 + local up = prev[x] + local upLeft = x > bpp and prev[x - bpp] or 0 + local v + if filter == 0 then v = raw + elseif filter == 1 then v = raw + left + elseif filter == 2 then v = raw + up + elseif filter == 3 then v = raw + math.floor((left + up) / 2) + elseif filter == 4 then v = raw + paeth(left, up, upLeft) + else error(path .. ": bad filter " .. filter) end + row[x] = v % 256 + end + rows[y + 1] = row + prev = row + end + local shades = {} + local maxGray = 2 ^ depth - 1 + for y = 1, height do + local row = rows[y] + for x = 0, width - 1 do + local gray, alpha + if colorType == 0 then + local bit = x * depth + local byte = row[math.floor(bit / 8) + 1] + local shift = 8 - depth - bit % 8 + gray = math.floor(byte / 2 ^ shift) % (maxGray + 1) / maxGray + alpha = 1 + else + local i = x * channels + 1 + gray = row[i] / 255 + alpha = (colorType == 4 and row[i + 1] or colorType == 6 and row[i + 3] or 255) / 255 + end + shades[#shades + 1] = { 3 - math.floor(gray * 3 + 0.5), alpha } + end + end + return shades, width, height +end + +local failures = 0 +for _, label in ipairs(LABELS) do + local mine, w, h = decodeShades(root .. "/assets/generated/pikachu/gfx_" .. label .. ".png") + local pret, pw, ph = decodeShades(PRET .. "/unknown_" .. label .. ".png") + local diff, translucent = 0, 0 + for i = 1, #pret do + if mine[i][1] ~= pret[i][1] then diff = diff + 1 end + if mine[i][2] < 1 then translucent = translucent + 1 end + end + local ok = w == 40 and h == 40 and pw == 40 and ph == 40 and diff == 0 and translucent == 0 + print(("%s gfx_%s: %d shade diffs, %d non-opaque pixels"):format( + ok and "PASS" or "FAIL", label, diff, translucent)) + if not ok then failures = failures + 1 end +end + +if failures > 0 then + error(("parity_yellow_pikapic_pose_2347: %d pose(s) differ from pret"):format(failures)) +end +print("parity_yellow_pikapic_pose_2347: all 30 poses match pret") diff --git a/tests/run_tests.lua b/tests/run_tests.lua index 918c4657..652ecd31 100644 --- a/tests/run_tests.lua +++ b/tests/run_tests.lua @@ -2448,10 +2448,25 @@ do StateStack:update(1 / 60) Input.pressed = {} end + local function waitTop(pred) + for _ = 1, 600 do + if pred(StateStack:top()) then return true end + StateStack:update(1 / 60) + end + return pred(StateStack:top()) + end + check(StateStack:top() ~= shop and StateStack:top().isTextBox, + "the greeting types before BUY/SELL/QUIT (text_script.asm:141-150)") + check(waitTop(function(t) return t == shop end), "the greeting hands over to the mart menu") press("a") -- BUY check(StateStack:top() ~= shop, "BUY opens the buy list") + eq(shop.hollowIndex, 1, "BUY leaves a hollow cursor (text_box.asm:176)") + check(waitTop(function(t) return t ~= nil and t.onChoose ~= nil end), + "the buy list follows Take your time.") press("b") -- close the list - eq(StateStack:top(), shop, "closing the list returns to the mart menu") + check(waitTop(function(t) return t == shop end), "closing the list returns to the mart menu") + eq(shop.index, 1, "the mart menu cursor is back on BUY (pokemart.asm:10)") + eq(shop.hollowIndex, nil, "and filled again") press("down") press("down") press("a") -- QUIT @@ -2459,6 +2474,8 @@ do local goodbye = StateStack:top() check(goodbye ~= shop and goodbye.isTextBox, "QUIT prints _PokemartThankYouText") + eq(StateStack.states[#StateStack.states - 1], shop, + "the mart menu stays under the goodbye (pokemart.asm:220)") for _ = 1, 600 do if quitCalled then break end press("a") @@ -2487,8 +2504,16 @@ end Game.save.inventory = { GREAT_BALL = 5, HYPER_POTION = 99 } local sellShop = require("src.ui.ShopMenu").new(Game, { "POTION" }, function() end) StateStack:push(sellShop) + for _ = 1, 600 do + if StateStack:top() == sellShop then break end + StateStack:update(1 / 60) + end Input.pressed = { down = true }; StateStack:update(1 / 60); Input.pressed = {} Input.pressed = { a = true }; StateStack:update(1 / 60); Input.pressed = {} + for _ = 1, 600 do + if StateStack:top() ~= sellShop and StateStack:top().items then break end + StateStack:update(1 / 60) + end local sellList = StateStack:top() local foundHyper for _, it in ipairs(sellList.items or {}) do diff --git a/tests/save_convert_tests.lua b/tests/save_convert_tests.lua index eb7dfc1e..b4ddeaf0 100644 --- a/tests/save_convert_tests.lua +++ b/tests/save_convert_tests.lua @@ -295,8 +295,8 @@ check(scSave and scSave.player and scSave.player.id == 12345, check(scSave and scSave.inventory and scSave.inventory.POKE_BALL == 5, "SaveConvert.importSav: decoded bag items survive the merge") -- merge over new-game defaults -check(scSave and type(scSave.options) == "table" and scSave.options.ruleset == "gen1_faithful", - "SaveConvert.importSav: new-game default options merged in") +check(scSave and scSave.options == nil, + "SaveConvert.importSav: no options table rides the imported save") check(scSave and type(scSave.defeatedTrainers) == "table" and type(scSave.modData) == "table" and scSave.repelSteps == 0, "SaveConvert.importSav: default defeatedTrainers/modData/repelSteps merged in") diff --git a/tests/save_convert_yellow_bug838_test.lua b/tests/save_convert_yellow_bug838_test.lua index f591bf00..5c8a1187 100644 --- a/tests/save_convert_yellow_bug838_test.lua +++ b/tests/save_convert_yellow_bug838_test.lua @@ -53,6 +53,7 @@ local yellowData = { local stampMapWindow = loadfile("tests/fixture_data/map_window.lua")() for mapId in pairs(shared.maps) do stampMapWindow(redData, mapId) end yellowData.tilesets, yellowData.audio = redData.tilesets, redData.audio +yellowData.encounters = redData.encounters local OFF = GenSave.OFFSETS diff --git a/tools/make_yellow_manifest.py b/tools/make_yellow_manifest.py index 10988433..66f58ed0 100755 --- a/tools/make_yellow_manifest.py +++ b/tools/make_yellow_manifest.py @@ -119,6 +119,13 @@ YELLOW_EXTRA_SYMBOLS = ( "Pic_e5b7d", "Pic_e5ddd", "GFX_e6020", "Pic_e6340", "Pic_e6587", "Pic_e67d6", "GFX_e6e6f", "GFX_e718f", "GFX_e74af", "Pic_e77cf", "Pic_f0abf", "Pic_f0cf4", + # data/pikachu/pikachu_pic_animation.asm:340 + "GFX_e4841", "GFX_e4ce0", "GFX_e4e70", "GFX_e50af", "GFX_e52fe", + "GFX_e5541", "GFX_e5794", "GFX_e59ed", "GFX_e5c4d", "GFX_e5e90", + "GFX_e61b0", "GFX_e63f7", "GFX_e6646", "GFX_e682f", "GFX_e69bf", + "GFX_e6b4f", "GFX_e6cdf", "GFX_e6fff", "GFX_e731f", "GFX_e763f", + "GFX_e7863", "GFX_e79f3", "GFX_e7b83", "GFX_e7d13", "GFX_f0b64", + "GFX_f0d82", # Yellow-only overworld player surf sprite, loaded outside # SpriteSheetPointerTable (LoadSurfingPlayerSpriteGraphics2) -- # needs its own extract like RedBikeSprite. (RFC 0001) diff --git a/tools/rom_manifest_yellow.json b/tools/rom_manifest_yellow.json index 5db89265..6b1615ff 100644 --- a/tools/rom_manifest_yellow.json +++ b/tools/rom_manifest_yellow.json @@ -21781,22 +21781,126 @@ 29, 18588 ], + "GFX_e4841": [ + 57, + 18497 + ], + "GFX_e4ce0": [ + 57, + 19680 + ], + "GFX_e4e70": [ + 57, + 20080 + ], + "GFX_e50af": [ + 57, + 20655 + ], + "GFX_e52fe": [ + 57, + 21246 + ], + "GFX_e5541": [ + 57, + 21825 + ], + "GFX_e5794": [ + 57, + 22420 + ], + "GFX_e59ed": [ + 57, + 23021 + ], + "GFX_e5c4d": [ + 57, + 23629 + ], + "GFX_e5e90": [ + 57, + 24208 + ], "GFX_e6020": [ 57, 24608 ], + "GFX_e61b0": [ + 57, + 25008 + ], + "GFX_e63f7": [ + 57, + 25591 + ], + "GFX_e6646": [ + 57, + 26182 + ], + "GFX_e682f": [ + 57, + 26671 + ], + "GFX_e69bf": [ + 57, + 27071 + ], + "GFX_e6b4f": [ + 57, + 27471 + ], + "GFX_e6cdf": [ + 57, + 27871 + ], "GFX_e6e6f": [ 57, 28271 ], + "GFX_e6fff": [ + 57, + 28671 + ], "GFX_e718f": [ 57, 29071 ], + "GFX_e731f": [ + 57, + 29471 + ], "GFX_e74af": [ 57, 29871 ], + "GFX_e763f": [ + 57, + 30271 + ], + "GFX_e7863": [ + 57, + 30819 + ], + "GFX_e79f3": [ + 57, + 31219 + ], + "GFX_e7b83": [ + 57, + 31619 + ], + "GFX_e7d13": [ + 57, + 32019 + ], + "GFX_f0b64": [ + 60, + 19300 + ], + "GFX_f0d82": [ + 60, + 19842 + ], "GamblerPic": [ 19, 21537 From f3f2e3b0b3408bfff9392abd67fe5cd2d6ef0b68 Mon Sep 17 00:00:00 2001 From: bryanthaboi Date: Fri, 25 Sep 2026 07:25:23 -0400 Subject: [PATCH 3/6] save editor options test runs on fixture data --- tests/engine/save_editor_options_2388.lua | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/tests/engine/save_editor_options_2388.lua b/tests/engine/save_editor_options_2388.lua index d7fbe58a..aebd96f8 100644 --- a/tests/engine/save_editor_options_2388.lua +++ b/tests/engine/save_editor_options_2388.lua @@ -25,6 +25,23 @@ local App = require("App") local fs = love.filesystem +local ffi = require("ffi") +local setVar +if ffi.os == "Windows" then + ffi.cdef([[ int _putenv(const char *envstring); ]]) + setVar = function(name, value) ffi.C._putenv(name .. "=" .. value) end +else + ffi.cdef([[ + int setenv(const char *name, const char *value, int overwrite); + int unsetenv(const char *name); + ]]) + setVar = function(name, value) + if value == "" then ffi.C.unsetenv(name) else ffi.C.setenv(name, value, 1) end + end +end +local originalDataDir = os.getenv("POKEPORT_DATA_DIR") +setVar("POKEPORT_DATA_DIR", "tests/fixture_data") + do local opts = SaveData.loadOptions() opts.battleLayout, opts.battleFit, opts.battleHud, opts.battleBg = "wide", "fixed", "extended", "world" @@ -98,5 +115,7 @@ do end end +setVar("POKEPORT_DATA_DIR", originalDataDir or "") + print(string.format("save editor options 2388: %d passed, %d failed", passed, failed)) if failed > 0 then os.exit(1) end From a685f16e00595ab39f31b409ddf6e71507dfc950 Mon Sep 17 00:00:00 2001 From: bryanthaboi Date: Fri, 25 Sep 2026 10:28:21 -0400 Subject: [PATCH 4/6] updates to online --- docs/modding.md | 33 +- docs/new-features.md | 2 + mod_option_schemas.json | 2 +- src/core/FixedStep.lua | 12 + src/core/Game.lua | 43 +- src/core/Game2.lua | 32 +- src/core/Game3.lua | 53 +- src/core/game3/dataset.lua | 1 + src/core/game3/field_view.lua | 123 +- src/core/game3/link/union_plaza_map.lua | 213 ++++ src/core/game3/link/union_room.lua | 1039 +++++------------ src/core/game3/objects.lua | 51 +- src/core/game3/save_schema_firered.lua | 19 + src/core/game3/scripting/adapters.lua | 6 + src/core/game3/virtual_objects.lua | 9 + src/import/LauncherSettings.lua | 8 - src/link/Wire.lua | 6 +- src/mods/Loader.lua | 5 +- src/online/Client.lua | 17 +- src/online/Protocol2.lua | 9 +- src/render/BattleTransition.lua | 1 + src/ui/OptionsMenu.lua | 16 +- src/ui/game3/bag_menu.lua | 2 +- src/ui/game3/option_rows.lua | 3 +- src/ui/game3/start_menu.lua | 2 +- src/ui/game3/union_room.lua | 8 +- src/ui/game3/wireless_icon.lua | 1 + src/ui/gen2/BattleState.lua | 1 + src/ui/gen2/BattleTransition.lua | 1 + .../drivers/battle_cry_speed_bug2087_test.lua | 24 +- .../battle_fanfare_speed_bug1952_test.lua | 36 +- tests/drivers/g3link_union_plaza.lua | 103 +- tests/drivers/g3link_union_plaza_live.lua | 228 ++++ tests/drivers/g3link_union_plaza_perf.lua | 196 ++++ tests/drivers/g3link_union_room.lua | 57 +- tests/drivers/game3_link_union_room.lua | 105 +- tests/drivers/game3_union_plaza_map.lua | 107 ++ .../gold_fanfare_speed_bug1952_test.lua | 12 +- tests/drivers/speed_lock_firered.lua | 149 +++ tests/drivers/speed_lock_gold.lua | 102 ++ tests/drivers/speed_lock_red.lua | 87 ++ tests/engine/game3_speed_hotkey_test.lua | 48 + .../game3_virtual_objects_drawhook_test.lua | 16 + tests/engine/game_speed_categories_test.lua | 26 +- tests/engine/gen2_logic_speed_bug1994.lua | 32 + tests/engine/options_submenu_marquee_test.lua | 6 +- tests/engine/speed_lock_test.lua | 188 +++ tests/g3link_fake_relay.lua | 2 +- tests/game3_link_continue_warp_test.lua | 20 + tests/game3_link_relay_union_test.lua | 321 +++-- tests/game3_link_union_test.lua | 188 +-- tests/game3_union_plaza_map_test.lua | 199 ++++ tests/mod_ui_tests.lua | 2 +- tests/online_client_gen3.lua | 13 +- tests/run_tests.lua | 8 +- tests/support/fake_relay.lua | 27 +- tools/run_driver.sh | 10 +- 57 files changed, 2694 insertions(+), 1336 deletions(-) create mode 100644 src/core/game3/link/union_plaza_map.lua create mode 100644 tests/drivers/g3link_union_plaza_live.lua create mode 100644 tests/drivers/g3link_union_plaza_perf.lua create mode 100644 tests/drivers/game3_union_plaza_map.lua create mode 100644 tests/drivers/speed_lock_firered.lua create mode 100644 tests/drivers/speed_lock_gold.lua create mode 100644 tests/drivers/speed_lock_red.lua create mode 100644 tests/engine/speed_lock_test.lua create mode 100644 tests/game3_union_plaza_map_test.lua diff --git a/docs/modding.md b/docs/modding.md index 88d107c1..a90aacaf 100644 --- a/docs/modding.md +++ b/docs/modding.md @@ -1212,9 +1212,9 @@ identifiers: `pc_box_withdraw`, `pc_box_deposit`, `pc_box_release`, control the battle text/menu layer and the HP/status panels. Both receive `(next, state)` and default to `true`, so vanilla rendering is unchanged. Both hooks apply to Gen 1 and Gen 2 battles. -Text boxes and YES/NO prompts pushed above a battle inherit a `false` result -for that battle, so hiding the bottom layer cannot leave their white backing -behind under another overlay. Text boxes also pass through the hook as their +Text boxes and YES/NO prompts pushed above a battle of either generation +inherit a `false` result for that battle, so hiding the bottom layer cannot +leave their white backing behind under another overlay. Text boxes also pass through the hook as their own state, preserving selective control outside a battle; a wrapper that only owns battle presentation should return `false` only for its active battle or text-box state. @@ -1251,17 +1251,22 @@ level is part of a row label rather than a drawn field. Both are noted in RFC 0019 as follow-ups. `core.logic_speed` receives `(next, game)` once per `Game:logicSpeed()` call -(once per frame). Vanilla behavior resolves the per-category GAME SPEED -option (`GameSpeed.CATEGORIES`: overworld/battle/menu) for whichever -category `Game.speedCategoryInStack` says is active right now. A mod may -call `next(game)` and return its result to pass that resolution through, or -return a different number outright to override it for that frame (a bot mod -forcing 1X for one route segment, say, regardless of the category or saved -option). The result is clamped to the nearest valid `GameSpeed.LEVELS` entry -regardless of what a subscriber returns, so a bad value (0, negative, `nil`) -cannot destabilize the fixed-step accumulator. This hook runs *after* link -play's 1X lock and the `--speed`/equivalent run-argument override, both of -which stay unconditional and are never visible to a subscriber. +(once per frame), but only on frames where the speed is not locked. Every +battle (wild, trainer, link, online, tournament, spectate), link play and a +fixed-speed minigame lock the logic clock to 1X, and `Game:speedLocked()` +is checked before anything else: the hook is never called on those frames, +so it cannot fast-forward a battle. On every other frame vanilla behavior +resolves the per-category GAME SPEED option (`speedOverworld` or +`speedMenu`) for whichever category `Game.speedCategoryInStack` says is +active. A mod may call `next(game)` and return its result to pass that +resolution through, or return a different number outright to override it +for that frame (a bot mod forcing 1X for one route segment, say). The +result is clamped to the nearest valid `GameSpeed.LEVELS` entry regardless +of what a subscriber returns, so a bad value (0, negative, `nil`) cannot +destabilize the fixed-step accumulator. The `--speed`/`POKEPORT_SPEED` +run-argument override also wins over the hook, but not over the lock. +Gen 2 and Gen 3 have no hook; their `logicSpeed()` facades report the +shell's own value, lock included. Developer mode also arms the mod loader's dev tripwire, which flags mods that reach outside their permission set. diff --git a/docs/new-features.md b/docs/new-features.md index 4bdab07f..24e913fa 100644 --- a/docs/new-features.md +++ b/docs/new-features.md @@ -27,6 +27,8 @@ Features intentionally added beyond the original Pokémon Red, Blue, and Yellow * **Filter Find mods by game**, a generation or single-game filter of its own, with every listing showing the games and tags it declares * **Update all** in one press from the MODS tab, installing every outdated mod and every installed cart the index lists ahead of it, with a summary of what failed * **Rebindable GAME SPEED shortcuts**, SPEED - / SPEED + rows in CONTROLS that move the shoulder hotkeys to any pad button or switch them off +* **Fast-forward locks to 1X in battles and link rooms**, every battle, link session and the FireRed/LeafGreen Union Room on every game +* **40-player Union Room** on FireRed and LeafGreen online, a larger square room where every trainer keeps a fixed spot and anyone can be talked to * **Key bar on the touch pad**, a corner toggle that slides out SAVE, LOAD, SPEED, COLOR, TILT and ZOOM for phones with no keyboard * **Save editor item verbs**, sorting the bag and PC by item number or name, filling one stack or every stack to x99, and a coin editor on every game * **Save editor bag / PC move**, a PC / BAG button on every item row that moves the stack across, clamped to the stack and slot caps diff --git a/mod_option_schemas.json b/mod_option_schemas.json index 592ffeba..4002f364 100644 --- a/mod_option_schemas.json +++ b/mod_option_schemas.json @@ -1 +1 @@ -{"mods":[],"schema_version":1} \ No newline at end of file +{"schema_version":1,"mods":[]} \ No newline at end of file diff --git a/src/core/FixedStep.lua b/src/core/FixedStep.lua index 9d8017c6..45c9ae24 100644 --- a/src/core/FixedStep.lua +++ b/src/core/FixedStep.lua @@ -67,6 +67,7 @@ function FixedStep:init(callback) self.suppressCatchup = false self.dtHistory, self.dtSum = nil, 0 self.phasedFor = nil + self.frameBreak = false end FixedStep.maxAccum = MAX_ACCUM @@ -102,11 +103,13 @@ function FixedStep:update(dt, speed) -- called (the hitch itself already ran inside the current step); absorb -- that one frame as a single step instead of the normal accumulator so -- the burst it would otherwise release doesn't play out as a slide. + self.frameBreak = false if self.suppressCatchup then self.suppressCatchup = false self.dtHistory, self.dtSum = nil, 0 self.accum = self.STEP * RESEED_PHASE self.callback(self.STEP) + self.frameBreak = false return end -- Snap/smooth against the wall-clock frame dt first. Game speed is a @@ -155,6 +158,11 @@ function FixedStep:update(dt, speed) while self.accum >= self.STEP - STEP_EPS do self.accum = self.accum - self.STEP self.callback(self.STEP) + if self.frameBreak then + self.frameBreak = false + self.accum = self.accum % self.STEP + break + end if deadline and self.accum >= self.STEP - STEP_EPS and clock() >= deadline then self.accum = self.accum % self.STEP break @@ -162,6 +170,10 @@ function FixedStep:update(dt, speed) end end +function FixedStep:endFrame() + self.frameBreak = true +end + -- Drop any pending catch-up steps and arm the one-frame clamp above. A -- hitch inside one logic step (map seam setMap / song start) makes the -- next real-time dt huge; without this the while-loop above would advance diff --git a/src/core/Game.lua b/src/core/Game.lua index e75225b2..a4230709 100644 --- a/src/core/Game.lua +++ b/src/core/Game.lua @@ -101,7 +101,10 @@ function Game:load(opts) -- apply the persisted audio + display options before anything plays self:applyOptions(self.save.options) - FixedStep:init(function(step) self:step(step) end) + FixedStep:init(function(step) + self:step(step) + self:_speedLockEdge() + end) self.fixedStep = FixedStep local OverworldState = require("src.world.OverworldController") @@ -369,12 +372,7 @@ function Game:_resolveLogicSpeed() return GameSpeed.clamp(opts and opts[key] or GameSpeed.DEFAULT) end --- The logic multiplier for this frame. Read live rather than cached so the --- Options rows take effect immediately; speedOverride is the --speed / --- POKEPORT_SPEED run argument, which wins over the saved option so a bot --- or screenshot run does not depend on whatever the player last chose. -function Game:logicSpeed() - local GameSpeed = require("src.core.GameSpeed") +function Game:speedLocked() -- Link play is always 1X on both machines, and this wins over every other -- source including POKEPORT_SPEED and every per-category option. -- Fast-forward multiplies the logic clock, so a peer at 10X burned a @@ -384,11 +382,30 @@ function Game:logicSpeed() -- either player set this to -- checked here, before the core.logic_speed -- hook ever runs, so a mod cannot defeat it either. if self.linkSession or (self.linkNet and not self.linkNet.closed) then - return 1 + return true, "link" end if Game.isFixedSpeedInStack and Game.isFixedSpeedInStack(self.stack) then - return 1 + return true, "minigame" end + if Game.speedCategoryInStack(self.stack) == "battle" then + return true, "battle" + end + return false +end + +function Game:_speedLockEdge() + if (self._frameSpeed or 1) > 1 and self:speedLocked() then + FixedStep:endFrame() + end +end + +-- The logic multiplier for this frame. Read live rather than cached so the +-- Options rows take effect immediately; speedOverride is the --speed / +-- POKEPORT_SPEED run argument, which wins over the saved option so a bot +-- or screenshot run does not depend on whatever the player last chose. +function Game:logicSpeed() + if self:speedLocked() then return 1 end + local GameSpeed = require("src.core.GameSpeed") if self.speedOverride then return GameSpeed.clamp(self.speedOverride) end -- Clamp here too, not just in _resolveLogicSpeed's vanilla path: a mod's -- core.logic_speed hook can return anything (0, negative, nil, NaN) and @@ -404,6 +421,7 @@ function Game:update(dt) -- Give the accumulator room for one full frame at the current speed, -- or the anti-spiral clamp quietly caps every level above ~15X. local speed = self:logicSpeed() + self._frameSpeed = speed FixedStep.maxAccum = FixedStep.catchupLimit(speed, dt) FixedStep:update(dt, speed) -- Audio runs off real time at a fixed 60Hz regardless of game speed or @@ -783,6 +801,7 @@ end function Game:_cycleSpeed(dir) if not (self.save and self.save.options) then return end + if self:speedLocked() then return end local busy local ow = self.overworld if ow then @@ -794,12 +813,6 @@ function Game:_cycleSpeed(dir) or ow.engaging or ow.emote)) end if busy then return end - -- Cycles whichever category Game.speedCategoryInStack says is active - -- right now (RFC 0007) -- pressing the hotkey during a battle speeds up - -- just the battle, on the overworld just the walk, in a menu just the - -- menu. A single physical control that means "speed up whatever I'm - -- looking at right now" needs no new UI and matches what a player - -- pressing it mid-battle almost certainly wants. local GameSpeed = require("src.core.GameSpeed") local key = GameSpeed.optionKey(Game.speedCategoryInStack(self.stack)) self.save.options[key] = GameSpeed.cycle(self.save.options[key], dir) diff --git a/src/core/Game2.lua b/src/core/Game2.lua index 420540af..c084e56a 100644 --- a/src/core/Game2.lua +++ b/src/core/Game2.lua @@ -1208,7 +1208,12 @@ function Game2:load(opts) self:showCopyright() end + local stepBody FixedStep:init(function(dt) + stepBody(dt) + self:_speedLockEdge() + end) + stepBody = function(dt) -- Tool mods (autoplay, accessibility drivers, input visualizers) act on the -- same fixed-step boundary a physical controller does. Raised HERE, ahead -- of both the AUTO_INPUT arm and Input:step, for the reason Gen 1 raises it @@ -1270,7 +1275,7 @@ function Game2:load(opts) self.world:interact() end self.world:step() - end) + end end function Game2:inFillBoot() @@ -1279,7 +1284,29 @@ function Game2:inFillBoot() return self.phase == "boot" and self.stack:top() ~= nil end +function Game2:speedLocked() + if self.linkSession or (self.linkNet and not self.linkNet.closed) then + return true, "link" + end + local states = self.stack and self.stack.states + for i = #(states or {}), 1, -1 do + local state = states[i] + if state and state.isBattle then return true, "battle" end + if state and (state.isFixedSpeed or state.isMinigame) then + return true, "minigame" + end + end + return false +end + +function Game2:_speedLockEdge() + if (self._frameSpeed or 1) > 1 and self:speedLocked() then + FixedStep:endFrame() + end +end + function Game2:logicSpeed() + if self:speedLocked() then return 1 end return math.max(1, tonumber(self.speedOverride) or tonumber(self.options and self.options.speed) or 1) @@ -1310,6 +1337,7 @@ function Game2:update(dt) -- driver/CLI hook and wins over the saved option. -- pokegold engine/menus/intro_menu.asm:848 IntroSequence: boot cinema runs on the same clock as the overworld local speed = self:logicSpeed() + self._frameSpeed = speed if self.phase == "boot" then FixedStep.maxAccum = FixedStep.catchupLimit(speed, dt) FixedStep:update(dt, speed) @@ -2057,6 +2085,7 @@ function Game2:hotkey(key) if loaded then self:continueGame(loaded) end return true elseif hk == "1" then + if self:speedLocked() then return true end local GameSpeed = require("src.core.GameSpeed") options.speed = GameSpeed.cycle(options.speed, 1) persist() @@ -2391,6 +2420,7 @@ function Game2:applyOptions() end function Game2:_cycleSpeed(dir) + if self:speedLocked() then return end local GameSpeed = require("src.core.GameSpeed") self.options.speed = GameSpeed.cycle(self.options.speed, dir) if self.save then self.save.options = self.options end diff --git a/src/core/Game3.lua b/src/core/Game3.lua index 3abc41d3..7fae71b0 100644 --- a/src/core/Game3.lua +++ b/src/core/Game3.lua @@ -185,6 +185,7 @@ function Game3:load(opts) if opts.arena then FixedStep:init(function(dt) self:fixedUpdate(dt) + self:_speedLockEdge() end) pcall(function() require("src.core.PresentSync").applyFixedStepPeriod() @@ -208,6 +209,7 @@ function Game3:load(opts) FixedStep:init(function(dt) self:fixedUpdate(dt) + self:_speedLockEdge() end) pcall(function() require("src.core.PresentSync").applyFixedStepPeriod() @@ -414,7 +416,7 @@ function Game3:_handleRegisteredItem() if not item then return end -- src/item_menu.c:2025 local Map = package.loaded["src.core.game3.map"] - if Map and Map.current == "FR_UNION_ROOM" then return end + if Map and require("src.core.game3.link.union_room").isUnionMap(Map.current) then return end -- src/overworld.c:2813 local Link = package.loaded["src.core.game3.link"] if type(Link) == "table" and Link.link ~= nil and Link.inLinkRoom() == true then return end @@ -585,8 +587,53 @@ function Game3:isFixedSpeed() return type(MG) == "table" and MG.isActive ~= nil and MG.isActive() == true end +local function unionRoomMap(id) + return require("src.core.game3.link.union_room").isUnionMap(id) +end + +function Game3:speedLocked() + if self:isFixedSpeed() then return true, "link" end + local Battle = package.loaded["src.core.game3.battle"] + if type(Battle) == "table" and Battle.isActive and Battle.isActive() then + return true, "battle" + end + local Transition = package.loaded["src.core.game3.battle_transition"] + if type(Transition) == "table" and Transition.isActive and Transition.isActive() then + return true, "battle" + end + local Union = package.loaded["src.core.game3.link.union_room"] + if type(Union) == "table" and Union.isActive and Union.isActive() then + return true, "link" + end + local LinkMenu = package.loaded["src.ui.game3.link_menu"] + if type(LinkMenu) == "table" then + if LinkMenu.isOpen and LinkMenu.isOpen() then return true, "link" end + local Direct = LinkMenu.Direct + if type(Direct) == "table" and Direct.isOpen and Direct.isOpen() then + return true, "link" + end + end + if self.phase ~= "field" then return false end + local Map = package.loaded["src.core.game3.map"] + if type(Map) == "table" and unionRoomMap(Map.current) then + return true, "link" + end + local Link = package.loaded["src.core.game3.link"] + if type(Link) == "table" and Link.inLinkRoom then + local ok, inRoom = pcall(Link.inLinkRoom) + if ok and inRoom == true then return true, "link" end + end + return false +end + +function Game3:_speedLockEdge() + if (self._frameSpeed or 1) > 1 and self:speedLocked() then + FixedStep:endFrame() + end +end + function Game3:logicSpeed() - if self:isFixedSpeed() then return 1 end + if self:speedLocked() then return 1 end local override = tonumber(self.speedOverride) if override then return math.max(1, override) end local b = self.phase == "boot" and self.boot @@ -603,6 +650,7 @@ end function Game3:_cycleSpeed(dir) if type(self.options) ~= "table" then return end + if self:speedLocked() then return end local GameSpeed = require("src.core.GameSpeed") local key = GameSpeed.optionKey(self:speedCategory()) self.options[key] = GameSpeed.cycle(self.options[key], dir) @@ -633,6 +681,7 @@ end function Game3:update(dt) local speed = self:logicSpeed() + self._frameSpeed = speed FixedStep.maxAccum = FixedStep.catchupLimit(speed, dt) FixedStep:update(dt, speed) self._audioAccum = (self._audioAccum or 0) + dt diff --git a/src/core/game3/dataset.lua b/src/core/game3/dataset.lua index cecc8f73..60db21d3 100644 --- a/src/core/game3/dataset.lua +++ b/src/core/game3/dataset.lua @@ -339,6 +339,7 @@ function Dataset.hydrate(game) Space.ensureBundle(nil) nEvents = Space.attachEventsToMaps(game.data.maps, Space.bundle) or 0 end + require("src.core.game3.link.union_plaza_map").ensure(game) local NativeTileset = require("src.core.game3.tileset_native") if NativeTileset.install then diff --git a/src/core/game3/field_view.lua b/src/core/game3/field_view.lua index babc307e..e4cd954e 100644 --- a/src/core/game3/field_view.lua +++ b/src/core/game3/field_view.lua @@ -433,10 +433,19 @@ local function actorPriority(a) end end +local function sortActors(a, b) + local ay = a.subpriority or a.sortY or a.y + local by = b.subpriority or b.sortY or b.y + if ay == by then return (a.i or 0) < (b.i or 0) end + return ay < by +end + -- event_object_movement.c:8379-8387, scrcmd.c:1130 -local function applyDrawOrder(actors) - local underActors = {} - local overActors = {} +local function applyDrawOrder(actors, underActors, overActors) + underActors = underActors or {} + overActors = overActors or {} + for i = #underActors, 1, -1 do underActors[i] = nil end + for i = #overActors, 1, -1 do overActors[i] = nil end for _, a in ipairs(actors) do local obj = a.eventObject if obj and obj.fixedPriority then @@ -454,18 +463,14 @@ local function applyDrawOrder(actors) underActors[#underActors + 1] = a end end - local function sortActors(a, b) - local ay = a.subpriority or a.sortY or a.y - local by = b.subpriority or b.sortY or b.y - if ay == by then return (a.i or 0) < (b.i or 0) end - return ay < by - end table.sort(underActors, sortActors) table.sort(overActors, sortActors) return underActors, overActors end FieldView.applyDrawOrder = applyDrawOrder +local owOpts = {} + local function drawSingleActor(game, mapDef, a, camX, camY) local daytime = daytimeFor(game, mapDef) local okOw, OwSprites = pcall(require, "src.core.game3.ow_sprites") @@ -478,15 +483,14 @@ local function drawSingleActor(game, mapDef, a, camX, camY) drew = true end if not drew and useOw and a.graphicsId ~= nil then - local opts = { - bow = a.bow, - fieldMove = a.fieldMove, - fieldMoveFrame = a.fieldMoveFrame, - fishing = a.fishing, - fishFrame = a.fishFrame, - frame = a.frame, - running = a.running, - } + local opts = owOpts + opts.bow = a.bow + opts.fieldMove = a.fieldMove + opts.fieldMoveFrame = a.fieldMoveFrame + opts.fishing = a.fishing + opts.fishFrame = a.fishFrame + opts.frame = a.frame + opts.running = a.running drew = OwSprites.draw( a.graphicsId, a.x, a.y, camX, camY, a.facing, a.walkPhase, a.stepFlip, opts) end @@ -509,11 +513,16 @@ local function drawSingleActor(game, mapDef, a, camX, camY) if billboarded then love.graphics.pop() end end +local frameActors, frameUnder, frameOver = {}, {}, {} +local npcActors = setmetatable({}, { __mode = "k" }) +local playerActor = {} + local function collectGame3Actors(game, mapDef, camX, camY, px, py, facing, walkPhase, stepFlip, playerYOff, playerXOff) local okO, Objects = pcall(require, "src.core.game3.objects") local okOw, OwSprites = pcall(require, "src.core.game3.ow_sprites") local useOw = okOw and OwSprites and OwSprites.ready and OwSprites.ready() - local actors = {} + local actors = frameActors + for i = #actors, 1, -1 do actors[i] = nil end local hasObjects = okO and Objects and Objects.hasMap and Objects.hasMap() if hasObjects then @@ -522,23 +531,27 @@ local function collectGame3Actors(game, mapDef, camX, camY, px, py, facing, walk if eo.moving and eo.targetY and eo.targetY > (eo.cellY or 0) then sortY = math.max(sortY, eo.targetY * CELL) end - actors[#actors + 1] = { - kind = "npc", - i = eo.localId, - obj = eo.def, - eventObject = eo, - elevation = eo.elevation or (eo.def and eo.def.elevation) or 0, - x = (eo.px or (eo.cellX * CELL)) + (eo.raiseX or 0), - y = (eo.py or (eo.cellY * CELL)) + (eo.raiseY or 0), - sortY = sortY, - facing = eo.facing or "down", - walkPhase = Objects.walkPhase(eo), - stepFlip = eo.stepFlip and true or false, - bow = (eo.bowFrames and eo.bowFrames > 0) or eo.raiseHand == true, - frame = eo.customFrame, - sprite = eo.sprite or spriteNameForObj(eo.def or {}), - graphicsId = eo.graphicsId or (eo.def and (eo.def.graphicsId or eo.def.graphics)), - } + local a = npcActors[eo] + if not a then + a = { kind = "npc", eventObject = eo } + npcActors[eo] = a + end + a.i = eo.localId + a.obj = eo.def + a.elevation = eo.elevation or (eo.def and eo.def.elevation) or 0 + a.x = (eo.px or (eo.cellX * CELL)) + (eo.raiseX or 0) + a.y = (eo.py or (eo.cellY * CELL)) + (eo.raiseY or 0) + a.sortY = sortY + a.facing = eo.facing or "down" + a.walkPhase = Objects.walkPhase(eo) + a.stepFlip = eo.stepFlip and true or false + a.bow = (eo.bowFrames and eo.bowFrames > 0) or eo.raiseHand == true + a.frame = eo.customFrame + a.sprite = eo.sprite or spriteNameForObj(eo.def or {}) + a.graphicsId = eo.graphicsId or (eo.def and (eo.def.graphicsId or eo.def.graphics)) + a.priority = nil + a.subpriority = nil + actors[#actors + 1] = a end collectNeighborActors(actors, 10000, currentMapId(game), resolveMapDef(game, currentMapId(game))) @@ -606,28 +619,30 @@ local function collectGame3Actors(game, mapDef, camX, camY, px, py, facing, walk if not fieldMove and FieldMod and FieldMod.fishingPose then fishFrame, fishX2, fishY2 = FieldMod.fishingPose() end - actors[#actors + 1] = { - kind = "player", - elevation = PlayerMod and PlayerMod.elevation or 3, - x = px + (playerXOff or 0) + (fishX2 or 0), - y = py + (playerYOff or 0) + (fishY2 or 0), - sortY = playerSortY, - facing = facing or "down", - walkPhase = (walkPhase == 1 or walkPhase == true) and 1 or 0, - stepFlip = stepFlip and true or false, - fieldMove = fieldMove, - fieldMoveFrame = fieldMoveFrame, - fishing = fishFrame ~= nil, - fishFrame = fishFrame, - running = PlayerMod and PlayerMod.runPose and PlayerMod.runPose() or nil, - sprite = playerSpriteName(game), - graphicsId = useOw and OwSprites.playerGraphicsId(game) or nil, - } + local a = playerActor + a.kind = "player" + a.elevation = PlayerMod and PlayerMod.elevation or 3 + a.x = px + (playerXOff or 0) + (fishX2 or 0) + a.y = py + (playerYOff or 0) + (fishY2 or 0) + a.sortY = playerSortY + a.facing = facing or "down" + a.walkPhase = (walkPhase == 1 or walkPhase == true) and 1 or 0 + a.stepFlip = stepFlip and true or false + a.fieldMove = fieldMove + a.fieldMoveFrame = fieldMoveFrame + a.fishing = fishFrame ~= nil + a.fishFrame = fishFrame + a.running = PlayerMod and PlayerMod.runPose and PlayerMod.runPose() or nil + a.sprite = playerSpriteName(game) + a.graphicsId = useOw and OwSprites.playerGraphicsId(game) or nil + a.priority = nil + a.subpriority = nil + actors[#actors + 1] = a end local follower = require("src.world.game3.Follower").actor() if follower then actors[#actors + 1] = follower end - return applyDrawOrder(actors) + return applyDrawOrder(actors, frameUnder, frameOver) end --- Collect visible tile draws grouped by palette slot for batched GbcPalette.with. diff --git a/src/core/game3/link/union_plaza_map.lua b/src/core/game3/link/union_plaza_map.lua new file mode 100644 index 00000000..90321305 --- /dev/null +++ b/src/core/game3/link/union_plaza_map.lua @@ -0,0 +1,213 @@ +local Plaza = {} + +Plaza.MAP_ID = "FR_UNION_ROOM_PLAZA" +Plaza.SOURCE_ID = "FR_UNION_ROOM" +Plaza.CAP = 40 +Plaza.WIDTH = 25 +Plaza.HEIGHT = 25 +Plaza.EXIT_X, Plaza.EXIT_Y = 12, 24 +Plaza.ATTENDANT_LOCAL_ID = 1 + +Plaza.ROLES = { + "ABCDTTTTTTTTTTTTTTTTTTTTE", + "abcdtttttttttttttttttttte", + "FGHHHHHHHHHHHHHHHHHHHHHIJ", + "fg.....................ij", + "L.......................R", + "L.......................R", + "L.......................R", + "L.......................R", + "L.......................R", + "L.......................R", + "L..........123..........R", + "L..........456..........R", + "L..........789..........R", + "L.......................R", + "L.......................R", + "L.......................R", + "L.......................R", + "L.......................R", + "L.......................R", + "L.......................R", + "L.......................R", + "L.......................R", + "L.......................R", + "Kk_________mno_________pq", + "###########xXz###########", +} + +Plaza.SOURCE = { + A = { 0, 0 }, B = { 1, 0 }, C = { 2, 0 }, D = { 3, 0 }, T = { 4, 0 }, E = { 14, 0 }, + a = { 0, 1 }, b = { 1, 1 }, c = { 2, 1 }, d = { 3, 1 }, t = { 4, 1 }, e = { 14, 1 }, + F = { 0, 2 }, G = { 1, 2 }, H = { 2, 2 }, I = { 13, 2 }, J = { 14, 2 }, + f = { 0, 3 }, g = { 1, 3 }, ["."] = { 2, 3 }, i = { 13, 3 }, j = { 14, 3 }, + L = { 0, 4 }, R = { 14, 4 }, + ["1"] = { 6, 5 }, ["2"] = { 7, 5 }, ["3"] = { 8, 5 }, + ["4"] = { 6, 6 }, ["5"] = { 7, 6 }, ["6"] = { 8, 6 }, + ["7"] = { 6, 7 }, ["8"] = { 7, 7 }, ["9"] = { 8, 7 }, + K = { 0, 10 }, k = { 1, 10 }, _ = { 2, 10 }, m = { 6, 10 }, n = { 7, 10 }, o = { 8, 10 }, + p = { 13, 10 }, q = { 14, 10 }, + ["#"] = { 0, 11 }, x = { 6, 11 }, X = { 7, 11 }, z = { 8, 11 }, +} + +Plaza.BLOCKED = { + A = true, B = true, C = true, D = true, T = true, E = true, + a = true, b = true, c = true, d = true, t = true, e = true, + ["#"] = true, +} + +local CELL_XS = { 3, 6, 9, 12, 15, 18, 21 } +local CELL_YS = { 5, 8, 11, 14, 17, 20 } +local DOOR_X, DOOR_Y = 12, 23 + +local cells, bySlot, byKey = {}, {}, {} +for _, y in ipairs(CELL_YS) do + for _, x in ipairs(CELL_XS) do + if not (x == DOOR_X and y == 20) then + cells[#cells + 1] = { x = x, y = y } + end + end +end +table.sort(cells, function(p, q) + local dp = math.abs(p.x - DOOR_X) + math.abs(p.y - DOOR_Y) + local dq = math.abs(q.x - DOOR_X) + math.abs(q.y - DOOR_Y) + if dp ~= dq then return dp < dq end + local ap, aq = math.abs(p.x - DOOR_X), math.abs(q.x - DOOR_X) + if ap ~= aq then return ap < aq end + if p.x ~= q.x then return p.x < q.x end + return p.y > q.y +end) +for i, c in ipairs(cells) do + if i <= Plaza.CAP then + bySlot[i] = c + byKey[c.y * 64 + c.x] = i + end +end +Plaza.CELLS = cells + +function Plaza.cellFor(slot) + local c = bySlot[tonumber(slot) or -1] + if not c then return nil end + return c.x, c.y, "down" +end + +function Plaza.slotAt(x, y) + x, y = tonumber(x), tonumber(y) + if not (x and y) then return nil end + return byKey[y * 64 + x] +end + +function Plaza.entry() + return Plaza.EXIT_X, Plaza.EXIT_Y, "up" +end + +function Plaza.roleAt(x, y) + local row = Plaza.ROLES[y + 1] + if not row or x < 0 or x >= #row then return nil end + return row:sub(x + 1, x + 1) +end + +local function copyRow(row) + local out = {} + for k, v in pairs(row) do out[k] = v end + return out +end + +function Plaza.buildDecoded(src) + local cellsOut = {} + for y = 0, Plaza.HEIGHT - 1 do + for x = 0, Plaza.WIDTH - 1 do + local s = Plaza.SOURCE[Plaza.roleAt(x, y)] + if s[1] >= (src.trueWidth or src.width or 0) or s[2] >= (src.trueHeight or src.height or 0) then + error(("union plaza: %s layout has no cell %d,%d; re-import the ROM"):format(Plaza.SOURCE_ID, s[1], s[2])) + end + local c = src:cellAt(s[1], s[2]) + cellsOut[y * Plaza.WIDTH + x + 1] = { mid = c.mid, coll = c.coll, elev = c.elev } + end + end + local border = {} + for i, m in ipairs(src.borderMids or { 0 }) do border[i] = m end + return { + width = Plaza.WIDTH, + height = Plaza.HEIGHT, + trueWidth = Plaza.WIDTH, + trueHeight = Plaza.HEIGHT, + borderWidth = src.borderWidth or 1, + borderHeight = src.borderHeight or 1, + borderMids = border, + cells = cellsOut, + } +end + +local function buildEvents(ev) + if type(ev) ~= "table" then return nil end + local out = {} + for k, v in pairs(ev) do out[k] = v end + local objs = {} + for _, row in ipairs(ev.objects or ev.objectEvents or {}) do + if tonumber(row.localId) == Plaza.ATTENDANT_LOCAL_ID then + objs[#objs + 1] = copyRow(row) + end + end + out.objects = objs + out.objectEvents = nil + out.bgEvents = {} + out.coordEvents = {} + return out +end + +function Plaza.ensure(game) + local maps = game and game.data and game.data.maps + if type(maps) ~= "table" then error("union plaza: no map table to build " .. Plaza.MAP_ID .. " into", 2) end + local srcDef = maps[Plaza.SOURCE_ID] + if not srcDef then + error("union plaza: " .. Plaza.SOURCE_ID .. " is missing from the cache; re-import the ROM", 2) + end + if not srcDef.midLayout then + local okM, Map = pcall(require, "src.core.game3.map") + if okM and Map and Map.ensureMidLayout then Map.ensureMidLayout(game, Plaza.SOURCE_ID, srcDef) end + end + local src = srcDef.midLayout + if not src then + error("union plaza: " .. Plaza.SOURCE_ID .. " has no layout in the cache; re-import the ROM", 2) + end + + local def = maps[Plaza.MAP_ID] + if not (def and def._plazaSource == src) then + local LayoutNative = require("src.core.game3.layout_native") + local pair = src.pair or srcDef.pair + def = {} + for k, v in pairs(srcDef) do def[k] = v end + def.id = Plaza.MAP_ID + def.name = Plaza.MAP_ID + def.width = Plaza.WIDTH + def.height = Plaza.HEIGHT + def.connections = {} + def.midLayout = LayoutNative.fromDecoded(Plaza.buildDecoded(src), Plaza.MAP_ID, pair) + def.pair = pair + local warp = copyRow((srcDef.warps and srcDef.warps[1]) or {}) + warp.x, warp.y = Plaza.EXIT_X, Plaza.EXIT_Y + def.warps = { warp } + def.objects = nil + def.objectEvents = nil + def.bgEvents = {} + def.coordEvents = {} + def._plazaSource = src + maps[Plaza.MAP_ID] = def + end + + local Space = package.loaded["src.core.game3.scripting.space"] + local bundle = Space and Space.bundle + local events = bundle and bundle.events + if type(events) == "table" and events[Plaza.SOURCE_ID] + and events[Plaza.MAP_ID] == nil then + events[Plaza.MAP_ID] = buildEvents(events[Plaza.SOURCE_ID]) + end + local ev = events and events[Plaza.MAP_ID] + if ev and def.objects == nil and Space.attachEventsToMaps then + Space.attachEventsToMaps({ [Plaza.MAP_ID] = def }, bundle) + end + return def +end + +return Plaza diff --git a/src/core/game3/link/union_room.lua b/src/core/game3/link/union_room.lua index aa210a49..8b4ce1ec 100644 --- a/src/core/game3/link/union_room.lua +++ b/src/core/game3/link/union_room.lua @@ -29,9 +29,6 @@ Union.ACTIVITY = { -- pokefirered/include/constants/union_room.h:49 Union.IN_UNION_ROOM = 0x40 --- pokefirered/include/constants/union_room.h:8 -Union.MAX_LEADERS = 8 - -- pokefirered/include/constants/union_room.h:51 Union.LINK_GROUP = { SINGLE_BATTLE = 0, @@ -79,8 +76,6 @@ Union.ACTIVITY_NAMES = RomText.lazy({ [12] = "sLinkGroupActivityNameTexts[12]", }) --- pokefirered/src/union_room_player_avatar.c:97 -Union.LOCAL_IDS = { 9, 8, 7, 2, 6, 5, 4, 3 } Union.AVATARS_FILE = "data/generated/gba/union_room/avatars.lua" -- pokefirered/include/constants/global.h:110 Union.DIR = { NONE = 0, SOUTH = 1, NORTH = 2, WEST = 3, EAST = 4 } @@ -106,26 +101,16 @@ function Union.avatarData() return Union._avatars end --- pokefirered/include/constants/flags.h:115 -Union.FLAG_HIDE_PLAYER_1 = 0x63 --- pokefirered/include/constants/vars.h:28 -Union.VAR_OBJ_GFX_ID_0 = 0x4010 -- pokefirered/include/constants/union_room.h:82 Union.INTERACT_ATTENDANT = 9 Union.INTERACT_START_MENU = 10 Union.MAP = "FR_UNION_ROOM" -Union.RESPONSE_SECONDS = 3 Union.MSG = { HELLO = "game3_union_hello", - BYE = "game3_union_bye", - REQUEST = "game3_union_request", - RESPONSE = "game3_union_response", } --- pokefirered/src/union_room_player_avatar.c:566 -Union.REFRESH_FRAMES = 300 Union.AWAIT_ROOM_SECONDS = 20 Union.CARD_WAIT_SECONDS = 3 @@ -148,7 +133,6 @@ Union.activity = nil Union.lastResult = nil Union._name = nil Union._pump = nil -Union._spawned = {} Union._trade = nil Union.relay = false Union.memberIds = {} @@ -156,10 +140,8 @@ Union.invite = nil Union.incoming = nil Union.direct = {} Union._refresh = 0 -Union._refreshTimer = 0 Union._answered = {} Union._await = nil -Union._objs = {} Union._vobjs = {} Union._vobjDirty = false Union.flow = nil @@ -194,10 +176,6 @@ local function objects() return package.loaded["src.core.game3.objects"] end -local function flags() - return require("src.core.game3.scripting.flags") -end - local function ctxOf(extra) return Union.textCtx(extra) end @@ -210,8 +188,23 @@ function Union.isActive() return Union.state ~= "off" end +local function plazaMap() + return require("src.core.game3.link.union_plaza_map") +end + +Union.plazaMap = plazaMap + +function Union.isUnionMap(id) + if type(id) ~= "string" then return false end + return id == Union.MAP or id == plazaMap().MAP_ID +end + function Union.onUnionRoomMap() - return link().currentMap() == Union.MAP + return Union.isUnionMap(link().currentMap()) +end + +function Union.capacity() + return plazaMap().CAP end -- pokefirered/src/union_room.c:114 URTRADE_STATE_* @@ -256,14 +249,6 @@ function Union.graphicsIdFor(gender, trainerId) return row[((tonumber(trainerId) or 0) % 8) + 1] end --- pokefirered/src/union_room_player_avatar.c:134 -function Union.memberCoords(slot, member) - local data = Union.avatarData() - local c = data.leader_coords[slot] - local o = data.group_offsets[(member or 0) + 1] - return c[1] + o[1], c[2] + o[2] -end - -- pokefirered/src/union_room_player_avatar.c:448 function Union.memberFacing(member, activity) if (member or 0) ~= 0 then return Union.avatarData().member_facing[member + 1] end @@ -272,62 +257,7 @@ function Union.memberFacing(member, activity) return Union.DIR.EAST end --- pokefirered/src/union_room_player_avatar.c:169 CreateUnionRoomPlayerObjectEvent -function Union.spawnLeader(slot, player) - if not (slot and slot >= 1 and slot <= Union.MAX_LEADERS) then return false end - local L = link() - local store = L.store() - local F = flags() - local gfx = Union.graphicsIdFor(player and player.gender, player and player.trainerId) - F.setVar(store, nil, Union.VAR_OBJ_GFX_ID_0 + (slot - 1), gfx) - -- pokefirered/src/union_room_player_avatar.c:159 ShowUnionRoomPlayer - F.setFlag(store, nil, Union.FLAG_HIDE_PLAYER_1 + (slot - 1), false) - local Objects = objects() - if Objects then - if Objects.addObject then Objects.addObject(Union.LOCAL_IDS[slot]) end - if Objects.refreshGraphics then Objects.refreshGraphics() end - end - Union._spawned[slot] = true - return true -end - --- pokefirered/src/union_room_player_avatar.c:174 RemoveUnionRoomPlayerObjectEvent -function Union.despawnLeader(slot) - if not (slot and slot >= 1 and slot <= Union.MAX_LEADERS) then return false end - local L = link() - local F = flags() - -- pokefirered/src/union_room_player_avatar.c:154 HideUnionRoomPlayer - F.setFlag(L.store(), nil, Union.FLAG_HIDE_PLAYER_1 + (slot - 1), true) - local Objects = objects() - if Objects and Objects.removeObject then Objects.removeObject(Union.LOCAL_IDS[slot]) end - Union._spawned[slot] = nil - return true -end - -local function avatarLive(slot) - local Objects = objects() - local eo = Objects and Objects.find and Objects.find(Union.LOCAL_IDS[slot]) - return eo ~= nil and eo.visible == true -end - --- pokefirered/src/union_room_player_avatar.c:367 Task_AnimateUnionRoomPlayers -function Union.refreshAvatars() - if not Union.onUnionRoomMap() then return 0 end - local n = 0 - for slot = 1, Union.MAX_LEADERS do - if Union.players[slot] and not avatarLive(slot) then - Union.spawnLeader(slot, Union.players[slot]) - n = n + 1 - end - end - return n -end - function Union.despawnAll() - for slot = 1, Union.MAX_LEADERS do - if Union._spawned[slot] then Union.despawnLeader(slot) end - end - Union._objs = {} if next(Union._vobjs or {}) then Union._vobjs = {} local VirtualObjects = package.loaded["src.core.game3.virtual_objects"] @@ -351,152 +281,106 @@ local function playerOn(x, y) return P.moving and tonumber(P.targetX) == x and tonumber(P.targetY) == y or false end -local function leaderObj(slot) - Union._objs = Union._objs or {} - local o = Union._objs[slot] - if not o then - o = { state = 0, anim = 0, sched = nil, y2 = 0 } - Union._objs[slot] = o - end - return o +local function plazaVobjId(slot) + return Union.VOBJ_BASE + slot end -Union.leaderObj = leaderObj +Union.vobjId = plazaVobjId -local function setRaise(slot, y2) - local Objects = objects() - local eo = Objects and Objects.find and Objects.find(Union.LOCAL_IDS[slot]) - if eo then eo.raiseY = y2 end +function Union.vobj(slot) + return Union._vobjs and Union._vobjs[plazaVobjId(slot)] or nil end --- pokefirered/src/union_room_player_avatar.c:265 -local function animateSpawn(slot, o) - if o.anim == 0 then - if not playerStandingStill() then return false end - local x, y = Union.memberCoords(slot, 0) - if playerOn(x, y) then return false end - Union.spawnLeader(slot, o.player) - o.y2 = -Union.FLY_HEIGHT - setRaise(slot, o.y2) - o.anim = 1 - return false - end - o.y2 = math.min(0, o.y2 + Union.FLY_STEP) - setRaise(slot, o.y2) - if o.y2 >= 0 then - o.anim = 0 - return true - end - return false -end - --- pokefirered/src/union_room_player_avatar.c:236 -local function animateDespawn(slot, o) - if o.anim == 0 then - o.y2 = 0 - o.anim = 1 - flags().setFlag(link().store(), nil, Union.FLAG_HIDE_PLAYER_1 + (slot - 1), true) - end - o.y2 = o.y2 - Union.FLY_STEP - setRaise(slot, o.y2) - if o.y2 <= -Union.FLY_HEIGHT then - Union.despawnLeader(slot) - o.anim = 0 - return true - end - return false -end - --- pokefirered/src/union_room_player_avatar.c:325 -function Union.animatePlayer(slot) - local o = leaderObj(slot) - if o.state == 0 then - if o.sched ~= "in" then - o.sched = nil - return - end - o.state, o.anim = 2, 0 - end - if o.state == 2 then - if o.sched == "out" then - o.state, o.anim = 0, 0 - if Union._spawned[slot] then Union.despawnLeader(slot) end - elseif animateSpawn(slot, o) then - o.state = 1 - end - elseif o.state == 1 then - if o.sched == "out" then - o.state, o.anim = 3, 0 - if animateDespawn(slot, o) then o.state = 0 end - end - elseif o.state == 3 then - if animateDespawn(slot, o) then o.state = 0 end - end - o.sched = nil -end - --- pokefirered/src/union_room_player_avatar.c:300 -function Union.scheduleLeaderIn(slot, player) - local o = leaderObj(slot) - o.sched = "in" - o.player = player -end - --- pokefirered/src/union_room_player_avatar.c:313 -function Union.scheduleLeaderOut(slot) - leaderObj(slot).sched = "out" -end - -local function vobjId(slot, member) - return Union.VOBJ_BASE + (slot - 1) * Union.GROUP_SIZE + member -end - -Union.vobjId = vobjId - -function Union.vobj(slot, member) - Union._vobjs = Union._vobjs or {} - return Union._vobjs[vobjId(slot, member)] -end - -function Union.vobjVisible(slot, member) - local v = Union.vobj(slot, member) +function Union.vobjVisible(slot) + local v = Union.vobj(slot) return v ~= nil and v.visible == true end +local function facingDir(facing) + if type(facing) == "number" then return facing end + return Union.FACE_DIR[facing] or Union.DIR.SOUTH +end + +function Union.cellFor(slot) + local x, y, facing = plazaMap().cellFor(slot) + return x, y, facingDir(facing) +end + +local function idleActivity(activity) + local raw = math.floor(tonumber(activity) or 0) % Union.IN_UNION_ROOM + return raw == Union.ACTIVITY.NONE or raw == Union.ACTIVITY.PLYRTALK or raw == Union.ACTIVITY.SEARCH +end + +Union.idleActivity = idleActivity + +function Union.cellFacing(slot, p) + if p and not idleActivity(p.activity) then return Union.memberFacing(0, p.activity) end + local _, _, dir = Union.cellFor(slot) + return dir +end + -- pokefirered/src/union_room_player_avatar.c:463 -function Union.spawnMember(slot, member, gfx, activity) - Union._vobjs = Union._vobjs or {} - local id = vobjId(slot, member) - local v = Union._vobjs[id] +function Union.showAvatar(slot, p) + local vobjs = Union._vobjs + local id = plazaVobjId(slot) + local v = vobjs[id] if not v then - v = { slot = slot, member = member, visible = false, y2 = 0 } - Union._vobjs[id] = v + v = { slot = slot, member = 0, visible = false, y2 = 0 } + vobjs[id] = v end + local x, y = Union.cellFor(slot) if not v.visible or v.anim == "out" then + if playerOn(x, y) then + v.waiting = true + Union._avatarWaiting = true + return false + end v.visible = true v.anim = "in" v.y2 = -Union.FLY_HEIGHT end - v.gfx = gfx - v.dir = Union.memberFacing(member, activity) - v.x, v.y = Union.memberCoords(slot, member) + v.waiting = nil + v.gfx = Union.graphicsIdFor(p.gender, p.trainerId) + v.x, v.y = x, y + if Union._talkSlot ~= slot then v.dir = Union.cellFacing(slot, p) end Union._vobjDirty = true + return true end -- pokefirered/src/union_room_player_avatar.c:478 -function Union.despawnMember(slot, member) - local v = Union.vobj(slot, member) - if v and v.visible and v.anim ~= "out" then +function Union.hideAvatar(slot) + local v = Union.vobj(slot) + if not v then return end + v.waiting = nil + if v.visible and v.anim ~= "out" then v.anim = "out" v.y2 = v.y2 or 0 Union._vobjDirty = true end end +function Union.retryWaitingAvatars() + if not playerStandingStill() then return end + local waiting = false + for slot = 1, Union.capacity() do + local v = Union.vobj(slot) + if v and v.waiting then + local p = Union.players[slot] + if p and not p.gone then + if not Union.showAvatar(slot, p) then waiting = true end + else + v.waiting = nil + end + end + end + Union._avatarWaiting = waiting +end + -- pokefirered/src/event_object_movement.c:9354 function Union.animateVobjs() local dirty = Union._vobjDirty - for _, v in pairs(Union._vobjs or {}) do + local vobjs = Union._vobjs + for _, v in pairs(vobjs) do if v.anim == "in" then v.y2 = math.min(0, v.y2 + Union.FLY_STEP) if v.y2 >= 0 then v.anim = nil end @@ -507,128 +391,83 @@ function Union.animateVobjs() v.visible = false v.anim = nil v.y2 = 0 + Union._vobjRebuild = true end dirty = true end end if not dirty then return end Union._vobjDirty = false - local okV, VirtualObjects = pcall(require, "src.core.game3.virtual_objects") - if not okV then return end - VirtualObjects.clear() - local ids = {} - for id, v in pairs(Union._vobjs or {}) do - if v.visible then ids[#ids + 1] = id end + local VirtualObjects = package.loaded["src.core.game3.virtual_objects"] + if not VirtualObjects then + local okV, mod = pcall(require, "src.core.game3.virtual_objects") + if not okV then return end + VirtualObjects = mod end - table.sort(ids) - for _, id in ipairs(ids) do - local v = Union._vobjs[id] - local rec = VirtualObjects.spawn(id, v.gfx, v.x, v.y, 3, v.dir) - if rec then - rec.y2 = v.y2 - rec.solid = v.anim ~= "out" - end + if Union._vobjRebuild then + Union._vobjRebuild = false + VirtualObjects.clear() end -end - --- pokefirered/src/union_room_player_avatar.c:486 -function Union.assembleGroup(slot, p) - if not Union.vobjVisible(slot, 0) then - local x, y = Union.memberCoords(slot, 0) - if playerOn(x, y) then return end - Union.spawnMember(slot, 0, Union.graphicsIdFor(p.gender, p.trainerId), p.activity) - end - for i = 1, Union.GROUP_SIZE - 1 do - local partner = p.partners and p.partners[i] - if not partner then - Union.despawnMember(slot, i) - else - local x, y = Union.memberCoords(slot, i) - if not playerOn(x, y) then - Union.spawnMember(slot, i, Union.graphicsIdFor(partner.gender, partner.trainerId), p.activity) + for id, v in pairs(vobjs) do + if v.visible then + local rec = VirtualObjects.get(id) or VirtualObjects.spawn(id, v.gfx, v.x, v.y, 3, v.dir) + if rec then + rec.graphicsId = v.gfx + rec.x, rec.y = v.x, v.y + rec.direction = v.dir + rec.y2 = v.y2 + rec.solid = v.anim ~= "out" end end end end --- pokefirered/src/union_room_player_avatar.c:510 -function Union.spawnGroup(slot, p) - local raw = math.floor(tonumber(p.activity) or 0) % Union.IN_UNION_ROOM - if raw == Union.ACTIVITY.NONE or raw == Union.ACTIVITY.PLYRTALK or raw == Union.ACTIVITY.SEARCH then - Union.scheduleLeaderIn(slot, p) - for i = 0, Union.GROUP_SIZE - 1 do Union.despawnMember(slot, i) end - else - Union.scheduleLeaderOut(slot) - Union.assembleGroup(slot, p) - end -end - --- pokefirered/src/union_room_player_avatar.c:544 -function Union.despawnGroup(slot) - Union.scheduleLeaderOut(slot) - for i = 0, Union.GROUP_SIZE - 1 do Union.despawnMember(slot, i) end -end - --- pokefirered/src/union_room_player_avatar.c:552 -function Union.updatePlayerSprites() - Union._refreshTimer = 0 - for slot = 1, Union.MAX_LEADERS do +function Union.refreshPlaza() + for slot = 1, Union.capacity() do local p = Union.players[slot] if p and p.gone then - Union.despawnGroup(slot) + Union.hideAvatar(slot) Union.players[slot] = nil Union.memberIds[slot] = nil if Union.partnerId == slot then Union.partnerId = nil end elseif p then - Union.spawnGroup(slot, p) + Union.showAvatar(slot, p) end end end --- pokefirered/src/union_room_player_avatar.c:566 -function Union.scheduleRefresh() - Union._refreshTimer = Union.REFRESH_FRAMES -end - --- pokefirered/src/union_room_player_avatar.c:571 -function Union.handleRefresh() - Union._refreshTimer = (Union._refreshTimer or 0) + 1 - if Union._refreshTimer > Union.REFRESH_FRAMES then Union.updatePlayerSprites() end -end - function Union.animateAll() - for slot = 1, Union.MAX_LEADERS do Union.animatePlayer(slot) end + if Union._avatarWaiting then Union.retryWaitingAvatars() end Union.animateVobjs() end +local FACING_DELTA = { down = { 0, 1 }, up = { 0, -1 }, left = { -1, 0 }, right = { 1, 0 } } + -- pokefirered/src/union_room_player_avatar.c:577 function Union.tryInteractWithMember() if not playerStandingStill() then return nil end local P = playerMod() - local d = P and ({ down = { 0, 1 }, up = { 0, -1 }, left = { -1, 0 }, right = { 1, 0 } })[P.facing or "down"] + local d = P and FACING_DELTA[P.facing or "down"] if not d then return nil end local fx, fy = (tonumber(P.cellX) or 0) + d[1], (tonumber(P.cellY) or 0) + d[2] - for slot = 1, Union.MAX_LEADERS do - local p = Union.players[slot] - for member = 0, Union.GROUP_SIZE - 1 do - local v = Union.vobj(slot, member) - if v and v.visible and v.anim == nil and p and not p.gone and v.x == fx and v.y == fy then - local opp = Union.avatarData().opposite_facing[(Union.FACE_DIR[P.facing] or 1) + 1] - v.dir = opp - Union._vobjDirty = true - return slot, member - end - end - end - return nil + local slot = plazaMap().slotAt(fx, fy) + if not slot then return nil end + local p = Union.players[slot] + local v = Union.vobj(slot) + if not (v and v.visible and v.anim == nil and p and not p.gone) then return nil end + v.dir = Union.avatarData().opposite_facing[(Union.FACE_DIR[P.facing] or 1) + 1] + Union._talkSlot = slot + Union._vobjDirty = true + return slot, 0 end -- pokefirered/src/union_room_player_avatar.c:621 -function Union.updateMemberFacing(slot, member) - local v = slot and Union.vobj(slot, member or 0) +function Union.updateMemberFacing(slot) + if slot == nil or Union._talkSlot == slot then Union._talkSlot = nil end + local v = slot and Union.vobj(slot) local p = slot and Union.players[slot] if not (v and p) then return end - v.dir = Union.memberFacing(member or 0, p.activity) + v.dir = Union.cellFacing(slot, p) Union._vobjDirty = true end @@ -638,7 +477,7 @@ end function Union.playerCount() local n = 0 - for slot = 1, Union.MAX_LEADERS do + for slot = 1, Union.capacity() do if Union.players[slot] then n = n + 1 end end return n @@ -646,7 +485,7 @@ end function Union.list() local out = {} - for slot = 1, Union.MAX_LEADERS do + for slot = 1, Union.capacity() do local p = Union.players[slot] if p then out[#out + 1] = { slot = slot, name = p.name, activity = p.activity } end end @@ -699,39 +538,6 @@ function Union.bufferPlayerName(ctx, adapters) return false, 1 end -local function addPlayer(hello) - for slot = 1, Union.MAX_LEADERS do - local p = Union.players[slot] - if p and p.trainerId == hello.trainerId and p.name == hello.name then - p.activity = hello.activity or p.activity - return slot, false - end - end - for slot = 1, Union.MAX_LEADERS do - if not Union.players[slot] then - Union.players[slot] = { - name = hello.name, - gender = tonumber(hello.gender) or 0, - trainerId = tonumber(hello.trainerId) or 0, - activity = tonumber(hello.activity) or Union.ACTIVITY.SEARCH, - } - return slot, true - end - end - return nil, false -end - -Union.addPlayer = addPlayer - -function Union.removePlayer(slot) - if not Union.players[slot] then return false end - Union.players[slot] = nil - Union.memberIds[slot] = nil - Union.despawnLeader(slot) - if Union.partnerId == slot then Union.partnerId = nil end - return true -end - function Union.announce() local L = link() local lk = L.link @@ -746,37 +552,28 @@ end -- pokefirered/src/union_room.c:3515 InitUnionRoom function Union.init(ctx) Union._name = nil - if Union.state ~= "off" then return false end - Union.players = {} - Union._spawned = {} - local lk = link().link - if lk and lk.isOpen and lk:isOpen() then - -- pokefirered/src/union_room.c:3536 Task_InitUnionRoom - Union.state = "search" - Union.startPump() - end return false end -- pokefirered/src/union_room.c:2579 RunUnionRoom function Union.run(ctx, adapters) link().setResult(ctx, 0) - if Union.state ~= "off" and Union.state ~= "search" and Union.onUnionRoomMap() then - if Union.relay then - Union._objs = {} - Union._spawned = {} - Union._vobjDirty = true - Union.scheduleRefresh() - end + if Union.state ~= "off" and Union.onUnionRoomMap() then + Union._vobjDirty = true + Union._vobjRebuild = true Union.startPump() return false end Union.players = {} - Union._spawned = {} - Union._objs = {} Union._vobjs = {} + Union._vobjDirty = false + Union._vobjRebuild = false + Union._avatarWaiting = false + Union._plazaSynced = false + Union._plazaInstance, Union._plazaRev = nil, nil + Union._offlineSince, Union._offlineWiped = nil, nil + Union._upgradeShown = nil Union.flow = nil - Union._refreshTimer = 0 Union.memberIds = {} Union.partnerId = nil Union.activity = nil @@ -787,13 +584,11 @@ function Union.run(ctx, adapters) Union._await = nil Union.state = "init" local L = link() - Union.relay = L.adapterConnected() - if Union.relay then - L.clientCall("joinPlaza", "union", L.liveProfile(), L.avatar()) - L.setStatus("idle") - Union._refresh = 0 - Union._synced = false - end + Union.relay = true + L.clientCall("joinPlaza", "union", L.liveProfile(), L.avatar(), plazaMap().CAP) + L.setStatus("idle") + Union._refresh = 0 + Union._synced = false L.setResult(ctx, 0) Union.startPump() return false @@ -802,20 +597,13 @@ end function Union.stop(reason) if Union.state == "off" then return false end local L = link() - if Union.relay then - if Union.incoming then L.clientCall("replyInvite", Union.incoming.id, false) end - L.clientCall("leavePlaza", "union") - L.setStatus("busy") - Union.relay = false - Union.invite = nil - Union.incoming = nil - Union._await = nil - else - local lk = L.link - if lk and lk.isOpen and lk:isOpen() then - lk:send({ type = Union.MSG.BYE, reason = tostring(reason or "left") }) - end - end + if Union.incoming then L.clientCall("replyInvite", Union.incoming.id, false) end + L.clientCall("leavePlaza", "union") + L.setStatus("busy") + Union.relay = false + Union.invite = nil + Union.incoming = nil + Union._await = nil local s = screen() if s and s.isOpen and s.isOpen() then s.close() end Union.flow = nil @@ -832,21 +620,6 @@ function Union.stop(reason) return true end -local function chooserOpen() - local s = screen() - return s and s.isOpen and s.isOpen() and s.mode == "activity" -end - -local function sendRequest(activity) - if Union.relay then return Union.sendInvite(activity) end - local lk = link().link - if lk and lk.isOpen and lk:isOpen() then - lk:send({ type = Union.MSG.REQUEST, activity = activity, name = localPlayer().name }) - return true - end - return false -end - -- pokefirered/src/union_room.c:2896 UR_STATE_HANDLE_DO_SOMETHING_PROMPT_INPUT function Union.chooseActivity(index) local item = Union.INVITE_ITEMS[tonumber(index) or 0] @@ -854,7 +627,7 @@ function Union.chooseActivity(index) local M = message() if item.activity == Union.ACTIVITY.NONE then Union.activity = nil - if Union.relay and M and M.show then + if M and M.show then -- pokefirered/src/union_room.c:2916 local p = Union.partnerRow() or {} local text = RomText.ascii(RomText.key("gTexts_UR_IfYouWantToDoSomething", tonumber(p.gender) == 1 and 1 or 0)) @@ -868,9 +641,9 @@ function Union.chooseActivity(index) local activity = item.union and (item.activity + Union.IN_UNION_ROOM) or item.activity Union.activity = activity Union._role = "child" - local sent = sendRequest(activity) + local sent = Union.sendInvite(activity) Union.state = sent and "send_activity_request" or "print_and_exit" - if sent and Union.relay and M and M.show then + if sent and M and M.show then -- pokefirered/src/union_room.c:2941 local p = Union.partnerRow() or {} local g = tonumber(p.gender) == 1 and 1 or 0 @@ -887,31 +660,6 @@ function Union.cancelActivity() return true end -local DELTA = { down = { 0, 1 }, up = { 0, -1 }, left = { -1, 0 }, right = { 1, 0 } } - -function Union.slotForLocalId(localId) - for slot = 1, Union.MAX_LEADERS do - if Union.LOCAL_IDS[slot] == localId then return slot end - end - return nil -end - --- pokefirered/src/union_room.c:2757 TryInteractWithUnionRoomMember -function Union.facingMemberSlot() - local Player = package.loaded["src.core.game3.player"] - local Objects = objects() - if not (Player and Objects and Objects.at) then return nil end - local d = DELTA[Player.facing or "down"] - if not d then return nil end - local eo = Objects.at((tonumber(Player.cellX) or 0) + d[1], (tonumber(Player.cellY) or 0) + d[2]) - if not eo then return nil end - -- pokefirered/include/constants/event_objects.h:72 - if tonumber(eo.graphicsId) == 66 then return Union.INTERACT_ATTENDANT end - local slot = Union.slotForLocalId(tonumber(eo.localId)) - if slot and Union._spawned[slot] then return slot end - return nil -end - local function pressedA() local game = link().game() local input = game and game.input @@ -919,204 +667,14 @@ local function pressedA() return input:wasPressed("a") and true or false end --- pokefirered/src/union_room.c:2734 UR_STATE_MAIN -local function pollInteraction(ctx) - local L = link() - local result = L.getVar(ctx, L.VAR_RESULT) - if result == 0 and pressedA() then - local slot = Union.facingMemberSlot() - if slot then - local okA, Audio = pcall(require, "src.core.game3.audio") - local okS, SE = pcall(require, "src.core.game3.se_ids") - if okA and okS and Audio.playSe then pcall(Audio.playSe, SE.SE_SELECT) end - result = slot - end - end - if result == 0 then return false end - L.setVar(ctx, L.VAR_RESULT, 0) - if result == Union.INTERACT_ATTENDANT then - Union.state = "interact_with_attendant" - return true - end - if result == Union.INTERACT_START_MENU then return false end - local slot = result - if not Union.players[slot] then - Union.state = "print_and_exit" - return true - end - Union.partnerId = slot - Union.state = "do_something_prompt" - return true -end - -- pokefirered/src/union_room.c:2647 Task_RunUnionRoom function Union.update(dt) if Union.state == "off" then return false end - local L = link() - local ctx = select(1, L.vmCtx()) - local lk = L.link - - if Union.state ~= "search" and not Union.onUnionRoomMap() then + if not Union.onUnionRoomMap() then Union.stop("left_union_room") return false end - - if Union.relay then return Union.relayUpdate(dt, ctx) end - if lk and lk.isOpen and lk:isOpen() then - local hello = lk:take(Union.MSG.HELLO) - while hello do - local slot, isNew = addPlayer(hello) - if slot and isNew then - if Union.state ~= "search" then Union.spawnLeader(slot, Union.players[slot]) end - Union.noteUnionRoomPlayer(Union.players[slot].name) - end - hello = lk:take(Union.MSG.HELLO) - end - if lk:take(Union.MSG.BYE) then - for slot = Union.MAX_LEADERS, 1, -1 do - if Union.players[slot] then Union.removePlayer(slot) end - end - end - local request = lk:take(Union.MSG.REQUEST) - if request and Union.state == "main" then - Union.activity = tonumber(request.activity) - Union._requestName = request.name - Union.state = "player_contacted_you" - end - local response = lk:take(Union.MSG.RESPONSE) - if response then - Union._waited = nil - Union.lastResult = response.accept and "accepted" or "declined" - Union.state = response.accept and "start_activity" or "print_and_exit" - end - elseif Union.state ~= "init" and Union.state ~= "search" then - for slot = Union.MAX_LEADERS, 1, -1 do - if Union.players[slot] then Union.removePlayer(slot) end - end - end - - -- pokefirered/src/union_room.c:2795 HandleUnionRoomPlayerRefresh - if Union.state ~= "search" then Union.refreshAvatars() end - - if Union.state == "search" then - if not (lk and lk.isOpen and lk:isOpen()) then - Union.state = "off" - return false - end - elseif Union.state == "init" then - -- pokefirered/src/union_room.c:2674 UR_STATE_INIT_LINK - Union.announce() - Union.state = "main" - elseif Union.state == "main" then - pollInteraction(ctx) - elseif Union.state == "player_contacted_you" then - Union.askActivityRequest() - elseif Union.state == "handle_activity_request" then - local M = message() - local okC, Choice = pcall(require, "src.ui.game3.choice") - Union.offerYesNo() - local waiting = (M and M.isOpen and M.isOpen()) - or (okC and Choice and Choice.isOpen and Choice.isOpen()) - if not waiting then Union.answerRequest(false) end - elseif Union.state == "do_something_prompt" then - if not chooserOpen() then - local s = screen() - if s then - s.showActivities(Union.INVITE_ITEMS, { - partner = Union.players[Union.partnerId or 0], - onChoose = function(index) Union.chooseActivity(index) end, - onCancel = function() Union.cancelActivity() end, - }) - Union.state = "handle_do_something_prompt_input" - else - Union.state = "main" - end - end - elseif Union.state == "handle_do_something_prompt_input" then - if not chooserOpen() then Union.state = "main" end - elseif Union.state == "interact_with_attendant" then - -- pokefirered/src/union_room.c:3373 UR_STATE_CHECK_TRADING_BOARD - local s = screen() - if s then - s.showPlayers(Union.list(), { - mode = "board", - onPoll = function() return Union.list() end, - -- pokefirered/src/union_room.c:3485 UR_STATE_TRADE_SELECT_MON - onConfirm = function(slot) - if not Union.chooseMonForTradingBoard(slot) then Union.state = "main" end - end, - onCancel = function() Union.state = "main" end, - }) - Union.state = "check_trading_board" - else - Union.state = "main" - end - elseif Union.state == "check_trading_board" then - local s = screen() - if not (s and s.isOpen and s.isOpen()) then Union.state = "main" end - elseif Union.state == "send_activity_request" and Union.relay then - Union.pollInvite() - elseif Union.state == "await_room" then - Union.pollAwaitRoom(dt) - elseif Union.state == "await_link" then - Union.pollAwaitLink(dt) - elseif Union.state == "send_activity_request" then - -- pokefirered/src/union_room.c:2937 UR_STATE_TRAINER_APPEARS_BUSY - Union._waited = (Union._waited or 0) + (tonumber(dt) or 0) - if Union._waited >= Union.RESPONSE_SECONDS then - Union._waited = nil - Union.lastResult = "busy" - local M = message() - if M and M.show then - M.show(RomText.ascii("gText_UR_TrainerAppearsBusy")) - end - Union.state = "print_and_exit" - end - elseif Union.state == "start_activity" then - Union.startActivity() - elseif Union.state == "in_activity" then - local raw = math.floor(tonumber(Union.activity) or 0) - if raw % Union.IN_UNION_ROOM == Union.ACTIVITY.CHAT then - -- pokefirered/src/union_room.c:1949 EnterUnionRoomChat - if not chat().isActive() then - Union.activity = nil - Union.partnerId = nil - Union.state = "main" - end - elseif raw % Union.IN_UNION_ROOM == Union.ACTIVITY.CARD then - -- pokefirered/src/union_room.c:1954 CB2_ShowCard - local okC, TrainerCard = pcall(require, "src.ui.game3.trainer_card") - local open = okC and TrainerCard and TrainerCard.isOpen and TrainerCard.isOpen() - if not open then - Union.activity = nil - Union.partnerId = nil - Union.state = "main" - end - elseif raw % Union.IN_UNION_ROOM == Union.ACTIVITY.TRADE then - -- pokefirered/src/union_room.c:1713 Task_StartUnionRoomTrade - local LT = linkTrade() - if not LT.isActive() then - Union.activity = nil - Union.partnerId = nil - Union.state = "main" - end - else - local LB = battle() - if LB.state == "setup" then - LB.pumpUnionSetup() - elseif LB.state ~= "battle" then - Union.activity = nil - Union.partnerId = nil - Union.state = "main" - end - end - elseif Union.state == "print_and_exit" then - Union.activity = nil - Union.partnerId = nil - Union.state = "main" - end - - return true + return Union.relayUpdate(dt, select(1, link().vmCtx())) end -- pokefirered/src/union_room.c:1832 WarpForCableClubActivity @@ -1168,7 +726,7 @@ function Union.startActivity() local act = raw % Union.IN_UNION_ROOM local inRoom = raw >= Union.IN_UNION_ROOM local L = link() - local warpOpts = Union.relay and { onDone = function() end } or nil + local warpOpts = { onDone = function() end } if act == Union.ACTIVITY.BATTLE_SINGLE and inRoom then -- pokefirered/src/union_room.c:1811 StartUnionRoomBattle if battle().startUnionRoomBattle() then @@ -1189,7 +747,7 @@ function Union.startActivity() return true elseif act == Union.ACTIVITY.TRADE and inRoom then -- pokefirered/src/union_room.c:1936 Task_StartUnionRoomTrade - if Union.relay then Union.prepareBoardTrade() end + Union.prepareBoardTrade() if linkTrade().startUnionRoomTrade(function() Union.state = "main" end) then Union.state = "in_activity" return true @@ -1199,20 +757,10 @@ function Union.startActivity() Union.stop() Union.warpForCableClubActivity(Union.TRADE_CENTER, L.USING.TRADE_CENTER, warpOpts) return true - elseif act == Union.ACTIVITY.CHAT and Union.relay then + elseif act == Union.ACTIVITY.CHAT then -- pokefirered/src/union_room.c:1949 local rs = Union._chatSession or L.clientCall("roomSession") if rs then return Union.enterChat(rs) end - elseif act == Union.ACTIVITY.CHAT then - -- pokefirered/src/union_room.c:1949 EnterUnionRoomChat - if chat().start({ onDone = function() - Union.activity = nil - Union.partnerId = nil - Union.state = "main" - end }) then - Union.state = "in_activity" - return true - end elseif act == Union.ACTIVITY.CARD then -- pokefirered/src/union_room.c:1954 CB2_ShowCard if Union.showPartnerCard() then @@ -1447,7 +995,7 @@ end -- pokefirered/src/union_room.c:4400 function Union.boardOffers() local out = {} - for slot = 1, Union.MAX_LEADERS do + for slot = 1, Union.capacity() do local p = Union.players[slot] local b = p and not p.gone and type(p.board) == "table" and p.board or nil if b and (tonumber(b.species) or 0) ~= 0 then @@ -1509,7 +1057,7 @@ function Union.openTradingBoard() own = own, offers = offers, onChoose = function(_, item) - if not item or item.id == 8 then return Union.toMain() end + if not item or item.id == s.BOARD_EXIT then return Union.toMain() end local entry = item.entry if not entry then return Union.toMain() end Union.boardPick(entry) @@ -1672,37 +1220,28 @@ end -- pokefirered/src/union_room.c:3148 function Union.answerRequest(accept) - if Union.relay then - local inv = Union.incoming - Union.incoming = nil - local raw = math.floor(tonumber(Union.activity) or 0) % Union.IN_UNION_ROOM - local M = message() - local shown = inv and M and M.show and type(love) == "table" and love.graphics - if inv then link().clientCall("replyInvite", inv.id, accept and true or false) end - Union.lastResult = accept and "accepted" or "declined" - if accept and inv then - Union._role = "parent" - Union.flow = nil - Union.beginAwaitRoom(nil) - else - Union.activity = nil - if shown then - -- pokefirered/src/union_room.c:887 - local key = (raw == Union.ACTIVITY.CHAT or raw == Union.ACTIVITY.CARD) - and "gText_UR_OfferDeclined2" or "gText_UR_OfferDeclined1" - return Union.printAndExit(RomText.ascii(key)) - end - Union.flow = nil - Union.state = "main" - end - return true - end - local lk = link().link - if lk and lk.isOpen and lk:isOpen() then - lk:send({ type = Union.MSG.RESPONSE, accept = accept and true or false }) - end - Union.state = accept and "start_activity" or "main" + local inv = Union.incoming + Union.incoming = nil + local raw = math.floor(tonumber(Union.activity) or 0) % Union.IN_UNION_ROOM + local M = message() + local shown = inv and M and M.show and type(love) == "table" and love.graphics + if inv then link().clientCall("replyInvite", inv.id, accept and true or false) end Union.lastResult = accept and "accepted" or "declined" + if accept and inv then + Union._role = "parent" + Union.flow = nil + Union.beginAwaitRoom(nil) + else + Union.activity = nil + if shown then + -- pokefirered/src/union_room.c:887 + local key = (raw == Union.ACTIVITY.CHAT or raw == Union.ACTIVITY.CARD) + and "gText_UR_OfferDeclined2" or "gText_UR_OfferDeclined1" + return Union.printAndExit(RomText.ascii(key)) + end + Union.flow = nil + Union.state = "main" + end return true end @@ -1873,7 +1412,7 @@ end function Union.slotForId(id) if id == nil then return nil end - for slot = 1, Union.MAX_LEADERS do + for slot = 1, Union.capacity() do if Union.memberIds[slot] == id then return slot end end return nil @@ -1917,11 +1456,7 @@ local function avatarRow(m) } end -local function partnerSig(list) - local out = {} - for i, p in ipairs(list or {}) do out[i] = tostring(p.id) end - return table.concat(out, ",") -end +local NO_MEMBERS = {} -- pokefirered/src/union_room.c:2781 Union.GONE_GRACE_SECONDS = 1.5 @@ -1929,101 +1464,83 @@ Union.GONE_GRACE_SECONDS = 1.5 function Union.syncPlaza() local plaza = link().clientCall("plaza") if type(plaza) ~= "table" then return false end + if Union._plazaSynced and plaza.instance == Union._plazaInstance and plaza.rev == Union._plazaRev then + return false + end + Union._plazaSynced = true + Union._plazaInstance, Union._plazaRev = plaza.instance, plaza.rev + Union.plazaBuilds = (Union.plazaBuilds or 0) + 1 local me = myId() local mySlot = tonumber(plaza.you) - local members, present = {}, {} - for _, m in ipairs(type(plaza.members) == "table" and plaza.members or {}) do - if type(m) == "table" and m.id ~= nil and m.id ~= me - and not (mySlot and tonumber(m.slot) == mySlot) then - members[#members + 1] = m - present[m.id] = m - end - end - table.sort(members, function(a, b) return (tonumber(a.slot) or 99) < (tonumber(b.slot) or 99) end) - local partnerOf = {} - for _, m in ipairs(members) do - local g = type(m.group) == "table" and m.group or nil - if g and g.leader ~= nil and g.leader ~= m.id and present[g.leader] then partnerOf[m.id] = g.leader end - end - local leaders, partners = {}, {} - for _, m in ipairs(members) do - if not partnerOf[m.id] then - leaders[m.id] = m - local list = {} - local g = type(m.group) == "table" and m.group or nil - for _, id in ipairs(g and type(g.members) == "table" and g.members or {}) do - if partnerOf[id] == m.id and present[id] and #list < Union.GROUP_SIZE - 1 then - list[#list + 1] = avatarRow(present[id]) - end + local cap = Union.capacity() + local gen = (Union._plazaGen or 0) + 1 + Union._plazaGen = gen + local fresh = false + local members = type(plaza.members) == "table" and plaza.members or NO_MEMBERS + for i = 1, #members do + local m = members[i] + local slot = type(m) == "table" and tonumber(m.slot) or nil + if slot and slot >= 1 and slot <= cap and m.id ~= nil and m.id ~= me and slot ~= mySlot then + local p = Union.players[slot] + if p and p.id ~= m.id then + Union.hideAvatar(slot) + p = nil end - partners[m.id] = list + if not p then + p = avatarRow(m) + Union.players[slot] = p + Union.memberIds[slot] = m.id + Union.noteUnionRoomPlayer(p.name) + fresh = true + end + p.gen = gen + p.gone = nil + p.online = m.online + p.status = m.status + p.group = m.group + p.board = m.board + p.activity = Union.memberActivity(m) end end - local changed, fresh = false, false - local now = Union.clock() - for slot = 1, Union.MAX_LEADERS do + for slot = 1, cap do local p = Union.players[slot] - if p and leaders[p.id] then - p.missingSince = nil - elseif p and not p.gone then - if present[p.id] then - p.gone = true - else - p.missingSince = p.missingSince or now - if now - p.missingSince >= Union.GONE_GRACE_SECONDS then p.gone = true end - end - end - end - for _, m in ipairs(members) do - if leaders[m.id] then - local slot = Union.slotForId(m.id) - local p = slot and Union.players[slot] or nil - local activity = Union.memberActivity(m) - if p then - if p.gone or p.activity ~= activity or partnerSig(p.partners) ~= partnerSig(partners[m.id]) then - changed = true - end - p.gone = nil - p.board = m.board - p.recruiting = m.recruiting - p.status = m.status - p.group = m.group - p.activity = activity - p.partners = partners[m.id] - elseif not slot then - for s = 1, Union.MAX_LEADERS do - if not Union.players[s] then - slot = s - break - end - end - if slot then - local row = avatarRow(m) - row.activity = activity - row.board = m.board - row.recruiting = m.recruiting - row.status = m.status - row.group = m.group - row.partners = partners[m.id] - Union.memberIds[slot] = m.id - Union.players[slot] = row - Union.noteUnionRoomPlayer(row.name) - fresh, changed = true, true - end - end - end + if p and p.gen ~= gen then p.gone = true end end -- pokefirered/src/union_room.c:2783 if fresh and Union._synced then playSe("SE_NOTE_C") end - if changed then Union.scheduleRefresh() end Union._synced = true + Union.refreshPlaza() return true end +function Union.plazaOffline() + local now = Union.clock() + Union._plazaSynced = false + Union._offlineSince = Union._offlineSince or now + if Union._offlineWiped or now - Union._offlineSince < Union.GONE_GRACE_SECONDS then return end + Union._offlineWiped = true + for slot = 1, Union.capacity() do + local p = Union.players[slot] + if p then p.gone = true end + end + Union.refreshPlaza() +end + +function Union.checkUpgrade() + if Union._upgradeShown or Union.state ~= "main" or Union.flow then return end + local up = link().clientCall("upgradeRequired") + if not up then return end + Union._upgradeShown = true + local M = message() + if M and M.show then + Union.printAndExit(require("src.online.Protocol2").upgradeText(up)) + end +end + -- pokefirered/src/union_room.c:3106 function Union.pollIncoming() local L = link() - if Union.state == "init" or Union.state == "search" then return end + if Union.state == "init" then return end for _, inv in ipairs(L.clientCall("invites") or {}) do local id = type(inv) == "table" and inv.id or nil if id ~= nil and not Union._answered[id] then @@ -2048,16 +1565,13 @@ end function Union.relayTick(_dt) local L = link() if not L.online() then - for slot = Union.MAX_LEADERS, 1, -1 do - local p = Union.players[slot] - if p and not p.gone then p.gone = true end - end - Union.handleRefresh() + Union.plazaOffline() Union.animateAll() + Union.checkUpgrade() return end + Union._offlineSince, Union._offlineWiped = nil, nil Union.syncPlaza() - Union.handleRefresh() Union.animateAll() Union.pollIncoming() if Union.state == "main" and L.link then @@ -2175,15 +1689,16 @@ function Union.toMain() Union.flow = nil Union.activity = nil Union.state = "main" + if Union._talkSlot then Union.updateMemberFacing(Union._talkSlot) end Union.releaseScript() end -- pokefirered/src/union_room.c:3455 -function Union.printAndExit(text, slot, member) +function Union.printAndExit(text, slot) return Union.runFlow(stepsOf( Union.sayStep(text), Union.doStep(function() - Union.updateMemberFacing(slot, member) + Union.updateMemberFacing(slot) Union.toMain() end) ), "print_and_exit") @@ -2308,32 +1823,35 @@ function Union.doSomethingPrompt(again) ), "do_something_prompt") end +function Union.chatHasRoom(p) + local g = type(p.group) == "table" and p.group or nil + local seats = g and type(g.members) == "table" and #g.members or 0 + return seats < Union.GROUP_SIZE +end + -- pokefirered/src/union_room.c:2805 -function Union.talkTo(slot, member) - member = member or 0 +function Union.talkTo(slot) local p = Union.players[slot] if not p or p.gone then - return Union.printAndExit(RomText.ascii("gText_UR_TrainerAppearsBusy"), slot, member) + return Union.printAndExit(RomText.ascii("gText_UR_TrainerAppearsBusy"), slot) end Union.partnerId = slot Union._partner = p local raw = math.floor(tonumber(p.activity) or 0) % Union.IN_UNION_ROOM - local idle = raw == Union.ACTIVITY.NONE or raw == Union.ACTIVITY.PLYRTALK or raw == Union.ACTIVITY.SEARCH - if member == 0 and idle then return Union.doSomethingPrompt(false) end - local who = member == 0 and p or (p.partners and p.partners[member]) or p - local g = genderIndex(who) - local ctx = textCtx({ stringVars = { who.name or "" } }) - if member == 0 and raw == Union.ACTIVITY.CHAT and #(p.partners or {}) < Union.GROUP_SIZE - 1 then + if idleActivity(p.activity) then return Union.doSomethingPrompt(false) end + local g = genderIndex(p) + local ctx = textCtx({ stringVars = { p.name or "" } }) + if raw == Union.ACTIVITY.CHAT and Union.chatHasRoom(p) then local met = Union.metBefore(p) and 1 or 0 return Union.runFlow(stepsOf( Union.stayStep(RomText.ascii(Union.JOIN_CHAT_TEXTS[met][g], ctx)), Union.yesNoStep(function(yes) if yes then return Union.joinChat(slot) end - Union.printAndExit(RomText.ascii(RomText.key("gTexts_UR_DeclineChat", g), ctx), slot, member) + Union.printAndExit(RomText.ascii(RomText.key("gTexts_UR_DeclineChat", g), ctx), slot) end) ), "recv_join_chat_request") end - return Union.printAndExit(Union.reactionText(p.activity, g, who.name), slot, member) + return Union.printAndExit(Union.reactionText(p.activity, g, p.name), slot) end -- pokefirered/src/union_room.c:3027 @@ -2388,7 +1906,6 @@ function Union.pollMain(ctx) if result ~= 0 then L.setVar(ctx, L.VAR_RESULT, 0) if result == Union.INTERACT_ATTENDANT then return Union.attendant() end - if result >= 1 and result <= Union.MAX_LEADERS then return Union.talkTo(result, 0) end Union.releaseScript() return end @@ -2396,10 +1913,10 @@ function Union.pollMain(ctx) local Hud = package.loaded["src.ui.game3.hud"] if Hud and Hud.busy and Hud.busy() then return end if not pressedA() then return end - local slot, member = Union.tryInteractWithMember() + local slot = Union.tryInteractWithMember() if slot then playSe("SE_SELECT") - return Union.talkTo(slot, member) + return Union.talkTo(slot) end if Union.facingTradingBoard() then return Union.checkTradingBoard() end end @@ -2407,10 +1924,11 @@ end function Union.facingTradingBoard() local P = playerMod() if not P or P.moving then return false end - local d = ({ down = { 0, 1 }, up = { 0, -1 }, left = { -1, 0 }, right = { 1, 0 } })[P.facing or "down"] + local d = FACING_DELTA[P.facing or "down"] if not d then return false end - return (tonumber(P.cellX) or 0) + d[1] == Union.TRADING_BOARD.x - and (tonumber(P.cellY) or 0) + d[2] == Union.TRADING_BOARD.y + local board = plazaMap().TRADING_BOARD or Union.TRADING_BOARD + return (tonumber(P.cellX) or 0) + d[1] == board.x + and (tonumber(P.cellY) or 0) + d[2] == board.y end function Union.namedRequest(name) @@ -2496,7 +2014,7 @@ function Union.relayUpdate(dt, ctx) if Union.flow then return true end end local st = Union.state - if st == "init" or st == "search" then + if st == "init" then Union.state = "main" elseif st == "main" then Union.pollMain(ctx) @@ -2601,8 +2119,7 @@ function Union.pollInvite() text = RomText.ascii("gText_UR_TrainerAppearsBusy") end if M and M.isOpen and M.isOpen() then M.close() end - if Union.relay and M and M.show then return Union.printAndExit(text) end - if M and M.show then M.show(text) end + if M and M.show then return Union.printAndExit(text) end Union.state = "print_and_exit" end @@ -2669,7 +2186,7 @@ function Union.pollAwaitLink(dt) if raw == Union.ACTIVITY.CARD and not L.peerCard and a.t < Union.CARD_WAIT_SECONDS then return end Union._await = nil local M = message() - if Union.relay and M and M.show and type(love) == "table" and love.graphics then + if M and M.show and type(love) == "table" and love.graphics then if raw == Union.ACTIVITY.CARD then return Union.cardFlow() end return Union.printStartActivity() end @@ -3459,7 +2976,6 @@ function Union.reset() Union.stop("reset") Union.state = "off" Union.players = {} - Union._spawned = {} Union.memberIds = {} Union.partnerId = nil Union.activity = nil @@ -3467,7 +2983,6 @@ function Union.reset() Union._name = nil Union._pump = nil Union._trade = nil - Union._waited = nil Union._requestName = nil Union.relay = false Union.invite = nil @@ -3479,10 +2994,14 @@ function Union.reset() Union._synced = false Union._groupMembers = nil Union._choose = nil - Union._objs = {} Union._vobjs = {} Union._vobjDirty = false - Union._refreshTimer = 0 + Union._vobjRebuild = false + Union._avatarWaiting = false + Union._plazaSynced = false + Union._plazaInstance, Union._plazaRev = nil, nil + Union._offlineSince, Union._offlineWiped = nil, nil + Union._upgradeShown = nil Union.flow = nil Union._partner = nil Union._role = nil diff --git a/src/core/game3/objects.lua b/src/core/game3/objects.lua index bfe75e68..f07b2197 100644 --- a/src/core/game3/objects.lua +++ b/src/core/game3/objects.lua @@ -570,35 +570,45 @@ end local VIRT_DIR_FACE = { [1] = "down", [2] = "up", [3] = "left", [4] = "right" } +local drawList = {} +local vrecs = {} + function Objects.forDraw() - local list = {} + local list = drawList + local n = 0 for _, lid in ipairs(Objects._order) do local eo = Objects._byId[lid] -- src/event_object_movement.c:8014 if eo and eo.visible and not eo.hidden and not eo.invisible and not offMap(Objects._bounds, eo) then - list[#list + 1] = eo + n = n + 1 + list[n] = eo end end -- src/event_object_movement.c:1719 - if VirtualObjects.count() > 0 then - for _, vo in ipairs(VirtualObjects.list()) do + for i = 1, VirtualObjects.slots() do + local vo = VirtualObjects.nth(i) + if vo then + local vrec = vrecs[vo.id] + if not vrec then + vrec = { virtualId = vo.id, visible = true, hidden = false } + vrecs[vo.id] = vrec + end local gid = tonumber(vo.graphicsId) or 0 - local vrec = { - virtualId = vo.id, - cellX = tonumber(vo.x) or 0, - cellY = tonumber(vo.y) or 0, - elevation = tonumber(vo.elevation) or 3, - facing = VIRT_DIR_FACE[tonumber(vo.direction)] or "down", - sprite = GfxIds.spriteFor(gid), - graphicsId = gid, - raiseY = tonumber(vo.y2) or 0, - visible = true, - hidden = false, - } - if not offMap(Objects._bounds, vrec) then list[#list + 1] = vrec end + vrec.cellX = tonumber(vo.x) or 0 + vrec.cellY = tonumber(vo.y) or 0 + vrec.elevation = tonumber(vo.elevation) or 3 + vrec.facing = VIRT_DIR_FACE[tonumber(vo.direction)] or "down" + vrec.sprite = GfxIds.spriteFor(gid) + vrec.graphicsId = gid + vrec.raiseY = tonumber(vo.y2) or 0 + if not offMap(Objects._bounds, vrec) then + n = n + 1 + list[n] = vrec + end end end + for i = #list, n + 1, -1 do list[i] = nil end return list end @@ -642,10 +652,9 @@ function Objects.blocks(tx, ty, exceptLocalId, elevation) end end -- pokefirered/src/union_room_player_avatar.c:475 - if VirtualObjects.count() > 0 then - for _, vo in ipairs(VirtualObjects.list()) do - if vo.solid == true and tonumber(vo.x) == tx and tonumber(vo.y) == ty then return true end - end + for i = 1, VirtualObjects.slots() do + local vo = VirtualObjects.nth(i) + if vo and vo.solid == true and tonumber(vo.x) == tx and tonumber(vo.y) == ty then return true end end return false end diff --git a/src/core/game3/save_schema_firered.lua b/src/core/game3/save_schema_firered.lua index 356b3b78..27c88327 100644 --- a/src/core/game3/save_schema_firered.lua +++ b/src/core/game3/save_schema_firered.lua @@ -76,6 +76,19 @@ local CONTINUE_GAME_WARP = 0x01 -- pokefirered/data/maps/PokemonLeague_HallOfFame/scripts.inc:40 local HALL_OF_FAME_MAP = "FR_POKEMON_LEAGUE_HALL_OF_FAME" +local UNION_ROOMS = { FR_UNION_ROOM = true, FR_UNION_ROOM_PLAZA = true } +-- pokefirered/data/maps/ViridianCity_PokemonCenter_2F/map.json:84 +local UNION_DOOR_X, UNION_DOOR_Y = 5, 1 +local FIRST_CENTER_2F = "FR_VIRIDIAN_CITY_POKEMON_CENTER_2F" + +local function union_room_door_map(session) + local heal = type(session.healMap) == "string" and session.healMap or "" + local city = heal:match("^(.+_POKEMON_CENTER)_1F$") + if city then return city .. "_2F" end + if heal:match("_POKECENTER$") then return heal .. "_2F" end + return FIRST_CENTER_2F +end + -- pokefirered/src/overworld.c:1706 CB2_ContinueSavedGame local function use_continue_game_warp(session, mounted) local Bit = require("bit") @@ -87,6 +100,11 @@ local function use_continue_game_warp(session, mounted) return end session._continueWarpDeferred = nil + if UNION_ROOMS[session.map] then + session.map, session.x, session.y, session.facing = + union_room_door_map(session), UNION_DOOR_X, UNION_DOOR_Y, "down" + return + end if session.map == HALL_OF_FAME_MAP then local Field = require("src.core.game3.field") if not mounted and not Field.flyDestinationsMounted() then @@ -111,6 +129,7 @@ local LINK_ROOMS = { FR_RECORD_CORNER = true, FR_BATTLE_COLOSSEUM_4P = true, FR_UNION_ROOM = true, + FR_UNION_ROOM_PLAZA = true, } -- pokefirered/src/load_save.c:149 SetContinueGameWarpStatusToDynamicWarp diff --git a/src/core/game3/scripting/adapters.lua b/src/core/game3/scripting/adapters.lua index 4f9dfd99..af38c110 100644 --- a/src/core/game3/scripting/adapters.lua +++ b/src/core/game3/scripting/adapters.lua @@ -1228,6 +1228,12 @@ function Adapters.host(mod, game, world) return v end local cx, cy = as_coord(x), as_coord(y) + if mapId == "FR_UNION_ROOM" then + local Plaza = require("src.core.game3.link.union_plaza_map") + Plaza.ensure(resolveGame()) + mapId = Plaza.MAP_ID + cx, cy = Plaza.entry() + end local wid = tonumber(warpId) if (not cx or not cy) and wid and wid ~= 0xFF and wid >= 0 then local def = w and w.data and w.data.maps and w.data.maps[mapId] diff --git a/src/core/game3/virtual_objects.lua b/src/core/game3/virtual_objects.lua index ac2e379a..735fdde9 100644 --- a/src/core/game3/virtual_objects.lua +++ b/src/core/game3/virtual_objects.lua @@ -64,6 +64,15 @@ function VirtualObjects.list() return out end +function VirtualObjects.slots() + return #order +end + +function VirtualObjects.nth(i) + local id = order[i] + return id and byId[id] or nil +end + function VirtualObjects.count() local n = 0 for _ in pairs(byId) do n = n + 1 end diff --git a/src/import/LauncherSettings.lua b/src/import/LauncherSettings.lua index 8c0fec24..ec38eef7 100644 --- a/src/import/LauncherSettings.lua +++ b/src/import/LauncherSettings.lua @@ -344,20 +344,12 @@ local function coreRows(opts, hooks) local okSpd, GameSpeed = pcall(require, "src.core.GameSpeed") if okSpd then - -- Per-category (RFC 0007): overworld/battle/menu each cycle their own - -- multiplier, mirroring OptionsMenu.lua's three rows. add(Strings("OVERWORLD SPEED"), function() return GameSpeed.levelLabel(opts.speedOverworld) end, function(dir) opts.speedOverworld = GameSpeed.cycle(opts.speedOverworld, dir) return true end) - add(Strings("BATTLE SPEED"), - function() return GameSpeed.levelLabel(opts.speedBattle) end, - function(dir) - opts.speedBattle = GameSpeed.cycle(opts.speedBattle, dir) - return true - end) add(Strings("MENU SPEED"), function() return GameSpeed.levelLabel(opts.speedMenu) end, function(dir) diff --git a/src/link/Wire.lua b/src/link/Wire.lua index 0c9d9427..a6d59493 100644 --- a/src/link/Wire.lua +++ b/src/link/Wire.lua @@ -327,7 +327,7 @@ local MAX_TEAM = 6 local MAX_DEADLINES = 8 local MAX_U32 = 4294967295 local MAX_SEATS = 5 -local MAX_PLAZA = 9 +local MAX_PLAZA = 40 local MAX_DIRECT = 64 local MAX_GROUPS = 64 local MAX_AVATAR_NAME = 16 @@ -979,6 +979,7 @@ end SCHEMAS.plaza_join = function(m) return { kind = Wire.str(m.kind, nil, MAX_NAME), + cap = Wire.num(m.cap, nil, 1, MAX_PLAZA), profile = profile(m.profile), avatar = Wire.avatar(m.avatar), } @@ -992,6 +993,8 @@ SCHEMAS.plaza_state = function(m) return { kind = Wire.str(m.kind, nil, MAX_NAME), instance = Wire.num(m.instance, nil, 0, MAX_INT), + cap = Wire.num(m.cap, nil, 1, MAX_PLAZA), + rev = Wire.num(m.rev, nil, 0, MAX_INT), you = Wire.num(m.you, nil, 1, MAX_PLAZA), members = type(m.members) == "table" and Wire.list(m.members, MAX_PLAZA, Wire.member) or nil, @@ -1002,6 +1005,7 @@ SCHEMAS.plaza_delta = function(m) return { kind = Wire.str(m.kind, nil, MAX_NAME), instance = Wire.num(m.instance, nil, 0, MAX_INT), + rev = Wire.num(m.rev, nil, 0, MAX_INT), joined = Wire.list(m.joined, MAX_PLAZA, Wire.member), left = idList(m.left, MAX_PLAZA), changed = Wire.list(m.changed, MAX_PLAZA, Wire.member), diff --git a/src/mods/Loader.lua b/src/mods/Loader.lua index b1c3a5a3..c473b2e5 100644 --- a/src/mods/Loader.lua +++ b/src/mods/Loader.lua @@ -258,11 +258,14 @@ function Loader:_installDevShim() -- doing it is the hole this closes, and any future path that runs mod -- code without a sandbox env still lands here. local owner = Runtime.currentMod or Runtime.modRequire - if owner or callerIsMod(3) then + if owner then local id = type(owner) == "string" and owner or nil local denial = Sandbox.moduleDenial(name, devShim.permissions[id]) or (id and crossGenerationDenial(name, devShim.generation)) if denial then error(("[%s] %s"):format(id or "mod", denial), 0) end + else + local denial = Sandbox.moduleDenial(name, nil) + if denial and callerIsMod(3) then error(("[mod] %s"):format(denial), 0) end end if devShim.dev or devShim.generation ~= 1 then scanRequire(name) end -- The Gen 1 name a mod asked for, answered by this generation's compat arm. diff --git a/src/online/Client.lua b/src/online/Client.lua index 35bcdd11..5f7ed943 100644 --- a/src/online/Client.lua +++ b/src/online/Client.lua @@ -143,6 +143,11 @@ function Client.upgradeRequired() return S.upgrade end function Client.invites() return S.invites end function Client.outgoing() return S.outgoing end function Client.plaza() return S.plaza end +function Client.plazaRev() + local p = S.plaza + if not p then return nil end + return p.instance, p.rev +end function Client.plazaCounts() return S.plazaCounts end function Client.group() return S.group end function Client.direct() return S.direct end @@ -747,6 +752,7 @@ local function applyPlazaDelta(msg) and msg.instance ~= plaza.instance then return false end + if type(msg.rev) == "number" then plaza.rev = msg.rev end local gone = {} for _, id in ipairs(msg.left or {}) do gone[id] = true end local members = {} @@ -831,7 +837,7 @@ local function resendState() if S.presence then sendRaw(Protocol2.presence(S.presence)) end for _, kind in ipairs({ "union", "wireless" }) do local j = S.plazaJoins[kind] - if j then sendRaw(Protocol2.plazaJoin(kind, j.profile, j.avatar)) end + if j then sendRaw(Protocol2.plazaJoin(kind, j.profile, j.avatar, j.cap)) end end local board = S.presence and S.presence.board if S.plazaJoins.union and type(board) == "table" then @@ -1051,7 +1057,7 @@ local function handle(msg) emit("invite_closed", msg) elseif kind == "plaza_state" then S.plaza = { kind = msg.kind, instance = msg.instance, you = msg.you, - members = sortMembers(msg.members) } + cap = msg.cap, rev = msg.rev, members = sortMembers(msg.members) } emit("plaza", S.plaza) elseif kind == "plaza_delta" then if applyPlazaDelta(msg) then emit("plaza", S.plaza) end @@ -1398,10 +1404,11 @@ function Client.replyInvite(id, accept) return sendRaw(Protocol2.inviteReply(id, accept == true)) end -function Client.joinPlaza(kind, profile, avatar) +function Client.joinPlaza(kind, profile, avatar, cap) profile = profile or defaultProfile(3) - S.plazaJoins[kind] = { profile = profile, avatar = avatar } - return sendRaw(Protocol2.plazaJoin(kind, profile, avatar)) + if cap == nil and kind == "union" then cap = Protocol2.PLAZA_CAP end + S.plazaJoins[kind] = { profile = profile, avatar = avatar, cap = cap } + return sendRaw(Protocol2.plazaJoin(kind, profile, avatar, cap)) end function Client.leavePlaza(kind) diff --git a/src/online/Protocol2.lua b/src/online/Protocol2.lua index 8f455801..47af9e49 100644 --- a/src/online/Protocol2.lua +++ b/src/online/Protocol2.lua @@ -98,9 +98,11 @@ function Protocol2.inviteReply(id, accept) return build({ type = "invite_reply", id = id, accept = accept == true }) end -function Protocol2.plazaJoin(kind, profile, avatar) +Protocol2.PLAZA_CAP = 40 + +function Protocol2.plazaJoin(kind, profile, avatar, cap) return build({ type = "plaza_join", kind = kind, profile = profile, - avatar = avatar }) + avatar = avatar, cap = cap }) end function Protocol2.plazaLeave(kind) @@ -399,11 +401,14 @@ end VALIDATORS.plaza_state = function(m) if type(m.members) ~= "table" then return nil, "plaza_state without members" end if type(m.kind) ~= "string" then return nil, "plaza_state without a kind" end + if m.rev ~= nil and type(m.rev) ~= "number" then return nil, "plaza_state rev is not a number" end + if m.cap ~= nil and type(m.cap) ~= "number" then return nil, "plaza_state cap is not a number" end return m end VALIDATORS.plaza_delta = function(m) if type(m.kind) ~= "string" then return nil, "plaza_delta without a kind" end + if m.rev ~= nil and type(m.rev) ~= "number" then return nil, "plaza_delta rev is not a number" end return m end diff --git a/src/render/BattleTransition.lua b/src/render/BattleTransition.lua index aa214344..012a146d 100644 --- a/src/render/BattleTransition.lua +++ b/src/render/BattleTransition.lua @@ -14,6 +14,7 @@ local Runtime = require("src.mods.Runtime") local BattleTransition = {} BattleTransition.__index = BattleTransition BattleTransition.isOpaque = false -- draws over the frozen overworld +BattleTransition.isFixedSpeed = true -- BattleTransition_FlashScreenPalettes: fade to black and back, then to -- white and back; each palette held 2 frames, whole sequence played 3 diff --git a/src/ui/OptionsMenu.lua b/src/ui/OptionsMenu.lua index 517b2d2f..cdc9f444 100644 --- a/src/ui/OptionsMenu.lua +++ b/src/ui/OptionsMenu.lua @@ -529,10 +529,7 @@ local function buildRows(game) return true end }, -- fast-forward the logic clock only; music and sfx keep their tempo - -- (src/core/GameSpeed.lua), so this is safe to leave on. Per-category - -- (RFC 0007): overworld walking, battle turns and menu navigation each - -- cycle their own multiplier -- GameSpeed.CATEGORIES is the single - -- source of truth for which three rows exist. + -- (src/core/GameSpeed.lua), so this is safe to leave on. { id = "speedOverworld", label = Strings("OVERWORLD SPEED"), value = function(g) return gameSpeedLabel(g.save.options.speedOverworld) @@ -542,15 +539,6 @@ local function buildRows(game) o.speedOverworld = GameSpeed.cycle(o.speedOverworld, dir) return true end }, - { id = "speedBattle", label = Strings("BATTLE SPEED"), - value = function(g) - return gameSpeedLabel(g.save.options.speedBattle) - end, - step = function(g, dir) - local o = g.save.options - o.speedBattle = GameSpeed.cycle(o.speedBattle, dir) - return true - end }, { id = "speedMenu", label = Strings("MENU SPEED"), value = function(g) return gameSpeedLabel(g.save.options.speedMenu) @@ -726,7 +714,7 @@ local GROUPS = { members = { "uiLayout", "videoMode", "orientation", "faithfulRes", "screenPos", "fpsCap", "vsync", "logicClock" } }, { id = "group.speed", label = "SPEED", - members = { "textSpeed", "speedOverworld", "speedBattle", "speedMenu" } }, + members = { "textSpeed", "speedOverworld", "speedMenu" } }, { id = "group.graphics", label = "GRAPHICS", members = { "colors", "uiLetterbox", "shaderfx", "shaderfx2" } }, -- A mod's Pipelines row splices in after TILT and is in no group, so it diff --git a/src/ui/game3/bag_menu.lua b/src/ui/game3/bag_menu.lua index 967f3e28..5d2eb95b 100644 --- a/src/ui/game3/bag_menu.lua +++ b/src/ui/game3/bag_menu.lua @@ -61,7 +61,7 @@ end -- src/union_room.c:4558 InUnionRoom local function link_menus_active() local Map = package.loaded["src.core.game3.map"] - if Map and Map.current == "FR_UNION_ROOM" then return true end + if Map and require("src.core.game3.link.union_room").isUnionMap(Map.current) then return true end local Link = package.loaded["src.core.game3.link"] return type(Link) == "table" and Link.link ~= nil and Link.inLinkRoom() == true end diff --git a/src/ui/game3/option_rows.lua b/src/ui/game3/option_rows.lua index baac784c..cd2d0e56 100644 --- a/src/ui/game3/option_rows.lua +++ b/src/ui/game3/option_rows.lua @@ -70,7 +70,6 @@ function Rows.build(ctx) step = function(c, dir) return cartCycle(c, "textSpeed", 3, dir) end, }) add(speedRow("speedOverworld", "OVERWORLD SPEED", "speedOverworld")) - add(speedRow("speedBattle", "BATTLE SPEED", "speedBattle")) add(speedRow("speedMenu", "MENU SPEED", "speedMenu")) add({ @@ -397,7 +396,7 @@ end Rows.GROUPS = { { id = "group.speed", label = "SPEED", - members = { "textSpeed", "speedOverworld", "speedBattle", "speedMenu" } }, + members = { "textSpeed", "speedOverworld", "speedMenu" } }, { id = "group.video", label = "VIDEO", members = { "uiLayout", "videoMode", "orientation", "faithfulRes", "screenPos", "fpsCap", "vsync", "logicClock" } }, diff --git a/src/ui/game3/start_menu.lua b/src/ui/game3/start_menu.lua index fae3fe36..456d101f 100644 --- a/src/ui/game3/start_menu.lua +++ b/src/ui/game3/start_menu.lua @@ -40,7 +40,7 @@ end local function in_union_room(session) local Map = package.loaded["src.core.game3.map"] local cur = (Map and type(Map.current) == "string" and Map.current) or (session and session.map) - return cur == "FR_UNION_ROOM" + return require("src.core.game3.link.union_room").isUnionMap(cur) end local function safari_active(session) diff --git a/src/ui/game3/union_room.lua b/src/ui/game3/union_room.lua index 9d978bdb..6c3c40a0 100644 --- a/src/ui/game3/union_room.lua +++ b/src/ui/game3/union_room.lua @@ -21,6 +21,9 @@ UnionRoomScreen.TYPES_TEMPLATE = Window.template(20, 2, 9, 11) UnionRoomScreen.BOARD_HEADER_TEMPLATE = Window.template(1, 1, 28, 2) -- pokefirered/src/data/union_room.h:302 UnionRoomScreen.BOARD_TEMPLATE = Window.template(1, 5, 28, 10) +-- pokefirered/src/union_room.c:4400 +UnionRoomScreen.BOARD_ROWS = 8 +UnionRoomScreen.BOARD_EXIT = "exit" -- pokefirered/src/data/union_room.h:197 UnionRoomScreen.ROW_HEIGHT = 14 @@ -202,14 +205,15 @@ function UnionRoomScreen.showBoard(opts) if item.entry then UnionRoomScreen.printBoardRow(item.entry, px, py, UnionRoomScreen.BOARD_SELF) end end } local offers = opts.offers or {} - for i = 0, 7 do + for i = 0, math.max(UnionRoomScreen.BOARD_ROWS, #offers) - 1 do local entry = offers[i + 1] rows[#rows + 1] = { label = "", id = i, disabled = entry == nil, entry = entry, print = function(item, px, py) if item.entry then UnionRoomScreen.printBoardRow(item.entry, px, py, UnionRoomScreen.BOARD_OTHER) end end } end - rows[#rows + 1] = { label = RomText.plain("gText_UR_Exit2"), id = 8, colors = UnionRoomScreen.BOARD_OTHER } + rows[#rows + 1] = { label = RomText.plain("gText_UR_Exit2"), id = UnionRoomScreen.BOARD_EXIT, + colors = UnionRoomScreen.BOARD_OTHER } local shown = UnionRoomScreen.showList("board", { template = UnionRoomScreen.BOARD_TEMPLATE, items = rows, diff --git a/src/ui/game3/wireless_icon.lua b/src/ui/game3/wireless_icon.lua index e954a6fe..ed051592 100644 --- a/src/ui/game3/wireless_icon.lua +++ b/src/ui/game3/wireless_icon.lua @@ -150,6 +150,7 @@ end function WirelessIcon.onLinkMap(mapId) if type(mapId) ~= "string" then return false end if WirelessIcon.LINK_MAPS[mapId] then return true end + if require("src.core.game3.link.union_room").isUnionMap(mapId) then return true end return mapId:match("_POKEMON_CENTER_2F$") ~= nil end diff --git a/src/ui/gen2/BattleState.lua b/src/ui/gen2/BattleState.lua index 38556edb..47aecf5a 100644 --- a/src/ui/gen2/BattleState.lua +++ b/src/ui/gen2/BattleState.lua @@ -54,6 +54,7 @@ local Unown = require("src.core.gen2.Unown") local BattleState = {} BattleState.__index = BattleState BattleState.isOpaque = true +BattleState.isBattle = true function BattleState:moveGridNavigation() if not Runtime.wantsHook("battle.move_grid_navigation") then return false end diff --git a/src/ui/gen2/BattleTransition.lua b/src/ui/gen2/BattleTransition.lua index 1a778fb3..9f9411f3 100644 --- a/src/ui/gen2/BattleTransition.lua +++ b/src/ui/gen2/BattleTransition.lua @@ -35,6 +35,7 @@ local Tilt = require("src.render.Tilt") local BattleTransition = {} BattleTransition.__index = BattleTransition BattleTransition.isOpaque = false +BattleTransition.isFixedSpeed = true local COLS, ROWS = 20, 18 -- SCREEN_WIDTH x SCREEN_HEIGHT, in tiles diff --git a/tests/drivers/battle_cry_speed_bug2087_test.lua b/tests/drivers/battle_cry_speed_bug2087_test.lua index 598e6492..8cfbb8f2 100644 --- a/tests/drivers/battle_cry_speed_bug2087_test.lua +++ b/tests/drivers/battle_cry_speed_bug2087_test.lua @@ -25,6 +25,19 @@ return function(game) ow:pushBattle(battle) U.log("logic speed", game:logicSpeed(), "sfx rate", Sound.rate()) + local function inBattle() + for _, st in ipairs(game.stack.states) do + if st == battle then return true end + end + return false + end + local function assertLocked(where) + if inBattle() and game:logicSpeed() ~= 1 then + error(("speed lock: %s ran at %sX with speedOverride 4") + :format(where, tostring(game:logicSpeed()))) + end + end + assertLocked("battle start") if Sound.rate() ~= 1 then error(("bug2087: Game:update pitched SFX off battle speed (rate %s at 4X)") :format(tostring(Sound.rate()))) @@ -58,8 +71,11 @@ return function(game) end end + local lockedFrames = 0 local shot = false for _ = 1, 2400 do + assertLocked("entrance") + if inBattle() then lockedFrames = lockedFrames + 1 end poll("entrance cry") if battle.phase == "menu" then break end if battle.waitingSound and not shot then @@ -87,6 +103,7 @@ return function(game) for _ = 1, 2400 do poll("post-move sfx") if game.stack:top() ~= battle then break end + assertLocked("post-move") if #gates > before and cur and not shotLevel then shotLevel = U.shot(game, DIR .. "/bug2087_levelup.png") end @@ -105,11 +122,12 @@ return function(game) fail = ("bug2087: %s was pitched with battle speed (%s)"):format( g.label, tostring(g.pitch)) elseif g.dur and g.held < g.dur * 0.9 then - fail = ("bug2087: %s cut short at 4X (%.3fs of %.3fs)"):format( + fail = ("bug2087: %s cut short (%.3fs of %.3fs)"):format( g.label, g.held, g.dur) end end if fail then error(fail) end - U.log("PASS every battle sfx gate held for its real length at 4X") - U.log("input is yours now") + if lockedFrames == 0 then error("speed lock: the battle never reached the stack") end + U.log("PASS every battle sfx gate held for its real length, battle locked to 1X under a 4X override") + love.event.quit(0) end diff --git a/tests/drivers/battle_fanfare_speed_bug1952_test.lua b/tests/drivers/battle_fanfare_speed_bug1952_test.lua index 578abc83..e62b0ed3 100644 --- a/tests/drivers/battle_fanfare_speed_bug1952_test.lua +++ b/tests/drivers/battle_fanfare_speed_bug1952_test.lua @@ -1,5 +1,4 @@ --- Wait gates hold for the sound's real length at high GAME SPEED --- (#1952/#2087) without pitching one-shot SFX (#1990/#1991/#1997). +-- home/text.asm:506 (#1952/#2087, #1990/#1991/#1997) return function(game) local U = dofile("tests/drivers/util.lua") local DIR = os.getenv("SHOT_DIR") or os.getenv("POKEPORT_SHOT_DIR") or "/tmp/shots" @@ -26,12 +25,26 @@ return function(game) ow:pushBattle(battle) U.log("logic speed", game:logicSpeed(), "sfx rate", Sound.rate()) + local function inBattle() + for _, st in ipairs(game.stack.states) do + if st == battle then return true end + end + return false + end + local function assertLocked(where) + if inBattle() and game:logicSpeed() ~= 1 then + error(("speed lock: %s ran at %sX with speedOverride 4") + :format(where, tostring(game:logicSpeed()))) + end + end + assertLocked("battle start") if Sound.rate() ~= 1 then error(("bug1952: Game:update pitched SFX off GAME SPEED (rate %s at 4X)") :format(tostring(Sound.rate()))) end for _ = 1, 240 do + assertLocked("battle intro") if battle.phase == "menu" then break end U.tap(game, "a") U.wait(3) @@ -50,6 +63,7 @@ return function(game) local shot = false for _ = 1, 1200 do U.wait(1) + assertLocked("level-up") if battle.waitingSound and not t0 then local src = battle.waitingSound t0 = love.timer.getTime() @@ -80,13 +94,25 @@ return function(game) if not dur then error("bug1952: no duration for the level-up fanfare") end if held < dur * 0.9 then - error(("bug2087: the 4X battle cut the fanfare short (%.3fs of %.3fs)") + error(("bug2087: the battle cut the fanfare short (%.3fs of %.3fs)") :format(held, dur)) end if held > dur + 1 then error(("bug1952: the fanfare dragged past its length (%.3fs of %.3fs)") :format(held, dur)) end - U.log("PASS the fanfare kept natural pitch and played to completion at 4X") - love.event.quit() + for _ = 1, 2400 do + if not inBattle() then break end + assertLocked("battle end") + U.tap(game, "a") + U.wait(1) + end + if inBattle() then error("speed lock: the battle never ended") end + U.wait(2) + if game:logicSpeed() ~= 4 then + error(("speed lock: after the battle logic speed is %s, want 4") + :format(tostring(game:logicSpeed()))) + end + U.log("PASS the fanfare kept natural pitch at 1X in a 4X-override battle, 4X back after") + love.event.quit(0) end diff --git a/tests/drivers/g3link_union_plaza.lua b/tests/drivers/g3link_union_plaza.lua index 278bf073..499aeaff 100644 --- a/tests/drivers/g3link_union_plaza.lua +++ b/tests/drivers/g3link_union_plaza.lua @@ -2,7 +2,9 @@ local U = require("tests.drivers.util") local DIR = os.getenv("POKEPORT_SHOT_DIR") or "/tmp/g3link" local CENTER_2F = "FR_VIRIDIAN_CITY_POKEMON_CENTER_2F" -local UNION_ROOM = "FR_UNION_ROOM" +local Plaza = require("src.core.game3.link.union_plaza_map") +local UNION_ROOM = Plaza.MAP_ID +local OTHERS = Plaza.CAP - 1 -- pokefirered/include/constants/flags.h:1375 local FLAG_SYS_POKEDEX_GET = 0x829 -- pokefirered/include/constants/metatile_behaviors.h:104 @@ -135,13 +137,82 @@ return function(game) me.presence.where = "union" local blue = peer("b0000002", "BLUE", 0x2222, 0, "leafgreen") - local leaf = peer("c0000003", "LEAF", 0x3131, 1, "firered") - relay:handle(blue, { type = "plaza_join", kind = "union", profile = live, avatar = blue.avatar }) - relay:handle(leaf, { type = "plaza_join", kind = "union", profile = live, avatar = leaf.avatar }) - result(waitFor(function() return Union.playerCount() == 2 end, 10, Union.REFRESH_FRAMES + 30), - "both plaza members appear as union room avatars") + relay:handle(blue, { type = "plaza_join", kind = "union", cap = 40, profile = live, avatar = blue.avatar }) + local crowd = { blue } + for i = 2, OTHERS do + local s = peer(string.format("c%07x", i), "T" .. i, 0x100 + i * 13, i % 2, i % 3 == 0 and "leafgreen" or "firered") + relay:handle(s, { type = "plaza_join", kind = "union", cap = 40, profile = live, avatar = s.avatar }) + crowd[#crowd + 1] = s + end + result(waitFor(function() return Union.playerCount() == OTHERS end, 10, 120), + "all 39 other plaza members appear as avatars") + result(waitFor(function() + local VirtualObjects = require("src.core.game3.virtual_objects") + return VirtualObjects.count() == OTHERS + end, 5, 60), "39 virtual objects, no cart map objects") + local mySlot = Client.plaza() and Client.plaza().you + result(mySlot ~= nil and Union.players[mySlot] == nil, "our own slot is not drawn") + local cellsOk = true + for slot = 1, Plaza.CAP do + if slot ~= mySlot then + local v = Union.vobj(slot) + local x, y = Plaza.cellFor(slot) + if not (v and v.visible and v.x == x and v.y == y) then cellsOk = false end + end + end + result(cellsOk, "every avatar stands on its slot's cell") wait(60) - U.shot(game, DIR .. "/g3link_union_plaza_avatars.png") + U.still(game, DIR .. "/g3link_union_plaza_entrance.png") + place(12, 12, "down") + wait(20) + U.still(game, DIR .. "/g3link_union_plaza_full_room.png") + place(22, 3, "left") + wait(20) + U.still(game, DIR .. "/g3link_union_plaza_far_corner.png") + + local far = crowd[#crowd] + local farSlot = Union.slotForId(far.id) + if farSlot ~= Plaza.CAP then + for _, s in ipairs(crowd) do + if Union.slotForId(s.id) == Plaza.CAP then far, farSlot = s, Plaza.CAP end + end + end + local fx, fy = Plaza.cellFor(Plaza.CAP) + result(farSlot == Plaza.CAP, "someone holds slot 40 at " .. tostring(fx) .. "," .. tostring(fy)) + place(12, 22, "up") + wait(10) + local function walk(dir, axis, target) + for _ = 1, 600 do + local v = axis == "x" and Player.cellX or Player.cellY + if v == target then + waitFor(function() return not Player.moving end, 2, 60) + return (axis == "x" and Player.cellX or Player.cellY) == target + end + if Player.moving then wait(1) else U.hold(game, dir, 1) end + end + return false + end + local walked = walk("up", "y", 18) and walk("left", "x", fx + 1) and walk("up", "y", fy) + if walked and Player.facing ~= "left" then + U.tap(game, "left") + wait(6) + end + print("[driver] walked to " .. tostring(Player.cellX) .. "," .. tostring(Player.cellY) .. " " .. tostring(Player.facing)) + result(walked and Player.cellX == fx + 1 and Player.cellY == fy, "walked through the crowd to slot 40's cell") + U.tap(game, "a") + local prompt = waitFor(function() + if Message.isOpen() and Message.isWaiting() and (Message._page or 1) < #(Message._pages or {}) then + U.tap(game, "a") + end + local Screen = require("src.ui.game3.union_room") + return Screen.isOpen() and Screen.mode == "activity" + end, 8, 600) + result(prompt, "talking to slot 40 opens the do-something prompt") + result(Union.vobj(Plaza.CAP).dir == Union.DIR.EAST, "slot 40 turned to face the player") + wait(10) + U.still(game, DIR .. "/g3link_union_plaza_slot40_prompt.png") + U.tap(game, "b") + drive(function() return Union.state == "main" and not Message.isOpen() end, 8) relay:handle(blue, { type = "invite", to = "a0000001", activity = "chat", detail = {}, profile = live }) result(waitFor(function() return Union.state == "player_contacted_you" or Union.state == "handle_activity_request" end, @@ -170,8 +241,16 @@ return function(game) "leaving the chat ends it") result(Client.room() == nil, "and leaves the private room") - Map.load(nil, game, CENTER_2F, { x = 7, y = 5, facing = "down" }) - wait(90) + place(12, 22, "down") + wait(10) + for _ = 1, 20 do + if Map.current == CENTER_2F then break end + U.hold(game, "down", 8) + relay:pump() + end + result(waitFor(function() return Map.current == CENTER_2F end, 8, 300), "the exit pad warps back to the PC 2F") + wait(60) + U.still(game, DIR .. "/g3link_union_plaza_exit_2f.png") result(Union.state == "off", "leaving the Union Room stops it") result(Client.plaza() == nil, "and leaves the plaza") @@ -194,9 +273,9 @@ return function(game) local rows = LinkMenu.rows print("[driver] rows trade=" .. tostring(rows[1] and rows[1].count) .. " battle=" .. tostring(rows[2] and rows[2].count) .. " union=" .. tostring(rows[3] and rows[3].count) .. " total=" .. tostring(rows[4] and rows[4].count)) - result(rows[Status.GROUPTYPE.UNION] and rows[Status.GROUPTYPE.UNION].count == 2, - "UNION ROOM counts the two plaza members") - result(rows[Status.GROUPTYPE.TOTAL] and rows[Status.GROUPTYPE.TOTAL].count == 2, "TOTAL = trade + battle + union") + result(rows[Status.GROUPTYPE.UNION] and rows[Status.GROUPTYPE.UNION].count == OTHERS, + "UNION ROOM counts the 39 plaza members") + result(rows[Status.GROUPTYPE.TOTAL] and rows[Status.GROUPTYPE.TOTAL].count == OTHERS, "TOTAL = trade + battle + union") result(relay.wireless["a0000001"] == true, "the monitor subscribed to wireless counts") U.shot(game, DIR .. "/g3link_wireless_monitor_counts.png") U.tap(game, "a") diff --git a/tests/drivers/g3link_union_plaza_live.lua b/tests/drivers/g3link_union_plaza_live.lua new file mode 100644 index 00000000..2ae400a1 --- /dev/null +++ b/tests/drivers/g3link_union_plaza_live.lua @@ -0,0 +1,228 @@ +local U = require("tests.drivers.util") +local DIR = os.getenv("POKEPORT_SHOT_DIR") or "/tmp/g3link" + +local CENTER_2F = "FR_VIRIDIAN_CITY_POKEMON_CENTER_2F" +local Plaza = require("src.core.game3.link.union_plaza_map") +-- pokefirered/include/constants/flags.h:1375 +local FLAG_SYS_POKEDEX_GET = 0x829 +local ROLE = os.getenv("B4_ROLE") or "A" +local NAMES = { A = "ALICE", B = "BOB", C = "CAROL" } +local NAME = NAMES[ROLE] +-- pokefirered/include/constants/species.h:10 +local CHARIZARD, CATERPIE, BULBASAUR = 6, 10, 1 + +local failures = 0 +local function result(ok, label) + print((ok and "PASS " or "FAIL ") .. "[" .. ROLE .. "] " .. label) + if not ok then failures = failures + 1 end + return ok +end + +local function finish() + local Link = package.loaded["src.core.game3.link"] + if Link then pcall(Link.reset) end + local Client = package.loaded["src.online.Client"] + if Client then pcall(Client.disconnect) end + print((failures == 0 and "PASS" or "FAIL") .. " g3link_union_plaza_live role=" .. ROLE .. " failures=" .. failures) + love.event.quit(failures == 0 and 0 or 1) + coroutine.yield() +end + +local function now() return love.timer.getTime() end + +return function(game) + print("PASS driver_started") + for _ = 1, 900 do + if game.phase == "boot" and game.boot then break end + U.wait(1) + end + game:_handleBootAction({ action = "new_game", name = NAME }) + U.wait(240) + + local Runtime = require("src.core.game3.runtime") + local Map = require("src.core.game3.map") + local Space = require("src.core.game3.scripting.space") + local Flags = require("src.core.game3.scripting.flags") + local Player = require("src.core.game3.player") + local Message = require("src.ui.game3.message") + local Choice = require("src.ui.game3.choice") + local Party = require("src.core.game3.party") + local Link = require("src.core.game3.link") + local Union = require("src.core.game3.link.union_room") + local LB = require("src.core.game3.link.battle") + local Chat = require("src.core.game3.link.chat") + local Screen = require("src.ui.game3.union_room") + local Client = require("src.online.Client") + local Natives = require("src.core.game3.scripting.natives") + local MapCatalog = require("src.import.gba.map_catalog") + + local session = Runtime.getSession() + session.name = NAME + if ROLE == "A" then Party.giveMon(session, CHARIZARD, 70) + elseif ROLE == "B" then Party.giveMon(session, CATERPIE, 3) + else Party.giveMon(session, BULBASAUR, 5) end + + local function ctx() return Space.vm and Space.vm.ctx end + local function place(x, y, facing) + Player.cellX, Player.cellY = x, y + Player.px, Player.py = x * 16, y * 16 + Player.targetX, Player.targetY = x, y + Player.facing = facing + game.session.x, game.session.y, game.session.facing = x, y, facing + end + local function waitFor(cond, seconds, onFrame) + local t0 = now() + while not cond() do + if onFrame then onFrame() end + U.wait(1) + if now() - t0 > (seconds or 5) then return false end + end + return true + end + local function pageThrough() + if Message.isOpen() and Message.isWaiting() and (Message._page or 1) < #(Message._pages or {}) then + U.tap(game, "a") + end + end + local function findByName(name) + for slot = 1, Plaza.CAP do + local p = Union.players[slot] + if p and not p.gone and p.name == name then return slot, p end + end + return nil + end + local function talkTo(slot) + local x, y = Plaza.cellFor(slot) + place(x, y + 1, "up") + U.wait(4) + U.tap(game, "a") + end + local function mashBattle(seconds) + local sawBattle = waitFor(function() return LB.state == "battle" end, 30, pageThrough) + if not sawBattle then return false, false end + local t0, k = now(), 0 + while LB.state == "battle" or LB.state == "setup" do + k = k + 1 + if k % 8 == 0 then U.tap(game, "a") else U.wait(1) end + if now() - t0 > seconds then return true, false end + end + return true, waitFor(function() return Union.state == "main" end, 30, function() + if Message.isOpen() then U.tap(game, "a") end + end) + end + + local live = Link.liveProfile() + if not result(live ~= nil, "live g3 profile (vanilla)") then return finish() end + Link.connect() + if not result(waitFor(function() return Client.state() == "online" end, 20), "online on the local relay") then + print("[driver] client state=" .. tostring(Client.state()) .. " err=" .. tostring(Client.error())) + return finish() + end + + Map.load(nil, game, CENTER_2F, { x = 5, y = 1, facing = "up" }) + U.wait(30) + Flags.setFlag(Space.store, ctx(), FLAG_SYS_POKEDEX_GET, true) + place(5, 1, "up") + U.wait(5) + -- pokefirered/data/specials.inc:12 + Natives.special(ctx(), 0x01, Space.vm.adapters) + local slotKey = MapCatalog.slotKeyFor("FR_UNION_ROOM") or "" + local group, num = slotKey:match("(%d+)%D+(%d+)") + -- pokefirered/data/scripts/cable_club.inc:797 + Space.vm.adapters.warp(tonumber(group), tonumber(num), 0xFF, 7, 11, function() end, "warpspinenter") + if not result(waitFor(function() return Space.mapId == Plaza.MAP_ID and Union.state == "main" end, 30), + "entered the plaza over the real relay") then + return finish() + end + result(waitFor(function() return Client.plaza() ~= nil end, 10), "plaza_state from the relay") + local mySlot = Client.plaza() and Client.plaza().you + print("[driver] " .. ROLE .. " slot=" .. tostring(mySlot) .. " instance=" .. tostring(Client.plaza() and Client.plaza().instance) + .. " cap=" .. tostring(Client.plaza() and Client.plaza().cap) .. " rev=" .. tostring(Client.plaza() and Client.plaza().rev)) + result(Client.plaza() and Client.plaza().cap == 40, "the relay reports a 40-cap plaza") + + if ROLE == "A" then + local slotB + result(waitFor(function() slotB = findByName("BOB") return slotB ~= nil end, 60), "BOB appears in the plaza") + if not slotB then return finish() end + U.wait(60) + local bx, by = Plaza.cellFor(slotB) + print("[driver] A sees BOB on slot " .. slotB .. " cell " .. bx .. "," .. by) + U.still(game, DIR .. "/live_a_sees_bob.png") + talkTo(slotB) + result(waitFor(function() return Screen.isOpen() and Screen.mode == "activity" end, 10, pageThrough), + "talking to BOB opens the do-something prompt") + Screen.cursor = 2 + U.tap(game, "a") + local started, back = mashBattle(180) + result(started, "the battle with BOB started") + result(back, "the battle ended and ALICE is back in the Union Room") + result(waitFor(function() return Space.mapId == Plaza.MAP_ID end, 10), "still on the plaza map") + U.wait(90) + local slotB2 = findByName("BOB") + result(Client.plaza() and Client.plaza().you == mySlot, "ALICE kept slot " .. tostring(mySlot)) + result(slotB2 == slotB, "BOB is back on slot " .. tostring(slotB)) + local v = Union.vobj(slotB) + result(v and v.visible and v.x == bx and v.y == by, "BOB's avatar stands on the same cell") + U.still(game, DIR .. "/live_a_after_battle.png") + U.wait(120) + talkTo(slotB) + result(waitFor(function() return Screen.isOpen() and Screen.mode == "activity" end, 10, pageThrough), + "BOB's menu again") + Screen.cursor = 3 + U.tap(game, "a") + result(waitFor(function() return Chat.isActive() end, 40, pageThrough), "ALICE and BOB are chatting") + local three = waitFor(function() + local room = Client.room() + return room and room.players and #room.players >= 3 + end, 120) + result(three, "CAROL joined the chat") + U.wait(120) + U.still(game, DIR .. "/live_a_chat_three.png") + Chat.stop("left") + waitFor(function() return Union.state == "main" end, 10) + elseif ROLE == "B" then + result(waitFor(function() return Choice.active end, 120, pageThrough), "ALICE's battle request rings BOB") + U.wait(10) + U.tap(game, "a") + local started, back = mashBattle(180) + result(started, "the battle with ALICE started") + result(back, "BOB is back in the Union Room") + U.wait(90) + result(Client.plaza() and Client.plaza().you == mySlot, "BOB kept slot " .. tostring(mySlot)) + local slotA = findByName("ALICE") + local ax, ay = Plaza.cellFor(slotA or 0) + local v = slotA and Union.vobj(slotA) + result(v and v.visible and v.x == ax and v.y == ay, "ALICE's avatar stands on her cell") + U.still(game, DIR .. "/live_b_after_battle.png") + result(waitFor(function() return Choice.active end, 120, pageThrough), "ALICE's chat request rings BOB") + U.wait(10) + U.tap(game, "a") + result(waitFor(function() return Chat.isActive() end, 40, pageThrough), "BOB is chatting") + waitFor(function() + local room = Client.room() + return room and room.players and #room.players >= 3 + end, 120) + waitFor(function() return not Chat.isActive() end, 60) + Chat.stop("left") + waitFor(function() return Union.state == "main" end, 10) + else + local slotB + result(waitFor(function() + slotB = findByName("BOB") + local p = slotB and Union.players[slotB] + return p and (p.activity % Union.IN_UNION_ROOM) == Union.ACTIVITY.CHAT + end, 300), "CAROL sees BOB chatting") + if not slotB then return finish() end + U.wait(30) + talkTo(slotB) + result(waitFor(function() return Choice.active end, 15, pageThrough), "the join-chat prompt") + U.still(game, DIR .. "/live_c_join_prompt.png") + U.tap(game, "a") + result(waitFor(function() return Chat.isActive() end, 40, pageThrough), "CAROL joined the chat") + U.wait(120) + U.still(game, DIR .. "/live_c_chat.png") + Chat.stop("left") + waitFor(function() return Union.state == "main" end, 10) + end + finish() +end diff --git a/tests/drivers/g3link_union_plaza_perf.lua b/tests/drivers/g3link_union_plaza_perf.lua new file mode 100644 index 00000000..c4ea43e9 --- /dev/null +++ b/tests/drivers/g3link_union_plaza_perf.lua @@ -0,0 +1,196 @@ +local U = require("tests.drivers.util") + +local CENTER_2F = "FR_VIRIDIAN_CITY_POKEMON_CENTER_2F" +local Plaza = require("src.core.game3.link.union_plaza_map") +-- pokefirered/include/constants/flags.h:1375 +local FLAG_SYS_POKEDEX_GET = 0x829 +local SECONDS = tonumber(os.getenv("PERF_SECONDS")) or 20 +local LABEL = os.getenv("POKEPORT_TOUCH") == "1" and "touch" or "desktop" + +local failures = 0 +local function result(ok, label) + print((ok and "PASS " or "FAIL ") .. label) + if not ok then failures = failures + 1 end + return ok +end + +local function finish() + local Link = package.loaded["src.core.game3.link"] + if Link then pcall(Link.reset) end + local Client = package.loaded["src.online.Client"] + if Client then pcall(Client.disconnect) end + if failures == 0 then + print("PASS g3link_union_plaza_perf") + love.event.quit(0) + else + print("FAIL g3link_union_plaza_perf failures=" .. failures) + love.event.quit(1) + end +end + +local function now() return love.timer.getTime() end + +return function(game) + print("PASS driver_started") + for _ = 1, 900 do + if game.phase == "boot" and game.boot then break end + U.wait(1) + end + game:_handleBootAction({ action = "new_game", name = "RED" }) + U.wait(240) + + local Map = require("src.core.game3.map") + local Space = require("src.core.game3.scripting.space") + local Flags = require("src.core.game3.scripting.flags") + local Player = require("src.core.game3.player") + local Message = require("src.ui.game3.message") + local Choice = require("src.ui.game3.choice") + local Link = require("src.core.game3.link") + local Union = require("src.core.game3.link.union_room") + local Client = require("src.online.Client") + local Relay = require("tests.support.fake_relay") + local Natives = require("src.core.game3.scripting.natives") + local MapCatalog = require("src.import.gba.map_catalog") + + local relay = Relay.new({ clock = function() return now() end }) + local me = relay:seat("a0000001", "RED") + Client.configure({ relayAddress = "fake:1", connect = function() return me.transport end }) + + local function ctx() return Space.vm and Space.vm.ctx end + local function wait(n) + for _ = 1, n do + relay:pump() + U.wait(1) + end + end + local function waitFor(cond, seconds) + local t0 = now() + while not cond() do + relay:pump() + U.wait(1) + if now() - t0 > (seconds or 5) then return false end + end + return true + end + local function drive(cond, seconds) + local t0 = now() + while not cond() and now() - t0 < (seconds or 10) do + if Choice.active or Message.isOpen() then U.tap(game, "a") end + wait(6) + end + return cond() + end + + local live = Link.liveProfile() + if not result(live ~= nil, "the live g3 profile computes (vanilla game)") then return finish() end + Link.connect() + result(waitFor(function() return Client.state() == "online" end, 5), "online on the relay") + Map.load(nil, game, CENTER_2F, { x = 5, y = 1, facing = "up" }) + wait(30) + Flags.setFlag(Space.store, ctx(), FLAG_SYS_POKEDEX_GET, true) + Player.cellX, Player.cellY, Player.targetX, Player.targetY = 5, 1, 5, 1 + Player.px, Player.py, Player.facing = 5 * 16, 1 * 16, "up" + wait(5) + -- pokefirered/data/specials.inc:12 + Natives.special(ctx(), 0x01, Space.vm.adapters) + local slot = MapCatalog.slotKeyFor("FR_UNION_ROOM") or "" + local group, num = slot:match("(%d+)%D+(%d+)") + -- pokefirered/data/scripts/cable_club.inc:797 + Space.vm.adapters.warp(tonumber(group), tonumber(num), 0xFF, 7, 11, function() end, "warpspinenter") + if not result(drive(function() return Space.mapId == Plaza.MAP_ID and Union.state == "main" end, 60), + "entered the plaza") then + return finish() + end + + local peers = {} + local function addPeers(n) + while #peers < n do + local i = #peers + 1 + local id = string.format("d%07x", i) + local s = relay:seat(id, "P" .. i) + relay:handle(s, { type = "lobby_hello", protocol = 3, name = "P" .. i, profiles = { live }, + presence = { where = "launcher", status = "idle", version = "firered" } }) + s.avatar = { name = "P" .. i, trainerId = i * 37, gender = i % 2, version = "firered" } + relay:handle(s, { type = "plaza_join", kind = "union", cap = 40, profile = live, avatar = s.avatar }) + peers[i] = s + end + end + + local ownUpdate, ownDraw = rawget(game, "update"), rawget(game, "draw") + local rawUpdate, rawDraw = game.update, game.draw + local upd, drw = { sum = 0, max = 0, n = 0 }, { sum = 0, max = 0, n = 0 } + local function timed(fn, acc) + return function(self, ...) + local t = love.timer.getTime() + local a, b = fn(self, ...) + local d = (love.timer.getTime() - t) * 1000 + acc.sum, acc.n = acc.sum + d, acc.n + 1 + if d > acc.max then acc.max = d end + return a, b + end + end + game.update = timed(rawUpdate, upd) + game.draw = timed(rawDraw, drw) + + local STATUSES = { "chatting", "battling", "idle" } + local function measure(n) + addPeers(n) + result(waitFor(function() return Union.playerCount() == n end, 10), n .. " avatars in the room") + Player.cellX, Player.cellY, Player.targetX, Player.targetY = 12, 12, 12, 12 + Player.px, Player.py = 12 * 16, 12 * 16 + wait(90) + upd.sum, upd.max, upd.n = 0, 0, 0 + drw.sum, drw.max, drw.n = 0, 0, 0 + collectgarbage("collect") + local kb0 = collectgarbage("count") + local last = kb0 + local allocated = 0 + local frame = { sum = 0, max = 0, n = 0 } + local builds0 = Union.plazaBuilds or 0 + local t0, tPrev, nextChange, k = now(), now(), now() + 1, 0 + while now() - t0 < SECONDS do + relay:pump() + for i = 1, #peers do + local box = peers[i].transport.inbox + for j = #box, 1, -1 do box[j] = nil end + end + if now() >= nextChange then + k = k + 1 + local s = peers[(k - 1) % n + 1] + s.status = STATUSES[(k - 1) % #STATUSES + 1] + relay:plazaChanged(s) + nextChange = nextChange + 1 + end + U.wait(1) + local t = now() + local d = (t - tPrev) * 1000 + tPrev = t + frame.sum, frame.n = frame.sum + d, frame.n + 1 + if d > frame.max then frame.max = d end + local kb = collectgarbage("count") + if kb > last then allocated = allocated + (kb - last) end + last = kb + end + local elapsed = now() - t0 + collectgarbage("collect") + local growth = collectgarbage("count") - kb0 + local line = string.format( + "PERF %s members=%d seconds=%.1f frames=%d frame_ms mean=%.2f max=%.2f update_ms mean=%.3f max=%.3f" + .. " draw_ms mean=%.3f max=%.3f alloc_kb_per_s=%.1f gc_growth_kb=%.1f status_changes=%d rebuilds=%d", + LABEL, n, elapsed, frame.n, frame.sum / math.max(1, frame.n), frame.max, + upd.sum / math.max(1, upd.n), upd.max, drw.sum / math.max(1, drw.n), drw.max, + allocated / elapsed, growth, k, (Union.plazaBuilds or 0) - builds0) + print(line) + local f = io.open(os.getenv("PERF_OUT") or "/tmp/g3link_union_plaza_perf.log", "a") + if f then + f:write(line, "\n") + f:close() + end + result((Union.plazaBuilds or 0) - builds0 <= k + 1, "one rebuild per status change at " .. n) + end + + measure(8) + measure(Plaza.CAP - 1) + game.update, game.draw = ownUpdate, ownDraw + finish() +end diff --git a/tests/drivers/g3link_union_room.lua b/tests/drivers/g3link_union_room.lua index 08aabfb0..86901a31 100644 --- a/tests/drivers/g3link_union_room.lua +++ b/tests/drivers/g3link_union_room.lua @@ -2,7 +2,8 @@ local U = require("tests.drivers.util") local DIR = os.getenv("POKEPORT_SHOT_DIR") or "/tmp/g3link" local CENTER_2F = "FR_VIRIDIAN_CITY_POKEMON_CENTER_2F" -local UNION_ROOM = "FR_UNION_ROOM" +local Plaza = require("src.core.game3.link.union_plaza_map") +local UNION_ROOM = Plaza.MAP_ID -- pokefirered/include/constants/flags.h:1375 local FLAG_SYS_POKEDEX_GET = 0x829 -- pokefirered/include/constants/species.h:5 @@ -69,16 +70,6 @@ return function(game) Party.giveMon(session, PIDGEY, 9) local relay = Relay.new({ clock = function() return now() end }) - local plazaState = relay.plazaStateMsg - relay.plazaStateMsg = function(self, s) - local msg = plazaState(self, s) - for _, m in ipairs(msg.members or {}) do - local ss = self.sessions[m.id] - if ss and ss.group then m.group = ss.group end - if ss and ss.status then m.status = ss.status end - end - return msg - end local me = relay:seat("a0000001", "RED") Client.configure({ relayAddress = "fake:1", connect = function() return me.transport end }) @@ -125,9 +116,6 @@ return function(game) return cond() end end - local function pushPlaza() - relay:to(me, relay:plazaStateMsg(me)) - end local live = Link.liveProfile() if not result(live ~= nil, "the live g3 profile computes (vanilla game)") then return finish() end @@ -163,32 +151,34 @@ return function(game) local yellow = peer("d0000004", "YELLOW", 6, 0, "firered") for _, s in ipairs({ green, pink, yellow }) do s.presence.where = "union" - relay:handle(s, { type = "plaza_join", kind = "union", profile = live, avatar = s.avatar }) + relay:handle(s, { type = "plaza_join", kind = "union", cap = 40, profile = live, avatar = s.avatar }) end local group = { leader = pink.id, members = { pink.id, yellow.id }, activity = "chat" } pink.group, pink.status = group, "chatting" yellow.group, yellow.status = group, "chatting" - pushPlaza() - result(waitFor(function() return Union.playerCount() == 2 end, 10, 60), - "GREEN takes a leader slot and PINK's chat group another") + relay:plazaChanged(pink) + relay:plazaChanged(yellow) + result(waitFor(function() return Union.playerCount() == 3 end, 10, 60), + "GREEN, PINK and YELLOW each take their own plaza slot") local slotG = Union.slotForId(green.id) local slotP = Union.slotForId(pink.id) - result(slotG ~= nil and slotP ~= nil, "both have slots") - result(waitFor(function() return slotG and Union.leaderObj(slotG).state == 1 end, 5, 60), - "GREEN flew down onto her spot") - result(slotP and Union.vobjVisible(slotP, 0) and Union.vobjVisible(slotP, 1), - "PINK and YELLOW stand at the group offsets") - result(slotP and Union.vobj(slotP, 0).dir == Union.DIR.SOUTH, "the chat leader faces south") - place(7, 9, "up") + local slotY = Union.slotForId(yellow.id) + result(slotG ~= nil and slotP ~= nil and slotY ~= nil, "all three have slots") + result(waitFor(function() return slotG and Union.vobjVisible(slotG) and Union.vobj(slotG).anim == nil end, 5, 60), + "GREEN flew down onto her cell") + local gx, gy = Plaza.cellFor(slotG) + result(Union.vobj(slotG).x == gx and Union.vobj(slotG).y == gy, "on her slot's cell") + result(slotP and Union.vobjVisible(slotP) and Union.vobjVisible(slotY), "PINK and YELLOW stand on their own cells") + result(slotP and Union.vobj(slotP).dir == Union.DIR.SOUTH, "a chatter faces south") + place(12, 22, "up") wait(40) U.still(game, DIR .. "/g3link_union_room_avatars.png") print("[driver] 2. talking to a trainer opens the invite menu") - local Objects = require("src.core.game3.objects") local opened = false for _ = 1, 20 do - local eo = Objects.find(Union.LOCAL_IDS[slotG]) - if eo and not eo.moving then + local eo = { cellX = gx, cellY = gy } + do place(eo.cellX, eo.cellY + 1, "up") wait(2) U.tap(game, "a") @@ -217,7 +207,7 @@ return function(game) drive(function() return Union.state == "main" and not Message.isOpen() end, 8) print("[driver] 3. an incoming invite rings") - place(7, 9, "up") + place(12, 22, "up") wait(6) relay:handle(green, { type = "invite", to = me.id, activity = "chat", detail = {}, profile = live }) result(waitFor(function() return Union.state == "player_contacted_you" or Union.state == "handle_activity_request" end, @@ -319,8 +309,8 @@ return function(game) end local asked = false for _ = 1, 20 do - local eo = Objects.find(Union.LOCAL_IDS[slotG]) - if eo and not eo.moving then + local eo = { cellX = gx, cellY = gy } + do place(eo.cellX, eo.cellY + 1, "up") wait(2) U.tap(game, "a") @@ -351,7 +341,7 @@ return function(game) U.still(game, DIR .. "/g3link_union_request_declined.png") drive(function() return Union.state == "main" and not Message.isOpen() end, 8) - place(7, 9, "up") + place(12, 22, "up") wait(6) relay:handle(green, { type = "invite", to = me.id, activity = "chat", detail = {}, profile = live }) result(waitFor(pageThrough(function() return Choice.active end), 8, 600), "GREEN asks to chat again") @@ -368,7 +358,6 @@ return function(game) print("[driver] 5. the trading board") relay:handle(green, { type = "presence", board = { species = BULBASAUR, level = 14, wantType = 10 } }) relay:handle(yellow, { type = "presence", board = { species = PIDGEY, level = 5, wantType = 12 } }) - pushPlaza() result(waitFor(function() return #Union.boardOffers() >= 1 end, 5, 120), "GREEN's offer is on the board") Union.trade().playerSpecies, Union.trade().playerLevel, Union.trade().type = CHARMANDER, 10, 11 place(2, 2, "up") @@ -395,7 +384,7 @@ return function(game) drive(function() return Union.state == "main" and not Message.isOpen() end, 8) print("[driver] 6. a minigame group recruiting") - place(7, 9, "up") + place(12, 22, "up") wait(6) Flags.setVar(Space.store, ctx(), Link.VAR_0x8004, Union.LINK_GROUP.BERRY_CRUSH) local c = ctx() diff --git a/tests/drivers/game3_link_union_room.lua b/tests/drivers/game3_link_union_room.lua index df6ef713..ca524a2d 100644 --- a/tests/drivers/game3_link_union_room.lua +++ b/tests/drivers/game3_link_union_room.lua @@ -1,7 +1,8 @@ local U = require("tests.drivers.util") local DIR = os.getenv("POKEPORT_SHOT_DIR") or "/tmp/game3_link_union_room" -local UNION_ROOM = "FR_UNION_ROOM" +local Plaza = require("src.core.game3.link.union_plaza_map") +local UNION_ROOM = Plaza.MAP_ID local CENTER_2F = "FR_VIRIDIAN_CITY_POKEMON_CENTER_2F" -- pokefirered/data/specials.inc:5 SetCableClubWarp local SET_CABLE_CLUB_WARP = 0x01 @@ -81,8 +82,10 @@ return function(game) result(session.dynamicWarp ~= nil and session.dynamicWarp.map == CENTER_2F, "SetCableClubWarp recorded the way back to the cable club counter") setVar(VAR_CABLE_CLUB_STATE, 6) - Map.load(nil, game, UNION_ROOM, { x = 7, y = 11, facing = "up" }) - place(7, 11, "up") + local slotKey = require("src.import.gba.map_catalog").slotKeyFor("FR_UNION_ROOM") or "" + local group, num = slotKey:match("(%d+)%D+(%d+)") + -- pokefirered/data/scripts/cable_club.inc:797 + Space.vm.adapters.warp(tonumber(group), tonumber(num), 0xFF, 7, 11, function() end, "warpspinenter") U.wait(120) result(Space.mapId == UNION_ROOM, "the player is in the Union Room") @@ -90,92 +93,9 @@ return function(game) print("[driver] union state after entry: " .. tostring(Union.state)) U.shot(game, DIR .. "/union_room_01_empty.png") - local host, peer = Game3Link.loopback({ game = game }) - host:update(0) - peer:update(0) - Link.attach(host) - result(host:isReady(), "the loopback session handshook") - - peer:send({ - type = Union.MSG.HELLO, - name = "BLUE", - trainerId = 0x2222, - gender = 0, - activity = Union.ACTIVITY.SEARCH + Union.IN_UNION_ROOM, - }) + result(Union.relay and Union.capacity() == Plaza.CAP, "offline, the Union Room is still the 40-player plaza") + result(Union.playerCount() == 0, "with nobody in it") local waited = 0 - while waited < 300 and Union.playerCount() == 0 do - U.wait(10) - waited = waited + 10 - end - if not result(Union.playerCount() == 1, "the peer appeared in the Union Room player list") then - U.shot(game, DIR .. "/union_room_99_no_peer.png") - return finish() - end - local avatar = Objects.find(Union.LOCAL_IDS[1]) - result(avatar ~= nil and avatar.visible == true, - "the slot 1 union room avatar is on the map") - U.wait(30) - U.shot(game, DIR .. "/union_room_02_player_spawned.png") - - -- pokefirered/src/union_room.c:3264 UR_STATE_INTERACT_WITH_ATTENDANT - place(3, 3, "up") - U.wait(15) - waited = 0 - while waited < 200 and not Screen.isOpen() do - U.tap(game, "a") - U.wait(20) - waited = waited + 20 - end - if result(Screen.isOpen(), "the Union Room attendant opened the player list") then - result(Screen.mode == "board", "the list is the trading board view") - result(#Screen.players == 1, "it lists the one other player in the room") - U.wait(20) - U.shot(game, DIR .. "/union_room_03_player_list.png") - U.tap(game, "b") - U.wait(30) - end - - -- pokefirered/data/maps/UnionRoom/scripts.inc:28 UnionRoom_EventScript_Player1 - waited = 0 - while waited < 240 and not Screen.isOpen() do - local eo = Objects.find(Union.LOCAL_IDS[1]) - if eo and not eo.moving then - place(tonumber(eo.cellX), tonumber(eo.cellY) + 1, "up") - U.wait(10) - U.tap(game, "a") - end - U.wait(20) - waited = waited + 30 - end - if not result(Screen.isOpen(), "talking to the player opened the activity chooser") then - print("[driver] VAR_RESULT=" .. tostring(getVar(VAR_RESULT)) .. - " state=" .. tostring(Union.state)) - U.shot(game, DIR .. "/union_room_98_no_chooser.png") - return finish() - end - result(Screen.mode == "activity", "the chooser is the invite-to-activity list") - result(#Screen.items == 4, "GREETINGS / BATTLE / CHAT / EXIT") - U.wait(20) - U.shot(game, DIR .. "/union_room_04_activity_chooser.png") - - U.tap(game, "a") - U.wait(30) - print("[driver] after greeting: activity=" .. tostring(Union.activity) - .. " state=" .. tostring(Union.state)) - result(not Screen.isOpen(), "GREETINGS closed the chooser") - result(Union.activity == Union.ACTIVITY.CARD, "and sent the trainer card activity") - U.shot(game, DIR .. "/union_room_05_after_greeting.png") - - -- pokefirered/src/union_room.c:2937 UR_STATE_TRAINER_APPEARS_BUSY - waited = 0 - while waited < 600 and Union.state ~= "main" do - U.tap(game, "a") - U.wait(20) - waited = waited + 20 - end - result(Union.state == "main", "an unanswered request frees the room again") - -- pokefirered/src/field_fadetransition.c:578 DoUnionRoomWarp waited = 0 while waited < 200 and Screen.isOpen() do @@ -184,7 +104,7 @@ return function(game) waited = waited + 20 end U.wait(30) - place(7, 10, "down") + place(12, 22, "down") U.wait(30) local Message = require("src.ui.game3.message") waited = 0 @@ -194,7 +114,12 @@ return function(game) waited = waited + 20 end U.wait(20) - U.hold(game, "down", 30) + for _ = 1, 20 do + if Space.mapId ~= UNION_ROOM then break end + U.hold(game, "down", 8) + end + print("[driver] exit walk: p=" .. tostring(Player.cellX) .. "," .. tostring(Player.cellY) + .. " msg=" .. tostring(Message.isOpen()) .. " union=" .. tostring(Union.state)) waited = 0 while waited < 600 and Space.mapId == UNION_ROOM do U.wait(15) diff --git a/tests/drivers/game3_union_plaza_map.lua b/tests/drivers/game3_union_plaza_map.lua new file mode 100644 index 00000000..539cf480 --- /dev/null +++ b/tests/drivers/game3_union_plaza_map.lua @@ -0,0 +1,107 @@ +local U = require("tests.drivers.util") +local DIR = os.getenv("SHOT_DIR") or os.getenv("POKEPORT_SHOT_DIR") or ".bazinga/union40/shots/map" + +local CENTER_2F = "FR_VIRIDIAN_CITY_POKEMON_CENTER_2F" +-- pokefirered/data/specials.inc:12 +local SET_CABLE_CLUB_WARP = 0x01 +-- pokefirered/include/constants/flags.h:1375 +local FLAG_SYS_POKEDEX_GET = 0x829 + +return function(game) + local function fail(msg) + print("FAIL game3_union_plaza_map: " .. msg) + love.event.quit(1) + coroutine.yield() + end + for _ = 1, 900 do + if game.phase == "boot" and game.boot then break end + U.wait(1) + end + game:_handleBootAction({ action = "new_game", name = "RED" }) + U.wait(240) + if game.phase ~= "field" then return fail("never reached the field") end + + local Map = require("src.core.game3.map") + local Space = require("src.core.game3.scripting.space") + local Flags = require("src.core.game3.scripting.flags") + local Player = require("src.core.game3.player") + local Natives = require("src.core.game3.scripting.natives") + local MapCatalog = require("src.import.gba.map_catalog") + local Plaza = require("src.core.game3.link.union_plaza_map") + + local function ctx() return Space.vm and Space.vm.ctx end + local function place(x, y, facing) + Player.cellX, Player.cellY = x, y + Player.px, Player.py = x * 16, y * 16 + Player.targetX, Player.targetY = x, y + Player.facing = facing + if game.session then + game.session.x, game.session.y, game.session.facing = x, y, facing + end + end + + local def = game.data and game.data.maps and game.data.maps[Plaza.MAP_ID] + if not def then return fail("hydrate did not register " .. Plaza.MAP_ID) end + + -- pokefirered/data/scripts/cable_club.inc:743 + Flags.setFlag(Space.store, ctx(), FLAG_SYS_POKEDEX_GET, true) + Map.load(nil, game, CENTER_2F, { x = 5, y = 2, facing = "up" }) + place(5, 2, "up") + U.wait(30) + place(5, 1, "up") + U.wait(10) + Natives.special(ctx(), SET_CABLE_CLUB_WARP, Space.vm and Space.vm.adapters) + local dw = game.session and game.session.dynamicWarp + if not (dw and dw.map == CENTER_2F) then return fail("SetCableClubWarp did not record the way back") end + + local slot = MapCatalog.slotKeyFor("FR_UNION_ROOM") or "" + local group, num = slot:match("(%d+)%D+(%d+)") + group, num = tonumber(group), tonumber(num) + if not (group and num) then return fail("no group/num for FR_UNION_ROOM (" .. slot .. ")") end + + local arrived = false + -- pokefirered/data/scripts/cable_club.inc:797 + Space.vm.adapters.warp(group, num, 0xFF, 7, 11, function() arrived = true end, "warpspinenter") + for _ = 1, 600 do + if arrived and Map.current == Plaza.MAP_ID then break end + U.wait(1) + end + if Map.current ~= Plaza.MAP_ID then + return fail("warp to the Union Room landed on " .. tostring(Map.current)) + end + local ex, ey = Plaza.entry() + if Player.cellX ~= ex or Player.cellY ~= ey then + return fail(("spawned at %s,%s want %d,%d"):format(tostring(Player.cellX), tostring(Player.cellY), ex, ey)) + end + U.log("entered", Map.current, Player.cellX, Player.cellY) + U.wait(120) + U.still(game, DIR .. "/plaza_entrance.png") + + place(12, 18, "up") + U.wait(30) + U.still(game, DIR .. "/plaza_center.png") + + place(22, 3, "up") + U.wait(30) + U.still(game, DIR .. "/plaza_far_corner.png") + + place(3, 3, "up") + U.wait(30) + U.still(game, DIR .. "/plaza_counter.png") + + place(12, 22, "down") + U.wait(30) + U.hold(game, "down", 40) + for _ = 1, 300 do + if Map.current == CENTER_2F then break end + U.wait(1) + end + if Map.current ~= CENTER_2F then + return fail("exit landed on " .. tostring(Map.current) .. " want " .. CENTER_2F) + end + U.wait(60) + U.still(game, DIR .. "/plaza_exit_center_2f.png") + U.log("exit landed", Map.current, Player.cellX, Player.cellY) + print("PASS game3_union_plaza_map") + love.event.quit(0) +end diff --git a/tests/drivers/gold_fanfare_speed_bug1952_test.lua b/tests/drivers/gold_fanfare_speed_bug1952_test.lua index 962ae358..610580af 100644 --- a/tests/drivers/gold_fanfare_speed_bug1952_test.lua +++ b/tests/drivers/gold_fanfare_speed_bug1952_test.lua @@ -22,6 +22,10 @@ return function(game) game.speedOverride = 4 U.wait(2) + if game:logicSpeed() ~= 4 then + error(("bug1952: the overworld did not take the 4X override (%s)") + :format(tostring(game:logicSpeed()))) + end U.log("gen2 speed override", 4, "sfx rate", Sound.rate()) if Sound.rate() ~= 1 then error(("bug1952: Game2:update pitched SFX off GAME SPEED (rate %s at 4X)") @@ -71,6 +75,12 @@ return function(game) :format(held, dur)) end + game.linkNet = { closed = false } + if game:logicSpeed() ~= 1 then + error(("speed lock: an open gen 2 link ran at %sX under a 4X override") + :format(tostring(game:logicSpeed()))) + end + game.linkNet = nil game.speedOverride = nil U.wait(2) if Sound.rate() ~= 1 then @@ -80,5 +90,5 @@ return function(game) U.shot(game, DIR .. "/bug1952_gold_after.png") U.log("PASS the gen 2 jingle kept natural pitch under GAME SPEED") - love.event.quit() + love.event.quit(0) end diff --git a/tests/drivers/speed_lock_firered.lua b/tests/drivers/speed_lock_firered.lua new file mode 100644 index 00000000..b7f408ce --- /dev/null +++ b/tests/drivers/speed_lock_firered.lua @@ -0,0 +1,149 @@ +local U = require("tests.drivers.util") +local DIR = os.getenv("SHOT_DIR") or os.getenv("POKEPORT_SHOT_DIR") or "/tmp/shots" + +local UNION_ROOM = "FR_UNION_ROOM" +local CENTER_2F = "FR_VIRIDIAN_CITY_POKEMON_CENTER_2F" +-- pokefirered/data/specials.inc:12 +local SET_CABLE_CLUB_WARP = 0x01 +-- pokefirered/include/constants/vars.h:163 +local VAR_CABLE_CLUB_STATE = 0x406F +-- pokefirered/include/constants/flags.h:1375 +local FLAG_SYS_POKEDEX_GET = 0x829 + +local function key(k) + love.keypressed(k, k, false) + love.keyreleased(k, k) +end + +return function(game) + local function fail(msg) + error("FAIL speed lock: " .. msg, 0) + end + for _ = 1, 900 do + if game.phase == "boot" and game.boot then break end + U.wait(1) + end + game:_handleBootAction({ action = "new_game", name = "RED" }) + U.wait(240) + if game.phase ~= "field" then fail("never reached the field") end + + local Runtime = require("src.core.game3.runtime") + local Party = require("src.core.game3.party") + local BattleBridge = require("src.core.game3.battle_bridge") + local Battle = require("src.core.game3.battle") + local Map = require("src.core.game3.map") + local Space = require("src.core.game3.scripting.space") + local Flags = require("src.core.game3.scripting.flags") + local Player = require("src.core.game3.player") + local Union = require("src.core.game3.link.union_room") + local o = game.options + + game.speedOverride = nil + o.speedOverworld, o.speedBattle, o.speedMenu = 10, 200, 1 + U.wait(2) + if game:logicSpeed() ~= 10 then + fail(("field at OVERWORLD SPEED 10 reads %s"):format(tostring(game:logicSpeed()))) + end + + local session = Runtime.getSession() + session.party = {} + Party.giveMon(session, 6, 50) + local ok, err = BattleBridge.startWild(Runtime._mod, game, { species = 16, level = 2 }, { fade = false }) + if not ok then fail("wild battle did not start " .. tostring(err)) end + + local checked, shot = 0, false + local Ui = require("src.core.game3.battle.ui") + for f = 1, 20000 do + if not Battle.isActive() then break end + if game:logicSpeed() ~= 1 then + fail(("battle ran at %sX with speedBattle 200"):format(tostring(game:logicSpeed()))) + end + checked = checked + 1 + if checked == 30 then + key("1") + game:gamepadaxis(nil, "triggerright", 1) + game:gamepadaxis(nil, "triggerright", 0) + if o.speedOverworld ~= 10 or o.speedBattle ~= 200 or o.speedMenu ~= 1 then + fail(("speed presses in battle changed options (%s/%s/%s)"):format( + tostring(o.speedOverworld), tostring(o.speedBattle), tostring(o.speedMenu))) + end + game.speedOverride = 200 + if game:logicSpeed() ~= 1 then fail("speedOverride 200 defeated the battle lock") end + game.speedOverride = nil + if game.touchSkinHotkey then game:touchSkinHotkey("fast_forward_hold", true) end + if game:logicSpeed() ~= 1 then fail("skin FF hold defeated the battle lock") end + if game.touchSkinHotkey then game:touchSkinHotkey("fast_forward_hold", false) end + end + if checked == 200 and not shot then + shot = U.shot(game, DIR .. "/firered_battle_locked.png") + end + local st = Battle.getState and Battle.getState() + if st and Battle._phase == "command" and Ui._mode == "menu" and not Ui._pendingCommand then + local mon = st.player.mon + mon.moves[1] = 33 + mon.pp = mon.pp or {} + mon.pp[1] = 10 + st.enemy.mon.hp = 1 + Ui._pendingCommand = { kind = "move", move = 33, slot = 1, user = "player" } + Ui._mode = "none" + U.wait(1) + elseif f % 14 == 0 then + U.tap(game, "a") + else + U.wait(1) + end + end + if Battle.isActive() then + fail(("battle never ended (phase %s, ui %s)"):format(tostring(Battle._phase), tostring(Ui._mode))) + end + U.log("battle frames checked at 1X", checked) + U.wait(120) + if game:logicSpeed() ~= 10 then + fail(("after the battle logic speed is %s, want 10"):format(tostring(game:logicSpeed()))) + end + + local function ctx() return Space.vm and Space.vm.ctx end + local function place(x, y, facing) + Player.cellX, Player.cellY = x, y + Player.px, Player.py = x * 16, y * 16 + Player.targetX, Player.targetY = x, y + Player.facing = facing + if game.session then + game.session.x, game.session.y, game.session.facing = x, y, facing + end + end + -- pokefirered/data/scripts/cable_club.inc:743 + Flags.setFlag(Space.store, ctx(), FLAG_SYS_POKEDEX_GET, true) + Map.load(nil, game, CENTER_2F, { x = 5, y = 2, facing = "up" }) + place(5, 2, "up") + U.wait(60) + if game:logicSpeed() ~= 10 then + fail(("the cable club counter room reads %s, want 10"):format(tostring(game:logicSpeed()))) + end + place(5, 1, "up") + U.wait(10) + local Natives = require("src.core.game3.scripting.natives") + Natives.special(ctx(), SET_CABLE_CLUB_WARP, Space.vm and Space.vm.adapters) + Flags.setVar(Space.store, ctx(), VAR_CABLE_CLUB_STATE, 6) + Map.load(nil, game, UNION_ROOM, { x = 7, y = 11, facing = "up" }) + place(7, 11, "up") + local seen = 0 + for _ = 1, 120 do + U.wait(1) + if game:logicSpeed() ~= 1 then + fail(("the Union Room ran at %sX with OVERWORLD SPEED 10"):format(tostring(game:logicSpeed()))) + end + seen = seen + 1 + end + if not Union.isActive() then U.log("note: union session not active, locked by map") end + key("1") + game:gamepadaxis(nil, "triggerright", 1) + game:gamepadaxis(nil, "triggerright", 0) + if o.speedOverworld ~= 10 then + fail(("speed presses in the Union Room moved OVERWORLD SPEED to %s"):format(tostring(o.speedOverworld))) + end + U.shot(game, DIR .. "/firered_union_locked.png") + U.log("union room frames checked at 1X", seen, "union state", tostring(Union.state)) + U.log("PASS firered battle and Union Room locked to 1X, OVERWORLD SPEED 10 back after the battle") + love.event.quit(0) +end diff --git a/tests/drivers/speed_lock_gold.lua b/tests/drivers/speed_lock_gold.lua new file mode 100644 index 00000000..3636e3a7 --- /dev/null +++ b/tests/drivers/speed_lock_gold.lua @@ -0,0 +1,102 @@ +local U = require("tests.drivers.util") + +local Mon = require("src.battle.gen2.Mon") + +return function(game) + local DIR = os.getenv("SHOT_DIR") or os.getenv("POKEPORT_SHOT_DIR") or "/tmp/shots" + local function fail(msg) + error("FAIL speed lock: " .. msg, 0) + end + local function tap(button, frames) + game.input.pressQueue[#game.input.pressQueue + 1] = button + game.input.state[button] = true + U.wait(2) + game.input.state[button] = false + U.wait(frames or 6) + end + + U.wait(45) + local world = game.world + if not (world and world.map) then return fail("gold world did not boot") end + + game.speedOverride = nil + game.options.speed = 10 + U.wait(2) + if game:logicSpeed() ~= 10 then + return fail(("overworld at GAME SPEED 10 reads %s"):format(tostring(game:logicSpeed()))) + end + U.log("overworld logic speed", game:logicSpeed()) + + local player = Mon.new(game.data, "CYNDAQUIL", 10) + game.save.party = { player } + local wild = Mon.new(game.data, "PIDGEY", 2) + if not world:startBattle({ wild = wild }) then return fail("startBattle failed") end + + local battle + for _ = 1, 600 do + local top = game.stack:top() + if top and top.battle then battle = top break end + U.wait(1) + end + if not battle then return fail("battle screen never came up") end + + local function inBattle() + for _, st in ipairs(game.stack.states) do + if st == battle then return true end + end + return false + end + + local checked, shot = 0, false + for _ = 1, 2000 do + if not inBattle() then break end + if game:logicSpeed() ~= 1 then + return fail(("battle ran at %sX with GAME SPEED 10"):format(tostring(game:logicSpeed()))) + end + checked = checked + 1 + if checked == 30 then + game:hotkey("1") + game:_cycleSpeed(1) + game:_cycleSpeed(-1) + if game.options.speed ~= 10 then + return fail(("speed presses in battle moved GAME SPEED to %s"):format(tostring(game.options.speed))) + end + game.speedOverride = 200 + if game:logicSpeed() ~= 1 then + return fail("speedOverride 200 defeated the battle lock") + end + game.speedOverride = nil + end + if battle.phase == "menu" and not shot then + shot = U.shot(game, DIR .. "/gold_battle_locked.png") + end + if battle.battle and battle.battle.over then + tap("a", 3) + elseif battle.phase == "menu" then + tap("a", 4) + tap("a", 4) + else + tap("a", 3) + end + end + if inBattle() then + local top = game.stack:top() + return fail(("battle never ended (phase %s, over %s, top %s)"):format( + tostring(battle.phase), tostring(battle.battle and battle.battle.over), + tostring(top and (top.screenId or top.name) or top))) + end + U.log("battle frames checked at 1X", checked) + U.wait(30) + if game:logicSpeed() ~= 10 then + return fail(("after the battle logic speed is %s, want 10"):format(tostring(game:logicSpeed()))) + end + game.linkNet = { closed = false } + if game:logicSpeed() ~= 1 then return fail("an open linkNet did not lock 1X") end + game.linkNet = nil + game.linkSession = true + if game:logicSpeed() ~= 1 then return fail("a linkSession did not lock 1X") end + game.linkSession = nil + U.shot(game, DIR .. "/gold_after_battle.png") + U.log("PASS gold battle and link locked to 1X, GAME SPEED 10 back after") + love.event.quit(0) +end diff --git a/tests/drivers/speed_lock_red.lua b/tests/drivers/speed_lock_red.lua new file mode 100644 index 00000000..29fe7e28 --- /dev/null +++ b/tests/drivers/speed_lock_red.lua @@ -0,0 +1,87 @@ +return function(game) + local U = dofile("tests/drivers/util.lua") + local DIR = os.getenv("SHOT_DIR") or os.getenv("POKEPORT_SHOT_DIR") or "/tmp/shots" + local Pokemon = require("src.pokemon.Pokemon") + local BattleState = require("src.battle.BattleState") + local function fail(msg) + error("FAIL speed lock: " .. msg, 0) + end + local function key(k) + love.keypressed(k, k, false) + love.keyreleased(k, k) + end + + local squirtle = Pokemon.new(game.data, "SQUIRTLE", 30, function(_, b) return b end) + game.save.party = { squirtle } + U.teleport(game, "ROUTE_1", 5, 5, "down") + local ow = game.overworld + + local o = game.save.options + game.speedOverride = nil + o.speedOverworld, o.speedBattle, o.speedMenu = 10, 200, 1 + U.wait(2) + if game:logicSpeed() ~= 10 then + fail(("overworld at OVERWORLD SPEED 10 reads %s"):format(tostring(game:logicSpeed()))) + end + U.log("overworld logic speed", game:logicSpeed()) + + local battle = BattleState.newWild(game, "RATTATA", 2) + battle.onFinish = function() end + battle.enemy.mon.hp = 1 + ow:pushBattle(battle) + + local function inBattle() + for _, st in ipairs(game.stack.states) do + if st == battle then return true end + end + return false + end + + for _ = 1, 600 do + if inBattle() then break end + U.wait(1) + end + if not inBattle() then fail("the battle never reached the stack") end + + local checked, shot = 0, false + for _ = 1, 2400 do + if not inBattle() then break end + if game:logicSpeed() ~= 1 then + fail(("battle ran at %sX with speedBattle 200"):format(tostring(game:logicSpeed()))) + end + checked = checked + 1 + if checked == 20 then + key("1") + game:gamepadaxis(nil, "triggerright", 1) + game:gamepadaxis(nil, "triggerright", 0) + game:touchSkinHotkey("fast_forward_toggle", true) + if o.speedOverworld ~= 10 or o.speedBattle ~= 200 or o.speedMenu ~= 1 then + fail(("speed presses in battle changed options (%s/%s/%s)"):format( + tostring(o.speedOverworld), tostring(o.speedBattle), tostring(o.speedMenu))) + end + game:touchSkinHotkey("fast_forward_hold", true) + if game:logicSpeed() ~= 1 then fail("skin FF hold defeated the battle lock") end + game:touchSkinHotkey("fast_forward_hold", false) + game.speedOverride = 200 + if game:logicSpeed() ~= 1 then fail("speedOverride 200 defeated the battle lock") end + game.speedOverride = nil + end + if battle.phase == "menu" and not shot then + shot = U.shot(game, DIR .. "/red_battle_locked.png") + end + U.tap(game, "a") + U.wait(2) + end + if inBattle() then fail("battle never ended") end + U.log("battle frames checked at 1X", checked) + U.wait(10) + if game:logicSpeed() ~= 10 then + fail(("after the battle logic speed is %s, want 10"):format(tostring(game:logicSpeed()))) + end + game.linkSession = true + if game:logicSpeed() ~= 1 then fail("a link session did not lock 1X") end + game.linkSession = nil + U.shot(game, DIR .. "/red_after_battle.png") + U.log("PASS red battle and link locked to 1X, OVERWORLD SPEED 10 back after") + love.event.quit(0) +end diff --git a/tests/engine/game3_speed_hotkey_test.lua b/tests/engine/game3_speed_hotkey_test.lua index da01a1eb..a8969f77 100644 --- a/tests/engine/game3_speed_hotkey_test.lua +++ b/tests/engine/game3_speed_hotkey_test.lua @@ -38,6 +38,14 @@ do eq(g:logicSpeed(), 2, "walk speed sticks after the menu closes") battleActive = true eq(g:speedCategory(), "battle", "battle stays battle") + g.options.speedBattle = 10 + eq(g:logicSpeed(), 1, "a gen3 battle runs 1X whatever BATTLE SPEED says") + g.speedOverride = 20 + eq(g:logicSpeed(), 1, "and whatever speedOverride says") + g.speedOverride = nil + g:keypressed("1") + eq(g.options.speedBattle, 10, "1 in battle is ignored") + eq(g.options.speedOverworld, 2, "and leaves OVERWORLD SPEED alone") battleActive = false eq(newGame3("boot"):speedCategory(), "menu", "boot phase stays menu") eq(newGame3("quest_log"):speedCategory(), "menu", "quest log stays menu") @@ -158,4 +166,44 @@ do package.loaded["src.core.game3.minigames.common"] = nil end +do + local g = newGame3("field") + g.options.speedOverworld = 10 + eq(g:logicSpeed(), 10, "plain field walk honors OVERWORLD SPEED") + local unionOn = true + package.loaded["src.core.game3.link.union_room"] = { + isActive = function() return unionOn end, + } + eq(g:logicSpeed(), 1, "an active Union Room is locked to 1X") + g:keypressed("1") + eq(g.options.speedOverworld, 10, "1 in the Union Room is ignored") + unionOn = false + eq(g:logicSpeed(), 10, "leaving the Union Room restores the walk speed") + package.loaded["src.core.game3.link.union_room"] = nil + package.loaded["src.core.game3.map"] = { current = "FR_UNION_ROOM" } + eq(g:logicSpeed(), 1, "standing on the Union Room map is locked to 1X") + package.loaded["src.core.game3.map"] = { current = "FR_PALLET_TOWN" } + eq(g:logicSpeed(), 10, "another map is not") + package.loaded["src.core.game3.map"] = nil + local room = 1 + package.loaded["src.core.game3.link"] = { + inLinkRoom = function() return room ~= 0 end, + } + eq(g:logicSpeed(), 1, "a cable club link room is locked to 1X") + room = 0 + eq(g:logicSpeed(), 10, "and outside it the walk speed is back") + package.loaded["src.core.game3.link"] = nil + local menuOpen, directOpen = true, false + package.loaded["src.ui.game3.link_menu"] = { + isOpen = function() return menuOpen end, + Direct = { isOpen = function() return directOpen end }, + } + eq(g:logicSpeed(), 1, "the wireless link menu is locked to 1X") + menuOpen, directOpen = false, true + eq(g:logicSpeed(), 1, "the Direct Corner chooser is locked to 1X") + directOpen = false + eq(g:logicSpeed(), 10, "closed link menus release the lock") + package.loaded["src.ui.game3.link_menu"] = nil +end + T.finish() diff --git a/tests/engine/game3_virtual_objects_drawhook_test.lua b/tests/engine/game3_virtual_objects_drawhook_test.lua index 8c99828b..47dfee56 100644 --- a/tests/engine/game3_virtual_objects_drawhook_test.lua +++ b/tests/engine/game3_virtual_objects_drawhook_test.lua @@ -31,6 +31,22 @@ eq(found and found.sprite, GfxIds.spriteFor(40), "sprite name reaches the non-OW eq(Objects._byId[1], nil, "the registry is not in the object store (no collision)") eq(Objects.at(5, 6), nil, "Objects.at cannot see it") +local again +for _, eo in ipairs(Objects.forDraw()) do + if eo.virtualId == 1 then again = eo end +end +check(again == found, "forDraw reuses the draw record for an unchanged virtual object") +if jit then jit.off() end +for _ = 1, 20 do Objects.forDraw() end +collectgarbage("collect") +collectgarbage("stop") +local kb0 = collectgarbage("count") +for _ = 1, 100 do Objects.forDraw() end +local grown = collectgarbage("count") - kb0 +collectgarbage("restart") +if jit then jit.on() end +check(grown < 1, "forDraw allocates nothing in steady state (" .. grown .. " KB)") + VirtualObjects.turn(1, 2) local turned for _, eo in ipairs(Objects.forDraw()) do diff --git a/tests/engine/game_speed_categories_test.lua b/tests/engine/game_speed_categories_test.lua index 6303fd42..200124c2 100644 --- a/tests/engine/game_speed_categories_test.lua +++ b/tests/engine/game_speed_categories_test.lua @@ -1,5 +1,5 @@ -- Per-category GAME SPEED (RFC 0007): Game.speedCategoryInStack's stack --- walk, Game:logicSpeed()'s precedence (link lock / run-argument override / +-- walk, Game:logicSpeed()'s precedence (battle/link lock / run-argument override / -- the core.logic_speed hook), Game:_cycleSpeed's per-category cycling, and -- the core.logic_speed hook itself exercised through the public mod API -- (Hooks.new() + bus:wrap, the same idiom other hooks' tests use -- not a @@ -66,6 +66,7 @@ do local g = gameWith({ battle }, { speedOverworld = 4, speedBattle = 10, speedMenu = 2 }) eq(g:_resolveLogicSpeed(), 10, "battle reads speedBattle") + eq(g:logicSpeed(), 1, "but a battle always runs 1X whatever speedBattle says") end do local g = gameWith({ overlay }, @@ -97,10 +98,17 @@ do eq(g:logicSpeed(), 1, "an open linkNet forces 1X the same way") end do - local g = gameWith({ battle }, { speedBattle = 50 }) + local g = gameWith({ overworld }, { speedOverworld = 50 }) g.linkNet = { closed = true } eq(g:logicSpeed(), 50, "a CLOSED linkNet does not force 1X") end +do + local g = gameWith({ overworld, battle }, { speedOverworld = 50, speedBattle = 50 }) + g.speedOverride = 20 + eq(g:logicSpeed(), 1, "a battle forces 1X over speedOverride too") + local locked, why = g:speedLocked() + check(locked and why == "battle", "speedLocked reports the battle") +end do local g = gameWith({ overworld }, { speedOverworld = 4 }) g.speedOverride = 20 @@ -172,10 +180,20 @@ do { speedOverworld = 1, speedBattle = 1, speedMenu = 1 }) function g:writeOptions() writeOptions.calls = writeOptions.calls + 1 end g:_cycleSpeed(1) - eq(g.save.options.speedBattle, 2, "cycling during battle bumps speedBattle") + eq(g.save.options.speedBattle, 1, "cycling during battle is ignored") eq(g.save.options.speedOverworld, 1, "...and leaves speedOverworld alone") eq(g.save.options.speedMenu, 1, "...and leaves speedMenu alone") - eq(writeOptions.calls, 1, "a successful cycle persists the option") + eq(writeOptions.calls, 0, "and persists nothing") +end +do + local calls = 0 + local g = gameWith({ overworld }, + { speedOverworld = 1, speedBattle = 1, speedMenu = 1 }) + function g:writeOptions() calls = calls + 1 end + g.linkSession = true + g:_cycleSpeed(1) + eq(g.save.options.speedOverworld, 1, "cycling during link play is ignored") + eq(calls, 0, "...and persists nothing") end do local g = gameWith({ overworld }, diff --git a/tests/engine/gen2_logic_speed_bug1994.lua b/tests/engine/gen2_logic_speed_bug1994.lua index d2f0305e..b434d876 100644 --- a/tests/engine/gen2_logic_speed_bug1994.lua +++ b/tests/engine/gen2_logic_speed_bug1994.lua @@ -25,6 +25,38 @@ eq(game({ options = { speed = -5 } }):logicSpeed(), 1, eq(game({ options = { speed = "fast" } }):logicSpeed(), 1, "an unparseable option falls back rather than erroring") +local function stack(...) return { states = { ... } } end +local battle = { isBattle = true } +local world = {} + +eq(game({ options = { speed = 10 }, stack = stack(world) }):logicSpeed(), 10, + "the overworld under a plain stack honors GAME SPEED") +eq(game({ options = { speed = 10 }, stack = stack(world, battle) }):logicSpeed(), 1, + "a battle on the stack is locked to 1X") +eq(game({ options = { speed = 10 }, speedOverride = 20, + stack = stack(world, battle, {}) }):logicSpeed(), 1, + "even with speedOverride and a menu over the battle") +eq(game({ options = { speed = 10 }, linkNet = { closed = false } }):logicSpeed(), 1, + "an open linkNet (online arena, LinkBattle2) is locked to 1X") +eq(game({ options = { speed = 10 }, linkNet = { closed = true } }):logicSpeed(), 10, + "a closed linkNet is not") +eq(game({ options = { speed = 10 }, linkSession = true }):logicSpeed(), 1, + "a link session (tournament, spectate) is locked to 1X") +eq(require("src.ui.gen2.BattleState").isBattle, true, + "the Gen 2 battle screen marks itself as a battle") + +do + local persisted = 0 + local g = game({ options = { speed = 1 }, stack = stack(world, battle), + persistOptions = function() persisted = persisted + 1 end }) + g:_cycleSpeed(1) + eq(g.options.speed, 1, "SPEED + in battle is ignored") + eq(persisted, 0, "and persists nothing") + g.stack = stack(world) + g:_cycleSpeed(1) + eq(g.options.speed, 2, "SPEED + on the overworld still cycles") +end + local Gen2Compat = require("src.mods.Gen2Compat") local live = game({ options = { speed = 4 } }) Gen2Compat.bind(function() return live end) diff --git a/tests/engine/options_submenu_marquee_test.lua b/tests/engine/options_submenu_marquee_test.lua index ce4b580e..4b119db2 100644 --- a/tests/engine/options_submenu_marquee_test.lua +++ b/tests/engine/options_submenu_marquee_test.lua @@ -45,7 +45,7 @@ local menu = OptionsMenu.new(game) T.check(find(menu.rows, "battleBg"), "self.rows keeps the flat list for mods") T.check(find(menu.rows, "musicVol"), "self.rows keeps the audio rows too") -for _, id in ipairs({ "battleBg", "speedBattle", "uiLayout", "tilt", "zoom", +for _, id in ipairs({ "battleBg", "speedMenu", "uiLayout", "tilt", "zoom", "voidFill", "colors", "shaderfx", "shaderfx2", "musicVol", "videoMode" }) do T.check(not find(menu.view, id), id .. " moved onto a page") @@ -53,7 +53,7 @@ end for _, spec in ipairs({ { "group.battle", 6 }, { "group.audio", 3 }, { "group.video", 5 }, - { "group.speed", 4 }, { "group.graphics", 4 }, { "group.extras", 3 }, + { "group.speed", 3 }, { "group.graphics", 4 }, { "group.extras", 3 }, }) do local row = find(menu.view, spec[1]) T.check(row, spec[1] .. " has an opener row") @@ -100,7 +100,7 @@ game.stack:pop() local speed = find(menu.view, "group.speed") speed.activate(game) T.eq(ids(game.stack:top().view), - "textSpeed,speedOverworld,speedBattle,speedMenu", + "textSpeed,speedOverworld,speedMenu", "TEXT SPEED heads the SPEED page") game.stack:pop() diff --git a/tests/engine/speed_lock_test.lua b/tests/engine/speed_lock_test.lua new file mode 100644 index 00000000..7903b8b2 --- /dev/null +++ b/tests/engine/speed_lock_test.lua @@ -0,0 +1,188 @@ +package.path = "./?.lua;./?/init.lua;" .. package.path +if not _G.love then _G.love = require("tests.love_stub") end + +local T = require("tests.harness") +local check, eq = T.check, T.eq + +local FixedStep = require("src.core.FixedStep") +local GameSpeed = require("src.core.GameSpeed") +local Hooks = require("src.mods.Hooks") +local Runtime = require("src.mods.Runtime") +local Game = require("src.core.Game") +local Game2 = require("src.core.Game2") +local Game3 = require("src.core.Game3") + +local function stack(...) return { states = { ... } } end +local unpack = table.unpack or unpack + +local battle = { isBattle = true } +local overworld = { isOverworld = true } + +local function gen1(states, opts) + return setmetatable({ + save = { options = opts or { speedOverworld = 200, speedBattle = 200, speedMenu = 200 } }, + stack = stack(unpack(states)), + writeOptions = function() end, + }, { __index = Game }) +end + +do + local g = gen1({ overworld }) + eq(g:logicSpeed(), 200, "gen1 overworld runs the saved 200X") + check(not g:speedLocked(), "gen1 overworld is not locked") + g = gen1({ overworld, battle }) + eq(g:logicSpeed(), 1, "gen1 battle is 1X at speedBattle 200") + g.speedOverride = 200 + eq(g:logicSpeed(), 1, "gen1 battle ignores speedOverride (--speed, skin FF hold)") + local bus = Hooks.new() + local saved = Runtime.hooks + Runtime.hooks = bus + local ran = false + local unsub = bus:wrap("core.logic_speed", function() ran = true; return 200 end) + g.speedOverride = nil + eq(g:logicSpeed(), 1, "gen1 battle ignores a core.logic_speed hook returning 200") + check(not ran, "the hook is never called while locked") + local ow = gen1({ overworld }) + eq(ow:logicSpeed(), 200, "outside battle the hook still runs") + check(ran, "...and was called") + unsub() + Runtime.hooks = saved +end + +do + GameSpeed.setAllowed({ 2, 4 }) + local g = gen1({ overworld, battle }) + eq(g:logicSpeed(), 1, "a cart ladder without 1 still locks to a literal 1") + eq(gen1({ overworld }, { speedOverworld = 4 }):logicSpeed(), 4, + "and outside battle the ladder applies") + GameSpeed.setAllowed(nil) +end + +do + local g = gen1({ overworld, battle }, + { speedOverworld = 1, speedBattle = 1, speedMenu = 1 }) + g:_cycleSpeed(1) + g:_cycleSpeed(-1) + g:_cycleSpeed(1) + eq(g.save.options.speedBattle, 1, "gen1 speed presses in battle leave speedBattle") + eq(g.save.options.speedOverworld, 1, "and speedOverworld") + g:touchSkinHotkey("fast_forward_toggle", true) + eq(g.save.options.speedBattle, 1, "gen1 skin FF toggle in battle is ignored") + g:touchSkinHotkey("fast_forward_hold", true) + eq(g:logicSpeed(), 1, "gen1 skin FF hold in battle stays 1X") + g:touchSkinHotkey("fast_forward_hold", false) + eq(g.speedOverride, nil, "and releasing restores the pre-hold override") +end + +do + local g = gen1({ overworld }) + g.linkSession = true + eq(g:logicSpeed(), 1, "gen1 link session is 1X") + g.linkSession = nil + g.linkNet = { closed = false } + eq(g:logicSpeed(), 1, "gen1 open linkNet (arena, tournament, spectate) is 1X") +end + +local function gen2(fields) + fields.persistOptions = fields.persistOptions or function() end + return setmetatable(fields, { __index = Game2 }) +end + +do + eq(gen2({ options = { speed = 200 }, stack = stack({}) }):logicSpeed(), 200, + "gen2 overworld runs GAME SPEED") + eq(gen2({ options = { speed = 200 }, stack = stack({}, battle) }):logicSpeed(), 1, + "gen2 battle is 1X") + eq(gen2({ options = { speed = 200 }, speedOverride = 200, + stack = stack({}, battle) }):logicSpeed(), 1, + "gen2 battle ignores speedOverride") + eq(gen2({ options = { speed = 200 }, linkNet = { closed = false } }):logicSpeed(), 1, + "gen2 online arena / LinkBattle2 linkNet is 1X") + eq(gen2({ options = { speed = 200 }, linkSession = true }):logicSpeed(), 1, + "gen2 tournament / spectate linkSession is 1X") + local g = gen2({ options = { speed = 1 }, stack = stack({}, battle) }) + g:_cycleSpeed(1) + eq(g.options.speed, 1, "gen2 pad speed press in battle is ignored") + g.stack = stack({}) + g.linkNet = { closed = false } + g:_cycleSpeed(1) + eq(g.options.speed, 1, "gen2 pad speed press over a link is ignored") +end + +local battleActive = false +package.loaded["src.core.game3.battle"] = { + isActive = function() return battleActive end, +} + +local function gen3() + return setmetatable({ + phase = "field", + options = { speedOverworld = 200, speedBattle = 200, speedMenu = 200 }, + writeOptions = function() end, + }, { __index = Game3 }) +end + +do + local g = gen3() + eq(g:logicSpeed(), 200, "gen3 field runs OVERWORLD SPEED") + battleActive = true + eq(g:logicSpeed(), 1, "gen3 battle is 1X") + g.speedOverride = 200 + eq(g:logicSpeed(), 1, "gen3 battle ignores speedOverride") + g.speedOverride = nil + g:_cycleSpeed(1) + eq(g.options.speedBattle, 200, "gen3 speed press in battle is ignored") + battleActive = false + package.loaded["src.core.game3.link.union_room"] = { isActive = function() return true end } + eq(g:logicSpeed(), 1, "gen3 Union Room is 1X") + package.loaded["src.core.game3.link.union_room"] = nil + package.loaded["src.core.game3.map"] = { current = "FR_UNION_ROOM" } + eq(g:logicSpeed(), 1, "gen3 Union Room map is 1X") + package.loaded["src.core.game3.map"] = nil + eq(g:logicSpeed(), 200, "and the field is back to 200X") +end + +local function runFrame(g, lockAt) + local steps = 0 + local savedInit = { accum = FixedStep.accum, callback = FixedStep.callback } + FixedStep.clock = function() return 0 end + FixedStep:init(function() + steps = steps + 1 + if steps == lockAt then battleActive = true; g.stack = stack(overworld, battle) end + g:_speedLockEdge() + end) + local speed = g:logicSpeed() + g._frameSpeed = speed + FixedStep.maxAccum = FixedStep.catchupLimit(speed, FixedStep.STEP) + FixedStep:update(FixedStep.STEP, speed) + FixedStep.clock = nil + FixedStep.accum, FixedStep.callback = savedInit.accum, savedInit.callback + return steps, speed +end + +do + battleActive = false + local g = gen3() + local steps, speed = runFrame(g, 3) + eq(speed, 200, "the frame started unlocked at 200X") + eq(steps, 3, "gen3: a battle starting mid-frame ends the frame on that step") + battleActive = false + + local g1 = gen1({ overworld }) + steps = runFrame(g1, 5) + eq(steps, 5, "gen1: a battle push mid-frame ends the frame on that step") + eq(g1:logicSpeed(), 1, "and the next frame samples 1X") + + local g2 = gen2({ options = { speed = 200 }, stack = stack({}) }) + steps = runFrame(g2, 2) + eq(steps, 2, "gen2: a battle push mid-frame ends the frame on that step") + battleActive = false + + local plain = gen1({ overworld }) + steps = runFrame(plain, -1) + check(steps > 100, "without a lock flip the 200X frame runs its steps") +end + +package.loaded["src.core.game3.battle"] = nil + +T.finish("speed lock") diff --git a/tests/g3link_fake_relay.lua b/tests/g3link_fake_relay.lua index 5be08448..dec6bd13 100644 --- a/tests/g3link_fake_relay.lua +++ b/tests/g3link_fake_relay.lua @@ -305,7 +305,7 @@ function FakeRelay.client(opts) rec("setStatus", status) C.status = status end - function C.joinPlaza(kind, profile, avatar) rec("joinPlaza", kind, profile, avatar) end + function C.joinPlaza(kind, profile, avatar, cap) rec("joinPlaza", kind, profile, avatar, cap) end function C.leavePlaza(kind) rec("leavePlaza", kind) end function C.plaza() return C._plaza end function C.plazaCounts() return C._counts end diff --git a/tests/game3_link_continue_warp_test.lua b/tests/game3_link_continue_warp_test.lua index fdfe93b6..7df3c56a 100644 --- a/tests/game3_link_continue_warp_test.lua +++ b/tests/game3_link_continue_warp_test.lua @@ -51,6 +51,26 @@ for _, room in ipairs({ "FR_BATTLE_COLOSSEUM_2P", "FR_BATTLE_COLOSSEUM_4P", "FR_ check(c.map == CENTER_2F and c.x == 9 and c.y == 1, room .. " save continues at the dynamic warp") end +for _, room in ipairs({ "FR_UNION_ROOM_PLAZA", "FR_UNION_ROOM" }) do + for _, case in ipairs({ + { heal = "FR_PEWTER_CITY_POKEMON_CENTER_1F", want = "FR_PEWTER_CITY_POKEMON_CENTER_2F" }, + { heal = "SEVII_ONE_ISLAND_POKECENTER", want = "SEVII_ONE_ISLAND_POKECENTER_2F" }, + { heal = "FR_PLAYERS_HOUSE_1F", want = CENTER_2F }, + }) do + local s = linkSession(room) + s.dynamicWarp = nil + s.healMap = case.heal + local saved = Schema.toSaveTable(s) + check((tonumber(saved.specialSaveWarpFlags) or 0) == 0, room .. " save with no dynamic warp sets no continue warp") + local c = Schema.fromSaveTable(saved) + check(c.map == case.want and c.x == 5 and c.y == 1 and c.facing == "down", + room .. " save with no dynamic warp (heal " .. case.heal .. ") continues at the Union Room door (got " + .. tostring(c.map) .. " " .. tostring(c.x) .. "," .. tostring(c.y) .. ")") + end + local c = Schema.fromSaveTable(Schema.toSaveTable(linkSession(room))) + check(c.map == CENTER_2F and c.x == 9 and c.y == 1, room .. " save with a dynamic warp still uses it") +end + local outside = linkSession(CENTER_2F) outside.x, outside.y = 7, 4 local o = Schema.fromSaveTable(Schema.toSaveTable(outside)) diff --git a/tests/game3_link_relay_union_test.lua b/tests/game3_link_relay_union_test.lua index 0ac39354..bb7009f3 100644 --- a/tests/game3_link_relay_union_test.lua +++ b/tests/game3_link_relay_union_test.lua @@ -18,17 +18,18 @@ end local FakeRelay = require("tests.g3link_fake_relay") -local UNION_MAP = "FR_UNION_ROOM" +local Plaza = require("src.core.game3.link.union_plaza_map") +local UNION_MAP = Plaza.MAP_ID local CENTER_MAP = "FR_TEST_POKEMON_CENTER_2F" local MAPS = { - [UNION_MAP] = { warps = { { x = 7, y = 11, mapGroup = 0x7F, mapNum = 0x7F, destWarp = 128 } } }, + [UNION_MAP] = { warps = { { x = 12, y = 24, mapGroup = 0x7F, mapNum = 0x7F, destWarp = 128 } } }, [CENTER_MAP] = { warps = { { x = 9, y = 1, destMap = "FR_TRADE_CENTER", destWarp = 1 } } }, FR_TRADE_CENTER = { warps = { { x = 5, y = 8, mapGroup = 0x7F, mapNum = 0x7F, destWarp = 128 } } }, } local store = { flags = {}, vars = {} } local session = { - store = store, map = UNION_MAP, x = 7, y = 11, name = "RED", gender = 0, trainerId = 0x1234, + store = store, map = UNION_MAP, x = 12, y = 24, name = "RED", gender = 0, trainerId = 0x1234, party = { { species = 1, level = 12 }, { species = 4, level = 9 } }, bag = { pockets = { items = {} } }, } @@ -42,7 +43,7 @@ package.loaded["src.core.game3.runtime"] = { isActive = function() return true end, _game = game, } -local Player = { cellX = 7, cellY = 11, facing = "down" } +local Player = { cellX = 12, cellY = 23, facing = "down" } package.loaded["src.core.game3.player"] = Player local mapLoads = {} package.loaded["src.core.game3.map"] = { @@ -181,64 +182,160 @@ local join = Client.last("joinPlaza") eq(join and join[1], "union", "joinPlaza union") eq(join and join[2] and join[2].rulesetId, "g3_link", "with the live g3_link profile") eq(join and join[3] and join[3].name, "RED", "and the avatar") +eq(join and join[4], 40, "announcing the 40-player plaza cap") +eq(Union.capacity(), Plaza.CAP, "the relay room holds 40 players") eq(Client.status, "idle", "presence status goes idle in the Union Room") +check(Union.isUnionMap(UNION_MAP) and Union.isUnionMap("FR_UNION_ROOM"), "both rooms are Union Room maps") +check(not Union.isUnionMap(CENTER_MAP), "the Pokemon Center is not") -print("[test] 2. plaza members fill the leader slots in slot order, self excluded") -Client._plaza = { kind = "union", instance = 1, you = 2, members = { +print("[test] 2. every other trainer stands on the cell of their relay slot, self excluded") +Client._plaza = { kind = "union", instance = 1, cap = 40, rev = 1, you = 2, members = { + member("aaaa0002", 1, "GREEN", 3, 1), member("0000beef", 2, "RED", 0x1234, 0), member("aaaa0001", 5, "BLUE", 0x2222, 0), - member("aaaa0002", 1, "GREEN", 3, 1), } } run(1) eq(Union.playerCount(), 2, "two other trainers") -eq(Union.players[1] and Union.players[1].name, "GREEN", "the lowest relay slot takes cart slot 1") -eq(Union.players[2] and Union.players[2].name, "BLUE", "the next takes cart slot 2") +eq(Union.players[1] and Union.players[1].name, "GREEN", "relay slot 1 is GREEN") +eq(Union.players[5] and Union.players[5].name, "BLUE", "relay slot 5 keeps its number (slot = cell)") +eq(Union.players[2], nil, "our own slot is never drawn") +eq(Union.vobj(2), nil, "and has no avatar") eq(Union.players[1] and Union.players[1].id, "aaaa0002", "the slot remembers the relay id") -eq(objectCalls.added[1], Union.LOCAL_IDS[1], "slot 1's avatar spawned on the scheduled refresh") -eq(getVar(Union.VAR_OBJ_GFX_ID_0), Union.graphicsIdFor(1, 3), "with the class graphics id") -local green = liveObjects[Union.LOCAL_IDS[1]] -eq(green and green.raiseY, -Union.FLY_HEIGHT, "UNION_ROOM_SPAWN_IN starts 160 px up (FLY_DOWN)") -run(10) -eq(green.raiseY, -Union.FLY_HEIGHT + 10 * Union.FLY_STEP, "and drops 8 px a frame") -run(10) -eq(green.raiseY, 0, "landing after 20 frames") -eq(Union.leaderObj(1).state, 1, "the leader is shown") -eq(Union.avatarData().leader_coords[1][1], 4, "leader slot 1 sits at sUnionRoomPlayerCoords[0]") +eq(#objectCalls.added, 0, "no cart map object is used") +local g1 = Union.vobj(1) +local cx1, cy1, cf1 = Plaza.cellFor(1) +check(g1 and g1.visible, "GREEN is a virtual object") +eq(g1 and g1.x, cx1, "on slot 1's cell x") +eq(g1 and g1.y, cy1, "on slot 1's cell y") +eq(g1 and g1.dir, Union.FACE_DIR[cf1], "facing the cell's default") +eq(Union.vobjId(5), Union.VOBJ_BASE + 5, "virtual object ids are VOBJ_BASE + slot") +local b5 = Union.vobj(5) +local cx5, cy5 = Plaza.cellFor(5) +eq(b5 and b5.x, cx5, "BLUE on slot 5's cell x") +eq(b5 and b5.y, cy5, "BLUE on slot 5's cell y") +local rec1 = VirtualObjects.get(Union.vobjId(1)) +eq(rec1 and rec1.graphicsId, Union.graphicsIdFor(1, 3), "with the class graphics id") +check(rec1 and rec1.y2 < 0, "flying in") +run(20) +eq(VirtualObjects.get(Union.vobjId(1)).y2, 0, "and landed") +eq(VirtualObjects.count(), 2, "two avatars in the virtual object pool") -print("[test] 3. refreshes are throttled like the cart, departures fly out") +print("[test] 3. the plaza rebuilds only on a new (instance, rev)") +local builds = Union.plazaBuilds +run(30) +eq(Union.plazaBuilds, builds, "no rebuild while the rev stands still") +Client._plaza.members[3].status = "battling" +run(1) +eq(Union.players[5].activity, Union.ACTIVITY.NONE + Union.IN_UNION_ROOM, "an unannounced change is not applied") +Client._plaza.rev = 2 +run(1) +eq(Union.plazaBuilds, builds + 1, "a new rev rebuilds once") +eq(Union.players[5].activity, Union.ACTIVITY.BATTLE_SINGLE + Union.IN_UNION_ROOM, "BLUE is battling") +eq(b5.x, cx5, "a busy player stays on its cell") +eq(b5.dir, Union.DIR.EAST, "facing its activity") +Client._plaza.members[3].status = "idle" +Client._plaza.instance, Client._plaza.rev = 2, 2 +run(1) +eq(Union.plazaBuilds, builds + 2, "a new instance with the same rev rebuilds too") +eq(b5.dir, Union.FACE_DIR[select(3, Plaza.cellFor(5))], "BLUE is idle again") +local blueRow = table.remove(Client._plaza.members, 3) +Client._plaza.rev = 3 +run(1) +eq(Union.players[5], nil, "a leaver is gone on the delta that drops it") +eq(b5.anim, "out", "and flies out") +run(Union.FLY_HEIGHT / Union.FLY_STEP) +eq(VirtualObjects.get(Union.vobjId(5)), nil, "then leaves the pool") +eq(VirtualObjects.count(), 1, "GREEN stays") +table.insert(Client._plaza.members, blueRow) +Client._plaza.rev = 4 +run(1) +check(Union.vobjVisible(5), "a rejoin on the same slot comes back to the same cell") +run(20) + +print("[test] 3a. a short relay blip keeps the room, a long drop empties it") local realClock = Union.clock local fakeNow = 1000 Union.clock = function() return fakeNow end -local blueRow = table.remove(Client._plaza.members, 2) +Client._state = "reconnecting" run(1) -check(Union.players[2] and not Union.players[2].gone, "a member missing for a moment is not gone yet") -table.insert(Client._plaza.members, 2, blueRow) +fakeNow = fakeNow + Union.GONE_GRACE_SECONDS / 2 +run(1) +eq(Union.playerCount(), 2, "a blip keeps everyone") +Client._state = "online" +run(1) +eq(Union.playerCount(), 2, "and the resumed plaza (same rev) is applied again") +Client._state = "reconnecting" run(1) fakeNow = fakeNow + Union.GONE_GRACE_SECONDS + 1 run(1) -check(Union.players[2] and not Union.players[2].gone, "and a blip that comes back never flies out") -table.remove(Client._plaza.members, 2) -run(1) -fakeNow = fakeNow + Union.GONE_GRACE_SECONDS +eq(Union.playerCount(), 0, "a drop past the grace empties the room") +Client._state = "online" run(1) +eq(Union.playerCount(), 2, "the same rev after the drop still rebuilds") Union.clock = realClock -eq(Union.playerCount(), 2, "not refreshed on the next frame") -check(Union.players[2] and Union.players[2].gone, "BLUE is marked gone once the grace runs out") -local frames = 0 -while Union.playerCount() == 2 and frames < Union.REFRESH_FRAMES + 5 do - run(1) - frames = frames + 1 -end -eq(Union.playerCount(), 1, "BLUE left on the periodic refresh") -check(frames > 200, "which waits for the 300-frame refresh (" .. frames .. ")") -eq(Union.players[1] and Union.players[1].name, "GREEN", "GREEN keeps slot 1 (sticky)") -local blue = liveObjects[Union.LOCAL_IDS[2]] -check(blue ~= nil and blue.raiseY < 0, "UNION_ROOM_SPAWN_OUT flies the avatar up") -run(Union.FLY_HEIGHT / Union.FLY_STEP) -eq(objectCalls.removed[#objectCalls.removed], Union.LOCAL_IDS[2], "then removes the object") -eq(liveObjects[Union.LOCAL_IDS[2]], nil, "slot 2's avatar is gone") +run(20) -print("[test] 3b. a busy pair is one group: leader and member at the cart offsets, facing each other") +print("[test] 3b. a full 40-player plaza: 39 avatars, no per-frame allocation") +local full = {} +for slot = 1, Plaza.CAP do + if slot == 2 then + full[#full + 1] = member("0000beef", 2, "RED", 0x1234, 0) + else + full[#full + 1] = member(string.format("bbbb%04x", slot), slot, "P" .. slot, slot * 7, slot % 2) + end +end +full[1] = member("aaaa0002", 1, "GREEN", 3, 1) +Client._plaza = { kind = "union", instance = 3, cap = 40, rev = 10, you = 2, members = full } +run(1) +eq(Union.playerCount(), Plaza.CAP - 1, "39 other trainers") +run(25) +eq(VirtualObjects.count(), Plaza.CAP - 1, "39 avatars in the pool") +local cellsOk, seen = true, {} +for slot = 1, Plaza.CAP do + if slot ~= 2 then + local v = Union.vobj(slot) + local x, y = Plaza.cellFor(slot) + if not (v and v.visible and v.x == x and v.y == y) or seen[y * 64 + x] then cellsOk = false end + seen[y * 64 + x] = true + end +end +check(cellsOk, "every avatar on its own slot cell") +builds = Union.plazaBuilds +local okJit, jit = pcall(require, "jit") +if okJit and jit and jit.off then jit.off() jit.flush() end +for _ = 1, 10 do Union.relayTick(1 / 60) end +collectgarbage("collect") +collectgarbage("stop") +local kb = collectgarbage("count") +for _ = 1, 600 do Union.relayTick(1 / 60) end +local grown = (collectgarbage("count") - kb) * 1024 +collectgarbage("restart") +if okJit and jit and jit.on then jit.on() end +eq(Union.plazaBuilds, builds, "600 frames on one rev never rebuild") +check(grown == 0, string.format("and allocate nothing (%d bytes)", grown)) +Client._plaza.members[40].status = "chatting" +Client._plaza.rev = 11 +run(1) +eq(Union.plazaBuilds, builds + 1, "one status change is one rebuild") +eq(Union.vobj(40).dir, Union.DIR.SOUTH, "a chatter faces south on its cell") +local x40, y40 = Plaza.cellFor(40) +Player.cellX, Player.cellY, Player.facing = x40 - 1, y40, "right" +input.pressed = { a = true } +run(1) +input.pressed = {} +eq(Union.state, "recv_join_chat_request", "slot 40's chatter is talkable from the west") +check(settle(), "the join prompt asks YES/NO") +answer(false) +drain() +eq(Union.state, "main", "back to the main loop") +Client._plaza = { kind = "union", instance = 1, cap = 40, rev = 20, you = 2, members = { + member("aaaa0002", 1, "GREEN", 3, 1), + member("0000beef", 2, "RED", 0x1234, 0), +} } +run(25) +eq(Union.playerCount(), 1, "back to GREEN alone") + +print("[test] 3c. anyone chatting can be joined, from any side; idle trainers from any side") local pink = member("aaaa0003", 3, "PINK", 5, 1) pink.status = "chatting" pink.group = { leader = "aaaa0003", members = { "aaaa0003", "aaaa0004" }, activity = "chat" } @@ -247,41 +344,30 @@ yellow.status = "chatting" yellow.group = pink.group table.insert(Client._plaza.members, pink) table.insert(Client._plaza.members, yellow) -run(1) -eq(Union.playerCount(), 2, "the member rides with its leader instead of taking a slot") -eq(Union.players[2] and Union.players[2].name, "PINK", "the leader takes the free slot") -eq(Union.players[2] and #Union.players[2].partners, 1, "with YELLOW as its group member") -eq(Union.players[2].activity, Union.ACTIVITY.CHAT + Union.IN_UNION_ROOM, "the group is chatting") -local vl = Union.vobj(2, 0) -local vm = Union.vobj(2, 1) -check(vl and vl.visible, "the leader is a virtual object") -check(vm and vm.visible, "and so is the member") -eq(vl and vl.x, 13, "leader at sUnionRoomPlayerCoords[1].x") -eq(vl and vl.y, 8, "leader at sUnionRoomPlayerCoords[1].y") -eq(vm and vm.x, 14, "member at offset (1,0)") -eq(vl and vl.dir, Union.DIR.SOUTH, "a chat leader faces south") -eq(vm and vm.dir, Union.DIR.WEST, "the member faces the leader") -eq(VirtualObjects.count(), 2, "both are in the virtual object pool") -check((VirtualObjects.get(Union.vobjId(2, 0)) or {}).y2 < 0, "flying in") -run(20) -eq((VirtualObjects.get(Union.vobjId(2, 0)) or {}).y2, 0, "and landed") -eq(liveObjects[Union.LOCAL_IDS[2]], nil, "no object event for a busy leader") - -print("[test] 3c. talking to a chatting group offers to join; a member gives a reaction") +Client._plaza.rev = 21 +run(21) +eq(Union.playerCount(), 3, "no grouping: the chat member has its own slot") +eq(Union.players[4] and Union.players[4].name, "YELLOW", "YELLOW on slot 4") +eq(Union.players[3].partners, nil, "no partner lists") +local vy = Union.vobj(4) +local x4, y4 = Plaza.cellFor(4) +eq(vy and vy.x, x4, "YELLOW stands on slot 4's cell") +eq(vy and vy.dir, Union.DIR.SOUTH, "facing its chat") Union.toMain() Message.reset() -Player.cellX, Player.cellY, Player.facing = 13, 9, "up" +Player.cellX, Player.cellY, Player.facing = x4, y4 + 1, "up" input.pressed = { a = true } run(1) input.pressed = {} -eq(Union.state, "recv_join_chat_request", "A in front of the chat leader") +eq(Union.state, "recv_join_chat_request", "A in front of a chat member who is not the host") +eq(vy.dir, Union.DIR.SOUTH, "YELLOW turns to face the player") check(settle(), "the join prompt asks YES/NO") if romBundle then - check(shows(RomText.ascii("sText_JoinChatFemale")), "gTexts_UR_JoinChat for a female leader") + check(shows(RomText.ascii("sText_JoinChatMale")), "gTexts_UR_JoinChat for a male chatter") end answer(true) local jinv = Client.last("invite") -eq(jinv and jinv[1], "aaaa0003", "joining asks the leader") +eq(jinv and jinv[1], "aaaa0004", "joining asks YELLOW directly") eq(jinv and jinv[2], "chat", "for the chat") eq(jinv and jinv[3] and jinv[3].join, true, "as a join") eq(Union.state, "send_activity_request", "waiting for the relay") @@ -290,32 +376,76 @@ jh.state, jh.why = "closed", "busy" run(1) eq(Union.state, "print_and_exit", "a refused join") if romBundle then - check(shows(RomText.ascii(RomText.key("gTexts_UR_ChatDeclined", 1))), "reads gTexts_UR_ChatDeclined") + check(shows(RomText.ascii(RomText.key("gTexts_UR_ChatDeclined", 0))), "reads gTexts_UR_ChatDeclined") end drain() eq(Union.state, "main", "back to the main loop") -Player.cellX, Player.cellY, Player.facing = 14, 9, "up" +eq(vy.dir, Union.DIR.SOUTH, "YELLOW faces its chat again") +local x3, y3 = Plaza.cellFor(3) +pink.group.members = { "aaaa0003", "aaaa0004", "c1", "c2", "c3" } +Client._plaza.rev = 22 +run(1) +Player.cellX, Player.cellY, Player.facing = x3 + 1, y3, "left" input.pressed = { a = true } run(1) input.pressed = {} -eq(Union.state, "print_and_exit", "A in front of a group member") -eq(vm.dir, Union.DIR.SOUTH, "the member turns to face the player") -run(2) -check(Message.isOpen(), "a reaction line") +eq(Union.state, "print_and_exit", "a full chat (5 seats) only gets a reaction") +eq(Union.vobj(3).dir, Union.DIR.EAST, "PINK turns east to the player") drain() -eq(vm.dir, Union.DIR.WEST, "and turns back to its leader") -Player.cellX, Player.cellY, Player.facing = 7, 11, "down" +local xg, yg = Plaza.cellFor(1) +for _, side in ipairs({ { 0, 1, "up" }, { 0, -1, "down" }, { -1, 0, "right" }, { 1, 0, "left" } }) do + Union.toMain() + Message.reset() + Player.cellX, Player.cellY, Player.facing = xg + side[1], yg + side[2], side[3] + input.pressed = { a = true } + run(1) + input.pressed = {} + eq(Union.state, "do_something_prompt", "idle GREEN is talkable facing " .. side[3]) + Union.toMain() + Union.flow = nil + Message.reset() +end +eq(Union.vobj(1).dir, Union.FACE_DIR[cf1], "and turns back to its cell facing") +Player.cellX, Player.cellY, Player.facing = 12, 23, "down" + +print("[test] 3d. a relay that refuses this build shows the update prompt once") +Union.toMain() +Message.reset() +Client._state = "error" +Client.upgradeRequired = function() return { type = "upgrade_required", text = "This build is too old for online play. Please update." } end +run(1) +eq(Union.state, "print_and_exit", "upgrade_required prints") +tickMsg() +check(Message.isOpen() and tostring(Message.currentPage()):find("too old", 1, true) ~= nil, "the relay's update text") +drain() +eq(Union.state, "main", "back to the main loop") +run(5) +eq(Union.state, "main", "and it is shown only once") +Client.upgradeRequired = nil +Client._state = "online" +run(25) +eq(Union.playerCount(), 3, "the room comes back when the relay does") +Union.toMain() +Message.reset() print("[test] 4. talking to a trainer: HiDoSomething, the invite menu, the cart's reject") run(1) local held = ctx.stateWait -eq(held, Union.scriptWaitTask, "the Union Room holds the next waitstate (UnionRoom_EventScript_Player#)") +eq(held, Union.scriptWaitTask, "the Union Room holds the next waitstate") ctx.stateWait = nil Flags.setVar(store, ctx, 0x800D, 1) eq(held(), false, "setvar VAR_RESULT, 1 then waitstate: the script waits") Flags.setVar(store, ctx, 0x800D, 0) run(1) +eq(Union.state, "main", "a VAR_RESULT that is not the attendant talks to no slot") +eq(Union.flow, nil, "and opens no flow") +eq(held(), true, "the waitstate is released") +Player.cellX, Player.cellY, Player.facing = xg, yg + 1, "up" +input.pressed = { a = true } +run(1) +input.pressed = {} eq(Union.state, "do_something_prompt", "talking to GREEN") +Player.cellX, Player.cellY, Player.facing = 12, 23, "down" check(settle(), "the activity menu opens") eq(Screen.mode, "activity", "GREETINGS / BATTLE / CHAT / EXIT") if romBundle then @@ -342,7 +472,6 @@ check(shows(RomText.ascii(RomText.key("gTexts_UR_BattleDeclined", 1))), "the partner's gendered battle refusal (GetURoomActivityRejectMsg)") drain() eq(Union.state, "main", "back to the main loop") -eq(held(), true, "and the talk script is released") Union.partnerId = 1 Union.chooseActivity(3) @@ -499,9 +628,10 @@ eq(board and board.wantType, 10, "wanting a FIRE type") drain() eq(Union.state, "main", "registration complete") -local greenMember = Client._plaza.members[2] +local greenMember = Client._plaza.members[1] eq(greenMember.name, "GREEN", "GREEN's plaza row") greenMember.board = { species = 4, level = 9, wantType = 12 } +Client._plaza.rev = Client._plaza.rev + 1 run(1) eq(Union.players[1].board and Union.players[1].board.species, 4, "GREEN's board offer is on the member row") local offers = Union.boardOffers() @@ -542,6 +672,39 @@ end eq(Union.state, "main", "back from the board") Player.cellX, Player.cellY, Player.facing = 7, 11, "down" +print("[test] 7b. the board lists every offer in the room and scrolls; EXIT never collides") +for slot = 5, 16 do + local m = member(string.format("cccc%04x", slot), slot, "T" .. slot, slot, 0) + m.board = { species = slot, level = slot, wantType = 12 } + table.insert(Client._plaza.members, m) +end +Client._plaza.rev = Client._plaza.rev + 1 +run(1) +eq(#Union.boardOffers(), 13, "13 offers from 40 possible slots") +Union.openTradingBoard() +eq(Screen.mode, "board", "the trading board") +local items = Screen.list.items +eq(#items, 15, "header, 13 offers, EXIT") +eq(items[#items].id, Screen.BOARD_EXIT, "EXIT has its own id") +eq(items[10].id, 8, "the ninth offer keeps id 8") +check(items[10].entry ~= nil and not items[10].disabled, "and is a real, pickable offer") +eq(Screen.list.maxShowed, 5, "five rows at a time") +Screen.select(10) +check(Screen.list.scroll > 0, "the list scrolls to reach it") +Screen.confirm() +check(Union.state ~= "main", "picking offer id 8 opens that offer, not EXIT (" .. tostring(Union.state) .. ")") +Union.toMain() +Message.reset() +Union.openTradingBoard() +Screen.select(#Screen.list.items) +Screen.confirm() +eq(Union.state, "main", "EXIT closes the board") +for i = #Client._plaza.members, 1, -1 do + if tostring(Client._plaza.members[i].id):sub(1, 4) == "cccc" then table.remove(Client._plaza.members, i) end +end +Client._plaza.rev = Client._plaza.rev + 1 +run(25) + Union.trade().playerSpecies, Union.trade().playerLevel = 1, 12 Flags.setVar(store, ctx, 0x800D, Union.INTERACT_ATTENDANT) run(1) diff --git a/tests/game3_link_union_test.lua b/tests/game3_link_union_test.lua index 93e7476c..a9fdec5c 100644 --- a/tests/game3_link_union_test.lua +++ b/tests/game3_link_union_test.lua @@ -111,16 +111,6 @@ local function getVar(id) return tonumber(Flags.getVar(store, ctx, id)) or 0 end -local function peerHello(name, trainerId, gender) - return { - type = Union.MSG.HELLO, - name = name, - trainerId = trainerId, - gender = gender or 0, - activity = Union.ACTIVITY.SEARCH + Union.IN_UNION_ROOM, - } -end - print("[test] 1. the union room specials answer to their pret index") local EXPECTED = { TryBecomeLinkLeader = 0x16B, @@ -153,7 +143,7 @@ end eq(#logs, 0, "nothing reached the unknown-special log") Link.reset() -print("[test] 3. RunUnionRoom starts the session and announces to the peer") +print("[test] 3. RunUnionRoom always opens the relay plaza, never a cable room") local host, guest = FakeRelay.pair({ game = game }) host:update(0) guest:update(0) @@ -164,74 +154,17 @@ Flags.setVar(store, ctx, Link.VAR_RESULT, 5) Natives.special(ctx, NativesLink.SPECIAL.RunUnionRoom, adapters) eq(Union.state, "init", "RunUnionRoom armed the union room task") eq(getVar(Link.VAR_RESULT), 0, "VAR_RESULT is cleared on entry") +eq(Union.relay, true, "with a cable link up and no relay the room is still the plaza") +eq(Union.capacity(), 40, "holding 40 players") Union.update(0) eq(Union.state, "main", "the session reached the main loop") guest:update(0) -local heard = guest:take(Union.MSG.HELLO) -check(heard ~= nil, "the peer heard this player enter the union room") -eq(heard and heard.name, "RED", "with the player's name") - -print("[test] 4. the player list fills from the transport and spawns an avatar") -guest:send(peerHello("BLUE", 0x2222, 0)) +eq(guest:take("game3_union_hello"), nil, "nothing is announced over the cable") +guest:send({ type = "game3_union_hello", name = "BLUE", trainerId = 0x2222, gender = 0, activity = 0x4C }) host:update(0) Union.update(0) -eq(Union.playerCount(), 1, "one other player is in the room") -local listed = Union.list()[1] -eq(listed and listed.name, "BLUE", "the list names the peer") -eq(listed and listed.slot, 1, "in the first leader slot") -eq(objectCalls.added[1], Union.LOCAL_IDS[1], "the slot 1 union room object was spawned") -eq(Flags.getFlag(store, ctx, Union.FLAG_HIDE_PLAYER_1), false, - "FLAG_HIDE_UNION_ROOM_PLAYER_1 was cleared") -eq(getVar(Union.VAR_OBJ_GFX_ID_0), Union.graphicsIdFor(0, 0x2222), - "VAR_OBJ_GFX_ID_0 holds the trainer-class graphics id") - -print("[test] 5. BufferUnionRoomPlayerName hands the nurse the name once") -local _, first = NativesLink.HANDLERS[NativesLink.SPECIAL.BufferUnionRoomPlayerName](ctx, adapters) -eq(first, 1, "the first call reports TRUE") -eq(ctx.stringVars[1], "BLUE", "and buffers the name into STR_VAR_1") -local _, second = NativesLink.HANDLERS[NativesLink.SPECIAL.BufferUnionRoomPlayerName](ctx, adapters) -eq(second, 0, "the second call reports FALSE") - -print("[test] 6. talking to a player opens the activity chooser") -Flags.setVar(store, ctx, Link.VAR_RESULT, 1) -Union.update(0) -eq(Union.partnerId, 1, "the interaction picked the player in slot 1") -Union.update(0) -check(Screen.isOpen(), "the union room screen opened") -eq(Screen.mode, "activity", "in activity-chooser mode") -eq(#Screen.items, 4, "with the four pret entries") -teq(Screen.labelFor(Screen.items[1]), "GREETINGS", "GREETINGS first") -teq(Screen.labelFor(Screen.items[4]), "EXIT", "EXIT last") - -print("[test] 7. BATTLE has no level limit") -session.party = { { species = 1, level = 42 }, { species = 4, level = 60 } } -Screen.cursor = 2 -Screen.confirm() -eq(Union.activity, Union.ACTIVITY.BATTLE_SINGLE + Union.IN_UNION_ROOM, - "the battle request carries ACTIVITY_BATTLE_SINGLE | IN_UNION_ROOM") -eq(Union.state, "send_activity_request", "and the request went out") -guest:update(0) -local request = guest:take(Union.MSG.REQUEST) -check(request ~= nil, "the peer received the activity request") -eq(request and request.activity, Union.ACTIVITY.BATTLE_SINGLE + Union.IN_UNION_ROOM, - "with the same activity id") - -print("[test] 8. a partner that never answers frees the room again") -eq(Union.state, "send_activity_request", "the request is still outstanding") -Union.update(Union.RESPONSE_SECONDS + 0.1) -eq(Union.lastResult, "busy", "the partner is reported busy") -Union.update(0) -eq(Union.state, "main", "and the union room goes back to its main loop") -eq(Union.activity, nil, "with no pending activity") - -print("[test] 9. EXIT leaves the chooser without contacting anybody") -Union.state = "do_something_prompt" -Union.partnerId = 1 -Union.update(0) -Screen.cursor = 4 -Screen.confirm() -eq(Union.activity, nil, "EXIT clears the pending activity") -eq(Union.state, "main", "and returns to the union room main loop") +eq(Union.playerCount(), 0, "and a cable hello adds nobody") +eq(#objectCalls.added, 0, "no cart player object is spawned") print("[test] 10. stepping on the union room pad returns the dynamic warp, not a header map") local pad = MAPS[UNION_MAP].warps[1] @@ -243,29 +176,15 @@ eq(destX, 5, "at the counter door x") eq(destY, 3, "at the counter door y") print("[test] 11. leaving the union room map ends the session") -objectCalls.removed = {} Space.mapId = CENTER_MAP session.map = CENTER_MAP local alive = Union.update(0) eq(alive, false, "the union room task stopped") eq(Union.state, "off", "the session is closed") -eq(Union.playerCount(), 0, "the player list is empty") -eq(objectCalls.removed[1], Union.LOCAL_IDS[1], "the spawned avatar was removed") -guest:update(0) -check(guest:take(Union.MSG.BYE) ~= nil, "the peer was told this player left") -print("[test] 12. InitUnionRoom scans from the Pokemon Center without spawning avatars") -objectCalls.added = {} +print("[test] 12. InitUnionRoom has no cable to scan") Natives.special(ctx, NativesLink.SPECIAL.InitUnionRoom, adapters) -eq(Union.state, "search", "the Pokemon Center ON_RESUME scan is running") -guest:send(peerHello("GREEN", 0x3333, 1)) -host:update(0) -Union.update(0) -eq(Union.playerCount(), 1, "the scan found a union room player") -eq(#objectCalls.added, 0, "and spawned nothing on the Pokemon Center map") -local _, greeted = NativesLink.HANDLERS[NativesLink.SPECIAL.BufferUnionRoomPlayerName](ctx, adapters) -eq(greeted, 1, "the nurse can greet the player it found") -eq(ctx.stringVars[1], "GREEN", "by name") +eq(Union.state, "off", "the Pokemon Center ON_RESUME call starts nothing") print("[test] 13. the link group flows answer LINKUP through VAR_RESULT") Link.reset() @@ -275,11 +194,6 @@ local host2, guest2 = FakeRelay.pair({ game = game }) host2:update(0) guest2:update(0) Link.attach(host2) -Natives.special(ctx, NativesLink.SPECIAL.RunUnionRoom, adapters) -Union.update(0) -guest2:send(peerHello("BLUE", 0x2222, 0)) -host2:update(0) -Union.update(0) Flags.setVar(store, ctx, Link.VAR_0x8004, Union.LINK_GROUP.SINGLE_BATTLE) local yielded = Natives.special(ctx, NativesLink.SPECIAL.TryBecomeLinkLeader, adapters) @@ -331,90 +245,6 @@ else end end -print("[test] an incoming activity request is answered, never parked") -Link.reset() -Union.reset() -local reqHost, reqGuest = FakeRelay.pair({ game = game }) -reqHost:update(0) -reqGuest:update(0) -Link.attach(reqHost) -Space.mapId = UNION_MAP -session.map = UNION_MAP -Natives.special(ctx, NativesLink.SPECIAL.RunUnionRoom, adapters) -Union.update(0) -reqGuest:update(0) -while reqGuest:take(Union.MSG.HELLO) do end -reqGuest:send({ type = Union.MSG.REQUEST, name = "BLUE", - activity = Union.ACTIVITY.CHAT + Union.IN_UNION_ROOM }) -reqHost:update(0) -Union.update(1 / 60) -eq(Union.activity, Union.ACTIVITY.CHAT + Union.IN_UNION_ROOM, - "the request lands in UR_STATE_RECV_ACTIVITY_REQUEST with the activity asked for") -eq(Union._requestName, "BLUE", "and the name of the trainer who asked") --- pokefirered/src/union_room.c:4486 -local prompt = Union.requestPrompt() -if romBundle then - eq(prompt, require("src.core.game3.rom_text").ascii("gText_UR_ChatInvitation"), - "the prompt is the cart's chat invitation") -else - print("[skip] ROM text: the contact prompt reads gText_UR_ChatInvitation") -end -Union.update(1 / 60) -reqHost:update(0) -reqGuest:update(0) -local answer = reqGuest:take(Union.MSG.RESPONSE) -check(answer ~= nil, "the peer gets a RESPONSE instead of timing out on a parked room") -check(Union.state ~= "player_contacted_you", "and the room leaves player_contacted_you") - -print("[test] the chooser's CHAT and GREETINGS start real activities") -local Chat = require("src.core.game3.link.chat") -Union.state = "main" -Union.activity = nil -Union.chooseActivity(3) -eq(Union.state, "send_activity_request", "CHAT asks the partner first") -reqGuest:update(0) -reqGuest:take(Union.MSG.REQUEST) -reqGuest:send({ type = Union.MSG.RESPONSE, accept = true }) -reqHost:update(0) -Union.update(1 / 60) -eq(Union.state, "in_activity", "an accepted CHAT enters the chat activity") -check(Chat.isActive(), "and the chat session is live") -Chat.say("HI") -reqGuest:update(0) -local said = reqGuest:take(Chat.MSG.LINE) -eq(said and said.text, "HI", "a line the player writes goes out on the wire") -reqGuest:send({ type = Chat.MSG.LINE, name = "BLUE", text = "HELLO" }) -reqHost:update(0) -Chat.update(1 / 60) -eq(#Chat.lines, 2, "and the peer's line lands in the log") -check(Chat.lines[2] and Chat.lines[2].text:find("BLUE", 1, true) == 1 - and Chat.lines[2].text:sub(-6) == ":HELLO", "with the peer's name and words") -Chat.stop("left") -Union.update(1 / 60) -eq(Union.state, "main", "leaving the chat puts the room back in its main loop") - -Union.state = "main" -Union.activity = nil -Union.chooseActivity(1) -eq(Union.state, "send_activity_request", "GREETINGS asks the partner first") -reqGuest:update(0) -reqGuest:take(Union.MSG.REQUEST) -reqGuest:send({ type = Union.MSG.RESPONSE, accept = true }) -reqHost:update(0) -Union.update(1 / 60) --- pokefirered/src/union_room.c:1954 CB2_ShowCard -eq(Union.state, "in_activity", "an accepted GREETINGS shows a trainer card") -eq(Union.lastResult, "card_shown", "built from CreateTrainerCardInBuffer") -local cardOut = nil -reqGuest:update(0) -local seen = reqGuest:take(Link.MSG.CARD) -while seen do - cardOut = seen - seen = reqGuest:take(Link.MSG.CARD) -end -check(cardOut ~= nil, "and this machine's own card went out to the peer") -eq(cardOut and cardOut.card and cardOut.card.name, session.name, "carrying the player's name") - print("[test] the link group at the counter lists the machine on the cable") Link.reset() Union.reset() diff --git a/tests/game3_union_plaza_map_test.lua b/tests/game3_union_plaza_map_test.lua new file mode 100644 index 00000000..f086dc5a --- /dev/null +++ b/tests/game3_union_plaza_map_test.lua @@ -0,0 +1,199 @@ +#!/usr/bin/env luajit +package.path = "./?.lua;./?/init.lua;" .. package.path + +local failed = 0 +local function check(cond, msg) + if cond then + print("[ok] " .. msg) + else + failed = failed + 1 + print("[FAIL] " .. msg) + end +end +local function eq(a, b, msg) + check(a == b, string.format("%s (%s == %s)", msg, tostring(a), tostring(b))) +end + +local Plaza = require("src.core.game3.link.union_plaza_map") + +print("[test] contract") +eq(Plaza.MAP_ID, "FR_UNION_ROOM_PLAZA", "map id") +eq(Plaza.CAP, 40, "cap") +eq(#Plaza.CELLS, 41, "41 cells on the grid") +eq(#Plaza.ROLES, 25, "role grid is 25 rows") +local badRow = nil +for y, row in ipairs(Plaza.ROLES) do + if #row ~= 25 then badRow = y end + for i = 1, #row do + if not Plaza.SOURCE[row:sub(i, i)] then badRow = y end + end +end +check(badRow == nil, "every role row is 25 wide with a known role: " .. tostring(badRow)) + +print("[test] slot table") +local seen, unique = {}, 0 +for slot = 1, Plaza.CAP do + local x, y, facing = Plaza.cellFor(slot) + check(x ~= nil and y ~= nil and facing ~= nil, "slot " .. slot .. " has a cell") + local k = tostring(x) .. "," .. tostring(y) + if not seen[k] then unique = unique + 1 end + seen[k] = true + eq(Plaza.slotAt(x, y), slot, "slotAt inverts slot " .. slot) +end +eq(unique, 40, "40 unique cells") +check(Plaza.cellFor(0) == nil and Plaza.cellFor(41) == nil, "slots outside 1..40 have no cell") +check(Plaza.slotAt(12, 24) == nil and Plaza.slotAt(0, 0) == nil, "slotAt is nil off the cell table") + +local ex, ey = Plaza.entry() +local function dist(slot) + local x, y = Plaza.cellFor(slot) + return math.abs(x - ex) + math.abs(y - (ey - 1)) +end +local sorted = true +for slot = 2, Plaza.CAP do + if dist(slot) < dist(slot - 1) then sorted = false end +end +check(sorted, "fill order moves outward from the entrance") +local x1, y1 = Plaza.cellFor(1) +eq(x1, 12, "slot 1 sits on the entrance column") +eq(y1, 17, "slot 1 is the first cell up from the door") +local sx, sy = Plaza.cellFor(40) +check(sy == 5, "slot 40 is on the far row") + +print("[test] geometry") +eq(ex, 12, "entry x") +eq(ey, 24, "entry y") +eq(Plaza.roleAt(ex, ey), "X", "entry is the exit mat") +local attX, attY = 3, 2 +local blocked = {} +local function key(x, y) return y * 64 + x end +for _, c in ipairs(Plaza.CELLS) do blocked[key(c.x, c.y)] = true end +blocked[key(attX, attY)] = true +local function walkable(x, y) + local r = Plaza.roleAt(x, y) + return r ~= nil and not Plaza.BLOCKED[r] and not blocked[key(x, y)] +end +local reach = { [key(ex, ey)] = true } +local queue = { { ex, ey } } +local head = 1 +while queue[head] do + local p = queue[head] + head = head + 1 + for _, d in ipairs({ { 1, 0 }, { -1, 0 }, { 0, 1 }, { 0, -1 } }) do + local nx, ny = p[1] + d[1], p[2] + d[2] + if walkable(nx, ny) and not reach[key(nx, ny)] then + reach[key(nx, ny)] = true + queue[#queue + 1] = { nx, ny } + end + end +end +local allSides, onBad = true, {} +for _, c in ipairs(Plaza.CELLS) do + for _, d in ipairs({ { 1, 0 }, { -1, 0 }, { 0, 1 }, { 0, -1 } }) do + if not reach[key(c.x + d[1], c.y + d[2])] then + allSides = false + print((" cell %d,%d side %d,%d unreachable"):format(c.x, c.y, d[1], d[2])) + end + end + local r = Plaza.roleAt(c.x, c.y) + if Plaza.BLOCKED[r] or c.y <= 3 or c.y >= 23 or (c.x == ex and c.y >= 19) then + onBad[#onBad + 1] = c.x .. "," .. c.y + end +end +check(allSides, "every cell is reachable from all 4 sides with the room full") +eq(#onBad, 0, "no cell on a wall, the counter rows or the exit lane") +check(reach[key(2, 2)] == true, "the trading board spot below the counter is reachable") +check(reach[key(3, 3)] == true, "the attendant is reachable from the front") + +print("[test] a cache that cannot build the plaza is a hard error") +eq(Plaza.shouldUse, nil, "no switch back to the cart room") +local function fails(game, want, msg) + local ok, err = pcall(Plaza.ensure, game) + check(not ok and tostring(err):find(want, 1, true) ~= nil, msg .. ": " .. tostring(err)) +end +local realMap = package.loaded["src.core.game3.map"] +package.loaded["src.core.game3.map"] = { ensureMidLayout = function() end } +fails({ data = {} }, "no map table", "no map table") +fails({ data = { maps = {} } }, "FR_UNION_ROOM is missing from the cache", "no FR_UNION_ROOM") +fails({ data = { maps = { FR_UNION_ROOM = { warps = {} } } } }, "FR_UNION_ROOM has no layout", + "FR_UNION_ROOM without a layout") +local tiny = { width = 4, height = 4, cellAt = function() return { mid = 1, coll = 0, elev = 0 } end } +fails({ data = { maps = { FR_UNION_ROOM = { warps = {}, midLayout = tiny } } } }, "layout has no cell", + "a truncated FR_UNION_ROOM layout") +local Adapters = require("src.core.game3.scripting.adapters") +local broken = Adapters.host(nil, { data = { maps = { FR_UNION_ROOM = { warps = {} } } } }, nil) +local realVersions = package.loaded["src.import.gba.versions"] +package.loaded["src.import.gba.versions"] = { + frMapFor = function() return "FR_UNION_ROOM" end, + seviiMapFor = function() return nil end, +} +local okWarp, warpErr = pcall(broken.warp, 1, 1, 0xFF, 7, 11, function() end, "warpspinenter") +package.loaded["src.import.gba.versions"] = realVersions +package.loaded["src.core.game3.map"] = realMap +check(not okWarp and tostring(warpErr):find("FR_UNION_ROOM has no layout", 1, true) ~= nil, + "the Union Room warp errors instead of landing in the cart room: " .. tostring(warpErr)) + +print("[test] built from the imported cache") +local Cache = require("tests.game3_cache") +local root = Cache.mount("meta.json", { native = true }) +if not root then + print("[skip] plaza cache build: " .. tostring(Cache.reason)) +else + local Dataset = require("src.core.game3.dataset") + local maps = Dataset.buildMaps() + local src = maps.FR_UNION_ROOM + check(src ~= nil, "FR_UNION_ROOM is in the cache") + Dataset.attachMidLayouts({ FR_UNION_ROOM = src }, Cache.cache()) + local game = { data = { maps = maps } } + local def = Plaza.ensure(game) + check(def ~= nil and maps[Plaza.MAP_ID] == def, "ensure registers the plaza def") + eq(Plaza.ensure(game), def, "ensure is idempotent") + if def and src and src.midLayout then + local L = def.midLayout + eq(L.width, 25, "layout width") + eq(L.height, 25, "layout height") + eq(def.width, 25, "def width") + eq(def.height, 25, "def height") + eq(def.pair, src.pair, "same tileset pair as the cart room") + local srcMids = {} + local SL = src.midLayout + for y = 0, (SL.trueHeight or SL.height) - 1 do + for x = 0, (SL.trueWidth or SL.width) - 1 do + srcMids[SL:midAt(x, y)] = true + end + end + local foreign, collMismatch = 0, 0 + for y = 0, 24 do + for x = 0, 24 do + if not srcMids[L:midAt(x, y)] then foreign = foreign + 1 end + local c = L:collAt(x, y) + local r = Plaza.roleAt(x, y) + if (c ~= 0) ~= (Plaza.BLOCKED[r] == true or r == "X") then + collMismatch = collMismatch + 1 + end + end + end + eq(foreign, 0, "every metatile comes from the Union Room layout") + eq(collMismatch, 0, "blocked roles match the cart collision") + for slot = 1, Plaza.CAP do + local x, y = Plaza.cellFor(slot) + if L:collAt(x, y) ~= 0 then check(false, "slot " .. slot .. " cell is floor") end + end + eq(#def.warps, 1, "one warp") + local w, sw = def.warps[1], src.warps[1] + eq(w.x, 12, "warp x") + eq(w.y, 24, "warp y") + eq(w.mapGroup, sw.mapGroup, "warp group matches FR_UNION_ROOM") + eq(w.mapNum, sw.mapNum, "warp num matches FR_UNION_ROOM") + eq(w.destWarp, sw.destWarp, "warp dest matches FR_UNION_ROOM") + eq(w.destMap, sw.destMap, "warp destMap matches FR_UNION_ROOM") + eq(L:collAt(12, 24), SL:collAt(7, 11), "exit tile keeps the cart warp collision") + eq(def.music, src.music, "music copied") + end +end + +if failed > 0 then + print(("[FAIL] %d check(s) failed"):format(failed)) + os.exit(1) +end +print("[PASS] union plaza map") diff --git a/tests/mod_ui_tests.lua b/tests/mod_ui_tests.lua index 0d4d7f5a..37e84a8a 100644 --- a/tests/mod_ui_tests.lua +++ b/tests/mod_ui_tests.lua @@ -288,7 +288,7 @@ local WANT_IDS = { "textSpeed", "animations", "battleStyle", "battleLayout", "performance", "colors", "tilt", "uiLetterbox", "shaderfx", "shaderfx2", "zoom", "voidFill", "videoMode", "faithfulRes", "screenPos", "fpsCap", "vsync", "logicClock", - "speedOverworld", "speedBattle", "speedMenu", + "speedOverworld", "speedMenu", "mods", "controls", "dateFormat", "timeFormat" } local function orow(menu, id) for _, row in ipairs(menu.rows) do diff --git a/tests/online_client_gen3.lua b/tests/online_client_gen3.lua index c73faf87..d1d8df90 100644 --- a/tests/online_client_gen3.lua +++ b/tests/online_client_gen3.lua @@ -367,7 +367,7 @@ end do local w = newWorld() - local A = w:add(0x30, "ANN") + local A, sA = w:add(0x30, "ANN") local B = w:add(0x31, "BEN") local Mon = w:add(0x32, "MON") w:pump() @@ -379,8 +379,17 @@ do check(p ~= nil and p.kind == "union", "plaza_state lands") eq(p and p.you, 1, "the first member takes slot 1") eq(p and #p.members, 1, "and is alone") + eq(p and p.cap, 40, "plaza_state carries the 40 cap") + local sentJoin = w.relay:sent(sA, "plaza_join")[1] + eq(sentJoin and sentJoin.cap, 40, "a union plaza_join announces cap 40") + local inst0, rev0 = A.plazaRev() + check(inst0 ~= nil and type(rev0) == "number", "plazaRev reports (instance, rev)") B.joinPlaza("union", PROFILE3, avatar("BEN", 201, 0)) w:pump() + local inst1, rev1 = A.plazaRev() + eq(inst1, inst0, "the joiner lands in the same instance") + check(rev1 > rev0, "a plaza_delta moves the rev forward") + eq(select(2, B.plazaRev()), rev1, "the joiner's plaza_state rev matches the delta rev") eq(#A.plaza().members, 2, "plaza_delta adds the joiner") eq(A.plaza().members[2].slot, 2, "members sort by slot") eq(A.plaza().members[2].avatar.trainerId, 201, "and carry their avatar") @@ -681,6 +690,8 @@ do "group_open", "group_list" } local seq = table.concat(order, ",") eq(seq, table.concat(want, ","), "a fresh welcome re-sends the session state in order") + local rejoin = w.relay:sent(sa, "plaza_join") + eq(rejoin[#rejoin] and rejoin[#rejoin].cap, 40, "the re-sent plaza_join keeps cap 40") local presence = w.relay:sent(sa, "presence") eq(presence[#presence].status, "busy", "the re-sent presence is the latest") local sp = w.relay:sent(sa, "set_profiles") diff --git a/tests/run_tests.lua b/tests/run_tests.lua index 652ecd31..a182bc9e 100644 --- a/tests/run_tests.lua +++ b/tests/run_tests.lua @@ -2972,8 +2972,6 @@ do check(seek("vsync"), "cursor reaches VSYNC") press("a") eq(og.save.options.vsync, "off", "A cycles VSYNC to OFF") - -- RFC 0007: the single GAME SPEED row is now three independent rows, - -- one per GameSpeed.CATEGORIES entry. check(seek("speedOverworld"), "cursor reaches OVERWORLD SPEED") press("a") eq(og.save.options.speedOverworld, 2, "A cycles OVERWORLD SPEED to 2X") @@ -2982,11 +2980,7 @@ do -- bug when the cycling is fine and the row is simply one longer. for _ = 1, #GameSpeed.LEVELS - 1 do press("a") end eq(og.save.options.speedOverworld, 1, "OVERWORLD SPEED wraps back to NORMAL") - check(seek("speedBattle"), "cursor reaches BATTLE SPEED") - press("a") - eq(og.save.options.speedBattle, 2, "A cycles BATTLE SPEED to 2X") - for _ = 1, #GameSpeed.LEVELS - 1 do press("a") end - eq(og.save.options.speedBattle, 1, "BATTLE SPEED wraps back to NORMAL") + check(not seek("speedBattle"), "no BATTLE SPEED row: battles always run 1X") check(seek("speedMenu"), "cursor reaches MENU SPEED") press("a") eq(og.save.options.speedMenu, 2, "A cycles MENU SPEED to 2X") diff --git a/tests/support/fake_relay.lua b/tests/support/fake_relay.lua index 21c9d139..218c929e 100644 --- a/tests/support/fake_relay.lua +++ b/tests/support/fake_relay.lua @@ -38,6 +38,7 @@ function FakeRelay.new(opts) invites = {}, tokens = {}, plazas = { union = {} }, + plazaRev = 0, wireless = {}, groups = {}, groupWatch = {}, @@ -369,9 +370,9 @@ end local function memberOf(s, slot) return { id = s.id, name = s.name, verified = true, slot = slot, - online = s.online, status = s.recruiting and "recruiting" or "idle", + online = s.online, status = s.status or (s.recruiting and "recruiting" or "idle"), avatar = copy(s.avatar), recruiting = copy(s.recruiting), - board = copy(s.presence.board) } + board = copy(s.presence.board), group = copy(s.group) } end function FakeRelay:plazaInstance(s) @@ -381,8 +382,12 @@ function FakeRelay:plazaInstance(s) return nil end +FakeRelay.PLAZA_CAP = 40 + function FakeRelay:plazaDelta(inst, index, fields, except) - local msg = { type = "plaza_delta", kind = "union", instance = index, + self.plazaRev = self.plazaRev + 1 + inst.rev = self.plazaRev + local msg = { type = "plaza_delta", kind = "union", instance = index, rev = inst.rev, joined = fields.joined or {}, left = fields.left or {}, changed = fields.changed or {} } for id in pairs(inst.slots) do @@ -397,8 +402,8 @@ function FakeRelay:plazaStateMsg(s) members[#members + 1] = memberOf(self.sessions[id], slot) end table.sort(members, function(a, b) return a.slot < b.slot end) - return { type = "plaza_state", kind = "union", instance = index, - you = inst.slots[s.id], members = members } + return { type = "plaza_state", kind = "union", instance = index, cap = FakeRelay.PLAZA_CAP, + rev = inst.rev, you = inst.slots[s.id], members = members } end function FakeRelay:plazaJoin(s, msg) @@ -409,6 +414,12 @@ function FakeRelay:plazaJoin(s, msg) if type(msg.profile) ~= "table" or msg.profile.engine ~= 3 then return self:joinError(s, "bad_profile") end + if not (math.floor(tonumber(msg.cap) or 0) >= FakeRelay.PLAZA_CAP) then + self:to(s, { type = "upgrade_required", protocol = self.minProtocol, minBuild = nil, + text = "This build is too old for online play. Please update." }) + s.transport.closed = true + return + end s.avatar = copy(msg.avatar) s.where = "union" if self:plazaInstance(s) then return self:to(s, self:plazaStateMsg(s)) end @@ -416,13 +427,13 @@ function FakeRelay:plazaJoin(s, msg) for i, inst in ipairs(self.plazas.union) do local n = 0 for _ in pairs(inst.slots) do n = n + 1 end - if n < 9 and (not best or n > best.n) then best, bestIndex = { inst = inst, n = n }, i end + if n < FakeRelay.PLAZA_CAP and (not best or n > best.n) then best, bestIndex = { inst = inst, n = n }, i end end local inst, index if best then inst, index = best.inst, bestIndex else - inst = { slots = {} } + inst = { slots = {}, rev = 0 } self.plazas.union[#self.plazas.union + 1] = inst index = #self.plazas.union end @@ -431,8 +442,8 @@ function FakeRelay:plazaJoin(s, msg) local slot = 1 while used[slot] do slot = slot + 1 end inst.slots[s.id] = slot - self:to(s, self:plazaStateMsg(s)) self:plazaDelta(inst, index, { joined = { memberOf(s, slot) } }, s.id) + self:to(s, self:plazaStateMsg(s)) end function FakeRelay:plazaLeave(s, kind) diff --git a/tools/run_driver.sh b/tools/run_driver.sh index 086b21c2..6d5ab8f3 100755 --- a/tools/run_driver.sh +++ b/tools/run_driver.sh @@ -3,6 +3,7 @@ set -u ROOT="$(cd "$(dirname "$0")/.." && pwd)" SLOW_DRIVERS="game3_daycare_egg game3_daycare_menu game3_daycare_deposit game3_import2_fresh_cache game3_import2_town_map game3_trade_scene game3_u8c_yesno_frame game3_u9c_catch_ball_open" +REALTIME_DRIVERS="battle_fanfare_speed_bug1952_test" help_text() { cat < Date: Fri, 25 Sep 2026 10:40:32 -0400 Subject: [PATCH 5/6] splash screen --- assets/launcher/splash.ogv | Bin 0 -> 808266 bytes main.lua | 32 ++++++++++- src/import/LauncherSplash.lua | 97 ++++++++++++++++++++++++++++++++++ 3 files changed, 128 insertions(+), 1 deletion(-) create mode 100644 assets/launcher/splash.ogv create mode 100644 src/import/LauncherSplash.lua diff --git a/assets/launcher/splash.ogv b/assets/launcher/splash.ogv new file mode 100644 index 0000000000000000000000000000000000000000..20c4e37a370c4bfedccca549968e8d53cc202ae9 GIT binary patch literal 808266 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�Cl2Zl@Nw&){9i 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

X0HYwa65QP2$)RzCL{oS#Y+01+_~Z5 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

CL-2eb4E0zGBOOB%piBJ$A6$g*U#f1zqNWl09 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 mFGoe;`CXRA%`lF{?xlq%`X`(lq86he+CtNeH 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≫9SD)913TUS@4ALanjx%czIRUic0`;TT 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 literal 0 HcmV?d00001 diff --git a/main.lua b/main.lua index 4dd9ba50..ca9aa79b 100644 --- a/main.lua +++ b/main.lua @@ -133,6 +133,7 @@ do end local Game, EditorApp, Importer, TouchEditor, Studio, Prelaunch +local launcherSplash -- #887: quit-to-launcher state, shared by love.load and love.quit (both need -- it, so it is declared here rather than next to love.quit). @@ -592,7 +593,7 @@ end local deferredLaunchRequest local function launcherBusy() - return Importer ~= nil and (Importer._updateAll ~= nil + return launcherSplash ~= nil or Importer ~= nil and (Importer._updateAll ~= nil or Importer._modInstall ~= nil or Importer._cartInstall ~= nil or Importer._autoUpdateAll ~= nil) end @@ -841,6 +842,7 @@ function love.load(args) -- Edit on a save row opens the bundled editor on that slot (openEditor). Importer = makeLauncher() if not relaunched then + launcherSplash = require("src.import.LauncherSplash").new() autoUpdateMods(resolvedLaunch, not resolvedLaunch.game and "mods" or nil) end @@ -852,6 +854,14 @@ function love.update(dt) SwitchDiagnostics.maybeFlush(false) -- NX only (no-op elsewhere): follow dock/undock without waiting for SDL. NxDisplay.sync() + if launcherSplash then + if launcherSplash:update(dt) then + launcherSplash:release() + launcherSplash = nil + if Importer and Importer.resumeAfterOverlay then Importer:resumeAfterOverlay() end + end + return + end if editorMode then return EditorApp.update(dt) end if TouchEditor then return TouchEditor.update(dt) end if Studio then return Studio.update(dt) end @@ -947,6 +957,7 @@ function love.draw() GameViewport.reset() HostDisplay.beginFrame("launcher", Importer) local result = Importer:draw() + if launcherSplash then launcherSplash:draw() end HostDisplay.endFrame("launcher", Importer) return result end @@ -974,6 +985,7 @@ function love.draw() end function love.keypressed(key, scancode, isrepeat) + if launcherSplash then return end if editorMode then return EditorApp.keypressed(key) end if TouchEditor then return TouchEditor.keypressed(key) end if Studio then return Studio.keypressed(key) end @@ -984,6 +996,7 @@ function love.keypressed(key, scancode, isrepeat) end function love.keyreleased(key) + if launcherSplash then return end if editorMode or TouchEditor or Studio then return end if Importer then return end if not Game then return end @@ -991,6 +1004,7 @@ function love.keyreleased(key) end function love.gamepadpressed(joystick, button) + if launcherSplash then return end SwitchDiagnostics.onJoystickEvent("gamepadpressed", joystick, button) if PadHints.windowMinimized() then return end if editorMode then @@ -1013,6 +1027,7 @@ function love.gamepadpressed(joystick, button) end function love.gamepadreleased(joystick, button) + if launcherSplash then return end SwitchDiagnostics.onJoystickEvent("gamepadreleased", joystick, button) if editorMode then if EditorApp and EditorApp.gamepadreleased then @@ -1033,6 +1048,7 @@ function love.gamepadreleased(joystick, button) end function love.gamepadaxis(joystick, axis, value) + if launcherSplash then return end SwitchDiagnostics.onJoystickEvent("gamepadaxis", joystick, axis, { value = value }) if PadHints.windowMinimized() then value = 0 end if editorMode then @@ -1054,6 +1070,7 @@ function love.gamepadaxis(joystick, axis, value) end function love.joystickpressed(joystick, button) + if launcherSplash then return end SwitchDiagnostics.onJoystickEvent("joystickpressed", joystick, button) if PadHints.windowMinimized() then return end if editorMode then @@ -1075,6 +1092,7 @@ function love.joystickpressed(joystick, button) end function love.joystickreleased(joystick, button) + if launcherSplash then return end SwitchDiagnostics.onJoystickEvent("joystickreleased", joystick, button) if editorMode then if EditorApp and EditorApp.joystickreleased then @@ -1095,6 +1113,7 @@ function love.joystickreleased(joystick, button) end function love.joystickaxis(joystick, axis, value) + if launcherSplash then return end SwitchDiagnostics.onJoystickEvent("joystickaxis", joystick, axis, { value = value }) if PadHints.windowMinimized() then value = 0 end if editorMode then @@ -1116,6 +1135,7 @@ function love.joystickaxis(joystick, axis, value) end function love.joystickhat(joystick, hat, direction) + if launcherSplash then return end SwitchDiagnostics.onJoystickEvent("joystickhat", joystick, hat, { direction = direction }) if PadHints.windowMinimized() then direction = "c" end if editorMode then @@ -1234,6 +1254,7 @@ function love.handlers.intent_uri(uri) end function love.touchpressed(id, x, y, dx, dy, pressure) + if launcherSplash then return end if editorMode then -- iOS synthesizes mousepressed for the primary touch; forwarding here -- would double-fire. Android / NX need the explicit touch → click path @@ -1263,6 +1284,7 @@ function love.touchpressed(id, x, y, dx, dy, pressure) end function love.touchmoved(id, x, y, dx, dy, pressure) + if launcherSplash then return end if editorMode then return end if TouchEditor then if love.system.getOS() == "iOS" then return end @@ -1277,6 +1299,7 @@ function love.touchmoved(id, x, y, dx, dy, pressure) end function love.touchreleased(id, x, y, dx, dy, pressure) + if launcherSplash then return end if editorMode then return end if TouchEditor then if love.system.getOS() == "iOS" then return end @@ -1291,6 +1314,7 @@ function love.touchreleased(id, x, y, dx, dy, pressure) end function love.wheelmoved(x, y) + if launcherSplash then return end if editorMode then if EditorApp.wheelmoved then return EditorApp.wheelmoved(x, y) end return @@ -1328,6 +1352,7 @@ if love.system and love.system.getOS() == "Linux" end function love.mousepressed(x, y, button, istouch) + if launcherSplash then return end if not istouch then eventMouseX, eventMouseY = x, y end if TouchEditor then -- Android primary touch already arrived via love.touchpressed; a second @@ -1375,6 +1400,7 @@ function love.mousepressed(x, y, button, istouch) end function love.mousereleased(x, y, button, istouch) + if launcherSplash then return end if TouchEditor then if love.system.getOS() == "Android" then return end return TouchEditor.mousereleased(x, y, button) @@ -1395,6 +1421,7 @@ function love.mousereleased(x, y, button, istouch) end function love.mousemoved(x, y, dx, dy, istouch) + if launcherSplash then return end if not istouch then eventMouseX, eventMouseY = x, y end if TouchEditor then if love.system.getOS() == "Android" then return end @@ -1413,6 +1440,7 @@ function love.mousemoved(x, y, dx, dy, istouch) end function love.textinput(text) + if launcherSplash then return end if TouchEditor then return end if Studio then return Studio.textinput(text) end if Importer then return Importer:textinput(text) end @@ -1428,6 +1456,7 @@ end local quitToLauncher = false function love.quit() + if launcherSplash then launcherSplash:release(); launcherSplash = nil end if Importer then require("src.import.LauncherWindow").observe(0) require("src.import.LauncherWindow").flush() @@ -1491,6 +1520,7 @@ function love.quit() end function love.filedropped(file) + if launcherSplash then return end local filename = file and file.getFilename and file:getFilename() if LaunchOptions.isLaunchURI(filename) then local request = LaunchOptions.parseURI(filename) diff --git a/src/import/LauncherSplash.lua b/src/import/LauncherSplash.lua new file mode 100644 index 00000000..6eac316c --- /dev/null +++ b/src/import/LauncherSplash.lua @@ -0,0 +1,97 @@ +local LauncherSplash = {} +LauncherSplash.__index = LauncherSplash + +local DURATION = 127 / 30 +local FADE_SECONDS = 0.75 +local REVEAL_SECONDS = 0.65 + +local function smoothstep(value) + local t = math.max(0, math.min(1, value)) + return t * t * (3 - 2 * t) +end + +function LauncherSplash.new() + local self = setmetatable({ elapsed = 0, age = 0, opacity = 1 }, LauncherSplash) + local ok, err = pcall(function() + self.video = love.graphics.newVideo("assets/launcher/splash.ogv", { + audio = love.audio ~= nil, + }) + self.video:setFilter("linear", "linear") + local width, height = self.video:getDimensions() + self.canvas = love.graphics.newCanvas(width, height) + self.canvas:setFilter("linear", "linear") + self.shader = love.graphics.newShader([[ + extern number opacity; + vec4 effect(vec4 color, Image texture, vec2 uv, vec2 screen) { + vec4 pixel = Texel(texture, uv); + float brightness = max(pixel.r, max(pixel.g, pixel.b)); + float coverage = smoothstep(0.015, 0.10, brightness); + return vec4(pixel.rgb, pixel.a * coverage * opacity) * color; + } + ]]) + local options = require("src.core.SaveData").loadOptions() + self.volume = math.max(0, math.min(7, tonumber(options.sfxVol) or 7)) / 7 + local source = self.video:getSource() + if source then source:setVolume(self.volume) end + self.video:play() + end) + if not ok then + self:release() + print("[launcher splash] unavailable: " .. tostring(err)) + return nil + end + return self +end + +function LauncherSplash:update(dt) + self.age = self.age + dt + self.elapsed = self.video:tell() + self.opacity = 1 - smoothstep((self.elapsed - (DURATION - FADE_SECONDS)) / FADE_SECONDS) + local source = self.video:getSource() + if source then source:setVolume(self.volume * self.opacity) end + -- A decoder that stalls must not prevent access to the launcher. + return self.elapsed >= DURATION - 0.035 or not self.video:isPlaying() + or self.age > DURATION + 2 +end + +function LauncherSplash:draw() + local g = love.graphics + local width, height = g.getDimensions() + local vw, vh = self.video:getDimensions() + local scale = width / vw + local backdrop = 1 - smoothstep((self.elapsed - DURATION / 2) / REVEAL_SECONDS) + + g.push("all") + g.origin() + g.setScissor() + g.setShader() + g.setBlendMode("alpha", "alphamultiply") + g.setColor(0, 0, 0, backdrop) + g.rectangle("fill", 0, 0, width, height) + + -- Video supplies YUV planes, so convert through a canvas before keying RGB. + local target = g.getCanvas() + g.setCanvas(self.canvas) + g.clear(0, 0, 0, 0) + g.setColor(1, 1, 1, 1) + g.draw(self.video, 0, 0) + g.setCanvas(target) + self.shader:send("opacity", self.opacity) + g.setShader(self.shader) + g.draw(self.canvas, 0, (height - vh * scale) / 2, 0, scale, scale) + g.pop() +end + +function LauncherSplash:release() + if self.video then + self.video:pause() + local source = self.video:getSource() + if source then source:stop() end + end + for _, key in ipairs({ "video", "canvas", "shader" }) do + local resource = self[key] + if resource then resource:release(); self[key] = nil end + end +end + +return LauncherSplash From 8d1e1551c795443805262ac5de71a1628f00d8cb Mon Sep 17 00:00:00 2001 From: bryanthaboi Date: Fri, 25 Sep 2026 11:12:10 -0400 Subject: [PATCH 6/6] mod count in saves --- src/core/SaveData.lua | 1 + src/sync/SyncEngine.lua | 3 +++ tests/engine/sync_session_meta_test.lua | 20 ++++++++++++++++++++ 3 files changed, 24 insertions(+) diff --git a/src/core/SaveData.lua b/src/core/SaveData.lua index cc9473a0..09e8451a 100644 --- a/src/core/SaveData.lua +++ b/src/core/SaveData.lua @@ -2011,6 +2011,7 @@ function SaveData.buildMeta(mods, previous, sessionStart) cartHash = type(previous) == "table" and previous.cartHash or nil, sealBroken = (type(previous) == "table" and previous.sealBroken == true) or nil, mods = list, + modCount = #list, } end diff --git a/src/sync/SyncEngine.lua b/src/sync/SyncEngine.lua index a1679f9f..0ef0fe6b 100644 --- a/src/sync/SyncEngine.lua +++ b/src/sync/SyncEngine.lua @@ -207,6 +207,9 @@ function SyncEngine.defaultSaves() playthroughId = id, format = meta.format, engine = meta.engine, + -- Derive from the saved set, including older saves that + -- predate modCount, rather than this device's current mods. + modCount = #(type(meta.mods) == "table" and meta.mods or {}), playTime = tonumber(save.playTime), summary = { name = name, diff --git a/tests/engine/sync_session_meta_test.lua b/tests/engine/sync_session_meta_test.lua index 36bf7a65..39c257c2 100644 --- a/tests/engine/sync_session_meta_test.lua +++ b/tests/engine/sync_session_meta_test.lua @@ -32,6 +32,13 @@ end do local plain = SaveData.buildMeta({}) + T.eq(plain.modCount, 0, "vanilla saves explicitly record zero mods") + local modded = SaveData.buildMeta({ { id = "one" }, { id = "two" } }) + T.eq(modded.modCount, 2, "the count reflects the mods that wrote the save") + T.eq(SaveData.buildMeta(nil, modded).modCount, 2, + "a headless rewrite preserves the saved mod count") + T.eq(SaveData.buildMeta({}, modded).modCount, 0, + "disabling all mods clears the previous count") T.check(type(plain.savedAt) == "number", "a save still records when it ended") T.eq(plain.sessionStart, nil, "and records no session start when nobody supplied one") @@ -106,9 +113,22 @@ do T.eq(entries[1].meta.summary.name, "ASH", "with the launcher summary the conflict prompt shows") T.check(entries[1].meta.sessionStart ~= nil, "and the session start") + T.eq(entries[1].meta.modCount, 0, "sync metadata explicitly reports vanilla") + T.eq(SaveData.decode(entries[1].blob).meta.modCount, 0, + "the saved blob also carries the count") T.check(entries[1].blob:find("ASH", 1, true) ~= nil, "the blob is the encoded save itself") + save.meta.mods = { { id = "one" }, { id = "two" } } + save.meta.modCount = nil + SaveData.writeSlot("red", slotId, save) + T.eq(provider.list()[1].meta.modCount, 2, + "older saves derive their sync count from their own mod list") + save.meta.modCount = 99 + SaveData.writeSlot("red", slotId, save) + T.eq(provider.list()[1].meta.modCount, 2, + "a stale count cannot override the saved mod list") + local other = SaveData.newGame() other.player.name = "BLUE" other.meta = SaveData.buildMeta({}, { playthroughId = "xyz" }, os.time() - 30)