summaryrefslogtreecommitdiff
path: root/src/engine/ai/hand_pokemon.asm
diff options
context:
space:
mode:
Diffstat (limited to 'src/engine/ai/hand_pokemon.asm')
-rw-r--r--src/engine/ai/hand_pokemon.asm627
1 files changed, 0 insertions, 627 deletions
diff --git a/src/engine/ai/hand_pokemon.asm b/src/engine/ai/hand_pokemon.asm
deleted file mode 100644
index 27a4176..0000000
--- a/src/engine/ai/hand_pokemon.asm
+++ /dev/null
@@ -1,627 +0,0 @@
-; determine whether AI plays
-; basic cards from hand
-AIDecidePlayPokemonCard: ; 15eae (5:5eae)
- call CreateHandCardList
- call SortTempHandByIDList
- ld hl, wDuelTempList
- ld de, wHandTempList
- call CopyHandCardList
- ld hl, wHandTempList
-
-.next_hand_card
- ld a, [hli]
- cp $ff
- jp z, AIDecideEvolution
-
- ld [wTempAIPokemonCard], a
- push hl
- call LoadCardDataToBuffer1_FromDeckIndex
- ld a, [wLoadedCard1Type]
- cp TYPE_ENERGY
- jr nc, .skip
- ; skip non-pokemon cards
-
- ld a, [wLoadedCard1Stage]
- or a
- jr nz, .skip
- ; skip non-basic pokemon
-
- ld a, 130
- ld [wAIScore], a
- call AIDecidePlayLegendaryBirds
-
-; if Play Area has more than 4 Pokémon, decrease AI score
-; else, increase AI score
- ld a, DUELVARS_NUMBER_OF_POKEMON_IN_PLAY_AREA
- call GetTurnDuelistVariable
- cp 4
- jr c, .has_4_or_fewer
- ld a, 20
- call SubFromAIScore
- jr .check_defending_can_ko
-.has_4_or_fewer
- ld a, 50
- call AddToAIScore
-
-; if defending Pokémon can KO active card, increase AI score
-.check_defending_can_ko
- xor a
- ldh [hTempPlayAreaLocation_ff9d], a
- call CheckIfDefendingPokemonCanKnockOut
- jr nc, .check_energy_cards
- ld a, 20
- call AddToAIScore
-
-; if energy cards are found in hand
-; for this card's attacks, raise AI score
-.check_energy_cards
- ld a, [wTempAIPokemonCard]
- call GetAttacksEnergyCostBits
- call CheckEnergyFlagsNeededInList
- jr nc, .check_evolution_hand
- ld a, 20
- call AddToAIScore
-
-; if evolution card is found in hand
-; for this card, raise AI score
-.check_evolution_hand
- ld a, [wTempAIPokemonCard]
- call CheckForEvolutionInList
- jr nc, .check_evolution_deck
- ld a, 20
- call AddToAIScore
-
-; if evolution card is found in deck
-; for this card, raise AI score
-.check_evolution_deck
- ld a, [wTempAIPokemonCard]
- call CheckForEvolutionInDeck
- jr nc, .check_score
- ld a, 10
- call AddToAIScore
-
-; if AI score is >= 180, play card from hand
-.check_score
- ld a, [wAIScore]
- cp 180
- jr c, .skip
- ld a, [wTempAIPokemonCard]
- ldh [hTemp_ffa0], a
- call CheckIfCardCanBePlayed
- jr c, .skip
- ld a, OPPACTION_PLAY_BASIC_PKMN
- bank1call AIMakeDecision
- jr c, .done
-.skip
- pop hl
- jp .next_hand_card
-.done
- pop hl
- ret
-
-; determine whether AI evolves
-; Pokémon in the Play Area
-AIDecideEvolution: ; 15f4c (5:5f4c)
- call CreateHandCardList
- ld hl, wDuelTempList
- ld de, wHandTempList
- call CopyHandCardList
- ld hl, wHandTempList
-
-.next_hand_card
- ld a, [hli]
- cp $ff
- jp z, .done
- ld [wTempAIPokemonCard], a
-
-; check if Prehistoric Power is active
-; and if so, skip to next card in hand
- push hl
- call IsPrehistoricPowerActive
- jp c, .done_hand_card
-
-; load evolution data to buffer1
-; skip if it's not a Pokémon card
-; and if it's a basic stage card
- ld a, [wTempAIPokemonCard]
- call LoadCardDataToBuffer1_FromDeckIndex
- ld a, [wLoadedCard1Type]
- cp TYPE_ENERGY
- jp nc, .done_hand_card
- ld a, [wLoadedCard1Stage]
- or a
- jp z, .done_hand_card
-
-; start looping Pokémon in Play Area
-; to find a card to evolve
- ld a, DUELVARS_NUMBER_OF_POKEMON_IN_PLAY_AREA
- call GetTurnDuelistVariable
- ld c, a
- ld b, 0
-.next_bench_pokemon
- push bc
- ld e, b
- ld a, [wTempAIPokemonCard]
- ld d, a
- call CheckIfCanEvolveInto
- pop bc
- push bc
- jp c, .done_bench_pokemon
-
-; store this Play Area location in wTempAI
-; and initialize the AI score
- ld a, b
- ld [wTempAI], a
- ldh [hTempPlayAreaLocation_ff9d], a
- ld a, $80
- ld [wAIScore], a
- call AIDecideSpecialEvolutions
-
-; check if the card can use any attacks
-; and if any of those attacks can KO
- xor a
- ld [wSelectedAttack], a
- call CheckIfSelectedAttackIsUnusable
- jr nc, .can_attack
- ld a, $01
- ld [wSelectedAttack], a
- call CheckIfSelectedAttackIsUnusable
- jr c, .cant_attack_or_ko
-.can_attack
- ld a, $01
- ld [wCurCardCanAttack], a
- call CheckIfAnyAttackKnocksOutDefendingCard
- jr nc, .check_evolution_attacks
- call CheckIfSelectedAttackIsUnusable
- jr c, .check_evolution_attacks
- ld a, $01
- ld [wCurCardCanKO], a
- jr .check_evolution_attacks
-.cant_attack_or_ko
- xor a
- ld [wCurCardCanAttack], a
- ld [wCurCardCanKO], a
-
-; check evolution to see if it can use any of its attacks:
-; if it can, raise AI score;
-; if it can't, decrease AI score and if an energy card that is needed
-; can be played from the hand, raise AI score.
-.check_evolution_attacks
- ldh a, [hTempPlayAreaLocation_ff9d]
- add DUELVARS_ARENA_CARD
- call GetTurnDuelistVariable
- push af
- ld a, [wTempAIPokemonCard]
- ld [hl], a
- xor a
- ld [wSelectedAttack], a
- call CheckIfSelectedAttackIsUnusable
- jr nc, .evolution_can_attack
- ld a, $01
- ld [wSelectedAttack], a
- call CheckIfSelectedAttackIsUnusable
- jr c, .evolution_cant_attack
-.evolution_can_attack
- ld a, 5
- call AddToAIScore
- jr .check_evolution_ko
-.evolution_cant_attack
- ld a, [wCurCardCanAttack]
- or a
- jr z, .check_evolution_ko
- ld a, 2
- call SubFromAIScore
- ld a, [wAlreadyPlayedEnergy]
- or a
- jr nz, .check_evolution_ko
- call LookForEnergyNeededInHand
- jr nc, .check_evolution_ko
- ld a, 7
- call AddToAIScore
-
-; if it's an active card:
-; if evolution can't KO but the current card can, lower AI score;
-; if evolution can KO as well, raise AI score.
-.check_evolution_ko
- ld a, [wCurCardCanAttack]
- or a
- jr z, .check_defending_can_ko_evolution
- ld a, [wTempAI]
- or a
- jr nz, .check_defending_can_ko_evolution
- call CheckIfAnyAttackKnocksOutDefendingCard
- jr nc, .evolution_cant_ko
- call CheckIfSelectedAttackIsUnusable
- jr c, .evolution_cant_ko
- ld a, 5
- call AddToAIScore
- jr .check_defending_can_ko_evolution
-.evolution_cant_ko
- ld a, [wCurCardCanKO]
- or a
- jr z, .check_defending_can_ko_evolution
- ld a, 20
- call SubFromAIScore
-
-; if defending Pokémon can KO evolution, lower AI score
-.check_defending_can_ko_evolution
- ld a, [wTempAI]
- or a
- jr nz, .check_mr_mime
- xor a
- ldh [hTempPlayAreaLocation_ff9d], a
- call CheckIfDefendingPokemonCanKnockOut
- jr nc, .check_mr_mime
- ld a, 5
- call SubFromAIScore
-
-; if evolution can't damage player's Mr Mime, lower AI score
-.check_mr_mime
- ld a, [wTempAI]
- call CheckDamageToMrMime
- jr c, .check_defending_can_ko
- ld a, 20
- call SubFromAIScore
-
-; if defending Pokémon can KO current card, raise AI score
-.check_defending_can_ko
- ld a, [wTempAI]
- add DUELVARS_ARENA_CARD
- call GetTurnDuelistVariable
- pop af
- ld [hl], a
- ld a, [wTempAI]
- or a
- jr nz, .check_2nd_stage_hand
- xor a
- ldh [hTempPlayAreaLocation_ff9d], a
- call CheckIfDefendingPokemonCanKnockOut
- jr nc, .check_status
- ld a, 5
- call AddToAIScore
-
-; if current card has a status condition, raise AI score
-.check_status
- ld a, DUELVARS_ARENA_CARD_STATUS
- call GetTurnDuelistVariable
- or a
- jr z, .check_2nd_stage_hand
- ld a, 4
- call AddToAIScore
-
-; if hand has 2nd stage card to evolve evolution card, raise AI score
-.check_2nd_stage_hand
- ld a, [wTempAIPokemonCard]
- call CheckForEvolutionInList
- jr nc, .check_2nd_stage_deck
- ld a, 2
- call AddToAIScore
- jr .check_damage
-
-; if deck has 2nd stage card to evolve evolution card, raise AI score
-.check_2nd_stage_deck
- ld a, [wTempAIPokemonCard]
- call CheckForEvolutionInDeck
- jr nc, .check_damage
- ld a, 1
- call AddToAIScore
-
-; decrease AI score proportional to damage
-; AI score -= floor(Damage / 40)
-.check_damage
- ld a, [wTempAI]
- ld e, a
- call GetCardDamageAndMaxHP
- or a
- jr z, .check_mysterious_fossil
- srl a
- srl a
- call CalculateByteTensDigit
- call SubFromAIScore
-
-; if is Mysterious Fossil or
-; wLoadedCard1Unknown2 is set to $02,
-; raise AI score
-.check_mysterious_fossil
- ld a, [wTempAI]
- add DUELVARS_ARENA_CARD
- call GetTurnDuelistVariable
- call LoadCardDataToBuffer1_FromDeckIndex
- ld a, [wLoadedCard1ID]
- cp MYSTERIOUS_FOSSIL
- jr z, .mysterious_fossil
- ld a, [wLoadedCard1Unknown2]
- cp $02
- jr nz, .pikachu_deck
- ld a, 2
- call AddToAIScore
- jr .pikachu_deck
-
-.mysterious_fossil
- ld a, 5
- call AddToAIScore
-
-; in Pikachu Deck, decrease AI score for evolving Pikachu
-.pikachu_deck
- ld a, [wOpponentDeckID]
- cp PIKACHU_DECK_ID
- jr nz, .check_score
- ld a, [wLoadedCard1ID]
- cp PIKACHU1
- jr z, .pikachu
- cp PIKACHU2
- jr z, .pikachu
- cp PIKACHU3
- jr z, .pikachu
- cp PIKACHU4
- jr nz, .check_score
-.pikachu
- ld a, 3
- call SubFromAIScore
-
-; if AI score >= 133, go through with the evolution
-.check_score
- ld a, [wAIScore]
- cp 133
- jr c, .done_bench_pokemon
- ld a, [wTempAI]
- ldh [hTempPlayAreaLocation_ffa1], a
- ld a, [wTempAIPokemonCard]
- ldh [hTemp_ffa0], a
- ld a, OPPACTION_EVOLVE_PKMN
- bank1call AIMakeDecision
- pop bc
- jr .done_hand_card
-
-.done_bench_pokemon
- pop bc
- inc b
- dec c
- jp nz, .next_bench_pokemon
-.done_hand_card
- pop hl
- jp .next_hand_card
-.done
- or a
- ret
-
-; determine AI score for evolving
-; Charmeleon, Magikarp, Dragonair and Grimer
-; in certain decks
-AIDecideSpecialEvolutions: ; 16120 (5:6120)
-; check if deck applies
- ld a, [wOpponentDeckID]
- cp LEGENDARY_DRAGONITE_DECK_ID
- jr z, .legendary_dragonite
- cp INVINCIBLE_RONALD_DECK_ID
- jr z, .invincible_ronald
- cp LEGENDARY_RONALD_DECK_ID
- jr z, .legendary_ronald
- ret
-
-.legendary_dragonite
- ld a, [wLoadedCard2ID]
- cp CHARMELEON
- jr z, .charmeleon
- cp MAGIKARP
- jr z, .magikarp
- cp DRAGONAIR
- jr z, .dragonair
- ret
-
-; check if number of energy cards attached to Charmeleon are at least 3
-; and if adding the energy cards in hand makes at least 6 energy cards
-.charmeleon
- ldh a, [hTempPlayAreaLocation_ff9d]
- ld e, a
- call CountNumberOfEnergyCardsAttached
- cp 3
- jr c, .not_enough_energy
- push af
- farcall CountOppEnergyCardsInHand
- pop bc
- add b
- cp 6
- jr c, .not_enough_energy
- ld a, 3
- call AddToAIScore
- ret
-.not_enough_energy
- ld a, 10
- call SubFromAIScore
- ret
-
-; check if Magikarp is not the active card
-; and has at least 2 energy cards attached
-.magikarp
- ldh a, [hTempPlayAreaLocation_ff9d]
- or a ; active card
- ret z
- ld e, a
- call CountNumberOfEnergyCardsAttached
- cp 2
- ret c
- ld a, 3
- call AddToAIScore
- ret
-
-.invincible_ronald
- ld a, [wLoadedCard2ID]
- cp GRIMER
- jr z, .grimer
- ret
-
-; check if Grimer is not active card
-.grimer
- ldh a, [hTempPlayAreaLocation_ff9d]
- or a ; active card
- ret z
- ld a, 10
- call AddToAIScore
- ret
-
-.legendary_ronald
- ld a, [wLoadedCard2ID]
- cp DRAGONAIR
- jr z, .dragonair
- ret
-
-.dragonair
- ldh a, [hTempPlayAreaLocation_ff9d]
- or a ; active card
- jr z, .is_active
-
-; if Dragonair is benched, check all Pokémon in Play Area
-; and sum all the damage in HP of all cards
-; if this result is >= 70, check if there's
-; a Muk in any duelist's Play Area
- ld a, DUELVARS_NUMBER_OF_POKEMON_IN_PLAY_AREA
- call GetTurnDuelistVariable
- ld b, a
- ld c, 0
-.loop
- dec b
- ld e, b
- push bc
- call GetCardDamageAndMaxHP
- pop bc
- add c
- ld c, a
- ld a, b
- or a
- jr nz, .loop
- ld a, 70
- cp c
- jr c, .check_muk
-.lower_score
- ld a, 10
- call SubFromAIScore
- ret
-
-; if there's no Muk, raise score
-.check_muk
- ld a, MUK
- call CountPokemonIDInBothPlayAreas
- jr c, .lower_score
- ld a, 10
- call AddToAIScore
- ret
-
-; if Dragonair is active, check its damage in HP
-; if this result is >= 50,
-; and if at least 3 energy cards attached,
-; check if there's a Muk in any duelist's Play Area
-.is_active
- ld e, 0
- call GetCardDamageAndMaxHP
- cp 50
- jr c, .lower_score
- ld e, PLAY_AREA_ARENA
- call GetPlayAreaCardAttachedEnergies
- ld a, [wTotalAttachedEnergies]
- cp 3
- jr c, .lower_score
- jr .check_muk
-
-; determine AI score for the legendary cards
-; Moltres, Zapdos and Articuno
-AIDecidePlayLegendaryBirds: ; 161d5 (5:61d5)
-; check if deck applies
- ld a, [wOpponentDeckID]
- cp LEGENDARY_ZAPDOS_DECK_ID
- jr z, .begin
- cp LEGENDARY_ARTICUNO_DECK_ID
- jr z, .begin
- cp LEGENDARY_RONALD_DECK_ID
- jr z, .begin
- ret
-
-; check if card applies
-.begin
- ld a, [wLoadedCard1ID]
- cp ARTICUNO2
- jr z, .articuno
- cp MOLTRES2
- jr z, .moltres
- cp ZAPDOS3
- jr z, .zapdos
- ret
-
-.articuno
- ; exit if not enough Pokemon in Play Area
- ld a, DUELVARS_NUMBER_OF_POKEMON_IN_PLAY_AREA
- call GetTurnDuelistVariable
- cp 2
- ret c
-
- call CheckIfActiveCardCanKnockOut
- jr c, .subtract
- call CheckIfActivePokemonCanUseAnyNonResidualAttack
- jr nc, .subtract
- call AIDecideWhetherToRetreat
- jr c, .subtract
-
- ; checks for player's active card status
- ld a, DUELVARS_ARENA_CARD_STATUS
- call GetNonTurnDuelistVariable
- and CNF_SLP_PRZ
- or a
- jr nz, .subtract
-
- ; checks for player's Pokemon Power
- call SwapTurn
- ld a, DUELVARS_ARENA_CARD
- call GetTurnDuelistVariable
- ld d, a
- ld e, $00
- call CopyAttackDataAndDamage_FromDeckIndex
- call SwapTurn
- ld a, [wLoadedAttackCategory]
- cp POKEMON_POWER
- jr z, .check_muk_and_snorlax
-
- ; return if no space on the bench
- ld a, DUELVARS_NUMBER_OF_POKEMON_IN_PLAY_AREA
- call GetTurnDuelistVariable
- cp MAX_BENCH_POKEMON
- jr c, .check_muk_and_snorlax
- ret
-
-.check_muk_and_snorlax
- ; checks for Muk in both Play Areas
- ld a, MUK
- call CountPokemonIDInBothPlayAreas
- jr c, .subtract
- ; checks if player's active card is Snorlax
- ld a, DUELVARS_ARENA_CARD
- call GetNonTurnDuelistVariable
- call SwapTurn
- call GetCardIDFromDeckIndex
- call SwapTurn
- ld a, e
- cp SNORLAX
- jr z, .subtract
-
-; add
- ld a, 70
- call AddToAIScore
- ret
-.subtract
- ld a, 100
- call SubFromAIScore
- ret
-
-.moltres
- ; checks if there's enough cards in deck
- ld a, DUELVARS_NUMBER_OF_CARDS_NOT_IN_DECK
- call GetTurnDuelistVariable
- cp 56 ; max number of cards not in deck to activate
- jr nc, .subtract
- ret
-
-.zapdos
- ; checks for Muk in both Play Areas
- ld a, MUK
- call CountPokemonIDInBothPlayAreas
- jr c, .subtract
- ret