diff --git a/engine/battle/core.asm b/engine/battle/core.asm index 9f45c390..b5af70ce 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,14 +1197,142 @@ 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 + 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: + ; in: d = box index (0..NUM_BOXES-1) + ; out: a = 1 if found, 0 if not + + ld a, d + cp NUM_BOXES / 2 + ld b, 2 + jr c, .haveBank + ld b, 3 + sub NUM_BOXES / 2 +.haveBank + ; a = index within half (0..5) + ld e, a + ld d, 0 + + 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 + + ; box count + ld a, [hl] + ld c, a + inc hl + + ; clamp + ld a, c + cp MONS_PER_BOX + 1 + jr c, .scan + ld c, MONS_PER_BOX + +.scan + 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 .scan + +.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 DoUseNextMonDialogue: 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: