diff options
Diffstat (limited to 'src/engine/ai/common.asm')
-rw-r--r-- | src/engine/ai/common.asm | 970 |
1 files changed, 0 insertions, 970 deletions
diff --git a/src/engine/ai/common.asm b/src/engine/ai/common.asm deleted file mode 100644 index d4f1da4..0000000 --- a/src/engine/ai/common.asm +++ /dev/null @@ -1,970 +0,0 @@ -; runs through Player's whole deck and -; sets carry if there's any Pokemon other -; than Mewtwo1. -CheckIfPlayerHasPokemonOtherThanMewtwo1: ; 227a9 (8:67a9) - call SwapTurn - ld e, 0 -.loop_deck - ld a, e - push de - call LoadCardDataToBuffer2_FromDeckIndex - pop de - ld a, [wLoadedCard2Type] - cp TYPE_ENERGY - jp nc, .next ; can be a jr - ld a, [wLoadedCard2ID] - cp MEWTWO1 - jr nz, .not_mewtwo1 -.next - inc e - ld a, DECK_SIZE - cp e - jr nz, .loop_deck - -; no carry - call SwapTurn - or a - ret - -.not_mewtwo1 - call SwapTurn - scf - ret - -; returns no carry if, given the Player is using a Mewtwo1 mill deck, -; the AI already has a Bench fully set up, in which case it -; will process some Trainer cards in hand (namely Energy Removals). -; this is used to check whether to skip some normal AI routines -; this turn and jump right to the attacking phase. -HandleAIAntiMewtwoDeckStrategy: ; 227d3 (8:67d3) -; return carry if Player is not playing Mewtwo1 mill deck - ld a, [wAIBarrierFlagCounter] - bit AI_MEWTWO_MILL_F, a - jr z, .set_carry - -; else, check if there's been less than 2 turns -; without the Player using Barrier. - cp AI_MEWTWO_MILL + 2 - jr c, .count_bench - -; if there has been, reset wAIBarrierFlagCounter -; and return carry. - xor a - ld [wAIBarrierFlagCounter], a - jr .set_carry - -; else, check number of Pokemon that are set up in Bench -; if less than 4, return carry. -.count_bench - farcall CountNumberOfSetUpBenchPokemon - cp 4 - jr c, .set_carry - -; if there's at least 4 Pokemon in the Bench set up, -; process Trainer hand cards of AI_TRAINER_CARD_PHASE_05 - ld a, AI_TRAINER_CARD_PHASE_05 - farcall AIProcessHandTrainerCards - or a - ret - -.set_carry - scf - ret - -; lists in wDuelTempList all the basic energy cards -; in card location of a. -; outputs in a number of cards found. -; returns carry if none were found. -; input: -; a = CARD_LOCATION_* to look -; output: -; a = number of cards found -FindBasicEnergyCardsInLocation: ; 227f6 (8:67f6) - ld [wTempAI], a - lb de, 0, 0 - ld hl, wDuelTempList - -; d = number of basic energy cards found -; e = current card in deck -; loop entire deck -.loop - ld a, DUELVARS_CARD_LOCATIONS - add e - push hl - call GetTurnDuelistVariable - ld hl, wTempAI - cp [hl] - pop hl - jr nz, .next_card - -; is in the card location we're looking for - ld a, e - push de - push hl - call GetCardIDFromDeckIndex - pop hl - ld a, e - pop de - cp DOUBLE_COLORLESS_ENERGY - ; only basic energy cards - ; will set carry here - jr nc, .next_card - -; is a basic energy card -; add this card to the TempList - ld a, e - ld [hli], a - inc d -.next_card - inc e - ld a, DECK_SIZE - cp e - jr nz, .loop - -; check if any were found - ld a, d - or a - jr z, .set_carry - -; some were found, add the termination byte on TempList - ld a, $ff - ld [hl], a - ld a, d - ret - -.set_carry - scf - ret - -; returns in a the card index of energy card -; attached to Pokémon in Play Area location a, -; that is to be discarded by the AI for an effect. -; outputs $ff is none was found. -; input: -; a = PLAY_AREA_* constant of card -; output: -; a = deck index of attached energy card chosen -AIPickEnergyCardToDiscard: ; 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 - -; returns in a the deck index of an energy card attached to card -; in player's Play Area location a to remove. -; prioritizes double colorless energy, then any useful energy, -; then defaults to the first energy card attached if neither -; of those are found. -; returns $ff in a if there are no energy cards attached. -; input: -; a = Play Area location to check -; output: -; a = deck index of attached energy card -PickAttachedEnergyCardToRemove: ; 22875 (8:6875) -; construct energy list and check if there are any energy cards attached - 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 data and store its 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 - -; first look for any double colorless energy - ld hl, wDuelTempList -.loop_1 - ld a, [hl] - cp $ff - jr z, .check_useful - push hl - call GetCardIDFromDeckIndex - ld a, e - cp DOUBLE_COLORLESS_ENERGY - pop hl - jr z, .found - inc hl - jr .loop_1 - -; then look for any energy cards that are useful -.check_useful - ld hl, wDuelTempList -.loop_2 - ld a, [hl] - cp $ff - jr z, .default - farcall CheckIfEnergyIsUseful - jr c, .found - inc hl - jr .loop_2 - -; return the energy card that was found -.found - ld a, [hl] - ret - -; if none were found with the above criteria, -; just return the first option -.default - ld hl, wDuelTempList - ld a, [hl] - ret - -; return $ff if no energy cards attached -.no_energy - ld a, $ff - ret - -; stores in wTempAI and wCurCardCanAttack the deck indices -; of energy cards attached to card in Play Area location a. -; prioritizes double colorless energy, then any useful energy, -; then defaults to the first two energy cards attached if neither -; of those are found. -; returns $ff in a if there are no energy cards attached. -; input: -; a = Play Area location to check -; output: -; [wTempAI] = deck index of attached energy card -; [wCurCardCanAttack] = deck index of attached energy card -PickTwoAttachedEnergyCards: ; 228d1 (8:68d1) - ldh [hTempPlayAreaLocation_ff9d], a - call CreateArenaOrBenchEnergyCardList - ldh a, [hTempPlayAreaLocation_ff9d] - ld e, a - farcall CountNumberOfEnergyCardsAttached - cp 2 - jp c, .not_enough - -; load card data and store its 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 - ld a, $ff - ld [wTempAI], a - ld [wCurCardCanAttack], a - -; first look for any double colorless energy - ld hl, wDuelTempList -.loop_1 - ld a, [hl] - cp $ff - jr z, .check_useful - push hl - call GetCardIDFromDeckIndex - ld a, e - cp DOUBLE_COLORLESS_ENERGY - pop hl - jr z, .found_double_colorless - inc hl - jr .loop_1 -.found_double_colorless - ld a, [wTempAI] - cp $ff - jr nz, .already_chosen_1 - ld a, [hli] - ld [wTempAI], a - jr .loop_1 -.already_chosen_1 - ld a, [hl] - ld [wCurCardCanAttack], a - jr .done - -; then look for any energy cards that are useful -.check_useful - ld hl, wDuelTempList -.loop_2 - ld a, [hl] - cp $ff - jr z, .default - farcall CheckIfEnergyIsUseful - jr c, .found_useful - inc hl - jr .loop_2 -.found_useful - ld a, [wTempAI] - cp $ff - jr nz, .already_chosen_2 - ld a, [hli] - ld [wTempAI], a - jr .loop_2 -.already_chosen_2 - ld a, [hl] - ld [wCurCardCanAttack], a - jr .done - -; if none were found with the above criteria, -; just return the first 2 options -.default - ld hl, wDuelTempList - ld a, [wTempAI] - cp $ff - jr nz, .pick_one_card - -; pick 2 cards - ld a, [hli] - ld [wTempAI], a - ld a, [hl] - ld [wCurCardCanAttack], a - jr .done -.pick_one_card - ld a, [wTempAI] - ld b, a -.loop_3 - ld a, [hli] - cp b - jr z, .loop_3 ; already picked - ld [wCurCardCanAttack], a - -.done - ld a, [wCurCardCanAttack] - ld b, a - ld a, [wTempAI] - ret - -; return $ff if no energy cards attached -.not_enough - ld a, $ff - ret - -; copies $ff terminated buffer from hl to de -CopyBuffer: ; 2297b (8:697b) - ld a, [hli] - ld [de], a - cp $ff - ret z - inc de - jr CopyBuffer - -; zeroes a bytes starting at hl -ClearMemory_Bank8: ; 22983 (8:6983) - push af - push bc - push hl - ld b, a - xor a -.loop - ld [hli], a - dec b - jr nz, .loop - pop hl - pop bc - pop af - ret - -; counts number of energy cards found in hand -; and outputs result in a -; sets carry if none are found -; output: -; a = number of energy cards found -CountOppEnergyCardsInHand: ; 22990 (8:6990) - farcall CreateEnergyCardListFromHand - ret c - ld b, -1 - ld hl, wDuelTempList -.loop - inc b - ld a, [hli] - cp $ff - jr nz, .loop - ld a, b - or a - ret - -; converts HP in a to number of equivalent damage counters -; input: -; a = HP -; output: -; a = number of damage counters -ConvertHPToCounters: ; 229a3 (8:69a3) - push bc - ld c, 0 -.loop - sub 10 - jr c, .carry - inc c - jr .loop -.carry - ld a, c - pop bc - ret - -; calculates floor(hl / 10) -CalculateWordTensDigit: ; 229b0 (8:69b0) - push bc - push de - lb bc, $ff, -10 - lb de, $ff, -1 -.asm_229b8 - inc de - add hl, bc - jr c, .asm_229b8 - ld h, d - ld l, e - pop de - pop bc - ret - -; returns in a division of b by a -CalculateBDividedByA_Bank8: ; 229c1 (8:69c1) - push bc - ld c, a - ld a, b - ld b, c - ld c, 0 -.loop - sub b - jr c, .done - inc c - jr .loop -.done - ld a, c - pop bc - ret - -; returns in a the deck index of the first -; instance of card with ID equal to the ID in e -; in card location a. -; returns carry if found. -; input: -; a = CARD_LOCATION_* -; e = card ID to look for -LookForCardIDInLocation: ; 229d0 (8:69d0) - ld b, a - ld c, e - lb de, $00, 0 ; d is never used -.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, .found -.next - inc e - ld a, DECK_SIZE - cp e - jr nz, .loop - -; not found - or a - ret -.found - ld a, e - scf - ret - -; return carry if card ID loaded in a is found in hand -; and outputs in a the deck index of that card -; input: -; a = card ID -; output: -; a = card deck index, if found -; carry set if found -LookForCardIDInHandList_Bank8: ; 229f3 (8:69f3) - ld [wTempCardIDToLook], a - call CreateHandCardList - ld hl, wDuelTempList - -.loop - ld a, [hli] - cp $ff - ret z - - ldh [hTempCardIndex_ff98], a - call LoadCardDataToBuffer1_FromDeckIndex - ld b, a - ld a, [wTempCardIDToLook] - cp b - jr nz, .loop - - ldh a, [hTempCardIndex_ff98] - scf - ret - -; searches in deck for card ID 1 in a, and -; if found, searches in Hand/Play Area for card ID 2 in b, and -; if found, searches for card ID 1 in Hand/Play Area, and -; if none found, return carry and output deck index -; of the card ID 1 in deck. -; input: -; a = card ID 1 -; b = card ID 2 -; output: -; a = index of card ID 1 in deck -LookForCardIDInDeck_GivenCardIDInHandAndPlayArea: ; 22a10 (8:6a10) -; store a in wCurCardCanAttack -; and b in wTempAI - ld c, a - ld a, b - ld [wTempAI], a - ld a, c - ld [wCurCardCanAttack], a - -; look for the card ID 1 in deck - ld e, a - ld a, CARD_LOCATION_DECK - call LookForCardIDInLocation - ret nc - -; was found, store its deck index in memory - ld [wTempAIPokemonCard], a - -; look for the card ID 2 -; in Hand and Play Area, return if not found. - ld a, [wTempAI] - call LookForCardIDInHandAndPlayArea - ret nc - -; look for the card ID 1 in the Hand and Play Area -; if any card is found, return no carry. - ld a, [wCurCardCanAttack] - call LookForCardIDInHandAndPlayArea - jr c, .no_carry -; none found - - ld a, [wTempAIPokemonCard] - scf - ret - -.no_carry - or a - ret - -; returns carry if card ID in a -; is found in Play Area or in hand -; input: -; a = card ID -LookForCardIDInHandAndPlayArea: ; 22a39 (8:6a39) - ld b, a - push bc - call LookForCardIDInHandList_Bank8 - pop bc - ret c - - ld a, b - ld b, PLAY_AREA_ARENA - call LookForCardIDInPlayArea_Bank8 - ret c - or a - ret - -; searches in deck for card ID 1 in a, and -; if found, searches in Hand Area for card ID 2 in b, and -; if found, searches for card ID 1 in Hand/Play Area, and -; if none found, return carry and output deck index -; of the card ID 1 in deck. -; input: -; a = card ID 1 -; b = card ID 2 -; output: -; a = index of card ID 1 in deck -LookForCardIDInDeck_GivenCardIDInHand: ; 22a49 (8:6a49) -; store a in wCurCardCanAttack -; and b in wTempAI - ld c, a - ld a, b - ld [wTempAI], a - ld a, c - ld [wCurCardCanAttack], a - -; look for the card ID 1 in deck - ld e, a - ld a, CARD_LOCATION_DECK - call LookForCardIDInLocation - ret nc - -; was found, store its deck index in memory - ld [wTempAIPokemonCard], a - -; look for the card ID 2 in hand, return if not found. - ld a, [wTempAI] - call LookForCardIDInHandList_Bank8 - ret nc - -; look for the card ID 1 in the Hand and Play Area -; if any card is found, return no carry. - ld a, [wCurCardCanAttack] - call LookForCardIDInHandAndPlayArea - jr c, .no_carry -; none found - - ld a, [wTempAIPokemonCard] - scf - ret - -.no_carry - or a - ret - -; returns carry if card ID in a -; is found in Play Area, starting with -; location in b -; input: -; a = card ID -; b = PLAY_AREA_* to start with -; output: -; a = PLAY_AREA_* of found card -; carry set if found -LookForCardIDInPlayArea_Bank8: ; 22a72 (8:6a72) - ld [wTempCardIDToLook], a -.loop - ld a, DUELVARS_ARENA_CARD - add b - call GetTurnDuelistVariable - cp $ff - ret z - - call LoadCardDataToBuffer1_FromDeckIndex - ld c, a - ld a, [wTempCardIDToLook] - cp c - jr z, .is_same - - inc b - ld a, MAX_PLAY_AREA_POKEMON - cp b - jr nz, .loop - ld b, $ff - or a - ret - -.is_same - ld a, b - scf - ret - -; runs through list avoiding card in e. -; removes first card in list not equal to e -; and that has a type allowed to be removed, in d. -; returns carry if successful in finding a card. -; input: -; d = type of card allowed to be removed -; ($00 = Trainer, $01 = Pokemon, $02 = Energy) -; e = card deck index to avoid removing -; output: -; a = card index of removed card -RemoveFromListDifferentCardOfGivenType: ; 22a95 (8:6a95) - push hl - push de - push bc - call CountCardsInDuelTempList - call ShuffleCards - -; loop list until a card with -; deck index different from e is found. -.loop_list - ld a, [hli] - cp $ff - jr z, .no_carry - cp e - jr z, .loop_list - -; get this card's type - ldh [hTempCardIndex_ff98], a - push de - call GetCardIDFromDeckIndex - call GetCardType - pop de - cp TYPE_ENERGY - jr c, .pkmn_card - cp TYPE_TRAINER - jr nz, .energy - -; only remove from list specific type. - -; trainer - ld a, d - or a - jr nz, .loop_list - jr .remove_card -.energy - ld a, d - cp $02 - jr nz, .loop_list - jr .remove_card -.pkmn_card - ld a, d - cp $01 - jr nz, .loop_list - ; fallthrough - -.remove_card - ld d, h - ld e, l - dec hl -.loop_remove - ld a, [de] - inc de - ld [hli], a - cp $ff - jr nz, .loop_remove - -; success - ldh a, [hTempCardIndex_ff98] - pop bc - pop de - pop hl - scf - ret -.no_carry - pop bc - pop de - pop hl - or a - ret - -; used in Pokemon Trader checks to look for a specific -; card in the deck to trade with a card in hand that -; has a card ID different from e. -; returns carry if successful. -; input: -; a = card ID 1 -; e = card ID 2 -; output: -; a = deck index of card ID 1 found in deck -; e = deck index of Pokemon card in hand different than card ID 2 -LookForCardIDToTradeWithDifferentHandCard: ; 22ae0 (8:6ae0) - ld hl, wCurCardCanAttack - ld [hl], e - ld [wTempAI], a - -; if card ID 1 is in hand, return no carry. - call LookForCardIDInHandList_Bank8 - jr c, .no_carry - -; if card ID 1 is not in deck, return no carry. - ld a, [wTempAI] - ld e, a - ld a, CARD_LOCATION_DECK - call LookForCardIDInLocation - jr nc, .no_carry - -; store its deck index - ld [wTempAI], a - -; look in hand for Pokemon card ID that -; is different from card ID 2. - ld a, [wCurCardCanAttack] - ld c, a - call CreateHandCardList - ld hl, wDuelTempList - -.loop_hand - ld a, [hli] - cp $ff - jr z, .no_carry - ld b, a - call LoadCardDataToBuffer1_FromDeckIndex - cp c - jr z, .loop_hand - ld a, [wLoadedCard1Type] - cp TYPE_ENERGY - jr nc, .loop_hand - -; found, output deck index of card ID 1 in deck -; and deck index of card found in hand, and set carry - ld e, b - ld a, [wTempAI] - scf - ret - -.no_carry - or a - ret - -; returns carry if at least one card in the hand -; has the card ID of input. Outputs its index. -; input: -; a = card ID to look for -; output: -; a = deck index of card in hand found -CheckIfHasCardIDInHand: ; 22b1f (8:6b1f) - ld [wTempCardIDToLook], a - call CreateHandCardList - ld hl, wDuelTempList - ld c, 0 - -.loop_hand - ld a, [hli] - cp $ff - ret z - ldh [hTempCardIndex_ff98], a - call LoadCardDataToBuffer1_FromDeckIndex - ld b, a - ld a, [wTempCardIDToLook] - cp b - jr nz, .loop_hand - ld a, c - or a - jr nz, .set_carry - inc c - jr nz, .loop_hand - -.set_carry - ldh a, [hTempCardIndex_ff98] - scf - ret - -; outputs in a total number of Pokemon cards in hand -; plus Pokemon in Turn Duelist's Play Area. -CountPokemonCardsInHandAndInPlayArea: ; 22b45 (8:6b45) - ld a, DUELVARS_NUMBER_OF_POKEMON_IN_PLAY_AREA - call GetTurnDuelistVariable - ld [wTempAI], a - call CreateHandCardList - ld hl, wDuelTempList -.loop_hand - ld a, [hli] - cp $ff - jr z, .done - call GetCardIDFromDeckIndex - call GetCardType - cp TYPE_ENERGY - jr nc, .loop_hand - ld a, [wTempAI] - inc a - ld [wTempAI], a - jr .loop_hand -.done - ld a, [wTempAI] - ret - -; returns carry if a duplicate Pokemon card is found in hand. -; outputs in a the deck index of one of them. -FindDuplicatePokemonCards: ; 22b6f (8:6b6f) - ld a, $ff - ld [wTempAI], a - call CreateHandCardList - ld hl, wDuelTempList - push hl - -.loop_hand_outer - pop hl - ld a, [hli] - cp $ff - jr z, .done - call GetCardIDFromDeckIndex - ld b, e - push hl - -.loop_hand_inner - ld a, [hli] - cp $ff - jr z, .loop_hand_outer - ld c, a - call GetCardIDFromDeckIndex - ld a, e - cp b - jr nz, .loop_hand_inner - -; found two cards with same ID, -; if they are Pokemon cards, store its deck index. - push bc - call GetCardType - pop bc - cp TYPE_ENERGY - jr nc, .loop_hand_outer - ld a, c - ld [wTempAI], a - ; for some reason loop still continues - ; even though if some other duplicate - ; cards are found, it overwrites the result. - jr .loop_hand_outer - -.done - ld a, [wTempAI] - cp $ff - jr z, .no_carry - -; found - scf - ret -.no_carry - or a - ret - -; return carry flag if attack is not high recoil. -AICheckIfAttackIsHighRecoil: ; 22bad (8:6bad) - farcall AIProcessButDontUseAttack - ret nc - ld a, [wSelectedAttack] - ld e, a - ld a, DUELVARS_ARENA_CARD - call GetTurnDuelistVariable - ld d, a - call CopyAttackDataAndDamage_FromDeckIndex - ld a, ATTACK_FLAG1_ADDRESS | HIGH_RECOIL_F - call CheckLoadedAttackFlag - ccf - ret |