From 515f9391c94d28bce84ff5c6aee8a113f1d8c7d2 Mon Sep 17 00:00:00 2001 From: ElectroDeoxys Date: Thu, 5 Sep 2019 22:27:49 +0100 Subject: Label AI functions --- src/engine/bank05.asm | 97 +++++++++++++++++++++++++++++---------------------- 1 file changed, 55 insertions(+), 42 deletions(-) (limited to 'src/engine') diff --git a/src/engine/bank05.asm b/src/engine/bank05.asm index 7e8854f..42d818b 100644 --- a/src/engine/bank05.asm +++ b/src/engine/bank05.asm @@ -58,30 +58,31 @@ PointerTable_1406a: ; 1406a (5:406a) dw $406c dw Func_14078 dw Func_14078 - dw $409e + dw Func_1409e dw $40a2 dw $40a6 dw $40aa Func_14078: ; 14078 (5:4078) - call Func_15eae - call Func_158b2 + call AIDecidePlayPokemonCard + call AIDecideWhetherToRetreat jr nc, .asm_14091 - call Func_15b72 - call Func_15d4f - call Func_158b2 + call AIDecideBenchPokemonToSwitchTo + call AIChooseEnergyToDiscardForRetreatCost + call AIDecideWhetherToRetreat jr nc, .asm_14091 - call Func_15b72 - call Func_15d4f + call AIDecideBenchPokemonToSwitchTo + call AIChooseEnergyToDiscardForRetreatCost .asm_14091 - call Func_164e8 + call AIDecidePlayEnergyCard call Func_169f8 ret c - ld a, $05 + ld a, OPPACTION_FINISH_NO_ATTACK bank1call AIMakeDecision ret ; 0x1409e +Func_1409e: ; 1409e (5:409e) INCROM $1409e, $140ae ; returns carry if damage dealt from any of @@ -1257,10 +1258,12 @@ Func_1468b: ; 1468b (5:468b) Func_14786: ; 14786 (5:4786) INCROM $14786, $14c91 -; if the player has more than 3 prize cards -; check for certain card IDs in bench, -; as well as their HP and energy cards attached -Func_14c91: ; 14c91 (5:4c91) +; this routine handles how Legendary Articuno +; prioritises playing energy cards to each Pokémon. +; first, it makes sure that all Lapras have at least +; 3 energy cards before moving on to Articuno, +; and then to Dewgong and Seel +ScoreLegendaryArticunoCards: ; 14c91 (5:4c91) call SwapTurn call CountPrizes call SwapTurn @@ -1285,9 +1288,9 @@ Func_14c91: ; 14c91 (5:4c91) jr .articuno ; the following routines check for certain card IDs in bench -; and call Func_174cd if these are found +; and call RaiseAIScoreToAllMatchingIDsInBench if these are found. ; for Lapras, an additional check is made to its -; attached energy count, which skips Func_174cd +; attached energy count, which skips calling the routine ; if this count is >= 3 .lapras ld a, LAPRAS @@ -1299,7 +1302,7 @@ Func_14c91: ; 14c91 (5:4c91) cp 3 jr nc, .articuno ld a, LAPRAS - call Func_174cd + call RaiseAIScoreToAllMatchingIDsInBench ret .articuno @@ -1308,7 +1311,7 @@ Func_14c91: ; 14c91 (5:4c91) call LookForCardIDInBench jr nc, .dewgong ld a, ARTICUNO1 - call Func_174cd + call RaiseAIScoreToAllMatchingIDsInBench ret .dewgong @@ -1317,7 +1320,7 @@ Func_14c91: ; 14c91 (5:4c91) call LookForCardIDInBench jr nc, .seel ld a, DEWGONG - call Func_174cd + call RaiseAIScoreToAllMatchingIDsInBench ret .seel @@ -1326,7 +1329,7 @@ Func_14c91: ; 14c91 (5:4c91) call LookForCardIDInBench ret nc ld a, SEEL - call Func_174cd + call RaiseAIScoreToAllMatchingIDsInBench ret ; 0x14cf7 @@ -1594,7 +1597,8 @@ Func_157a3: ; 157a3 (5:57a3) INCROM $157a3, $158b2 ; determine AI score for retreating -Func_158b2: ; 158b2 (5:58b2) +; return carry if AI decides to retreat +AIDecideWhetherToRetreat: ; 158b2 (5:58b2) ld a, [wGotHeadsFromConfusionCheckDuringRetreat] or a jp nz, .no_carry @@ -2056,7 +2060,9 @@ Func_15b54: ; 15b54 (5:5b54) ; 0x15b72 ; calculates AI score for bench Pokémon -Func_15b72: ; 15b72 (5:5b72) +; returns in hTempPlayAreaLocation_ff9d the +; Play Area location of best card to switch to +AIDecideBenchPokemonToSwitchTo: ; 15b72 (5:5b72) xor a ldh [hTempPlayAreaLocation_ff9d], a ld a, DUELVARS_NUMBER_OF_POKEMON_IN_PLAY_AREA @@ -2359,7 +2365,7 @@ Func_15b72: ; 15b72 (5:5b72) ; handles AI action of retreating Arena Pokémon ; and chooses which energy cards to discard ; if card can't discard, return carry -Func_15d4f: ; 15d4f (5:5d4f) +AIChooseEnergyToDiscardForRetreatCost: ; 15d4f (5:5d4f) push af ld a, [wAIPlayEnergyCardForRetreat] or a @@ -2609,8 +2615,8 @@ CopyHandCardList: ; 15ea6 (5:5ea6) jr CopyHandCardList ; determine whether AI plays -; basic card from hand -Func_15eae: ; 15eae (5:5eae) +; basic cards from hand +AIDecidePlayPokemonCard: ; 15eae (5:5eae) call CreateHandCardList call SortTempHandByIDList ld hl, wDuelTempList @@ -2621,7 +2627,7 @@ Func_15eae: ; 15eae (5:5eae) .next_hand_card ld a, [hli] cp $ff - jp z, Func_15f4c + jp z, AIDecideEvolution ld [wTempAIPokemonCard], a push hl @@ -2711,7 +2717,7 @@ Func_15eae: ; 15eae (5:5eae) ; determine whether AI evolves ; Pokémon in the Play Area -Func_15f4c: ; 15f4c (5:5f4c) +AIDecideEvolution: ; 15f4c (5:5f4c) call CreateHandCardList ld hl, wDuelTempList ld de, wHandTempList @@ -3169,7 +3175,7 @@ Func_161d5: ; 161d5 (5:61d5) jr c, .subtract call CheckIfActivePokemonCanUseAnyNonResidualMove jr nc, .subtract - call Func_158b2 + call AIDecideWhetherToRetreat jr c, .subtract ; checks for player's active card status @@ -3756,7 +3762,7 @@ Func_164d3: ; 164d3 (5:64d3) ret ; 0x164e8 -Func_164e8: ; 164e8 (5:64e8) +AIDecidePlayEnergyCard: ; 164e8 (5:64e8) xor a ld [wcdd8], a call CreateEnergyCardListFromHand @@ -3782,7 +3788,8 @@ Func_164e8: ; 164e8 (5:64e8) dec b jr nz, .loop - call Func_175bd + call HandleLegendaryArticunoEnergyScoring + ld b, PLAY_AREA_ARENA ld a, DUELVARS_NUMBER_OF_POKEMON_IN_PLAY_AREA call GetTurnDuelistVariable @@ -3811,7 +3818,7 @@ Func_164e8: ; 164e8 (5:64e8) call GetMovesEnergyCostBits ld hl, wDuelTempList call CheckEnergyFlagsNeededInList - jp nc, .asm_16661 + jp nc, .store_score ld a, [wCurCardCanAttack] call CheckForEvolutionInList jr nc, .no_evolution_in_hand @@ -3950,16 +3957,17 @@ Func_164e8: ; 164e8 (5:64e8) jr c, .check_id_score ld a, 10 call SubFromAIScore - jr .asm_16661 + jr .store_score .check_id_score ld a, [hli] cp $80 - jr c, .asm_16622 + jr c, .decrease_score_1 sub $80 call AddToAIScore jr .check_boss_deck -.asm_16622 + +.decrease_score_1 ld d, a ld a, $80 sub d @@ -3985,15 +3993,17 @@ Func_164e8: ; 164e8 (5:64e8) add hl, bc ld a, [hl] cp $80 - jr c, .asm_1664c + jr c, .decrease_score_2 sub $80 call AddToAIScore jr .skip_boss_deck -.asm_1664c + +.decrease_score_2 ld b, a ld a, $80 sub b call SubFromAIScore + .skip_boss_deck ld a, 1 call AddToAIScore @@ -4003,7 +4013,7 @@ Func_164e8: ; 164e8 (5:64e8) ld a, $01 ; second move call Func_16695 -.asm_16661 +.store_score ldh a, [hTempPlayAreaLocation_ff9d] ld c, a ld b, $00 @@ -4015,13 +4025,16 @@ Func_164e8: ; 164e8 (5:64e8) inc b dec c jp nz, .loop_play_area + call Func_167b5 jp nc, Func_1668a + ld a, [wcdd8] or a jr z, .asm_16684 scf jp Func_164d3 + .asm_16684 call CreateEnergyCardListFromHand jp Func_1689f @@ -4720,7 +4733,7 @@ CheckForBenchIDAtHalfHPAndCanUseSecondMove: ; 17474 (5:7474) ; in bench that have same ID as register a ; input: ; a = card ID to look for -Func_174cd: ; 174cd (5:74cd) +RaiseAIScoreToAllMatchingIDsInBench: ; 174cd (5:74cd) ld d, a ld a, DUELVARS_BENCH call GetTurnDuelistVariable @@ -4922,15 +4935,15 @@ Func_175a8: ; 175a8 (5:75a8) ret ; 0x175bd -; handle Legendary Articuno deck -; card IDs in bench -Func_175bd: ; 175bd (5:75bd) +; handle how AI scores giving out Energy Cards +; when using Legendary Articuno deck +HandleLegendaryArticunoEnergyScoring: ; 175bd (5:75bd) ld a, [wOpponentDeckID] cp LEGENDARY_ARTICUNO_DECK_ID jr z, .articuno_deck ret .articuno_deck - call Func_14c91 + call ScoreLegendaryArticunoCards ret ; 0x175c9 -- cgit v1.2.3 From 280eade7c51c5b2405942bd666a7961ee14c8835 Mon Sep 17 00:00:00 2001 From: ElectroDeoxys Date: Sat, 7 Sep 2019 10:37:07 +0100 Subject: Disassemble Func_169f8 --- src/engine/bank05.asm | 559 +++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 556 insertions(+), 3 deletions(-) (limited to 'src/engine') diff --git a/src/engine/bank05.asm b/src/engine/bank05.asm index 42d818b..c0bb334 100644 --- a/src/engine/bank05.asm +++ b/src/engine/bank05.asm @@ -4213,10 +4213,563 @@ Func_167b5 ; 167b5 (5:67b5) INCROM $167b5, $1689f Func_1689f ; 1689f (5:689f) - INCROM $1689f, $169f8 + INCROM $1689f, $169e3 -Func_169f8 ; 169f8 (5:69f8) - INCROM $169f8, $170c9 +Func_169e3 ; 169e3 (5:69e3) + INCROM $169e3, $169f8 + +Func_169f8: ; 169f8 (5:69f8) + xor a + ld [wcdd9], a + ld a, [wce20] + and $01 + jr z, .asm_16a0b + ld a, [wcdd6] + ld [wSelectedMoveIndex], a + jr .asm_16a3e + +.asm_16a0b + ld a, [wcda7] + cp $80 + jp z, .asm_16a77 + xor a + call Func_16a86 + ld a, [wAIScore] + ld [wBenchAIScore], a + ld a, $01 + call Func_16a86 + ld c, $01 + ld a, [wBenchAIScore] + ld b, a + ld a, [wAIScore] + cp b + jr nc, .asm_16a30 + dec c + ld a, b +.asm_16a30 + cp $50 + jr c, .asm_16a77 + ld a, c + ld [wSelectedMoveIndex], a + or a + jr z, .asm_16a3e + call Func_17019 + +.asm_16a3e + ld a, [wcdd9] + or a + jr z, .asm_16a48 + scf + jp Func_169e3 +.asm_16a48 + ld a, $0e + call Func_14663 + xor a + ldh [hTempPlayAreaLocation_ff9d], a + ld a, [wSelectedMoveIndex] + call EstimateDamage_VersusDefendingCard + ld a, [wDamage] + or a + jr z, .asm_16a62 +.asm_16a5c + xor a + ld [$cdb4], a + jr .asm_16a6d +.asm_16a62 + ld a, $05 + call CheckLoadedMoveFlag + jr c, .asm_16a5c + ld hl, $cdb4 + inc [hl] +.asm_16a6d + ld a, $01 + ld [wcddb], a + call Func_14145 + scf + ret +.asm_16a77 + ld a, [wcdd9] + or a + jr z, .asm_16a80 + jp Func_169e3 +.asm_16a80 + ld hl, $cdb4 + inc [hl] + or a + ret +; 0x16a86 + +Func_16a86: ; 16a86 (5:6a86) + ld [wSelectedMoveIndex], a + ld a, $50 + ld [wAIScore], a + xor a + ldh [hTempPlayAreaLocation_ff9d], a + call CheckIfCardCanUseSelectedMove + jr nc, .asm_16a9d +.asm_16a96 + xor a + ld [wAIScore], a + jp .done + +.asm_16a9d + xor a + ld [wcdf0], a + ld a, DUELVARS_ARENA_CARD + call GetTurnDuelistVariable + call GetCardIDFromDeckIndex + ld a, e + ld [wTempTurnDuelistCardID], a + call SwapTurn + ld a, DUELVARS_ARENA_CARD + call GetTurnDuelistVariable + call GetCardIDFromDeckIndex + ld a, e + ld [wTempNonTurnDuelistCardID], a + bank1call HandleNoDamageOrEffectSubstatus + call SwapTurn + jr nc, .skip_no_damage_substatus + + ; player is under No Damage substatus + ld a, $01 + ld [wcdf0], a + ld a, [wSelectedMoveIndex] + call EstimateDamage_VersusDefendingCard + ld a, [wLoadedMoveCategory] + cp POKEMON_POWER + jr z, .asm_16a96 + and $80 + jr nz, .skip_no_damage_substatus + ld a, $05 + call CheckLoadedMoveFlag + jr nc, .asm_16a96 + +.skip_no_damage_substatus + ld a, [wSelectedMoveIndex] + call EstimateDamage_VersusDefendingCard + ld a, DUELVARS_ARENA_CARD_HP + call GetNonTurnDuelistVariable + ld hl, wDamage + sub [hl] + jr c, .can_ko + jr z, .can_ko + jr .check_damage +.can_ko + ld a, 20 + call AddToAIScore + +.check_damage + xor a + ld [wce02], a + ld a, [wDamage] + ld [wCurCardPlayAreaLocation], a + or a + jr z, .no_damage + call CalculateTensDigit + call AddToAIScore + jr .check_recoil +.no_damage + ld a, $01 + ld [wce02], a + call SubFromAIScore + ld a, [wAIMaxDamage] + or a + jr z, .asm_16b27 + ld a, $02 + call AddToAIScore + + xor a + ld [wce02], a +.asm_16b27 + ld a, $05 + call CheckLoadedMoveFlag + jr nc, .check_recoil + ld a, $02 + call AddToAIScore + +.check_recoil + ld a, $04 ; LOW_RECOIL + call CheckLoadedMoveFlag + jr c, .asm_16b42 + ld a, $06 ; HIGH_RECOIL + call CheckLoadedMoveFlag + jp nc, .check_defending_can_ko +.asm_16b42 + ld a, [wLoadedMoveUnknown1] + or a + jp z, .check_defending_can_ko + ld [wDamage], a + call ApplyDamageModifiers_DamageToSelf + ld a, e + call CalculateTensDigit + call SubFromAIScore + + push de + ld a, $06 + call CheckLoadedMoveFlag + pop de + jr c, .high_recoil + + ; check if LOW_RECOIL KOs self + ld a, DUELVARS_ARENA_CARD_HP + call GetTurnDuelistVariable + cp e + jr c, .kos_self + jp nz, .check_defending_can_ko +.kos_self + ld a, $0a + call SubFromAIScore + +.high_recoil + ; dismiss this move if no benched Pokémon + ld a, DUELVARS_NUMBER_OF_POKEMON_IN_PLAY_AREA + call GetTurnDuelistVariable + cp 2 + jr c, .dismiss_high_recoil_move + ; has benched Pokémon + ld a, [wOpponentDeckID] + cp ROCK_CRUSHER_DECK_ID + jr z, .rock_crusher_deck + cp ZAPPING_SELFDESTRUCT_DECK_ID + jr z, .zapping_selfdestruct_deck + cp BOOM_BOOM_SELFDESTRUCT_DECK_ID + jr z, .encourage_high_recoil_move + cp POWER_GENERATOR_DECK_ID + jr nz, .asm_16be0 + +.dismiss_high_recoil_move + xor a + ld [wAIScore], a + jp .done + +.encourage_high_recoil_move + ld a, $14 + call AddToAIScore + jp .done + +.zapping_selfdestruct_deck + ld a, DUELVARS_NUMBER_OF_CARDS_NOT_IN_DECK + call GetTurnDuelistVariable + cp 31 + jr nc, .asm_16be0 + ld e, PLAY_AREA_ARENA + call GetCardDamage + sla a + cp c + jr c, .asm_16be0 + + ld b, 0 + ld a, DUELVARS_ARENA_CARD + call GetTurnDuelistVariable + call GetCardIDFromDeckIndex + ld a, e + cp MAGNEMITE1 + jr z, .magnemite1 + ld b, 10 +.magnemite1 + ld a, 10 + add b + ld b, a + ld a, $01 + call .asm_16c35 + jr c, .dismiss_high_recoil_move + jr .encourage_high_recoil_move + +.rock_crusher_deck + call CountPrizes + cp 4 + jr nc, .dismiss_high_recoil_move + ; prize count < 4 + ld b, $14 + call SwapTurn + xor a + call .asm_16c35 + call SwapTurn + jr c, .encourage_high_recoil_move + +.asm_16be0 + ld a, DUELVARS_ARENA_CARD + call GetTurnDuelistVariable + call GetCardIDFromDeckIndex + ld a, e + cp CHANSEY + jr z, .asm_16bfd + cp MAGNEMITE1 + jr z, .asm_16bf9 + cp WEEZING + jr z, .asm_16bf9 + + ld b, 20 + jr .asm_16bff +.asm_16bf9 + ld b, 10 + jr .asm_16bff +.asm_16bfd + ld b, 0 +.asm_16bff + push bc + call SwapTurn + xor a + call .asm_16c35 + call SwapTurn + pop bc + jr c, .asm_16c1d + push de + ld a, $01 + call .asm_16c35 + pop bc + jr nc, .asm_16c25 + + xor a + ld [wAIScore], a + jp .done +.asm_16c1d + ld a, 20 + call AddToAIScore + jp .done + +.asm_16c25 + push bc + ld a, d + or a + jr z, .asm_16c2e + dec a + call SubFromAIScore + +.asm_16c2e + pop bc + ld a, b + call AddToAIScore + jr .check_defending_can_ko + +.asm_16c35 + ld d, a + ld a, DUELVARS_BENCH + call GetTurnDuelistVariable + ld e, PLAY_AREA_ARENA +.loop + inc e + ld a, [hli] + cp $ff + jr z, .asm_16c53 + ld a, e + add DUELVARS_ARENA_CARD_HP + push hl + call GetTurnDuelistVariable + pop hl + cp b + jr z, .asm_16c50 + jr nc, .loop +.asm_16c50 + inc d + jr .loop +.asm_16c53 + push de + call SwapTurn + call CountPrizes + call SwapTurn + pop de + cp d + jp c, .asm_16c67 + jp z, .asm_16c67 + or a + ret +.asm_16c67 + scf + ret + +.check_defending_can_ko + ld a, [wSelectedMoveIndex] + push af + call CheckIfDefendingPokemonCanKnockOut + pop bc + ld a, b + ld [wSelectedMoveIndex], a + jr nc, .check_discard + ld a, 5 + call AddToAIScore + ld a, [wce02] + or a + jr z, .check_discard + ld a, 5 + call SubFromAIScore + +.check_discard + ld a, [wSelectedMoveIndex] + ld e, a + ld a, DUELVARS_ARENA_CARD + call GetTurnDuelistVariable + ld d, a + call CopyMoveDataAndDamage_FromDeckIndex + ld a, $0b ; DISCARD_ENERGY + call CheckLoadedMoveFlag + jr nc, .asm_16ca6 + ld a, 1 + call SubFromAIScore + ld a, [wLoadedMoveUnknown1] + call SubFromAIScore + +.asm_16ca6 + ld a, $0e ; FLAG_2_BIT_6 + call CheckLoadedMoveFlag + jr nc, .asm_16cb3 + ld a, [wLoadedMoveUnknown1] + call AddToAIScore + +.asm_16cb3 + ld a, $0a ; NULLIFY_OR_WEAKEN_ATTACK + call CheckLoadedMoveFlag + jr nc, .asm_16cbf + ld a, 1 + call AddToAIScore + +.asm_16cbf + ld a, $07 ; DRAW_CARD + call CheckLoadedMoveFlag + jr nc, .asm_16ccb + ld a, $01 + call AddToAIScore + +.asm_16ccb + ld a, $09 ; HEAL_USER + call CheckLoadedMoveFlag + jr nc, .asm_16d09 + ld a, [wLoadedMoveUnknown1] + cp $01 + jr z, .asm_16cf8 + ld a, [wCurCardPlayAreaLocation] + call CalculateTensDigit + ld b, a + ld a, [wLoadedMoveUnknown1] + cp $03 + jr z, .asm_16cec + srl b + jr nc, .asm_16cec + inc b +.asm_16cec + ld a, DUELVARS_ARENA_CARD_HP + call GetTurnDuelistVariable + call CalculateTensDigit + cp b + jr c, .asm_16cf8 + ld a, b +.asm_16cf8 + push af + ld e, $00 + call GetCardDamage + call CalculateTensDigit + pop bc + cp b + jr c, .asm_16d06 + ld a, b +.asm_16d06 + call AddToAIScore + +.asm_16d09 + ld a, DUELVARS_ARENA_CARD + call GetNonTurnDuelistVariable + call SwapTurn + call GetCardIDFromDeckIndex + call SwapTurn + ld a, e + cp SNORLAX + jp z, .asm_16db0 + ld a, DUELVARS_ARENA_CARD_STATUS + call GetNonTurnDuelistVariable + ld [wCurCardPlayAreaLocation], a + ld a, $00 + call CheckLoadedMoveFlag + jr nc, .asm_16d4a + ld a, [wCurCardPlayAreaLocation] + and $c0 + jr z, .asm_16d45 + and $40 + jr z, .asm_16d4a + ld a, $0e + call CheckLoadedMoveFlag + jr nc, .asm_16d4a + ld a, $02 + call SubFromAIScore + jr .asm_16d4a +.asm_16d45 + ld a, $02 + call AddToAIScore +.asm_16d4a + ld a, $01 + call CheckLoadedMoveFlag + jr nc, .asm_16d5f + ld a, [wCurCardPlayAreaLocation] + and $0f + cp $02 + jr z, .asm_16d5f + ld a, $01 + call AddToAIScore +.asm_16d5f + ld a, $02 + call CheckLoadedMoveFlag + jr nc, .asm_16d7b + ld a, [wCurCardPlayAreaLocation] + and $0f + cp $02 + jr z, .asm_16d76 + ld a, $01 + call AddToAIScore + jr .asm_16d7b +.asm_16d76 + ld a, $01 + call SubFromAIScore +.asm_16d7b + ld a, $03 + call CheckLoadedMoveFlag + jr nc, .asm_16da0 + ld a, [wCurCardPlayAreaLocation] + and $0f + cp $02 + jr z, .asm_16d9b + ld a, [wCurCardPlayAreaLocation] + and $0f + cp $01 + jr z, .asm_16da0 + ld a, $01 + call AddToAIScore + jr .asm_16da0 +.asm_16d9b + ld a, $01 + call SubFromAIScore +.asm_16da0 + ld a, $f0 + call GetTurnDuelistVariable + and $0f + cp $01 + jr nz, .asm_16db0 + ld a, $01 + call SubFromAIScore + +.asm_16db0 + ld a, $11 ; FLAG_3_BIT_1 + call CheckLoadedMoveFlag + jr nc, .done + call Func_16dcd + cp $80 + jr c, .asm_16dc5 + sub $80 + call AddToAIScore + jr .done + +.asm_16dc5 + ld b, a + ld a, $80 + sub b + call SubFromAIScore +.done + ret +; 0x16dcd + +Func_16dcd ; 16dcd (5:6dcd) + INCROM $16dcd, $17019 + +Func_17019 ; 17019 (5:7019) + INCROM $17019, $170c9 ; returns carry if the following conditions are met: ; - arena card HP >= half max HP -- cgit v1.2.3 From cb34b3c97e0978223bfb940092080e4baf204f0e Mon Sep 17 00:00:00 2001 From: ElectroDeoxys Date: Sun, 8 Sep 2019 21:08:59 +0100 Subject: Rename CheckIfSelectedMoveIsUnusable --- src/engine/bank05.asm | 93 ++++++++++++++++++++++++++------------------------- 1 file changed, 47 insertions(+), 46 deletions(-) (limited to 'src/engine') diff --git a/src/engine/bank05.asm b/src/engine/bank05.asm index c0bb334..357d01f 100644 --- a/src/engine/bank05.asm +++ b/src/engine/bank05.asm @@ -305,7 +305,7 @@ Func_14226: ; 14226 (5:4226) ; input: ; [hTempPlayAreaLocation_ff9d] = location of Pokémon card ; [wSelectedMoveIndex] = selected move to examine -CheckIfCardCanUseSelectedMove: ; 1424b (5:424b) +CheckIfSelectedMoveIsUnusable: ; 1424b (5:424b) ldh a, [hTempPlayAreaLocation_ff9d] or a jr nz, .bench @@ -330,7 +330,7 @@ CheckIfCardCanUseSelectedMove: ; 1424b (5:424b) .bench call CheckEnergyNeededForAttack ret c ; can't be used - ld a, $0d ; $00001101 + ld a, MOVE_FLAG2_ADDRESS | FLAG_2_BIT_5 call CheckLoadedMoveFlag ret ; 0x14279 @@ -1637,7 +1637,7 @@ AIDecideWhetherToRetreat: ; 158b2 (5:58b2) ldh [hTempPlayAreaLocation_ff9d], a call CheckIfAnyMoveKnocksOutDefendingCard jr nc, .active_cant_ko_1 - call CheckIfCardCanUseSelectedMove + call CheckIfSelectedMoveIsUnusable jp nc, .active_cant_use_move call LookForEnergyNeededForMoveInHand jr nc, .active_cant_ko_1 @@ -1838,7 +1838,7 @@ AIDecideWhetherToRetreat: ; 158b2 (5:58b2) push bc call CheckIfAnyMoveKnocksOutDefendingCard jr nc, .no_ko - call CheckIfCardCanUseSelectedMove + call CheckIfSelectedMoveIsUnusable jr nc, .success call LookForEnergyNeededForMoveInHand jr c, .success @@ -1867,7 +1867,7 @@ AIDecideWhetherToRetreat: ; 158b2 (5:58b2) ldh [hTempPlayAreaLocation_ff9d], a call CheckIfAnyMoveKnocksOutDefendingCard jr nc, .active_cant_ko_2 - call CheckIfCardCanUseSelectedMove + call CheckIfSelectedMoveIsUnusable jp nc, .check_defending_id .active_cant_ko_2 ld a, 40 @@ -2094,7 +2094,7 @@ AIDecideBenchPokemonToSwitchTo: ; 15b72 (5:5b72) ; if on last prize card, raise AI score again call CheckIfAnyMoveKnocksOutDefendingCard jr nc, .check_can_use_moves - call CheckIfCardCanUseSelectedMove + call CheckIfSelectedMoveIsUnusable jr c, .check_can_use_moves ld a, 10 call AddToAIScore @@ -2112,11 +2112,11 @@ AIDecideBenchPokemonToSwitchTo: ; 15b72 (5:5b72) .check_can_use_moves xor a ld [wSelectedMoveIndex], a - call CheckIfCardCanUseSelectedMove + call CheckIfSelectedMoveIsUnusable call nc, .calculate_damage ld a, $01 ld [wSelectedMoveIndex], a - call CheckIfCardCanUseSelectedMove + call CheckIfSelectedMoveIsUnusable call nc, .calculate_damage jr .check_energy_card @@ -2777,18 +2777,18 @@ AIDecideEvolution: ; 15f4c (5:5f4c) ; and if any of those moves can KO xor a ld [wSelectedMoveIndex], a - call CheckIfCardCanUseSelectedMove + call CheckIfSelectedMoveIsUnusable jr nc, .can_attack ld a, $01 ld [wSelectedMoveIndex], a - call CheckIfCardCanUseSelectedMove + call CheckIfSelectedMoveIsUnusable jr c, .cant_attack_or_ko .can_attack ld a, $01 ld [wCurCardCanAttack], a call CheckIfAnyMoveKnocksOutDefendingCard jr nc, .check_evolution_attacks - call CheckIfCardCanUseSelectedMove + call CheckIfSelectedMoveIsUnusable jr c, .check_evolution_attacks ld a, $01 ld [wCurCardCanKO], a @@ -2811,11 +2811,11 @@ AIDecideEvolution: ; 15f4c (5:5f4c) ld [hl], a xor a ld [wSelectedMoveIndex], a - call CheckIfCardCanUseSelectedMove + call CheckIfSelectedMoveIsUnusable jr nc, .evolution_can_attack ld a, $01 ld [wSelectedMoveIndex], a - call CheckIfCardCanUseSelectedMove + call CheckIfSelectedMoveIsUnusable jr c, .evolution_cant_attack .evolution_can_attack ld a, 5 @@ -2847,7 +2847,7 @@ AIDecideEvolution: ; 15f4c (5:5f4c) jr nz, .check_defending_can_ko_evolution call CheckIfAnyMoveKnocksOutDefendingCard jr nc, .evolution_cant_ko - call CheckIfCardCanUseSelectedMove + call CheckIfSelectedMoveIsUnusable jr c, .evolution_cant_ko ld a, 5 call AddToAIScore @@ -3278,7 +3278,7 @@ CheckIfActiveCardCanKnockOut: ; 1628f (5:628f) ldh [hTempPlayAreaLocation_ff9d], a call CheckIfAnyMoveKnocksOutDefendingCard jr nc, .fail - call CheckIfCardCanUseSelectedMove + call CheckIfSelectedMoveIsUnusable jp c, .fail scf ret @@ -3295,7 +3295,7 @@ CheckIfActivePokemonCanUseAnyNonResidualMove: ; 162a1 (5:62a1) ldh [hTempPlayAreaLocation_ff9d], a ; first move ld [wSelectedMoveIndex], a - call CheckIfCardCanUseSelectedMove + call CheckIfSelectedMoveIsUnusable jr c, .next_move ld a, [wLoadedMoveCategory] and RESIDUAL @@ -3305,7 +3305,7 @@ CheckIfActivePokemonCanUseAnyNonResidualMove: ; 162a1 (5:62a1) ; second move ld a, $01 ld [wSelectedMoveIndex], a - call CheckIfCardCanUseSelectedMove + call CheckIfSelectedMoveIsUnusable jr c, .fail ld a, [wLoadedMoveCategory] and RESIDUAL @@ -4047,10 +4047,10 @@ Func_16695: ; 16695 (5:6695) ld [wSelectedMoveIndex], a call CheckEnergyNeededForAttack jp c, .asm_1671e - ld a, $0c ; ATTACHED_ENERGY_BOOST + ld a, MOVE_FLAG2_ADDRESS | ATTACHED_ENERGY_BOOST call CheckLoadedMoveFlag jr c, .asm_166af - ld a, $0b ; FLAG_2_BIT_5 + ld a, MOVE_FLAG2_ADDRESS | DISCARD_ENERGY call CheckLoadedMoveFlag jr c, .asm_16710 jp .check_evolution @@ -4078,7 +4078,7 @@ Func_16695: ; 16695 (5:6695) ; check whether move has ATTACHED_ENERGY_BOOST flag ; and add to AI score if attaching another energy ; will KO defending Pokémon - ld a, $0c + ld a, MOVE_FLAG2_ADDRESS | ATTACHED_ENERGY_BOOST call CheckLoadedMoveFlag jp nc, .check_evolution ld a, [wSelectedMoveIndex] @@ -4118,7 +4118,7 @@ Func_16695: ; 16695 (5:6695) jr .asm_166c5 .asm_1671e - ld a, $0d ; FLAG_2_BIT_5 + ld a, MOVE_FLAG2_ADDRESS | FLAG_2_BIT_5 call CheckLoadedMoveFlag jr nc, .asm_1672a ld a, 5 @@ -4181,7 +4181,7 @@ Func_16695: ; 16695 (5:6695) ld [hl], b call CheckEnergyNeededForAttack jr nc, .done - ld a, $0d ; FLAG_2_BIT_5 + ld a, MOVE_FLAG2_ADDRESS | FLAG_2_BIT_5 call CheckLoadedMoveFlag jr c, .done ld a, b @@ -4276,7 +4276,7 @@ Func_169f8: ; 169f8 (5:69f8) ld [$cdb4], a jr .asm_16a6d .asm_16a62 - ld a, $05 + ld a, MOVE_FLAG1_ADDRESS | DAMAGE_TO_OPPONENT_BENCH call CheckLoadedMoveFlag jr c, .asm_16a5c ld hl, $cdb4 @@ -4305,8 +4305,9 @@ Func_16a86: ; 16a86 (5:6a86) ld [wAIScore], a xor a ldh [hTempPlayAreaLocation_ff9d], a - call CheckIfCardCanUseSelectedMove + call CheckIfSelectedMoveIsUnusable jr nc, .asm_16a9d + .asm_16a96 xor a ld [wAIScore], a @@ -4340,7 +4341,7 @@ Func_16a86: ; 16a86 (5:6a86) jr z, .asm_16a96 and $80 jr nz, .skip_no_damage_substatus - ld a, $05 + ld a, MOVE_FLAG1_ADDRESS | DAMAGE_TO_OPPONENT_BENCH call CheckLoadedMoveFlag jr nc, .asm_16a96 @@ -4381,17 +4382,17 @@ Func_16a86: ; 16a86 (5:6a86) xor a ld [wce02], a .asm_16b27 - ld a, $05 + ld a, MOVE_FLAG1_ADDRESS | DAMAGE_TO_OPPONENT_BENCH call CheckLoadedMoveFlag jr nc, .check_recoil ld a, $02 call AddToAIScore .check_recoil - ld a, $04 ; LOW_RECOIL + ld a, MOVE_FLAG1_ADDRESS | LOW_RECOIL call CheckLoadedMoveFlag jr c, .asm_16b42 - ld a, $06 ; HIGH_RECOIL + ld a, MOVE_FLAG1_ADDRESS | HIGH_RECOIL call CheckLoadedMoveFlag jp nc, .check_defending_can_ko .asm_16b42 @@ -4405,7 +4406,7 @@ Func_16a86: ; 16a86 (5:6a86) call SubFromAIScore push de - ld a, $06 + ld a, MOVE_FLAG1_ADDRESS | HIGH_RECOIL call CheckLoadedMoveFlag pop de jr c, .high_recoil @@ -4601,7 +4602,7 @@ Func_16a86: ; 16a86 (5:6a86) call GetTurnDuelistVariable ld d, a call CopyMoveDataAndDamage_FromDeckIndex - ld a, $0b ; DISCARD_ENERGY + ld a, MOVE_FLAG2_ADDRESS | DISCARD_ENERGY call CheckLoadedMoveFlag jr nc, .asm_16ca6 ld a, 1 @@ -4610,28 +4611,28 @@ Func_16a86: ; 16a86 (5:6a86) call SubFromAIScore .asm_16ca6 - ld a, $0e ; FLAG_2_BIT_6 + ld a, MOVE_FLAG2_ADDRESS | FLAG_2_BIT_6 call CheckLoadedMoveFlag jr nc, .asm_16cb3 ld a, [wLoadedMoveUnknown1] call AddToAIScore .asm_16cb3 - ld a, $0a ; NULLIFY_OR_WEAKEN_ATTACK + ld a, MOVE_FLAG2_ADDRESS | NULLIFY_OR_WEAKEN_ATTACK call CheckLoadedMoveFlag jr nc, .asm_16cbf ld a, 1 call AddToAIScore .asm_16cbf - ld a, $07 ; DRAW_CARD + ld a, MOVE_FLAG1_ADDRESS | DRAW_CARD call CheckLoadedMoveFlag jr nc, .asm_16ccb ld a, $01 call AddToAIScore .asm_16ccb - ld a, $09 ; HEAL_USER + ld a, MOVE_FLAG2_ADDRESS | HEAL_USER call CheckLoadedMoveFlag jr nc, .asm_16d09 ld a, [wLoadedMoveUnknown1] @@ -4677,7 +4678,7 @@ Func_16a86: ; 16a86 (5:6a86) ld a, DUELVARS_ARENA_CARD_STATUS call GetNonTurnDuelistVariable ld [wCurCardPlayAreaLocation], a - ld a, $00 + ld a, MOVE_FLAG1_ADDRESS | INFLICT_POISON call CheckLoadedMoveFlag jr nc, .asm_16d4a ld a, [wCurCardPlayAreaLocation] @@ -4685,7 +4686,7 @@ Func_16a86: ; 16a86 (5:6a86) jr z, .asm_16d45 and $40 jr z, .asm_16d4a - ld a, $0e + ld a, MOVE_FLAG2_ADDRESS | FLAG_2_BIT_6 call CheckLoadedMoveFlag jr nc, .asm_16d4a ld a, $02 @@ -4695,7 +4696,7 @@ Func_16a86: ; 16a86 (5:6a86) ld a, $02 call AddToAIScore .asm_16d4a - ld a, $01 + ld a, MOVE_FLAG1_ADDRESS | INFLICT_SLEEP call CheckLoadedMoveFlag jr nc, .asm_16d5f ld a, [wCurCardPlayAreaLocation] @@ -4705,7 +4706,7 @@ Func_16a86: ; 16a86 (5:6a86) ld a, $01 call AddToAIScore .asm_16d5f - ld a, $02 + ld a, MOVE_FLAG1_ADDRESS | INFLICT_PARALYSIS call CheckLoadedMoveFlag jr nc, .asm_16d7b ld a, [wCurCardPlayAreaLocation] @@ -4719,7 +4720,7 @@ Func_16a86: ; 16a86 (5:6a86) ld a, $01 call SubFromAIScore .asm_16d7b - ld a, $03 + ld a, MOVE_FLAG1_ADDRESS | INFLICT_CONFUSION call CheckLoadedMoveFlag jr nc, .asm_16da0 ld a, [wCurCardPlayAreaLocation] @@ -4746,7 +4747,7 @@ Func_16a86: ; 16a86 (5:6a86) call SubFromAIScore .asm_16db0 - ld a, $11 ; FLAG_3_BIT_1 + ld a, MOVE_FLAG3_ADDRESS | FLAG_3_BIT_1 call CheckLoadedMoveFlag jr nc, .done call Func_16dcd @@ -4804,7 +4805,7 @@ CheckIfArenaCardIsAtHalfHPCanEvolveAndUseSecondMove: ; 170c9 (5:70c9) ld a, $01 ; second move ld [wSelectedMoveIndex], a push hl - call CheckIfCardCanUseSelectedMove + call CheckIfSelectedMoveIsUnusable pop hl jr c, .no_carry scf @@ -4872,7 +4873,7 @@ CheckIfBenchCardsAreAtHalfHPCanEvolveAndUseSecondMove: ; 17101 (5:7101) ld [wSelectedMoveIndex], a push bc push hl - call CheckIfCardCanUseSelectedMove + call CheckIfSelectedMoveIsUnusable pop hl pop bc jr c, .next @@ -5060,7 +5061,7 @@ CheckIfCanDamageDefendingPokemon: ; 17383 (5:7383) ldh [hTempPlayAreaLocation_ff9d], a xor a ; first move ld [wSelectedMoveIndex], a - call CheckIfCardCanUseSelectedMove + call CheckIfSelectedMoveIsUnusable jr c, .second_move xor a call EstimateDamage_VersusDefendingCard @@ -5071,7 +5072,7 @@ CheckIfCanDamageDefendingPokemon: ; 17383 (5:7383) .second_move ld a, $01 ; second move ld [wSelectedMoveIndex], a - call CheckIfCardCanUseSelectedMove + call CheckIfSelectedMoveIsUnusable jr c, .no_carry ld a, $01 call EstimateDamage_VersusDefendingCard @@ -5143,7 +5144,7 @@ CheckIfDefendingPokemonCanKnockOutWithMove: ; 173e4 (5:73e4) xor a ldh [hTempPlayAreaLocation_ff9d], a call SwapTurn - call CheckIfCardCanUseSelectedMove + call CheckIfSelectedMoveIsUnusable call SwapTurn pop bc ld a, b @@ -5264,7 +5265,7 @@ CheckForBenchIDAtHalfHPAndCanUseSecondMove: ; 17474 (5:7474) ld a, $01 ; second move ld [wSelectedMoveIndex], a push bc - call CheckIfCardCanUseSelectedMove + call CheckIfSelectedMoveIsUnusable pop bc jr c, .loop inc b -- cgit v1.2.3 From 0a82721428624d80ef4eb0f8c67e3f8cabbcfd66 Mon Sep 17 00:00:00 2001 From: ElectroDeoxys Date: Mon, 9 Sep 2019 21:35:06 +0100 Subject: Label Func_16a86 --- src/engine/bank05.asm | 228 ++++++++++++++++++++++++++++++++------------------ 1 file changed, 146 insertions(+), 82 deletions(-) (limited to 'src/engine') diff --git a/src/engine/bank05.asm b/src/engine/bank05.asm index 357d01f..c7d2c13 100644 --- a/src/engine/bank05.asm +++ b/src/engine/bank05.asm @@ -4306,14 +4306,15 @@ Func_16a86: ; 16a86 (5:6a86) xor a ldh [hTempPlayAreaLocation_ff9d], a call CheckIfSelectedMoveIsUnusable - jr nc, .asm_16a9d + jr nc, .usable -.asm_16a96 +.unusable xor a ld [wAIScore], a jp .done -.asm_16a9d +; load arena card IDs +.usable xor a ld [wcdf0], a ld a, DUELVARS_ARENA_CARD @@ -4327,9 +4328,15 @@ Func_16a86: ; 16a86 (5:6a86) call GetCardIDFromDeckIndex ld a, e ld [wTempNonTurnDuelistCardID], a + +; handle the case where the player has No Damage substatus. +; in the case the player does, check if this move is +; has a residual effect, or if it can damage the opposing bench. +; If none of those are true, render the move unusable. +; also if it's a PKMN power, consider it unusable as well. bank1call HandleNoDamageOrEffectSubstatus call SwapTurn - jr nc, .skip_no_damage_substatus + jr nc, .check_if_can_ko ; player is under No Damage substatus ld a, $01 @@ -4338,14 +4345,16 @@ Func_16a86: ; 16a86 (5:6a86) call EstimateDamage_VersusDefendingCard ld a, [wLoadedMoveCategory] cp POKEMON_POWER - jr z, .asm_16a96 - and $80 - jr nz, .skip_no_damage_substatus + jr z, .unusable + and RESIDUAL + jr nz, .check_if_can_ko ld a, MOVE_FLAG1_ADDRESS | DAMAGE_TO_OPPONENT_BENCH call CheckLoadedMoveFlag - jr nc, .asm_16a96 + jr nc, .unusable -.skip_no_damage_substatus +; calculate damage to player to check if move can KO. +; encourage move if it's able to KO. +.check_if_can_ko ld a, [wSelectedMoveIndex] call EstimateDamage_VersusDefendingCard ld a, DUELVARS_ARENA_CARD_HP @@ -4359,11 +4368,16 @@ Func_16a86: ; 16a86 (5:6a86) ld a, 20 call AddToAIScore +; raise AI score by the number of damage counters that this move deals. +; if no damage is dealt, subtract AI score. in case wDamage is zero +; but wMaxDamage is not, then encourage move afterwards. +; otherwise, if wMaxDamage is also zero, check for damage against +; player's bench, and encourage move in case there is. .check_damage xor a ld [wce02], a ld a, [wDamage] - ld [wCurCardPlayAreaLocation], a + ld [wCurMoveDamage], a or a jr z, .no_damage call CalculateTensDigit @@ -4375,27 +4389,29 @@ Func_16a86: ; 16a86 (5:6a86) call SubFromAIScore ld a, [wAIMaxDamage] or a - jr z, .asm_16b27 - ld a, $02 + jr z, .no_max_damage + ld a, 2 call AddToAIScore - xor a ld [wce02], a -.asm_16b27 +.no_max_damage ld a, MOVE_FLAG1_ADDRESS | DAMAGE_TO_OPPONENT_BENCH call CheckLoadedMoveFlag jr nc, .check_recoil - ld a, $02 + ld a, 2 call AddToAIScore +; handle recoil moves (low and high recoil). .check_recoil ld a, MOVE_FLAG1_ADDRESS | LOW_RECOIL call CheckLoadedMoveFlag - jr c, .asm_16b42 + jr c, .is_recoil ld a, MOVE_FLAG1_ADDRESS | HIGH_RECOIL call CheckLoadedMoveFlag jp nc, .check_defending_can_ko -.asm_16b42 +.is_recoil + ; sub from AI score number of damage counters + ; that move deals to itself. ld a, [wLoadedMoveUnknown1] or a jp z, .check_defending_can_ko @@ -4411,14 +4427,14 @@ Func_16a86: ; 16a86 (5:6a86) pop de jr c, .high_recoil - ; check if LOW_RECOIL KOs self + ; if LOW_RECOIL KOs self, decrease AI score ld a, DUELVARS_ARENA_CARD_HP call GetTurnDuelistVariable cp e jr c, .kos_self jp nz, .check_defending_can_ko .kos_self - ld a, $0a + ld a, 10 call SubFromAIScore .high_recoil @@ -4428,6 +4444,9 @@ Func_16a86: ; 16a86 (5:6a86) cp 2 jr c, .dismiss_high_recoil_move ; has benched Pokémon + +; here the AI handles high recoil moves differently +; depending on what deck it's playing. ld a, [wOpponentDeckID] cp ROCK_CRUSHER_DECK_ID jr z, .rock_crusher_deck @@ -4435,8 +4454,10 @@ Func_16a86: ; 16a86 (5:6a86) jr z, .zapping_selfdestruct_deck cp BOOM_BOOM_SELFDESTRUCT_DECK_ID jr z, .encourage_high_recoil_move + ; Boom Boom Selfdestruct deck always encourages cp POWER_GENERATOR_DECK_ID - jr nz, .asm_16be0 + jr nz, .high_recoil_generic_checks + ; Power Generator deck always dismisses .dismiss_high_recoil_move xor a @@ -4444,21 +4465,23 @@ Func_16a86: ; 16a86 (5:6a86) jp .done .encourage_high_recoil_move - ld a, $14 + ld a, 20 call AddToAIScore jp .done +; Zapping Selfdestruct deck only uses this move +; if number of cards in deck >= 30 and +; HP of active card is < half max HP. .zapping_selfdestruct_deck ld a, DUELVARS_NUMBER_OF_CARDS_NOT_IN_DECK call GetTurnDuelistVariable cp 31 - jr nc, .asm_16be0 + jr nc, .high_recoil_generic_checks ld e, PLAY_AREA_ARENA call GetCardDamage sla a cp c - jr c, .asm_16be0 - + jr c, .high_recoil_generic_checks ld b, 0 ld a, DUELVARS_ARENA_CARD call GetTurnDuelistVariable @@ -4466,84 +4489,111 @@ Func_16a86: ; 16a86 (5:6a86) ld a, e cp MAGNEMITE1 jr z, .magnemite1 - ld b, 10 + ld b, 10 ; bench damage .magnemite1 ld a, 10 add b - ld b, a - ld a, $01 - call .asm_16c35 + ld b, a ; 20 bench damage if not Magnemite1 + +; if this move causes player to win the duel by +; knocking out own Pokémon, dismiss move. + ld a, 1 ; count active Pokémon as KO'd + call .check_if_kos_bench jr c, .dismiss_high_recoil_move jr .encourage_high_recoil_move +; Rock Crusher Deck only uses this move if +; prize count is below 4 and move wins (or potentially draws) the duel, +; (at least gets KOs equal to prize cards left). .rock_crusher_deck call CountPrizes cp 4 jr nc, .dismiss_high_recoil_move ; prize count < 4 - ld b, $14 + ld b, 20 ; damage dealt to bench call SwapTurn xor a - call .asm_16c35 + call .check_if_kos_bench call SwapTurn jr c, .encourage_high_recoil_move -.asm_16be0 +; generic checks for all other deck IDs. +; encourage move if it wins (or potentially draws) the duel, +; (at least gets KOs equal to prize cards left). +; dismiss it if it causes the player to win. +.high_recoil_generic_checks ld a, DUELVARS_ARENA_CARD call GetTurnDuelistVariable call GetCardIDFromDeckIndex ld a, e cp CHANSEY - jr z, .asm_16bfd + jr z, .chansey cp MAGNEMITE1 - jr z, .asm_16bf9 + jr z, .magnemite1_or_weezing cp WEEZING - jr z, .asm_16bf9 - - ld b, 20 - jr .asm_16bff -.asm_16bf9 - ld b, 10 - jr .asm_16bff -.asm_16bfd - ld b, 0 -.asm_16bff + jr z, .magnemite1_or_weezing + ld b, 20 ; bench damage + jr .check_bench_kos +.magnemite1_or_weezing + ld b, 10 ; bench damage + jr .check_bench_kos +.chansey + ld b, 0 ; no bench damage + +.check_bench_kos push bc call SwapTurn xor a - call .asm_16c35 + call .check_if_kos_bench call SwapTurn pop bc - jr c, .asm_16c1d + jr c, .wins_the_duel push de - ld a, $01 - call .asm_16c35 + ld a, 1 + call .check_if_kos_bench pop bc - jr nc, .asm_16c25 + jr nc, .count_own_ko_bench +; move causes player to draw all prize cards xor a ld [wAIScore], a jp .done -.asm_16c1d + +; move causes CPU to draw all prize cards +.wins_the_duel ld a, 20 call AddToAIScore jp .done -.asm_16c25 +; subtract from AI score number of own benched Pokémon KO'd +.count_own_ko_bench push bc ld a, d or a - jr z, .asm_16c2e + jr z, .count_player_ko_bench dec a call SubFromAIScore -.asm_16c2e +; add to AI score number of player benched Pokémon KO'd +.count_player_ko_bench pop bc ld a, b call AddToAIScore jr .check_defending_can_ko -.asm_16c35 +; local function that gets called to determine damage to +; benched Pokémoncaused by a HIGH_RECOIL move. +; return carry if using move causes number of benched Pokémon KOs +; equal to or larger than remaining prize cards. +; this function is independent on duelist turn, so whatever +; turn it is when this is called, it's that duelist's +; bench/prize cards that get checked. +; input: +; a = initial number of KO's beside benched Pokémon, +; so that if the active Pokémon is KO'd by the move, +; this counts towards the prize cards collected +; b = damage dealt to bench Pokémon +.check_if_kos_bench ld d, a ld a, DUELVARS_BENCH call GetTurnDuelistVariable @@ -4552,33 +4602,36 @@ Func_16a86: ; 16a86 (5:6a86) inc e ld a, [hli] cp $ff - jr z, .asm_16c53 + jr z, .exit_loop ld a, e add DUELVARS_ARENA_CARD_HP push hl call GetTurnDuelistVariable pop hl cp b - jr z, .asm_16c50 + jr z, .increase_count jr nc, .loop -.asm_16c50 + ; increase d if damage dealt KOs +.increase_count inc d jr .loop -.asm_16c53 +.exit_loop push de call SwapTurn call CountPrizes call SwapTurn pop de cp d - jp c, .asm_16c67 - jp z, .asm_16c67 + jp c, .set_carry + jp z, .set_carry or a ret -.asm_16c67 +.set_carry scf ret +; if defending card can KO, encourage move +; unless wce02 is non-zero. .check_defending_can_ko ld a, [wSelectedMoveIndex] push af @@ -4595,6 +4648,8 @@ Func_16a86: ; 16a86 (5:6a86) ld a, 5 call SubFromAIScore +; subtract from AI score if this move requires +; discarding any energy cards. .check_discard ld a, [wSelectedMoveIndex] ld e, a @@ -4613,32 +4668,34 @@ Func_16a86: ; 16a86 (5:6a86) .asm_16ca6 ld a, MOVE_FLAG2_ADDRESS | FLAG_2_BIT_6 call CheckLoadedMoveFlag - jr nc, .asm_16cb3 + jr nc, .check_nullify_flag ld a, [wLoadedMoveUnknown1] call AddToAIScore -.asm_16cb3 +; encourage move if it has a nullify or weaken attack effect. +.check_nullify_flag ld a, MOVE_FLAG2_ADDRESS | NULLIFY_OR_WEAKEN_ATTACK call CheckLoadedMoveFlag - jr nc, .asm_16cbf + jr nc, .check_draw_flag ld a, 1 call AddToAIScore -.asm_16cbf +; encourage move if it has an effect to draw a card. +.check_draw_flag ld a, MOVE_FLAG1_ADDRESS | DRAW_CARD call CheckLoadedMoveFlag - jr nc, .asm_16ccb + jr nc, .check_heal_flag ld a, $01 call AddToAIScore -.asm_16ccb +.check_heal_flag ld a, MOVE_FLAG2_ADDRESS | HEAL_USER call CheckLoadedMoveFlag - jr nc, .asm_16d09 + jr nc, .check_status_effect ld a, [wLoadedMoveUnknown1] cp $01 jr z, .asm_16cf8 - ld a, [wCurCardPlayAreaLocation] + ld a, [wCurMoveDamage] call CalculateTensDigit ld b, a ld a, [wLoadedMoveUnknown1] @@ -4656,70 +4713,77 @@ Func_16a86: ; 16a86 (5:6a86) ld a, b .asm_16cf8 push af - ld e, $00 + ld e, PLAY_AREA_ARENA call GetCardDamage call CalculateTensDigit pop bc - cp b + cp b ; wLoadedMoveUnknown1 jr c, .asm_16d06 ld a, b .asm_16d06 call AddToAIScore -.asm_16d09 +.check_status_effect ld a, DUELVARS_ARENA_CARD call GetNonTurnDuelistVariable call SwapTurn call GetCardIDFromDeckIndex call SwapTurn ld a, e + ; skip if player has Snorlax cp SNORLAX jp z, .asm_16db0 + ld a, DUELVARS_ARENA_CARD_STATUS call GetNonTurnDuelistVariable ld [wCurCardPlayAreaLocation], a + +; check poison ld a, MOVE_FLAG1_ADDRESS | INFLICT_POISON call CheckLoadedMoveFlag - jr nc, .asm_16d4a + jr nc, .check_sleep ld a, [wCurCardPlayAreaLocation] and $c0 jr z, .asm_16d45 and $40 - jr z, .asm_16d4a + jr z, .check_sleep ld a, MOVE_FLAG2_ADDRESS | FLAG_2_BIT_6 call CheckLoadedMoveFlag - jr nc, .asm_16d4a + jr nc, .check_sleep ld a, $02 call SubFromAIScore - jr .asm_16d4a + jr .check_sleep .asm_16d45 ld a, $02 call AddToAIScore -.asm_16d4a + +.check_sleep ld a, MOVE_FLAG1_ADDRESS | INFLICT_SLEEP call CheckLoadedMoveFlag - jr nc, .asm_16d5f + jr nc, .check_paralysis ld a, [wCurCardPlayAreaLocation] and $0f cp $02 - jr z, .asm_16d5f + jr z, .check_paralysis ld a, $01 call AddToAIScore -.asm_16d5f + +.check_paralysis ld a, MOVE_FLAG1_ADDRESS | INFLICT_PARALYSIS call CheckLoadedMoveFlag - jr nc, .asm_16d7b + jr nc, .check_confusion ld a, [wCurCardPlayAreaLocation] and $0f cp $02 jr z, .asm_16d76 ld a, $01 call AddToAIScore - jr .asm_16d7b + jr .check_confusion .asm_16d76 ld a, $01 call SubFromAIScore -.asm_16d7b + +.check_confusion ld a, MOVE_FLAG1_ADDRESS | INFLICT_CONFUSION call CheckLoadedMoveFlag jr nc, .asm_16da0 -- cgit v1.2.3 From 4984d5204818795c4a0c200c0f21f31610661e2e Mon Sep 17 00:00:00 2001 From: ElectroDeoxys Date: Mon, 9 Sep 2019 22:56:36 +0100 Subject: Disassemble Func_16dcd --- src/engine/bank05.asm | 354 +++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 349 insertions(+), 5 deletions(-) (limited to 'src/engine') diff --git a/src/engine/bank05.asm b/src/engine/bank05.asm index c7d2c13..c0287b9 100644 --- a/src/engine/bank05.asm +++ b/src/engine/bank05.asm @@ -3741,7 +3741,10 @@ CheckForEvolutionInDeck: ; 16451 (5:6451) ; 0x16488 Func_16488 ; 16488 (5:6488) - INCROM $16488, $164d3 + INCROM $16488, $164a1 + +Func_164a1 ; 164a1 (5:64a1) + INCROM $164a1, $164d3 ; copies bench AI score to wcddd ; and loads in wAIscore value in wcde3 @@ -4830,11 +4833,352 @@ Func_16a86: ; 16a86 (5:6a86) ret ; 0x16dcd -Func_16dcd ; 16dcd (5:6dcd) - INCROM $16dcd, $17019 +Func_16dcd: ; 16dcd (5:6dcd) + ldh a, [hTempPlayAreaLocation_ff9d] + add DUELVARS_ARENA_CARD + call GetTurnDuelistVariable + call GetCardIDFromDeckIndex + ld a, e + + cp NIDORANF + jr z, .asm_16e55 + cp ODDISH + jr z, .asm_16e3e + cp BELLSPROUT + jr z, .asm_16e3e + cp EXEGGUTOR + jp z, .asm_16ec2 + cp SCYTHER + jp z, .asm_16ecb + cp KRABBY + jr z, .asm_16e3e + cp VAPOREON1 + jp z, .asm_16ecb + cp ELECTRODE2 + jp z, .asm_16eea + cp MAROWAK1 + jr z, .asm_16e77 + cp MEW3 + jp z, .asm_16f0f + cp JIGGLYPUFF2 + jp z, .asm_16ead + cp PORYGON + jp z, .asm_16f18 + cp MEWTWO3 + jp z, .asm_16f41 + cp MEWTWO2 + jp z, .asm_16f41 + cp NINETAILS2 + jp z, .asm_16f4e + cp ZAPDOS3 + jp z, .asm_16fb8 + cp KANGASKHAN + jp z, .asm_16fbb + cp DUGTRIO + jp z, .asm_16fc8 + cp ELECTRODE1 + jp z, .asm_16ff2 + cp GOLDUCK + jp z, Func_17005 + cp DRAGONAIR + jp z, Func_17005 + +.done + xor a + ret + +.asm_16e3e + ld a, CARD_LOCATION_DECK + call Func_157a3 + jr nc, .done + ld a, DUELVARS_NUMBER_OF_POKEMON_IN_PLAY_AREA + call GetTurnDuelistVariable + cp MAX_BENCH_POKEMON + jr nc, .done + ld b, a + ld a, MAX_BENCH_POKEMON + sub b + add $80 + ret + +.asm_16e55 + ld e, NIDORANM + ld a, CARD_LOCATION_DECK + call Func_157a3 + jr c, .asm_16e67 + ld e, NIDORANF + ld a, CARD_LOCATION_DECK + call Func_157a3 + jr nc, .done +.asm_16e67 + ld a, DUELVARS_NUMBER_OF_POKEMON_IN_PLAY_AREA + call GetTurnDuelistVariable + cp MAX_PLAY_AREA_POKEMON + jr nc, .done + ld b, a + ld a, MAX_PLAY_AREA_POKEMON + sub b + add $80 + ret + +.asm_16e77 + ld e, GEODUDE + ld a, CARD_LOCATION_DECK + call Func_157a3 + jr c, .asm_16e9d + ld e, ONIX + ld a, CARD_LOCATION_DECK + call Func_157a3 + jr c, .asm_16e9d + ld e, CUBONE + ld a, CARD_LOCATION_DECK + call Func_157a3 + jr c, .asm_16e9d + ld e, RHYHORN + ld a, CARD_LOCATION_DECK + call Func_157a3 + jr c, .asm_16e9d + jr .done +.asm_16e9d + ld a, DUELVARS_NUMBER_OF_POKEMON_IN_PLAY_AREA + call GetTurnDuelistVariable + cp MAX_BENCH_POKEMON + jr nc, .done + ld b, a + ld a, MAX_BENCH_POKEMON + sub b + add $80 + ret + +.asm_16ead: ; 16ead (5:6ead) + call Func_17057 + jr nc, .done + ld a, DUELVARS_NUMBER_OF_POKEMON_IN_PLAY_AREA + call GetTurnDuelistVariable + cp MAX_PLAY_AREA_POKEMON + jr nc, .done + ld b, a + ld a, MAX_PLAY_AREA_POKEMON + sub b + add $80 + ret + +.asm_16ec2: ; 16ec2 (5:6ec2) + call AIDecideWhetherToRetreat + jp nc, .done + ld a, $8a + ret + +.asm_16ecb: ; 16ecb (5:6ecb) + ld a, [wcdf0] + or a + jr nz, .asm_16ee7 + ld a, $01 ; second move + ld [wSelectedMoveIndex], a + call CheckIfSelectedMoveIsUnusable + jr c, .asm_16ee7 + ld a, $01 ; second move + call EstimateDamage_VersusDefendingCard + ld a, [wDamage] + or a + jp nz, .done +.asm_16ee7 + ld a, $85 + ret + +.asm_16eea: ; 16eea (5:6eea) + call SwapTurn + call GetArenaCardColor + call SwapTurn + ld b, a + ld a, DUELVARS_BENCH + call GetTurnDuelistVariable +.asm_16ef9 + ld a, [hli] + cp $ff + jr z, .asm_16f0c + push bc + call GetCardIDFromDeckIndex + call GetCardType + pop bc + cp b + jr nz, .asm_16ef9 + jp .done +.asm_16f0c + ld a, $82 + ret + +.asm_16f0f: ; 16f0f (5:6f0f) + call Func_17080 + jp nc, .done + ld a, $85 + ret + +.asm_16f18: ; 16f18 (5:6f18) + ld a, DUELVARS_ARENA_CARD_STATUS + call GetTurnDuelistVariable + and CNF_SLP_PRZ + cp CONFUSED + jp z, .done + ld a, [wSelectedMoveIndex] + or a + jr nz, .asm_16f34 + call CheckIfBenchCardsAreAtHalfHPCanEvolveAndUseSecondMove + cp 2 + jr c, .asm_16f3e + ld a, $82 + ret +.asm_16f34 + call CheckIfBenchCardsAreAtHalfHPCanEvolveAndUseSecondMove + cp 2 + jr nc, .asm_16f3e + ld a, $82 + ret +.asm_16f3e + ld a, $81 + ret + +.asm_16f41: ; 16f41 (5:6f41) + ld e, PSYCHIC_ENERGY + ld a, CARD_LOCATION_DISCARD_PILE + call Func_157a3 + jp nc, .done + ld a, $82 + ret + +.asm_16f4e: ; 16f4e (5:6f4e) + ld a, DUELVARS_NUMBER_OF_CARDS_IN_HAND + call GetNonTurnDuelistVariable + or a + ret z + ld a, $03 + call Random + or a + jr z, .asm_16fb5 + dec a + ret z + call SwapTurn + call CreateHandCardList + call SwapTurn + or a + ret z + ld a, DUELVARS_NUMBER_OF_POKEMON_IN_PLAY_AREA + call GetNonTurnDuelistVariable + cp 3 + jr nc, .asm_16f9d + + ld hl, wDuelTempList + ld b, 0 +.asm_16f78 + ld a, [hli] + cp $ff + jr z, .asm_16f98 + push bc + call SwapTurn + call LoadCardDataToBuffer2_FromDeckIndex + call SwapTurn + pop bc + ld a, [wLoadedCard2Type] + cp TYPE_ENERGY + jr nc, .asm_16f78 + ld a, [wLoadedCard2Stage] + or a + jr nz, .asm_16f78 + inc b + jr .asm_16f78 +.asm_16f98 + ld a, b + cp 2 + jr nc, .asm_16fb5 +.asm_16f9d + ld a, DUELVARS_ARENA_CARD + call GetNonTurnDuelistVariable +.asm_16fa2 + ld a, [hli] + cp $ff + jp z, .done + push hl + call SwapTurn + call CheckForEvolutionInList + call SwapTurn + pop hl + jr nc, .asm_16fa2 +.asm_16fb5 + ld a, $83 + ret + +.asm_16fb8: ; 16fb8 (5:6fb8) + ld a, $83 + ret + +.asm_16fbb: ; 16fbb (5:6fbb) + ld a, DUELVARS_NUMBER_OF_CARDS_NOT_IN_DECK + call GetTurnDuelistVariable + cp 41 + jp nc, .done + ld a, $80 + ret + +.asm_16fc8: ; 16fc8 (5:6fc8) + ld a, DUELVARS_BENCH + call GetTurnDuelistVariable + + lb de, 0, 0 +.asm_16fd0 + inc e + ld a, [hli] + cp $ff + jr z, .asm_16fe3 + ld a, e + add DUELVARS_ARENA_CARD_HP + call GetTurnDuelistVariable + cp 20 + jr nc, .asm_16fd0 + inc d + jr .asm_16fd0 + +.asm_16fe3 + push de + call CountPrizes + pop de + cp d + jp c, .done + jp z, .done + ld a, $80 + ret + +.asm_16ff2: ; 16ff2 (5:6ff2) + ld a, CARD_LOCATION_DECK + ld e, LIGHTNING_ENERGY + call Func_157a3 + jp nc, .done + call Func_164a1 + jp nc, .done + ld a, $83 + ret + +Func_17005: ; 17005 (5:7005) + call SwapTurn + ld e, PLAY_AREA_ARENA + call CountNumberOfEnergyCardsAttached + call SwapTurn + or a + jr z, .asm_17016 + ld a, $83 + ret +.asm_17016 + ld a, $80 + ret +; 0x17019 Func_17019 ; 17019 (5:7019) - INCROM $17019, $170c9 + INCROM $17019, $17057 + +Func_17057 ; 17057 (5:7057) + INCROM $17057, $17080 + +Func_17080 ; 17080 (5:7080) + INCROM $17080, $170c9 ; returns carry if the following conditions are met: ; - arena card HP >= half max HP @@ -4886,7 +5230,7 @@ CheckIfArenaCardIsAtHalfHPCanEvolveAndUseSecondMove: ; 170c9 (5:70c9) ; is set but there's no evolution of card in hand/deck ; - card can use second move ; Also outputs the number of Pokémon in bench -; that meet these requirements in b +; that meet these requirements in a CheckIfBenchCardsAreAtHalfHPCanEvolveAndUseSecondMove: ; 17101 (5:7101) ldh a, [hTempPlayAreaLocation_ff9d] ld d, a -- cgit v1.2.3 From 35859ec72f645affa3cfc0e6eae6e5327e03c62e Mon Sep 17 00:00:00 2001 From: ElectroDeoxys Date: Mon, 9 Sep 2019 23:14:57 +0100 Subject: Disassemble and label CheckIfAnyCardIDinLocation --- src/engine/bank05.asm | 57 +++++++++++++++++++++++++++++++++++++++++---------- 1 file changed, 46 insertions(+), 11 deletions(-) (limited to 'src/engine') diff --git a/src/engine/bank05.asm b/src/engine/bank05.asm index c0287b9..3b790f0 100644 --- a/src/engine/bank05.asm +++ b/src/engine/bank05.asm @@ -1593,8 +1593,43 @@ CountNumberOfEnergyCardsAttached: ; 15787 (5:5787) ret ; 0x157a3 -Func_157a3: ; 157a3 (5:57a3) - INCROM $157a3, $158b2 +; returns carry if any card with ID in e is found +; in card location in a +; input: +; a = card location to look in; +; e = card ID to look for. +CheckIfAnyCardIDinLocation: ; 157a3 (5:57a3) + ld b, a + ld c, e + lb de, 0, 0 +.loop + ld a, DUELVARS_CARD_LOCATIONS + add e + call GetTurnDuelistVariable + cp b + jr nz, .next + ld a, e + push de + call GetCardIDFromDeckIndex + ld a, e + pop de + cp c + jr z, .set_carry +.next + inc e + ld a, DECK_SIZE + cp e + jr nz, .loop + or a + ret +.set_carry + ld a, e + scf + ret +; 0x157c6 + +Func_157c6: ; 157c6 (5:57c6) + INCROM $157c6, $158b2 ; determine AI score for retreating ; return carry if AI decides to retreat @@ -4889,7 +4924,7 @@ Func_16dcd: ; 16dcd (5:6dcd) .asm_16e3e ld a, CARD_LOCATION_DECK - call Func_157a3 + call CheckIfAnyCardIDinLocation jr nc, .done ld a, DUELVARS_NUMBER_OF_POKEMON_IN_PLAY_AREA call GetTurnDuelistVariable @@ -4904,11 +4939,11 @@ Func_16dcd: ; 16dcd (5:6dcd) .asm_16e55 ld e, NIDORANM ld a, CARD_LOCATION_DECK - call Func_157a3 + call CheckIfAnyCardIDinLocation jr c, .asm_16e67 ld e, NIDORANF ld a, CARD_LOCATION_DECK - call Func_157a3 + call CheckIfAnyCardIDinLocation jr nc, .done .asm_16e67 ld a, DUELVARS_NUMBER_OF_POKEMON_IN_PLAY_AREA @@ -4924,19 +4959,19 @@ Func_16dcd: ; 16dcd (5:6dcd) .asm_16e77 ld e, GEODUDE ld a, CARD_LOCATION_DECK - call Func_157a3 + call CheckIfAnyCardIDinLocation jr c, .asm_16e9d ld e, ONIX ld a, CARD_LOCATION_DECK - call Func_157a3 + call CheckIfAnyCardIDinLocation jr c, .asm_16e9d ld e, CUBONE ld a, CARD_LOCATION_DECK - call Func_157a3 + call CheckIfAnyCardIDinLocation jr c, .asm_16e9d ld e, RHYHORN ld a, CARD_LOCATION_DECK - call Func_157a3 + call CheckIfAnyCardIDinLocation jr c, .asm_16e9d jr .done .asm_16e9d @@ -5041,7 +5076,7 @@ Func_16dcd: ; 16dcd (5:6dcd) .asm_16f41: ; 16f41 (5:6f41) ld e, PSYCHIC_ENERGY ld a, CARD_LOCATION_DISCARD_PILE - call Func_157a3 + call CheckIfAnyCardIDinLocation jp nc, .done ld a, $82 ret @@ -5150,7 +5185,7 @@ Func_16dcd: ; 16dcd (5:6dcd) .asm_16ff2: ; 16ff2 (5:6ff2) ld a, CARD_LOCATION_DECK ld e, LIGHTNING_ENERGY - call Func_157a3 + call CheckIfAnyCardIDinLocation jp nc, .done call Func_164a1 jp nc, .done -- cgit v1.2.3 From 37af0eac26585f6a38582bbc0ab8459e2387543d Mon Sep 17 00:00:00 2001 From: ElectroDeoxys Date: Mon, 9 Sep 2019 23:21:26 +0100 Subject: Disassemble and label CheckIfAnyBasicPokemonInDeck --- src/engine/bank05.asm | 35 ++++++++++++++++++++++++++++++++--- 1 file changed, 32 insertions(+), 3 deletions(-) (limited to 'src/engine') diff --git a/src/engine/bank05.asm b/src/engine/bank05.asm index 3b790f0..0385820 100644 --- a/src/engine/bank05.asm +++ b/src/engine/bank05.asm @@ -4986,7 +4986,7 @@ Func_16dcd: ; 16dcd (5:6dcd) ret .asm_16ead: ; 16ead (5:6ead) - call Func_17057 + call CheckIfAnyBasicPokemonInDeck jr nc, .done ld a, DUELVARS_NUMBER_OF_POKEMON_IN_PLAY_AREA call GetTurnDuelistVariable @@ -5209,8 +5209,37 @@ Func_17005: ; 17005 (5:7005) Func_17019 ; 17019 (5:7019) INCROM $17019, $17057 -Func_17057 ; 17057 (5:7057) - INCROM $17057, $17080 +; returns carry if there are +; any basic Pokémon cards in deck. +CheckIfAnyBasicPokemonInDeck: ; 17057 (5:7057) + ld e, 0 +.loop + ld a, DUELVARS_CARD_LOCATIONS + add e + call GetTurnDuelistVariable + cp CARD_LOCATION_DECK + jr nz, .next + push de + ld a, e + call LoadCardDataToBuffer2_FromDeckIndex + pop de + ld a, [wLoadedCard2Type] + cp TYPE_ENERGY + jr nc, .next + ld a, [wLoadedCard2Stage] + or a + jr z, .set_carry +.next + inc e + ld a, DECK_SIZE + cp e + jr nz, .loop + or a + ret +.set_carry + scf + ret +; 0x17080 Func_17080 ; 17080 (5:7080) INCROM $17080, $170c9 -- cgit v1.2.3 From d4959345dfa703a0054dd84d2e2c54ca9eac25ee Mon Sep 17 00:00:00 2001 From: ElectroDeoxys Date: Mon, 9 Sep 2019 23:49:05 +0100 Subject: Disassemble Func_17080 --- src/engine/bank01.asm | 1 + src/engine/bank05.asm | 52 +++++++++++++++++++++++++++++++++++++++++++++++++-- 2 files changed, 51 insertions(+), 2 deletions(-) (limited to 'src/engine') diff --git a/src/engine/bank01.asm b/src/engine/bank01.asm index f9f8781..0880839 100644 --- a/src/engine/bank01.asm +++ b/src/engine/bank01.asm @@ -7620,6 +7620,7 @@ PrintThereWasNoEffectFromStatusText: ; 700a (1:700a) ret ; 0x7045 +Func_7045: ; 7045 (1:7045) INCROM $7045, $70aa ; initializes variables when a duel begins, such as zeroing wDuelFinished or wDuelTurns, diff --git a/src/engine/bank05.asm b/src/engine/bank05.asm index 0385820..8c78a94 100644 --- a/src/engine/bank05.asm +++ b/src/engine/bank05.asm @@ -5241,8 +5241,56 @@ CheckIfAnyBasicPokemonInDeck: ; 17057 (5:7057) ret ; 0x17080 -Func_17080 ; 17080 (5:7080) - INCROM $17080, $170c9 +Func_17080: ; 17080 (5:7080) + ldh a, [hTempPlayAreaLocation_ff9d] + push af + call SwapTurn + ld a, DUELVARS_NUMBER_OF_POKEMON_IN_PLAY_AREA + call GetTurnDuelistVariable + ld b, a + ld c, PLAY_AREA_ARENA + +.loop + ld a, c + ldh [hTempPlayAreaLocation_ff9d], a + push bc + bank1call Func_7045 + pop bc + jr c, .next + ld a, d + push bc + call LoadCardDataToBuffer2_FromDeckIndex + pop bc + ld a, [wLoadedCard2HP] + ld [wCurMoveDamage], a + ld e, c + push bc + call GetCardDamage + pop bc + ld e, a + ld a, [wCurMoveDamage] + cp e + jr c, .set_carry + jr z, .set_carry +.next + inc c + ld a, c + cp b + jr nz, .loop + + call SwapTurn + pop af + ldh [hTempPlayAreaLocation_ff9d], a + or a + ret +.set_carry + call SwapTurn + pop af + ldh [hTempPlayAreaLocation_ff9d], a + ld a, c + scf + ret +; 0x170c9 ; returns carry if the following conditions are met: ; - arena card HP >= half max HP -- cgit v1.2.3 From a8d40599bf1c767c7247695c49a7272d2e54cedd Mon Sep 17 00:00:00 2001 From: ElectroDeoxys Date: Tue, 10 Sep 2019 19:08:37 +0100 Subject: Label GetCardOneStageBelow --- src/engine/bank01.asm | 82 +++++++++++++++++++++++++++++++++++++++++++++++++-- src/engine/bank05.asm | 6 +++- 2 files changed, 85 insertions(+), 3 deletions(-) (limited to 'src/engine') diff --git a/src/engine/bank01.asm b/src/engine/bank01.asm index 0880839..644a6c2 100644 --- a/src/engine/bank01.asm +++ b/src/engine/bank01.asm @@ -7620,8 +7620,86 @@ PrintThereWasNoEffectFromStatusText: ; 700a (1:700a) ret ; 0x7045 -Func_7045: ; 7045 (1:7045) - INCROM $7045, $70aa +; returns carry if card at hTempPlayAreaLocation_ff9d +; is a basic card. +; otherwise, lists the card indices of all stages in +; in that card location, and returns the card one +; stage below. +; input: +; hTempPlayAreaLocation_ff9d = play area location to check; +; output: +; a = card index in hTempPlayAreaLocation_ff9d; +; d = card index of card one stage below; +; carry set if card is a basic card. +GetCardOneStageBelow: ; 7045 (1:7045) + ldh a, [hTempPlayAreaLocation_ff9d] + add DUELVARS_ARENA_CARD + call GetTurnDuelistVariable + call LoadCardDataToBuffer2_FromDeckIndex + ld a, [wLoadedCard2Stage] + or a + jr nz, .not_basic + scf + ret + +.not_basic + ld hl, wAllStagesIndices + ld a, $ff + ld [hli], a + ld [hli], a + ld [hl], a + +; loads deck indices of the stages present in hTempPlayAreaLocation_ff9d. +; the three stages are loaded consecutively in wAllStagesIndices. + ldh a, [hTempPlayAreaLocation_ff9d] + or CARD_LOCATION_ARENA + ld c, a + ld a, DUELVARS_CARD_LOCATIONS + call GetTurnDuelistVariable +.loop + ld a, [hl] + cp c + jr nz, .next + ld a, l + call LoadCardDataToBuffer2_FromDeckIndex + ld a, [wLoadedCard2Type] + cp TYPE_ENERGY + jr nc, .next + ld b, l + push hl + ld a, [wLoadedCard2Stage] + ld e, a + ld d, $00 + ld hl, wAllStagesIndices + add hl, de + ld [hl], b + pop hl +.next + inc l + ld a, l + cp DECK_SIZE + jr c, .loop + +; if card at hTempPlayAreaLocation_ff9d is a stage 1, load d with basic card. +; otherwise if stage 2, load d with the stage 1 card. + ldh a, [hTempPlayAreaLocation_ff9d] + add DUELVARS_ARENA_CARD_STAGE + call GetTurnDuelistVariable + ld hl, wAllStagesIndices ; pointing to basic + cp STAGE1 + jr z, .done + cp STAGE2 + 1 ; unnecessary check? + jr z, .done + inc hl ; pointing to stage 1 +.done + ld d, [hl] + ldh a, [hTempPlayAreaLocation_ff9d] + add DUELVARS_ARENA_CARD + call GetTurnDuelistVariable + ld e, a + or a + ret +; 0x70aa ; initializes variables when a duel begins, such as zeroing wDuelFinished or wDuelTurns, ; and setting wDuelType based on wPlayerDuelistType and wOpponentDuelistType diff --git a/src/engine/bank05.asm b/src/engine/bank05.asm index 8c78a94..2991bf8 100644 --- a/src/engine/bank05.asm +++ b/src/engine/bank05.asm @@ -5241,6 +5241,7 @@ CheckIfAnyBasicPokemonInDeck: ; 17057 (5:7057) ret ; 0x17080 + Func_17080: ; 17080 (5:7080) ldh a, [hTempPlayAreaLocation_ff9d] push af @@ -5254,9 +5255,11 @@ Func_17080: ; 17080 (5:7080) ld a, c ldh [hTempPlayAreaLocation_ff9d], a push bc - bank1call Func_7045 + bank1call GetCardOneStageBelow pop bc jr c, .next + ; is not a basic card + ; compare its HP with current damage ld a, d push bc call LoadCardDataToBuffer2_FromDeckIndex @@ -5283,6 +5286,7 @@ Func_17080: ; 17080 (5:7080) ldh [hTempPlayAreaLocation_ff9d], a or a ret + .set_carry call SwapTurn pop af -- cgit v1.2.3 From 5ee751abb284c4a4939f5731aeec95166f30739a Mon Sep 17 00:00:00 2001 From: ElectroDeoxys Date: Tue, 10 Sep 2019 20:45:10 +0100 Subject: Fix move flag constants and some card constants --- src/engine/bank05.asm | 46 +++++++++++++++++++++++----------------------- 1 file changed, 23 insertions(+), 23 deletions(-) (limited to 'src/engine') diff --git a/src/engine/bank05.asm b/src/engine/bank05.asm index 2991bf8..ecfc85c 100644 --- a/src/engine/bank05.asm +++ b/src/engine/bank05.asm @@ -330,7 +330,7 @@ CheckIfSelectedMoveIsUnusable: ; 1424b (5:424b) .bench call CheckEnergyNeededForAttack ret c ; can't be used - ld a, MOVE_FLAG2_ADDRESS | FLAG_2_BIT_5 + ld a, MOVE_FLAG2_ADDRESS | FLAG_2_BIT_5_F call CheckLoadedMoveFlag ret ; 0x14279 @@ -4085,10 +4085,10 @@ Func_16695: ; 16695 (5:6695) ld [wSelectedMoveIndex], a call CheckEnergyNeededForAttack jp c, .asm_1671e - ld a, MOVE_FLAG2_ADDRESS | ATTACHED_ENERGY_BOOST + ld a, MOVE_FLAG2_ADDRESS | ATTACHED_ENERGY_BOOST_F call CheckLoadedMoveFlag jr c, .asm_166af - ld a, MOVE_FLAG2_ADDRESS | DISCARD_ENERGY + ld a, MOVE_FLAG2_ADDRESS | DISCARD_ENERGY_F call CheckLoadedMoveFlag jr c, .asm_16710 jp .check_evolution @@ -4116,7 +4116,7 @@ Func_16695: ; 16695 (5:6695) ; check whether move has ATTACHED_ENERGY_BOOST flag ; and add to AI score if attaching another energy ; will KO defending Pokémon - ld a, MOVE_FLAG2_ADDRESS | ATTACHED_ENERGY_BOOST + ld a, MOVE_FLAG2_ADDRESS | ATTACHED_ENERGY_BOOST_F call CheckLoadedMoveFlag jp nc, .check_evolution ld a, [wSelectedMoveIndex] @@ -4156,7 +4156,7 @@ Func_16695: ; 16695 (5:6695) jr .asm_166c5 .asm_1671e - ld a, MOVE_FLAG2_ADDRESS | FLAG_2_BIT_5 + ld a, MOVE_FLAG2_ADDRESS | FLAG_2_BIT_5_F call CheckLoadedMoveFlag jr nc, .asm_1672a ld a, 5 @@ -4219,7 +4219,7 @@ Func_16695: ; 16695 (5:6695) ld [hl], b call CheckEnergyNeededForAttack jr nc, .done - ld a, MOVE_FLAG2_ADDRESS | FLAG_2_BIT_5 + ld a, MOVE_FLAG2_ADDRESS | FLAG_2_BIT_5_F call CheckLoadedMoveFlag jr c, .done ld a, b @@ -4314,7 +4314,7 @@ Func_169f8: ; 169f8 (5:69f8) ld [$cdb4], a jr .asm_16a6d .asm_16a62 - ld a, MOVE_FLAG1_ADDRESS | DAMAGE_TO_OPPONENT_BENCH + ld a, MOVE_FLAG1_ADDRESS | DAMAGE_TO_OPPONENT_BENCH_F call CheckLoadedMoveFlag jr c, .asm_16a5c ld hl, $cdb4 @@ -4386,7 +4386,7 @@ Func_16a86: ; 16a86 (5:6a86) jr z, .unusable and RESIDUAL jr nz, .check_if_can_ko - ld a, MOVE_FLAG1_ADDRESS | DAMAGE_TO_OPPONENT_BENCH + ld a, MOVE_FLAG1_ADDRESS | DAMAGE_TO_OPPONENT_BENCH_F call CheckLoadedMoveFlag jr nc, .unusable @@ -4433,7 +4433,7 @@ Func_16a86: ; 16a86 (5:6a86) xor a ld [wce02], a .no_max_damage - ld a, MOVE_FLAG1_ADDRESS | DAMAGE_TO_OPPONENT_BENCH + ld a, MOVE_FLAG1_ADDRESS | DAMAGE_TO_OPPONENT_BENCH_F call CheckLoadedMoveFlag jr nc, .check_recoil ld a, 2 @@ -4441,10 +4441,10 @@ Func_16a86: ; 16a86 (5:6a86) ; handle recoil moves (low and high recoil). .check_recoil - ld a, MOVE_FLAG1_ADDRESS | LOW_RECOIL + ld a, MOVE_FLAG1_ADDRESS | LOW_RECOIL_F call CheckLoadedMoveFlag jr c, .is_recoil - ld a, MOVE_FLAG1_ADDRESS | HIGH_RECOIL + ld a, MOVE_FLAG1_ADDRESS | HIGH_RECOIL_F call CheckLoadedMoveFlag jp nc, .check_defending_can_ko .is_recoil @@ -4460,7 +4460,7 @@ Func_16a86: ; 16a86 (5:6a86) call SubFromAIScore push de - ld a, MOVE_FLAG1_ADDRESS | HIGH_RECOIL + ld a, MOVE_FLAG1_ADDRESS | HIGH_RECOIL_F call CheckLoadedMoveFlag pop de jr c, .high_recoil @@ -4695,7 +4695,7 @@ Func_16a86: ; 16a86 (5:6a86) call GetTurnDuelistVariable ld d, a call CopyMoveDataAndDamage_FromDeckIndex - ld a, MOVE_FLAG2_ADDRESS | DISCARD_ENERGY + ld a, MOVE_FLAG2_ADDRESS | DISCARD_ENERGY_F call CheckLoadedMoveFlag jr nc, .asm_16ca6 ld a, 1 @@ -4704,7 +4704,7 @@ Func_16a86: ; 16a86 (5:6a86) call SubFromAIScore .asm_16ca6 - ld a, MOVE_FLAG2_ADDRESS | FLAG_2_BIT_6 + ld a, MOVE_FLAG2_ADDRESS | FLAG_2_BIT_6_F call CheckLoadedMoveFlag jr nc, .check_nullify_flag ld a, [wLoadedMoveUnknown1] @@ -4712,7 +4712,7 @@ Func_16a86: ; 16a86 (5:6a86) ; encourage move if it has a nullify or weaken attack effect. .check_nullify_flag - ld a, MOVE_FLAG2_ADDRESS | NULLIFY_OR_WEAKEN_ATTACK + ld a, MOVE_FLAG2_ADDRESS | NULLIFY_OR_WEAKEN_ATTACK_F call CheckLoadedMoveFlag jr nc, .check_draw_flag ld a, 1 @@ -4720,14 +4720,14 @@ Func_16a86: ; 16a86 (5:6a86) ; encourage move if it has an effect to draw a card. .check_draw_flag - ld a, MOVE_FLAG1_ADDRESS | DRAW_CARD + ld a, MOVE_FLAG1_ADDRESS | DRAW_CARD_F call CheckLoadedMoveFlag jr nc, .check_heal_flag ld a, $01 call AddToAIScore .check_heal_flag - ld a, MOVE_FLAG2_ADDRESS | HEAL_USER + ld a, MOVE_FLAG2_ADDRESS | HEAL_USER_F call CheckLoadedMoveFlag jr nc, .check_status_effect ld a, [wLoadedMoveUnknown1] @@ -4777,7 +4777,7 @@ Func_16a86: ; 16a86 (5:6a86) ld [wCurCardPlayAreaLocation], a ; check poison - ld a, MOVE_FLAG1_ADDRESS | INFLICT_POISON + ld a, MOVE_FLAG1_ADDRESS | INFLICT_POISON_F call CheckLoadedMoveFlag jr nc, .check_sleep ld a, [wCurCardPlayAreaLocation] @@ -4785,7 +4785,7 @@ Func_16a86: ; 16a86 (5:6a86) jr z, .asm_16d45 and $40 jr z, .check_sleep - ld a, MOVE_FLAG2_ADDRESS | FLAG_2_BIT_6 + ld a, MOVE_FLAG2_ADDRESS | FLAG_2_BIT_6_F call CheckLoadedMoveFlag jr nc, .check_sleep ld a, $02 @@ -4796,7 +4796,7 @@ Func_16a86: ; 16a86 (5:6a86) call AddToAIScore .check_sleep - ld a, MOVE_FLAG1_ADDRESS | INFLICT_SLEEP + ld a, MOVE_FLAG1_ADDRESS | INFLICT_SLEEP_F call CheckLoadedMoveFlag jr nc, .check_paralysis ld a, [wCurCardPlayAreaLocation] @@ -4807,7 +4807,7 @@ Func_16a86: ; 16a86 (5:6a86) call AddToAIScore .check_paralysis - ld a, MOVE_FLAG1_ADDRESS | INFLICT_PARALYSIS + ld a, MOVE_FLAG1_ADDRESS | INFLICT_PARALYSIS_F call CheckLoadedMoveFlag jr nc, .check_confusion ld a, [wCurCardPlayAreaLocation] @@ -4822,7 +4822,7 @@ Func_16a86: ; 16a86 (5:6a86) call SubFromAIScore .check_confusion - ld a, MOVE_FLAG1_ADDRESS | INFLICT_CONFUSION + ld a, MOVE_FLAG1_ADDRESS | INFLICT_CONFUSION_F call CheckLoadedMoveFlag jr nc, .asm_16da0 ld a, [wCurCardPlayAreaLocation] @@ -4849,7 +4849,7 @@ Func_16a86: ; 16a86 (5:6a86) call SubFromAIScore .asm_16db0 - ld a, MOVE_FLAG3_ADDRESS | FLAG_3_BIT_1 + ld a, MOVE_FLAG3_ADDRESS | FLAG_3_BIT_1_F call CheckLoadedMoveFlag jr nc, .done call Func_16dcd -- cgit v1.2.3 From e22f197a411f09fe9ee763a514aadc38f2227ab8 Mon Sep 17 00:00:00 2001 From: ElectroDeoxys Date: Tue, 10 Sep 2019 22:38:44 +0100 Subject: Label Func_16a86 --- src/engine/bank05.asm | 101 +++++++++++++++++++++++++++++--------------------- 1 file changed, 58 insertions(+), 43 deletions(-) (limited to 'src/engine') diff --git a/src/engine/bank05.asm b/src/engine/bank05.asm index ecfc85c..e6599d1 100644 --- a/src/engine/bank05.asm +++ b/src/engine/bank05.asm @@ -4723,7 +4723,7 @@ Func_16a86: ; 16a86 (5:6a86) ld a, MOVE_FLAG1_ADDRESS | DRAW_CARD_F call CheckLoadedMoveFlag jr nc, .check_heal_flag - ld a, $01 + ld a, 1 call AddToAIScore .check_heal_flag @@ -4731,13 +4731,13 @@ Func_16a86: ; 16a86 (5:6a86) call CheckLoadedMoveFlag jr nc, .check_status_effect ld a, [wLoadedMoveUnknown1] - cp $01 - jr z, .asm_16cf8 + cp 1 + jr z, .tally_heal_score ld a, [wCurMoveDamage] call CalculateTensDigit ld b, a ld a, [wLoadedMoveUnknown1] - cp $03 + cp 3 jr z, .asm_16cec srl b jr nc, .asm_16cec @@ -4747,18 +4747,18 @@ Func_16a86: ; 16a86 (5:6a86) call GetTurnDuelistVariable call CalculateTensDigit cp b - jr c, .asm_16cf8 + jr c, .tally_heal_score ld a, b -.asm_16cf8 +.tally_heal_score push af ld e, PLAY_AREA_ARENA call GetCardDamage call CalculateTensDigit pop bc cp b ; wLoadedMoveUnknown1 - jr c, .asm_16d06 + jr c, .add_heal_score ld a, b -.asm_16d06 +.add_heal_score call AddToAIScore .check_status_effect @@ -4770,85 +4770,100 @@ Func_16a86: ; 16a86 (5:6a86) ld a, e ; skip if player has Snorlax cp SNORLAX - jp z, .asm_16db0 + jp z, .handle_flag3_bit1 ld a, DUELVARS_ARENA_CARD_STATUS call GetNonTurnDuelistVariable ld [wCurCardPlayAreaLocation], a +; encourage a poison inflicting move if opposing +; Pokémon isn't (doubly) poisoned already. +; if opposing Pokémon is only poisoned and not +; double poisoned, and this move has FLAG_2_BIT_6 set, +; discourage it (possibly to make Nidoking's Toxic attack +; less likely to be chosen if the other Pokémon is poisoned.) ; check poison ld a, MOVE_FLAG1_ADDRESS | INFLICT_POISON_F call CheckLoadedMoveFlag jr nc, .check_sleep ld a, [wCurCardPlayAreaLocation] - and $c0 - jr z, .asm_16d45 - and $40 + and DOUBLE_POISONED + jr z, .add_poison_score + and $40 ; only double poisoned? jr z, .check_sleep ld a, MOVE_FLAG2_ADDRESS | FLAG_2_BIT_6_F call CheckLoadedMoveFlag jr nc, .check_sleep - ld a, $02 + ld a, 2 call SubFromAIScore jr .check_sleep -.asm_16d45 - ld a, $02 +.add_poison_score + ld a, 2 call AddToAIScore +; encourage sleep-inducing move if other Pokémon isn't asleep. .check_sleep ld a, MOVE_FLAG1_ADDRESS | INFLICT_SLEEP_F call CheckLoadedMoveFlag jr nc, .check_paralysis ld a, [wCurCardPlayAreaLocation] - and $0f - cp $02 + and CNF_SLP_PRZ + cp ASLEEP jr z, .check_paralysis - ld a, $01 + ld a, 1 call AddToAIScore +; encourage paralysis-inducing move if other Pokémon isn't asleep. +; otherwise, if other Pokémon is asleep, discourage move. .check_paralysis ld a, MOVE_FLAG1_ADDRESS | INFLICT_PARALYSIS_F call CheckLoadedMoveFlag jr nc, .check_confusion ld a, [wCurCardPlayAreaLocation] - and $0f - cp $02 - jr z, .asm_16d76 - ld a, $01 + and CNF_SLP_PRZ + cp ASLEEP + jr z, .sub_prz_score + ld a, 1 call AddToAIScore jr .check_confusion -.asm_16d76 - ld a, $01 +.sub_prz_score + ld a, 1 call SubFromAIScore +; encourage confuse-inducing move if other Pokémon +; isn't asleep or confused already +; otherwise, if other Pokémon is asleep or confused, +; discourage move instead. .check_confusion ld a, MOVE_FLAG1_ADDRESS | INFLICT_CONFUSION_F call CheckLoadedMoveFlag - jr nc, .asm_16da0 + jr nc, .check_if_confused ld a, [wCurCardPlayAreaLocation] - and $0f - cp $02 - jr z, .asm_16d9b + and CNF_SLP_PRZ + cp ASLEEP + jr z, .sub_cnf_score ld a, [wCurCardPlayAreaLocation] - and $0f - cp $01 - jr z, .asm_16da0 - ld a, $01 + and CNF_SLP_PRZ + cp CONFUSED + jr z, .check_if_confused + ld a, 1 call AddToAIScore - jr .asm_16da0 -.asm_16d9b - ld a, $01 + jr .check_if_confused +.sub_cnf_score + ld a, 1 call SubFromAIScore -.asm_16da0 - ld a, $f0 + +; if Pokémon is confused, subtract from score. +.check_if_confused + ld a, DUELVARS_ARENA_CARD_STATUS call GetTurnDuelistVariable - and $0f - cp $01 - jr nz, .asm_16db0 - ld a, $01 + and CNF_SLP_PRZ + cp CONFUSED + jr nz, .handle_flag3_bit1 + ld a, 1 call SubFromAIScore -.asm_16db0 +.handle_flag3_bit1 ld a, MOVE_FLAG3_ADDRESS | FLAG_3_BIT_1_F call CheckLoadedMoveFlag jr nc, .done @@ -4858,12 +4873,12 @@ Func_16a86: ; 16a86 (5:6a86) sub $80 call AddToAIScore jr .done - .asm_16dc5 ld b, a ld a, $80 sub b call SubFromAIScore + .done ret ; 0x16dcd -- cgit v1.2.3 From 68e1190a67dcb9b44e63fff454a84ecd0bf5b842 Mon Sep 17 00:00:00 2001 From: ElectroDeoxys Date: Wed, 11 Sep 2019 08:31:12 +0100 Subject: Label HandleSpecialAIMoves and related routines --- src/engine/bank05.asm | 291 +++++++++++++++++++++++++++++++------------------- 1 file changed, 181 insertions(+), 110 deletions(-) (limited to 'src/engine') diff --git a/src/engine/bank05.asm b/src/engine/bank05.asm index e6599d1..5d3d726 100644 --- a/src/engine/bank05.asm +++ b/src/engine/bank05.asm @@ -4867,23 +4867,29 @@ Func_16a86: ; 16a86 (5:6a86) ld a, MOVE_FLAG3_ADDRESS | FLAG_3_BIT_1_F call CheckLoadedMoveFlag jr nc, .done - call Func_16dcd + call HandleSpecialAIMoves cp $80 - jr c, .asm_16dc5 + jr c, .negative_score sub $80 call AddToAIScore jr .done -.asm_16dc5 +.negative_score ld b, a ld a, $80 sub b call SubFromAIScore - + .done ret ; 0x16dcd -Func_16dcd: ; 16dcd (5:6dcd) +; this function handles moves with the FLAG_3_BIT_1 set, +; and makes specific checks in each of these moves +; to either return a positive score (value above $80) +; or a negative score (value below $80). +; input: +; hTempPlayAreaLocation_ff9d = location of card with move. +HandleSpecialAIMoves: ; 16dcd (5:6dcd) ldh a, [hTempPlayAreaLocation_ff9d] add DUELVARS_ARENA_CARD call GetTurnDuelistVariable @@ -4891,238 +4897,281 @@ Func_16dcd: ; 16dcd (5:6dcd) ld a, e cp NIDORANF - jr z, .asm_16e55 + jr z, HandleNidoranFCallForFamily cp ODDISH - jr z, .asm_16e3e + jr z, HandleCallForFamily cp BELLSPROUT - jr z, .asm_16e3e + jr z, HandleCallForFamily cp EXEGGUTOR - jp z, .asm_16ec2 + jp z, HandleExeggcutorTeleport cp SCYTHER - jp z, .asm_16ecb + jp z, HandleSwordsDanceAndFocusEnergy cp KRABBY - jr z, .asm_16e3e + jr z, HandleCallForFamily cp VAPOREON1 - jp z, .asm_16ecb + jp z, HandleSwordsDanceAndFocusEnergy cp ELECTRODE2 - jp z, .asm_16eea + jp z, HandleElectrode2ChainLightning cp MAROWAK1 - jr z, .asm_16e77 + jr z, HandleMarowak1CallForFriend cp MEW3 - jp z, .asm_16f0f + jp z, HandleMew3DevolutionBeam cp JIGGLYPUFF2 - jp z, .asm_16ead + jp z, HandleJigglypuff2FriendshipSong cp PORYGON - jp z, .asm_16f18 + jp z, HandlePorygonConversion cp MEWTWO3 - jp z, .asm_16f41 + jp z, HandleEnergyAbsorption cp MEWTWO2 - jp z, .asm_16f41 + jp z, HandleEnergyAbsorption cp NINETAILS2 - jp z, .asm_16f4e + jp z, HandleNinetalesMixUp cp ZAPDOS3 - jp z, .asm_16fb8 + jp z, HandleZapdos3BigThunder cp KANGASKHAN - jp z, .asm_16fbb + jp z, HandleKangaskhanFetch cp DUGTRIO - jp z, .asm_16fc8 + jp z, HandleDugtrioEarthquake cp ELECTRODE1 - jp z, .asm_16ff2 + jp z, HandleElectrode1EnergySpike cp GOLDUCK - jp z, Func_17005 + jp z, HandleHyperBeam cp DRAGONAIR - jp z, Func_17005 + jp z, HandleHyperBeam -.done +; return zero score. +.zero xor a ret -.asm_16e3e +; if any of card ID in a is found in deck, +; return a score of $80 + slots available in bench. +HandleCallForFamily: ld a, CARD_LOCATION_DECK call CheckIfAnyCardIDinLocation - jr nc, .done + jr nc, HandleSpecialAIMoves.zero ld a, DUELVARS_NUMBER_OF_POKEMON_IN_PLAY_AREA call GetTurnDuelistVariable cp MAX_BENCH_POKEMON - jr nc, .done + jr nc, HandleSpecialAIMoves.zero ld b, a ld a, MAX_BENCH_POKEMON sub b add $80 ret -.asm_16e55 +; if any of NidoranM or NidoranF is found in deck, +; return a score of $80 + slots available in bench. +HandleNidoranFCallForFamily: ld e, NIDORANM ld a, CARD_LOCATION_DECK call CheckIfAnyCardIDinLocation - jr c, .asm_16e67 + jr c, .found ld e, NIDORANF ld a, CARD_LOCATION_DECK call CheckIfAnyCardIDinLocation - jr nc, .done -.asm_16e67 + jr nc, HandleSpecialAIMoves.zero +.found ld a, DUELVARS_NUMBER_OF_POKEMON_IN_PLAY_AREA call GetTurnDuelistVariable cp MAX_PLAY_AREA_POKEMON - jr nc, .done + jr nc, HandleSpecialAIMoves.zero ld b, a ld a, MAX_PLAY_AREA_POKEMON sub b add $80 ret -.asm_16e77 +; checks for certain card IDs of Fighting color in deck. +; if any of them are found, return a score of +; $80 + slots available in bench. +HandleMarowak1CallForFriend ld e, GEODUDE ld a, CARD_LOCATION_DECK call CheckIfAnyCardIDinLocation - jr c, .asm_16e9d + jr c, .found ld e, ONIX ld a, CARD_LOCATION_DECK call CheckIfAnyCardIDinLocation - jr c, .asm_16e9d + jr c, .found ld e, CUBONE ld a, CARD_LOCATION_DECK call CheckIfAnyCardIDinLocation - jr c, .asm_16e9d + jr c, .found ld e, RHYHORN ld a, CARD_LOCATION_DECK call CheckIfAnyCardIDinLocation - jr c, .asm_16e9d - jr .done -.asm_16e9d + jr c, .found + jr HandleSpecialAIMoves.zero +.found ld a, DUELVARS_NUMBER_OF_POKEMON_IN_PLAY_AREA call GetTurnDuelistVariable cp MAX_BENCH_POKEMON - jr nc, .done + jr nc, HandleSpecialAIMoves.zero ld b, a ld a, MAX_BENCH_POKEMON sub b add $80 ret -.asm_16ead: ; 16ead (5:6ead) +; if any basic cards are found in deck, +; return a score of $80 + slots available in bench. +HandleJigglypuff2FriendshipSong: ; 16ead (5:6ead) call CheckIfAnyBasicPokemonInDeck - jr nc, .done + jr nc, HandleSpecialAIMoves.zero ld a, DUELVARS_NUMBER_OF_POKEMON_IN_PLAY_AREA call GetTurnDuelistVariable cp MAX_PLAY_AREA_POKEMON - jr nc, .done + jr nc, HandleSpecialAIMoves.zero ld b, a ld a, MAX_PLAY_AREA_POKEMON sub b add $80 ret -.asm_16ec2: ; 16ec2 (5:6ec2) +; if AI decides to retreat, return a score of $80 + 10. +HandleExeggcutorTeleport: ; 16ec2 (5:6ec2) call AIDecideWhetherToRetreat - jp nc, .done + jp nc, HandleSpecialAIMoves.zero ld a, $8a ret -.asm_16ecb: ; 16ecb (5:6ecb) +; tests for the following conditions: +; - player is under No Damage substatus; +; - second move is unusable; +; - second move deals no damage; +; if any are true, returns score of $80 + 5. +HandleSwordsDanceAndFocusEnergy: ; 16ecb (5:6ecb) ld a, [wcdf0] or a - jr nz, .asm_16ee7 + jr nz, .success ld a, $01 ; second move ld [wSelectedMoveIndex], a call CheckIfSelectedMoveIsUnusable - jr c, .asm_16ee7 + jr c, .success ld a, $01 ; second move call EstimateDamage_VersusDefendingCard ld a, [wDamage] or a - jp nz, .done -.asm_16ee7 + jp nz, HandleSpecialAIMoves.zero +.success ld a, $85 ret -.asm_16eea: ; 16eea (5:6eea) +; checks player's active card color, then +; loops through bench looking for a Pokémon +; with that same color. +; if none are found, returns score of $80 + 2. +HandleElectrode2ChainLightning: ; 16eea (5:6eea) call SwapTurn call GetArenaCardColor call SwapTurn ld b, a ld a, DUELVARS_BENCH call GetTurnDuelistVariable -.asm_16ef9 +.loop ld a, [hli] cp $ff - jr z, .asm_16f0c + jr z, .success push bc call GetCardIDFromDeckIndex call GetCardType pop bc cp b - jr nz, .asm_16ef9 - jp .done -.asm_16f0c + jr nz, .loop + jp HandleSpecialAIMoves.zero +.success ld a, $82 ret -.asm_16f0f: ; 16f0f (5:6f0f) - call Func_17080 - jp nc, .done +HandleMew3DevolutionBeam: ; 16f0f (5:6f0f) + call LookForCardThatIsKnockedOutOnDevolution + jp nc, HandleSpecialAIMoves.zero ld a, $85 ret -.asm_16f18: ; 16f18 (5:6f18) +; first checks if card is confused, and if so return 0. +; then checks number of Pokémon in bench that are viable to use: +; - if that number is < 2 and this move is Conversion 1 OR +; - if that number is >= 2 and this move is Conversion 2 +; then return score of $80 + 2. +; otherwise return score of $80 + 1. +HandlePorygonConversion: ; 16f18 (5:6f18) ld a, DUELVARS_ARENA_CARD_STATUS call GetTurnDuelistVariable and CNF_SLP_PRZ cp CONFUSED - jp z, .done + jp z, HandleSpecialAIMoves.zero + ld a, [wSelectedMoveIndex] or a - jr nz, .asm_16f34 + jr nz, .conversion_2 + +; conversion 1 call CheckIfBenchCardsAreAtHalfHPCanEvolveAndUseSecondMove cp 2 - jr c, .asm_16f3e + jr c, .low_score ld a, $82 ret -.asm_16f34 + +.conversion_2 call CheckIfBenchCardsAreAtHalfHPCanEvolveAndUseSecondMove cp 2 - jr nc, .asm_16f3e + jr nc, .low_score ld a, $82 ret -.asm_16f3e + +.low_score ld a, $81 ret -.asm_16f41: ; 16f41 (5:6f41) +; if any Psychic Energy is found in the Discard Pile, +; return a score of $80 + 2. +HandleEnergyAbsorption: ; 16f41 (5:6f41) ld e, PSYCHIC_ENERGY ld a, CARD_LOCATION_DISCARD_PILE call CheckIfAnyCardIDinLocation - jp nc, .done + jp nc, HandleSpecialAIMoves.zero ld a, $82 ret -.asm_16f4e: ; 16f4e (5:6f4e) +; if player has cards in hand, AI calls Random: +; - 1/3 chance to encourage move regardless; +; - 1/3 chance to dismiss move regardless; +; - 1/3 change to make some checks to player's hand. +; AI tallies number of basic cards in hand, and if this +; number is >= 2, encourage move. +; otherwise, if it finds an evolution card in hand that +; can evolve a card in player's deck, encourage. +; if encouraged, returns a score of $80 + 3. +HandleNinetalesMixUp: ; 16f4e (5:6f4e) ld a, DUELVARS_NUMBER_OF_CARDS_IN_HAND call GetNonTurnDuelistVariable or a - ret z - ld a, $03 + ret z ; return if no hand cards + + ld a, 3 call Random or a - jr z, .asm_16fb5 + jr z, .encourage ; if a = 0 dec a - ret z + ret z ; return if a = 1 call SwapTurn call CreateHandCardList call SwapTurn or a - ret z + ret z ; return if no hand cards (again) ld a, DUELVARS_NUMBER_OF_POKEMON_IN_PLAY_AREA call GetNonTurnDuelistVariable cp 3 - jr nc, .asm_16f9d + jr nc, .check_play_area ld hl, wDuelTempList ld b, 0 -.asm_16f78 +.loop_hand ld a, [hli] cp $ff - jr z, .asm_16f98 + jr z, .tally_basic_cards push bc call SwapTurn call LoadCardDataToBuffer2_FromDeckIndex @@ -5130,93 +5179,108 @@ Func_16dcd: ; 16dcd (5:6dcd) pop bc ld a, [wLoadedCard2Type] cp TYPE_ENERGY - jr nc, .asm_16f78 + jr nc, .loop_hand ld a, [wLoadedCard2Stage] or a - jr nz, .asm_16f78 - inc b - jr .asm_16f78 -.asm_16f98 + jr nz, .loop_hand + ; is a basic Pokémon card + inc b + jr .loop_hand +.tally_basic_cards ld a, b cp 2 - jr nc, .asm_16fb5 -.asm_16f9d + jr nc, .encourage + +; less than 2 basic cards in hand +.check_play_area ld a, DUELVARS_ARENA_CARD call GetNonTurnDuelistVariable -.asm_16fa2 +.loop_play_area ld a, [hli] cp $ff - jp z, .done + jp z, HandleSpecialAIMoves.zero push hl call SwapTurn call CheckForEvolutionInList call SwapTurn pop hl - jr nc, .asm_16fa2 -.asm_16fb5 + jr nc, .loop_play_area + +.encourage ld a, $83 ret -.asm_16fb8: ; 16fb8 (5:6fb8) +; return score of $80 + 3. +HandleZapdos3BigThunder: ; 16fb8 (5:6fb8) ld a, $83 ret -.asm_16fbb: ; 16fbb (5:6fbb) +; dismiss move if cards in deck <= 20. +; otherwise return a score of $80 + 0. +HandleKangaskhanFetch: ; 16fbb (5:6fbb) ld a, DUELVARS_NUMBER_OF_CARDS_NOT_IN_DECK call GetTurnDuelistVariable cp 41 - jp nc, .done + jp nc, HandleSpecialAIMoves.zero ld a, $80 ret -.asm_16fc8: ; 16fc8 (5:6fc8) +; dismiss move if number of own benched cards which would +; be KOd is greater than or equal to the number +; of prize cards left for player. +HandleDugtrioEarthquake: ; 16fc8 (5:6fc8) ld a, DUELVARS_BENCH call GetTurnDuelistVariable lb de, 0, 0 -.asm_16fd0 +.loop inc e ld a, [hli] cp $ff - jr z, .asm_16fe3 + jr z, .count_prizes ld a, e add DUELVARS_ARENA_CARD_HP call GetTurnDuelistVariable cp 20 - jr nc, .asm_16fd0 + jr nc, .loop inc d - jr .asm_16fd0 + jr .loop -.asm_16fe3 +.count_prizes push de call CountPrizes pop de cp d - jp c, .done - jp z, .done + jp c, HandleSpecialAIMoves.zero + jp z, HandleSpecialAIMoves.zero ld a, $80 ret -.asm_16ff2: ; 16ff2 (5:6ff2) +; if there's any lightning energy cards in deck, +; return a score of $80 + 3. +HandleElectrode1EnergySpike: ; 16ff2 (5:6ff2) ld a, CARD_LOCATION_DECK ld e, LIGHTNING_ENERGY call CheckIfAnyCardIDinLocation - jp nc, .done + jp nc, HandleSpecialAIMoves.zero call Func_164a1 - jp nc, .done + jp nc, HandleSpecialAIMoves.zero ld a, $83 ret -Func_17005: ; 17005 (5:7005) +; only incentivize move if player's active card, +; has any energy cards attached, and if so, +; return a score of $80 + 3. +HandleHyperBeam: ; 17005 (5:7005) call SwapTurn ld e, PLAY_AREA_ARENA call CountNumberOfEnergyCardsAttached call SwapTurn or a - jr z, .asm_17016 + jr z, .keep_score ld a, $83 ret -.asm_17016 +.keep_score ld a, $80 ret ; 0x17019 @@ -5256,8 +5320,15 @@ CheckIfAnyBasicPokemonInDeck: ; 17057 (5:7057) ret ; 0x17080 - -Func_17080: ; 17080 (5:7080) +; checks in other Play Area for non-basic cards. +; afterwards, that card is checked for damage, +; and if the damage counters it has is greater than or equal +; to the max HP of the card stage below it, +; return carry and that card's Play Area location in a. +; output: +; a = card location of Pokémon card, if found; +; cerry set if such a card is found. +LookForCardThatIsKnockedOutOnDevolution: ; 17080 (5:7080) ldh a, [hTempPlayAreaLocation_ff9d] push af call SwapTurn -- cgit v1.2.3 From 6cc0384220283a0c7be627fc76dccc7f5320ac70 Mon Sep 17 00:00:00 2001 From: ElectroDeoxys Date: Wed, 11 Sep 2019 12:41:51 +0100 Subject: Disassemble Func_164a1 --- src/engine/bank05.asm | 48 ++++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 40 insertions(+), 8 deletions(-) (limited to 'src/engine') diff --git a/src/engine/bank05.asm b/src/engine/bank05.asm index 5d3d726..e2e1ae0 100644 --- a/src/engine/bank05.asm +++ b/src/engine/bank05.asm @@ -74,7 +74,7 @@ Func_14078: ; 14078 (5:4078) call AIDecideBenchPokemonToSwitchTo call AIChooseEnergyToDiscardForRetreatCost .asm_14091 - call AIDecidePlayEnergyCard + call AIDecidePlayEnergyCardFromHand call Func_169f8 ret c ld a, OPPACTION_FINISH_NO_ATTACK @@ -3778,8 +3778,42 @@ CheckForEvolutionInDeck: ; 16451 (5:6451) Func_16488 ; 16488 (5:6488) INCROM $16488, $164a1 -Func_164a1 ; 164a1 (5:64a1) - INCROM $164a1, $164d3 +; copies wBenchAIScore to wcddd. +; copies AIScore to wcde3. +; decides which card to get energy card. +Func_164a1: ; 164a1 (5:64a1) + ld a, $03 + ld [wcdd8], a + ld de, wcddd + ld hl, wBenchAIScore + ld b, MAX_PLAY_AREA_POKEMON +.loop_play_area + ld a, [hli] + ld [de], a + inc de + dec b + jr nz, .loop_play_area + + ld a, [wAIScore] + ld [de], a + jr AIDecideWhichCardToAttachEnergy + +Func_164ba: ; 164ba (5:64ba) + ld a, $83 + ld [wcdd8], a + ld de, wcddd + ld hl, wBenchAIScore + ld b, MAX_PLAY_AREA_POKEMON +.asm_164c7 + ld a, [hli] + ld [de], a + inc de + dec b + jr nz, .asm_164c7 + + ld a, [wAIScore] + ld [de], a + jr AIDecideWhichCardToAttachEnergy ; copies bench AI score to wcddd ; and loads in wAIscore value in wcde3 @@ -3800,24 +3834,22 @@ Func_164d3: ; 164d3 (5:64d3) ret ; 0x164e8 -AIDecidePlayEnergyCard: ; 164e8 (5:64e8) +AIDecidePlayEnergyCardFromHand: ; 164e8 (5:64e8) xor a ld [wcdd8], a call CreateEnergyCardListFromHand - jr nc, .has_energy + jr nc, AIDecideWhichCardToAttachEnergy ; no energy ld a, [wcdd8] or a jr z, .exit - ; can this even be reached? jp Func_164d3 .exit or a ret -; initialize wcde4 to $80 -.has_energy +AIDecideWhichCardToAttachEnergy: ; 164fc (5:64fc) ld a, $80 ld b, MAX_PLAY_AREA_POKEMON ld hl, wcde4 -- cgit v1.2.3 From 8d40c59f4a63163e0057731f6e8c7244d9ecdb82 Mon Sep 17 00:00:00 2001 From: ElectroDeoxys Date: Wed, 11 Sep 2019 23:49:28 +0100 Subject: Work on DetermineAIScoreOfMoveEnergyRequirement --- src/engine/bank05.asm | 170 ++++++++++++++++++++++++++++++-------------------- 1 file changed, 104 insertions(+), 66 deletions(-) (limited to 'src/engine') diff --git a/src/engine/bank05.asm b/src/engine/bank05.asm index e2e1ae0..dc95a88 100644 --- a/src/engine/bank05.asm +++ b/src/engine/bank05.asm @@ -123,7 +123,7 @@ FindHighestBenchScore: ; 140df (5:40df) ld c, 0 ld e, c ld d, c - ld hl, wBenchAIScore + 1 + ld hl, wPlayAreaAIScore + 1 jp .next .loop @@ -2382,7 +2382,7 @@ AIDecideBenchPokemonToSwitchTo: ; 15b72 (5:5b72) ldh a, [hTempPlayAreaLocation_ff9d] ld c, a ld b, $00 - ld hl, wBenchAIScore + ld hl, wPlayAreaAIScore add hl, bc ld a, [wAIScore] ld [hl], a @@ -2799,10 +2799,10 @@ AIDecideEvolution: ; 15f4c (5:5f4c) push bc jp c, .done_bench_pokemon -; store this Play Area location in wCurCardPlayAreaLocation +; store this Play Area location in wTempAI ; and initialize the AI score ld a, b - ld [wCurCardPlayAreaLocation], a + ld [wTempAI], a ldh [hTempPlayAreaLocation_ff9d], a ld a, 128 ld [wAIScore], a @@ -2877,7 +2877,7 @@ AIDecideEvolution: ; 15f4c (5:5f4c) ld a, [wCurCardCanAttack] or a jr z, .check_defending_can_ko_evolution - ld a, [wCurCardPlayAreaLocation] + ld a, [wTempAI] or a jr nz, .check_defending_can_ko_evolution call CheckIfAnyMoveKnocksOutDefendingCard @@ -2896,7 +2896,7 @@ AIDecideEvolution: ; 15f4c (5:5f4c) ; if defending Pokémon can KO evolution, lower AI score .check_defending_can_ko_evolution - ld a, [wCurCardPlayAreaLocation] + ld a, [wTempAI] or a jr nz, .check_mr_mime xor a @@ -2908,7 +2908,7 @@ AIDecideEvolution: ; 15f4c (5:5f4c) ; if evolution can't damage player's Mr Mime, lower AI score .check_mr_mime - ld a, [wCurCardPlayAreaLocation] + ld a, [wTempAI] call CheckDamageToMrMime jr c, .check_defending_can_ko ld a, 20 @@ -2916,12 +2916,12 @@ AIDecideEvolution: ; 15f4c (5:5f4c) ; if defending Pokémon can KO current card, raise AI score .check_defending_can_ko - ld a, [wCurCardPlayAreaLocation] + ld a, [wTempAI] add DUELVARS_ARENA_CARD call GetTurnDuelistVariable pop af ld [hl], a - ld a, [wCurCardPlayAreaLocation] + ld a, [wTempAI] or a jr nz, .check_2nd_stage_hand xor a @@ -2960,7 +2960,7 @@ AIDecideEvolution: ; 15f4c (5:5f4c) ; decrease AI score proportional to damage ; AI score -= floor(Damage / 40) .check_damage - ld a, [wCurCardPlayAreaLocation] + ld a, [wTempAI] ld e, a call GetCardDamage or a @@ -2974,7 +2974,7 @@ AIDecideEvolution: ; 15f4c (5:5f4c) ; wLoadedCard1Unknown2 is set to $02, ; raise AI score .check_mysterious_fossil - ld a, [wCurCardPlayAreaLocation] + ld a, [wTempAI] add DUELVARS_ARENA_CARD call GetTurnDuelistVariable call LoadCardDataToBuffer1_FromDeckIndex @@ -3015,7 +3015,7 @@ AIDecideEvolution: ; 15f4c (5:5f4c) ld a, [wAIScore] cp 133 jr c, .done_bench_pokemon - ld a, [wCurCardPlayAreaLocation] + ld a, [wTempAI] ldh [hTempPlayAreaLocation_ffa1], a ld a, [wTempAIPokemonCard] ldh [hTemp_ffa0], a @@ -3778,14 +3778,14 @@ CheckForEvolutionInDeck: ; 16451 (5:6451) Func_16488 ; 16488 (5:6488) INCROM $16488, $164a1 -; copies wBenchAIScore to wcddd. +; copies wPlayAreaAIScore to wcddd. ; copies AIScore to wcde3. ; decides which card to get energy card. Func_164a1: ; 164a1 (5:64a1) ld a, $03 ld [wcdd8], a ld de, wcddd - ld hl, wBenchAIScore + ld hl, wPlayAreaAIScore ld b, MAX_PLAY_AREA_POKEMON .loop_play_area ld a, [hli] @@ -3802,7 +3802,7 @@ Func_164ba: ; 164ba (5:64ba) ld a, $83 ld [wcdd8], a ld de, wcddd - ld hl, wBenchAIScore + ld hl, wPlayAreaAIScore ld b, MAX_PLAY_AREA_POKEMON .asm_164c7 ld a, [hli] @@ -3819,7 +3819,7 @@ Func_164ba: ; 164ba (5:64ba) ; and loads in wAIscore value in wcde3 Func_164d3: ; 164d3 (5:64d3) push af - ld de, wBenchAIScore + ld de, wPlayAreaAIScore ld hl, wcddd ld b, MAX_PLAY_AREA_POKEMON .loop @@ -3872,7 +3872,7 @@ AIDecideWhichCardToAttachEnergy: ; 164fc (5:64fc) ld a, $80 ld [wAIScore], a ld a, $ff - ld [wCurCardPlayAreaLocation], a + ld [wTempAI], a ld a, [wcdd8] and $02 jr nz, .check_venusaur @@ -3892,7 +3892,7 @@ AIDecideWhichCardToAttachEnergy: ; 164fc (5:64fc) ld a, [wCurCardCanAttack] call CheckForEvolutionInList jr nc, .no_evolution_in_hand - ld [wCurCardPlayAreaLocation], a + ld [wTempAI], a ld a, 2 call AddToAIScore jr .check_venusaur @@ -4077,17 +4077,20 @@ AIDecideWhichCardToAttachEnergy: ; 164fc (5:64fc) .skip_boss_deck ld a, 1 call AddToAIScore - + +; add AI score for both moves, +; according to their energy requirements. xor a ; first move - call Func_16695 + call DetermineAIScoreOfMoveEnergyRequirement ld a, $01 ; second move - call Func_16695 + call DetermineAIScoreOfMoveEnergyRequirement +; store bench score for this card. .store_score ldh a, [hTempPlayAreaLocation_ff9d] ld c, a ld b, $00 - ld hl, wBenchAIScore + ld hl, wPlayAreaAIScore add hl, bc ld a, [wAIScore] ld [hl], a @@ -4096,6 +4099,8 @@ AIDecideWhichCardToAttachEnergy: ; 164fc (5:64fc) dec c jp nz, .loop_play_area +; the Play Area loop is over and the score +; for each card has been calculated. call Func_167b5 jp nc, Func_1668a @@ -4113,41 +4118,49 @@ AIDecideWhichCardToAttachEnergy: ; 164fc (5:64fc) Func_1668a ; 1668a (5:668a) INCROM $1668a, $16695 -Func_16695: ; 16695 (5:6695) +; checks score related to selected move, +; in order to determine whether to play energy card. +; the AI score is increased/decreased accordingly. +; input: +; [wSelectedMoveIndex] = move to check. +DetermineAIScoreOfMoveEnergyRequirement: ; 16695 (5:6695) ld [wSelectedMoveIndex], a call CheckEnergyNeededForAttack - jp c, .asm_1671e + jp c, .not_enough_energy ld a, MOVE_FLAG2_ADDRESS | ATTACHED_ENERGY_BOOST_F call CheckLoadedMoveFlag - jr c, .asm_166af + jr c, .attached_energy_boost ld a, MOVE_FLAG2_ADDRESS | DISCARD_ENERGY_F call CheckLoadedMoveFlag - jr c, .asm_16710 + jr c, .discard_energy jp .check_evolution -.asm_166af +.attached_energy_boost ld a, [wLoadedMoveUnknown1] cp $02 - jr z, .asm_166bc + jr z, .check_surplus_energy call AddToAIScore jp .check_evolution -.asm_166bc - call Func_171fb +.check_surplus_energy + call CheckIfNoSurplusEnergyForMove jr c, .asm_166cd - cp 3 + cp 3 ; check how much surplus energy jr c, .asm_166cd + .asm_166c5 ld a, 5 call SubFromAIScore jp .check_evolution + .asm_166cd ld a, 2 call AddToAIScore ; check whether move has ATTACHED_ENERGY_BOOST flag ; and add to AI score if attaching another energy -; will KO defending Pokémon +; will KO defending Pokémon. +; add more to score if this is currently active Pokémon. ld a, MOVE_FLAG2_ADDRESS | ATTACHED_ENERGY_BOOST_F call CheckLoadedMoveFlag jp nc, .check_evolution @@ -4165,9 +4178,10 @@ Func_16695: ; 16695 (5:6695) ld a, DUELVARS_ARENA_CARD_HP call GetNonTurnDuelistVariable sub b - jr c, .asm_166ff + jr c, .attaching_kos_player jr nz, .check_evolution -.asm_166ff + +.attaching_kos_player ld a, 20 call AddToAIScore ldh a, [hTempPlayAreaLocation_ff9d] @@ -4177,41 +4191,47 @@ Func_16695: ; 16695 (5:6695) call AddToAIScore jr .check_evolution -; FLAG_2_BIT_5 is set only for Pokémon Powers, -; except for Magnemite2's Magnetic Storm attack -.asm_16710 +; checks if there is surplus energy for move +; that discards attached energy card. +; if current card is Zapdos2, don't add to score. +; if there is no surplus energy, encourage playing energy. +.discard_energy ld a, [wLoadedCard1ID] cp ZAPDOS2 jr z, .check_evolution - call Func_171fb + call CheckIfNoSurplusEnergyForMove jr c, .asm_166cd jr .asm_166c5 -.asm_1671e +.not_enough_energy ld a, MOVE_FLAG2_ADDRESS | FLAG_2_BIT_5_F call CheckLoadedMoveFlag - jr nc, .asm_1672a + jr nc, .check_color_needed ld a, 5 call SubFromAIScore -.asm_1672a +; if the energy card color needed is in hand, increase AI score. +; if a colorless card is needed, increase AI score. +.check_color_needed ld a, b or a - jr z, .asm_1673b + jr z, .check_colorless_needed ld a, e call LookForCardIDInHand - jr c, .asm_1673b + jr c, .check_colorless_needed ld a, 4 call AddToAIScore - jr .asm_16744 -.asm_1673b + jr .check_total_needed +.check_colorless_needed ld a, c or a jr z, .check_evolution ld a, 3 call AddToAIScore -.asm_16744 +; if only one energy card is needed for move, +; encourage playing energy card. +.check_total_needed ld a, b add c dec a @@ -4219,6 +4239,7 @@ Func_16695: ; 16695 (5:6695) ld a, 3 call AddToAIScore +; if the move KOs player and this is the active card, add to AI score. ldh a, [hTempPlayAreaLocation_ff9d] or a jr nz, .check_evolution @@ -4228,11 +4249,18 @@ Func_16695: ; 16695 (5:6695) call GetNonTurnDuelistVariable ld hl, wDamage sub [hl] - jr z, .asm_16766 + jr z, .move_kos_defending jr nc, .check_evolution -.asm_16766 +.move_kos_defending ld a, 20 call AddToAIScore + +; this is possibly a bug. +; this is an identical check as above to test whether this card is active. +; in case it is active, the score gets added 10 more points, +; in addition to the 20 points already added above. +; what was probably intended was to add 20 points in case this card +; is active and only 10 in case it is benched. ldh a, [hTempPlayAreaLocation_ff9d] or a jr nz, .check_evolution @@ -4240,15 +4268,22 @@ Func_16695: ; 16695 (5:6695) call AddToAIScore .check_evolution - ld a, [wCurCardPlayAreaLocation] + ld a, [wTempAI] ; evolution in hand cp $ff ret z + +; temporarily replace this card with evolution in hand. ld b, a ldh a, [hTempPlayAreaLocation_ff9d] add DUELVARS_ARENA_CARD call GetTurnDuelistVariable push af ld [hl], b + +; check for energy still needed for evolution to attack. +; if FLAG_2_BIT_5 is not set, check what color is needed. +; if the energy card color needed is in hand, increase AI score. +; if a colorless card is needed, increase AI score. call CheckEnergyNeededForAttack jr nc, .done ld a, MOVE_FLAG2_ADDRESS | FLAG_2_BIT_5_F @@ -4256,20 +4291,21 @@ Func_16695: ; 16695 (5:6695) jr c, .done ld a, b or a - jr z, .asm_167a2 + jr z, .check_colorless_needed_evo ld a, e call LookForCardIDInHand - jr c, .asm_167a2 + jr c, .check_colorless_needed_evo ld a, 2 call AddToAIScore jr .done -.asm_167a2 +.check_colorless_needed_evo ld a, c or a jr z, .done ld a, 1 call AddToAIScore +; recover the original card in the Play Area location. .done ldh a, [hTempPlayAreaLocation_ff9d] add DUELVARS_ARENA_CARD @@ -4305,11 +4341,11 @@ Func_169f8: ; 169f8 (5:69f8) xor a call Func_16a86 ld a, [wAIScore] - ld [wBenchAIScore], a + ld [wPlayAreaAIScore], a ld a, $01 call Func_16a86 ld c, $01 - ld a, [wBenchAIScore] + ld a, [wPlayAreaAIScore] ld b, a ld a, [wAIScore] cp b @@ -4447,7 +4483,7 @@ Func_16a86: ; 16a86 (5:6a86) xor a ld [wce02], a ld a, [wDamage] - ld [wCurMoveDamage], a + ld [wTempAI], a or a jr z, .no_damage call CalculateTensDigit @@ -4765,7 +4801,7 @@ Func_16a86: ; 16a86 (5:6a86) ld a, [wLoadedMoveUnknown1] cp 1 jr z, .tally_heal_score - ld a, [wCurMoveDamage] + ld a, [wTempAI] call CalculateTensDigit ld b, a ld a, [wLoadedMoveUnknown1] @@ -4806,7 +4842,7 @@ Func_16a86: ; 16a86 (5:6a86) ld a, DUELVARS_ARENA_CARD_STATUS call GetNonTurnDuelistVariable - ld [wCurCardPlayAreaLocation], a + ld [wTempAI], a ; encourage a poison inflicting move if opposing ; Pokémon isn't (doubly) poisoned already. @@ -4818,7 +4854,7 @@ Func_16a86: ; 16a86 (5:6a86) ld a, MOVE_FLAG1_ADDRESS | INFLICT_POISON_F call CheckLoadedMoveFlag jr nc, .check_sleep - ld a, [wCurCardPlayAreaLocation] + ld a, [wTempAI] and DOUBLE_POISONED jr z, .add_poison_score and $40 ; only double poisoned? @@ -4838,7 +4874,7 @@ Func_16a86: ; 16a86 (5:6a86) ld a, MOVE_FLAG1_ADDRESS | INFLICT_SLEEP_F call CheckLoadedMoveFlag jr nc, .check_paralysis - ld a, [wCurCardPlayAreaLocation] + ld a, [wTempAI] and CNF_SLP_PRZ cp ASLEEP jr z, .check_paralysis @@ -4851,7 +4887,7 @@ Func_16a86: ; 16a86 (5:6a86) ld a, MOVE_FLAG1_ADDRESS | INFLICT_PARALYSIS_F call CheckLoadedMoveFlag jr nc, .check_confusion - ld a, [wCurCardPlayAreaLocation] + ld a, [wTempAI] and CNF_SLP_PRZ cp ASLEEP jr z, .sub_prz_score @@ -4870,11 +4906,11 @@ Func_16a86: ; 16a86 (5:6a86) ld a, MOVE_FLAG1_ADDRESS | INFLICT_CONFUSION_F call CheckLoadedMoveFlag jr nc, .check_if_confused - ld a, [wCurCardPlayAreaLocation] + ld a, [wTempAI] and CNF_SLP_PRZ cp ASLEEP jr z, .sub_cnf_score - ld a, [wCurCardPlayAreaLocation] + ld a, [wTempAI] and CNF_SLP_PRZ cp CONFUSED jr z, .check_if_confused @@ -5383,13 +5419,13 @@ LookForCardThatIsKnockedOutOnDevolution: ; 17080 (5:7080) call LoadCardDataToBuffer2_FromDeckIndex pop bc ld a, [wLoadedCard2HP] - ld [wCurMoveDamage], a + ld [wTempAI], a ld e, c push bc call GetCardDamage pop bc ld e, a - ld a, [wCurMoveDamage] + ld a, [wTempAI] cp e jr c, .set_carry jr z, .set_carry @@ -5546,7 +5582,9 @@ Func_17161 ; 17161 (5:7161) ; input: ; [hTempPlayAreaLocation_ff9d] = play area location ; [wSelectedMoveIndex] = move index to check -Func_171fb: ; 171fb (5:71fb) +; output: +; a = number of extra energy cards attached +CheckIfNoSurplusEnergyForMove: ; 171fb (5:71fb) ldh a, [hTempPlayAreaLocation_ff9d] add DUELVARS_ARENA_CARD call GetTurnDuelistVariable @@ -5603,7 +5641,7 @@ Func_171fb: ; 171fb (5:71fb) or a ret nz ; return if surplus energy -; exactly the amount of energy needed + ; exactly the amount of energy needed scf ret ; 0x17258 -- cgit v1.2.3 From 7aa58838576c5588a84f73d89496e1e706a2c38b Mon Sep 17 00:00:00 2001 From: ElectroDeoxys Date: Thu, 12 Sep 2019 00:09:45 +0100 Subject: FindPlayAreaCardWithHighestAIScore --- src/engine/bank05.asm | 82 +++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 79 insertions(+), 3 deletions(-) (limited to 'src/engine') diff --git a/src/engine/bank05.asm b/src/engine/bank05.asm index dc95a88..4e1092a 100644 --- a/src/engine/bank05.asm +++ b/src/engine/bank05.asm @@ -4101,7 +4101,8 @@ AIDecideWhichCardToAttachEnergy: ; 164fc (5:64fc) ; the Play Area loop is over and the score ; for each card has been calculated. - call Func_167b5 +; now to determine the highest score. + call FindPlayAreaCardWithHighestAIScore jp nc, Func_1668a ld a, [wcdd8] @@ -4315,8 +4316,83 @@ DetermineAIScoreOfMoveEnergyRequirement: ; 16695 (5:6695) ret ; 0x167b5 -Func_167b5 ; 167b5 (5:67b5) - INCROM $167b5, $1689f +; returns in hTempPlayAreaLocation_ff9d the Play Area location +; of the card with the highest Play Area AI score, unless +; the highest score is below $85. +; if it succeeds in return a card location, set carry. +FindPlayAreaCardWithHighestAIScore: ; 167b5 (5:67b5) + ld a, [wcdd8] + and $80 + jr nz, .asm_167e1 + + ld a, DUELVARS_NUMBER_OF_POKEMON_IN_PLAY_AREA + call GetTurnDuelistVariable + ld b, a + ld c, 0 ; PLAY_AREA_ARENA + ld e, c + ld d, c + ld hl, wPlayAreaAIScore +; find highest Play Area AI score. +.loop_1 + ld a, [hli] + cp e + jr c, .next_1 + jr z, .next_1 + ld e, a ; overwrite highest score found + ld d, c ; overwrite Play Area of highest score +.next_1 + inc c + dec b + jr nz, .loop_1 + +; if highest AI score is below $85, return no carry. +; else, store Play Area location and return carry. + ld a, e + cp $85 + jr c, .not_enough_score + ld a, d + ldh [hTempPlayAreaLocation_ff9d], a + scf + ret +.not_enough_score + or a + ret + +; same as above but only check bench Pokémon scores. +.asm_167e1 + ld a, DUELVARS_NUMBER_OF_POKEMON_IN_PLAY_AREA + call GetTurnDuelistVariable + dec a + jr z, .no_carry + + ld b, a + ld e, 0 + ld c, PLAY_AREA_BENCH_1 + ld d, c + ld hl, wPlayAreaAIScore + 1 +.loop_2 + ld a, [hli] + cp e + jr c, .next_2 + jr z, .next_2 + ld e, a ; overwrite highest score found + ld d, c ; overwrite Play Area of highest score +.next_2 + inc c + dec b + jr nz, .loop_2 + + ld a, d + ldh [hTempPlayAreaLocation_ff9d], a + scf + ret +.no_carry + or a + ret +; 0x16805 + +Func_16805 ; 16805 (5:6805) + INCROM $16805, $1689f Func_1689f ; 1689f (5:689f) INCROM $1689f, $169e3 -- cgit v1.2.3 From 5646f1bc834dc15f74f28dce9bb43fe250f648b4 Mon Sep 17 00:00:00 2001 From: ElectroDeoxys Date: Thu, 12 Sep 2019 08:46:45 +0100 Subject: Disassemble Func_1689f --- src/engine/bank05.asm | 151 +++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 144 insertions(+), 7 deletions(-) (limited to 'src/engine') diff --git a/src/engine/bank05.asm b/src/engine/bank05.asm index 4e1092a..eeadfda 100644 --- a/src/engine/bank05.asm +++ b/src/engine/bank05.asm @@ -3815,8 +3815,8 @@ Func_164ba: ; 164ba (5:64ba) ld [de], a jr AIDecideWhichCardToAttachEnergy -; copies bench AI score to wcddd -; and loads in wAIscore value in wcde3 +; copies Play Area AI score to wcddd +; and loads wAIscore with value in wcde3. Func_164d3: ; 164d3 (5:64d3) push af ld de, wPlayAreaAIScore @@ -4116,8 +4116,15 @@ AIDecideWhichCardToAttachEnergy: ; 164fc (5:64fc) jp Func_1689f ; 0x1668a -Func_1668a ; 1668a (5:668a) - INCROM $1668a, $16695 +Func_1668a: ; 1668a (5:668a) + ld a, [wcdd8] + or a + jr z, .asm_16693 + jp Func_164d3 +.asm_16693 + or a + ret +; 0x16695 ; checks score related to selected move, ; in order to determine whether to play energy card. @@ -4392,10 +4399,140 @@ FindPlayAreaCardWithHighestAIScore: ; 167b5 (5:67b5) ; 0x16805 Func_16805 ; 16805 (5:6805) - INCROM $16805, $1689f + INCROM $16805, $1683b + +Func_1683b ; 1683b (5:683b) + INCROM $1683b, $1689f + +Func_1689f: ; 1689f (5:689f) + xor a + ld [wTempAI], a + ld [wSelectedMoveIndex], a + call CheckEnergyNeededForAttack + jr nc, .second_move + ld a, b + or a + jr nz, .asm_16902 + ld a, c + or a + jr nz, .asm_16902 + +.second_move + ld a, $01 + ld [wSelectedMoveIndex], a + call CheckEnergyNeededForAttack + jr nc, .asm_168c5 + ld a, b + or a + jr nz, .asm_16902 + ld a, c + or a + jr nz, .asm_16902 + +.asm_168c5 + ld a, $01 + ld [wTempAI], a + xor a ; first attack + ld [wSelectedMoveIndex], a + call CheckEnergyNeededForAttack + ld a, MOVE_FLAG2_ADDRESS | ATTACHED_ENERGY_BOOST_F + call CheckLoadedMoveFlag + jr c, .energy_boost_or_discard_energy + ld a, MOVE_FLAG2_ADDRESS | DISCARD_ENERGY_F + call CheckLoadedMoveFlag + jr c, .energy_boost_or_discard_energy + + ld a, $01 ; second attack + ld [wSelectedMoveIndex], a + call CheckEnergyNeededForAttack + ld a, MOVE_FLAG2_ADDRESS | ATTACHED_ENERGY_BOOST_F + call CheckLoadedMoveFlag + jr c, .energy_boost_or_discard_energy + ld a, MOVE_FLAG2_ADDRESS | DISCARD_ENERGY_F + call CheckLoadedMoveFlag + jr c, .energy_boost_or_discard_energy + call Func_16805 + ret nc + + call CreateEnergyCardListFromHand + jr .asm_16902 + +.energy_boost_or_discard_energy + call Func_1683b + ret nc + +.asm_16902 + call Func_1696e + jr c, .asm_16954 + ld a, b + or a + jr z, .asm_16913 + ld a, e + call LookForCardIDInHand + ldh [hTemp_ffa0], a + jr nc, .asm_16954 +.asm_16913 + ldh a, [hTempPlayAreaLocation_ff9d] + or a + jr nz, .asm_16934 + ld a, c + or a + jr z, .asm_1695f + cp $02 + jr nz, .asm_16934 + ld hl, wDuelTempList +.asm_16923 + ld a, [hli] + cp $ff + jr z, .asm_16934 + ldh [hTemp_ffa0], a + call GetCardIDFromDeckIndex + ld a, e + cp DOUBLE_COLORLESS_ENERGY + jr nz, .asm_16923 + jr .asm_16954 +.asm_16934 + ld hl, wDuelTempList + call CountCardsInDuelTempList + call ShuffleCards +.asm_1693d + ld a, [hli] + cp $ff + jr z, .asm_1695f + call CheckIfOpponentHasBossDeckID + jr nc, .asm_16952 + push af + call GetCardIDFromDeckIndex + ld a, e + cp DOUBLE_COLORLESS_ENERGY + pop bc + jr z, .asm_1693d + ld a, b +.asm_16952 + ldh [hTemp_ffa0], a +.asm_16954 + ldh a, [hTempPlayAreaLocation_ff9d] + ldh [hTempPlayAreaLocation_ffa1], a + ld a, OPPACTION_PLAY_ENERGY + bank1call AIMakeDecision + scf + ret + +.asm_1695f + ld a, [wTempAI] + or a + jr z, .asm_16966 + ret + +.asm_16966 + ld a, [wSelectedMoveIndex] + or a + jp z, .second_move + ret +; 0x1696e -Func_1689f ; 1689f (5:689f) - INCROM $1689f, $169e3 +Func_1696e ; 1696e (5:696e) + INCROM $1696e, $169e3 Func_169e3 ; 169e3 (5:69e3) INCROM $169e3, $169f8 -- cgit v1.2.3 From fe96fdf1a5bf4fc28f44c8c9d257d063f2c9bbaa Mon Sep 17 00:00:00 2001 From: ElectroDeoxys Date: Thu, 12 Sep 2019 08:58:08 +0100 Subject: Document CheckIfEvolutionNeedsEnergyForMove --- src/engine/bank05.asm | 52 +++++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 46 insertions(+), 6 deletions(-) (limited to 'src/engine') diff --git a/src/engine/bank05.asm b/src/engine/bank05.asm index eeadfda..da50053 100644 --- a/src/engine/bank05.asm +++ b/src/engine/bank05.asm @@ -4398,8 +4398,45 @@ FindPlayAreaCardWithHighestAIScore: ; 167b5 (5:67b5) ret ; 0x16805 -Func_16805 ; 16805 (5:6805) - INCROM $16805, $1683b +; returns carry if there's an evolution card +; that can evolve card in hTempPlayAreaLocation_ff9d, +; and that card needs energy to use wSelectedMove. +CheckIfEvolutionNeedsEnergyForMove: ; 16805 (5:6805) + call CreateHandCardList + ldh a, [hTempPlayAreaLocation_ff9d] + add DUELVARS_ARENA_CARD + call GetTurnDuelistVariable + call CheckCardEvolutionInHandOrDeck + jr c, .has_evolution + or a + ret + +.has_evolution + ld b, a + ldh a, [hTempPlayAreaLocation_ff9d] + add DUELVARS_ARENA_CARD + call GetTurnDuelistVariable + push af + ld [hl], b + call CheckEnergyNeededForAttack + jr c, .not_enough_energy + ldh a, [hTempPlayAreaLocation_ff9d] + add DUELVARS_ARENA_CARD + call GetTurnDuelistVariable + pop af + ld [hl], a + or a + ret + +.not_enough_energy + ldh a, [hTempPlayAreaLocation_ff9d] + add DUELVARS_ARENA_CARD + call GetTurnDuelistVariable + pop af + ld [hl], a + scf + ret +; 0x1683b Func_1683b ; 1683b (5:683b) INCROM $1683b, $1689f @@ -4451,7 +4488,7 @@ Func_1689f: ; 1689f (5:689f) ld a, MOVE_FLAG2_ADDRESS | DISCARD_ENERGY_F call CheckLoadedMoveFlag jr c, .energy_boost_or_discard_energy - call Func_16805 + call CheckIfEvolutionNeedsEnergyForMove ret nc call CreateEnergyCardListFromHand @@ -5894,16 +5931,19 @@ CalculateParticularAttachedEnergyNeeded: ; 17258 (5:7258) ; 0x17274 ; return carry if there is a card that -; can evolve a Pokémon in hand or deck +; can evolve a Pokémon in hand or deck. ; input: -; a = deck index of card to check +; a = deck index of card to check; +; output: +; a = deck index of evolution in hand, if found; +; carry set if there's a card in hand that can evolve. CheckCardEvolutionInHandOrDeck: ; 17274 (5:7274) ld b, a ld a, DUELVARS_ARENA_CARD call GetTurnDuelistVariable push af ld [hl], b - ld e, $00 + ld e, 0 .loop ld a, DUELVARS_CARD_LOCATIONS -- cgit v1.2.3 From 3fee428ac58c1619ed7439ac6e1436f0dbd83eb2 Mon Sep 17 00:00:00 2001 From: ElectroDeoxys Date: Thu, 12 Sep 2019 18:58:20 +0100 Subject: Disassemble Func_1683b --- src/engine/bank05.asm | 74 +++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 72 insertions(+), 2 deletions(-) (limited to 'src/engine') diff --git a/src/engine/bank05.asm b/src/engine/bank05.asm index da50053..055764a 100644 --- a/src/engine/bank05.asm +++ b/src/engine/bank05.asm @@ -4438,8 +4438,78 @@ CheckIfEvolutionNeedsEnergyForMove: ; 16805 (5:6805) ret ; 0x1683b -Func_1683b ; 1683b (5:683b) - INCROM $1683b, $1689f +Func_1683b: ; 1683b (5:683b) + ldh a, [hTempPlayAreaLocation_ff9d] + add DUELVARS_ARENA_CARD + call GetTurnDuelistVariable + call LoadCardDataToBuffer2_FromDeckIndex + + ld b, a + ld a, [wSelectedMoveIndex] + or a + jr z, .first_move + +; second move + ld a, b + cp ZAPDOS2 + jr z, .zapdos2 + cp CHARIZARD + jr z, .charizard_or_exeggcutor + cp EXEGGUTOR + jr z, .charizard_or_exeggcutor + ld hl, wLoadedCard2Move2EnergyCost + jr .asm_16861 +.first_move + ld hl, wLoadedCard2Move1EnergyCost + +.asm_16861 + ld a, [hli] + ld b, a + and $f0 + jr z, .asm_1686b + ld e, $02 + jr .set_carry +.asm_1686b + ld a, b + and $0f + jr z, .asm_16874 + ld e, $01 + jr .set_carry +.asm_16874 + ld a, [hli] + ld b, a + and $f0 + jr z, .asm_1687e + ld e, $04 + jr .set_carry +.asm_1687e + ld a, b + and $0f + jr z, .asm_16887 + ld e, $03 + jr .set_carry +.asm_16887 + ld a, [hli] + ld b, a + and $f0 + jr z, .asm_16891 + ld e, $05 + jr .set_carry +.asm_16891 + ld e, $06 + +.set_carry + lb bc, $01, $00 + scf + ret +.zapdos2 + or a + ret +.charizard_or_exeggcutor + lb bc, $00, $01 + scf + ret +; 0x1689f Func_1689f: ; 1689f (5:689f) xor a -- cgit v1.2.3 From 554d0c56848e55607d9809a2ca1821866eef9a2f Mon Sep 17 00:00:00 2001 From: ElectroDeoxys Date: Thu, 12 Sep 2019 23:30:42 +0100 Subject: Document CheckSpecificDecksToAttachDoubleColorless --- src/engine/bank05.asm | 93 +++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 90 insertions(+), 3 deletions(-) (limited to 'src/engine') diff --git a/src/engine/bank05.asm b/src/engine/bank05.asm index 055764a..df20a07 100644 --- a/src/engine/bank05.asm +++ b/src/engine/bank05.asm @@ -4569,7 +4569,7 @@ Func_1689f: ; 1689f (5:689f) ret nc .asm_16902 - call Func_1696e + call CheckSpecificDecksToAttachDoubleColorless jr c, .asm_16954 ld a, b or a @@ -4638,8 +4638,95 @@ Func_1689f: ; 1689f (5:689f) ret ; 0x1696e -Func_1696e ; 1696e (5:696e) - INCROM $1696e, $169e3 +; check if playing certain decks so that AI can decide +; whether to play double colorless to some specific cards. +; these are cards that do not need double colorless +; to any of their moves but are required by their evolutions. +; return carry if there's a double colorless in hand to attach +; and it's one of the card IDs from these decks. +; output: +; [hTemp_ffa0] = card index of double colorless in hand; +; carry set if can play energy card. +CheckSpecificDecksToAttachDoubleColorless: ; 1696e (5:696e) + push bc + push de + push hl + +; check if AI is playing any of the aplicable decks. + ld a, [wOpponentDeckID] + cp LEGENDARY_DRAGONITE_DECK_ID + jr z, .legendary_dragonite_deck + cp FIRE_CHARGE_DECK_ID + jr z, .fire_charge_deck + cp LEGENDARY_RONALD_DECK_ID + jr z, .legendary_ronald_deck + +.no_carry + pop hl + pop de + pop bc + or a + ret + +; if playing Legendary Dragonite deck, +; check for Charmander and Dratini. +.legendary_dragonite_deck + call .get_id + cp CHARMANDER + jr z, .check_colorless_attached + cp DRATINI + jr z, .check_colorless_attached + jr .no_carry + +; if playing Fire Charge deck, +; check for Growlithe. +.fire_charge_deck + call .get_id + cp GROWLITHE + jr z, .check_colorless_attached + jr .no_carry + +; if playing Legendary Ronald deck, +; check for Dratini. +.legendary_ronald_deck + call .get_id + cp DRATINI + jr z, .check_colorless_attached + jr .no_carry + +; check if card has any colorless energy cards attached, +; and if there are any, return no carry. +.check_colorless_attached + ldh a, [hTempPlayAreaLocation_ff9d] + ld e, a + call GetPlayAreaCardAttachedEnergies + ld a, [wAttachedEnergies + COLORLESS] + or a + jr nz, .no_carry + +; card has no colorless energy, so look for double colorless +; in hand and if found, return carry and its card index. + ld a, DOUBLE_COLORLESS_ENERGY + call LookForCardIDInHand + jr c, .no_carry + ldh [hTemp_ffa0], a + pop hl + pop de + pop bc + scf + ret + +.get_id: + ldh a, [hTempPlayAreaLocation_ff9d] + add DUELVARS_ARENA_CARD + call GetTurnDuelistVariable + call GetCardIDFromDeckIndex + ld a, e + ret +; 0x169ca + +Func_169ca ; 169ca (5:69ca) + INCROM $169ca, $169e3 Func_169e3 ; 169e3 (5:69e3) INCROM $169e3, $169f8 -- cgit v1.2.3 From 99edc50a2b740c90792f3580307ba5beb3d748da Mon Sep 17 00:00:00 2001 From: ElectroDeoxys Date: Sat, 14 Sep 2019 00:42:42 +0100 Subject: Finish AITryToPlayEnergyCard --- src/engine/bank05.asm | 215 ++++++++++++++++++++++++++++++++------------------ 1 file changed, 137 insertions(+), 78 deletions(-) (limited to 'src/engine') diff --git a/src/engine/bank05.asm b/src/engine/bank05.asm index df20a07..c02713e 100644 --- a/src/engine/bank05.asm +++ b/src/engine/bank05.asm @@ -341,8 +341,8 @@ CheckIfSelectedMoveIsUnusable: ; 1424b (5:424b) ; [hTempPlayAreaLocation_ff9d] = location of Pokémon card ; [wSelectedMoveIndex] = selected move to examine ; output: -; b = colorless energy still needed -; c = basic energy still needed +; b = basic energy still needed +; c = colorless energy still needed ; e = output of ConvertColorToEnergyCardID, or $0 if not a move ; carry set if no move ; OR if it's a Pokémon Power @@ -3372,12 +3372,12 @@ LookForEnergyNeededInHand: ; 162c8 (5:62c8) cp 1 jr z, .one_energy cp 2 - jr nz, .second_move + jr nz, .second_attack ld a, c cp 2 jr z, .two_colorless -.second_move +.second_attack ld a, $01 ; second move ld [wSelectedMoveIndex], a call CheckEnergyNeededForAttack @@ -4113,7 +4113,7 @@ AIDecideWhichCardToAttachEnergy: ; 164fc (5:64fc) .asm_16684 call CreateEnergyCardListFromHand - jp Func_1689f + jp AITryToPlayEnergyCard ; 0x1668a Func_1668a: ; 1668a (5:668a) @@ -4438,18 +4438,30 @@ CheckIfEvolutionNeedsEnergyForMove: ; 16805 (5:6805) ret ; 0x1683b -Func_1683b: ; 1683b (5:683b) +; returns in e the card ID of the energy required for +; the Discard/Energy Boost attack loaded in wSelectedMoveIndex. +; if it's Zapdos2's Thunderbolt attack, return no carry. +; if it's Charizard's Fire Spin or Exeggutor's Big Eggplosion +; attack, don't return energy card ID, but set carry. +; output: +; b = 1 if needs color energy, 0 otherwise; +; c = 1 if only needs colorless energy, 0 otherwise; +; carry set if not Zapdos2's Thunderbolt attack. +GetEnergyCardForDiscardOrEnergyBoostAttack: ; 1683b (5:683b) +; load card ID and check selected move index. ldh a, [hTempPlayAreaLocation_ff9d] add DUELVARS_ARENA_CARD call GetTurnDuelistVariable call LoadCardDataToBuffer2_FromDeckIndex - ld b, a ld a, [wSelectedMoveIndex] or a - jr z, .first_move + jr z, .first_attack -; second move +; check if second attack is Zapdos2's Thunderbolt, +; Charizard's Fire Spin or Exeggcutor's Big Eggsplosion, +; for these to be treated differently. +; for both attacks, load its energy cost. ld a, b cp ZAPDOS2 jr z, .zapdos2 @@ -4458,87 +4470,108 @@ Func_1683b: ; 1683b (5:683b) cp EXEGGUTOR jr z, .charizard_or_exeggcutor ld hl, wLoadedCard2Move2EnergyCost - jr .asm_16861 -.first_move + jr .fire +.first_attack ld hl, wLoadedCard2Move1EnergyCost -.asm_16861 +; check which energy color the move requires, +; and load in e the card ID of corresponding energy card, +; then return carry flag set. +.fire ld a, [hli] ld b, a and $f0 - jr z, .asm_1686b - ld e, $02 + jr z, .grass + ld e, FIRE_ENERGY jr .set_carry -.asm_1686b +.grass ld a, b and $0f - jr z, .asm_16874 - ld e, $01 + jr z, .lightning + ld e, GRASS_ENERGY jr .set_carry -.asm_16874 +.lightning ld a, [hli] ld b, a and $f0 - jr z, .asm_1687e - ld e, $04 + jr z, .water + ld e, LIGHTNING_ENERGY jr .set_carry -.asm_1687e +.water ld a, b and $0f - jr z, .asm_16887 - ld e, $03 + jr z, .fighting + ld e, WATER_ENERGY jr .set_carry -.asm_16887 +.fighting ld a, [hli] ld b, a and $f0 - jr z, .asm_16891 - ld e, $05 + jr z, .psychic + ld e, FIGHTING_ENERGY jr .set_carry -.asm_16891 - ld e, $06 +.psychic + ld e, PSYCHIC_ENERGY .set_carry lb bc, $01, $00 scf ret + +; for Zapdos2's Thunderbolt attack, return with no carry. .zapdos2 or a ret + +; Charizard's Fire Spin and Exeggcutor's Big Eggsplosion, +; return carry. .charizard_or_exeggcutor lb bc, $00, $01 scf ret ; 0x1689f -Func_1689f: ; 1689f (5:689f) +; called after the AI has decided which card to attach +; energy from hand. AI does checks to determine whether +; this card needs more energy or not, and chooses the +; right energy card to play. If the card is played, +; return with carry flag set. +AITryToPlayEnergyCard: ; 1689f (5:689f) +; check if energy cards are still needed for attacks. +; if first attack doesn't need, test for the second attack. xor a ld [wTempAI], a ld [wSelectedMoveIndex], a call CheckEnergyNeededForAttack - jr nc, .second_move + jr nc, .second_attack ld a, b or a - jr nz, .asm_16902 + jr nz, .check_deck ld a, c or a - jr nz, .asm_16902 + jr nz, .check_deck -.second_move - ld a, $01 +.second_attack + ld a, $01 ; second attack ld [wSelectedMoveIndex], a call CheckEnergyNeededForAttack - jr nc, .asm_168c5 + jr nc, .check_discard_or_energy_boost ld a, b or a - jr nz, .asm_16902 + jr nz, .check_deck ld a, c or a - jr nz, .asm_16902 + jr nz, .check_deck -.asm_168c5 +; neither attack needs energy cards to be used. +; check whether these attacks can be given +; extra energy cards for their effects. +.check_discard_or_energy_boost ld a, $01 ld [wTempAI], a + +; for both attacks, check if it has the effect of +; discarding energy cards or attached energy boost. xor a ; first attack ld [wSelectedMoveIndex], a call CheckEnergyNeededForAttack @@ -4558,66 +4591,90 @@ Func_1689f: ; 1689f (5:689f) ld a, MOVE_FLAG2_ADDRESS | DISCARD_ENERGY_F call CheckLoadedMoveFlag jr c, .energy_boost_or_discard_energy + +; if none of the attacks have those flags, do an additional +; check to ascertain whether evolution card needs energy +; to use second attack. Return if all these checks fail. call CheckIfEvolutionNeedsEnergyForMove ret nc - call CreateEnergyCardListFromHand - jr .asm_16902 + jr .check_deck +; for attacks that discard energy or get boost for +; additional energy cards, get the energy card ID required by move. +; if it's Zapdos2's Thunderbolt move, return. .energy_boost_or_discard_energy - call Func_1683b + call GetEnergyCardForDiscardOrEnergyBoostAttack ret nc -.asm_16902 +; some decks allow basic Pokémon to be given double colorless +; in anticipation for evolution, so play card if that is the case. +.check_deck call CheckSpecificDecksToAttachDoubleColorless - jr c, .asm_16954 + jr c, .play_energy_card + ld a, b or a - jr z, .asm_16913 + jr z, .colorless_energy + +; in this case, Pokémon needs a specific basic energy card. +; look for basic energy card needed in hand and play it. ld a, e call LookForCardIDInHand ldh [hTemp_ffa0], a - jr nc, .asm_16954 -.asm_16913 + jr nc, .play_energy_card + +; in this case Pokémon just needs colorless (any basic energy card). +; if active card, check if it needs 2 colorless. +; if it does (and also doesn't additionally need a color energy), +; look for double colorless card in hand and play it if found. +.colorless_energy ldh a, [hTempPlayAreaLocation_ff9d] or a - jr nz, .asm_16934 + jr nz, .look_for_any_energy ld a, c or a - jr z, .asm_1695f - cp $02 - jr nz, .asm_16934 + jr z, .check_if_done + cp 2 + jr nz, .look_for_any_energy + + ; needs two colorless ld hl, wDuelTempList -.asm_16923 +.loop_1 ld a, [hli] cp $ff - jr z, .asm_16934 + jr z, .look_for_any_energy ldh [hTemp_ffa0], a call GetCardIDFromDeckIndex ld a, e cp DOUBLE_COLORLESS_ENERGY - jr nz, .asm_16923 - jr .asm_16954 -.asm_16934 + jr nz, .loop_1 + jr .play_energy_card + +; otherwise, look for any card and play it. +; if it's a boss deck, only play double colorless in this situation. +.look_for_any_energy ld hl, wDuelTempList call CountCardsInDuelTempList call ShuffleCards -.asm_1693d +.loop_2 ld a, [hli] cp $ff - jr z, .asm_1695f + jr z, .check_if_done call CheckIfOpponentHasBossDeckID - jr nc, .asm_16952 + jr nc, .load_card push af call GetCardIDFromDeckIndex ld a, e cp DOUBLE_COLORLESS_ENERGY pop bc - jr z, .asm_1693d + jr z, .loop_2 ld a, b -.asm_16952 +.load_card ldh [hTemp_ffa0], a -.asm_16954 + +; plays energy card loaded in hTemp_ffa0 and sets carry flag. +.play_energy_card ldh a, [hTempPlayAreaLocation_ff9d] ldh [hTempPlayAreaLocation_ffa1], a ld a, OPPACTION_PLAY_ENERGY @@ -4625,23 +4682,25 @@ Func_1689f: ; 1689f (5:689f) scf ret -.asm_1695f +; wTempAI is 1 if the attack had a Discard/Energy Boost effect, +; and 0 otherwise. If 1, then return. If not one, check if +; there is still a second attack to check. +.check_if_done ld a, [wTempAI] or a - jr z, .asm_16966 + jr z, .check_first_attack ret - -.asm_16966 +.check_first_attack ld a, [wSelectedMoveIndex] or a - jp z, .second_move + jp z, .second_attack ret ; 0x1696e -; check if playing certain decks so that AI can decide -; whether to play double colorless to some specific cards. -; these are cards that do not need double colorless -; to any of their moves but are required by their evolutions. +; check if playing certain decks so that AI can decide whether to play +; double colorless to some specific cards. +; these are cards that do not need double colorless to any of their moves +; but are required by their evolutions. ; return carry if there's a double colorless in hand to attach ; and it's one of the card IDs from these decks. ; output: @@ -5879,12 +5938,12 @@ CheckIfArenaCardIsAtHalfHPCanEvolveAndUseSecondMove: ; 170c9 (5:70c9) ld a, [wLoadedCard1Unknown2] and %00010000 - jr z, .check_second_move + jr z, .check_second_attack ld a, d call CheckCardEvolutionInHandOrDeck jr c, .no_carry -.check_second_move +.check_second_attack xor a ; active card ldh [hTempPlayAreaLocation_ff9d], a ld a, $01 ; second move @@ -5943,7 +6002,7 @@ CheckIfBenchCardsAreAtHalfHPCanEvolveAndUseSecondMove: ; 17101 (5:7101) ld a, [wLoadedCard1Unknown2] and $10 - jr z, .check_second_move + jr z, .check_second_attack ld a, d push bc @@ -5951,7 +6010,7 @@ CheckIfBenchCardsAreAtHalfHPCanEvolveAndUseSecondMove: ; 17101 (5:7101) pop bc jr c, .next -.check_second_move +.check_second_attack ld a, c ldh [hTempPlayAreaLocation_ff9d], a ld a, $01 ; second move @@ -6152,14 +6211,14 @@ CheckIfCanDamageDefendingPokemon: ; 17383 (5:7383) xor a ; first move ld [wSelectedMoveIndex], a call CheckIfSelectedMoveIsUnusable - jr c, .second_move + jr c, .second_attack xor a call EstimateDamage_VersusDefendingCard ld a, [wDamage] or a jr nz, .set_carry -.second_move +.second_attack ld a, $01 ; second move ld [wSelectedMoveIndex], a call CheckIfSelectedMoveIsUnusable @@ -6193,11 +6252,11 @@ CheckIfDefendingPokemonCanKnockOut: ; 173b1 (5:73b1) ld [wce00], a ld [wce01], a call CheckIfDefendingPokemonCanKnockOutWithMove - jr nc, .second_move + jr nc, .second_attack ld a, [wDamage] ld [wce00], a -.second_move +.second_attack ld a, $01 ; second move call CheckIfDefendingPokemonCanKnockOutWithMove jr nc, .return_if_neither_kos -- cgit v1.2.3 From 91306db57f56710872515379b428c5715d99844a Mon Sep 17 00:00:00 2001 From: ElectroDeoxys Date: Sat, 14 Sep 2019 01:10:49 +0100 Subject: Document more GetAIScoreOfMove --- src/engine/bank05.asm | 74 ++++++++++++++++++++++++++++----------------------- 1 file changed, 41 insertions(+), 33 deletions(-) (limited to 'src/engine') diff --git a/src/engine/bank05.asm b/src/engine/bank05.asm index c02713e..1597bea 100644 --- a/src/engine/bank05.asm +++ b/src/engine/bank05.asm @@ -3834,6 +3834,8 @@ Func_164d3: ; 164d3 (5:64d3) ret ; 0x164e8 +; have AI decide whether to play energy card from hand +; and determine which card is best to attach it. AIDecidePlayEnergyCardFromHand: ; 164e8 (5:64e8) xor a ld [wcdd8], a @@ -3849,6 +3851,8 @@ AIDecidePlayEnergyCardFromHand: ; 164e8 (5:64e8) or a ret +; have AI decide whether to play energy card +; and determine which card is best to attach it. AIDecideWhichCardToAttachEnergy: ; 164fc (5:64fc) ld a, $80 ld b, MAX_PLAY_AREA_POKEMON @@ -4103,20 +4107,19 @@ AIDecideWhichCardToAttachEnergy: ; 164fc (5:64fc) ; for each card has been calculated. ; now to determine the highest score. call FindPlayAreaCardWithHighestAIScore - jp nc, Func_1668a + jp nc, .asm_1668a ld a, [wcdd8] or a - jr z, .asm_16684 + jr z, .play_card scf jp Func_164d3 -.asm_16684 +.play_card call CreateEnergyCardListFromHand jp AITryToPlayEnergyCard -; 0x1668a -Func_1668a: ; 1668a (5:668a) +.asm_1668a: ; 1668a (5:668a) ld a, [wcdd8] or a jr z, .asm_16693 @@ -4804,12 +4807,12 @@ Func_169f8: ; 169f8 (5:69f8) ld a, [wcda7] cp $80 jp z, .asm_16a77 - xor a - call Func_16a86 + xor a ; first attack + call GetAIScoreOfAttack ld a, [wAIScore] ld [wPlayAreaAIScore], a - ld a, $01 - call Func_16a86 + ld a, $01 ; second attack + call GetAIScoreOfAttack ld c, $01 ld a, [wPlayAreaAIScore] ld b, a @@ -4871,15 +4874,19 @@ Func_169f8: ; 169f8 (5:69f8) ret ; 0x16a86 -Func_16a86: ; 16a86 (5:6a86) +; determines the AI score of attack in wSelectedMoveIndex. +GetAIScoreOfAttack: ; 16a86 (5:6a86) +; initialize AI score. ld [wSelectedMoveIndex], a ld a, $50 ld [wAIScore], a + xor a ldh [hTempPlayAreaLocation_ff9d], a call CheckIfSelectedMoveIsUnusable jr nc, .usable - + +; return zero AI score. .unusable xor a ld [wAIScore], a @@ -4888,7 +4895,7 @@ Func_16a86: ; 16a86 (5:6a86) ; load arena card IDs .usable xor a - ld [wcdf0], a + ld [wAICannotDamage], a ld a, DUELVARS_ARENA_CARD call GetTurnDuelistVariable call GetCardIDFromDeckIndex @@ -4902,7 +4909,7 @@ Func_16a86: ; 16a86 (5:6a86) ld [wTempNonTurnDuelistCardID], a ; handle the case where the player has No Damage substatus. -; in the case the player does, check if this move is +; in the case the player does, check if this move ; has a residual effect, or if it can damage the opposing bench. ; If none of those are true, render the move unusable. ; also if it's a PKMN power, consider it unusable as well. @@ -4912,7 +4919,7 @@ Func_16a86: ; 16a86 (5:6a86) ; player is under No Damage substatus ld a, $01 - ld [wcdf0], a + ld [wAICannotDamage], a ld a, [wSelectedMoveIndex] call EstimateDamage_VersusDefendingCard ld a, [wLoadedMoveCategory] @@ -4947,7 +4954,7 @@ Func_16a86: ; 16a86 (5:6a86) ; player's bench, and encourage move in case there is. .check_damage xor a - ld [wce02], a + ld [wAIMoveIsNonDamaging], a ld a, [wDamage] ld [wTempAI], a or a @@ -4957,7 +4964,7 @@ Func_16a86: ; 16a86 (5:6a86) jr .check_recoil .no_damage ld a, $01 - ld [wce02], a + ld [wAIMoveIsNonDamaging], a call SubFromAIScore ld a, [wAIMaxDamage] or a @@ -4965,7 +4972,7 @@ Func_16a86: ; 16a86 (5:6a86) ld a, 2 call AddToAIScore xor a - ld [wce02], a + ld [wAIMoveIsNonDamaging], a .no_max_damage ld a, MOVE_FLAG1_ADDRESS | DAMAGE_TO_OPPONENT_BENCH_F call CheckLoadedMoveFlag @@ -5076,7 +5083,7 @@ Func_16a86: ; 16a86 (5:6a86) ; Rock Crusher Deck only uses this move if ; prize count is below 4 and move wins (or potentially draws) the duel, -; (at least gets KOs equal to prize cards left). +; (i.e. at least gets KOs equal to prize cards left). .rock_crusher_deck call CountPrizes cp 4 @@ -5091,7 +5098,7 @@ Func_16a86: ; 16a86 (5:6a86) ; generic checks for all other deck IDs. ; encourage move if it wins (or potentially draws) the duel, -; (at least gets KOs equal to prize cards left). +; (i.e. at least gets KOs equal to prize cards left). ; dismiss it if it causes the player to win. .high_recoil_generic_checks ld a, DUELVARS_ARENA_CARD @@ -5183,8 +5190,8 @@ Func_16a86: ; 16a86 (5:6a86) cp b jr z, .increase_count jr nc, .loop - ; increase d if damage dealt KOs .increase_count + ; increase d if damage dealt KOs inc d jr .loop .exit_loop @@ -5203,7 +5210,7 @@ Func_16a86: ; 16a86 (5:6a86) ret ; if defending card can KO, encourage move -; unless wce02 is non-zero. +; unless move is non-damaging. .check_defending_can_ko ld a, [wSelectedMoveIndex] push af @@ -5214,7 +5221,7 @@ Func_16a86: ; 16a86 (5:6a86) jr nc, .check_discard ld a, 5 call AddToAIScore - ld a, [wce02] + ld a, [wAIMoveIsNonDamaging] or a jr z, .check_discard ld a, 5 @@ -5310,13 +5317,12 @@ Func_16a86: ; 16a86 (5:6a86) call GetNonTurnDuelistVariable ld [wTempAI], a -; encourage a poison inflicting move if opposing -; Pokémon isn't (doubly) poisoned already. -; if opposing Pokémon is only poisoned and not -; double poisoned, and this move has FLAG_2_BIT_6 set, -; discourage it (possibly to make Nidoking's Toxic attack -; less likely to be chosen if the other Pokémon is poisoned.) -; check poison +; encourage a poison inflicting move if opposing Pokémon +; isn't (doubly) poisoned already. +; if opposing Pokémon is only poisoned and not double poisoned, +; and this move has FLAG_2_BIT_6 set, discourage it +; (possibly to make Nidoking's Toxic attack less likely to be chosen +; if the other Pokémon is poisoned.) ld a, MOVE_FLAG1_ADDRESS | INFLICT_POISON_F call CheckLoadedMoveFlag jr nc, .check_sleep @@ -5364,8 +5370,8 @@ Func_16a86: ; 16a86 (5:6a86) ld a, 1 call SubFromAIScore -; encourage confuse-inducing move if other Pokémon -; isn't asleep or confused already +; encourage confuse-inducing move if other Pokémon isn't asleep +; or confused already. ; otherwise, if other Pokémon is asleep or confused, ; discourage move instead. .check_confusion @@ -5387,7 +5393,7 @@ Func_16a86: ; 16a86 (5:6a86) ld a, 1 call SubFromAIScore -; if Pokémon is confused, subtract from score. +; if this Pokémon is confused, subtract from score. .check_if_confused ld a, DUELVARS_ARENA_CARD_STATUS call GetTurnDuelistVariable @@ -5397,6 +5403,8 @@ Func_16a86: ; 16a86 (5:6a86) ld a, 1 call SubFromAIScore +; flag3_bit1 marks moves that the AI handles individually. +; each move has its own checks and modifies AI score accordingly. .handle_flag3_bit1 ld a, MOVE_FLAG3_ADDRESS | FLAG_3_BIT_1_F call CheckLoadedMoveFlag @@ -5576,7 +5584,7 @@ HandleExeggcutorTeleport: ; 16ec2 (5:6ec2) ; - second move deals no damage; ; if any are true, returns score of $80 + 5. HandleSwordsDanceAndFocusEnergy: ; 16ecb (5:6ecb) - ld a, [wcdf0] + ld a, [wAICannotDamage] or a jr nz, .success ld a, $01 ; second move -- cgit v1.2.3 From d0058515037aafdaec05d60af3f2bf3f35147803 Mon Sep 17 00:00:00 2001 From: ElectroDeoxys Date: Sat, 14 Sep 2019 21:02:07 +0100 Subject: Document CheckWhetherToSwitchToFirstAttack --- src/engine/bank05.asm | 93 +++++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 83 insertions(+), 10 deletions(-) (limited to 'src/engine') diff --git a/src/engine/bank05.asm b/src/engine/bank05.asm index 1597bea..44beb8c 100644 --- a/src/engine/bank05.asm +++ b/src/engine/bank05.asm @@ -3817,6 +3817,7 @@ Func_164ba: ; 164ba (5:64ba) ; copies Play Area AI score to wcddd ; and loads wAIscore with value in wcde3. +; identical to Func_169e3. Func_164d3: ; 164d3 (5:64d3) push af ld de, wPlayAreaAIScore @@ -4790,8 +4791,25 @@ CheckSpecificDecksToAttachDoubleColorless: ; 1696e (5:696e) Func_169ca ; 169ca (5:69ca) INCROM $169ca, $169e3 -Func_169e3 ; 169e3 (5:69e3) - INCROM $169e3, $169f8 +; copies Play Area AI score to wcddd +; and loads wAIscore with value in wcde3. +; identical to Func_164d3. +Func_169e3: ; 169e3 (5:69e3) + push af + ld de, wPlayAreaAIScore + ld hl, wcddd + ld b, MAX_PLAY_AREA_POKEMON +.loop + ld a, [hli] + ld [de], a + inc de + dec b + jr nz, .loop + ld a, [hl] + ld [wAIScore], a + pop af + ret +; 0x169f8 Func_169f8: ; 169f8 (5:69f8) xor a @@ -4801,12 +4819,14 @@ Func_169f8: ; 169f8 (5:69f8) jr z, .asm_16a0b ld a, [wcdd6] ld [wSelectedMoveIndex], a - jr .asm_16a3e + jr .first_attack .asm_16a0b ld a, [wcda7] cp $80 jp z, .asm_16a77 + +; determine AI score of both attacks. xor a ; first attack call GetAIScoreOfAttack ld a, [wAIScore] @@ -4819,18 +4839,23 @@ Func_169f8: ; 169f8 (5:69f8) ld a, [wAIScore] cp b jr nc, .asm_16a30 + ; first attack is higher score dec c ld a, b + +; c holds the attack index chosen by AI, +; and a holds its AI score. +; first check if chosen attack has at least minimum score. .asm_16a30 - cp $50 + cp $50 ; minimum score to use attack jr c, .asm_16a77 ld a, c ld [wSelectedMoveIndex], a or a - jr z, .asm_16a3e - call Func_17019 + jr z, .first_attack + call CheckWhetherToSwitchToFirstAttack -.asm_16a3e +.first_attack ld a, [wcdd9] or a jr z, .asm_16a48 @@ -4874,7 +4899,7 @@ Func_169f8: ; 169f8 (5:69f8) ret ; 0x16a86 -; determines the AI score of attack in wSelectedMoveIndex. +; determines the AI score of attack index in a. GetAIScoreOfAttack: ; 16a86 (5:6a86) ; initialize AI score. ld [wSelectedMoveIndex], a @@ -5827,8 +5852,56 @@ HandleHyperBeam: ; 17005 (5:7005) ret ; 0x17019 -Func_17019 ; 17019 (5:7019) - INCROM $17019, $17057 +; called when second attack is determined by AI to have +; more AI score than the first attack, so that it checks +; whether the first attack is a better alternative. +CheckWhetherToSwitchToFirstAttack: ; 17019 (5:7019) +; this checks whether the first attack is also viable +; (has more than minimum score to be used) + ld a, [wPlayAreaAIScore] + cp $50 + jr c, .keep_second_attack + +; first attack has more than minimum score to be used. +; check if second attack can KO. +; in case it can't, the AI keeps it as the attack to be used. +; (possibly due to the assumption that if the +; second attack cannot KO, the first attack can't KO as well.) + xor a + ldh [hTempPlayAreaLocation_ff9d], a + call EstimateDamage_VersusDefendingCard + ld a, DUELVARS_ARENA_CARD_HP + call GetNonTurnDuelistVariable + ld hl, wDamage + sub [hl] + jr z, .check_flag + jr nc, .keep_second_attack + +; second attack can ko, check its flag. +; in case its effect is to heal user or nullify/weaken damage +; next turn, keep second move as the option. +; otherwise switch to the first attack. +.check_flag + ld a, DUELVARS_ARENA_CARD + call GetTurnDuelistVariable + ld d, a + ld e, $01 ; second attack + call CopyMoveDataAndDamage_FromDeckIndex + ld a, MOVE_FLAG2_ADDRESS | HEAL_USER_F + call CheckLoadedMoveFlag + jr c, .keep_second_attack + ld a, MOVE_FLAG2_ADDRESS | NULLIFY_OR_WEAKEN_ATTACK_F + call CheckLoadedMoveFlag + jr c, .keep_second_attack +; switch to first attack + xor a + ld [wSelectedMoveIndex], a + ret +.keep_second_attack + ld a, $01 + ld [wSelectedMoveIndex], a + ret +; 0x17057 ; returns carry if there are ; any basic Pokémon cards in deck. -- cgit v1.2.3 From aafcf7d44b8a69e8d2b6c772ce979d6b75a31676 Mon Sep 17 00:00:00 2001 From: ElectroDeoxys Date: Sun, 15 Sep 2019 09:03:33 +0100 Subject: Work on Func_200e5 --- src/engine/bank05.asm | 3 ++ src/engine/bank08.asm | 82 ++++++++++++++++++++++++++++++--------------------- 2 files changed, 52 insertions(+), 33 deletions(-) (limited to 'src/engine') diff --git a/src/engine/bank05.asm b/src/engine/bank05.asm index 44beb8c..fc54604 100644 --- a/src/engine/bank05.asm +++ b/src/engine/bank05.asm @@ -4846,6 +4846,8 @@ Func_169f8: ; 169f8 (5:69f8) ; c holds the attack index chosen by AI, ; and a holds its AI score. ; first check if chosen attack has at least minimum score. +; then check if first attack is better than second attack +; in case the second one was chosen. .asm_16a30 cp $50 ; minimum score to use attack jr c, .asm_16a77 @@ -4861,6 +4863,7 @@ Func_169f8: ; 169f8 (5:69f8) jr z, .asm_16a48 scf jp Func_169e3 + .asm_16a48 ld a, $0e call Func_14663 diff --git a/src/engine/bank08.asm b/src/engine/bank08.asm index 15ff62a..4d96bff 100644 --- a/src/engine/bank08.asm +++ b/src/engine/bank08.asm @@ -1,80 +1,92 @@ +Data_20000: ; 20000 (8:4000) INCROM $20000, $200e5 ; 0 - e4 is a big set of data, seems to be one entry for each card Func_200e5: ; 200e5 (8:40e5) ld [wce18], a +; create hand list in wDuelTempList and wTempHandCardList. call CreateHandCardList ld hl, wDuelTempList ld de, wTempHandCardList call CopyBuffer ld hl, wTempHandCardList + +.loop_hand ld a, [hli] ld [wce16], a cp $ff ret z + push hl ld a, [wce18] ld d, a - ld hl, $4000 -.asm_4106 + ld hl, Data_20000 +.loop_data xor a ld [wce21], a ld a, [hli] cp $ff - jp z, $41b1 + jp z, .pop_hl + +; compare input to first byte in data and continue if equal. cp d - jp nz, .incHL5 + jp nz, .inc_hl_by_5 ld a, [hli] ld [wce17], a ld a, [wce16] call LoadCardDataToBuffer1_FromDeckIndex - cp $d2 - jr nz, .asm_2012b + cp SWITCH + jr nz, .skip_switch_check + ld b, a ld a, [wce20] - and $2 - jr nz, .incHL4 + and $02 + jr nz, .inc_hl_by_4 ld a, b -.asm_2012b +.skip_switch_check +; compare hand card to second byte in data and continue if equal. ld b, a ld a, [wce17] cp b - jr nz, .incHL4 + jr nz, .inc_hl_by_4 + push hl push de ld a, [wce16] ldh [hTempCardIndex_ff9f], a bank1call CheckCantUseTrainerDueToHeadache - jp c, $41a8 + jp c, .next_in_data call LoadNonPokemonCardEffectCommands - ld a, EFFECTCMDTYPE_INITIAL_EFFECT_1 + ld a, OPPACTION_PLAY_BASIC_PKMN call TryExecuteEffectCommandFunction - jp c, $41a8 - farcall $5, $743b - jr c, .asm_201a8 + jp c, .next_in_data + farcall Func_1743b + jr c, .next_in_data pop de pop hl push hl call CallIndirect pop hl - jr nc, .incHL4 + jr nc, .inc_hl_by_4 inc hl inc hl ld [wce19], a + push de push hl ld a, [wce16] ldh [hTempCardIndex_ff9f], a - ld a, $6 - bank1call $67be + ld a, OPPACTION_PLAY_TRAINER + bank1call AIMakeDecision pop hl pop de - jr c, .incHL2 + jr c, .inc_hl_by_2 push hl call CallIndirect pop hl + inc hl inc hl ld a, [wce20] @@ -83,41 +95,45 @@ Func_200e5: ; 200e5 (8:40e5) or b ld [wce20], a pop hl - and $8 - jp z, $40f7 + and $08 + jp z, .loop_hand + call CreateHandCardList ld hl, wDuelTempList ld de, wTempHandCardList - call $697b + call CopyBuffer ld hl, wTempHandCardList ld a, [wce20] and $f7 ld [wce20], a - jp $40f7 + jp .loop_hand -.incHL5 +.inc_hl_by_5 inc hl - -.incHL4 +.inc_hl_by_4 inc hl inc hl - -.incHL2 +.inc_hl_by_2 inc hl inc hl - jp .asm_4106 + jp .loop_data -.asm_201a8 +.next_in_data pop de pop hl inc hl inc hl inc hl inc hl - jp .asm_4106 -; 0x201b1 + jp .loop_data + +.pop_hl + pop hl + jp .loop_hand +; 0x201b5 - INCROM $201b1, $2297b +Func_201b5: ; 201b5 (8:41b5) + INCROM $201b5, $2297b ; copies $ff terminated buffer from hl to de CopyBuffer: ; 2297b (8:697b) -- cgit v1.2.3 From 5e9ea902efbcae52e02fa221e07f9f8eb7c281eb Mon Sep 17 00:00:00 2001 From: ElectroDeoxys Date: Sun, 15 Sep 2019 09:27:36 +0100 Subject: Disassemble Func_1743b --- src/engine/bank05.asm | 45 +++++++++++++++++++++++++++++++++++++++++++-- src/engine/bank08.asm | 1 + 2 files changed, 44 insertions(+), 2 deletions(-) (limited to 'src/engine') diff --git a/src/engine/bank05.asm b/src/engine/bank05.asm index fc54604..b56c149 100644 --- a/src/engine/bank05.asm +++ b/src/engine/bank05.asm @@ -6444,8 +6444,49 @@ CheckIfNotABossDeckID: ; 17426 (5:7426) ret ; 0x1743b -Func_1743b ; 1743b (5:743b) - INCROM $1743b, $17474 +; probability to return carry: +; - 50% if deck AI is playing is on the list; +; - 25% for all other decks. +Func_1743b: ; 1743b (5:743b) + push hl + push de + call CheckIfNotABossDeckID + jr c, .check_deck + pop de + pop hl + ret + +.check_deck + ld a, [wOpponentDeckID] + cp MUSCLES_FOR_BRAINS_DECK_ID + jr z, .carry_50_percent + cp BLISTERING_POKEMON_DECK_ID + jr z, .carry_50_percent + cp WATERFRONT_POKEMON_DECK_ID + jr z, .carry_50_percent + cp BOOM_BOOM_SELFDESTRUCT_DECK_ID + jr z, .carry_50_percent + cp KALEIDOSCOPE_DECK_ID + jr z, .carry_50_percent + cp RESHUFFLE_DECK_ID + jr z, .carry_50_percent + +; carry 25 percent + ld a, 4 + call Random + cp 1 + pop de + pop hl + ret + +.carry_50_percent + ld a, 4 + call Random + cp 2 + pop de + pop hl + ret +; 0x17474 ; checks if any bench Pokémon has same ID ; as input, and sets carry if it has more than diff --git a/src/engine/bank08.asm b/src/engine/bank08.asm index 4d96bff..12fdb75 100644 --- a/src/engine/bank08.asm +++ b/src/engine/bank08.asm @@ -98,6 +98,7 @@ Func_200e5: ; 200e5 (8:40e5) and $08 jp z, .loop_hand +.asm_20186 ; 20186 (8:4186) call CreateHandCardList ld hl, wDuelTempList ld de, wTempHandCardList -- cgit v1.2.3 From 425ac5aa98085a58dca71a83cad4a250a4b1d822 Mon Sep 17 00:00:00 2001 From: ElectroDeoxys Date: Sun, 15 Sep 2019 11:14:05 +0100 Subject: List out data in bank 8 --- src/engine/bank08.asm | 49 ++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 46 insertions(+), 3 deletions(-) (limited to 'src/engine') diff --git a/src/engine/bank08.asm b/src/engine/bank08.asm index 12fdb75..54262b7 100644 --- a/src/engine/bank08.asm +++ b/src/engine/bank08.asm @@ -1,7 +1,50 @@ -Data_20000: ; 20000 (8:4000) - INCROM $20000, $200e5 +; unknown byte / card ID / function pointer 1 / function pointer 2 +unknown_data_20000: MACRO + db \1, \2 + dw \3 + dw \4 +ENDM -; 0 - e4 is a big set of data, seems to be one entry for each card +Data_20000: ; 20000 (8:4000) + unknown_data_20000 $07, POTION, $41d1, $41b5 + unknown_data_20000 $0a, POTION, $4204, $41b5 + unknown_data_20000 $08, SUPER_POTION, $42cc, $42a8 + unknown_data_20000 $0b, SUPER_POTION, $430f, $42a8 + unknown_data_20000 $0d, DEFENDER, $4406, $43f8 + unknown_data_20000 $0e, DEFENDER, $4486, $43f8 + unknown_data_20000 $0d, PLUSPOWER, $4501, $44e8 + unknown_data_20000 $0e, PLUSPOWER, $45a5, $44e8 + unknown_data_20000 $09, SWITCH, $462e, $4612 + unknown_data_20000 $07, GUST_OF_WIND, $467e, $4666 + unknown_data_20000 $0a, GUST_OF_WIND, $467e, $4666 + unknown_data_20000 $04, BILL, $4878, $486d + unknown_data_20000 $05, ENERGY_REMOVAL, $4895, $4880 + unknown_data_20000 $05, SUPER_ENERGY_REMOVAL, $49bc, $4994 + unknown_data_20000 $07, POKEMON_BREEDER, $4b1b, $4b06 + unknown_data_20000 $0f, PROFESSOR_OAK, $4cc1, $4cae + unknown_data_20000 $0a, ENERGY_RETRIEVAL, $4e6e, $4e44 + unknown_data_20000 $0b, SUPER_ENERGY_RETRIEVAL, $4fc1, $4f80 + unknown_data_20000 $06, POKEMON_CENTER, $50eb, $50e0 + unknown_data_20000 $07, IMPOSTER_PROFESSOR_OAK, $517b, $5170 + unknown_data_20000 $0c, ENERGY_SEARCH, $51aa, $519a + unknown_data_20000 $03, POKEDEX, $52dc, $52b4 + unknown_data_20000 $07, FULL_HEAL, $5428, $541d + unknown_data_20000 $0a, MR_FUJI, $54a7, $5497 + unknown_data_20000 $0a, SCOOP_UP, $5506, $54f1 + unknown_data_20000 $02, MAINTENANCE, $562c, $560f + unknown_data_20000 $03, RECYCLE, $56b8, $569a + unknown_data_20000 $0d, LASS, $5768, $5755 + unknown_data_20000 $04, ITEM_FINDER, $57b1, $578f + unknown_data_20000 $01, IMAKUNI_CARD, $581e, $5813 + unknown_data_20000 $01, GAMBLER, $5875, $582d + unknown_data_20000 $05, REVIVE, $58a9, $5899 + unknown_data_20000 $0d, POKEMON_FLUTE, $58e8, $58d8 + unknown_data_20000 $05, CLEFAIRY_DOLL, $5982, $5977 + unknown_data_20000 $05, MYSTERIOUS_FOSSIL, $5982, $5977 + unknown_data_20000 $02, POKE_BALL, $59c6, $59a6 + unknown_data_20000 $02, COMPUTER_SEARCH, $5b34, $5b12 + unknown_data_20000 $02, POKEMON_TRADER, $5d8f, $5d7a + db $ff Func_200e5: ; 200e5 (8:40e5) ld [wce18], a -- cgit v1.2.3 From bfe775e2bb249eb77d65d97d46dab83cd1a13399 Mon Sep 17 00:00:00 2001 From: ElectroDeoxys Date: Sun, 15 Sep 2019 12:47:16 +0100 Subject: Disassemble bank 8 --- src/engine/bank08.asm | 67 ++++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 64 insertions(+), 3 deletions(-) (limited to 'src/engine') diff --git a/src/engine/bank08.asm b/src/engine/bank08.asm index 54262b7..e247089 100644 --- a/src/engine/bank08.asm +++ b/src/engine/bank08.asm @@ -6,7 +6,7 @@ unknown_data_20000: MACRO ENDM Data_20000: ; 20000 (8:4000) - unknown_data_20000 $07, POTION, $41d1, $41b5 + unknown_data_20000 $07, POTION, Func_201d1, $41b5 unknown_data_20000 $0a, POTION, $4204, $41b5 unknown_data_20000 $08, SUPER_POTION, $42cc, $42a8 unknown_data_20000 $0b, SUPER_POTION, $430f, $42a8 @@ -177,7 +177,49 @@ Func_200e5: ; 200e5 (8:40e5) ; 0x201b5 Func_201b5: ; 201b5 (8:41b5) - INCROM $201b5, $2297b + INCROM $201b5, $201d1 + +Func_201d1: ; 201d1 (8:41d1) + farcall AIDecideWhetherToRetreat + jr c, .no_carry + call Func_22bad + jr c, .no_carry + xor a ; active card + ldh [hTempPlayAreaLocation_ff9d], a + farcall CheckIfDefendingPokemonCanKnockOut + jr nc, .no_carry + ld d, a + + ld a, DUELVARS_ARENA_CARD_HP + call GetTurnDuelistVariable + ld h, a + ld e, PLAY_AREA_ARENA + call GetCardDamage + cp 21 ; if damage <= 20 + jr c, .asm_201f7 + ld a, 20 ; amount of Potion HP healing + +; if damage done by defending Pokémon next turn will still +; KO this card after healing, return no carry. +.asm_201f7 + ld l, a + ld a, h + add l + sub d + jr c, .no_carry + jr z, .no_carry + +; return carry. + xor a + scf + ret +.no_carry + or a + ret +; 0x20204 + +Func_20204: ; 20204 (8:4204) + INCROM $20204, $2297b ; copies $ff terminated buffer from hl to de CopyBuffer: ; 2297b (8:697b) @@ -189,6 +231,7 @@ CopyBuffer: ; 2297b (8:697b) jr CopyBuffer ; 0x22983 +Func_22983: ; 22983 (8:6983) INCROM $22983, $22990 ; counts number of energy cards found in hand @@ -212,4 +255,22 @@ CountEnergyCardsInHand: ; 22990 (8:6990) ; 0x229a3 Func_229a3 ; 229a3 (8:69a3) - INCROM $229a3, $24000 + INCROM $229a3, $22bad + +Func_22bad: ; 22bad (8:6bad) + farcall Func_169ca + ret nc + ld a, [wSelectedMoveIndex] + ld e, a + ld a, DUELVARS_ARENA_CARD + call GetTurnDuelistVariable + ld d, a + call CopyMoveDataAndDamage_FromDeckIndex + ld a, MOVE_FLAG1_ADDRESS | HIGH_RECOIL_F + call CheckLoadedMoveFlag + ccf + ret +; 0x22bc6 + +Func_22bc6 ; 22bc6 (8:6bc6) + INCROM $22bc6, $24000 -- cgit v1.2.3 From 7ceca8371ebcc3bd9db892b8315f23934fa93e45 Mon Sep 17 00:00:00 2001 From: ElectroDeoxys Date: Sun, 15 Sep 2019 20:41:51 +0100 Subject: Disassemble Func_169ca --- src/engine/bank05.asm | 38 ++++++++++++++++++++++++++++---------- 1 file changed, 28 insertions(+), 10 deletions(-) (limited to 'src/engine') diff --git a/src/engine/bank05.asm b/src/engine/bank05.asm index b56c149..18b4217 100644 --- a/src/engine/bank05.asm +++ b/src/engine/bank05.asm @@ -3778,13 +3778,13 @@ CheckForEvolutionInDeck: ; 16451 (5:6451) Func_16488 ; 16488 (5:6488) INCROM $16488, $164a1 -; copies wPlayAreaAIScore to wcddd. +; copies wPlayAreaAIScore to wTempPlayAreaAIScore. ; copies AIScore to wcde3. ; decides which card to get energy card. Func_164a1: ; 164a1 (5:64a1) ld a, $03 ld [wcdd8], a - ld de, wcddd + ld de, wTempPlayAreaAIScore ld hl, wPlayAreaAIScore ld b, MAX_PLAY_AREA_POKEMON .loop_play_area @@ -3801,7 +3801,7 @@ Func_164a1: ; 164a1 (5:64a1) Func_164ba: ; 164ba (5:64ba) ld a, $83 ld [wcdd8], a - ld de, wcddd + ld de, wTempPlayAreaAIScore ld hl, wPlayAreaAIScore ld b, MAX_PLAY_AREA_POKEMON .asm_164c7 @@ -3815,13 +3815,13 @@ Func_164ba: ; 164ba (5:64ba) ld [de], a jr AIDecideWhichCardToAttachEnergy -; copies Play Area AI score to wcddd +; copies Play Area AI score to wTempPlayAreaAIScore ; and loads wAIscore with value in wcde3. ; identical to Func_169e3. Func_164d3: ; 164d3 (5:64d3) push af ld de, wPlayAreaAIScore - ld hl, wcddd + ld hl, wTempPlayAreaAIScore ld b, MAX_PLAY_AREA_POKEMON .loop ld a, [hli] @@ -4788,16 +4788,33 @@ CheckSpecificDecksToAttachDoubleColorless: ; 1696e (5:696e) ret ; 0x169ca -Func_169ca ; 169ca (5:69ca) - INCROM $169ca, $169e3 +Func_169ca: ; 169ca (5:69ca) + ld a, $01 + ld [wcdd9], a + +; copy wPlayAreaAIScore to wTempPlayAreaAIScore. + ld de, wTempPlayAreaAIScore + ld hl, wPlayAreaAIScore + ld b, MAX_PLAY_AREA_POKEMON +.loop + ld a, [hli] + ld [de], a + inc de + dec b + jr nz, .loop + + ld a, [wAIScore] + ld [de], a + jr Func_169f8.asm_169fc -; copies Play Area AI score to wcddd +; copies wPlayAreaAIScore to wTempPlayAreaAIScore ; and loads wAIscore with value in wcde3. ; identical to Func_164d3. +; TODO: reconsider function structure here. Func_169e3: ; 169e3 (5:69e3) push af ld de, wPlayAreaAIScore - ld hl, wcddd + ld hl, wTempPlayAreaAIScore ld b, MAX_PLAY_AREA_POKEMON .loop ld a, [hli] @@ -4814,6 +4831,7 @@ Func_169e3: ; 169e3 (5:69e3) Func_169f8: ; 169f8 (5:69f8) xor a ld [wcdd9], a +.asm_169fc ld a, [wce20] and $01 jr z, .asm_16a0b @@ -4839,7 +4857,7 @@ Func_169f8: ; 169f8 (5:69f8) ld a, [wAIScore] cp b jr nc, .asm_16a30 - ; first attack is higher score + ; first attack has higher score dec c ld a, b -- cgit v1.2.3 From a89c5bd464eee483d7292cd1c1e8349d2fa6beb1 Mon Sep 17 00:00:00 2001 From: ElectroDeoxys Date: Sun, 15 Sep 2019 20:58:04 +0100 Subject: Document AI Potion routines --- src/engine/bank08.asm | 33 +++++++++++++++++++++++++++------ 1 file changed, 27 insertions(+), 6 deletions(-) (limited to 'src/engine') diff --git a/src/engine/bank08.asm b/src/engine/bank08.asm index e247089..37db2c0 100644 --- a/src/engine/bank08.asm +++ b/src/engine/bank08.asm @@ -6,7 +6,7 @@ unknown_data_20000: MACRO ENDM Data_20000: ; 20000 (8:4000) - unknown_data_20000 $07, POTION, Func_201d1, $41b5 + unknown_data_20000 $07, POTION, CheckIfPotionAvoidsGettingKnockedOut, AIPlayPotion unknown_data_20000 $0a, POTION, $4204, $41b5 unknown_data_20000 $08, SUPER_POTION, $42cc, $42a8 unknown_data_20000 $0b, SUPER_POTION, $430f, $42a8 @@ -176,10 +176,30 @@ Func_200e5: ; 200e5 (8:40e5) jp .loop_hand ; 0x201b5 -Func_201b5: ; 201b5 (8:41b5) - INCROM $201b5, $201d1 +; makes AI use potion card. +AIPlayPotion: ; 201b5 (8:41b5) + ld a, [wce16] + ldh [hTempCardIndex_ff9f], a + ld a, [wce19] + ldh [hTemp_ffa0], a + ld e, a + call GetCardDamage + cp 20 + jr c, .play_card + ld a, 20 +.play_card + ldh [hTempPlayAreaLocation_ffa1], a + ld a, OPPACTION_EXECUTE_TRAINER_EFFECTS + bank1call AIMakeDecision + ret +; 0x201d1 -Func_201d1: ; 201d1 (8:41d1) +; if AI doesn't decide to retreat this card, +; check if defending Pokémon can KO active card +; next turn after using Potion. +; if it cannot, return carry. +; also take into account whether move is high recoil for this. +CheckIfPotionAvoidsGettingKnockedOut: ; 201d1 (8:41d1) farcall AIDecideWhetherToRetreat jr c, .no_carry call Func_22bad @@ -196,12 +216,12 @@ Func_201d1: ; 201d1 (8:41d1) ld e, PLAY_AREA_ARENA call GetCardDamage cp 21 ; if damage <= 20 - jr c, .asm_201f7 + jr c, .calculate_hp ld a, 20 ; amount of Potion HP healing ; if damage done by defending Pokémon next turn will still ; KO this card after healing, return no carry. -.asm_201f7 +.calculate_hp ld l, a ld a, h add l @@ -257,6 +277,7 @@ CountEnergyCardsInHand: ; 22990 (8:6990) Func_229a3 ; 229a3 (8:69a3) INCROM $229a3, $22bad +; return carry flag if move is not high recoil. Func_22bad: ; 22bad (8:6bad) farcall Func_169ca ret nc -- cgit v1.2.3 From feb8b16f17a8cd9497ecf124e0f116dd144878d6 Mon Sep 17 00:00:00 2001 From: ElectroDeoxys Date: Sun, 15 Sep 2019 21:51:50 +0100 Subject: Disassemble Func_20204 --- src/engine/bank08.asm | 94 +++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 92 insertions(+), 2 deletions(-) (limited to 'src/engine') diff --git a/src/engine/bank08.asm b/src/engine/bank08.asm index 37db2c0..03916b8 100644 --- a/src/engine/bank08.asm +++ b/src/engine/bank08.asm @@ -215,7 +215,7 @@ CheckIfPotionAvoidsGettingKnockedOut: ; 201d1 (8:41d1) ld h, a ld e, PLAY_AREA_ARENA call GetCardDamage - cp 21 ; if damage <= 20 + cp 20 + 1 ; if damage <= 20 jr c, .calculate_hp ld a, 20 ; amount of Potion HP healing @@ -239,7 +239,97 @@ CheckIfPotionAvoidsGettingKnockedOut: ; 201d1 (8:41d1) ; 0x20204 Func_20204: ; 20204 (8:4204) - INCROM $20204, $2297b + xor a + ldh [hTempPlayAreaLocation_ff9d], a + farcall CheckIfDefendingPokemonCanKnockOut + jr nc, .start_from_active +; can KO + ld d, a + ld a, DUELVARS_ARENA_CARD_HP + call GetTurnDuelistVariable + ld h, a + ld e, $00 + call GetCardDamage + cp 20 + 1 ; if damage <= 20 + jr c, .calculate_hp + ld a, 20 +.calculate_hp + ld l, a + ld a, h + add l + sub d + jr c, .count_prizes + jr z, .count_prizes + or a + ret + +.count_prizes + call SwapTurn + call CountPrizes + call SwapTurn + dec a + jr z, .start_from_active + ld e, PLAY_AREA_BENCH_1 + jr .loop +.start_from_active + ld e, PLAY_AREA_ARENA + +; find Play Area Pokémon with more than 10 damage. +.loop + ld a, DUELVARS_ARENA_CARD + add e + call GetTurnDuelistVariable + cp $ff + ret z + call Func_2027e + jr c, .asm_20250 + call GetCardDamage + cp 20 ; if damage >= 20 + jr nc, .found +.asm_20250 + inc e + jr .loop + +.found + ld a, e + or a + jr z, .active_card + +; not active card + push de + call SwapTurn + call CountPrizes + call SwapTurn + dec a + or a + jr z, .check_random + ld a, 10 + call Random + cp 3 +; 7/10 chance of returning carry. +.check_random + pop de + jr c, .no_carry + ld a, e + scf + ret + +; always return carry for active card. +.active_card + push de + call Func_22bad + pop de + jr c, .no_carry + ld a, e + scf + ret +.no_carry + or a + ret +; 0x2027e + +Func_2027e: ; 2027e (8:427e) + INCROM $2027e, $2297b ; copies $ff terminated buffer from hl to de CopyBuffer: ; 2297b (8:697b) -- cgit v1.2.3 From ae822f8889f486835c7194eead6f3ba0ce7e1da2 Mon Sep 17 00:00:00 2001 From: ElectroDeoxys Date: Mon, 16 Sep 2019 19:28:45 +0100 Subject: More AI Potion routines --- src/engine/bank05.asm | 4 +-- src/engine/bank08.asm | 68 +++++++++++++++++++++++++++++++++++++++------------ 2 files changed, 55 insertions(+), 17 deletions(-) (limited to 'src/engine') diff --git a/src/engine/bank05.asm b/src/engine/bank05.asm index 18b4217..fc398e2 100644 --- a/src/engine/bank05.asm +++ b/src/engine/bank05.asm @@ -3815,7 +3815,7 @@ Func_164ba: ; 164ba (5:64ba) ld [de], a jr AIDecideWhichCardToAttachEnergy -; copies Play Area AI score to wTempPlayAreaAIScore +; copies wTempPlayAreaAIScore to wPlayAreaAIScore ; and loads wAIscore with value in wcde3. ; identical to Func_169e3. Func_164d3: ; 164d3 (5:64d3) @@ -4807,7 +4807,7 @@ Func_169ca: ; 169ca (5:69ca) ld [de], a jr Func_169f8.asm_169fc -; copies wPlayAreaAIScore to wTempPlayAreaAIScore +; copies wTempPlayAreaAIScore to wPlayAreaAIScore ; and loads wAIscore with value in wcde3. ; identical to Func_164d3. ; TODO: reconsider function structure here. diff --git a/src/engine/bank08.asm b/src/engine/bank08.asm index 03916b8..3e34714 100644 --- a/src/engine/bank08.asm +++ b/src/engine/bank08.asm @@ -6,8 +6,8 @@ unknown_data_20000: MACRO ENDM Data_20000: ; 20000 (8:4000) - unknown_data_20000 $07, POTION, CheckIfPotionAvoidsGettingKnockedOut, AIPlayPotion - unknown_data_20000 $0a, POTION, $4204, $41b5 + unknown_data_20000 $07, POTION, CheckIfPotionPreventsKnockOut, AIPlayPotion + unknown_data_20000 $0a, POTION, FindTargetCardForPotion, AIPlayPotion unknown_data_20000 $08, SUPER_POTION, $42cc, $42a8 unknown_data_20000 $0b, SUPER_POTION, $430f, $42a8 unknown_data_20000 $0d, DEFENDER, $4406, $43f8 @@ -102,7 +102,7 @@ Func_200e5: ; 200e5 (8:40e5) bank1call CheckCantUseTrainerDueToHeadache jp c, .next_in_data call LoadNonPokemonCardEffectCommands - ld a, OPPACTION_PLAY_BASIC_PKMN + ld a, EFFECTCMDTYPE_INITIAL_EFFECT_1 call TryExecuteEffectCommandFunction jp c, .next_in_data farcall Func_1743b @@ -198,8 +198,8 @@ AIPlayPotion: ; 201b5 (8:41b5) ; check if defending Pokémon can KO active card ; next turn after using Potion. ; if it cannot, return carry. -; also take into account whether move is high recoil for this. -CheckIfPotionAvoidsGettingKnockedOut: ; 201d1 (8:41d1) +; also take into account whether move is high recoil. +CheckIfPotionPreventsKnockOut: ; 201d1 (8:41d1) farcall AIDecideWhetherToRetreat jr c, .no_carry call Func_22bad @@ -238,7 +238,11 @@ CheckIfPotionAvoidsGettingKnockedOut: ; 201d1 (8:41d1) ret ; 0x20204 -Func_20204: ; 20204 (8:4204) +; finds a card in Play Area to use Potion on. +; output: +; a = card to use Potion on; +; carry set if Potion should be used. +FindTargetCardForPotion: ; 20204 (8:4204) xor a ldh [hTempPlayAreaLocation_ff9d], a farcall CheckIfDefendingPokemonCanKnockOut @@ -248,11 +252,12 @@ Func_20204: ; 20204 (8:4204) ld a, DUELVARS_ARENA_CARD_HP call GetTurnDuelistVariable ld h, a - ld e, $00 + ld e, PLAY_AREA_ARENA call GetCardDamage cp 20 + 1 ; if damage <= 20 jr c, .calculate_hp ld a, 20 +; return if using potion prevents KO. .calculate_hp ld l, a ld a, h @@ -263,6 +268,9 @@ Func_20204: ; 20204 (8:4204) or a ret +; using Potion on active card does not prevent a KO. +; if player is at last prize, start loop with active card. +; otherwise start loop at first bench Pokémon. .count_prizes call SwapTurn call CountPrizes @@ -271,22 +279,23 @@ Func_20204: ; 20204 (8:4204) jr z, .start_from_active ld e, PLAY_AREA_BENCH_1 jr .loop -.start_from_active - ld e, PLAY_AREA_ARENA ; find Play Area Pokémon with more than 10 damage. +; skip Pokémon if it has a BOOST_IF_TAKEN_DAMAGE attack. +.start_from_active + ld e, PLAY_AREA_ARENA .loop ld a, DUELVARS_ARENA_CARD add e call GetTurnDuelistVariable cp $ff ret z - call Func_2027e - jr c, .asm_20250 + call CheckIfEitherAttackHaveBoostIfTakenDamageEffect + jr c, .has_boost_damage call GetCardDamage cp 20 ; if damage >= 20 jr nc, .found -.asm_20250 +.has_boost_damage inc e jr .loop @@ -295,7 +304,7 @@ Func_20204: ; 20204 (8:4204) or a jr z, .active_card -; not active card +; bench card push de call SwapTurn call CountPrizes @@ -328,8 +337,37 @@ Func_20204: ; 20204 (8:4204) ret ; 0x2027e -Func_2027e: ; 2027e (8:427e) - INCROM $2027e, $2297b +; return carry if either of the attacks are usable +; and have the BOOST_IF_TAKEN_DAMAGE effect. +CheckIfEitherAttackHaveBoostIfTakenDamageEffect: ; 2027e (8:427e) + push de + xor a ; first attack + ld [wSelectedMoveIndex], a + farcall CheckIfSelectedMoveIsUnusable + jr c, .second_attack + ld a, MOVE_FLAG3_ADDRESS | BOOST_IF_TAKEN_DAMAGE_F + call CheckLoadedMoveFlag + jr c, .set_carry +.second_attack + ld a, $01 ; second attack + ld [wSelectedMoveIndex], a + farcall CheckIfSelectedMoveIsUnusable + jr c, .no_carry + ld a, MOVE_FLAG3_ADDRESS | BOOST_IF_TAKEN_DAMAGE_F + call CheckLoadedMoveFlag + jr c, .set_carry +.no_carry + pop de + or a + ret +.set_carry + pop de + scf + ret +; 0x202a8 + +Func_202a8: ; 202a8 (8:42a8) + INCROM $202a8, $2297b ; copies $ff terminated buffer from hl to de CopyBuffer: ; 2297b (8:697b) -- cgit v1.2.3 From c1d4866ff3b74f8290689adf798ef512711c2247 Mon Sep 17 00:00:00 2001 From: ElectroDeoxys Date: Mon, 16 Sep 2019 19:47:04 +0100 Subject: Work on AI Super Potion routines --- src/engine/bank08.asm | 89 ++++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 85 insertions(+), 4 deletions(-) (limited to 'src/engine') diff --git a/src/engine/bank08.asm b/src/engine/bank08.asm index 3e34714..461ada6 100644 --- a/src/engine/bank08.asm +++ b/src/engine/bank08.asm @@ -8,7 +8,7 @@ ENDM Data_20000: ; 20000 (8:4000) unknown_data_20000 $07, POTION, CheckIfPotionPreventsKnockOut, AIPlayPotion unknown_data_20000 $0a, POTION, FindTargetCardForPotion, AIPlayPotion - unknown_data_20000 $08, SUPER_POTION, $42cc, $42a8 + unknown_data_20000 $08, SUPER_POTION, CheckIfSuperPotionPreventsKnockOut, $42a8 unknown_data_20000 $0b, SUPER_POTION, $430f, $42a8 unknown_data_20000 $0d, DEFENDER, $4406, $43f8 unknown_data_20000 $0e, DEFENDER, $4486, $43f8 @@ -176,7 +176,7 @@ Func_200e5: ; 200e5 (8:40e5) jp .loop_hand ; 0x201b5 -; makes AI use potion card. +; makes AI use Potion card. AIPlayPotion: ; 201b5 (8:41b5) ld a, [wce16] ldh [hTempCardIndex_ff9f], a @@ -366,8 +366,89 @@ CheckIfEitherAttackHaveBoostIfTakenDamageEffect: ; 2027e (8:427e) ret ; 0x202a8 -Func_202a8: ; 202a8 (8:42a8) - INCROM $202a8, $2297b +; makes AI use Super Potion card. +AIPlaySuperPotion: ; 202a8 (8:42a8) + ld a, [wce16] + ldh [hTempCardIndex_ff9f], a + ld a, [wce19] + ldh [hTempPlayAreaLocation_ffa1], a + call Func_2282e + ldh [hTemp_ffa0], a + ld a, [wce19] + ld e, a + call GetCardDamage + cp 40 + jr c, .play_card + ld a, 40 +.play_card + ldh [hTempRetreatCostCards], a + ld a, OPPACTION_EXECUTE_TRAINER_EFFECTS + bank1call AIMakeDecision + ret +; 0x202cc + +; if AI doesn't decide to retreat this card and card has +; any energy cards attached, check if defending Pokémon can KO +; active card next turn after using Super Potion. +; if it cannot, return carry. +; also take into account whether move is high recoil. +CheckIfSuperPotionPreventsKnockOut: ; 202cc (8:42cc) + farcall AIDecideWhetherToRetreat + jr c, .no_carry + call Func_22bad + jr c, .no_carry + xor a + ldh [hTempPlayAreaLocation_ff9d], a + ld e, a + call CheckIfHasAttachedEnergy + ret nc + farcall CheckIfDefendingPokemonCanKnockOut + jr nc, .no_carry + + ld d, a + ld d, a + ld a, DUELVARS_ARENA_CARD_HP + call GetTurnDuelistVariable + ld h, a + ld e, $00 + call GetCardDamage + cp 40 + 1 ; if damage >= 40 + jr c, .calculate_hp + ld a, 40 +.calculate_hp + ld l, a + ld a, h + add l + sub d + jr c, .no_carry + jr z, .no_carry + +; return carry + ld a, e + scf + ret +.no_carry + or a + ret +; 0x20305 + +; returns carry if card has energies attached. +; input: +; e = location to check, i.e. PLAY_AREA_* +CheckIfHasAttachedEnergy: ; 20305 (8:4305) + call GetPlayAreaCardAttachedEnergies + ld a, [wTotalAttachedEnergies] + or a + ret z + scf + ret +; 0x2030f + +Func_2030f: ; 2030f (8:430f) + INCROM $2030f, $2282e + +Func_2282e: ; 2282e (8:630f) + INCROM $2282e, $2297b ; copies $ff terminated buffer from hl to de CopyBuffer: ; 2297b (8:697b) -- cgit v1.2.3 From d532bce3fee7b3d323f63950022632b972282913 Mon Sep 17 00:00:00 2001 From: ElectroDeoxys Date: Mon, 16 Sep 2019 20:39:01 +0100 Subject: More AI Super Potion routines --- src/engine/bank05.asm | 2 +- src/engine/bank08.asm | 58 ++++++++++++++++++++++++++++++++++++++++++++++++--- 2 files changed, 56 insertions(+), 4 deletions(-) (limited to 'src/engine') diff --git a/src/engine/bank05.asm b/src/engine/bank05.asm index fc398e2..90bb442 100644 --- a/src/engine/bank05.asm +++ b/src/engine/bank05.asm @@ -203,7 +203,7 @@ Func_14145: ; 14145 (5:4145) ; return carry if any of the following is satisfied: ; - deck index in a corresponds to a double colorless energy card; -; - card type in wTempCardType is double colorless energy; +; - card type in wTempCardType is colorless; ; - card ID in wTempCardID is a Pokémon card that has ; moves that require energy other than its color and ; the deck index in a corresponds to that energy type; diff --git a/src/engine/bank08.asm b/src/engine/bank08.asm index 461ada6..e28ea73 100644 --- a/src/engine/bank08.asm +++ b/src/engine/bank08.asm @@ -372,7 +372,7 @@ AIPlaySuperPotion: ; 202a8 (8:42a8) ldh [hTempCardIndex_ff9f], a ld a, [wce19] ldh [hTempPlayAreaLocation_ffa1], a - call Func_2282e + call GetEnergyCardToDiscard ldh [hTemp_ffa0], a ld a, [wce19] ld e, a @@ -447,8 +447,60 @@ CheckIfHasAttachedEnergy: ; 20305 (8:4305) Func_2030f: ; 2030f (8:430f) INCROM $2030f, $2282e -Func_2282e: ; 2282e (8:630f) - INCROM $2282e, $2297b +; returns in a the card index of energy card +; attached to Pokémon in Play Area location a, +; that is to be discarded. +GetEnergyCardToDiscard: ; 2282e (8:682e) +; load Pokémon's attached energy cards. + ldh [hTempPlayAreaLocation_ff9d], a + call CreateArenaOrBenchEnergyCardList + ldh a, [hTempPlayAreaLocation_ff9d] + ld e, a + call GetPlayAreaCardAttachedEnergies + ld a, [wTotalAttachedEnergies] + or a + jr z, .no_energy + +; load card's ID and type. + ldh a, [hTempPlayAreaLocation_ff9d] + ld b, a + ld a, DUELVARS_ARENA_CARD + add b + call GetTurnDuelistVariable + call GetCardIDFromDeckIndex + ld a, e + ld [wTempCardID], a + call LoadCardDataToBuffer1_FromCardID + ld a, [wLoadedCard1Type] + or TYPE_ENERGY + ld [wTempCardType], a + +; find a card that is not useful. +; if none is found, just return the first energy card attached. + ld hl, wDuelTempList +.loop + ld a, [hl] + cp $ff + jr z, .not_found + farcall CheckIfEnergyIsUseful + jr nc, .found + inc hl + jr .loop + +.found + ld a, [hl] + ret +.not_found + ld hl, wDuelTempList + ld a, [hl] + ret +.no_energy + ld a, $ff + ret +; 0x22875 + +Func_22875: ; 22875 (8:6875) + INCROM $22875, $2297b ; copies $ff terminated buffer from hl to de CopyBuffer: ; 2297b (8:697b) -- cgit v1.2.3 From f448efd6d47f98f7b6b12825739b13c3e954c81b Mon Sep 17 00:00:00 2001 From: ElectroDeoxys Date: Mon, 16 Sep 2019 20:51:41 +0100 Subject: Disassemble AIPlaySuperPotion --- src/engine/bank08.asm | 124 +++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 117 insertions(+), 7 deletions(-) (limited to 'src/engine') diff --git a/src/engine/bank08.asm b/src/engine/bank08.asm index e28ea73..d4f6258 100644 --- a/src/engine/bank08.asm +++ b/src/engine/bank08.asm @@ -8,8 +8,8 @@ ENDM Data_20000: ; 20000 (8:4000) unknown_data_20000 $07, POTION, CheckIfPotionPreventsKnockOut, AIPlayPotion unknown_data_20000 $0a, POTION, FindTargetCardForPotion, AIPlayPotion - unknown_data_20000 $08, SUPER_POTION, CheckIfSuperPotionPreventsKnockOut, $42a8 - unknown_data_20000 $0b, SUPER_POTION, $430f, $42a8 + unknown_data_20000 $08, SUPER_POTION, CheckIfSuperPotionPreventsKnockOut, AIPlaySuperPotion + unknown_data_20000 $0b, SUPER_POTION, FindTargetCardForSuperPotion, AIPlaySuperPotion unknown_data_20000 $0d, DEFENDER, $4406, $43f8 unknown_data_20000 $0e, DEFENDER, $4486, $43f8 unknown_data_20000 $0d, PLUSPOWER, $4501, $44e8 @@ -257,7 +257,7 @@ FindTargetCardForPotion: ; 20204 (8:4204) cp 20 + 1 ; if damage <= 20 jr c, .calculate_hp ld a, 20 -; return if using potion prevents KO. +; return if using healing prevents KO. .calculate_hp ld l, a ld a, h @@ -323,7 +323,7 @@ FindTargetCardForPotion: ; 20204 (8:4204) scf ret -; always return carry for active card. +; return carry for active card if not Hgh Recoil. .active_card push de call Func_22bad @@ -412,7 +412,7 @@ CheckIfSuperPotionPreventsKnockOut: ; 202cc (8:42cc) ld h, a ld e, $00 call GetCardDamage - cp 40 + 1 ; if damage >= 40 + cp 40 + 1 ; if damage < 40 jr c, .calculate_hp ld a, 40 .calculate_hp @@ -444,8 +444,118 @@ CheckIfHasAttachedEnergy: ; 20305 (8:4305) ret ; 0x2030f -Func_2030f: ; 2030f (8:430f) - INCROM $2030f, $2282e +; finds a card in Play Area to use Super Potion on. +; output: +; a = card to use Super Potion on; +; carry set if Super Potion should be used. +FindTargetCardForSuperPotion: ; 2030f (8:430f) + xor a + ldh [hTempPlayAreaLocation_ff9d], a + farcall CheckIfDefendingPokemonCanKnockOut + jr nc, .start_from_active +; can KO + ld d, a + ld a, DUELVARS_ARENA_CARD_HP + call GetTurnDuelistVariable + ld h, a + ld e, $00 + call GetCardDamage + cp 40 + 1 ; if damage < 40 + jr c, .calculate_hp + ld a, 40 +; return if using healing prevents KO. +.calculate_hp + ld l, a + ld a, h + add l + sub d + jr c, .count_prizes + jr z, .count_prizes + or a + ret + +; using Super Potion on active card does not prevent a KO. +; if player is at last prize, start loop with active card. +; otherwise start loop at first bench Pokémon. +.count_prizes + call SwapTurn + call CountPrizes + call SwapTurn + dec a + jr z, .start_from_active + ld e, PLAY_AREA_BENCH_1 + jr .loop + +; find Play Area Pokémon with more than 10 damage. +; skip Pokémon if it has a BOOST_IF_TAKEN_DAMAGE attack. +.start_from_active + ld e, PLAY_AREA_ARENA +.loop + ld a, DUELVARS_ARENA_CARD + add e + call GetTurnDuelistVariable + cp $ff + ret z + ld d, a + call Func_20394 + jr nc, .asm_20366 + call Func_2039e + jr c, .asm_20366 + call Func_203c8 + jr c, .asm_20366 + call GetCardDamage + cp 40 ; if damage >= 40 + jr nc, .found +.asm_20366 + inc e + jr .loop + +.found + ld a, e + or a + jr z, .active_card + +; bench card + push de + call SwapTurn + call CountPrizes + call SwapTurn + dec a + or a + jr z, .check_random + ld a, 10 + call Random + cp 3 +; 7/10 chance of returning carry. +.check_random + pop de + jr c, .no_carry + ld a, e + scf + ret + +; return carry for active card if not Hgh Recoil. +.active_card + push de + call Func_22bad + pop de + jr c, .no_carry + ld a, e + scf + ret +.no_carry + or a + ret +; 0x20394 + +Func_20394: ; 20394 (8:4394) + INCROM $20394, $2039e + +Func_2039e: ; 2039e (8:439e) + INCROM $2039e, $203c8 + +Func_203c8: ; 203c8 (8:43c8) + INCROM $203c8, $2282e ; returns in a the card index of energy card ; attached to Pokémon in Play Area location a, -- cgit v1.2.3 From d7de7b06afffc0cc5df4ca82acb918d6f808820b Mon Sep 17 00:00:00 2001 From: ElectroDeoxys Date: Mon, 16 Sep 2019 21:15:28 +0100 Subject: Work on AIPlaySuperPotion --- src/engine/bank08.asm | 67 +++++++++++++++++++++++++++++++++++++-------------- 1 file changed, 49 insertions(+), 18 deletions(-) (limited to 'src/engine') diff --git a/src/engine/bank08.asm b/src/engine/bank08.asm index d4f6258..5dd1a16 100644 --- a/src/engine/bank08.asm +++ b/src/engine/bank08.asm @@ -290,7 +290,7 @@ FindTargetCardForPotion: ; 20204 (8:4204) call GetTurnDuelistVariable cp $ff ret z - call CheckIfEitherAttackHaveBoostIfTakenDamageEffect + call .check_boost_if_taken_damage jr c, .has_boost_damage call GetCardDamage cp 20 ; if damage >= 20 @@ -339,7 +339,7 @@ FindTargetCardForPotion: ; 20204 (8:4204) ; return carry if either of the attacks are usable ; and have the BOOST_IF_TAKEN_DAMAGE effect. -CheckIfEitherAttackHaveBoostIfTakenDamageEffect: ; 2027e (8:427e) +.check_boost_if_taken_damage ; 2027e (8:427e) push de xor a ; first attack ld [wSelectedMoveIndex], a @@ -352,11 +352,11 @@ CheckIfEitherAttackHaveBoostIfTakenDamageEffect: ; 2027e (8:427e) ld a, $01 ; second attack ld [wSelectedMoveIndex], a farcall CheckIfSelectedMoveIsUnusable - jr c, .no_carry + jr c, .false ld a, MOVE_FLAG3_ADDRESS | BOOST_IF_TAKEN_DAMAGE_F call CheckLoadedMoveFlag jr c, .set_carry -.no_carry +.false pop de or a ret @@ -400,7 +400,7 @@ CheckIfSuperPotionPreventsKnockOut: ; 202cc (8:42cc) xor a ldh [hTempPlayAreaLocation_ff9d], a ld e, a - call CheckIfHasAttachedEnergy + call .check_attached_energy ret nc farcall CheckIfDefendingPokemonCanKnockOut jr nc, .no_carry @@ -433,9 +433,7 @@ CheckIfSuperPotionPreventsKnockOut: ; 202cc (8:42cc) ; 0x20305 ; returns carry if card has energies attached. -; input: -; e = location to check, i.e. PLAY_AREA_* -CheckIfHasAttachedEnergy: ; 20305 (8:4305) +.check_attached_energy ; 20305 (8:4305) call GetPlayAreaCardAttachedEnergies ld a, [wTotalAttachedEnergies] or a @@ -497,16 +495,16 @@ FindTargetCardForSuperPotion: ; 2030f (8:430f) cp $ff ret z ld d, a - call Func_20394 - jr nc, .asm_20366 - call Func_2039e - jr c, .asm_20366 + call .check_attached_energy + jr nc, .next + call .check_boost_if_taken_damage + jr c, .next call Func_203c8 - jr c, .asm_20366 + jr c, .next call GetCardDamage cp 40 ; if damage >= 40 jr nc, .found -.asm_20366 +.next inc e jr .loop @@ -548,11 +546,44 @@ FindTargetCardForSuperPotion: ; 2030f (8:430f) ret ; 0x20394 -Func_20394: ; 20394 (8:4394) - INCROM $20394, $2039e +; returns carry if card has energies attached. +.check_attached_energy ; 20394 (8:4394) + call GetPlayAreaCardAttachedEnergies + ld a, [wTotalAttachedEnergies] + or a + ret z + scf + ret +; 0x2039e -Func_2039e: ; 2039e (8:439e) - INCROM $2039e, $203c8 +; return carry if either of the attacks are usable +; and have the BOOST_IF_TAKEN_DAMAGE effect. +.check_boost_if_taken_damage ; 2039e (8:439e) + push de + xor a ; first attack + ld [wSelectedMoveIndex], a + farcall CheckIfSelectedMoveIsUnusable + jr c, .second_attack + ld a, MOVE_FLAG3_ADDRESS | BOOST_IF_TAKEN_DAMAGE_F + call CheckLoadedMoveFlag + jr c, .set_carry +.second_attack + ld a, $01 ; second attack + ld [wSelectedMoveIndex], a + farcall CheckIfSelectedMoveIsUnusable + jr c, .false + ld a, MOVE_FLAG3_ADDRESS | BOOST_IF_TAKEN_DAMAGE_F + call CheckLoadedMoveFlag + jr c, .set_carry +.false + pop de + or a + ret +.set_carry + pop de + scf + ret +; 0x203c8 Func_203c8: ; 203c8 (8:43c8) INCROM $203c8, $2282e -- cgit v1.2.3 From 68e8ba310f724114df5b0e09201e088ede9468b1 Mon Sep 17 00:00:00 2001 From: ElectroDeoxys Date: Mon, 16 Sep 2019 21:28:41 +0100 Subject: Disassemble asm_203c8 --- src/engine/bank05.asm | 1 + src/engine/bank08.asm | 41 ++++++++++++++++++++++++++++++++++++----- 2 files changed, 37 insertions(+), 5 deletions(-) (limited to 'src/engine') diff --git a/src/engine/bank05.asm b/src/engine/bank05.asm index 90bb442..a8f2672 100644 --- a/src/engine/bank05.asm +++ b/src/engine/bank05.asm @@ -1502,6 +1502,7 @@ Func_15649: ; 15649 (5:5649) ret ; 0x156c3 +Func_156c3: ; 156c3 (5:56c3) INCROM $156c3, $1575e ; zeroes a bytes starting at hl diff --git a/src/engine/bank08.asm b/src/engine/bank08.asm index 5dd1a16..98e7cf9 100644 --- a/src/engine/bank08.asm +++ b/src/engine/bank08.asm @@ -499,7 +499,7 @@ FindTargetCardForSuperPotion: ; 2030f (8:430f) jr nc, .next call .check_boost_if_taken_damage jr c, .next - call Func_203c8 + call .asm_203c8 jr c, .next call GetCardDamage cp 40 ; if damage >= 40 @@ -563,11 +563,11 @@ FindTargetCardForSuperPotion: ; 2030f (8:430f) xor a ; first attack ld [wSelectedMoveIndex], a farcall CheckIfSelectedMoveIsUnusable - jr c, .second_attack + jr c, .second_attack_1 ld a, MOVE_FLAG3_ADDRESS | BOOST_IF_TAKEN_DAMAGE_F call CheckLoadedMoveFlag jr c, .set_carry -.second_attack +.second_attack_1 ld a, $01 ; second attack ld [wSelectedMoveIndex], a farcall CheckIfSelectedMoveIsUnusable @@ -585,8 +585,39 @@ FindTargetCardForSuperPotion: ; 2030f (8:430f) ret ; 0x203c8 -Func_203c8: ; 203c8 (8:43c8) - INCROM $203c8, $2282e +.asm_203c8 ; 203c8 (8:43c8) + push de + xor a ; first attack + ld [wSelectedMoveIndex], a + ld a, e + ldh [hTempPlayAreaLocation_ff9d], a + farcall CheckEnergyNeededForAttack + jr c, .second_attack_2 + farcall Func_156c3 + jr c, .asm_203f5 +.second_attack_2 + pop de + push de + ld a, $01 ; second attack + ld [wSelectedMoveIndex], a + ld a, e + ldh [hTempPlayAreaLocation_ff9d], a + farcall CheckEnergyNeededForAttack + jr c, .asm_203f2 + farcall Func_156c3 + jr c, .asm_203f5 +.asm_203f2 + pop de + or a + ret +.asm_203f5 + pop de + scf + ret +; 0x203f8 + +Func_203f8: ; 203f8 (8:43f8) + INCROM $203f8, $2282e ; returns in a the card index of energy card ; attached to Pokémon in Play Area location a, -- cgit v1.2.3 From 706dd0dc1236e7f0fab25fed04c836e5d03e7a2e Mon Sep 17 00:00:00 2001 From: ElectroDeoxys <40245959+ElectroDeoxys@users.noreply.github.com> Date: Mon, 16 Sep 2019 21:29:46 +0100 Subject: Update src/engine/bank01.asm Co-Authored-By: Andrew --- src/engine/bank01.asm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/engine') diff --git a/src/engine/bank01.asm b/src/engine/bank01.asm index 644a6c2..5131025 100644 --- a/src/engine/bank01.asm +++ b/src/engine/bank01.asm @@ -7623,7 +7623,7 @@ PrintThereWasNoEffectFromStatusText: ; 700a (1:700a) ; returns carry if card at hTempPlayAreaLocation_ff9d ; is a basic card. ; otherwise, lists the card indices of all stages in -; in that card location, and returns the card one +; that card location, and returns the card one ; stage below. ; input: ; hTempPlayAreaLocation_ff9d = play area location to check; -- cgit v1.2.3 From fbeee52c8f7e0679b440bc9cb35d335a79f9cfd5 Mon Sep 17 00:00:00 2001 From: ElectroDeoxys Date: Tue, 17 Sep 2019 20:50:02 +0100 Subject: Disassemble CheckEnergyNeededForAttackAfterDiscard --- src/engine/bank05.asm | 134 ++++++++++++++++++++++++++++++++++++++++++++++---- src/engine/bank08.asm | 4 +- 2 files changed, 126 insertions(+), 12 deletions(-) (limited to 'src/engine') diff --git a/src/engine/bank05.asm b/src/engine/bank05.asm index a8f2672..1e734d1 100644 --- a/src/engine/bank05.asm +++ b/src/engine/bank05.asm @@ -358,17 +358,17 @@ CheckEnergyNeededForAttack: ; 14279 (5:4279) ld hl, wLoadedMoveName ld a, [hli] or [hl] - jr z, .no_move + jr z, .no_attack ld a, [wLoadedMoveCategory] cp POKEMON_POWER - jr nz, .is_move -.no_move + jr nz, .is_attack +.no_attack lb bc, 0, 0 ld e, c scf ret -.is_move +.is_attack ldh a, [hTempPlayAreaLocation_ff9d] ld e, a call GetPlayAreaCardAttachedEnergies @@ -673,7 +673,7 @@ EstimateDamage_VersusDefendingCard: ; 143e5 (5:43e5) call CopyMoveDataAndDamage_FromDeckIndex ld a, [wLoadedMoveCategory] cp POKEMON_POWER - jr nz, .is_move + jr nz, .is_attack ; is a Pokémon Power ; set wDamage, wAIMinDamage and wAIMaxDamage to zero @@ -687,7 +687,7 @@ EstimateDamage_VersusDefendingCard: ; 143e5 (5:43e5) ld d, a ret -.is_move +.is_attack ; set wAIMinDamage and wAIMaxDamage to damage of move ; these values take into account the range of damage ; that the move can span (e.g. min and max number of hits) @@ -890,7 +890,7 @@ EstimateDamage_FromDefendingPokemon: ; 1450b (5:450b) call SwapTurn ld a, [wLoadedMoveCategory] cp POKEMON_POWER - jr nz, .is_move + jr nz, .is_attack ; is a Pokémon Power ; set wDamage, wAIMinDamage and wAIMaxDamage to zero @@ -904,7 +904,7 @@ EstimateDamage_FromDefendingPokemon: ; 1450b (5:450b) ld d, a ret -.is_move +.is_attack ; set wAIMinDamage and wAIMaxDamage to damage of move ; these values take into account the range of damage ; that the move can span (e.g. min and max number of hits) @@ -1502,8 +1502,122 @@ Func_15649: ; 15649 (5:5649) ret ; 0x156c3 -Func_156c3: ; 156c3 (5:56c3) - INCROM $156c3, $1575e +; load selected move from Pokémon in hTempPlayAreaLocation_ff9d, +; gets an energy card to discard and subsequently +; check if there is enough energy to execute the selected move +; after removing that attached energy card. +; input: +; [hTempPlayAreaLocation_ff9d] = location of Pokémon card +; [wSelectedMoveIndex] = selected move to examine +; output: +; b = basic energy still needed +; c = colorless energy still needed +; e = output of ConvertColorToEnergyCardID, or $0 if not a move +; carry set if no move +; OR if it's a Pokémon Power +; OR if not enough energy for move +CheckEnergyNeededForAttackAfterDiscard: ; 156c3 (5:56c3) + ldh a, [hTempPlayAreaLocation_ff9d] + add DUELVARS_ARENA_CARD + call GetTurnDuelistVariable + ld d, a + ld a, [wSelectedMoveIndex] + ld e, a + call CopyMoveDataAndDamage_FromDeckIndex + ld hl, wLoadedMoveName + ld a, [hli] + or [hl] + jr z, .no_attack + ld a, [wLoadedMoveCategory] + cp POKEMON_POWER + jr nz, .is_attack +.no_attack + lb bc, 0, 0 + ld e, c + scf + ret + +.is_attack + ldh a, [hTempPlayAreaLocation_ff9d] + farcall GetEnergyCardToDiscard + call LoadCardDataToBuffer1_FromDeckIndex + cp DOUBLE_COLORLESS_ENERGY + jr z, .colorless + +; color energy +; decrease respective attached energy by 1. + ld hl, wAttachedEnergies + dec a + ld c, a + ld b, $00 + add hl, bc + dec [hl] + ld hl, wTotalAttachedEnergies + dec [hl] + jr .asm_1570c +; decrease attached colorless by 2. +.colorless + ld hl, wAttachedEnergies + COLORLESS + dec [hl] + dec [hl] + ld hl, wTotalAttachedEnergies + dec [hl] + dec [hl] + +.asm_1570c + bank1call HandleEnergyBurn + xor a + ld [wTempLoadedMoveEnergyCost], a + ld [wTempLoadedMoveEnergyNeededAmount], a + ld [wTempLoadedMoveEnergyNeededType], a + ld hl, wAttachedEnergies + ld de, wLoadedMoveEnergyCost + ld b, 0 + ld c, (NUM_TYPES / 2) - 1 +.loop + ; check all basic energy cards except colorless + ld a, [de] + swap a + call CheckIfEnoughParticularAttachedEnergy + ld a, [de] + call CheckIfEnoughParticularAttachedEnergy + inc de + dec c + jr nz, .loop + + ld a, [de] + swap a + and $0f + ld b, a ; colorless energy still needed + ld a, [wTempLoadedMoveEnergyCost] + ld hl, wTempLoadedMoveEnergyNeededAmount + sub [hl] + ld c, a ; basic energy still needed + ld a, [wTotalAttachedEnergies] + sub c + sub b + jr c, .not_enough_energy + + ld a, [wTempLoadedMoveEnergyNeededAmount] + or a + ret z + +; being here means the energy cost isn't satisfied, +; including with colorless energy + xor a +.not_enough_energy + cpl + inc a + ld c, a ; colorless energy still needed + ld a, [wTempLoadedMoveEnergyNeededAmount] + ld b, a ; basic energy still needed + ld a, [wTempLoadedMoveEnergyNeededType] + call ConvertColorToEnergyCardID + ld e, a + ld d, 0 + scf + ret +; 0x1575e ; zeroes a bytes starting at hl ZeroData: ; 1575e (5:575e) diff --git a/src/engine/bank08.asm b/src/engine/bank08.asm index 98e7cf9..d736f0e 100644 --- a/src/engine/bank08.asm +++ b/src/engine/bank08.asm @@ -593,7 +593,7 @@ FindTargetCardForSuperPotion: ; 2030f (8:430f) ldh [hTempPlayAreaLocation_ff9d], a farcall CheckEnergyNeededForAttack jr c, .second_attack_2 - farcall Func_156c3 + farcall CheckEnergyNeededForAttackAfterDiscard jr c, .asm_203f5 .second_attack_2 pop de @@ -604,7 +604,7 @@ FindTargetCardForSuperPotion: ; 2030f (8:430f) ldh [hTempPlayAreaLocation_ff9d], a farcall CheckEnergyNeededForAttack jr c, .asm_203f2 - farcall Func_156c3 + farcall CheckEnergyNeededForAttackAfterDiscard jr c, .asm_203f5 .asm_203f2 pop de -- cgit v1.2.3 From 1c5df17ca0ea2db1b1bce6fede09fffae3c8c986 Mon Sep 17 00:00:00 2001 From: ElectroDeoxys Date: Wed, 18 Sep 2019 18:54:20 +0100 Subject: Document AIPlaySuperPotion helper routines --- src/engine/bank08.asm | 36 ++++++++++++++++++++++-------------- 1 file changed, 22 insertions(+), 14 deletions(-) (limited to 'src/engine') diff --git a/src/engine/bank08.asm b/src/engine/bank08.asm index d736f0e..e759733 100644 --- a/src/engine/bank08.asm +++ b/src/engine/bank08.asm @@ -299,6 +299,7 @@ FindTargetCardForPotion: ; 20204 (8:4204) inc e jr .loop +; a card was found, now to check if it's active or benched. .found ld a, e or a @@ -484,8 +485,10 @@ FindTargetCardForSuperPotion: ; 2030f (8:430f) ld e, PLAY_AREA_BENCH_1 jr .loop -; find Play Area Pokémon with more than 10 damage. -; skip Pokémon if it has a BOOST_IF_TAKEN_DAMAGE attack. +; find Play Area Pokémon with more than 30 damage. +; skip Pokémon if it doesn't have any energy attached, +; has a BOOST_IF_TAKEN_DAMAGE attack, +; or if discarding makes any attack of its attacks unusable. .start_from_active ld e, PLAY_AREA_ARENA .loop @@ -499,7 +502,7 @@ FindTargetCardForSuperPotion: ; 2030f (8:430f) jr nc, .next call .check_boost_if_taken_damage jr c, .next - call .asm_203c8 + call .check_energy_cost jr c, .next call GetCardDamage cp 40 ; if damage >= 40 @@ -508,6 +511,7 @@ FindTargetCardForSuperPotion: ; 2030f (8:430f) inc e jr .loop +; a card was found, now to check if it's active or benched. .found ld a, e or a @@ -566,26 +570,28 @@ FindTargetCardForSuperPotion: ; 2030f (8:430f) jr c, .second_attack_1 ld a, MOVE_FLAG3_ADDRESS | BOOST_IF_TAKEN_DAMAGE_F call CheckLoadedMoveFlag - jr c, .set_carry + jr c, .true_1 .second_attack_1 ld a, $01 ; second attack ld [wSelectedMoveIndex], a farcall CheckIfSelectedMoveIsUnusable - jr c, .false + jr c, .false_1 ld a, MOVE_FLAG3_ADDRESS | BOOST_IF_TAKEN_DAMAGE_F call CheckLoadedMoveFlag - jr c, .set_carry -.false + jr c, .true_1 +.false_1 pop de or a ret -.set_carry +.true_1 pop de scf ret ; 0x203c8 -.asm_203c8 ; 203c8 (8:43c8) +; returns carry if discarding energy card renders any attack unusable, +; given that they have enough energy to be used before discarding. +.check_energy_cost ; 203c8 (8:43c8) push de xor a ; first attack ld [wSelectedMoveIndex], a @@ -594,7 +600,8 @@ FindTargetCardForSuperPotion: ; 2030f (8:430f) farcall CheckEnergyNeededForAttack jr c, .second_attack_2 farcall CheckEnergyNeededForAttackAfterDiscard - jr c, .asm_203f5 + jr c, .true_2 + .second_attack_2 pop de push de @@ -603,14 +610,15 @@ FindTargetCardForSuperPotion: ; 2030f (8:430f) ld a, e ldh [hTempPlayAreaLocation_ff9d], a farcall CheckEnergyNeededForAttack - jr c, .asm_203f2 + jr c, .false_2 farcall CheckEnergyNeededForAttackAfterDiscard - jr c, .asm_203f5 -.asm_203f2 + jr c, .true_2 + +.false_2 pop de or a ret -.asm_203f5 +.true_2 pop de scf ret -- cgit v1.2.3 From 8dbbbc9c14e94b3c7f67bad349b9a3b3170ec20b Mon Sep 17 00:00:00 2001 From: ElectroDeoxys Date: Wed, 18 Sep 2019 23:00:44 +0100 Subject: Defender AI functions --- src/engine/bank05.asm | 24 ++++++- src/engine/bank08.asm | 179 ++++++++++++++++++++++++++++++++++++++++++++++++-- 2 files changed, 198 insertions(+), 5 deletions(-) (limited to 'src/engine') diff --git a/src/engine/bank05.asm b/src/engine/bank05.asm index 1e734d1..c9e0b53 100644 --- a/src/engine/bank05.asm +++ b/src/engine/bank05.asm @@ -111,7 +111,29 @@ CheckIfMoveKnocksOutDefendingCard: ; 140b5 (5:40b5) ret ; 0x140c5 - INCROM $140c5, $140df +; returns carry if any of the defending Pokémon's attacks +; brings card at hTempPlayAreaLocation_ff9d down +; to exactly 0 HP. +; outputs that attack index in wSelectedMove. +CheckIfAnyDefendingPokemonAttackDealsSameDamageAsHP: ; 140c5 (5:40c5) + xor a ; first attack + call .check_damage + ret c + ld a, $01 ; second attack + +.check_damage + call EstimateDamage_FromDefendingPokemon + ldh a, [hTempPlayAreaLocation_ff9d] + add DUELVARS_ARENA_CARD_HP + call GetTurnDuelistVariable + ld hl, wDamage + sub [hl] + jr z, .true + ret +.true + scf + ret +; 0x140df ; checks AI scores for all benched Pokémon ; returns the location of the card with highest score diff --git a/src/engine/bank08.asm b/src/engine/bank08.asm index e759733..6836798 100644 --- a/src/engine/bank08.asm +++ b/src/engine/bank08.asm @@ -10,8 +10,8 @@ Data_20000: ; 20000 (8:4000) unknown_data_20000 $0a, POTION, FindTargetCardForPotion, AIPlayPotion unknown_data_20000 $08, SUPER_POTION, CheckIfSuperPotionPreventsKnockOut, AIPlaySuperPotion unknown_data_20000 $0b, SUPER_POTION, FindTargetCardForSuperPotion, AIPlaySuperPotion - unknown_data_20000 $0d, DEFENDER, $4406, $43f8 - unknown_data_20000 $0e, DEFENDER, $4486, $43f8 + unknown_data_20000 $0d, DEFENDER, CheckIfDefenderPreventsKnockOut, AIPlayDefender + unknown_data_20000 $0e, DEFENDER, CheckIfDefenderPreventsRecoilKnockOut, AIPlayDefender unknown_data_20000 $0d, PLUSPOWER, $4501, $44e8 unknown_data_20000 $0e, PLUSPOWER, $45a5, $44e8 unknown_data_20000 $09, SWITCH, $462e, $4612 @@ -624,8 +624,179 @@ FindTargetCardForSuperPotion: ; 2030f (8:430f) ret ; 0x203f8 -Func_203f8: ; 203f8 (8:43f8) - INCROM $203f8, $2282e +AIPlayDefender: ; 203f8 (8:43f8) + ld a, [wce16] + ldh [hTempCardIndex_ff9f], a + xor a + ldh [hTemp_ffa0], a + ld a, OPPACTION_EXECUTE_TRAINER_EFFECTS + bank1call AIMakeDecision + ret +; 0x20406 + +; returns carry if using Defender can prevent a KO +; by the defending Pokémon. +; this takes into account both attacks and whether they're useable. +CheckIfDefenderPreventsKnockOut: ; 20406 (8:4406) + xor a + ldh [hTempPlayAreaLocation_ff9d], a + farcall CheckIfAnyMoveKnocksOutDefendingCard + jr nc, .asm_2041b + farcall CheckIfSelectedMoveIsUnusable + jr nc, .no_carry + farcall LookForEnergyNeededForMoveInHand + jr c, .no_carry + +.asm_2041b +; check if any of the defending Pokémon's attacks deal +; damage exactly equal to current HP, and if so, +; only continue if that move is useable. + farcall CheckIfAnyDefendingPokemonAttackDealsSameDamageAsHP + jr nc, .no_carry + call SwapTurn + farcall CheckIfSelectedMoveIsUnusable + call SwapTurn + jr c, .no_carry + + ld a, [wSelectedMoveIndex] + farcall EstimateDamage_FromDefendingPokemon + ld a, [wDamage] + ld [wce06], a + ld d, a + +; load in a the attack that was not selected, +; and check if it is useable. + ld a, [wSelectedMoveIndex] + ld b, a + ld a, $01 + sub b + ld [wSelectedMoveIndex], a + push de + call SwapTurn + farcall CheckIfSelectedMoveIsUnusable + call SwapTurn + pop de + jr c, .switch_back + +; the other attack is useable. +; compare its damage to the selected move. + ld a, [wSelectedMoveIndex] + push de + farcall EstimateDamage_FromDefendingPokemon + pop de + ld a, [wDamage] + cp d + jr nc, .subtract + +; in case the non-selected move is useable +; and deals less damage than the selected move, +; switch back to the other attack. +.switch_back + ld a, [wSelectedMoveIndex] + ld b, a + ld a, $01 + sub b + ld [wSelectedMoveIndex], a + ld a, [wce06] + ld [wDamage], a + +; now the selected attack is the one that deals +; the most damage of the two (and is useable). +; if subtracting damage by using Defender +; still prevents a KO, return carry. +.subtract + ld a, [wDamage] + sub 20 + ld d, a + ld a, DUELVARS_ARENA_CARD_HP + call GetTurnDuelistVariable + sub d + jr c, .no_carry + jr z, .no_carry + scf + ret +.no_carry + or a + ret +; 0x20486 + +; return carry if using Defender prevents Pokémon +; from being knocked out by an attack with recoil. +CheckIfDefenderPreventsRecoilKnockOut: ; 20486 (8:4486) + ld a, MOVE_FLAG1_ADDRESS | HIGH_RECOIL_F + call CheckLoadedMoveFlag + jr c, .recoil + ld a, MOVE_FLAG1_ADDRESS | LOW_RECOIL_F + call CheckLoadedMoveFlag + jr c, .recoil + or a + ret + +.recoil + ld a, DUELVARS_ARENA_CARD + call GetTurnDuelistVariable + call LoadCardDataToBuffer2_FromDeckIndex + ld a, [wSelectedMoveIndex] + or a + jr nz, .second_attack +; first attack + ld a, [wLoadedCard2Move1Unknown1] + jr .check_weak +.second_attack + ld a, [wLoadedCard2Move2Unknown1] + +; double recoil damage if card is weak to its own color. +.check_weak + ld d, a + push de + call GetArenaCardColor + call TranslateColorToWR + ld b, a + call GetArenaCardWeakness + and b + pop de + jr z, .check_resist + sla d + +; subtract 30 from recoil damage if card resists its own color. +; if this yields a negative number, return no carry. +.check_resist + push de + call GetArenaCardColor + call TranslateColorToWR + ld b, a + call GetArenaCardResistance + and b + pop de + jr z, .subtract + ld a, d + sub 30 + jr c, .no_carry + ld d, a + +; subtract damage prevented by Defender. +; if damage still knocks out card, return no carry. +; if damage does not knock out, return carry. +.subtract + ld a, d + or a + jr z, .no_carry + sub 20 + ld d, a + ld a, DUELVARS_ARENA_CARD_HP + call GetTurnDuelistVariable + sub d + jr c, .no_carry + jr z, .no_carry + scf + ret +.no_carry + or a + ret +; 0x204e8 + +Func_204e8: ; 204e8 (8:44e8) + INCROM $204e8, $2282e ; returns in a the card index of energy card ; attached to Pokémon in Play Area location a, -- cgit v1.2.3 From 0479d5332b78a60964735929779a730d2151970c Mon Sep 17 00:00:00 2001 From: ElectroDeoxys Date: Thu, 19 Sep 2019 12:54:15 +0100 Subject: Disassemble Pluspower AI routines --- src/engine/bank08.asm | 152 ++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 148 insertions(+), 4 deletions(-) (limited to 'src/engine') diff --git a/src/engine/bank08.asm b/src/engine/bank08.asm index 6836798..48ed23f 100644 --- a/src/engine/bank08.asm +++ b/src/engine/bank08.asm @@ -12,8 +12,8 @@ Data_20000: ; 20000 (8:4000) unknown_data_20000 $0b, SUPER_POTION, FindTargetCardForSuperPotion, AIPlaySuperPotion unknown_data_20000 $0d, DEFENDER, CheckIfDefenderPreventsKnockOut, AIPlayDefender unknown_data_20000 $0e, DEFENDER, CheckIfDefenderPreventsRecoilKnockOut, AIPlayDefender - unknown_data_20000 $0d, PLUSPOWER, $4501, $44e8 - unknown_data_20000 $0e, PLUSPOWER, $45a5, $44e8 + unknown_data_20000 $0d, PLUSPOWER, $4501, AIPlayPluspower + unknown_data_20000 $0e, PLUSPOWER, $45a5, AIPlayPluspower unknown_data_20000 $09, SWITCH, $462e, $4612 unknown_data_20000 $07, GUST_OF_WIND, $467e, $4666 unknown_data_20000 $0a, GUST_OF_WIND, $467e, $4666 @@ -795,8 +795,152 @@ CheckIfDefenderPreventsRecoilKnockOut: ; 20486 (8:4486) ret ; 0x204e8 -Func_204e8: ; 204e8 (8:44e8) - INCROM $204e8, $2282e +AIPlayPluspower: ; 204e8 (8:44e8) + ld a, [wce21] + or $01 + ld [wce21], a + ld a, [wce19] + ld [wcdd6], a + ld a, [wce16] + ldh [hTempCardIndex_ff9f], a + ld a, OPPACTION_EXECUTE_TRAINER_EFFECTS + bank1call AIMakeDecision + ret +; 0x20501 + +Func_20501: ; 20501 (8:4501) +; this is mistakenly duplicated + xor a + ldh [hTempPlayAreaLocation_ff9d], a + xor a + ldh [hTempPlayAreaLocation_ff9d], a + +; continue if no attack can knock out. +; if there's an attack that can, only continue +; if it's unusable and there's no card in hand +; to fulfill its energy cost. + farcall CheckIfAnyMoveKnocksOutDefendingCard + jr nc, .cannot_ko + farcall CheckIfSelectedMoveIsUnusable + jr nc, .no_carry + farcall LookForEnergyNeededForMoveInHand + jr c, .no_carry + +; cannot use an attack that knocks out. +.cannot_ko +; get active Pokémon's info. + ld a, DUELVARS_ARENA_CARD + call GetTurnDuelistVariable + call GetCardIDFromDeckIndex + ld a, e + ld [wTempTurnDuelistCardID], a + +; get defending Pokémon's info and check +; its No Damage or Effect substatus. +; if substatus is active, return. + call SwapTurn + ld a, DUELVARS_ARENA_CARD + call GetTurnDuelistVariable + call GetCardIDFromDeckIndex + ld a, e + ld [wTempNonTurnDuelistCardID], a + bank1call HandleNoDamageOrEffectSubstatus + call SwapTurn + jr c, .no_carry + + xor a ; first attack + ld [wSelectedMoveIndex], a + call .asm_20562 + jr c, .asm_20551 + ld a, $01 ; second attack + ld [wSelectedMoveIndex], a + call .asm_20562 + jr c, .asm_20559 + +.no_carry + or a + ret +.asm_20551 + call .asm_20589 + jr nc, .no_carry + xor a ; first attack + scf + ret +.asm_20559 + call .asm_20589 + jr nc, .no_carry + ld a, $01 ; first attack + scf + ret +; 0x20562 + +.asm_20562 ; 20562 (8:4562) + farcall CheckIfSelectedMoveIsUnusable + jr c, .unusable + ld a, [wSelectedMoveIndex] + farcall EstimateDamage_VersusDefendingCard + ld a, DUELVARS_ARENA_CARD_HP + call GetNonTurnDuelistVariable + ld b, a + ld hl, wDamage + sub [hl] + jr c, .no_carry + jr z, .no_carry + ld a, [hl] + add 10 + ld c, a + ld a, b + sub c + ret c + ret nz + scf + ret +.unusable + or a + ret +; 0x20589 + +.asm_20589 ; 20589 (8:4589) + ld a, [wDamage] + add 10 + cp 30 + ret c + call SwapTurn + ld a, DUELVARS_ARENA_CARD + call GetTurnDuelistVariable + call GetCardIDFromDeckIndex + call SwapTurn + ld a, e + cp $9b + ret z + scf + ret +; 0x205a5 + +Func_205a5: ; 205a5 (8:45a5) + xor a + ldh [hTempPlayAreaLocation_ff9d], a + call Func_205d7 + jr nc, .asm_205b9 + call Func_205f6 + jr nc, .asm_205b9 + call Func_205bb + jr nc, .asm_205b9 + scf + ret +.asm_205b9 + or a + ret +; 0x205bb + +Func_205bb: ; 205bb (8:45bb) + INCROM $205bb, $205d7 + +Func_205d7: ; 205d7 (8:45d7) + INCROM $205d7, $205f6 + +Func_205f6: ; 205f6 (8:45f6) + INCROM $205f6, $2282e ; returns in a the card index of energy card ; attached to Pokémon in Play Area location a, -- cgit v1.2.3 From 1a7cad8645cba65555ef490bb47150e2ffa01035 Mon Sep 17 00:00:00 2001 From: Andrew Martinek Date: Thu, 14 Nov 2019 11:14:54 -0500 Subject: minor formatting changes --- src/engine/bank05.asm | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'src/engine') diff --git a/src/engine/bank05.asm b/src/engine/bank05.asm index c9e0b53..251f5c5 100644 --- a/src/engine/bank05.asm +++ b/src/engine/bank05.asm @@ -5344,7 +5344,7 @@ GetAIScoreOfAttack: ; 16a86 (5:6a86) jr .check_defending_can_ko ; local function that gets called to determine damage to -; benched Pokémoncaused by a HIGH_RECOIL move. +; benched Pokémon caused by a HIGH_RECOIL move. ; return carry if using move causes number of benched Pokémon KOs ; equal to or larger than remaining prize cards. ; this function is independent on duelist turn, so whatever @@ -5873,14 +5873,14 @@ HandleNinetalesMixUp: ; 16f4e (5:6f4e) ld a, DUELVARS_NUMBER_OF_CARDS_IN_HAND call GetNonTurnDuelistVariable or a - ret z ; return if no hand cards + ret z ld a, 3 call Random or a - jr z, .encourage ; if a = 0 + jr z, .encourage dec a - ret z ; return if a = 1 + ret z call SwapTurn call CreateHandCardList call SwapTurn @@ -6931,4 +6931,4 @@ HandleLegendaryArticunoEnergyScoring: ; 175bd (5:75bd) ; 0x175c9 Func_175c9 ; 175c9 (5:75c9) - INCROM $175c9, $18000 \ No newline at end of file + INCROM $175c9, $18000 -- cgit v1.2.3