From 0d490e57d36915014935a9e3509f5533ff4b96f3 Mon Sep 17 00:00:00 2001 From: robjlyons <81177492+robjlyons@users.noreply.github.com> Date: Wed, 11 Feb 2026 10:55:52 +0000 Subject: [PATCH 01/12] Fix overworld poison-faint run-away handling --- engine/events/poison.asm | 32 +++----------------------------- 1 file changed, 3 insertions(+), 29 deletions(-) diff --git a/engine/events/poison.asm b/engine/events/poison.asm index 9d87b3ca..f3c66345 100644 --- a/engine/events/poison.asm +++ b/engine/events/poison.asm @@ -68,7 +68,9 @@ ApplyOutOfBattlePoisonDamage: callfar PlayPikachuSoundClip callfar_ModifyPikachuHappiness PIKAHAPPY_PSNFNT .curMonNotPlayerPikachu - call HandlePoisonFaintedMonRanAway + ld a, [wWhichPokemon] + ld [wPlayerMonNumber], a + callfar HandleFaintedPlayerMonRanAway pop de pop hl jr .restartAfterRemoval @@ -148,34 +150,6 @@ ApplyOutOfBattlePoisonDamage: ld [wOutOfBattleBlackout], a ret -PoisonFaintedMonRanAwayText: - text_far _PokemonRanAwayBadTrainingText - text_end - -HandlePoisonFaintedMonRanAway: - ld a, [wPartyCount] - cp 1 - ret z ; don't remove the final party mon to avoid invalid 0-mon party state - ld hl, wPartyMonNicks - call GetPartyMonName - ld hl, PoisonFaintedMonRanAwayText - call PrintText - xor a - ld [wRemoveMonFromBox], a - call RemovePokemon - ld a, [wPartyCount] - and a - ret z - dec a - ld b, a - ld a, [wWhichPokemon] - cp b - jr c, .done - ld a, b - ld [wWhichPokemon], a -.done - ret - Func_c4c7: ld a, [wStepCounter] and a From 9f66b83ada62eeb34f3852ddab849910513b88b5 Mon Sep 17 00:00:00 2001 From: robjlyons <81177492+robjlyons@users.noreply.github.com> Date: Wed, 11 Feb 2026 11:56:47 +0000 Subject: [PATCH 02/12] Also block catches for species already in PC boxes --- engine/battle/core.asm | 109 +++++++++++++++++++++++++++++++++++++++ engine/events/poison.asm | 32 ++---------- 2 files changed, 112 insertions(+), 29 deletions(-) diff --git a/engine/battle/core.asm b/engine/battle/core.asm index f13ed4b7..0d7300c0 100644 --- a/engine/battle/core.asm +++ b/engine/battle/core.asm @@ -170,6 +170,9 @@ StartBattle: ld a, c and a jr z, .skipWildCatchInit + call IsEnemyMonSpeciesInPlayerCollection + and a + jr nz, .skipWildCatchInit ld a, 1 ld [wWildEncounterCanCatch], a .skipWildCatchInit @@ -1207,6 +1210,112 @@ DisableEncounterCatchSRAM_Battle: ld [$0000], a ; disable SRAM ret +; Returns non-zero if the current wild enemy species is in the player's party or PC boxes. +IsEnemyMonSpeciesInPlayerCollection: + call IsEnemyMonSpeciesInPlayerParty + and a + ret nz + call IsEnemyMonSpeciesInAnyPlayerPCBox + and a + ret + +; Returns non-zero if the current wild enemy species is already present in the player's party. +IsEnemyMonSpeciesInPlayerParty: + ld a, [wPartyCount] + ld c, a + ld hl, wPartySpecies +.loop + ld a, c + and a + jr z, .notInParty + ld a, [hli] + ld b, a + ld a, [wEnemyMonSpecies] + cp b + jr z, .inParty + dec c + jr .loop +.inParty + ld a, 1 + ret +.notInParty + xor a + ret + +; Returns non-zero if the current wild enemy species is present in any of the player's PC boxes. +IsEnemyMonSpeciesInAnyPlayerPCBox: + ld d, 0 +.boxLoop + ld a, d + cp NUM_BOXES + jr z, .notInPC + push de + call IsEnemyMonSpeciesInPlayerPCBox + pop de + and a + jr nz, .inPC + inc d + jr .boxLoop +.inPC + ld a, 1 + ret +.notInPC + xor a + ret + +; Checks one PC box. +; in: d = box index (0 to NUM_BOXES - 1) +; out: non-zero if the current wild enemy species exists in that box +IsEnemyMonSpeciesInPlayerPCBox: + ld a, d + cp NUM_BOXES / 2 + ld b, 2 + jr c, .haveBank + ld b, 3 + sub NUM_BOXES / 2 +.haveBank + ld e, a + ld d, 0 + ld hl, BattleBoxSRAMPointerTable + add hl, de + add hl, de + ld a, [hli] + ld h, [hl] + ld l, a + call EnableSRAM + ld a, b + ld [rRAMB], a + ld a, [hl] + ld c, a + inc hl +.scanSpeciesLoop + ld a, c + and a + jr z, .notInBox + ld a, [hli] + ld b, a + ld a, [wEnemyMonSpecies] + cp b + jr z, .inBox + dec c + jr .scanSpeciesLoop +.inBox + call DisableSRAM + ld a, 1 + ret +.notInBox + call DisableSRAM + xor a + ret + +BattleBoxSRAMPointerTable: + dw sBox1 ; sBox7 + dw sBox2 ; sBox8 + dw sBox3 ; sBox9 + dw sBox4 ; sBox10 + dw sBox5 ; sBox11 + dw sBox6 ; sBox12 + ; asks if you want to use next mon ; stores whether you ran in C flag DoUseNextMonDialogue: diff --git a/engine/events/poison.asm b/engine/events/poison.asm index 9d87b3ca..f3c66345 100644 --- a/engine/events/poison.asm +++ b/engine/events/poison.asm @@ -68,7 +68,9 @@ ApplyOutOfBattlePoisonDamage: callfar PlayPikachuSoundClip callfar_ModifyPikachuHappiness PIKAHAPPY_PSNFNT .curMonNotPlayerPikachu - call HandlePoisonFaintedMonRanAway + ld a, [wWhichPokemon] + ld [wPlayerMonNumber], a + callfar HandleFaintedPlayerMonRanAway pop de pop hl jr .restartAfterRemoval @@ -148,34 +150,6 @@ ApplyOutOfBattlePoisonDamage: ld [wOutOfBattleBlackout], a ret -PoisonFaintedMonRanAwayText: - text_far _PokemonRanAwayBadTrainingText - text_end - -HandlePoisonFaintedMonRanAway: - ld a, [wPartyCount] - cp 1 - ret z ; don't remove the final party mon to avoid invalid 0-mon party state - ld hl, wPartyMonNicks - call GetPartyMonName - ld hl, PoisonFaintedMonRanAwayText - call PrintText - xor a - ld [wRemoveMonFromBox], a - call RemovePokemon - ld a, [wPartyCount] - and a - ret z - dec a - ld b, a - ld a, [wWhichPokemon] - cp b - jr c, .done - ld a, b - ld [wWhichPokemon], a -.done - ret - Func_c4c7: ld a, [wStepCounter] and a From 31e12f3b602650358aa8c6f71586de815e9eb211 Mon Sep 17 00:00:00 2001 From: robjlyons <81177492+robjlyons@users.noreply.github.com> Date: Wed, 11 Feb 2026 12:18:31 +0000 Subject: [PATCH 03/12] Harden PC species scan for empty/uninitialized boxes --- engine/battle/core.asm | 115 +++++++++++++++++++++++++++++++++++++++ engine/events/poison.asm | 32 +---------- 2 files changed, 118 insertions(+), 29 deletions(-) diff --git a/engine/battle/core.asm b/engine/battle/core.asm index f13ed4b7..606e9cf6 100644 --- a/engine/battle/core.asm +++ b/engine/battle/core.asm @@ -170,6 +170,9 @@ StartBattle: ld a, c and a jr z, .skipWildCatchInit + call IsEnemyMonSpeciesInPlayerCollection + and a + jr nz, .skipWildCatchInit ld a, 1 ld [wWildEncounterCanCatch], a .skipWildCatchInit @@ -1207,6 +1210,118 @@ DisableEncounterCatchSRAM_Battle: ld [$0000], a ; disable SRAM ret +; Returns non-zero if the current wild enemy species is in the player's party or PC boxes. +IsEnemyMonSpeciesInPlayerCollection: + call IsEnemyMonSpeciesInPlayerParty + and a + ret nz + call IsEnemyMonSpeciesInAnyPlayerPCBox + and a + ret + +; Returns non-zero if the current wild enemy species is already present in the player's party. +IsEnemyMonSpeciesInPlayerParty: + ld a, [wPartyCount] + ld c, a + ld hl, wPartySpecies +.loop + ld a, c + and a + jr z, .notInParty + ld a, [hli] + ld b, a + ld a, [wEnemyMonSpecies] + cp b + jr z, .inParty + dec c + jr .loop +.inParty + ld a, 1 + ret +.notInParty + xor a + ret + +; Returns non-zero if the current wild enemy species is present in any of the player's PC boxes. +IsEnemyMonSpeciesInAnyPlayerPCBox: + ld d, 0 +.boxLoop + ld a, d + cp NUM_BOXES + jr z, .notInPC + push de + call IsEnemyMonSpeciesInPlayerPCBox + pop de + and a + jr nz, .inPC + inc d + jr .boxLoop +.inPC + ld a, 1 + ret +.notInPC + xor a + ret + +; Checks one PC box. +; in: d = box index (0 to NUM_BOXES - 1) +; out: non-zero if the current wild enemy species exists in that box +IsEnemyMonSpeciesInPlayerPCBox: + ld a, d + cp NUM_BOXES / 2 + ld b, 2 + jr c, .haveBank + ld b, 3 + sub NUM_BOXES / 2 +.haveBank + ld e, a + ld d, 0 + ld hl, BattleBoxSRAMPointerTable + add hl, de + add hl, de + ld a, [hli] + ld h, [hl] + ld l, a + call EnableSRAM + ld a, b + ld [rRAMB], a + ld a, [hl] + ld c, a + inc hl + ld a, c + cp MONS_PER_BOX + 1 + jr c, .scanSpeciesLoop + ld c, MONS_PER_BOX +.scanSpeciesLoop + ld a, c + and a + jr z, .notInBox + ld a, [hli] + cp -1 + jr z, .notInBox + ld b, a + ld a, [wEnemyMonSpecies] + cp b + jr z, .inBox + dec c + jr .scanSpeciesLoop +.inBox + call DisableSRAM + ld a, 1 + ret +.notInBox + call DisableSRAM + xor a + ret + +BattleBoxSRAMPointerTable: + dw sBox1 ; sBox7 + dw sBox2 ; sBox8 + dw sBox3 ; sBox9 + dw sBox4 ; sBox10 + dw sBox5 ; sBox11 + dw sBox6 ; sBox12 + ; asks if you want to use next mon ; stores whether you ran in C flag DoUseNextMonDialogue: diff --git a/engine/events/poison.asm b/engine/events/poison.asm index 9d87b3ca..f3c66345 100644 --- a/engine/events/poison.asm +++ b/engine/events/poison.asm @@ -68,7 +68,9 @@ ApplyOutOfBattlePoisonDamage: callfar PlayPikachuSoundClip callfar_ModifyPikachuHappiness PIKAHAPPY_PSNFNT .curMonNotPlayerPikachu - call HandlePoisonFaintedMonRanAway + ld a, [wWhichPokemon] + ld [wPlayerMonNumber], a + callfar HandleFaintedPlayerMonRanAway pop de pop hl jr .restartAfterRemoval @@ -148,34 +150,6 @@ ApplyOutOfBattlePoisonDamage: ld [wOutOfBattleBlackout], a ret -PoisonFaintedMonRanAwayText: - text_far _PokemonRanAwayBadTrainingText - text_end - -HandlePoisonFaintedMonRanAway: - ld a, [wPartyCount] - cp 1 - ret z ; don't remove the final party mon to avoid invalid 0-mon party state - ld hl, wPartyMonNicks - call GetPartyMonName - ld hl, PoisonFaintedMonRanAwayText - call PrintText - xor a - ld [wRemoveMonFromBox], a - call RemovePokemon - ld a, [wPartyCount] - and a - ret z - dec a - ld b, a - ld a, [wWhichPokemon] - cp b - jr c, .done - ld a, b - ld [wWhichPokemon], a -.done - ret - Func_c4c7: ld a, [wStepCounter] and a From 4c4824c99a26cb0f999d8178543a0394da464fd4 Mon Sep 17 00:00:00 2001 From: robjlyons <81177492+robjlyons@users.noreply.github.com> Date: Wed, 11 Feb 2026 12:27:26 +0000 Subject: [PATCH 04/12] Fix wild encounter crash from cross-bank SRAM calls --- engine/battle/core.asm | 137 ++++++++++++++++++++++++++++++++++++--- engine/events/poison.asm | 32 +-------- 2 files changed, 130 insertions(+), 39 deletions(-) diff --git a/engine/battle/core.asm b/engine/battle/core.asm index f13ed4b7..306117a6 100644 --- a/engine/battle/core.asm +++ b/engine/battle/core.asm @@ -170,6 +170,9 @@ StartBattle: ld a, c and a jr z, .skipWildCatchInit + call IsEnemyMonSpeciesInPlayerCollection + and a + jr nz, .skipWildCatchInit ld a, 1 ld [wWildEncounterCanCatch], a .skipWildCatchInit @@ -1194,18 +1197,132 @@ EnsureEncounterCatchFlagsInitialized: ret EnableEncounterCatchSRAM_Battle: - ld a, $0A - ld [$0000], a ; enable SRAM - ld a, $01 - ld [$6000], a ; MBC1: RAM banking mode (harmless on others) - ld a, BANK(sMapEncounterCatchFlags) - ld [$4000], a ; select SRAM bank that holds the flags - ret + ld a, BMODE_ADVANCED + ld [rBMODE], a + ld a, RAMG_SRAM_ENABLE + ld [rRAMG], a + ld a, BANK(sMapEncounterCatchFlags) + ld [rRAMB], a + ret DisableEncounterCatchSRAM_Battle: - xor a - ld [$0000], a ; disable SRAM - ret + ld a, BMODE_SIMPLE ; preserve flags + ld [rBMODE], a + ASSERT RAMG_SRAM_DISABLE == BMODE_SIMPLE + ld [rRAMG], a + ret + +; Returns non-zero if the current wild enemy species is in the player's party or PC boxes. +IsEnemyMonSpeciesInPlayerCollection: + call IsEnemyMonSpeciesInPlayerParty + and a + ret nz + call IsEnemyMonSpeciesInAnyPlayerPCBox + and a + ret + +; Returns non-zero if the current wild enemy species is already present in the player's party. +IsEnemyMonSpeciesInPlayerParty: + ld a, [wPartyCount] + ld c, a + ld hl, wPartySpecies +.loop + ld a, c + and a + jr z, .notInParty + ld a, [hli] + ld b, a + ld a, [wEnemyMonSpecies] + cp b + jr z, .inParty + dec c + jr .loop +.inParty + ld a, 1 + ret +.notInParty + xor a + ret + +; Returns non-zero if the current wild enemy species is present in any of the player's PC boxes. +IsEnemyMonSpeciesInAnyPlayerPCBox: + ld d, 0 +.boxLoop + ld a, d + cp NUM_BOXES + jr z, .notInPC + push de + call IsEnemyMonSpeciesInPlayerPCBox + pop de + and a + jr nz, .inPC + inc d + jr .boxLoop +.inPC + ld a, 1 + ret +.notInPC + xor a + ret + +; Checks one PC box. +; in: d = box index (0 to NUM_BOXES - 1) +; out: non-zero if the current wild enemy species exists in that box +IsEnemyMonSpeciesInPlayerPCBox: + ld a, d + cp NUM_BOXES / 2 + ld b, 2 + jr c, .haveBank + ld b, 3 + sub NUM_BOXES / 2 +.haveBank + ld e, a + ld d, 0 + ld hl, BattleBoxSRAMPointerTable + add hl, de + add hl, de + ld a, [hli] + ld h, [hl] + ld l, a + call EnableEncounterCatchSRAM_Battle + ld a, b + ld [rRAMB], a + ld a, [hl] + ld c, a + inc hl + ld a, c + cp MONS_PER_BOX + 1 + jr c, .scanSpeciesLoop + ld c, MONS_PER_BOX +.scanSpeciesLoop + ld a, c + and a + jr z, .notInBox + ld a, [hli] + cp -1 + jr z, .notInBox + ld b, a + ld a, [wEnemyMonSpecies] + cp b + jr z, .inBox + dec c + jr .scanSpeciesLoop +.inBox + call DisableEncounterCatchSRAM_Battle + ld a, 1 + ret +.notInBox + call DisableEncounterCatchSRAM_Battle + xor a + ret + +BattleBoxSRAMPointerTable: + dw sBox1 ; sBox7 + dw sBox2 ; sBox8 + dw sBox3 ; sBox9 + dw sBox4 ; sBox10 + dw sBox5 ; sBox11 + dw sBox6 ; sBox12 ; asks if you want to use next mon ; stores whether you ran in C flag diff --git a/engine/events/poison.asm b/engine/events/poison.asm index 9d87b3ca..f3c66345 100644 --- a/engine/events/poison.asm +++ b/engine/events/poison.asm @@ -68,7 +68,9 @@ ApplyOutOfBattlePoisonDamage: callfar PlayPikachuSoundClip callfar_ModifyPikachuHappiness PIKAHAPPY_PSNFNT .curMonNotPlayerPikachu - call HandlePoisonFaintedMonRanAway + ld a, [wWhichPokemon] + ld [wPlayerMonNumber], a + callfar HandleFaintedPlayerMonRanAway pop de pop hl jr .restartAfterRemoval @@ -148,34 +150,6 @@ ApplyOutOfBattlePoisonDamage: ld [wOutOfBattleBlackout], a ret -PoisonFaintedMonRanAwayText: - text_far _PokemonRanAwayBadTrainingText - text_end - -HandlePoisonFaintedMonRanAway: - ld a, [wPartyCount] - cp 1 - ret z ; don't remove the final party mon to avoid invalid 0-mon party state - ld hl, wPartyMonNicks - call GetPartyMonName - ld hl, PoisonFaintedMonRanAwayText - call PrintText - xor a - ld [wRemoveMonFromBox], a - call RemovePokemon - ld a, [wPartyCount] - and a - ret z - dec a - ld b, a - ld a, [wWhichPokemon] - cp b - jr c, .done - ld a, b - ld [wWhichPokemon], a -.done - ret - Func_c4c7: ld a, [wStepCounter] and a From 8560a58b73260507bc3f6ec0a9bc2684a3d201d8 Mon Sep 17 00:00:00 2001 From: robjlyons <81177492+robjlyons@users.noreply.github.com> Date: Wed, 11 Feb 2026 12:41:06 +0000 Subject: [PATCH 05/12] Update core.asm --- engine/battle/core.asm | 32 -------------------------------- 1 file changed, 32 deletions(-) diff --git a/engine/battle/core.asm b/engine/battle/core.asm index 74756bc1..135c2cd2 100644 --- a/engine/battle/core.asm +++ b/engine/battle/core.asm @@ -1324,38 +1324,6 @@ BattleBoxSRAMPointerTable: dw sBox5 ; sBox11 dw sBox6 ; sBox12 -; Returns non-zero if the current wild enemy species is in the player's party or PC boxes. -IsEnemyMonSpeciesInPlayerCollection: - call IsEnemyMonSpeciesInPlayerParty - and a - ret nz - call IsEnemyMonSpeciesInAnyPlayerPCBox - and a - ret - -; Returns non-zero if the current wild enemy species is already present in the player's party. -IsEnemyMonSpeciesInPlayerParty: - ld a, [wPartyCount] - ld c, a - ld hl, wPartySpecies -.loop - ld a, c - and a - jr z, .notInParty - ld a, [hli] - ld b, a - ld a, [wEnemyMonSpecies] - cp b - jr z, .inParty - dec c - jr .loop -.inParty - ld a, 1 - ret -.notInParty - xor a - ret - ; Returns non-zero if the current wild enemy species is present in any of the player's PC boxes. IsEnemyMonSpeciesInAnyPlayerPCBox: ld d, 0 From 7190a7e0c7e67f30bf0ec10417e14e1957927689 Mon Sep 17 00:00:00 2001 From: robjlyons <81177492+robjlyons@users.noreply.github.com> Date: Wed, 11 Feb 2026 12:43:30 +0000 Subject: [PATCH 06/12] Remove enemy species check from PC boxes Removed functions that check if the current wild enemy species is present in the player's PC boxes. --- engine/battle/core.asm | 74 ------------------------------------------ 1 file changed, 74 deletions(-) diff --git a/engine/battle/core.asm b/engine/battle/core.asm index 135c2cd2..306117a6 100644 --- a/engine/battle/core.asm +++ b/engine/battle/core.asm @@ -1324,80 +1324,6 @@ BattleBoxSRAMPointerTable: dw sBox5 ; sBox11 dw sBox6 ; sBox12 -; Returns non-zero if the current wild enemy species is present in any of the player's PC boxes. -IsEnemyMonSpeciesInAnyPlayerPCBox: - ld d, 0 -.boxLoop - ld a, d - cp NUM_BOXES - jr z, .notInPC - push de - call IsEnemyMonSpeciesInPlayerPCBox - pop de - and a - jr nz, .inPC - inc d - jr .boxLoop -.inPC - ld a, 1 - ret -.notInPC - xor a - ret - -; Checks one PC box. -; in: d = box index (0 to NUM_BOXES - 1) -; out: non-zero if the current wild enemy species exists in that box -IsEnemyMonSpeciesInPlayerPCBox: - ld a, d - cp NUM_BOXES / 2 - ld b, 2 - jr c, .haveBank - ld b, 3 - sub NUM_BOXES / 2 -.haveBank - ld e, a - ld d, 0 - ld hl, BattleBoxSRAMPointerTable - add hl, de - add hl, de - ld a, [hli] - ld h, [hl] - ld l, a - call EnableSRAM - ld a, b - ld [rRAMB], a - ld a, [hl] - ld c, a - inc hl -.scanSpeciesLoop - ld a, c - and a - jr z, .notInBox - ld a, [hli] - ld b, a - ld a, [wEnemyMonSpecies] - cp b - jr z, .inBox - dec c - jr .scanSpeciesLoop -.inBox - call DisableSRAM - ld a, 1 - ret -.notInBox - call DisableSRAM - xor a - ret - -BattleBoxSRAMPointerTable: - dw sBox1 ; sBox7 - dw sBox2 ; sBox8 - dw sBox3 ; sBox9 - dw sBox4 ; sBox10 - dw sBox5 ; sBox11 - dw sBox6 ; sBox12 - ; asks if you want to use next mon ; stores whether you ran in C flag DoUseNextMonDialogue: From 9742b7126ae229799778a1696f64074810730f65 Mon Sep 17 00:00:00 2001 From: robjlyons <81177492+robjlyons@users.noreply.github.com> Date: Wed, 11 Feb 2026 13:18:46 +0000 Subject: [PATCH 07/12] Use home SRAM API for battle PC box scanning --- engine/battle/core.asm | 129 ++++++++++++++++++++++++++++++++++++--- engine/events/poison.asm | 32 +--------- 2 files changed, 122 insertions(+), 39 deletions(-) diff --git a/engine/battle/core.asm b/engine/battle/core.asm index f13ed4b7..c9b1365e 100644 --- a/engine/battle/core.asm +++ b/engine/battle/core.asm @@ -170,6 +170,9 @@ StartBattle: ld a, c and a jr z, .skipWildCatchInit + call IsEnemyMonSpeciesInPlayerCollection + and a + jr nz, .skipWildCatchInit ld a, 1 ld [wWildEncounterCanCatch], a .skipWildCatchInit @@ -1194,18 +1197,124 @@ EnsureEncounterCatchFlagsInitialized: ret EnableEncounterCatchSRAM_Battle: - ld a, $0A - ld [$0000], a ; enable SRAM - ld a, $01 - ld [$6000], a ; MBC1: RAM banking mode (harmless on others) - ld a, BANK(sMapEncounterCatchFlags) - ld [$4000], a ; select SRAM bank that holds the flags - ret + ld a, BANK(sMapEncounterCatchFlags) + call OpenSRAM + ret DisableEncounterCatchSRAM_Battle: - xor a - ld [$0000], a ; disable SRAM - ret + call CloseSRAM + ret + +; Returns non-zero if the current wild enemy species is in the player's party or PC boxes. +IsEnemyMonSpeciesInPlayerCollection: + call IsEnemyMonSpeciesInPlayerParty + and a + ret nz + call IsEnemyMonSpeciesInAnyPlayerPCBox + and a + ret + +; Returns non-zero if the current wild enemy species is already present in the player's party. +IsEnemyMonSpeciesInPlayerParty: + ld a, [wPartyCount] + ld c, a + ld hl, wPartySpecies +.loop + ld a, c + and a + jr z, .notInParty + ld a, [hli] + ld b, a + ld a, [wEnemyMonSpecies] + cp b + jr z, .inParty + dec c + jr .loop +.inParty + ld a, 1 + ret +.notInParty + xor a + ret + +; Returns non-zero if the current wild enemy species is present in any of the player's PC boxes. +IsEnemyMonSpeciesInAnyPlayerPCBox: + ld d, 0 +.boxLoop + ld a, d + cp NUM_BOXES + jr z, .notInPC + push de + call IsEnemyMonSpeciesInPlayerPCBox + pop de + and a + jr nz, .inPC + inc d + jr .boxLoop +.inPC + ld a, 1 + ret +.notInPC + xor a + ret + +; Checks one PC box. +; in: d = box index (0 to NUM_BOXES - 1) +; out: non-zero if the current wild enemy species exists in that box +IsEnemyMonSpeciesInPlayerPCBox: + ld a, d + cp NUM_BOXES / 2 + ld b, 2 + jr c, .haveBank + ld b, 3 + sub NUM_BOXES / 2 +.haveBank + ld e, a + ld d, 0 + ld hl, BattleBoxSRAMPointerTable + add hl, de + add hl, de + ld a, [hli] + ld h, [hl] + ld l, a + ld a, b + call OpenSRAM + ld a, [hl] + ld c, a + inc hl + ld a, c + cp MONS_PER_BOX + 1 + jr c, .scanSpeciesLoop + ld c, MONS_PER_BOX +.scanSpeciesLoop + ld a, c + and a + jr z, .notInBox + ld a, [hli] + cp -1 + jr z, .notInBox + ld b, a + ld a, [wEnemyMonSpecies] + cp b + jr z, .inBox + dec c + jr .scanSpeciesLoop +.inBox + call CloseSRAM + ld a, 1 + ret +.notInBox + call CloseSRAM + xor a + ret + +BattleBoxSRAMPointerTable: + dw sBox1 ; sBox7 + dw sBox2 ; sBox8 + dw sBox3 ; sBox9 + dw sBox4 ; sBox10 + dw sBox5 ; sBox11 + dw sBox6 ; sBox12 ; asks if you want to use next mon ; stores whether you ran in C flag diff --git a/engine/events/poison.asm b/engine/events/poison.asm index 9d87b3ca..f3c66345 100644 --- a/engine/events/poison.asm +++ b/engine/events/poison.asm @@ -68,7 +68,9 @@ ApplyOutOfBattlePoisonDamage: callfar PlayPikachuSoundClip callfar_ModifyPikachuHappiness PIKAHAPPY_PSNFNT .curMonNotPlayerPikachu - call HandlePoisonFaintedMonRanAway + ld a, [wWhichPokemon] + ld [wPlayerMonNumber], a + callfar HandleFaintedPlayerMonRanAway pop de pop hl jr .restartAfterRemoval @@ -148,34 +150,6 @@ ApplyOutOfBattlePoisonDamage: ld [wOutOfBattleBlackout], a ret -PoisonFaintedMonRanAwayText: - text_far _PokemonRanAwayBadTrainingText - text_end - -HandlePoisonFaintedMonRanAway: - ld a, [wPartyCount] - cp 1 - ret z ; don't remove the final party mon to avoid invalid 0-mon party state - ld hl, wPartyMonNicks - call GetPartyMonName - ld hl, PoisonFaintedMonRanAwayText - call PrintText - xor a - ld [wRemoveMonFromBox], a - call RemovePokemon - ld a, [wPartyCount] - and a - ret z - dec a - ld b, a - ld a, [wWhichPokemon] - cp b - jr c, .done - ld a, b - ld [wWhichPokemon], a -.done - ret - Func_c4c7: ld a, [wStepCounter] and a From 50941f22115b6f9e1eed710e2252b72cde4711a0 Mon Sep 17 00:00:00 2001 From: robjlyons <81177492+robjlyons@users.noreply.github.com> Date: Wed, 11 Feb 2026 14:00:04 +0000 Subject: [PATCH 08/12] Update core.asm --- engine/battle/core.asm | 11 ++--------- 1 file changed, 2 insertions(+), 9 deletions(-) diff --git a/engine/battle/core.asm b/engine/battle/core.asm index 306117a6..592c5613 100644 --- a/engine/battle/core.asm +++ b/engine/battle/core.asm @@ -1197,19 +1197,12 @@ EnsureEncounterCatchFlagsInitialized: ret EnableEncounterCatchSRAM_Battle: - ld a, BMODE_ADVANCED - ld [rBMODE], a - ld a, RAMG_SRAM_ENABLE - ld [rRAMG], a ld a, BANK(sMapEncounterCatchFlags) - ld [rRAMB], a + call OpenSRAM ret DisableEncounterCatchSRAM_Battle: - ld a, BMODE_SIMPLE ; preserve flags - ld [rBMODE], a - ASSERT RAMG_SRAM_DISABLE == BMODE_SIMPLE - ld [rRAMG], a + call CloseSRAM ret ; Returns non-zero if the current wild enemy species is in the player's party or PC boxes. From 04be5b621c5c6e23212ba5350d6db1e32a85e974 Mon Sep 17 00:00:00 2001 From: robjlyons <81177492+robjlyons@users.noreply.github.com> Date: Wed, 11 Feb 2026 14:13:19 +0000 Subject: [PATCH 09/12] Update core.asm --- engine/battle/core.asm | 102 ++++++++++++++++++++++++----------------- 1 file changed, 60 insertions(+), 42 deletions(-) diff --git a/engine/battle/core.asm b/engine/battle/core.asm index 592c5613..b9c958bc 100644 --- a/engine/battle/core.asm +++ b/engine/battle/core.asm @@ -1262,52 +1262,70 @@ IsEnemyMonSpeciesInAnyPlayerPCBox: ; in: d = box index (0 to NUM_BOXES - 1) ; out: non-zero if the current wild enemy species exists in that box IsEnemyMonSpeciesInPlayerPCBox: - ld a, d - cp NUM_BOXES / 2 - ld b, 2 - jr c, .haveBank - ld b, 3 - sub NUM_BOXES / 2 + ; input: d = box index (0..NUM_BOXES-1) + ; output: a = 1 if found, 0 if not + ; clobbers: a,b,c,d,e,hl + + ld a, d + cp NUM_BOXES / 2 + ld b, 2 + jr c, .haveBank + ld b, 3 + sub NUM_BOXES / 2 .haveBank - ld e, a - ld d, 0 - ld hl, BattleBoxSRAMPointerTable - add hl, de - add hl, de - ld a, [hli] - ld h, [hl] - ld l, a - call EnableEncounterCatchSRAM_Battle - ld a, b - ld [rRAMB], a - ld a, [hl] - ld c, a - inc hl - ld a, c - cp MONS_PER_BOX + 1 - jr c, .scanSpeciesLoop - ld c, MONS_PER_BOX + ; a now = box index within this SRAM half (0..) + ld e, a + ld d, 0 + + ; hl = BattleBoxSRAMPointerTable[box] (word table) + ld hl, BattleBoxSRAMPointerTable + add hl, de + add hl, de + ld a, [hli] + ld h, [hl] + ld l, a + + ; --- open SRAM bank b safely --- + ld a, b + call OpenSRAM + + ; first byte is box count + ld a, [hl] + ld c, a + inc hl + + ; clamp count to MONS_PER_BOX + ld a, c + cp MONS_PER_BOX + 1 + jr c, .scanSpeciesLoop + ld c, MONS_PER_BOX + .scanSpeciesLoop - ld a, c - and a - jr z, .notInBox - ld a, [hli] - cp -1 - jr z, .notInBox - ld b, a - ld a, [wEnemyMonSpecies] - cp b - jr z, .inBox - dec c - jr .scanSpeciesLoop + ld a, c + and a + jr z, .notInBox + + ld a, [hli] + cp -1 + jr z, .notInBox + + ld b, a + ld a, [wEnemyMonSpecies] + cp b + jr z, .inBox + + dec c + jr .scanSpeciesLoop + .inBox - call DisableEncounterCatchSRAM_Battle - ld a, 1 - ret + call CloseSRAM + ld a, 1 + ret + .notInBox - call DisableEncounterCatchSRAM_Battle - xor a - ret + call CloseSRAM + xor a + ret BattleBoxSRAMPointerTable: dw sBox1 ; sBox7 From ee17b3a8cff7f253b906c00ff3bcd392ef1d8170 Mon Sep 17 00:00:00 2001 From: robjlyons <81177492+robjlyons@users.noreply.github.com> Date: Wed, 11 Feb 2026 14:29:51 +0000 Subject: [PATCH 10/12] Update core.asm --- engine/battle/core.asm | 32 +++++++++++++++----------------- 1 file changed, 15 insertions(+), 17 deletions(-) diff --git a/engine/battle/core.asm b/engine/battle/core.asm index b9c958bc..14a74af4 100644 --- a/engine/battle/core.asm +++ b/engine/battle/core.asm @@ -1197,13 +1197,13 @@ EnsureEncounterCatchFlagsInitialized: ret EnableEncounterCatchSRAM_Battle: - ld a, BANK(sMapEncounterCatchFlags) - call OpenSRAM - ret + ld a, BANK(sMapEncounterCatchFlags) ; should be 0 now + call OpenSRAM + ret DisableEncounterCatchSRAM_Battle: - call CloseSRAM - ret + call CloseSRAM + ret ; Returns non-zero if the current wild enemy species is in the player's party or PC boxes. IsEnemyMonSpeciesInPlayerCollection: @@ -1245,7 +1245,7 @@ IsEnemyMonSpeciesInAnyPlayerPCBox: cp NUM_BOXES jr z, .notInPC push de - call IsEnemyMonSpeciesInPlayerPCBox + call pop de and a jr nz, .inPC @@ -1262,9 +1262,8 @@ IsEnemyMonSpeciesInAnyPlayerPCBox: ; in: d = box index (0 to NUM_BOXES - 1) ; out: non-zero if the current wild enemy species exists in that box IsEnemyMonSpeciesInPlayerPCBox: - ; input: d = box index (0..NUM_BOXES-1) - ; output: a = 1 if found, 0 if not - ; clobbers: a,b,c,d,e,hl + ; in: d = box index (0..NUM_BOXES-1) + ; out: a = 1 if found, 0 if not ld a, d cp NUM_BOXES / 2 @@ -1273,11 +1272,10 @@ IsEnemyMonSpeciesInPlayerPCBox: ld b, 3 sub NUM_BOXES / 2 .haveBank - ; a now = box index within this SRAM half (0..) + ; a = index within half (0..5) ld e, a ld d, 0 - ; hl = BattleBoxSRAMPointerTable[box] (word table) ld hl, BattleBoxSRAMPointerTable add hl, de add hl, de @@ -1285,22 +1283,22 @@ IsEnemyMonSpeciesInPlayerPCBox: ld h, [hl] ld l, a - ; --- open SRAM bank b safely --- + ; --- Open SRAM bank b safely --- ld a, b call OpenSRAM - ; first byte is box count + ; box count ld a, [hl] ld c, a inc hl - ; clamp count to MONS_PER_BOX + ; clamp ld a, c cp MONS_PER_BOX + 1 - jr c, .scanSpeciesLoop + jr c, .scan ld c, MONS_PER_BOX -.scanSpeciesLoop +.scan ld a, c and a jr z, .notInBox @@ -1315,7 +1313,7 @@ IsEnemyMonSpeciesInPlayerPCBox: jr z, .inBox dec c - jr .scanSpeciesLoop + jr .scan .inBox call CloseSRAM From 4b6057472a89206390d9534372d375002e787963 Mon Sep 17 00:00:00 2001 From: robjlyons <81177492+robjlyons@users.noreply.github.com> Date: Wed, 11 Feb 2026 14:30:33 +0000 Subject: [PATCH 11/12] Update item_effects.asm --- engine/items/item_effects.asm | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/engine/items/item_effects.asm b/engine/items/item_effects.asm index 1f6b4d34..37cd2d76 100644 --- a/engine/items/item_effects.asm +++ b/engine/items/item_effects.asm @@ -2669,15 +2669,12 @@ MarkWildEncounterCatchUsedItem: ret EnableEncounterCatchSRAM_Item: - ld a, $0A - ld [$0000], a ; enable SRAM - xor a - ld [$4000], a ; SRAM bank 0 + ld a, BANK(sMapEncounterCatchFlags) ; should be 0 now + call OpenSRAM ret DisableEncounterCatchSRAM_Item: - xor a - ld [$0000], a ; disable SRAM + call CloseSRAM ret NoCyclingAllowedHereText: From 0275f2d56e028a89f4b6bdc540016780dc29d2f9 Mon Sep 17 00:00:00 2001 From: robjlyons <81177492+robjlyons@users.noreply.github.com> Date: Wed, 11 Feb 2026 14:32:51 +0000 Subject: [PATCH 12/12] Update core.asm --- engine/battle/core.asm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/engine/battle/core.asm b/engine/battle/core.asm index 14a74af4..b5af70ce 100644 --- a/engine/battle/core.asm +++ b/engine/battle/core.asm @@ -1245,7 +1245,7 @@ IsEnemyMonSpeciesInAnyPlayerPCBox: cp NUM_BOXES jr z, .notInPC push de - call + call IsEnemyMonSpeciesInPlayerPCBox pop de and a jr nz, .inPC