summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorElectroDeoxys <ElectroDeoxys@gmail.com>2020-04-15 14:26:16 +0100
committerElectroDeoxys <ElectroDeoxys@gmail.com>2020-04-15 14:26:16 +0100
commitd86d032bb65bcdfbf666a9d7185d65bbe7e74028 (patch)
treec1a00d17f9645b176033e7669bb86260bb084b6d /src
parent81c72a30d42eaccd054868f73a2ff0101ed6b5ce (diff)
AI Energy Retrieval routines
Diffstat (limited to 'src')
-rw-r--r--src/engine/bank08.asm320
1 files changed, 316 insertions, 4 deletions
diff --git a/src/engine/bank08.asm b/src/engine/bank08.asm
index 8965da1..3f9ddd9 100644
--- a/src/engine/bank08.asm
+++ b/src/engine/bank08.asm
@@ -22,7 +22,7 @@ Data_20000: ; 20000 (8:4000)
unknown_data_20000 $05, SUPER_ENERGY_REMOVAL, CheckTwoEnergyCardsToRemoveInPlayArea, AIPlaySuperEnergyRemoval
unknown_data_20000 $07, POKEMON_BREEDER, CheckIfCanEvolve2StageFromHand, AIPlayPokemonBreeder
unknown_data_20000 $0f, PROFESSOR_OAK, CheckIfCanPlayProfessorOak, AIPlayProfessorOak
- unknown_data_20000 $0a, ENERGY_RETRIEVAL, $4e6e, $4e44
+ unknown_data_20000 $0a, ENERGY_RETRIEVAL, CheckEnergyRetrievalCardsToPick, AIPlayEnergyRetrieval
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
@@ -1741,7 +1741,7 @@ CheckTwoEnergyCardsToRemoveInPlayArea: ; 209bc (8:49bc)
ret z
call LoadCardDataToBuffer1_FromDeckIndex
cp DOUBLE_COLORLESS_ENERGY
- ; any non-double colorless energy card
+ ; any basic energy card
; will set carry flag here
jr nc, .loop_2
ret
@@ -1751,7 +1751,7 @@ CheckTwoEnergyCardsToRemoveInPlayArea: ; 209bc (8:49bc)
ret
; card in Play Area location e was found with
-; a non-double colorless energy card
+; a basic energy card
.not_double_colorless
ld a, e
ld [wce0f], a
@@ -2664,7 +2664,319 @@ CheckIfCanPlayProfessorOak: ; 20cc1 (8:4cc1)
ret
; 0x20e44
- INCROM $20e44, $2282e
+AIPlayEnergyRetrieval: ; 20e44 (8:4e44)
+ ld a, [wce21]
+ or $08
+ ld [wce21], a
+ ld a, [wce16]
+ ldh [hTempCardIndex_ff9f], a
+ ld a, [wce19]
+ ldh [hTemp_ffa0], a
+ ld a, [wce1a]
+ ldh [hTempPlayAreaLocation_ffa1], a
+ ld a, [wce1b]
+ ldh [hTempRetreatCostCards], a
+ cp $ff
+ jr z, .asm_20e68
+ ld a, $ff
+ ldh [$ffa3], a
+.asm_20e68
+ ld a, OPPACTION_EXECUTE_TRAINER_EFFECTS
+ bank1call AIMakeDecision
+ ret
+; 0x20e6e
+
+; checks whether AI can play Energy Retrieval and
+; picks the energy cards from the discard pile,
+; and duplicate cards in hand to discard.
+CheckEnergyRetrievalCardsToPick: ; 20e6e (8:4e6e)
+; return no carry if no cards in hand
+ farcall CreateEnergyCardListFromHand
+ jp nc, .no_carry
+
+; handle Go Go Rain Dance deck
+; return no carry if there's no Muk card in play and
+; if there's no Blastoise card in Play Area
+; if there's a Muk in play, continue as normal
+ ld a, [wOpponentDeckID]
+ cp GO_GO_RAIN_DANCE_DECK_ID
+ jr nz, .start
+ ld a, MUK
+ call CountPokemonIDInBothPlayAreas
+ jr c, .start
+ ld a, BLASTOISE
+ call CountPokemonIDInPlayArea
+ jp nc, .no_carry
+
+.start
+ call CreateHandCardList
+ ld hl, wDuelTempList
+ call .CheckDuplicatePokemonAndNonPokemonCards
+ jp c, .no_carry
+
+ ld [wce06], a
+ ld a, CARD_LOCATION_DISCARD_PILE
+ call FindBasicEnergyCardsInLocation
+ jp c, .no_carry
+
+; some basic energy cards were found in Discard Pile
+ ld a, $ff
+ ld [wce1a], a
+ ld [wce1b], a
+ ld [wce1c], a
+
+ ld a, DUELVARS_NUMBER_OF_POKEMON_IN_PLAY_AREA
+ call GetTurnDuelistVariable
+ ld d, a
+ ld e, PLAY_AREA_ARENA
+
+; first check if there are useful energy cards in the list
+; and choose them for retrieval first
+.loop_play_area
+ ld a, DUELVARS_ARENA_CARD
+ add e
+ push de
+
+; load this card's ID in wTempCardID
+; and this card's Type in wTempCardType
+ call GetTurnDuelistVariable
+ call GetCardIDFromDeckIndex
+ ld a, e
+ ld [wTempCardID], a
+ call LoadCardDataToBuffer1_FromCardID
+ pop de
+ ld a, [wLoadedCard1Type]
+ or TYPE_ENERGY
+ ld [wTempCardType], a
+
+; loop the energy cards in the Discard Pile
+; and check if they are useful for this Pokemon
+ ld hl, wDuelTempList
+.loop_energy_cards_1
+ ld a, [hli]
+ cp $ff
+ jr z, .next_play_area
+
+ ld b, a
+ push hl
+ farcall CheckIfEnergyIsUseful
+ pop hl
+ jr nc, .loop_energy_cards_1
+
+ ld a, [wce1a]
+ cp $ff
+ jr nz, .second_energy_1
+
+; check if there were already chosen cards,
+; if this is the second chosen card, return carry
+
+; first energy card found
+ ld a, b
+ ld [wce1a], a
+ call .RemoveEnergyCardFromList
+ jr .next_play_area
+.second_energy_1
+ ld a, b
+ ld [wce1b], a
+ jr .set_carry
+
+.next_play_area
+ inc e
+ dec d
+ jr nz, .loop_play_area
+
+; next, if there are still energy cards left to choose,
+; loop through the energy cards again and select
+; them in order.
+ ld hl, wDuelTempList
+.loop_energy_cards_2
+ ld a, [hli]
+ cp $ff
+ jr z, .check_chosen
+ ld b, a
+ ld a, [wce1a]
+ cp $ff
+ jr nz, .second_energy_2
+ ld a, b
+ ld [wce1a], a
+ call .RemoveEnergyCardFromList
+ jr .loop_energy_cards_2
+
+.second_energy_2
+ ld a, b
+ ld [wce1b], a
+ jr .set_carry
+
+; will set carry if at least one has been chosen
+.check_chosen
+ ld a, [wce1a]
+ cp $ff
+ jr nz, .set_carry
+.no_carry
+ or a
+ ret
+
+.set_carry
+ ld a, [wce06]
+ scf
+ ret
+; 0x20f27
+
+; function to remove an element from the list
+; and shorten it accordingly
+.RemoveEnergyCardFromList: ; 20f27 (8:4f27)
+ push de
+ ld d, h
+ ld e, l
+ dec hl
+ push hl
+.loop_remove
+ ld a, [de]
+ ld [hli], a
+ cp $ff
+ jr z, .done_remove
+ inc de
+ jr .loop_remove
+.done_remove
+ pop hl
+ pop de
+ ret
+; 0x20f38
+
+; returns carry if duplicate cards with found for
+; at least one Pokemon card and at least one Non-Pokemon card
+.CheckDuplicatePokemonAndNonPokemonCards ; 20f38 (8:4f38)
+ ld a, $ff
+ ld [wce0f], a
+ ld [wce0f + 1], a
+ push hl
+
+.loop_outer
+; get ID of current card
+ pop hl
+ ld a, [hli]
+ cp $ff
+ jr z, .check_found
+ call GetCardIDFromDeckIndex
+ ld b, e
+ push hl
+
+; loop the rest of the list to find
+; another card with the same ID
+.loop_inner
+ ld a, [hli]
+ cp $ff
+ jr z, .loop_outer
+ ld c, a
+ call GetCardIDFromDeckIndex
+ ld a, e
+ cp b
+ jr nz, .loop_inner
+
+; found two cards with same ID
+ push bc
+ call GetCardType
+ pop bc
+ cp TYPE_ENERGY
+ jr c, .not_energy
+
+; they are energy or trainer cards
+; loads wce0f+1 with this card deck index
+ ld a, c
+ ld [wce0f + 1], a
+ jr .loop_outer
+
+.not_energy
+; they are Pokemon cards
+; loads wce0f with this card deck index
+ ld a, c
+ ld [wce0f], a
+ jr .loop_outer
+
+.check_found
+ ld a, [wce0f]
+ cp $ff
+ jr nz, .no_carry_duplicate
+ ld a, [wce0f + 1]
+ cp $ff
+ jr nz, .no_carry_duplicate
+
+; only set carry if duplicate cards were found
+; for both Pokemon and Non-Pokemon cards
+ scf
+ ret
+
+.no_carry_duplicate
+; two cards with the same ID were not found
+; of either Pokemon and Non-Pokemon cards
+ or a
+ ret
+; 0x20f80
+
+ INCROM $20f80, $227f6
+
+; lists in wDuelTempList all the basic energy cards
+; is card location of a.
+; returns carry if none were found.
+; input:
+; a = CARD_LOCATION_* to look
+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
+; 0x2282e
; returns in a the card index of energy card
; attached to Pokémon in Play Area location a,