fix: restore wild encounter grace period

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
This commit is contained in:
Shane McGovern
2026-08-10 12:15:18 +01:00
parent 943ba5dcbf
commit ae1b59ce7f
2 changed files with 39 additions and 0 deletions
+16
View File
@@ -37,6 +37,10 @@ local mapScripts -- registry of hand-ported map scripts
local COMPASS = { up = "north", down = "south", left = "west", right = "east" }
local DIRVEC = { up = { 0, -1 }, down = { 0, 1 }, left = { -1, 0 }, right = { 1, 0 } }
-- pokered's wNumberOfNoRandomBattleStepsLeft: three completed steps
-- after a wild battle before another random battle can start.
local WILD_ENCOUNTER_GRACE_STEPS = 3
-- Fly animation coord paths (engine/overworld/player_animations.asm):
-- y/x pairs in GB screen pixels, one pair every 3 frames (DoFlyAnimation's
-- Delay3). The port anchors a path on the player's own position instead
@@ -224,6 +228,8 @@ function OverworldState:enter(mapId, x, y, facing, opts)
-- a fresh entry, or a stale flag can freeze player input forever
self.engaging = false
self.emote = nil
-- volatile WRAM state in pokered; never serialize across save/load
self.wildEncounterGraceSteps = 0
-- survives save/load: a loaded game may start inside a building whose
-- exit mat is a LAST_MAP warp
self.lastOutdoor = Game.save.lastOutdoor
@@ -3472,6 +3478,10 @@ end
function OverworldState:onStepComplete()
local p = self.player
local suppressWildEncounter = self.wildEncounterGraceSteps > 0
if suppressWildEncounter then
self.wildEncounterGraceSteps = self.wildEncounterGraceSteps - 1
end
self.todSteps = (self.todSteps or 0) + 1
-- UpdatePikachuHappinessAndMood rides the step counter (poison.asm)
require("src.world.PikachuFollower").onStep(Game.save)
@@ -3584,6 +3594,9 @@ function OverworldState:onStepComplete()
-- wild encounters in grass, on water while surfing, or -- on indoor
-- maps whose tileset is not FOREST -- on EVERY tile
-- (wild_encounters.asm: caves, towers, the Mansion, Power Plant)
-- The cooldown is checked after all other step processing so repel and
-- movement systems continue to advance during the protected steps.
if suppressWildEncounter then return end
local encDef = Game.data.encounters[self.map.id]
local enc
local indoor = Game.data.field.indoorEncounters
@@ -3970,6 +3983,9 @@ end
-- battle is optional; when given, Oak's Lab OPP_RIVAL1 losses skip the
-- blackout (pret HandlePlayerBlackOut) so the map script can HealParty.
function OverworldState:afterBattle(result, battle)
if battle and battle.kind == "wild" then
self.wildEncounterGraceSteps = WILD_ENCOUNTER_GRACE_STEPS
end
local lead = Game.save.party[1]
Logger.info("battle over: %s (lead %s %d/%d)", tostring(result),
lead and lead.species or "-", lead and lead.hp or 0,
+23
View File
@@ -823,6 +823,29 @@ do
and caught.enemy.mon.species == "TANGELA",
"and it is the species the authored encounter table names")
-- Trainer battles do not arm the wild-encounter cooldown.
walker.wildEncounterGraceSteps = 0
walker:afterBattle("win", { kind = "trainer" })
check(walker.wildEncounterGraceSteps == 0,
"trainer battles do not start the wild encounter grace period")
-- pokered grants three completed steps after a wild battle before the
-- next random battle can start (end_of_battle.asm + home/overworld.asm).
local finishedWild = caught
walker:afterBattle("run", finishedWild)
caught = nil
withBuses(function(_, hooks)
hooks:wrap("encounter.roll", function()
return { species = "TANGELA", level = 5 }
end, 0, "grace-period")
for step = 1, 3 do
pcall(walker.onStepComplete, walker)
check(caught == nil, "wild encounter grace period blocks step " .. step)
end
pcall(walker.onStepComplete, walker)
check(caught ~= nil, "wild encounter is eligible on step 4")
end)
-- the same walk with an encounter.roll wrapper never starts a battle
withBuses(function(_, hooks)
hooks:wrap("encounter.roll", function() return nil end, 0, "nuzlocke")