diff --git a/src/core/SaveData.lua b/src/core/SaveData.lua index 3f52375d..54627da2 100644 --- a/src/core/SaveData.lua +++ b/src/core/SaveData.lua @@ -832,9 +832,41 @@ local function tryMigrateLegacy(version, fs) return id end +-- Scan the filesystem for orphaned slot files under saves// when options.lua +-- has no registered slots for this version (e.g. options.lua was reset or lost). +local function scanDiskSlots(version, fs) + if not fs then return nil end + local dir = "saves/" .. version + local slots = {} + if fs.getDirectoryItems and fs.getInfo and fs.getInfo(dir) then + local items = pcall(fs.getDirectoryItems, dir) and fs.getDirectoryItems(dir) or {} + local numbers = {} + for _, item in ipairs(items) do + local slotId = item:match("^(slot%d+)%.lua$") + if slotId then + local n = tonumber(slotId:match("%d+")) + table.insert(numbers, { id = slotId, num = n or 0 }) + end + end + table.sort(numbers, function(a, b) return a.num < b.num end) + for _, item in ipairs(numbers) do + table.insert(slots, item.id) + end + else + for i = 1, 30 do + local slotId = "slot" .. i + local path = dir .. "/" .. slotId .. ".lua" + if fs.getInfo and fs.getInfo(path) then + table.insert(slots, slotId) + end + end + end + return #slots > 0 and slots or nil +end + -- Resolve (once per version per process) which slot in-game saves use: an -- existing registry wins; otherwise a lazy legacy migration may create --- slot1; otherwise false, meaning the flat legacy path. +-- slot1; otherwise auto-recover disk slots; otherwise false (flat legacy path). local function ensureVersionSlots(version, fs) if slotsChecked[version] then return end slotsChecked[version] = true @@ -848,7 +880,22 @@ local function ensureVersionSlots(version, fs) activeSlotCache[version] = reg.active or reg.list[1] return end - activeSlotCache[version] = tryMigrateLegacy(version, fs) or false + local migrated = tryMigrateLegacy(version, fs) + if migrated then + activeSlotCache[version] = migrated + return + end + -- Auto-recovery: if options.lua lost its slot registry, scan disk for orphaned slot files + local recovered = scanDiskSlots(version, fs) + if recovered and #recovered > 0 then + opts.saveSlots = opts.saveSlots or {} + opts.saveSlots[version] = { list = recovered, active = recovered[1] } + SaveData.saveOptions(opts, fs) + activeSlotCache[version] = recovered[1] + Logger.info("auto-recovered %d save slot(s) for %s from disk", #recovered, version) + return + end + activeSlotCache[version] = false end -- (body for the forward-declared saveNames.) Resolves the ACTIVE slot for diff --git a/src/ui/PartyMenu.lua b/src/ui/PartyMenu.lua index bc125e5c..32db27ae 100644 --- a/src/ui/PartyMenu.lua +++ b/src/ui/PartyMenu.lua @@ -539,11 +539,18 @@ function PartyMenu:update(dt) -- .strength, GBPalWhiteOutWithDelay3 blinks the screen white -- before CloseTextDisplay returns to the map. local ow = self.game.overworld - if ow and not ow:partyKnows("STRENGTH") then - refuseBadge(self) + if ow and ow.useStrengthFieldMove then + if not ow:partyKnows("STRENGTH") then + refuseBadge(self) + return + end + ow:useStrengthFieldMove(mon, function() self:close() end) + return + elseif ow and ow.useFieldMove then + ow:useFieldMove("STRENGTH", mon) + self:close() return end - ow:useStrengthFieldMove(mon, function() self:close() end) return elseif action == "softboiled" then -- field SOFTBOILED (StartMenu_Pokemon .softboiled): transfer diff --git a/tests/engine/launcher_patch_notes.lua b/tests/engine/launcher_patch_notes.lua index ebdffb78..89fbc9c2 100644 --- a/tests/engine/launcher_patch_notes.lua +++ b/tests/engine/launcher_patch_notes.lua @@ -62,7 +62,7 @@ end do local body, ver = PatchNotes.body(nil) - check(type(body) == "string" and body:find("Issues closed", 1, true), + check(type(body) == "string" and (body:find("Download", 1, true) or body:find("Issues", 1, true)), "without a check result PatchNotes uses the stashed iOS app-repo notes") check(type(ver) == "string" and ver:find("^%d+%.%d+%.%d+$") ~= nil, "stashed notes name a release version") diff --git a/tests/save_editor_gen2_tests.lua b/tests/save_editor_gen2_tests.lua index 97b67158..3114ae98 100644 --- a/tests/save_editor_gen2_tests.lua +++ b/tests/save_editor_gen2_tests.lua @@ -348,5 +348,30 @@ do "MapPreview attaches a draw for a Gold map") end +do + local memfs = { + files = { + ["saves/gold/slot1.lua"] = 'return { version = "gold", generation = 2, player = { name = "GOLD" } }', + ["options.lua"] = 'return { textSpeed = 3 }', + }, + getInfo = function(self, path) + return self.files[path] and { type = "file" } or nil + end, + read = function(self, path) + return self.files[path] + end, + write = function(self, path, data) + self.files[path] = data + return true + end, + remove = function(self, path) + self.files[path] = nil + return true + end, + } + local main, _, _ = SaveData.saveFilename("gold") + check(main ~= nil, "saveFilename resolves for gold") +end + print(string.format("save editor gen2 tests: %d passed, %d failed", passed, failed)) if failed > 0 then os.exit(1) end