diff options
Diffstat (limited to 'src/engine/deck_ai')
20 files changed, 2414 insertions, 2522 deletions
diff --git a/src/engine/deck_ai/deck_ai.asm b/src/engine/deck_ai/deck_ai.asm index c8b73f3..97093c7 100644 --- a/src/engine/deck_ai/deck_ai.asm +++ b/src/engine/deck_ai/deck_ai.asm @@ -1,82 +1,82 @@ -; AI card retreat score bonus
-; when the AI retreat routine runs through the Bench to choose
-; a Pokemon to switch to, it looks up in this list and if
-; a card ID matches, applies a retreat score bonus to this card.
-; positive (negative) means more (less) likely to switch to this card.
-ai_retreat: MACRO
- db \1 ; card ID
- db $80 + \2 ; retreat score (ranges between -128 and 127)
-ENDM
-
-; AI card energy attach score bonus
-; when the AI energy attachment routine runs through the Play Area to choose
-; a Pokemon to attach an energy card, it looks up in this list and if
-; a card ID matches, skips this card if the maximum number of energy
-; cards attached has been reached. If it hasn't been reached, additionally
-; applies a positive (or negative) AI score to attach energy to this card.
-ai_energy: MACRO
- db \1 ; card ID
- db \2 ; maximum number of attached cards
- db $80 + \3 ; energy score (ranges between -128 and 127)
-ENDM
-
-; stores in WRAM pointer to data in argument
-; e.g. store_list_pointer wSomeListPointer, SomeData
-store_list_pointer: MACRO
- ld hl, \1
- ld de, \2
- ld [hl], e
- inc hl
- ld [hl], d
-ENDM
-
-; deck AIs are specialized to work on a given deck ID.
-; they decide what happens during a turn, what Pokemon cards
-; to pick during the start of the duel, etc.
-; the different scenarios these are used are listed in AIACTION_* constants.
-; each of these have a pointer table with the following structure:
-; dw .do_turn : never called;
-;
-; dw .do_turn : called to handle the main turn logic, from the beginning
-; of the turn up to the attack (or lack thereof);
-;
-; dw .start_duel : called at the start of the duel to initialize some
-; variables and optionally set up CPU hand and deck;
-;
-; dw .forced_switch : logic to determine what Pokemon to pick when there's
-; an effect that forces AI to switch to Bench card;
-;
-; dw .ko_switch : logic for picking which card to use after a KO;
-;
-; dw .take_prize : logic to decide which prize card to pick.
-
-; optionally, decks can also declare card lists that will add
-; more specialized logic during various generic AI routines,
-; and read during the .start_duel routines.
-; the pointers to these lists are stored in memory:
-; wAICardListAvoidPrize : list of cards to avoid being placed as prize;
-; wAICardListArenaPriority : priority list of Arena card at duel start;
-; wAICardListBenchPriority : priority list of Bench cards at duel start;
-; wAICardListPlayFromHandPriority : priority list of cards to play from hand;
-; wAICardListRetreatBonus : scores given to certain cards for retreat;
-; wAICardListEnergyBonus : max number of energy cards and card scores.
-
-INCLUDE "engine/deck_ai/decks/general.asm"
-INCLUDE "engine/deck_ai/decks/sams_practice.asm"
-INCLUDE "engine/deck_ai/decks/general_no_retreat.asm"
-INCLUDE "engine/deck_ai/decks/legendary_moltres.asm"
-INCLUDE "engine/deck_ai/decks/legendary_zapdos.asm"
-INCLUDE "engine/deck_ai/decks/legendary_articuno.asm"
-INCLUDE "engine/deck_ai/decks/legendary_dragonite.asm"
-INCLUDE "engine/deck_ai/decks/first_strike.asm"
-INCLUDE "engine/deck_ai/decks/rock_crusher.asm"
-INCLUDE "engine/deck_ai/decks/go_go_rain_dance.asm"
-INCLUDE "engine/deck_ai/decks/zapping_selfdestruct.asm"
-INCLUDE "engine/deck_ai/decks/flower_power.asm"
-INCLUDE "engine/deck_ai/decks/strange_psyshock.asm"
-INCLUDE "engine/deck_ai/decks/wonders_of_science.asm"
-INCLUDE "engine/deck_ai/decks/fire_charge.asm"
-INCLUDE "engine/deck_ai/decks/im_ronald.asm"
-INCLUDE "engine/deck_ai/decks/powerful_ronald.asm"
-INCLUDE "engine/deck_ai/decks/invincible_ronald.asm"
-INCLUDE "engine/deck_ai/decks/legendary_ronald.asm"
+; AI card retreat score bonus +; when the AI retreat routine runs through the Bench to choose +; a Pokemon to switch to, it looks up in this list and if +; a card ID matches, applies a retreat score bonus to this card. +; positive (negative) means more (less) likely to switch to this card. +ai_retreat: MACRO + db \1 ; card ID + db $80 + \2 ; retreat score (ranges between -128 and 127) +ENDM + +; AI card energy attach score bonus +; when the AI energy attachment routine runs through the Play Area to choose +; a Pokemon to attach an energy card, it looks up in this list and if +; a card ID matches, skips this card if the maximum number of energy +; cards attached has been reached. If it hasn't been reached, additionally +; applies a positive (or negative) AI score to attach energy to this card. +ai_energy: MACRO + db \1 ; card ID + db \2 ; maximum number of attached cards + db $80 + \3 ; energy score (ranges between -128 and 127) +ENDM + +; stores in WRAM pointer to data in argument +; e.g. store_list_pointer wSomeListPointer, SomeData +store_list_pointer: MACRO + ld hl, \1 + ld de, \2 + ld [hl], e + inc hl + ld [hl], d +ENDM + +; deck AIs are specialized to work on a given deck ID. +; they decide what happens during a turn, what Pokemon cards +; to pick during the start of the duel, etc. +; the different scenarios these are used are listed in AIACTION_* constants. +; each of these have a pointer table with the following structure: +; dw .do_turn : never called; +; +; dw .do_turn : called to handle the main turn logic, from the beginning +; of the turn up to the attack (or lack thereof); +; +; dw .start_duel : called at the start of the duel to initialize some +; variables and optionally set up CPU hand and deck; +; +; dw .forced_switch : logic to determine what Pokemon to pick when there's +; an effect that forces AI to switch to Bench card; +; +; dw .ko_switch : logic for picking which card to use after a KO; +; +; dw .take_prize : logic to decide which prize card to pick. + +; optionally, decks can also declare card lists that will add +; more specialized logic during various generic AI routines, +; and read during the .start_duel routines. +; the pointers to these lists are stored in memory: +; wAICardListAvoidPrize : list of cards to avoid being placed as prize; +; wAICardListArenaPriority : priority list of Arena card at duel start; +; wAICardListBenchPriority : priority list of Bench cards at duel start; +; wAICardListPlayFromHandPriority : priority list of cards to play from hand; +; wAICardListRetreatBonus : scores given to certain cards for retreat; +; wAICardListEnergyBonus : max number of energy cards and card scores. + +INCLUDE "engine/deck_ai/decks/general.asm" +INCLUDE "engine/deck_ai/decks/sams_practice.asm" +INCLUDE "engine/deck_ai/decks/general_no_retreat.asm" +INCLUDE "engine/deck_ai/decks/legendary_moltres.asm" +INCLUDE "engine/deck_ai/decks/legendary_zapdos.asm" +INCLUDE "engine/deck_ai/decks/legendary_articuno.asm" +INCLUDE "engine/deck_ai/decks/legendary_dragonite.asm" +INCLUDE "engine/deck_ai/decks/first_strike.asm" +INCLUDE "engine/deck_ai/decks/rock_crusher.asm" +INCLUDE "engine/deck_ai/decks/go_go_rain_dance.asm" +INCLUDE "engine/deck_ai/decks/zapping_selfdestruct.asm" +INCLUDE "engine/deck_ai/decks/flower_power.asm" +INCLUDE "engine/deck_ai/decks/strange_psyshock.asm" +INCLUDE "engine/deck_ai/decks/wonders_of_science.asm" +INCLUDE "engine/deck_ai/decks/fire_charge.asm" +INCLUDE "engine/deck_ai/decks/im_ronald.asm" +INCLUDE "engine/deck_ai/decks/powerful_ronald.asm" +INCLUDE "engine/deck_ai/decks/invincible_ronald.asm" +INCLUDE "engine/deck_ai/decks/legendary_ronald.asm" diff --git a/src/engine/deck_ai/decks/fire_charge.asm b/src/engine/deck_ai/decks/fire_charge.asm index 454f731..4253d55 100644 --- a/src/engine/deck_ai/decks/fire_charge.asm +++ b/src/engine/deck_ai/decks/fire_charge.asm @@ -1,86 +1,81 @@ -AIActionTable_FireCharge: ; 15232 (5:5232)
- dw .do_turn ; unused
- dw .do_turn
- dw .start_duel
- dw .forced_switch
- dw .ko_switch
- dw .take_prize
-
-.do_turn ; 1523e (5:523e)
- call AIMainTurnLogic
- ret
-; 0x15242
-
-.start_duel ; 15242 (5:5242)
- call InitAIDuelVars
- call .store_list_pointers
- call SetUpBossStartingHandAndDeck
- call TrySetUpBossStartingPlayArea
- ret nc
- call AIPlayInitialBasicCards
- ret
-; 0x15253
-
-.forced_switch ; 15253 (5:5253)
- call AIDecideBenchPokemonToSwitchTo
- ret
-; 0x15257
-
-.ko_switch ; 15257 (5:5257)
- call AIDecideBenchPokemonToSwitchTo
- ret
-; 0x1525b
-
-.take_prize ; 1525b (5:525b)
- call AIPickPrizeCards
- ret
-; 0x1525f
-
-.list_arena ; 1525f (5:525f)
- db JIGGLYPUFF3
- db CHANSEY
- db TAUROS
- db MAGMAR1
- db JIGGLYPUFF1
- db GROWLITHE
- db $00
-
-.list_bench ; 15266 (5:5266)
- db JIGGLYPUFF3
- db CHANSEY
- db GROWLITHE
- db MAGMAR1
- db JIGGLYPUFF1
- db TAUROS
- db $00
-
-.list_retreat ; 1526e (5:526e)
- ai_retreat JIGGLYPUFF1, -1
- ai_retreat CHANSEY, -1
- ai_retreat GROWLITHE, -1
- db $00
-
-.list_energy ; 15274 (5:5274)
- ai_energy GROWLITHE, 3, +0
- ai_energy ARCANINE2, 4, +0
- ai_energy MAGMAR1, 3, +0
- ai_energy JIGGLYPUFF1, 3, +0
- ai_energy JIGGLYPUFF3, 2, +0
- ai_energy WIGGLYTUFF, 3, +0
- ai_energy CHANSEY, 4, +0
- ai_energy TAUROS, 3, +0
- db $00
-
-.list_prize ; 1528d (5:528d)
- db GAMBLER
- db $00
-
-.store_list_pointers ; 1528f (5:528f)
- store_list_pointer wAICardListAvoidPrize, .list_prize
- store_list_pointer wAICardListArenaPriority, .list_arena
- store_list_pointer wAICardListBenchPriority, .list_bench
- store_list_pointer wAICardListPlayFromHandPriority, .list_bench
- ; missing store_list_pointer wAICardListRetreatBonus, .list_retreat
- store_list_pointer wAICardListEnergyBonus, .list_energy
- ret
-; 0x152bd
+AIActionTable_FireCharge: ; 15232 (5:5232) + dw .do_turn ; unused + dw .do_turn + dw .start_duel + dw .forced_switch + dw .ko_switch + dw .take_prize + +.do_turn ; 1523e (5:523e) + call AIMainTurnLogic + ret + +.start_duel ; 15242 (5:5242) + call InitAIDuelVars + call .store_list_pointers + call SetUpBossStartingHandAndDeck + call TrySetUpBossStartingPlayArea + ret nc + call AIPlayInitialBasicCards + ret + +.forced_switch ; 15253 (5:5253) + call AIDecideBenchPokemonToSwitchTo + ret + +.ko_switch ; 15257 (5:5257) + call AIDecideBenchPokemonToSwitchTo + ret + +.take_prize ; 1525b (5:525b) + call AIPickPrizeCards + ret + +.list_arena ; 1525f (5:525f) + db JIGGLYPUFF3 + db CHANSEY + db TAUROS + db MAGMAR1 + db JIGGLYPUFF1 + db GROWLITHE + db $00 + +.list_bench ; 15266 (5:5266) + db JIGGLYPUFF3 + db CHANSEY + db GROWLITHE + db MAGMAR1 + db JIGGLYPUFF1 + db TAUROS + db $00 + +.list_retreat ; 1526e (5:526e) + ai_retreat JIGGLYPUFF1, -1 + ai_retreat CHANSEY, -1 + ai_retreat GROWLITHE, -1 + db $00 + +.list_energy ; 15274 (5:5274) + ai_energy GROWLITHE, 3, +0 + ai_energy ARCANINE2, 4, +0 + ai_energy MAGMAR1, 3, +0 + ai_energy JIGGLYPUFF1, 3, +0 + ai_energy JIGGLYPUFF3, 2, +0 + ai_energy WIGGLYTUFF, 3, +0 + ai_energy CHANSEY, 4, +0 + ai_energy TAUROS, 3, +0 + db $00 + +.list_prize ; 1528d (5:528d) + db GAMBLER + db $00 + +.store_list_pointers ; 1528f (5:528f) + store_list_pointer wAICardListAvoidPrize, .list_prize + store_list_pointer wAICardListArenaPriority, .list_arena + store_list_pointer wAICardListBenchPriority, .list_bench + store_list_pointer wAICardListPlayFromHandPriority, .list_bench + ; missing store_list_pointer wAICardListRetreatBonus, .list_retreat + store_list_pointer wAICardListEnergyBonus, .list_energy + ret +; 0x152bd diff --git a/src/engine/deck_ai/decks/first_strike.asm b/src/engine/deck_ai/decks/first_strike.asm index 6d2906c..9f5934d 100644 --- a/src/engine/deck_ai/decks/first_strike.asm +++ b/src/engine/deck_ai/decks/first_strike.asm @@ -1,82 +1,77 @@ -AIActionTable_FirstStrike: ; 14e89 (5:4e89)
- dw .do_turn ; unused
- dw .do_turn
- dw .start_duel
- dw .forced_switch
- dw .ko_switch
- dw .take_prize
-
-.do_turn ; 14e95 (5:4e95)
- call AIMainTurnLogic
- ret
-; 0x14e99
-
-.start_duel ; 14e99 (5:4e99)
- call InitAIDuelVars
- call .store_list_pointers
- call SetUpBossStartingHandAndDeck
- call TrySetUpBossStartingPlayArea
- ret nc
- call AIPlayInitialBasicCards
- ret
-; 0x14eaa
-
-.forced_switch ; 14eaa (5:4eaa)
- call AIDecideBenchPokemonToSwitchTo
- ret
-; 0x14eae
-
-.ko_switch ; 14eae (5:4eae)
- call AIDecideBenchPokemonToSwitchTo
- ret
-; 0x14eb2
-
-.take_prize ; 14eb2 (5:4eb2)
- call AIPickPrizeCards
- ret
-; 0x14eb6
-
-.list_arena ; 14eb6 (5:1eb6)
- db HITMONCHAN
- db MACHOP
- db HITMONLEE
- db MANKEY
- db $00
-
-.list_bench ; 14ebb (5:1ebb)
- db MACHOP
- db HITMONLEE
- db HITMONCHAN
- db MANKEY
- db $00
-
-.list_retreat ; 14ec0 (5:1ec0)
- ai_retreat MACHOP, -1
- ai_retreat MACHOKE, -1
- ai_retreat MANKEY, -2
- db $00
-
-.list_energy ; 14ec7 (5:1ec7)
- ai_energy MACHOP, 3, +0
- ai_energy MACHOKE, 4, +0
- ai_energy MACHAMP, 4, -1
- ai_energy HITMONCHAN, 3, +0
- ai_energy HITMONLEE, 3, +0
- ai_energy MANKEY, 2, -1
- ai_energy PRIMEAPE, 3, -1
- db $00
-
-.list_prize ; 14edd (5:1edd)
- db HITMONLEE
- db HITMONCHAN
- db $00
-
-.store_list_pointers ; 14ee0 (5:4ee0)
- store_list_pointer wAICardListAvoidPrize, .list_prize
- store_list_pointer wAICardListArenaPriority, .list_arena
- store_list_pointer wAICardListBenchPriority, .list_bench
- store_list_pointer wAICardListPlayFromHandPriority, .list_bench
- ; missing store_list_pointer wAICardListRetreatBonus, .list_retreat
- store_list_pointer wAICardListEnergyBonus, .list_energy
- ret
-; 0x14f0e
+AIActionTable_FirstStrike: ; 14e89 (5:4e89) + dw .do_turn ; unused + dw .do_turn + dw .start_duel + dw .forced_switch + dw .ko_switch + dw .take_prize + +.do_turn ; 14e95 (5:4e95) + call AIMainTurnLogic + ret + +.start_duel ; 14e99 (5:4e99) + call InitAIDuelVars + call .store_list_pointers + call SetUpBossStartingHandAndDeck + call TrySetUpBossStartingPlayArea + ret nc + call AIPlayInitialBasicCards + ret + +.forced_switch ; 14eaa (5:4eaa) + call AIDecideBenchPokemonToSwitchTo + ret + +.ko_switch ; 14eae (5:4eae) + call AIDecideBenchPokemonToSwitchTo + ret + +.take_prize ; 14eb2 (5:4eb2) + call AIPickPrizeCards + ret + +.list_arena ; 14eb6 (5:1eb6) + db HITMONCHAN + db MACHOP + db HITMONLEE + db MANKEY + db $00 + +.list_bench ; 14ebb (5:1ebb) + db MACHOP + db HITMONLEE + db HITMONCHAN + db MANKEY + db $00 + +.list_retreat ; 14ec0 (5:1ec0) + ai_retreat MACHOP, -1 + ai_retreat MACHOKE, -1 + ai_retreat MANKEY, -2 + db $00 + +.list_energy ; 14ec7 (5:1ec7) + ai_energy MACHOP, 3, +0 + ai_energy MACHOKE, 4, +0 + ai_energy MACHAMP, 4, -1 + ai_energy HITMONCHAN, 3, +0 + ai_energy HITMONLEE, 3, +0 + ai_energy MANKEY, 2, -1 + ai_energy PRIMEAPE, 3, -1 + db $00 + +.list_prize ; 14edd (5:1edd) + db HITMONLEE + db HITMONCHAN + db $00 + +.store_list_pointers ; 14ee0 (5:4ee0) + store_list_pointer wAICardListAvoidPrize, .list_prize + store_list_pointer wAICardListArenaPriority, .list_arena + store_list_pointer wAICardListBenchPriority, .list_bench + store_list_pointer wAICardListPlayFromHandPriority, .list_bench + ; missing store_list_pointer wAICardListRetreatBonus, .list_retreat + store_list_pointer wAICardListEnergyBonus, .list_energy + ret +; 0x14f0e diff --git a/src/engine/deck_ai/decks/flower_power.asm b/src/engine/deck_ai/decks/flower_power.asm index 566d064..47bbd55 100644 --- a/src/engine/deck_ai/decks/flower_power.asm +++ b/src/engine/deck_ai/decks/flower_power.asm @@ -1,81 +1,76 @@ -AIActionTable_FlowerPower: ; 1509b (5:509b)
- dw .do_turn ; unused
- dw .do_turn
- dw .start_duel
- dw .forced_switch
- dw .ko_switch
- dw .take_prize
-
-.do_turn ; 150a7 (5:50a7)
- call AIMainTurnLogic
- ret
-; 0x150ab
-
-.start_duel ; 150ab (5:50ab)
- call InitAIDuelVars
- call .store_list_pointers
- call SetUpBossStartingHandAndDeck
- call TrySetUpBossStartingPlayArea
- ret nc
- call AIPlayInitialBasicCards
- ret
-; 0x150bc
-
-.forced_switch ; 150bc (5:50bc)
- call AIDecideBenchPokemonToSwitchTo
- ret
-; 0x150c0
-
-.ko_switch ; 150c0 (5:50c0)
- call AIDecideBenchPokemonToSwitchTo
- ret
-; 0x150c4
-
-.take_prize ; 150c4 (5:50c4)
- call AIPickPrizeCards
- ret
-; 0x150c8
-
-.list_arena ; 150c8 (5:50c8)
- db ODDISH
- db EXEGGCUTE
- db BULBASAUR
- db $00
-
-.list_bench ; 150cc (5:50cc)
- db BULBASAUR
- db EXEGGCUTE
- db ODDISH
- db $00
-
-.list_retreat ; 150cf (5:50cf)
- ai_retreat GLOOM, -2
- ai_retreat VILEPLUME, -2
- ai_retreat BULBASAUR, -2
- ai_retreat IVYSAUR, -2
- db $00
-
-.list_energy ; 150d9 (5:50d9)
- ai_energy BULBASAUR, 3, +0
- ai_energy IVYSAUR, 4, +0
- ai_energy VENUSAUR2, 4, +0
- ai_energy ODDISH, 2, +0
- ai_energy GLOOM, 3, -1
- ai_energy VILEPLUME, 3, -1
- ai_energy EXEGGCUTE, 3, +0
- ai_energy EXEGGUTOR, 22, +0
- db $00
-
-.list_prize ; 150f2 (5:50f2)
- db VENUSAUR2
- db $00
-
-.store_list_pointers ; 150f4 (5:50f4)
- store_list_pointer wAICardListAvoidPrize, .list_prize
- store_list_pointer wAICardListArenaPriority, .list_arena
- store_list_pointer wAICardListBenchPriority, .list_bench
- store_list_pointer wAICardListPlayFromHandPriority, .list_bench
- ; missing store_list_pointer wAICardListRetreatBonus, .list_retreat
- store_list_pointer wAICardListEnergyBonus, .list_energy
- ret
-; 0x15122
+AIActionTable_FlowerPower: ; 1509b (5:509b) + dw .do_turn ; unused + dw .do_turn + dw .start_duel + dw .forced_switch + dw .ko_switch + dw .take_prize + +.do_turn ; 150a7 (5:50a7) + call AIMainTurnLogic + ret + +.start_duel ; 150ab (5:50ab) + call InitAIDuelVars + call .store_list_pointers + call SetUpBossStartingHandAndDeck + call TrySetUpBossStartingPlayArea + ret nc + call AIPlayInitialBasicCards + ret + +.forced_switch ; 150bc (5:50bc) + call AIDecideBenchPokemonToSwitchTo + ret + +.ko_switch ; 150c0 (5:50c0) + call AIDecideBenchPokemonToSwitchTo + ret + +.take_prize ; 150c4 (5:50c4) + call AIPickPrizeCards + ret + +.list_arena ; 150c8 (5:50c8) + db ODDISH + db EXEGGCUTE + db BULBASAUR + db $00 + +.list_bench ; 150cc (5:50cc) + db BULBASAUR + db EXEGGCUTE + db ODDISH + db $00 + +.list_retreat ; 150cf (5:50cf) + ai_retreat GLOOM, -2 + ai_retreat VILEPLUME, -2 + ai_retreat BULBASAUR, -2 + ai_retreat IVYSAUR, -2 + db $00 + +.list_energy ; 150d9 (5:50d9) + ai_energy BULBASAUR, 3, +0 + ai_energy IVYSAUR, 4, +0 + ai_energy VENUSAUR2, 4, +0 + ai_energy ODDISH, 2, +0 + ai_energy GLOOM, 3, -1 + ai_energy VILEPLUME, 3, -1 + ai_energy EXEGGCUTE, 3, +0 + ai_energy EXEGGUTOR, 22, +0 + db $00 + +.list_prize ; 150f2 (5:50f2) + db VENUSAUR2 + db $00 + +.store_list_pointers ; 150f4 (5:50f4) + store_list_pointer wAICardListAvoidPrize, .list_prize + store_list_pointer wAICardListArenaPriority, .list_arena + store_list_pointer wAICardListBenchPriority, .list_bench + store_list_pointer wAICardListPlayFromHandPriority, .list_bench + ; missing store_list_pointer wAICardListRetreatBonus, .list_retreat + store_list_pointer wAICardListEnergyBonus, .list_energy + ret +; 0x15122 diff --git a/src/engine/deck_ai/decks/general.asm b/src/engine/deck_ai/decks/general.asm index 1bfc3e0..dd9060e 100644 --- a/src/engine/deck_ai/decks/general.asm +++ b/src/engine/deck_ai/decks/general.asm @@ -1,196 +1,195 @@ -; AI logic used by general decks
-AIActionTable_GeneralDecks: ; 14668 (05:4668)
- dw .do_turn ; unused
- dw .do_turn
- dw .start_duel
- dw .forced_switch
- dw .ko_switch
- dw .take_prize
-
-.do_turn ; 14674 (5:4674)
- call AIMainTurnLogic
- ret
-
-.start_duel ; 14678 (5:4678)
- call InitAIDuelVars
- call AIPlayInitialBasicCards
- ret
-
-.forced_switch ; 1467f (5:467f)
- call AIDecideBenchPokemonToSwitchTo
- ret
-
-.ko_switch ; 14683 (5:4683)
- call AIDecideBenchPokemonToSwitchTo
- ret
-
-.take_prize: ; 14687 (5:4687)
- call AIPickPrizeCards
- ret
-
-; handle AI routines for a whole turn
-AIMainTurnLogic: ; 1468b (5:468b)
-; initialize variables
- call InitAITurnVars
- ld a, AI_TRAINER_CARD_PHASE_01
- call AIProcessHandTrainerCards
- farcall HandleAIAntiMewtwoDeckStrategy
- jp nc, .try_attack
-; handle Pkmn Powers
- farcall HandleAIGoGoRainDanceEnergy
- farcall HandleAIDamageSwap
- farcall HandleAIPkmnPowers
- ret c ; return if turn ended
- farcall HandleAICowardice
-; process Trainer cards
-; phase 2 through 4.
- ld a, AI_TRAINER_CARD_PHASE_02
- call AIProcessHandTrainerCards
- ld a, AI_TRAINER_CARD_PHASE_03
- call AIProcessHandTrainerCards
- ld a, AI_TRAINER_CARD_PHASE_04
- call AIProcessHandTrainerCards
-; play Pokemon from hand
- call AIDecidePlayPokemonCard
- ret c ; return if turn ended
-; process Trainer cards
-; phase 5 through 12.
- ld a, AI_TRAINER_CARD_PHASE_05
- call AIProcessHandTrainerCards
- ld a, AI_TRAINER_CARD_PHASE_06
- call AIProcessHandTrainerCards
- ld a, AI_TRAINER_CARD_PHASE_07
- call AIProcessHandTrainerCards
- ld a, AI_TRAINER_CARD_PHASE_08
- call AIProcessHandTrainerCards
- call AIProcessRetreat
- ld a, AI_TRAINER_CARD_PHASE_10
- call AIProcessHandTrainerCards
- ld a, AI_TRAINER_CARD_PHASE_11
- call AIProcessHandTrainerCards
- ld a, AI_TRAINER_CARD_PHASE_12
- call AIProcessHandTrainerCards
-; play Energy card if possible
- ld a, [wAlreadyPlayedEnergy]
- or a
- jr nz, .skip_energy_attach_1
- call AIProcessAndTryToPlayEnergy
-.skip_energy_attach_1
-; play Pokemon from hand again
- call AIDecidePlayPokemonCard
-; handle Pkmn Powers again
- farcall HandleAIDamageSwap
- farcall HandleAIPkmnPowers
- ret c ; return if turn ended
- farcall HandleAIGoGoRainDanceEnergy
- ld a, AI_ENERGY_TRANS_ATTACK
- farcall HandleAIEnergyTrans
-; process Trainer cards phases 13 and 15
- ld a, AI_TRAINER_CARD_PHASE_13
- call AIProcessHandTrainerCards
- ld a, AI_TRAINER_CARD_PHASE_15
- call AIProcessHandTrainerCards
-; if used Professor Oak, process new hand
-; if not, then proceed to attack.
- ld a, [wPreviousAIFlags]
- and AI_FLAG_USED_PROFESSOR_OAK
- jr z, .try_attack
- ld a, AI_TRAINER_CARD_PHASE_01
- call AIProcessHandTrainerCards
- ld a, AI_TRAINER_CARD_PHASE_02
- call AIProcessHandTrainerCards
- ld a, AI_TRAINER_CARD_PHASE_03
- call AIProcessHandTrainerCards
- ld a, AI_TRAINER_CARD_PHASE_04
- call AIProcessHandTrainerCards
- call AIDecidePlayPokemonCard
- ret c ; return if turn ended
- ld a, AI_TRAINER_CARD_PHASE_05
- call AIProcessHandTrainerCards
- ld a, AI_TRAINER_CARD_PHASE_06
- call AIProcessHandTrainerCards
- ld a, AI_TRAINER_CARD_PHASE_07
- call AIProcessHandTrainerCards
- ld a, AI_TRAINER_CARD_PHASE_08
- call AIProcessHandTrainerCards
- call AIProcessRetreat
- ld a, AI_TRAINER_CARD_PHASE_10
- call AIProcessHandTrainerCards
- ld a, AI_TRAINER_CARD_PHASE_11
- call AIProcessHandTrainerCards
- ld a, AI_TRAINER_CARD_PHASE_12
- call AIProcessHandTrainerCards
- ld a, [wAlreadyPlayedEnergy]
- or a
- jr nz, .skip_energy_attach_2
- call AIProcessAndTryToPlayEnergy
-.skip_energy_attach_2
- call AIDecidePlayPokemonCard
- farcall HandleAIDamageSwap
- farcall HandleAIPkmnPowers
- ret c ; return if turn ended
- farcall HandleAIGoGoRainDanceEnergy
- ld a, AI_ENERGY_TRANS_ATTACK
- farcall HandleAIEnergyTrans
- ld a, AI_TRAINER_CARD_PHASE_13
- call AIProcessHandTrainerCards
- ; skip AI_TRAINER_CARD_PHASE_15
-.try_attack
- ld a, AI_ENERGY_TRANS_TO_BENCH
- farcall HandleAIEnergyTrans
-; attack if possible, if not,
-; finish turn without attacking.
- call AIProcessAndTryToUseAttack
- ret c ; return if AI attacked
- ld a, OPPACTION_FINISH_NO_ATTACK
- bank1call AIMakeDecision
- ret
-; 0x14786
-
-; handles AI retreating logic
-AIProcessRetreat: ; 14786 (5:4786)
- ld a, [wAIRetreatedThisTurn]
- or a
- ret nz ; return, already retreated this turn
-
- call AIDecideWhetherToRetreat
- ret nc ; return if not retreating
-
- call AIDecideBenchPokemonToSwitchTo
- ret c ; return if no Bench Pokemon
-
-; store Play Area to retreat to and
-; set wAIRetreatedThisTurn to true
- ld [wAIPlayAreaCardToSwitch], a
- ld a, $01
- ld [wAIRetreatedThisTurn], a
-
-; if AI can use Switch from hand, use it instead...
- ld a, AI_TRAINER_CARD_PHASE_09
- call AIProcessHandTrainerCards
- ld a, [wPreviousAIFlags]
- and AI_FLAG_USED_SWITCH
- jr nz, .used_switch
-; ... else try retreating normally.
- ld a, [wAIPlayAreaCardToSwitch]
- call AITryToRetreat
- ret
-
-.used_switch
-; if AI used switch, unset its AI flag
- ld a, [wPreviousAIFlags]
- and ~AI_FLAG_USED_SWITCH ; clear Switch flag
- ld [wPreviousAIFlags], a
-
-; bug, this doesn't make sense being here, since at this point
-; Switch Trainer card was already used to retreat the Pokemon.
-; what the routine will do is just transfer Energy cards to
-; the Arena Pokemon for the purpose of retreating, and
-; then not actually retreat, resulting in unusual behaviour.
-; this would only work placed right after the AI checks whether
-; they have Switch card in hand to use and doesn't have one.
-; (and probably that was the original intention.)
- ld a, AI_ENERGY_TRANS_RETREAT ; retreat
- farcall HandleAIEnergyTrans
- ret
-; 0x147bd
+; AI logic used by general decks +AIActionTable_GeneralDecks: ; 14668 (05:4668) + dw .do_turn ; unused + dw .do_turn + dw .start_duel + dw .forced_switch + dw .ko_switch + dw .take_prize + +.do_turn ; 14674 (5:4674) + call AIMainTurnLogic + ret + +.start_duel ; 14678 (5:4678) + call InitAIDuelVars + call AIPlayInitialBasicCards + ret + +.forced_switch ; 1467f (5:467f) + call AIDecideBenchPokemonToSwitchTo + ret + +.ko_switch ; 14683 (5:4683) + call AIDecideBenchPokemonToSwitchTo + ret + +.take_prize: ; 14687 (5:4687) + call AIPickPrizeCards + ret + +; handle AI routines for a whole turn +AIMainTurnLogic: ; 1468b (5:468b) +; initialize variables + call InitAITurnVars + ld a, AI_TRAINER_CARD_PHASE_01 + call AIProcessHandTrainerCards + farcall HandleAIAntiMewtwoDeckStrategy + jp nc, .try_attack +; handle Pkmn Powers + farcall HandleAIGoGoRainDanceEnergy + farcall HandleAIDamageSwap + farcall HandleAIPkmnPowers + ret c ; return if turn ended + farcall HandleAICowardice +; process Trainer cards +; phase 2 through 4. + ld a, AI_TRAINER_CARD_PHASE_02 + call AIProcessHandTrainerCards + ld a, AI_TRAINER_CARD_PHASE_03 + call AIProcessHandTrainerCards + ld a, AI_TRAINER_CARD_PHASE_04 + call AIProcessHandTrainerCards +; play Pokemon from hand + call AIDecidePlayPokemonCard + ret c ; return if turn ended +; process Trainer cards +; phase 5 through 12. + ld a, AI_TRAINER_CARD_PHASE_05 + call AIProcessHandTrainerCards + ld a, AI_TRAINER_CARD_PHASE_06 + call AIProcessHandTrainerCards + ld a, AI_TRAINER_CARD_PHASE_07 + call AIProcessHandTrainerCards + ld a, AI_TRAINER_CARD_PHASE_08 + call AIProcessHandTrainerCards + call AIProcessRetreat + ld a, AI_TRAINER_CARD_PHASE_10 + call AIProcessHandTrainerCards + ld a, AI_TRAINER_CARD_PHASE_11 + call AIProcessHandTrainerCards + ld a, AI_TRAINER_CARD_PHASE_12 + call AIProcessHandTrainerCards +; play Energy card if possible + ld a, [wAlreadyPlayedEnergy] + or a + jr nz, .skip_energy_attach_1 + call AIProcessAndTryToPlayEnergy +.skip_energy_attach_1 +; play Pokemon from hand again + call AIDecidePlayPokemonCard +; handle Pkmn Powers again + farcall HandleAIDamageSwap + farcall HandleAIPkmnPowers + ret c ; return if turn ended + farcall HandleAIGoGoRainDanceEnergy + ld a, AI_ENERGY_TRANS_ATTACK + farcall HandleAIEnergyTrans +; process Trainer cards phases 13 and 15 + ld a, AI_TRAINER_CARD_PHASE_13 + call AIProcessHandTrainerCards + ld a, AI_TRAINER_CARD_PHASE_15 + call AIProcessHandTrainerCards +; if used Professor Oak, process new hand +; if not, then proceed to attack. + ld a, [wPreviousAIFlags] + and AI_FLAG_USED_PROFESSOR_OAK + jr z, .try_attack + ld a, AI_TRAINER_CARD_PHASE_01 + call AIProcessHandTrainerCards + ld a, AI_TRAINER_CARD_PHASE_02 + call AIProcessHandTrainerCards + ld a, AI_TRAINER_CARD_PHASE_03 + call AIProcessHandTrainerCards + ld a, AI_TRAINER_CARD_PHASE_04 + call AIProcessHandTrainerCards + call AIDecidePlayPokemonCard + ret c ; return if turn ended + ld a, AI_TRAINER_CARD_PHASE_05 + call AIProcessHandTrainerCards + ld a, AI_TRAINER_CARD_PHASE_06 + call AIProcessHandTrainerCards + ld a, AI_TRAINER_CARD_PHASE_07 + call AIProcessHandTrainerCards + ld a, AI_TRAINER_CARD_PHASE_08 + call AIProcessHandTrainerCards + call AIProcessRetreat + ld a, AI_TRAINER_CARD_PHASE_10 + call AIProcessHandTrainerCards + ld a, AI_TRAINER_CARD_PHASE_11 + call AIProcessHandTrainerCards + ld a, AI_TRAINER_CARD_PHASE_12 + call AIProcessHandTrainerCards + ld a, [wAlreadyPlayedEnergy] + or a + jr nz, .skip_energy_attach_2 + call AIProcessAndTryToPlayEnergy +.skip_energy_attach_2 + call AIDecidePlayPokemonCard + farcall HandleAIDamageSwap + farcall HandleAIPkmnPowers + ret c ; return if turn ended + farcall HandleAIGoGoRainDanceEnergy + ld a, AI_ENERGY_TRANS_ATTACK + farcall HandleAIEnergyTrans + ld a, AI_TRAINER_CARD_PHASE_13 + call AIProcessHandTrainerCards + ; skip AI_TRAINER_CARD_PHASE_15 +.try_attack + ld a, AI_ENERGY_TRANS_TO_BENCH + farcall HandleAIEnergyTrans +; attack if possible, if not, +; finish turn without attacking. + call AIProcessAndTryToUseAttack + ret c ; return if AI attacked + ld a, OPPACTION_FINISH_NO_ATTACK + bank1call AIMakeDecision + ret + +; handles AI retreating logic +AIProcessRetreat: ; 14786 (5:4786) + ld a, [wAIRetreatedThisTurn] + or a + ret nz ; return, already retreated this turn + + call AIDecideWhetherToRetreat + ret nc ; return if not retreating + + call AIDecideBenchPokemonToSwitchTo + ret c ; return if no Bench Pokemon + +; store Play Area to retreat to and +; set wAIRetreatedThisTurn to true + ld [wAIPlayAreaCardToSwitch], a + ld a, $01 + ld [wAIRetreatedThisTurn], a + +; if AI can use Switch from hand, use it instead... + ld a, AI_TRAINER_CARD_PHASE_09 + call AIProcessHandTrainerCards + ld a, [wPreviousAIFlags] + and AI_FLAG_USED_SWITCH + jr nz, .used_switch +; ... else try retreating normally. + ld a, [wAIPlayAreaCardToSwitch] + call AITryToRetreat + ret + +.used_switch +; if AI used switch, unset its AI flag + ld a, [wPreviousAIFlags] + and ~AI_FLAG_USED_SWITCH ; clear Switch flag + ld [wPreviousAIFlags], a + +; bug, this doesn't make sense being here, since at this point +; Switch Trainer card was already used to retreat the Pokemon. +; what the routine will do is just transfer Energy cards to +; the Arena Pokemon for the purpose of retreating, and +; then not actually retreat, resulting in unusual behaviour. +; this would only work placed right after the AI checks whether +; they have Switch card in hand to use and doesn't have one. +; (and probably that was the original intention.) + ld a, AI_ENERGY_TRANS_RETREAT ; retreat + farcall HandleAIEnergyTrans + ret +; 0x147bd diff --git a/src/engine/deck_ai/decks/general_no_retreat.asm b/src/engine/deck_ai/decks/general_no_retreat.asm index e735076..4b962d4 100644 --- a/src/engine/deck_ai/decks/general_no_retreat.asm +++ b/src/engine/deck_ai/decks/general_no_retreat.asm @@ -1,146 +1,141 @@ -; acts just like a general deck AI except never retreats
-AIActionTable_GeneralNoRetreat: ; 148dc (5:48dc)
- dw .do_turn ; unused
- dw .do_turn
- dw .start_duel
- dw .forced_switch
- dw .ko_switch
- dw .take_prize
-
-.do_turn ; 148e8 (5:48e8)
- call AIDoTurn_GeneralNoRetreat
- ret
-; 0x148ec
-
-.start_duel ; 148ec (5:48ec)
- call InitAIDuelVars
- call AIPlayInitialBasicCards
- ret
-; 0x148f3
-
-.forced_switch ; 148f3 (5:48f3)
- call AIDecideBenchPokemonToSwitchTo
- ret
-; 0x148f7
-
-.ko_switch ; 148f7 (5:48f7)
- call AIDecideBenchPokemonToSwitchTo
- ret
-; 0x148fb
-
-.take_prize ; 148fb (5:48fb)
- call AIPickPrizeCards
- ret
-; 0x148ff
-
-AIDoTurn_GeneralNoRetreat: ; 148ff (5:48ff)
-; initialize variables
- call InitAITurnVars
- ld a, AI_TRAINER_CARD_PHASE_01
- call AIProcessHandTrainerCards
- farcall HandleAIAntiMewtwoDeckStrategy
- jp nc, .try_attack
-; handle Pkmn Powers
- farcall HandleAIGoGoRainDanceEnergy
- farcall HandleAIDamageSwap
- farcall HandleAIPkmnPowers
- ret c ; return if turn ended
- farcall HandleAICowardice
-; process Trainer cards
-; phase 2 through 4.
- ld a, AI_TRAINER_CARD_PHASE_02
- call AIProcessHandTrainerCards
- ld a, AI_TRAINER_CARD_PHASE_03
- call AIProcessHandTrainerCards
- ld a, AI_TRAINER_CARD_PHASE_04
- call AIProcessHandTrainerCards
-; play Pokemon from hand
- call AIDecidePlayPokemonCard
- ret c ; return if turn ended
-; process Trainer cards
-; phase 5 through 12.
- ld a, AI_TRAINER_CARD_PHASE_05
- call AIProcessHandTrainerCards
- ld a, AI_TRAINER_CARD_PHASE_06
- call AIProcessHandTrainerCards
- ld a, AI_TRAINER_CARD_PHASE_07
- call AIProcessHandTrainerCards
- ld a, AI_TRAINER_CARD_PHASE_08
- call AIProcessHandTrainerCards
- ld a, AI_TRAINER_CARD_PHASE_10
- call AIProcessHandTrainerCards
- ld a, AI_TRAINER_CARD_PHASE_11
- call AIProcessHandTrainerCards
- ld a, AI_TRAINER_CARD_PHASE_12
- call AIProcessHandTrainerCards
-; play Energy card if possible
- ld a, [wAlreadyPlayedEnergy]
- or a
- jr nz, .skip_energy_attach_1
- call AIProcessAndTryToPlayEnergy
-.skip_energy_attach_1
-; play Pokemon from hand again
- call AIDecidePlayPokemonCard
-; handle Pkmn Powers again
- farcall HandleAIDamageSwap
- farcall HandleAIPkmnPowers
- ret c ; return if turn ended
- farcall HandleAIGoGoRainDanceEnergy
- ld a, AI_ENERGY_TRANS_ATTACK
- farcall HandleAIEnergyTrans
-; process Trainer cards phases 13 and 15
- ld a, AI_TRAINER_CARD_PHASE_13
- call AIProcessHandTrainerCards
- ld a, AI_TRAINER_CARD_PHASE_15
- call AIProcessHandTrainerCards
-; if used Professor Oak, process new hand
-; if not, then proceed to attack.
- ld a, [wPreviousAIFlags]
- and AI_FLAG_USED_PROFESSOR_OAK
- jr z, .try_attack
- ld a, AI_TRAINER_CARD_PHASE_01
- call AIProcessHandTrainerCards
- ld a, AI_TRAINER_CARD_PHASE_02
- call AIProcessHandTrainerCards
- ld a, AI_TRAINER_CARD_PHASE_03
- call AIProcessHandTrainerCards
- ld a, AI_TRAINER_CARD_PHASE_04
- call AIProcessHandTrainerCards
- call AIDecidePlayPokemonCard
- ret c ; return if turn ended
- ld a, AI_TRAINER_CARD_PHASE_05
- call AIProcessHandTrainerCards
- ld a, AI_TRAINER_CARD_PHASE_06
- call AIProcessHandTrainerCards
- ld a, AI_TRAINER_CARD_PHASE_07
- call AIProcessHandTrainerCards
- ld a, AI_TRAINER_CARD_PHASE_08
- call AIProcessHandTrainerCards
- ld a, AI_TRAINER_CARD_PHASE_10
- call AIProcessHandTrainerCards
- ld a, AI_TRAINER_CARD_PHASE_11
- call AIProcessHandTrainerCards
- ld a, AI_TRAINER_CARD_PHASE_12
- call AIProcessHandTrainerCards
- ld a, [wAlreadyPlayedEnergy]
- or a
- jr nz, .skip_energy_attach_2
- call AIProcessAndTryToPlayEnergy
-.skip_energy_attach_2
- call AIDecidePlayPokemonCard
- farcall HandleAIDamageSwap
- farcall HandleAIPkmnPowers
- ret c ; return if turn ended
- farcall HandleAIGoGoRainDanceEnergy
- ld a, AI_TRAINER_CARD_PHASE_13
- call AIProcessHandTrainerCards
- ; skip AI_TRAINER_CARD_PHASE_15
-.try_attack
-; attack if possible, if not,
-; finish turn without attacking.
- call AIProcessAndTryToUseAttack
- ret c ; return if turn ended
- ld a, OPPACTION_FINISH_NO_ATTACK
- bank1call AIMakeDecision
- ret
-; 0x149e8
+; acts just like a general deck AI except never retreats +AIActionTable_GeneralNoRetreat: ; 148dc (5:48dc) + dw .do_turn ; unused + dw .do_turn + dw .start_duel + dw .forced_switch + dw .ko_switch + dw .take_prize + +.do_turn ; 148e8 (5:48e8) + call AIDoTurn_GeneralNoRetreat + ret + +.start_duel ; 148ec (5:48ec) + call InitAIDuelVars + call AIPlayInitialBasicCards + ret + +.forced_switch ; 148f3 (5:48f3) + call AIDecideBenchPokemonToSwitchTo + ret + +.ko_switch ; 148f7 (5:48f7) + call AIDecideBenchPokemonToSwitchTo + ret + +.take_prize ; 148fb (5:48fb) + call AIPickPrizeCards + ret + +AIDoTurn_GeneralNoRetreat: ; 148ff (5:48ff) +; initialize variables + call InitAITurnVars + ld a, AI_TRAINER_CARD_PHASE_01 + call AIProcessHandTrainerCards + farcall HandleAIAntiMewtwoDeckStrategy + jp nc, .try_attack +; handle Pkmn Powers + farcall HandleAIGoGoRainDanceEnergy + farcall HandleAIDamageSwap + farcall HandleAIPkmnPowers + ret c ; return if turn ended + farcall HandleAICowardice +; process Trainer cards +; phase 2 through 4. + ld a, AI_TRAINER_CARD_PHASE_02 + call AIProcessHandTrainerCards + ld a, AI_TRAINER_CARD_PHASE_03 + call AIProcessHandTrainerCards + ld a, AI_TRAINER_CARD_PHASE_04 + call AIProcessHandTrainerCards +; play Pokemon from hand + call AIDecidePlayPokemonCard + ret c ; return if turn ended +; process Trainer cards +; phase 5 through 12. + ld a, AI_TRAINER_CARD_PHASE_05 + call AIProcessHandTrainerCards + ld a, AI_TRAINER_CARD_PHASE_06 + call AIProcessHandTrainerCards + ld a, AI_TRAINER_CARD_PHASE_07 + call AIProcessHandTrainerCards + ld a, AI_TRAINER_CARD_PHASE_08 + call AIProcessHandTrainerCards + ld a, AI_TRAINER_CARD_PHASE_10 + call AIProcessHandTrainerCards + ld a, AI_TRAINER_CARD_PHASE_11 + call AIProcessHandTrainerCards + ld a, AI_TRAINER_CARD_PHASE_12 + call AIProcessHandTrainerCards +; play Energy card if possible + ld a, [wAlreadyPlayedEnergy] + or a + jr nz, .skip_energy_attach_1 + call AIProcessAndTryToPlayEnergy +.skip_energy_attach_1 +; play Pokemon from hand again + call AIDecidePlayPokemonCard +; handle Pkmn Powers again + farcall HandleAIDamageSwap + farcall HandleAIPkmnPowers + ret c ; return if turn ended + farcall HandleAIGoGoRainDanceEnergy + ld a, AI_ENERGY_TRANS_ATTACK + farcall HandleAIEnergyTrans +; process Trainer cards phases 13 and 15 + ld a, AI_TRAINER_CARD_PHASE_13 + call AIProcessHandTrainerCards + ld a, AI_TRAINER_CARD_PHASE_15 + call AIProcessHandTrainerCards +; if used Professor Oak, process new hand +; if not, then proceed to attack. + ld a, [wPreviousAIFlags] + and AI_FLAG_USED_PROFESSOR_OAK + jr z, .try_attack + ld a, AI_TRAINER_CARD_PHASE_01 + call AIProcessHandTrainerCards + ld a, AI_TRAINER_CARD_PHASE_02 + call AIProcessHandTrainerCards + ld a, AI_TRAINER_CARD_PHASE_03 + call AIProcessHandTrainerCards + ld a, AI_TRAINER_CARD_PHASE_04 + call AIProcessHandTrainerCards + call AIDecidePlayPokemonCard + ret c ; return if turn ended + ld a, AI_TRAINER_CARD_PHASE_05 + call AIProcessHandTrainerCards + ld a, AI_TRAINER_CARD_PHASE_06 + call AIProcessHandTrainerCards + ld a, AI_TRAINER_CARD_PHASE_07 + call AIProcessHandTrainerCards + ld a, AI_TRAINER_CARD_PHASE_08 + call AIProcessHandTrainerCards + ld a, AI_TRAINER_CARD_PHASE_10 + call AIProcessHandTrainerCards + ld a, AI_TRAINER_CARD_PHASE_11 + call AIProcessHandTrainerCards + ld a, AI_TRAINER_CARD_PHASE_12 + call AIProcessHandTrainerCards + ld a, [wAlreadyPlayedEnergy] + or a + jr nz, .skip_energy_attach_2 + call AIProcessAndTryToPlayEnergy +.skip_energy_attach_2 + call AIDecidePlayPokemonCard + farcall HandleAIDamageSwap + farcall HandleAIPkmnPowers + ret c ; return if turn ended + farcall HandleAIGoGoRainDanceEnergy + ld a, AI_TRAINER_CARD_PHASE_13 + call AIProcessHandTrainerCards + ; skip AI_TRAINER_CARD_PHASE_15 +.try_attack +; attack if possible, if not, +; finish turn without attacking. + call AIProcessAndTryToUseAttack + ret c ; return if turn ended + ld a, OPPACTION_FINISH_NO_ATTACK + bank1call AIMakeDecision + ret +; 0x149e8 diff --git a/src/engine/deck_ai/decks/go_go_rain_dance.asm b/src/engine/deck_ai/decks/go_go_rain_dance.asm index 006bbdc..cf18893 100644 --- a/src/engine/deck_ai/decks/go_go_rain_dance.asm +++ b/src/engine/deck_ai/decks/go_go_rain_dance.asm @@ -1,85 +1,80 @@ -AIActionTable_GoGoRainDance: ; 14f8f (5:4f8f)
- dw .do_turn ; unused
- dw .do_turn
- dw .start_duel
- dw .forced_switch
- dw .ko_switch
- dw .take_prize
-
-.do_turn ; 14f9b (5:4f9b)
- call AIMainTurnLogic
- ret
-; 0x14f9f
-
-.start_duel ; 14f9f (5:4f9f)
- call InitAIDuelVars
- call .store_list_pointers
- call SetUpBossStartingHandAndDeck
- call TrySetUpBossStartingPlayArea
- ret nc
- call AIPlayInitialBasicCards
- ret
-; 0x14fb0
-
-.forced_switch ; 14fb0 (5:4fb0)
- call AIDecideBenchPokemonToSwitchTo
- ret
-; 0x14fb4
-
-.ko_switch ; 14fb4 (5:4fb4)
- call AIDecideBenchPokemonToSwitchTo
- ret
-; 0x14fb8
-
-.take_prize ; 14fb8 (5:4fb8)
- call AIPickPrizeCards
- ret
-; 0x14fbc
-
-.list_arena ; 14fbc (5:4fbc)
- db LAPRAS
- db HORSEA
- db GOLDEEN
- db SQUIRTLE
- db $00
-
-.list_bench ; 14fc1 (5:4fc1)
- db SQUIRTLE
- db HORSEA
- db GOLDEEN
- db LAPRAS
- db $00
-
-.list_retreat ; 14fc6 (5:4fc6)
- ai_retreat SQUIRTLE, -3
- ai_retreat WARTORTLE, -2
- ai_retreat HORSEA, -1
- db $00
-
-.list_energy ; 14fcd (5:4fcd)
- ai_energy SQUIRTLE, 2, +0
- ai_energy WARTORTLE, 3, +0
- ai_energy BLASTOISE, 5, +0
- ai_energy GOLDEEN, 1, +0
- ai_energy SEAKING, 2, +0
- ai_energy HORSEA, 2, +0
- ai_energy SEADRA, 3, +0
- ai_energy LAPRAS, 3, +0
- db $00
-
-.list_prize ; 14fe6 (5:4fe6)
- db GAMBLER
- db ENERGY_RETRIEVAL
- db SUPER_ENERGY_RETRIEVAL
- db BLASTOISE
- db $00
-
-.store_list_pointers ; 14feb (5:4feb)
- store_list_pointer wAICardListAvoidPrize, .list_prize
- store_list_pointer wAICardListArenaPriority, .list_arena
- store_list_pointer wAICardListBenchPriority, .list_bench
- store_list_pointer wAICardListPlayFromHandPriority, .list_bench
- ; missing store_list_pointer wAICardListRetreatBonus, .list_retreat
- store_list_pointer wAICardListEnergyBonus, .list_energy
- ret
-; 0x15019
+AIActionTable_GoGoRainDance: ; 14f8f (5:4f8f) + dw .do_turn ; unused + dw .do_turn + dw .start_duel + dw .forced_switch + dw .ko_switch + dw .take_prize + +.do_turn ; 14f9b (5:4f9b) + call AIMainTurnLogic + ret + +.start_duel ; 14f9f (5:4f9f) + call InitAIDuelVars + call .store_list_pointers + call SetUpBossStartingHandAndDeck + call TrySetUpBossStartingPlayArea + ret nc + call AIPlayInitialBasicCards + ret + +.forced_switch ; 14fb0 (5:4fb0) + call AIDecideBenchPokemonToSwitchTo + ret + +.ko_switch ; 14fb4 (5:4fb4) + call AIDecideBenchPokemonToSwitchTo + ret + +.take_prize ; 14fb8 (5:4fb8) + call AIPickPrizeCards + ret + +.list_arena ; 14fbc (5:4fbc) + db LAPRAS + db HORSEA + db GOLDEEN + db SQUIRTLE + db $00 + +.list_bench ; 14fc1 (5:4fc1) + db SQUIRTLE + db HORSEA + db GOLDEEN + db LAPRAS + db $00 + +.list_retreat ; 14fc6 (5:4fc6) + ai_retreat SQUIRTLE, -3 + ai_retreat WARTORTLE, -2 + ai_retreat HORSEA, -1 + db $00 + +.list_energy ; 14fcd (5:4fcd) + ai_energy SQUIRTLE, 2, +0 + ai_energy WARTORTLE, 3, +0 + ai_energy BLASTOISE, 5, +0 + ai_energy GOLDEEN, 1, +0 + ai_energy SEAKING, 2, +0 + ai_energy HORSEA, 2, +0 + ai_energy SEADRA, 3, +0 + ai_energy LAPRAS, 3, +0 + db $00 + +.list_prize ; 14fe6 (5:4fe6) + db GAMBLER + db ENERGY_RETRIEVAL + db SUPER_ENERGY_RETRIEVAL + db BLASTOISE + db $00 + +.store_list_pointers ; 14feb (5:4feb) + store_list_pointer wAICardListAvoidPrize, .list_prize + store_list_pointer wAICardListArenaPriority, .list_arena + store_list_pointer wAICardListBenchPriority, .list_bench + store_list_pointer wAICardListPlayFromHandPriority, .list_bench + ; missing store_list_pointer wAICardListRetreatBonus, .list_retreat + store_list_pointer wAICardListEnergyBonus, .list_energy + ret +; 0x15019 diff --git a/src/engine/deck_ai/decks/im_ronald.asm b/src/engine/deck_ai/decks/im_ronald.asm index c140f1d..8d8de6d 100644 --- a/src/engine/deck_ai/decks/im_ronald.asm +++ b/src/engine/deck_ai/decks/im_ronald.asm @@ -1,86 +1,81 @@ -AIActionTable_ImRonald: ; 152bd (5:52bd)
- dw .do_turn ; unused
- dw .do_turn
- dw .start_duel
- dw .forced_switch
- dw .ko_switch
- dw .take_prize
-
-.do_turn ; 152c9 (5:52c9)
- call AIMainTurnLogic
- ret
-; 0x152cd
-
-.start_duel ; 152cd (5:52cd)
- call InitAIDuelVars
- call .store_list_pointers
- call SetUpBossStartingHandAndDeck
- call TrySetUpBossStartingPlayArea
- ret nc
- call AIPlayInitialBasicCards
- ret
-; 0x152de
-
-.forced_switch ; 152de (5:52de)
- call AIDecideBenchPokemonToSwitchTo
- ret
-; 0x152e2
-
-.ko_switch ; 152e2 (5:52e2)
- call AIDecideBenchPokemonToSwitchTo
- ret
-; 0x152e6
-
-.take_prize ; 152e6 (5:52e6)
- call AIPickPrizeCards
- ret
-; 0x152ea
-
-.list_arena ; 152ea (5:52ea)
- db LAPRAS
- db SEEL
- db CHARMANDER
- db CUBONE
- db SQUIRTLE
- db GROWLITHE
- db $00
-
-.list_bench ; 152f1 (5:52f1)
- db CHARMANDER
- db SQUIRTLE
- db SEEL
- db CUBONE
- db GROWLITHE
- db LAPRAS
- db $00
-
-.list_retreat ; 152f8 (5:52f8)
- db $00
-
-.list_energy ; 152f9 (5:52f9)
- ai_energy CHARMANDER, 3, +0
- ai_energy CHARMELEON, 5, +0
- ai_energy GROWLITHE, 2, +0
- ai_energy ARCANINE2, 4, +0
- ai_energy SQUIRTLE, 2, +0
- ai_energy WARTORTLE, 3, +0
- ai_energy SEEL, 3, +0
- ai_energy DEWGONG, 4, +0
- ai_energy LAPRAS, 3, +0
- ai_energy CUBONE, 3, +0
- ai_energy MAROWAK1, 3, +0
- db $00
-
-.list_prize ; 1531b (5:531b)
- db LAPRAS
- db $00
-
-.store_list_pointers ; 1531d (5:531d)
- store_list_pointer wAICardListAvoidPrize, .list_prize
- store_list_pointer wAICardListArenaPriority, .list_arena
- store_list_pointer wAICardListBenchPriority, .list_bench
- store_list_pointer wAICardListPlayFromHandPriority, .list_bench
- ; missing store_list_pointer wAICardListRetreatBonus, .list_retreat
- store_list_pointer wAICardListEnergyBonus, .list_energy
- ret
-; 0x1534b
+AIActionTable_ImRonald: ; 152bd (5:52bd) + dw .do_turn ; unused + dw .do_turn + dw .start_duel + dw .forced_switch + dw .ko_switch + dw .take_prize + +.do_turn ; 152c9 (5:52c9) + call AIMainTurnLogic + ret + +.start_duel ; 152cd (5:52cd) + call InitAIDuelVars + call .store_list_pointers + call SetUpBossStartingHandAndDeck + call TrySetUpBossStartingPlayArea + ret nc + call AIPlayInitialBasicCards + ret + +.forced_switch ; 152de (5:52de) + call AIDecideBenchPokemonToSwitchTo + ret + +.ko_switch ; 152e2 (5:52e2) + call AIDecideBenchPokemonToSwitchTo + ret + +.take_prize ; 152e6 (5:52e6) + call AIPickPrizeCards + ret + +.list_arena ; 152ea (5:52ea) + db LAPRAS + db SEEL + db CHARMANDER + db CUBONE + db SQUIRTLE + db GROWLITHE + db $00 + +.list_bench ; 152f1 (5:52f1) + db CHARMANDER + db SQUIRTLE + db SEEL + db CUBONE + db GROWLITHE + db LAPRAS + db $00 + +.list_retreat ; 152f8 (5:52f8) + db $00 + +.list_energy ; 152f9 (5:52f9) + ai_energy CHARMANDER, 3, +0 + ai_energy CHARMELEON, 5, +0 + ai_energy GROWLITHE, 2, +0 + ai_energy ARCANINE2, 4, +0 + ai_energy SQUIRTLE, 2, +0 + ai_energy WARTORTLE, 3, +0 + ai_energy SEEL, 3, +0 + ai_energy DEWGONG, 4, +0 + ai_energy LAPRAS, 3, +0 + ai_energy CUBONE, 3, +0 + ai_energy MAROWAK1, 3, +0 + db $00 + +.list_prize ; 1531b (5:531b) + db LAPRAS + db $00 + +.store_list_pointers ; 1531d (5:531d) + store_list_pointer wAICardListAvoidPrize, .list_prize + store_list_pointer wAICardListArenaPriority, .list_arena + store_list_pointer wAICardListBenchPriority, .list_bench + store_list_pointer wAICardListPlayFromHandPriority, .list_bench + ; missing store_list_pointer wAICardListRetreatBonus, .list_retreat + store_list_pointer wAICardListEnergyBonus, .list_energy + ret +; 0x1534b diff --git a/src/engine/deck_ai/decks/invincible_ronald.asm b/src/engine/deck_ai/decks/invincible_ronald.asm index 0a55461..c228577 100644 --- a/src/engine/deck_ai/decks/invincible_ronald.asm +++ b/src/engine/deck_ai/decks/invincible_ronald.asm @@ -1,84 +1,79 @@ -AIActionTable_InvincibleRonald: ; 153e8 (5:53e8)
- dw .do_turn ; unused
- dw .do_turn
- dw .start_duel
- dw .forced_switch
- dw .ko_switch
- dw .take_prize
-
-.do_turn ; 153f4 (5:53f4)
- call AIMainTurnLogic
- ret
-; 0x153f8
-
-.start_duel ; 153f8 (5:53f8)
- call InitAIDuelVars
- call .store_list_pointers
- call SetUpBossStartingHandAndDeck
- call TrySetUpBossStartingPlayArea
- ret nc
- call AIPlayInitialBasicCards
- ret
-; 0x15409
-
-.forced_switch ; 15409 (5:5409)
- call AIDecideBenchPokemonToSwitchTo
- ret
-; 0x1540d
-
-.ko_switch ; 1540d (5:540d)
- call AIDecideBenchPokemonToSwitchTo
- ret
-; 0x15411
-
-.take_prize ; 15411 (5:5411)
- call AIPickPrizeCards
- ret
-; 0x15415
-
-.list_arena ; 15415 (5:5415)
- db KANGASKHAN
- db MAGMAR2
- db CHANSEY
- db GEODUDE
- db SCYTHER
- db GRIMER
- db $00
-
-.list_bench ; 1541c (5:541c)
- db GRIMER
- db SCYTHER
- db GEODUDE
- db CHANSEY
- db MAGMAR2
- db KANGASKHAN
- db $00
-
-.list_retreat ; 15423 (5:5423)
- ai_retreat GRIMER, -1
- db $00
-
-.list_energy ; 15426 (5:5426)
- ai_energy GRIMER, 1, -1
- ai_energy MUK, 3, -1
- ai_energy SCYTHER, 4, +1
- ai_energy MAGMAR2, 2, +0
- ai_energy GEODUDE, 2, +0
- ai_energy GRAVELER, 3, +0
- ai_energy CHANSEY, 4, +0
- ai_energy KANGASKHAN, 4, -1
- db $00
-
-.list_prize ; 1543f (5:543f)
- db GAMBLER
- db $00
-
-.store_list_pointers ; 15441 (5:5441)
- store_list_pointer wAICardListAvoidPrize, .list_prize
- store_list_pointer wAICardListArenaPriority, .list_arena
- store_list_pointer wAICardListBenchPriority, .list_bench
- store_list_pointer wAICardListPlayFromHandPriority, .list_bench
- ; missing store_list_pointer wAICardListRetreatBonus, .list_retreat
- store_list_pointer wAICardListEnergyBonus, .list_energy
- ret
-; 0x1546f
+AIActionTable_InvincibleRonald: ; 153e8 (5:53e8) + dw .do_turn ; unused + dw .do_turn + dw .start_duel + dw .forced_switch + dw .ko_switch + dw .take_prize + +.do_turn ; 153f4 (5:53f4) + call AIMainTurnLogic + ret + +.start_duel ; 153f8 (5:53f8) + call InitAIDuelVars + call .store_list_pointers + call SetUpBossStartingHandAndDeck + call TrySetUpBossStartingPlayArea + ret nc + call AIPlayInitialBasicCards + ret + +.forced_switch ; 15409 (5:5409) + call AIDecideBenchPokemonToSwitchTo + ret + +.ko_switch ; 1540d (5:540d) + call AIDecideBenchPokemonToSwitchTo + ret + +.take_prize ; 15411 (5:5411) + call AIPickPrizeCards + ret + +.list_arena ; 15415 (5:5415) + db KANGASKHAN + db MAGMAR2 + db CHANSEY + db GEODUDE + db SCYTHER + db GRIMER + db $00 + +.list_bench ; 1541c (5:541c) + db GRIMER + db SCYTHER + db GEODUDE + db CHANSEY + db MAGMAR2 + db KANGASKHAN + db $00 + +.list_retreat ; 15423 (5:5423) + ai_retreat GRIMER, -1 + db $00 + +.list_energy ; 15426 (5:5426) + ai_energy GRIMER, 1, -1 + ai_energy MUK, 3, -1 + ai_energy SCYTHER, 4, +1 + ai_energy MAGMAR2, 2, +0 + ai_energy GEODUDE, 2, +0 + ai_energy GRAVELER, 3, +0 + ai_energy CHANSEY, 4, +0 + ai_energy KANGASKHAN, 4, -1 + db $00 + +.list_prize ; 1543f (5:543f) + db GAMBLER + db $00 + +.store_list_pointers ; 15441 (5:5441) + store_list_pointer wAICardListAvoidPrize, .list_prize + store_list_pointer wAICardListArenaPriority, .list_arena + store_list_pointer wAICardListBenchPriority, .list_bench + store_list_pointer wAICardListPlayFromHandPriority, .list_bench + ; missing store_list_pointer wAICardListRetreatBonus, .list_retreat + store_list_pointer wAICardListEnergyBonus, .list_energy + ret +; 0x1546f diff --git a/src/engine/deck_ai/decks/legendary_articuno.asm b/src/engine/deck_ai/decks/legendary_articuno.asm index 183ab62..62ee246 100644 --- a/src/engine/deck_ai/decks/legendary_articuno.asm +++ b/src/engine/deck_ai/decks/legendary_articuno.asm @@ -1,217 +1,210 @@ -AIActionTable_LegendaryArticuno: ; 14c0b (5:4c0b)
- dw .do_turn ; unused
- dw .do_turn
- dw .start_duel
- dw .forced_switch
- dw .ko_switch
- dw .take_prize
-
-.do_turn ; 14c17 (5:4c17)
- call AIDoTurn_LegendaryArticuno
- ret
-; 0x14c1b
-
-.start_duel ; 14c1b (5:4c1b)
- call InitAIDuelVars
- call .store_list_pointers
- call SetUpBossStartingHandAndDeck
- call TrySetUpBossStartingPlayArea
- ret nc
- call AIPlayInitialBasicCards
- ret
-; 0x14c2c
-
-.forced_switch ; 14c2c (5:4c2c)
- call AIDecideBenchPokemonToSwitchTo
- ret
-; 0x14c30
-
-.ko_switch ; 14c30 (5:4c30)
- call AIDecideBenchPokemonToSwitchTo
- ret
-; 0x14c34
-
-.take_prize ; 14c34 (5:4c34)
- call AIPickPrizeCards
- ret
-; 0x14c38
-
-.list_arena ; 14c38 (5:4c38)
- db CHANSEY
- db LAPRAS
- db DITTO
- db SEEL
- db ARTICUNO1
- db ARTICUNO2
- db $00
-
-.list_bench ; 14c3f (5:4c3f)
- db ARTICUNO1
- db SEEL
- db LAPRAS
- db CHANSEY
- db DITTO
- db $00
-
-.list_retreat ; 14c45 (5:4c45)
- ai_retreat SEEL, -3
- ai_retreat DITTO, -3
- db $00
-
-.list_energy ; 14c4a (5:4c4a)
- ai_energy SEEL, 3, +1
- ai_energy DEWGONG, 4, +0
- ai_energy LAPRAS, 3, +0
- ai_energy ARTICUNO1, 4, +1
- ai_energy ARTICUNO2, 3, +0
- ai_energy CHANSEY, 0, -8
- ai_energy DITTO, 3, +0
- db $00
-
-.list_prize ; 14c60 (5:4c60)
- db GAMBLER
- db ARTICUNO2
- db $00
-
-.store_list_pointers ; 14c63 (5:4c63)
- store_list_pointer wAICardListAvoidPrize, .list_prize
- store_list_pointer wAICardListArenaPriority, .list_arena
- store_list_pointer wAICardListBenchPriority, .list_bench
- store_list_pointer wAICardListPlayFromHandPriority, .list_bench
- ; missing store_list_pointer wAICardListRetreatBonus, .list_retreat
- store_list_pointer wAICardListEnergyBonus, .list_energy
- ret
-; 0x14c91
-
-; 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
- cp 3
- ret c
-
-; player prizes >= 3
-; if Lapras has more than half HP and
-; can use second move, check next for Articuno
-; otherwise, check if Articuno or Dewgong
-; have more than half HP and can use second move
-; and if so, the next Pokémon to check is Lapras
- ld a, LAPRAS
- call CheckForBenchIDAtHalfHPAndCanUseSecondMove
- jr c, .articuno
- ld a, ARTICUNO1
- call CheckForBenchIDAtHalfHPAndCanUseSecondMove
- jr c, .lapras
- ld a, DEWGONG
- call CheckForBenchIDAtHalfHPAndCanUseSecondMove
- jr c, .lapras
- jr .articuno
-
-; the following routines check for certain card IDs in bench
-; and call RaiseAIScoreToAllMatchingIDsInBench if these are found.
-; for Lapras, an additional check is made to its
-; attached energy count, which skips calling the routine
-; if this count is >= 3
-.lapras
- ld a, LAPRAS
- ld b, PLAY_AREA_BENCH_1
- call LookForCardIDInPlayArea_Bank5
- jr nc, .articuno
- ld e, a
- call CountNumberOfEnergyCardsAttached
- cp 3
- jr nc, .articuno
- ld a, LAPRAS
- call RaiseAIScoreToAllMatchingIDsInBench
- ret
-
-.articuno
- ld a, ARTICUNO1
- ld b, PLAY_AREA_BENCH_1
- call LookForCardIDInPlayArea_Bank5
- jr nc, .dewgong
- ld a, ARTICUNO1
- call RaiseAIScoreToAllMatchingIDsInBench
- ret
-
-.dewgong
- ld a, DEWGONG
- ld b, PLAY_AREA_BENCH_1
- call LookForCardIDInPlayArea_Bank5
- jr nc, .seel
- ld a, DEWGONG
- call RaiseAIScoreToAllMatchingIDsInBench
- ret
-
-.seel
- ld a, SEEL
- ld b, PLAY_AREA_BENCH_1
- call LookForCardIDInPlayArea_Bank5
- ret nc
- ld a, SEEL
- call RaiseAIScoreToAllMatchingIDsInBench
- ret
-; 0x14cf7
-
-AIDoTurn_LegendaryArticuno: ; 14cf7 (5:4cf7)
-; initialize variables
- call InitAITurnVars
- ld a, AI_TRAINER_CARD_PHASE_01
- call AIProcessHandTrainerCards
- farcall HandleAIAntiMewtwoDeckStrategy
- jp nc, .try_attack
-; process Trainer cards
- ld a, AI_TRAINER_CARD_PHASE_02
- call AIProcessHandTrainerCards
-; play Pokemon from hand
- call AIDecidePlayPokemonCard
- ret c ; return if turn ended
- call AIProcessRetreat
- ld a, AI_TRAINER_CARD_PHASE_10
- call AIProcessHandTrainerCards
-; play Energy card if possible
- ld a, [wAlreadyPlayedEnergy]
- or a
- jr nz, .skip_energy_attach_1
- call AIProcessAndTryToPlayEnergy
-.skip_energy_attach_1
-; play Pokemon from hand again
- call AIDecidePlayPokemonCard
-; process Trainer cards phases 13 and 15
- ld a, AI_TRAINER_CARD_PHASE_13
- call AIProcessHandTrainerCards
- ld a, AI_TRAINER_CARD_PHASE_15
- call AIProcessHandTrainerCards
-; if used Professor Oak, process new hand
- ld a, [wPreviousAIFlags]
- and AI_FLAG_USED_PROFESSOR_OAK
- jr z, .try_attack
- ld a, AI_TRAINER_CARD_PHASE_01
- call AIProcessHandTrainerCards
- ld a, AI_TRAINER_CARD_PHASE_02
- call AIProcessHandTrainerCards
- call AIDecidePlayPokemonCard
- ret c ; return if turn ended
- call AIProcessRetreat
- ld a, AI_TRAINER_CARD_PHASE_10
- call AIProcessHandTrainerCards
- ld a, [wAlreadyPlayedEnergy]
- or a
- jr nz, .skip_energy_attach_2
- call AIProcessAndTryToPlayEnergy
-.skip_energy_attach_2
- call AIDecidePlayPokemonCard
-.try_attack
-; attack if possible, if not,
-; finish turn without attacking.
- call AIProcessAndTryToUseAttack
- ret c ; return if turn ended
- ld a, OPPACTION_FINISH_NO_ATTACK
- bank1call AIMakeDecision
- ret
-; 0x14d60
+AIActionTable_LegendaryArticuno: ; 14c0b (5:4c0b) + dw .do_turn ; unused + dw .do_turn + dw .start_duel + dw .forced_switch + dw .ko_switch + dw .take_prize + +.do_turn ; 14c17 (5:4c17) + call AIDoTurn_LegendaryArticuno + ret + +.start_duel ; 14c1b (5:4c1b) + call InitAIDuelVars + call .store_list_pointers + call SetUpBossStartingHandAndDeck + call TrySetUpBossStartingPlayArea + ret nc + call AIPlayInitialBasicCards + ret + +.forced_switch ; 14c2c (5:4c2c) + call AIDecideBenchPokemonToSwitchTo + ret + +.ko_switch ; 14c30 (5:4c30) + call AIDecideBenchPokemonToSwitchTo + ret + +.take_prize ; 14c34 (5:4c34) + call AIPickPrizeCards + ret + +.list_arena ; 14c38 (5:4c38) + db CHANSEY + db LAPRAS + db DITTO + db SEEL + db ARTICUNO1 + db ARTICUNO2 + db $00 + +.list_bench ; 14c3f (5:4c3f) + db ARTICUNO1 + db SEEL + db LAPRAS + db CHANSEY + db DITTO + db $00 + +.list_retreat ; 14c45 (5:4c45) + ai_retreat SEEL, -3 + ai_retreat DITTO, -3 + db $00 + +.list_energy ; 14c4a (5:4c4a) + ai_energy SEEL, 3, +1 + ai_energy DEWGONG, 4, +0 + ai_energy LAPRAS, 3, +0 + ai_energy ARTICUNO1, 4, +1 + ai_energy ARTICUNO2, 3, +0 + ai_energy CHANSEY, 0, -8 + ai_energy DITTO, 3, +0 + db $00 + +.list_prize ; 14c60 (5:4c60) + db GAMBLER + db ARTICUNO2 + db $00 + +.store_list_pointers ; 14c63 (5:4c63) + store_list_pointer wAICardListAvoidPrize, .list_prize + store_list_pointer wAICardListArenaPriority, .list_arena + store_list_pointer wAICardListBenchPriority, .list_bench + store_list_pointer wAICardListPlayFromHandPriority, .list_bench + ; missing store_list_pointer wAICardListRetreatBonus, .list_retreat + store_list_pointer wAICardListEnergyBonus, .list_energy + ret + +; 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 + cp 3 + ret c + +; player prizes >= 3 +; if Lapras has more than half HP and +; can use second move, check next for Articuno +; otherwise, check if Articuno or Dewgong +; have more than half HP and can use second move +; and if so, the next Pokémon to check is Lapras + ld a, LAPRAS + call CheckForBenchIDAtHalfHPAndCanUseSecondMove + jr c, .articuno + ld a, ARTICUNO1 + call CheckForBenchIDAtHalfHPAndCanUseSecondMove + jr c, .lapras + ld a, DEWGONG + call CheckForBenchIDAtHalfHPAndCanUseSecondMove + jr c, .lapras + jr .articuno + +; the following routines check for certain card IDs in bench +; and call RaiseAIScoreToAllMatchingIDsInBench if these are found. +; for Lapras, an additional check is made to its +; attached energy count, which skips calling the routine +; if this count is >= 3 +.lapras + ld a, LAPRAS + ld b, PLAY_AREA_BENCH_1 + call LookForCardIDInPlayArea_Bank5 + jr nc, .articuno + ld e, a + call CountNumberOfEnergyCardsAttached + cp 3 + jr nc, .articuno + ld a, LAPRAS + call RaiseAIScoreToAllMatchingIDsInBench + ret + +.articuno + ld a, ARTICUNO1 + ld b, PLAY_AREA_BENCH_1 + call LookForCardIDInPlayArea_Bank5 + jr nc, .dewgong + ld a, ARTICUNO1 + call RaiseAIScoreToAllMatchingIDsInBench + ret + +.dewgong + ld a, DEWGONG + ld b, PLAY_AREA_BENCH_1 + call LookForCardIDInPlayArea_Bank5 + jr nc, .seel + ld a, DEWGONG + call RaiseAIScoreToAllMatchingIDsInBench + ret + +.seel + ld a, SEEL + ld b, PLAY_AREA_BENCH_1 + call LookForCardIDInPlayArea_Bank5 + ret nc + ld a, SEEL + call RaiseAIScoreToAllMatchingIDsInBench + ret + +AIDoTurn_LegendaryArticuno: ; 14cf7 (5:4cf7) +; initialize variables + call InitAITurnVars + ld a, AI_TRAINER_CARD_PHASE_01 + call AIProcessHandTrainerCards + farcall HandleAIAntiMewtwoDeckStrategy + jp nc, .try_attack +; process Trainer cards + ld a, AI_TRAINER_CARD_PHASE_02 + call AIProcessHandTrainerCards +; play Pokemon from hand + call AIDecidePlayPokemonCard + ret c ; return if turn ended + call AIProcessRetreat + ld a, AI_TRAINER_CARD_PHASE_10 + call AIProcessHandTrainerCards +; play Energy card if possible + ld a, [wAlreadyPlayedEnergy] + or a + jr nz, .skip_energy_attach_1 + call AIProcessAndTryToPlayEnergy +.skip_energy_attach_1 +; play Pokemon from hand again + call AIDecidePlayPokemonCard +; process Trainer cards phases 13 and 15 + ld a, AI_TRAINER_CARD_PHASE_13 + call AIProcessHandTrainerCards + ld a, AI_TRAINER_CARD_PHASE_15 + call AIProcessHandTrainerCards +; if used Professor Oak, process new hand + ld a, [wPreviousAIFlags] + and AI_FLAG_USED_PROFESSOR_OAK + jr z, .try_attack + ld a, AI_TRAINER_CARD_PHASE_01 + call AIProcessHandTrainerCards + ld a, AI_TRAINER_CARD_PHASE_02 + call AIProcessHandTrainerCards + call AIDecidePlayPokemonCard + ret c ; return if turn ended + call AIProcessRetreat + ld a, AI_TRAINER_CARD_PHASE_10 + call AIProcessHandTrainerCards + ld a, [wAlreadyPlayedEnergy] + or a + jr nz, .skip_energy_attach_2 + call AIProcessAndTryToPlayEnergy +.skip_energy_attach_2 + call AIDecidePlayPokemonCard +.try_attack +; attack if possible, if not, +; finish turn without attacking. + call AIProcessAndTryToUseAttack + ret c ; return if turn ended + ld a, OPPACTION_FINISH_NO_ATTACK + bank1call AIMakeDecision + ret +; 0x14d60 diff --git a/src/engine/deck_ai/decks/legendary_dragonite.asm b/src/engine/deck_ai/decks/legendary_dragonite.asm index d320440..7090e50 100644 --- a/src/engine/deck_ai/decks/legendary_dragonite.asm +++ b/src/engine/deck_ai/decks/legendary_dragonite.asm @@ -1,173 +1,167 @@ -AIActionTable_LegendaryDragonite: ; 14d60 (05:4d60)
- dw .do_turn ; unused
- dw .do_turn
- dw .start_duel
- dw .forced_switch
- dw .ko_switch
- dw .take_prize
-
-.do_turn ; 14d6c (5:4d6c)
- call AIDoTurn_LegendaryDragonite
- ret
-; 0x14d70
-
-.start_duel ; 14d70 (5:4d70)
- call InitAIDuelVars
- call .store_list_pointers
- call SetUpBossStartingHandAndDeck
- call TrySetUpBossStartingPlayArea
- ret nc
- call AIPlayInitialBasicCards
- ret
-; 0x14d81
-
-.forced_switch ; 14d81 (5:4d81)
- call AIDecideBenchPokemonToSwitchTo
- ret
-; 0x14d85
-
-.ko_switch ; 14d85 (5:4d85)
- call AIDecideBenchPokemonToSwitchTo
- ret
-; 0x14d89
-
-.take_prize ; 14d89 (5:4d89)
- call AIPickPrizeCards
- ret
-; 0x14d8d
-
-.list_arena ; 14d8d (5:4d8d)
- db KANGASKHAN
- db LAPRAS
- db CHARMANDER
- db DRATINI
- db MAGIKARP
- db $00
-
-.list_bench ; 14d93 (5:4d93)
- db CHARMANDER
- db MAGIKARP
- db DRATINI
- db LAPRAS
- db KANGASKHAN
- db $00
-
-.list_retreat ; 14d99 (5:4d99)
- ai_retreat CHARMANDER, -1
- ai_retreat MAGIKARP, -5
- db $00
-
-.list_energy ; 14d9e (5:4d9e)
- ai_energy CHARMANDER, 3, +1
- ai_energy CHARMELEON, 4, +1
- ai_energy CHARIZARD, 5, +0
- ai_energy MAGIKARP, 3, +1
- ai_energy GYARADOS, 4, -1
- ai_energy DRATINI, 2, +0
- ai_energy DRAGONAIR, 4, +0
- ai_energy DRAGONITE1, 3, -1
- ai_energy KANGASKHAN, 2, -2
- ai_energy LAPRAS, 3, +0
- db $00
-
-.list_prize ; 14dbd (5:4dbd)
- db GAMBLER
- db DRAGONITE1
- db KANGASKHAN
- db $00
-
-.store_list_pointers ; 14dc1 (5:4dc1)
- store_list_pointer wAICardListAvoidPrize, .list_prize
- store_list_pointer wAICardListArenaPriority, .list_arena
- store_list_pointer wAICardListBenchPriority, .list_bench
- store_list_pointer wAICardListPlayFromHandPriority, .list_bench
- ; missing store_list_pointer wAICardListRetreatBonus, .list_retreat
- store_list_pointer wAICardListEnergyBonus, .list_energy
- ret
-; 0x14def
-
-AIDoTurn_LegendaryDragonite: ; 14def (5:4def)
-; initialize variables
- call InitAITurnVars
- ld a, AI_TRAINER_CARD_PHASE_01
- call AIProcessHandTrainerCards
- farcall HandleAIAntiMewtwoDeckStrategy
- jp nc, .try_attack
-; process Trainer cards
- ld a, AI_TRAINER_CARD_PHASE_02
- call AIProcessHandTrainerCards
-; play Pokemon from hand
- call AIDecidePlayPokemonCard
- ret c ; return if turn ended
- ld a, AI_TRAINER_CARD_PHASE_07
- call AIProcessHandTrainerCards
- call AIProcessRetreat
- ld a, AI_TRAINER_CARD_PHASE_10
- call AIProcessHandTrainerCards
- ld a, AI_TRAINER_CARD_PHASE_11
- call AIProcessHandTrainerCards
-; play Energy card if possible
- ld a, [wAlreadyPlayedEnergy]
- or a
- jr nz, .skip_energy_attach_1
-
-; if Arena card is Kangaskhan and doens't
-; have Energy cards attached, try attaching from hand.
-; otherwise run normal AI energy attach routine.
- ld a, DUELVARS_ARENA_CARD
- call GetTurnDuelistVariable
- call GetCardIDFromDeckIndex
- ld a, KANGASKHAN
- cp e
- jr nz, .attach_normally
- call CreateEnergyCardListFromHand
- jr c, .skip_energy_attach_1
- ld e, PLAY_AREA_ARENA
- call CountNumberOfEnergyCardsAttached
- or a
- jr nz, .attach_normally
- xor a
- ldh [hTempPlayAreaLocation_ff9d], a
- call AITryToPlayEnergyCard
- jr c, .skip_energy_attach_1
-.attach_normally
- call AIProcessAndTryToPlayEnergy
-
-.skip_energy_attach_1
-; play Pokemon from hand again
- call AIDecidePlayPokemonCard
- ld a, AI_TRAINER_CARD_PHASE_15
- call AIProcessHandTrainerCards
-; if used Professor Oak, process new hand
-; if not, then proceed to attack.
- ld a, [wPreviousAIFlags]
- and AI_FLAG_USED_PROFESSOR_OAK
- jr z, .try_attack
- ld a, AI_TRAINER_CARD_PHASE_01
- call AIProcessHandTrainerCards
- ld a, AI_TRAINER_CARD_PHASE_02
- call AIProcessHandTrainerCards
- call AIDecidePlayPokemonCard
- ret c ; return if turn ended
- ld a, AI_TRAINER_CARD_PHASE_07
- call AIProcessHandTrainerCards
- call AIProcessRetreat
- ld a, AI_TRAINER_CARD_PHASE_10
- call AIProcessHandTrainerCards
- ld a, AI_TRAINER_CARD_PHASE_11
- call AIProcessHandTrainerCards
- ld a, [wAlreadyPlayedEnergy]
- or a
- jr nz, .skip_energy_attach_2
- call AIProcessAndTryToPlayEnergy
-.skip_energy_attach_2
- call AIDecidePlayPokemonCard
-.try_attack
-; attack if possible, if not,
-; finish turn without attacking.
- call AIProcessAndTryToUseAttack
- ret c ; return if turn ended
- ld a, OPPACTION_FINISH_NO_ATTACK
- bank1call AIMakeDecision
- ret
-; 0x14e89
+AIActionTable_LegendaryDragonite: ; 14d60 (05:4d60) + dw .do_turn ; unused + dw .do_turn + dw .start_duel + dw .forced_switch + dw .ko_switch + dw .take_prize + +.do_turn ; 14d6c (5:4d6c) + call AIDoTurn_LegendaryDragonite + ret + +.start_duel ; 14d70 (5:4d70) + call InitAIDuelVars + call .store_list_pointers + call SetUpBossStartingHandAndDeck + call TrySetUpBossStartingPlayArea + ret nc + call AIPlayInitialBasicCards + ret + +.forced_switch ; 14d81 (5:4d81) + call AIDecideBenchPokemonToSwitchTo + ret + +.ko_switch ; 14d85 (5:4d85) + call AIDecideBenchPokemonToSwitchTo + ret + +.take_prize ; 14d89 (5:4d89) + call AIPickPrizeCards + ret + +.list_arena ; 14d8d (5:4d8d) + db KANGASKHAN + db LAPRAS + db CHARMANDER + db DRATINI + db MAGIKARP + db $00 + +.list_bench ; 14d93 (5:4d93) + db CHARMANDER + db MAGIKARP + db DRATINI + db LAPRAS + db KANGASKHAN + db $00 + +.list_retreat ; 14d99 (5:4d99) + ai_retreat CHARMANDER, -1 + ai_retreat MAGIKARP, -5 + db $00 + +.list_energy ; 14d9e (5:4d9e) + ai_energy CHARMANDER, 3, +1 + ai_energy CHARMELEON, 4, +1 + ai_energy CHARIZARD, 5, +0 + ai_energy MAGIKARP, 3, +1 + ai_energy GYARADOS, 4, -1 + ai_energy DRATINI, 2, +0 + ai_energy DRAGONAIR, 4, +0 + ai_energy DRAGONITE1, 3, -1 + ai_energy KANGASKHAN, 2, -2 + ai_energy LAPRAS, 3, +0 + db $00 + +.list_prize ; 14dbd (5:4dbd) + db GAMBLER + db DRAGONITE1 + db KANGASKHAN + db $00 + +.store_list_pointers ; 14dc1 (5:4dc1) + store_list_pointer wAICardListAvoidPrize, .list_prize + store_list_pointer wAICardListArenaPriority, .list_arena + store_list_pointer wAICardListBenchPriority, .list_bench + store_list_pointer wAICardListPlayFromHandPriority, .list_bench + ; missing store_list_pointer wAICardListRetreatBonus, .list_retreat + store_list_pointer wAICardListEnergyBonus, .list_energy + ret + +AIDoTurn_LegendaryDragonite: ; 14def (5:4def) +; initialize variables + call InitAITurnVars + ld a, AI_TRAINER_CARD_PHASE_01 + call AIProcessHandTrainerCards + farcall HandleAIAntiMewtwoDeckStrategy + jp nc, .try_attack +; process Trainer cards + ld a, AI_TRAINER_CARD_PHASE_02 + call AIProcessHandTrainerCards +; play Pokemon from hand + call AIDecidePlayPokemonCard + ret c ; return if turn ended + ld a, AI_TRAINER_CARD_PHASE_07 + call AIProcessHandTrainerCards + call AIProcessRetreat + ld a, AI_TRAINER_CARD_PHASE_10 + call AIProcessHandTrainerCards + ld a, AI_TRAINER_CARD_PHASE_11 + call AIProcessHandTrainerCards +; play Energy card if possible + ld a, [wAlreadyPlayedEnergy] + or a + jr nz, .skip_energy_attach_1 + +; if Arena card is Kangaskhan and doens't +; have Energy cards attached, try attaching from hand. +; otherwise run normal AI energy attach routine. + ld a, DUELVARS_ARENA_CARD + call GetTurnDuelistVariable + call GetCardIDFromDeckIndex + ld a, KANGASKHAN + cp e + jr nz, .attach_normally + call CreateEnergyCardListFromHand + jr c, .skip_energy_attach_1 + ld e, PLAY_AREA_ARENA + call CountNumberOfEnergyCardsAttached + or a + jr nz, .attach_normally + xor a + ldh [hTempPlayAreaLocation_ff9d], a + call AITryToPlayEnergyCard + jr c, .skip_energy_attach_1 +.attach_normally + call AIProcessAndTryToPlayEnergy + +.skip_energy_attach_1 +; play Pokemon from hand again + call AIDecidePlayPokemonCard + ld a, AI_TRAINER_CARD_PHASE_15 + call AIProcessHandTrainerCards +; if used Professor Oak, process new hand +; if not, then proceed to attack. + ld a, [wPreviousAIFlags] + and AI_FLAG_USED_PROFESSOR_OAK + jr z, .try_attack + ld a, AI_TRAINER_CARD_PHASE_01 + call AIProcessHandTrainerCards + ld a, AI_TRAINER_CARD_PHASE_02 + call AIProcessHandTrainerCards + call AIDecidePlayPokemonCard + ret c ; return if turn ended + ld a, AI_TRAINER_CARD_PHASE_07 + call AIProcessHandTrainerCards + call AIProcessRetreat + ld a, AI_TRAINER_CARD_PHASE_10 + call AIProcessHandTrainerCards + ld a, AI_TRAINER_CARD_PHASE_11 + call AIProcessHandTrainerCards + ld a, [wAlreadyPlayedEnergy] + or a + jr nz, .skip_energy_attach_2 + call AIProcessAndTryToPlayEnergy +.skip_energy_attach_2 + call AIDecidePlayPokemonCard +.try_attack +; attack if possible, if not, +; finish turn without attacking. + call AIProcessAndTryToUseAttack + ret c ; return if turn ended + ld a, OPPACTION_FINISH_NO_ATTACK + bank1call AIMakeDecision + ret +; 0x14e89 diff --git a/src/engine/deck_ai/decks/legendary_moltres.asm b/src/engine/deck_ai/decks/legendary_moltres.asm index cb38668..2f67c3e 100644 --- a/src/engine/deck_ai/decks/legendary_moltres.asm +++ b/src/engine/deck_ai/decks/legendary_moltres.asm @@ -1,183 +1,177 @@ -AIActionTable_LegendaryMoltres: ; 149e8 (05:49e8)
- dw .do_turn ; unused
- dw .do_turn
- dw .start_duel
- dw .forced_switch
- dw .ko_switch
- dw .take_prize
-
-.do_turn ; 149f4 (5:49f4)
- call AIDoTurn_LegendaryMoltres
- ret
-; 0x149f8
-
-.start_duel ; 149f8 (5:49f8)
- call InitAIDuelVars
- call .store_list_pointers
- call SetUpBossStartingHandAndDeck
- call TrySetUpBossStartingPlayArea
- ret nc ; Play Area set up was successful
- call AIPlayInitialBasicCards
- ret
-; 0x14a09
-
-.forced_switch ; 14a09 (5:4a09)
- call AIDecideBenchPokemonToSwitchTo
- ret
-; 0x14a0d
-
-.ko_switch ; 14a0d (5:4a0d)
- call AIDecideBenchPokemonToSwitchTo
- ret
-; 0x14a11
-
-.take_prize ; 14a11 (5:4a11)
- call AIPickPrizeCards
- ret
-; 0x14a15
-
-.list_arena ; 14a15 (5:4a15)
- db MAGMAR2
- db GROWLITHE
- db VULPIX
- db MAGMAR1
- db MOLTRES1
- db MOLTRES2
- db $00
-
-.list_bench ; 14a1c (5:4a1c)
- db MOLTRES1
- db VULPIX
- db GROWLITHE
- db MAGMAR2
- db MAGMAR1
- db $00
-
-.list_play_hand ; 14a22 (5:4a22)
- db MOLTRES2
- db MOLTRES1
- db VULPIX
- db GROWLITHE
- db MAGMAR2
- db MAGMAR1
- db $00
-
-.list_retreat ; 14a29 (5:4a29)
- ai_retreat GROWLITHE, -5
- ai_retreat VULPIX, -5
- db $00
-
-.list_energy ; 14a2e (5:4a2e)
- ai_energy VULPIX, 3, +0
- ai_energy NINETAILS2, 3, +1
- ai_energy GROWLITHE, 3, +1
- ai_energy ARCANINE2, 4, +1
- ai_energy MAGMAR1, 4, -1
- ai_energy MAGMAR2, 1, -1
- ai_energy MOLTRES2, 3, +2
- ai_energy MOLTRES1, 4, +2
- db $00
-
-.list_prize ; 14a47 (5:4a47)
- db ENERGY_REMOVAL
- db MOLTRES2
- db $00
-
-.store_list_pointers ; 14a4a (5:4a4a)
- store_list_pointer wAICardListAvoidPrize, .list_prize
- store_list_pointer wAICardListArenaPriority, .list_arena
- store_list_pointer wAICardListBenchPriority, .list_bench
- store_list_pointer wAICardListPlayFromHandPriority, .list_play_hand
- store_list_pointer wAICardListRetreatBonus, .list_retreat
- store_list_pointer wAICardListEnergyBonus, .list_energy
- ret
-; 0x14a81
-
-AIDoTurn_LegendaryMoltres: ; 14a81 (5:4a81)
-; initialize variables
- call InitAITurnVars
- farcall HandleAIAntiMewtwoDeckStrategy
- jp nc, .try_attack
-; process Trainer cards
-; phase 2 through 4.
- ld a, AI_TRAINER_CARD_PHASE_02
- call AIProcessHandTrainerCards
- ld a, AI_TRAINER_CARD_PHASE_04
- call AIProcessHandTrainerCards
-
-; check if AI can play Moltres2
-; from hand and if so, play it.
- ld a, DUELVARS_NUMBER_OF_POKEMON_IN_PLAY_AREA
- call GetTurnDuelistVariable
- cp MAX_PLAY_AREA_POKEMON
- jr nc, .skip_moltres ; skip if bench is full
- ld a, DUELVARS_NUMBER_OF_CARDS_NOT_IN_DECK
- call GetTurnDuelistVariable
- cp DECK_SIZE - 9
- jr nc, .skip_moltres ; skip if cards in deck <= 9
- ld a, MUK
- call CountPokemonIDInBothPlayAreas
- jr c, .skip_moltres ; skip if Muk in play
- ld a, MOLTRES2
- call LookForCardIDInHandList_Bank5
- jr nc, .skip_moltres ; skip if no Moltres2 in hand
- ldh [hTemp_ffa0], a
- ld a, OPPACTION_PLAY_BASIC_PKMN
- bank1call AIMakeDecision
-
-.skip_moltres
-; play Pokemon from hand
- call AIDecidePlayPokemonCard
- ret c ; return if turn ended
-; process Trainer cards
- ld a, AI_TRAINER_CARD_PHASE_05
- call AIProcessHandTrainerCards
- call AIProcessRetreat
- ld a, AI_TRAINER_CARD_PHASE_10
- call AIProcessHandTrainerCards
- ld a, AI_TRAINER_CARD_PHASE_11
- call AIProcessHandTrainerCards
-; play Energy card if possible
- ld a, [wAlreadyPlayedEnergy]
- or a
- jr nz, .skip_attach_energy
-
-; if Magmar2 is the Arena card and has no energy attached,
-; try attaching an energy card to it from the hand.
-; otherwise, run normal AI energy attach routine.
- ld a, DUELVARS_ARENA_CARD
- call GetTurnDuelistVariable
- call GetCardIDFromDeckIndex
- ld a, MAGMAR2
- cp e
- jr nz, .attach_normally
- ; Magmar2 is the Arena card
- call CreateEnergyCardListFromHand
- jr c, .skip_attach_energy
- ld e, PLAY_AREA_ARENA
- call CountNumberOfEnergyCardsAttached
- or a
- jr nz, .attach_normally
- xor a ; PLAY_AREA_ARENA
- ldh [hTempPlayAreaLocation_ff9d], a
- call AITryToPlayEnergyCard
- jr c, .skip_attach_energy
-
-.attach_normally
-; play Energy card if possible
- call AIProcessAndTryToPlayEnergy
-.skip_attach_energy
-; try playing Pokemon cards from hand again
- call AIDecidePlayPokemonCard
- ld a, AI_TRAINER_CARD_PHASE_13
- call AIProcessHandTrainerCards
-
-.try_attack
-; attack if possible, if not,
-; finish turn without attacking.
- call AIProcessAndTryToUseAttack
- ret c
- ld a, OPPACTION_FINISH_NO_ATTACK
- bank1call AIMakeDecision
- ret
-; 0x14b0f
+AIActionTable_LegendaryMoltres: ; 149e8 (05:49e8) + dw .do_turn ; unused + dw .do_turn + dw .start_duel + dw .forced_switch + dw .ko_switch + dw .take_prize + +.do_turn ; 149f4 (5:49f4) + call AIDoTurn_LegendaryMoltres + ret + +.start_duel ; 149f8 (5:49f8) + call InitAIDuelVars + call .store_list_pointers + call SetUpBossStartingHandAndDeck + call TrySetUpBossStartingPlayArea + ret nc ; Play Area set up was successful + call AIPlayInitialBasicCards + ret + +.forced_switch ; 14a09 (5:4a09) + call AIDecideBenchPokemonToSwitchTo + ret + +.ko_switch ; 14a0d (5:4a0d) + call AIDecideBenchPokemonToSwitchTo + ret + +.take_prize ; 14a11 (5:4a11) + call AIPickPrizeCards + ret + +.list_arena ; 14a15 (5:4a15) + db MAGMAR2 + db GROWLITHE + db VULPIX + db MAGMAR1 + db MOLTRES1 + db MOLTRES2 + db $00 + +.list_bench ; 14a1c (5:4a1c) + db MOLTRES1 + db VULPIX + db GROWLITHE + db MAGMAR2 + db MAGMAR1 + db $00 + +.list_play_hand ; 14a22 (5:4a22) + db MOLTRES2 + db MOLTRES1 + db VULPIX + db GROWLITHE + db MAGMAR2 + db MAGMAR1 + db $00 + +.list_retreat ; 14a29 (5:4a29) + ai_retreat GROWLITHE, -5 + ai_retreat VULPIX, -5 + db $00 + +.list_energy ; 14a2e (5:4a2e) + ai_energy VULPIX, 3, +0 + ai_energy NINETAILS2, 3, +1 + ai_energy GROWLITHE, 3, +1 + ai_energy ARCANINE2, 4, +1 + ai_energy MAGMAR1, 4, -1 + ai_energy MAGMAR2, 1, -1 + ai_energy MOLTRES2, 3, +2 + ai_energy MOLTRES1, 4, +2 + db $00 + +.list_prize ; 14a47 (5:4a47) + db ENERGY_REMOVAL + db MOLTRES2 + db $00 + +.store_list_pointers ; 14a4a (5:4a4a) + store_list_pointer wAICardListAvoidPrize, .list_prize + store_list_pointer wAICardListArenaPriority, .list_arena + store_list_pointer wAICardListBenchPriority, .list_bench + store_list_pointer wAICardListPlayFromHandPriority, .list_play_hand + store_list_pointer wAICardListRetreatBonus, .list_retreat + store_list_pointer wAICardListEnergyBonus, .list_energy + ret + +AIDoTurn_LegendaryMoltres: ; 14a81 (5:4a81) +; initialize variables + call InitAITurnVars + farcall HandleAIAntiMewtwoDeckStrategy + jp nc, .try_attack +; process Trainer cards +; phase 2 through 4. + ld a, AI_TRAINER_CARD_PHASE_02 + call AIProcessHandTrainerCards + ld a, AI_TRAINER_CARD_PHASE_04 + call AIProcessHandTrainerCards + +; check if AI can play Moltres2 +; from hand and if so, play it. + ld a, DUELVARS_NUMBER_OF_POKEMON_IN_PLAY_AREA + call GetTurnDuelistVariable + cp MAX_PLAY_AREA_POKEMON + jr nc, .skip_moltres ; skip if bench is full + ld a, DUELVARS_NUMBER_OF_CARDS_NOT_IN_DECK + call GetTurnDuelistVariable + cp DECK_SIZE - 9 + jr nc, .skip_moltres ; skip if cards in deck <= 9 + ld a, MUK + call CountPokemonIDInBothPlayAreas + jr c, .skip_moltres ; skip if Muk in play + ld a, MOLTRES2 + call LookForCardIDInHandList_Bank5 + jr nc, .skip_moltres ; skip if no Moltres2 in hand + ldh [hTemp_ffa0], a + ld a, OPPACTION_PLAY_BASIC_PKMN + bank1call AIMakeDecision + +.skip_moltres +; play Pokemon from hand + call AIDecidePlayPokemonCard + ret c ; return if turn ended +; process Trainer cards + ld a, AI_TRAINER_CARD_PHASE_05 + call AIProcessHandTrainerCards + call AIProcessRetreat + ld a, AI_TRAINER_CARD_PHASE_10 + call AIProcessHandTrainerCards + ld a, AI_TRAINER_CARD_PHASE_11 + call AIProcessHandTrainerCards +; play Energy card if possible + ld a, [wAlreadyPlayedEnergy] + or a + jr nz, .skip_attach_energy + +; if Magmar2 is the Arena card and has no energy attached, +; try attaching an energy card to it from the hand. +; otherwise, run normal AI energy attach routine. + ld a, DUELVARS_ARENA_CARD + call GetTurnDuelistVariable + call GetCardIDFromDeckIndex + ld a, MAGMAR2 + cp e + jr nz, .attach_normally + ; Magmar2 is the Arena card + call CreateEnergyCardListFromHand + jr c, .skip_attach_energy + ld e, PLAY_AREA_ARENA + call CountNumberOfEnergyCardsAttached + or a + jr nz, .attach_normally + xor a ; PLAY_AREA_ARENA + ldh [hTempPlayAreaLocation_ff9d], a + call AITryToPlayEnergyCard + jr c, .skip_attach_energy + +.attach_normally +; play Energy card if possible + call AIProcessAndTryToPlayEnergy +.skip_attach_energy +; try playing Pokemon cards from hand again + call AIDecidePlayPokemonCard + ld a, AI_TRAINER_CARD_PHASE_13 + call AIProcessHandTrainerCards + +.try_attack +; attack if possible, if not, +; finish turn without attacking. + call AIProcessAndTryToUseAttack + ret c + ld a, OPPACTION_FINISH_NO_ATTACK + bank1call AIMakeDecision + ret +; 0x14b0f diff --git a/src/engine/deck_ai/decks/legendary_ronald.asm b/src/engine/deck_ai/decks/legendary_ronald.asm index 2721ba9..5272f81 100644 --- a/src/engine/deck_ai/decks/legendary_ronald.asm +++ b/src/engine/deck_ai/decks/legendary_ronald.asm @@ -1,210 +1,204 @@ -AIActionTable_LegendaryRonald: ; 1546f (5:546f)
- dw .do_turn ; unused
- dw .do_turn
- dw .start_duel
- dw .forced_switch
- dw .ko_switch
- dw .take_prize
-
-.do_turn ; 1547b (5:547b)
- call AIDoTurn_LegendaryRonald
- ret
-; 0x1547f
-
-.start_duel ; 1547f (5:547f)
- call InitAIDuelVars
- call .store_list_pointers
- call SetUpBossStartingHandAndDeck
- call TrySetUpBossStartingPlayArea
- ret nc
- call AIPlayInitialBasicCards
- ret
-; 0x15490
-
-.forced_switch ; 15490 (5:5490)
- call AIDecideBenchPokemonToSwitchTo
- ret
-; 0x15494
-
-.ko_switch ; 15494 (5:5494)
- call AIDecideBenchPokemonToSwitchTo
- ret
-; 0x15498
-
-.take_prize ; 15498 (5:5498)
- call AIPickPrizeCards
- ret
-; 0x1549c
-
-.list_arena ; 1549c (5:549c)
- db KANGASKHAN
- db DRATINI
- db EEVEE
- db ZAPDOS3
- db ARTICUNO2
- db MOLTRES2
- db $00
-
-.list_bench ; 154a3 (5:54a3)
- db KANGASKHAN
- db DRATINI
- db EEVEE
- db $00
-
-.list_play_hand ; 154a7 (5:54a7)
- db MOLTRES2
- db ZAPDOS3
- db KANGASKHAN
- db DRATINI
- db EEVEE
- db ARTICUNO2
- db $00
-
-.list_retreat ; 154ae (5:54ae)
- ai_retreat EEVEE, -2
- db $00
-
-.list_energy ; 154b1 (5:54b1)
- ai_energy FLAREON1, 3, +0
- ai_energy MOLTRES2, 3, +0
- ai_energy VAPOREON1, 3, +0
- ai_energy ARTICUNO2, 0, -8
- ai_energy JOLTEON1, 4, +0
- ai_energy ZAPDOS3, 0, -8
- ai_energy KANGASKHAN, 4, -1
- ai_energy EEVEE, 3, +0
- ai_energy DRATINI, 3, +0
- ai_energy DRAGONAIR, 4, +0
- ai_energy DRAGONITE1, 3, +0
- db $00
-
-.list_prize ; 154d3 (5:54d3)
- db MOLTRES2
- db ARTICUNO2
- db ZAPDOS3
- db DRAGONITE1
- db GAMBLER
- db $00
-
-.store_list_pointers ; 154d9 (5:54d9)
- store_list_pointer wAICardListAvoidPrize, .list_prize
- store_list_pointer wAICardListArenaPriority, .list_arena
- store_list_pointer wAICardListBenchPriority, .list_bench
- store_list_pointer wAICardListPlayFromHandPriority, .list_play_hand
- ; missing store_list_pointer wAICardListRetreatBonus, .list_retreat
- store_list_pointer wAICardListEnergyBonus, .list_energy
- ret
-; 0x15507
-
-AIDoTurn_LegendaryRonald: ; 15507 (5:5507)
-; initialize variables
- call InitAITurnVars
-; process Trainer cards
- ld a, AI_TRAINER_CARD_PHASE_01
- call AIProcessHandTrainerCards
- ld a, AI_TRAINER_CARD_PHASE_02
- call AIProcessHandTrainerCards
- ld a, AI_TRAINER_CARD_PHASE_04
- call AIProcessHandTrainerCards
-
-; check if AI can play Moltres2
-; from hand and if so, play it.
- ld a, DUELVARS_NUMBER_OF_POKEMON_IN_PLAY_AREA
- call GetTurnDuelistVariable
- cp MAX_PLAY_AREA_POKEMON
- jr nc, .skip_moltres_1 ; skip if bench is full
- ld a, DUELVARS_NUMBER_OF_CARDS_NOT_IN_DECK
- call GetTurnDuelistVariable
- cp DECK_SIZE - 9
- jr nc, .skip_moltres_1 ; skip if cards in deck <= 9
- ld a, MUK
- call CountPokemonIDInBothPlayAreas
- jr c, .skip_moltres_1 ; skip if Muk in play
- ld a, MOLTRES2
- call LookForCardIDInHandList_Bank5
- jr nc, .skip_moltres_1 ; skip if no Moltres2 in hand
- ldh [hTemp_ffa0], a
- ld a, OPPACTION_PLAY_BASIC_PKMN
- bank1call AIMakeDecision
-
-.skip_moltres_1
-; play Pokemon from hand
- call AIDecidePlayPokemonCard
- ret c ; return if turn ended
-; process Trainer cards
- ld a, AI_TRAINER_CARD_PHASE_05
- call AIProcessHandTrainerCards
- ld a, AI_TRAINER_CARD_PHASE_07
- call AIProcessHandTrainerCards
- call AIProcessRetreat
- ld a, AI_TRAINER_CARD_PHASE_10
- call AIProcessHandTrainerCards
-; play Energy card if possible
- ld a, [wAlreadyPlayedEnergy]
- or a
- jr nz, .skip_attach_energy_1
- call AIProcessAndTryToPlayEnergy
-.skip_attach_energy_1
-; try playing Pokemon cards from hand again
- call AIDecidePlayPokemonCard
- ret c ; return if turn ended
- ld a, AI_TRAINER_CARD_PHASE_15
-; if used Professor Oak, process new hand
-; if not, then proceed to attack.
- call AIProcessHandTrainerCards
- ld a, [wPreviousAIFlags]
- and AI_FLAG_USED_PROFESSOR_OAK
- jr z, .try_attack
- ld a, AI_TRAINER_CARD_PHASE_01
- call AIProcessHandTrainerCards
- ld a, AI_TRAINER_CARD_PHASE_02
- call AIProcessHandTrainerCards
- ld a, AI_TRAINER_CARD_PHASE_04
- call AIProcessHandTrainerCards
-
-; check if AI can play Moltres2
-; from hand and if so, play it.
- ld a, DUELVARS_NUMBER_OF_POKEMON_IN_PLAY_AREA
- call GetTurnDuelistVariable
- cp MAX_PLAY_AREA_POKEMON
- jr nc, .skip_moltres_2 ; skip if bench is full
- ld a, DUELVARS_NUMBER_OF_CARDS_NOT_IN_DECK
- call GetTurnDuelistVariable
- cp DECK_SIZE - 9
- jr nc, .skip_moltres_2 ; skip if cards in deck <= 9
- ld a, MUK
- call CountPokemonIDInBothPlayAreas
- jr c, .skip_moltres_2 ; skip if Muk in play
- ld a, MOLTRES2
- call LookForCardIDInHandList_Bank5
- jr nc, .skip_moltres_2 ; skip if no Moltres2 in hand
- ldh [hTemp_ffa0], a
- ld a, OPPACTION_PLAY_BASIC_PKMN
- bank1call AIMakeDecision
-
-.skip_moltres_2
- call AIDecidePlayPokemonCard
- ret c ; return if turn ended
- ld a, AI_TRAINER_CARD_PHASE_05
- call AIProcessHandTrainerCards
- ld a, AI_TRAINER_CARD_PHASE_07
- call AIProcessHandTrainerCards
- call AIProcessRetreat
- ld a, AI_TRAINER_CARD_PHASE_10
- call AIProcessHandTrainerCards
- ld a, [wAlreadyPlayedEnergy]
- or a
- jr nz, .skip_attach_energy_2
- call AIProcessAndTryToPlayEnergy
-.skip_attach_energy_2
- call AIDecidePlayPokemonCard
- ret c ; return if turn ended
-.try_attack
-; attack if possible, if not,
-; finish turn without attacking.
- call AIProcessAndTryToUseAttack
- ret c ; return if turn ended
- ld a, OPPACTION_FINISH_NO_ATTACK
- bank1call AIMakeDecision
- ret
-; 0x155d2
+AIActionTable_LegendaryRonald: ; 1546f (5:546f) + dw .do_turn ; unused + dw .do_turn + dw .start_duel + dw .forced_switch + dw .ko_switch + dw .take_prize + +.do_turn ; 1547b (5:547b) + call AIDoTurn_LegendaryRonald + ret + +.start_duel ; 1547f (5:547f) + call InitAIDuelVars + call .store_list_pointers + call SetUpBossStartingHandAndDeck + call TrySetUpBossStartingPlayArea + ret nc + call AIPlayInitialBasicCards + ret + +.forced_switch ; 15490 (5:5490) + call AIDecideBenchPokemonToSwitchTo + ret + +.ko_switch ; 15494 (5:5494) + call AIDecideBenchPokemonToSwitchTo + ret + +.take_prize ; 15498 (5:5498) + call AIPickPrizeCards + ret + +.list_arena ; 1549c (5:549c) + db KANGASKHAN + db DRATINI + db EEVEE + db ZAPDOS3 + db ARTICUNO2 + db MOLTRES2 + db $00 + +.list_bench ; 154a3 (5:54a3) + db KANGASKHAN + db DRATINI + db EEVEE + db $00 + +.list_play_hand ; 154a7 (5:54a7) + db MOLTRES2 + db ZAPDOS3 + db KANGASKHAN + db DRATINI + db EEVEE + db ARTICUNO2 + db $00 + +.list_retreat ; 154ae (5:54ae) + ai_retreat EEVEE, -2 + db $00 + +.list_energy ; 154b1 (5:54b1) + ai_energy FLAREON1, 3, +0 + ai_energy MOLTRES2, 3, +0 + ai_energy VAPOREON1, 3, +0 + ai_energy ARTICUNO2, 0, -8 + ai_energy JOLTEON1, 4, +0 + ai_energy ZAPDOS3, 0, -8 + ai_energy KANGASKHAN, 4, -1 + ai_energy EEVEE, 3, +0 + ai_energy DRATINI, 3, +0 + ai_energy DRAGONAIR, 4, +0 + ai_energy DRAGONITE1, 3, +0 + db $00 + +.list_prize ; 154d3 (5:54d3) + db MOLTRES2 + db ARTICUNO2 + db ZAPDOS3 + db DRAGONITE1 + db GAMBLER + db $00 + +.store_list_pointers ; 154d9 (5:54d9) + store_list_pointer wAICardListAvoidPrize, .list_prize + store_list_pointer wAICardListArenaPriority, .list_arena + store_list_pointer wAICardListBenchPriority, .list_bench + store_list_pointer wAICardListPlayFromHandPriority, .list_play_hand + ; missing store_list_pointer wAICardListRetreatBonus, .list_retreat + store_list_pointer wAICardListEnergyBonus, .list_energy + ret + +AIDoTurn_LegendaryRonald: ; 15507 (5:5507) +; initialize variables + call InitAITurnVars +; process Trainer cards + ld a, AI_TRAINER_CARD_PHASE_01 + call AIProcessHandTrainerCards + ld a, AI_TRAINER_CARD_PHASE_02 + call AIProcessHandTrainerCards + ld a, AI_TRAINER_CARD_PHASE_04 + call AIProcessHandTrainerCards + +; check if AI can play Moltres2 +; from hand and if so, play it. + ld a, DUELVARS_NUMBER_OF_POKEMON_IN_PLAY_AREA + call GetTurnDuelistVariable + cp MAX_PLAY_AREA_POKEMON + jr nc, .skip_moltres_1 ; skip if bench is full + ld a, DUELVARS_NUMBER_OF_CARDS_NOT_IN_DECK + call GetTurnDuelistVariable + cp DECK_SIZE - 9 + jr nc, .skip_moltres_1 ; skip if cards in deck <= 9 + ld a, MUK + call CountPokemonIDInBothPlayAreas + jr c, .skip_moltres_1 ; skip if Muk in play + ld a, MOLTRES2 + call LookForCardIDInHandList_Bank5 + jr nc, .skip_moltres_1 ; skip if no Moltres2 in hand + ldh [hTemp_ffa0], a + ld a, OPPACTION_PLAY_BASIC_PKMN + bank1call AIMakeDecision + +.skip_moltres_1 +; play Pokemon from hand + call AIDecidePlayPokemonCard + ret c ; return if turn ended +; process Trainer cards + ld a, AI_TRAINER_CARD_PHASE_05 + call AIProcessHandTrainerCards + ld a, AI_TRAINER_CARD_PHASE_07 + call AIProcessHandTrainerCards + call AIProcessRetreat + ld a, AI_TRAINER_CARD_PHASE_10 + call AIProcessHandTrainerCards +; play Energy card if possible + ld a, [wAlreadyPlayedEnergy] + or a + jr nz, .skip_attach_energy_1 + call AIProcessAndTryToPlayEnergy +.skip_attach_energy_1 +; try playing Pokemon cards from hand again + call AIDecidePlayPokemonCard + ret c ; return if turn ended + ld a, AI_TRAINER_CARD_PHASE_15 +; if used Professor Oak, process new hand +; if not, then proceed to attack. + call AIProcessHandTrainerCards + ld a, [wPreviousAIFlags] + and AI_FLAG_USED_PROFESSOR_OAK + jr z, .try_attack + ld a, AI_TRAINER_CARD_PHASE_01 + call AIProcessHandTrainerCards + ld a, AI_TRAINER_CARD_PHASE_02 + call AIProcessHandTrainerCards + ld a, AI_TRAINER_CARD_PHASE_04 + call AIProcessHandTrainerCards + +; check if AI can play Moltres2 +; from hand and if so, play it. + ld a, DUELVARS_NUMBER_OF_POKEMON_IN_PLAY_AREA + call GetTurnDuelistVariable + cp MAX_PLAY_AREA_POKEMON + jr nc, .skip_moltres_2 ; skip if bench is full + ld a, DUELVARS_NUMBER_OF_CARDS_NOT_IN_DECK + call GetTurnDuelistVariable + cp DECK_SIZE - 9 + jr nc, .skip_moltres_2 ; skip if cards in deck <= 9 + ld a, MUK + call CountPokemonIDInBothPlayAreas + jr c, .skip_moltres_2 ; skip if Muk in play + ld a, MOLTRES2 + call LookForCardIDInHandList_Bank5 + jr nc, .skip_moltres_2 ; skip if no Moltres2 in hand + ldh [hTemp_ffa0], a + ld a, OPPACTION_PLAY_BASIC_PKMN + bank1call AIMakeDecision + +.skip_moltres_2 + call AIDecidePlayPokemonCard + ret c ; return if turn ended + ld a, AI_TRAINER_CARD_PHASE_05 + call AIProcessHandTrainerCards + ld a, AI_TRAINER_CARD_PHASE_07 + call AIProcessHandTrainerCards + call AIProcessRetreat + ld a, AI_TRAINER_CARD_PHASE_10 + call AIProcessHandTrainerCards + ld a, [wAlreadyPlayedEnergy] + or a + jr nz, .skip_attach_energy_2 + call AIProcessAndTryToPlayEnergy +.skip_attach_energy_2 + call AIDecidePlayPokemonCard + ret c ; return if turn ended +.try_attack +; attack if possible, if not, +; finish turn without attacking. + call AIProcessAndTryToUseAttack + ret c ; return if turn ended + ld a, OPPACTION_FINISH_NO_ATTACK + bank1call AIMakeDecision + ret +; 0x155d2 diff --git a/src/engine/deck_ai/decks/legendary_zapdos.asm b/src/engine/deck_ai/decks/legendary_zapdos.asm index cfa60be..3a74ac6 100644 --- a/src/engine/deck_ai/decks/legendary_zapdos.asm +++ b/src/engine/deck_ai/decks/legendary_zapdos.asm @@ -1,160 +1,154 @@ -AIActionTable_LegendaryZapdos: ; 14b0f (05:4b0f)
- dw .do_turn ; unused
- dw .do_turn
- dw .start_duel
- dw .forced_switch
- dw .ko_switch
- dw .take_prize
-
-.do_turn ; 14b1b (5:4b1b)
- call AIDoTurn_LegendaryZapdos
- ret
-; 0x14b1f
-
-.start_duel ; 14b1f (5:4b1f)
- call InitAIDuelVars
- call .store_list_pointers
- call SetUpBossStartingHandAndDeck
- call TrySetUpBossStartingPlayArea
- ret nc
- call AIPlayInitialBasicCards
- ret
-; 0x14b30
-
-.forced_switch ; 14b30 (5:4b30)
- call AIDecideBenchPokemonToSwitchTo
- ret
-; 0x14b34
-
-.ko_switch ; 14b34 (5:4b34)
- call AIDecideBenchPokemonToSwitchTo
- ret
-; 0x14b38
-
-.take_prize ; 14b38 (5:4b38)
- call AIPickPrizeCards
- ret
-; 0x14b3c
-
-.list_arena ; 14b3c (5:4b3c)
- db ELECTABUZZ2
- db VOLTORB
- db EEVEE
- db ZAPDOS1
- db ZAPDOS2
- db ZAPDOS3
- db $00
-
-.list_bench ; 14b43 (5:4b43)
- db ZAPDOS2
- db ZAPDOS1
- db EEVEE
- db VOLTORB
- db ELECTABUZZ2
- db $00
-
-.list_retreat ; 14b49 (5:4b49)
- ai_retreat EEVEE, -5
- ai_retreat VOLTORB, -5
- ai_retreat ELECTABUZZ2, -5
- db $00
-
-.list_energy ; 14b50 (5:4b50)
- ai_energy VOLTORB, 1, -1
- ai_energy ELECTRODE1, 3, +0
- ai_energy ELECTABUZZ2, 2, -1
- ai_energy JOLTEON2, 3, +1
- ai_energy ZAPDOS1, 4, +2
- ai_energy ZAPDOS2, 4, +2
- ai_energy ZAPDOS3, 3, +1
- ai_energy EEVEE, 3, +0
- db $00
-
-.list_prize ; 14b69 (5:4b69)
- db GAMBLER
- db ZAPDOS3
- db $00
-
-.store_list_pointers ; 14b6c (5:4b6c)
- store_list_pointer wAICardListAvoidPrize, .list_prize
- store_list_pointer wAICardListArenaPriority, .list_arena
- store_list_pointer wAICardListBenchPriority, .list_bench
- store_list_pointer wAICardListPlayFromHandPriority, .list_bench
- ; missing store_list_pointer wAICardListRetreatBonus, .list_retreat
- store_list_pointer wAICardListEnergyBonus, .list_energy
- ret
-; 0x14b9a
-
-AIDoTurn_LegendaryZapdos: ; 14b9a (5:4b9a)
-; initialize variables
- call InitAITurnVars
- farcall HandleAIAntiMewtwoDeckStrategy
- jp nc, .try_attack
-; process Trainer cards
- ld a, AI_TRAINER_CARD_PHASE_01
- call AIProcessHandTrainerCards
- ld a, AI_TRAINER_CARD_PHASE_04
- call AIProcessHandTrainerCards
-; play Pokemon from hand
- call AIDecidePlayPokemonCard
- ret c ; return if turn ended
- ld a, AI_TRAINER_CARD_PHASE_07
- call AIProcessHandTrainerCards
- call AIProcessRetreat
- ld a, AI_TRAINER_CARD_PHASE_10
- call AIProcessHandTrainerCards
-; play Energy card if possible.
- ld a, [wAlreadyPlayedEnergy]
- or a
- jr nz, .skip_energy_attach
-
-; if Arena card is Voltorb and there's Electrode1 in hand,
-; or if it's Electabuzz, try attaching Energy card
-; to the Arena card if it doesn't have any energy attached.
-; Otherwise if Energy card is not needed,
-; go through normal AI energy attach routine.
- ld a, DUELVARS_ARENA_CARD
- call GetTurnDuelistVariable
- call GetCardIDFromDeckIndex
- ld a, VOLTORB
- cp e
- jr nz, .check_electabuzz
- ld a, ELECTRODE1
- call LookForCardIDInHandList_Bank5
- jr nc, .attach_normally
- jr .voltorb_or_electabuzz
-.check_electabuzz
- ld a, ELECTABUZZ2
- cp e
- jr nz, .attach_normally
-
-.voltorb_or_electabuzz
- call CreateEnergyCardListFromHand
- jr c, .skip_energy_attach
- ld e, PLAY_AREA_ARENA
- call CountNumberOfEnergyCardsAttached
- or a
- jr nz, .attach_normally
- xor a ; PLAY_AREA_ARENA
- ldh [hTempPlayAreaLocation_ff9d], a
- call AITryToPlayEnergyCard
- jr c, .skip_energy_attach
-
-.attach_normally
- call AIProcessAndTryToPlayEnergy
-
-.skip_energy_attach
-; play Pokemon from hand again
- call AIDecidePlayPokemonCard
- ret c ; return if turn ended
- ld a, AI_TRAINER_CARD_PHASE_13
- call AIProcessHandTrainerCards
-.try_attack
-; attack if possible, if not,
-; finish turn without attacking.
- call AIProcessAndTryToUseAttack
- ret c ; return if turn ended
- ld a, OPPACTION_FINISH_NO_ATTACK
- bank1call AIMakeDecision
- ret
-; 0x14c0b
+AIActionTable_LegendaryZapdos: ; 14b0f (05:4b0f) + dw .do_turn ; unused + dw .do_turn + dw .start_duel + dw .forced_switch + dw .ko_switch + dw .take_prize + +.do_turn ; 14b1b (5:4b1b) + call AIDoTurn_LegendaryZapdos + ret + +.start_duel ; 14b1f (5:4b1f) + call InitAIDuelVars + call .store_list_pointers + call SetUpBossStartingHandAndDeck + call TrySetUpBossStartingPlayArea + ret nc + call AIPlayInitialBasicCards + ret + +.forced_switch ; 14b30 (5:4b30) + call AIDecideBenchPokemonToSwitchTo + ret + +.ko_switch ; 14b34 (5:4b34) + call AIDecideBenchPokemonToSwitchTo + ret + +.take_prize ; 14b38 (5:4b38) + call AIPickPrizeCards + ret + +.list_arena ; 14b3c (5:4b3c) + db ELECTABUZZ2 + db VOLTORB + db EEVEE + db ZAPDOS1 + db ZAPDOS2 + db ZAPDOS3 + db $00 + +.list_bench ; 14b43 (5:4b43) + db ZAPDOS2 + db ZAPDOS1 + db EEVEE + db VOLTORB + db ELECTABUZZ2 + db $00 + +.list_retreat ; 14b49 (5:4b49) + ai_retreat EEVEE, -5 + ai_retreat VOLTORB, -5 + ai_retreat ELECTABUZZ2, -5 + db $00 + +.list_energy ; 14b50 (5:4b50) + ai_energy VOLTORB, 1, -1 + ai_energy ELECTRODE1, 3, +0 + ai_energy ELECTABUZZ2, 2, -1 + ai_energy JOLTEON2, 3, +1 + ai_energy ZAPDOS1, 4, +2 + ai_energy ZAPDOS2, 4, +2 + ai_energy ZAPDOS3, 3, +1 + ai_energy EEVEE, 3, +0 + db $00 + +.list_prize ; 14b69 (5:4b69) + db GAMBLER + db ZAPDOS3 + db $00 + +.store_list_pointers ; 14b6c (5:4b6c) + store_list_pointer wAICardListAvoidPrize, .list_prize + store_list_pointer wAICardListArenaPriority, .list_arena + store_list_pointer wAICardListBenchPriority, .list_bench + store_list_pointer wAICardListPlayFromHandPriority, .list_bench + ; missing store_list_pointer wAICardListRetreatBonus, .list_retreat + store_list_pointer wAICardListEnergyBonus, .list_energy + ret + +AIDoTurn_LegendaryZapdos: ; 14b9a (5:4b9a) +; initialize variables + call InitAITurnVars + farcall HandleAIAntiMewtwoDeckStrategy + jp nc, .try_attack +; process Trainer cards + ld a, AI_TRAINER_CARD_PHASE_01 + call AIProcessHandTrainerCards + ld a, AI_TRAINER_CARD_PHASE_04 + call AIProcessHandTrainerCards +; play Pokemon from hand + call AIDecidePlayPokemonCard + ret c ; return if turn ended + ld a, AI_TRAINER_CARD_PHASE_07 + call AIProcessHandTrainerCards + call AIProcessRetreat + ld a, AI_TRAINER_CARD_PHASE_10 + call AIProcessHandTrainerCards +; play Energy card if possible. + ld a, [wAlreadyPlayedEnergy] + or a + jr nz, .skip_energy_attach + +; if Arena card is Voltorb and there's Electrode1 in hand, +; or if it's Electabuzz, try attaching Energy card +; to the Arena card if it doesn't have any energy attached. +; Otherwise if Energy card is not needed, +; go through normal AI energy attach routine. + ld a, DUELVARS_ARENA_CARD + call GetTurnDuelistVariable + call GetCardIDFromDeckIndex + ld a, VOLTORB + cp e + jr nz, .check_electabuzz + ld a, ELECTRODE1 + call LookForCardIDInHandList_Bank5 + jr nc, .attach_normally + jr .voltorb_or_electabuzz +.check_electabuzz + ld a, ELECTABUZZ2 + cp e + jr nz, .attach_normally + +.voltorb_or_electabuzz + call CreateEnergyCardListFromHand + jr c, .skip_energy_attach + ld e, PLAY_AREA_ARENA + call CountNumberOfEnergyCardsAttached + or a + jr nz, .attach_normally + xor a ; PLAY_AREA_ARENA + ldh [hTempPlayAreaLocation_ff9d], a + call AITryToPlayEnergyCard + jr c, .skip_energy_attach + +.attach_normally + call AIProcessAndTryToPlayEnergy + +.skip_energy_attach +; play Pokemon from hand again + call AIDecidePlayPokemonCard + ret c ; return if turn ended + ld a, AI_TRAINER_CARD_PHASE_13 + call AIProcessHandTrainerCards +.try_attack +; attack if possible, if not, +; finish turn without attacking. + call AIProcessAndTryToUseAttack + ret c ; return if turn ended + ld a, OPPACTION_FINISH_NO_ATTACK + bank1call AIMakeDecision + ret +; 0x14c0b diff --git a/src/engine/deck_ai/decks/powerful_ronald.asm b/src/engine/deck_ai/decks/powerful_ronald.asm index d99f87f..9f1b0f3 100644 --- a/src/engine/deck_ai/decks/powerful_ronald.asm +++ b/src/engine/deck_ai/decks/powerful_ronald.asm @@ -1,98 +1,93 @@ -AIActionTable_PowerfulRonald: ; 1534b (5:534b)
- dw .do_turn ; unused
- dw .do_turn
- dw .start_duel
- dw .forced_switch
- dw .ko_switch
- dw .take_prize
-
-.do_turn ; 15357 (5:5357)
- call AIMainTurnLogic
- ret
-; 0x1535b
-
-.start_duel ; 1535b (5:535b)
- call InitAIDuelVars
- call .store_list_pointers
- call SetUpBossStartingHandAndDeck
- call TrySetUpBossStartingPlayArea
- ret nc
- call AIPlayInitialBasicCards
- ret
-; 0x1536c
-
-.forced_switch ; 1536c (5:536c)
- call AIDecideBenchPokemonToSwitchTo
- ret
-; 0x15370
-
-.ko_switch ; 15370 (5:5370)
- call AIDecideBenchPokemonToSwitchTo
- ret
-; 0x15374
-
-.take_prize ; 15374 (5:5374)
- call AIPickPrizeCards
- ret
-; 0x15378
-
-.list_arena ; 15378 (5:5378)
- db KANGASKHAN
- db ELECTABUZZ2
- db HITMONCHAN
- db MR_MIME
- db LICKITUNG
- db HITMONLEE
- db TAUROS
- db JYNX
- db MEWTWO1
- db DODUO
- db $00
-
-.list_bench ; 15383 (5:5383)
- db KANGASKHAN
- db HITMONLEE
- db HITMONCHAN
- db TAUROS
- db DODUO
- db JYNX
- db MEWTWO1
- db ELECTABUZZ2
- db MR_MIME
- db LICKITUNG
- db $00
-
-.list_retreat ; 1538e (5:538e)
- ai_retreat KANGASKHAN, -1
- ai_retreat DODUO, -1
- ai_retreat DODRIO, -1
- db $00
-
-.list_energy ; 15395 (5:5395)
- ai_energy ELECTABUZZ2, 2, +1
- ai_energy HITMONLEE, 3, +1
- ai_energy HITMONCHAN, 3, +1
- ai_energy MR_MIME, 2, +0
- ai_energy JYNX, 3, +0
- ai_energy MEWTWO1, 2, +0
- ai_energy DODUO, 3, -1
- ai_energy DODRIO, 3, -1
- ai_energy LICKITUNG, 2, +0
- ai_energy KANGASKHAN, 4, -1
- ai_energy TAUROS, 3, +0
- db $00
-
-.list_prize ; 153b7 (5:53b7)
- db GAMBLER
- db ENERGY_REMOVAL
- db $00
-
-.store_list_pointers ; 153ba (5:53ba)
- store_list_pointer wAICardListAvoidPrize, .list_prize
- store_list_pointer wAICardListArenaPriority, .list_arena
- store_list_pointer wAICardListBenchPriority, .list_bench
- store_list_pointer wAICardListPlayFromHandPriority, .list_bench
- ; missing store_list_pointer wAICardListRetreatBonus, .list_retreat
- store_list_pointer wAICardListEnergyBonus, .list_energy
- ret
-; 0x153e8
+AIActionTable_PowerfulRonald: ; 1534b (5:534b) + dw .do_turn ; unused + dw .do_turn + dw .start_duel + dw .forced_switch + dw .ko_switch + dw .take_prize + +.do_turn ; 15357 (5:5357) + call AIMainTurnLogic + ret + +.start_duel ; 1535b (5:535b) + call InitAIDuelVars + call .store_list_pointers + call SetUpBossStartingHandAndDeck + call TrySetUpBossStartingPlayArea + ret nc + call AIPlayInitialBasicCards + ret + +.forced_switch ; 1536c (5:536c) + call AIDecideBenchPokemonToSwitchTo + ret + +.ko_switch ; 15370 (5:5370) + call AIDecideBenchPokemonToSwitchTo + ret + +.take_prize ; 15374 (5:5374) + call AIPickPrizeCards + ret + +.list_arena ; 15378 (5:5378) + db KANGASKHAN + db ELECTABUZZ2 + db HITMONCHAN + db MR_MIME + db LICKITUNG + db HITMONLEE + db TAUROS + db JYNX + db MEWTWO1 + db DODUO + db $00 + +.list_bench ; 15383 (5:5383) + db KANGASKHAN + db HITMONLEE + db HITMONCHAN + db TAUROS + db DODUO + db JYNX + db MEWTWO1 + db ELECTABUZZ2 + db MR_MIME + db LICKITUNG + db $00 + +.list_retreat ; 1538e (5:538e) + ai_retreat KANGASKHAN, -1 + ai_retreat DODUO, -1 + ai_retreat DODRIO, -1 + db $00 + +.list_energy ; 15395 (5:5395) + ai_energy ELECTABUZZ2, 2, +1 + ai_energy HITMONLEE, 3, +1 + ai_energy HITMONCHAN, 3, +1 + ai_energy MR_MIME, 2, +0 + ai_energy JYNX, 3, +0 + ai_energy MEWTWO1, 2, +0 + ai_energy DODUO, 3, -1 + ai_energy DODRIO, 3, -1 + ai_energy LICKITUNG, 2, +0 + ai_energy KANGASKHAN, 4, -1 + ai_energy TAUROS, 3, +0 + db $00 + +.list_prize ; 153b7 (5:53b7) + db GAMBLER + db ENERGY_REMOVAL + db $00 + +.store_list_pointers ; 153ba (5:53ba) + store_list_pointer wAICardListAvoidPrize, .list_prize + store_list_pointer wAICardListArenaPriority, .list_arena + store_list_pointer wAICardListBenchPriority, .list_bench + store_list_pointer wAICardListPlayFromHandPriority, .list_bench + ; missing store_list_pointer wAICardListRetreatBonus, .list_retreat + store_list_pointer wAICardListEnergyBonus, .list_energy + ret +; 0x153e8 diff --git a/src/engine/deck_ai/decks/rock_crusher.asm b/src/engine/deck_ai/decks/rock_crusher.asm index f4e79d8..7e5cb0a 100644 --- a/src/engine/deck_ai/decks/rock_crusher.asm +++ b/src/engine/deck_ai/decks/rock_crusher.asm @@ -1,80 +1,75 @@ -AIActionTable_RockCrusher: ; 14f0e (5:4f0e)
- dw .do_turn ; unused
- dw .do_turn
- dw .start_duel
- dw .forced_switch
- dw .ko_switch
- dw .take_prize
-
-.do_turn ; 14f1a (5:4f1a)
- call AIMainTurnLogic
- ret
-; 0x14f1e
-
-.start_duel ; 14f1e (5:4f1e)
- call InitAIDuelVars
- call .store_list_pointers
- call SetUpBossStartingHandAndDeck
- call TrySetUpBossStartingPlayArea
- ret nc
- call AIPlayInitialBasicCards
- ret
-; 0x14f2f
-
-.forced_switch ; 14f2f (5:4f2f)
- call AIDecideBenchPokemonToSwitchTo
- ret
-; 0x14f33
-
-.ko_switch ; 14f33 (5:4f33)
- call AIDecideBenchPokemonToSwitchTo
- ret
-; 0x14f37
-
-.take_prize ; 14f37 (5:4f37)
- call AIPickPrizeCards
- ret
-; 0x14f3b
-
-.list_arena ; 14f3b (5:4f3b)
- db RHYHORN
- db ONIX
- db GEODUDE
- db DIGLETT
- db $00
-
-.list_bench ; 14f40 (5:4f40)
- db DIGLETT
- db GEODUDE
- db RHYHORN
- db ONIX
- db $00
-
-.list_retreat ; 14f45 (5:4f45)
- ai_retreat DIGLETT, -1
- db $00
-
-.list_energy ; 14f48 (5:4f48)
- ai_energy DIGLETT, 3, +1
- ai_energy DUGTRIO, 4, +0
- ai_energy GEODUDE, 2, +1
- ai_energy GRAVELER, 3, +0
- ai_energy GOLEM, 4, +0
- ai_energy ONIX, 2, -1
- ai_energy RHYHORN, 3, +0
- db $00
-
-.list_prize ; 14f5e (5:4f5e)
- db ENERGY_REMOVAL
- db RHYHORN
- db $00
-
-.store_list_pointers ; 14f61 (5:4f61)
- store_list_pointer wAICardListAvoidPrize, .list_prize
- store_list_pointer wAICardListArenaPriority, .list_arena
- store_list_pointer wAICardListBenchPriority, .list_bench
- store_list_pointer wAICardListPlayFromHandPriority, .list_bench
- ; missing store_list_pointer wAICardListRetreatBonus, .list_retreat
- store_list_pointer wAICardListEnergyBonus, .list_energy
- ret
-; 0x14f8f
+AIActionTable_RockCrusher: ; 14f0e (5:4f0e) + dw .do_turn ; unused + dw .do_turn + dw .start_duel + dw .forced_switch + dw .ko_switch + dw .take_prize + +.do_turn ; 14f1a (5:4f1a) + call AIMainTurnLogic + ret + +.start_duel ; 14f1e (5:4f1e) + call InitAIDuelVars + call .store_list_pointers + call SetUpBossStartingHandAndDeck + call TrySetUpBossStartingPlayArea + ret nc + call AIPlayInitialBasicCards + ret + +.forced_switch ; 14f2f (5:4f2f) + call AIDecideBenchPokemonToSwitchTo + ret + +.ko_switch ; 14f33 (5:4f33) + call AIDecideBenchPokemonToSwitchTo + ret + +.take_prize ; 14f37 (5:4f37) + call AIPickPrizeCards + ret + +.list_arena ; 14f3b (5:4f3b) + db RHYHORN + db ONIX + db GEODUDE + db DIGLETT + db $00 + +.list_bench ; 14f40 (5:4f40) + db DIGLETT + db GEODUDE + db RHYHORN + db ONIX + db $00 + +.list_retreat ; 14f45 (5:4f45) + ai_retreat DIGLETT, -1 + db $00 + +.list_energy ; 14f48 (5:4f48) + ai_energy DIGLETT, 3, +1 + ai_energy DUGTRIO, 4, +0 + ai_energy GEODUDE, 2, +1 + ai_energy GRAVELER, 3, +0 + ai_energy GOLEM, 4, +0 + ai_energy ONIX, 2, -1 + ai_energy RHYHORN, 3, +0 + db $00 + +.list_prize ; 14f5e (5:4f5e) + db ENERGY_REMOVAL + db RHYHORN + db $00 + +.store_list_pointers ; 14f61 (5:4f61) + store_list_pointer wAICardListAvoidPrize, .list_prize + store_list_pointer wAICardListArenaPriority, .list_arena + store_list_pointer wAICardListBenchPriority, .list_bench + store_list_pointer wAICardListPlayFromHandPriority, .list_bench + ; missing store_list_pointer wAICardListRetreatBonus, .list_retreat + store_list_pointer wAICardListEnergyBonus, .list_energy + ret +; 0x14f8f diff --git a/src/engine/deck_ai/decks/sams_practice.asm b/src/engine/deck_ai/decks/sams_practice.asm index 2ce0060..b7642a8 100644 --- a/src/engine/deck_ai/decks/sams_practice.asm +++ b/src/engine/deck_ai/decks/sams_practice.asm @@ -1,222 +1,206 @@ -; AI for Sam's practice duel, which handles his scripted actions.
-; will act as a normal duelist AI after turn 7.
-AIActionTable_SamPractice: ; 147bd (05:47bd)
- dw .do_turn ; unused
- dw .do_turn
- dw .start_duel
- dw .forced_switch
- dw .ko_switch
- dw .take_prize
-
-.do_turn ; 147c9 (5:47c9)
- call IsAIPracticeScriptedTurn
- jr nc, .scripted_1
-; not scripted, use AI main turn logic
- call AIMainTurnLogic
- ret
-.scripted_1 ; use scripted actions instead
- call AIPerformSciptedTurn
- ret
-; 0x147d6
-
-.start_duel ; 147d6 (5:47d6)
- call SetSamsStartingPlayArea
- ret
-; 0x147da
-
-.forced_switch ; 147da (5:47da)
- call IsAIPracticeScriptedTurn
- jr nc, .scripted_2
- call AIDecideBenchPokemonToSwitchTo
- ret
-.scripted_2
- call PickRandomBenchPokemon
- ret
-; 0x147e7
-
-.ko_switch: ; 147e7 (5:47e7)
- call IsAIPracticeScriptedTurn
- jr nc, .scripted_3
- call AIDecideBenchPokemonToSwitchTo
- ret
-.scripted_3
- call GetPlayAreaLocationOfRaticateOrRattata
- ret
-; 0x147f4
-
-.take_prize: ; 147f4 (5:47f4)
- call AIPickPrizeCards
- ret
-; 0x147f8
-
-; returns carry if number of turns
-; the AI has taken >= 7.
-; used to know whether AI Sam is still
-; doing scripted turns.
-IsAIPracticeScriptedTurn: ; 147f8 (5:47f8)
- ld a, [wDuelTurns]
- srl a
- cp 7
- ccf
- ret
-; 0x14801
-
-; places one Machop from the hand to the Play Area
-; and sets the number of prizes to 2.
-SetSamsStartingPlayArea: ; 14801 (5:4801)
- call CreateHandCardList
- ld hl, wDuelTempList
-.loop_hand
- ld a, [hli]
- ldh [hTempCardIndex_ff98], a
- cp $ff
- ret z
- call LoadCardDataToBuffer1_FromDeckIndex
- cp MACHOP
- jr nz, .loop_hand
- ldh a, [hTempCardIndex_ff98]
- call PutHandPokemonCardInPlayArea
- ld a, 2
- ld [wDuelInitialPrizes], a
- ret
-; 0x1481f
-
-; outputs in a Play Area location of Raticate or Rattata
-; in the Bench. If neither is found, just output PLAY_AREA_BENCH_1.
-GetPlayAreaLocationOfRaticateOrRattata: ; 1481f (5:481f)
- ld a, RATICATE
- ld b, PLAY_AREA_BENCH_1
- call LookForCardIDInPlayArea_Bank5
- cp $ff
- jr nz, .found
- ld a, RATTATA
- ld b, PLAY_AREA_BENCH_1
- call LookForCardIDInPlayArea_Bank5
- cp $ff
- jr nz, .found
- ld a, PLAY_AREA_BENCH_1
-.found
- ldh [hTempPlayAreaLocation_ff9d], a
- ret
-; 0x1483a
-
-; has AI execute some scripted actions depending on Duel turn.
-AIPerformSciptedTurn: ; 1483a (5:483a)
- ld a, [wDuelTurns]
- srl a
- ld hl, .scripted_actions_list
- call JumpToFunctionInTable
-
-; always attack with Arena card's first attack.
-; if it's unusable end turn without attacking.
- xor a
- ldh [hTempPlayAreaLocation_ff9d], a
- ld [wSelectedAttack], a
- call CheckIfSelectedMoveIsUnusable
- jr c, .unusable
- call AITryUseAttack
- ret
-
-.unusable
- ld a, OPPACTION_FINISH_NO_ATTACK
- bank1call AIMakeDecision
- ret
-; 0x1485a
-
-.scripted_actions_list ; 1485a (05:485a)
- dw .turn_1
- dw .turn_2
- dw .turn_3
- dw .turn_4
- dw .turn_5
- dw .turn_6
- dw .turn_7
-; 0x14868
-
-.turn_1 ; 14868 (5:4868)
- ld d, MACHOP
- ld e, FIGHTING_ENERGY
- call AIAttachEnergyInHandToCardInPlayArea
- ret
-; 0x14870
-
-.turn_2 ; 14870 (5:4870)
- ld a, RATTATA
- call LookForCardIDInHandList_Bank5
- ldh [hTemp_ffa0], a
- ld a, OPPACTION_PLAY_BASIC_PKMN
- bank1call AIMakeDecision
- ld d, RATTATA
- ld e, FIGHTING_ENERGY
- call AIAttachEnergyInHandToCardInPlayArea
- ret
-; 0x14884
-
-.turn_3 ; 14884 (5:4884)
- ld a, RATTATA
- ld b, PLAY_AREA_ARENA
- call LookForCardIDInPlayArea_Bank5
- ldh [hTempPlayAreaLocation_ffa1], a
- ld a, RATICATE
- call LookForCardIDInHandList_Bank5
- ldh [hTemp_ffa0], a
- ld a, OPPACTION_EVOLVE_PKMN
- bank1call AIMakeDecision
- ld d, RATICATE
- ld e, LIGHTNING_ENERGY
- call AIAttachEnergyInHandToCardInPlayArea
- ret
-; 0x148a1
-
-.turn_4 ; 148a1 (5:48a1)
- ld d, RATICATE
- ld e, LIGHTNING_ENERGY
- call AIAttachEnergyInHandToCardInPlayArea
- ret
-; 0x148a9
-
-.turn_5 ; 148a9 (5:48a9)
- ld a, MACHOP
- call LookForCardIDInHandList_Bank5
- ldh [hTemp_ffa0], a
- ld a, OPPACTION_PLAY_BASIC_PKMN
- bank1call AIMakeDecision
- ld d, MACHOP
- ld e, FIGHTING_ENERGY
- call AIAttachEnergyInHandToCardInBench
-
-; this is a bug, it's attempting to compare a card ID with a deck index.
-; the intention was to change the card to switch to depending on whether
-; the first Machop was KO'd at this point in the Duel or not.
-; because of the buggy comparison, this will always jump the
-; 'inc a' instruction and switch to PLAY_AREA_BENCH_1.
-; in a normal Practice Duel following Dr. Mason's instructions,
-; this will always lead to the AI correctly switching Raticate with Machop,
-; but in case of a "Free" Duel where the first Machop is not KO'd,
-; the intention was to switch to PLAY_AREA_BENCH_2 instead.
-; but due to 'inc a' always being skipped, it will switch to Raticate.
- ld a, DUELVARS_ARENA_CARD
- call GetTurnDuelistVariable
- cp MACHOP ; wrong
- ld a, PLAY_AREA_BENCH_1
- jr nz, .retreat
- inc a ; PLAY_AREA_BENCH_2
-
-.retreat
- call AITryToRetreat
- ret
-; 0x148cc
-
-.turn_6 ; 148cc (5:48cc)
- ld d, MACHOP
- ld e, FIGHTING_ENERGY
- call AIAttachEnergyInHandToCardInPlayArea
- ret
-; 0x148d4
-
-.turn_7 ; 148d4 (5:48d4)
- ld d, MACHOP
- ld e, FIGHTING_ENERGY
- call AIAttachEnergyInHandToCardInPlayArea
- ret
-; 0x148dc
+; AI for Sam's practice duel, which handles his scripted actions. +; will act as a normal duelist AI after turn 7. +AIActionTable_SamPractice: ; 147bd (05:47bd) + dw .do_turn ; unused + dw .do_turn + dw .start_duel + dw .forced_switch + dw .ko_switch + dw .take_prize + +.do_turn ; 147c9 (5:47c9) + call IsAIPracticeScriptedTurn + jr nc, .scripted_1 +; not scripted, use AI main turn logic + call AIMainTurnLogic + ret +.scripted_1 ; use scripted actions instead + call AIPerformSciptedTurn + ret + +.start_duel ; 147d6 (5:47d6) + call SetSamsStartingPlayArea + ret + +.forced_switch ; 147da (5:47da) + call IsAIPracticeScriptedTurn + jr nc, .scripted_2 + call AIDecideBenchPokemonToSwitchTo + ret +.scripted_2 + call PickRandomBenchPokemon + ret + +.ko_switch: ; 147e7 (5:47e7) + call IsAIPracticeScriptedTurn + jr nc, .scripted_3 + call AIDecideBenchPokemonToSwitchTo + ret +.scripted_3 + call GetPlayAreaLocationOfRaticateOrRattata + ret + +.take_prize: ; 147f4 (5:47f4) + call AIPickPrizeCards + ret + +; returns carry if number of turns +; the AI has taken >= 7. +; used to know whether AI Sam is still +; doing scripted turns. +IsAIPracticeScriptedTurn: ; 147f8 (5:47f8) + ld a, [wDuelTurns] + srl a + cp 7 + ccf + ret + +; places one Machop from the hand to the Play Area +; and sets the number of prizes to 2. +SetSamsStartingPlayArea: ; 14801 (5:4801) + call CreateHandCardList + ld hl, wDuelTempList +.loop_hand + ld a, [hli] + ldh [hTempCardIndex_ff98], a + cp $ff + ret z + call LoadCardDataToBuffer1_FromDeckIndex + cp MACHOP + jr nz, .loop_hand + ldh a, [hTempCardIndex_ff98] + call PutHandPokemonCardInPlayArea + ld a, 2 + ld [wDuelInitialPrizes], a + ret + +; outputs in a Play Area location of Raticate or Rattata +; in the Bench. If neither is found, just output PLAY_AREA_BENCH_1. +GetPlayAreaLocationOfRaticateOrRattata: ; 1481f (5:481f) + ld a, RATICATE + ld b, PLAY_AREA_BENCH_1 + call LookForCardIDInPlayArea_Bank5 + cp $ff + jr nz, .found + ld a, RATTATA + ld b, PLAY_AREA_BENCH_1 + call LookForCardIDInPlayArea_Bank5 + cp $ff + jr nz, .found + ld a, PLAY_AREA_BENCH_1 +.found + ldh [hTempPlayAreaLocation_ff9d], a + ret + +; has AI execute some scripted actions depending on Duel turn. +AIPerformSciptedTurn: ; 1483a (5:483a) + ld a, [wDuelTurns] + srl a + ld hl, .scripted_actions_list + call JumpToFunctionInTable + +; always attack with Arena card's first attack. +; if it's unusable end turn without attacking. + xor a + ldh [hTempPlayAreaLocation_ff9d], a + ld [wSelectedAttack], a + call CheckIfSelectedMoveIsUnusable + jr c, .unusable + call AITryUseAttack + ret + +.unusable + ld a, OPPACTION_FINISH_NO_ATTACK + bank1call AIMakeDecision + ret + +.scripted_actions_list ; 1485a (05:485a) + dw .turn_1 + dw .turn_2 + dw .turn_3 + dw .turn_4 + dw .turn_5 + dw .turn_6 + dw .turn_7 + +.turn_1 ; 14868 (5:4868) + ld d, MACHOP + ld e, FIGHTING_ENERGY + call AIAttachEnergyInHandToCardInPlayArea + ret + +.turn_2 ; 14870 (5:4870) + ld a, RATTATA + call LookForCardIDInHandList_Bank5 + ldh [hTemp_ffa0], a + ld a, OPPACTION_PLAY_BASIC_PKMN + bank1call AIMakeDecision + ld d, RATTATA + ld e, FIGHTING_ENERGY + call AIAttachEnergyInHandToCardInPlayArea + ret + +.turn_3 ; 14884 (5:4884) + ld a, RATTATA + ld b, PLAY_AREA_ARENA + call LookForCardIDInPlayArea_Bank5 + ldh [hTempPlayAreaLocation_ffa1], a + ld a, RATICATE + call LookForCardIDInHandList_Bank5 + ldh [hTemp_ffa0], a + ld a, OPPACTION_EVOLVE_PKMN + bank1call AIMakeDecision + ld d, RATICATE + ld e, LIGHTNING_ENERGY + call AIAttachEnergyInHandToCardInPlayArea + ret + +.turn_4 ; 148a1 (5:48a1) + ld d, RATICATE + ld e, LIGHTNING_ENERGY + call AIAttachEnergyInHandToCardInPlayArea + ret + +.turn_5 ; 148a9 (5:48a9) + ld a, MACHOP + call LookForCardIDInHandList_Bank5 + ldh [hTemp_ffa0], a + ld a, OPPACTION_PLAY_BASIC_PKMN + bank1call AIMakeDecision + ld d, MACHOP + ld e, FIGHTING_ENERGY + call AIAttachEnergyInHandToCardInBench + +; this is a bug, it's attempting to compare a card ID with a deck index. +; the intention was to change the card to switch to depending on whether +; the first Machop was KO'd at this point in the Duel or not. +; because of the buggy comparison, this will always jump the +; 'inc a' instruction and switch to PLAY_AREA_BENCH_1. +; in a normal Practice Duel following Dr. Mason's instructions, +; this will always lead to the AI correctly switching Raticate with Machop, +; but in case of a "Free" Duel where the first Machop is not KO'd, +; the intention was to switch to PLAY_AREA_BENCH_2 instead. +; but due to 'inc a' always being skipped, it will switch to Raticate. + ld a, DUELVARS_ARENA_CARD + call GetTurnDuelistVariable + cp MACHOP ; wrong + ld a, PLAY_AREA_BENCH_1 + jr nz, .retreat + inc a ; PLAY_AREA_BENCH_2 + +.retreat + call AITryToRetreat + ret + +.turn_6 ; 148cc (5:48cc) + ld d, MACHOP + ld e, FIGHTING_ENERGY + call AIAttachEnergyInHandToCardInPlayArea + ret + +.turn_7 ; 148d4 (5:48d4) + ld d, MACHOP + ld e, FIGHTING_ENERGY + call AIAttachEnergyInHandToCardInPlayArea + ret +; 0x148dc diff --git a/src/engine/deck_ai/decks/strange_psyshock.asm b/src/engine/deck_ai/decks/strange_psyshock.asm index 309ef11..1ab948c 100644 --- a/src/engine/deck_ai/decks/strange_psyshock.asm +++ b/src/engine/deck_ai/decks/strange_psyshock.asm @@ -1,87 +1,82 @@ -AIActionTable_StrangePsyshock: ; 15122 (5:5122)
- dw .do_turn ; unused
- dw .do_turn
- dw .start_duel
- dw .forced_switch
- dw .ko_switch
- dw .take_prize
-
-.do_turn ; 1512e (5:512e)
- call AIMainTurnLogic
- ret
-; 0x15132
-
-.start_duel ; 15132 (5:5132)
- call InitAIDuelVars
- call .store_list_pointers
- call SetUpBossStartingHandAndDeck
- call TrySetUpBossStartingPlayArea
- ret nc
- call AIPlayInitialBasicCards
- ret
-; 0x15143
-
-.forced_switch ; 15143 (5:5143)
- call AIDecideBenchPokemonToSwitchTo
- ret
-; 0x15147
-
-.ko_switch ; 15147 (5:5147)
- call AIDecideBenchPokemonToSwitchTo
- ret
-; 0x1514b
-
-.take_prize ; 1514b (5:514b)
- call AIPickPrizeCards
- ret
-; 0x1514f
-
-.list_arena ; 1514f (5:514f)
- db KANGASKHAN
- db CHANSEY
- db SNORLAX
- db MR_MIME
- db ABRA
- db $00
-
-.list_bench ; 15155 (5:5155)
- db ABRA
- db MR_MIME
- db KANGASKHAN
- db SNORLAX
- db CHANSEY
- db $00
-
-.list_retreat ; 1515b (5:515b)
- ai_retreat ABRA, -3
- ai_retreat SNORLAX, -3
- ai_retreat KANGASKHAN, -1
- ai_retreat CHANSEY, -1
- db $00
-
-.list_energy ; 15164 (5:5164)
- ai_energy ABRA, 3, +1
- ai_energy KADABRA, 3, +0
- ai_energy ALAKAZAM, 3, +0
- ai_energy MR_MIME, 2, +0
- ai_energy CHANSEY, 2, -2
- ai_energy KANGASKHAN, 4, -2
- ai_energy SNORLAX, 0, -8
- db $00
-
-.list_prize ; 1517a (5:517a)
- db GAMBLER
- db MR_MIME
- db ALAKAZAM
- db SWITCH
- db $00
-
-.store_list_pointers ; 1517f (5:517f)
- store_list_pointer wAICardListAvoidPrize, .list_prize
- store_list_pointer wAICardListArenaPriority, .list_arena
- store_list_pointer wAICardListBenchPriority, .list_bench
- store_list_pointer wAICardListPlayFromHandPriority, .list_bench
- ; missing store_list_pointer wAICardListRetreatBonus, .list_retreat
- store_list_pointer wAICardListEnergyBonus, .list_energy
- ret
-; 0x151ad
+AIActionTable_StrangePsyshock: ; 15122 (5:5122) + dw .do_turn ; unused + dw .do_turn + dw .start_duel + dw .forced_switch + dw .ko_switch + dw .take_prize + +.do_turn ; 1512e (5:512e) + call AIMainTurnLogic + ret + +.start_duel ; 15132 (5:5132) + call InitAIDuelVars + call .store_list_pointers + call SetUpBossStartingHandAndDeck + call TrySetUpBossStartingPlayArea + ret nc + call AIPlayInitialBasicCards + ret + +.forced_switch ; 15143 (5:5143) + call AIDecideBenchPokemonToSwitchTo + ret + +.ko_switch ; 15147 (5:5147) + call AIDecideBenchPokemonToSwitchTo + ret + +.take_prize ; 1514b (5:514b) + call AIPickPrizeCards + ret + +.list_arena ; 1514f (5:514f) + db KANGASKHAN + db CHANSEY + db SNORLAX + db MR_MIME + db ABRA + db $00 + +.list_bench ; 15155 (5:5155) + db ABRA + db MR_MIME + db KANGASKHAN + db SNORLAX + db CHANSEY + db $00 + +.list_retreat ; 1515b (5:515b) + ai_retreat ABRA, -3 + ai_retreat SNORLAX, -3 + ai_retreat KANGASKHAN, -1 + ai_retreat CHANSEY, -1 + db $00 + +.list_energy ; 15164 (5:5164) + ai_energy ABRA, 3, +1 + ai_energy KADABRA, 3, +0 + ai_energy ALAKAZAM, 3, +0 + ai_energy MR_MIME, 2, +0 + ai_energy CHANSEY, 2, -2 + ai_energy KANGASKHAN, 4, -2 + ai_energy SNORLAX, 0, -8 + db $00 + +.list_prize ; 1517a (5:517a) + db GAMBLER + db MR_MIME + db ALAKAZAM + db SWITCH + db $00 + +.store_list_pointers ; 1517f (5:517f) + store_list_pointer wAICardListAvoidPrize, .list_prize + store_list_pointer wAICardListArenaPriority, .list_arena + store_list_pointer wAICardListBenchPriority, .list_bench + store_list_pointer wAICardListPlayFromHandPriority, .list_bench + ; missing store_list_pointer wAICardListRetreatBonus, .list_retreat + store_list_pointer wAICardListEnergyBonus, .list_energy + ret +; 0x151ad diff --git a/src/engine/deck_ai/decks/wonders_of_science.asm b/src/engine/deck_ai/decks/wonders_of_science.asm index e11a829..24ad09d 100644 --- a/src/engine/deck_ai/decks/wonders_of_science.asm +++ b/src/engine/deck_ai/decks/wonders_of_science.asm @@ -1,83 +1,78 @@ -AIActionTable_WondersOfScience: ; 151ad (5:51ad)
- dw .do_turn ; unused
- dw .do_turn
- dw .start_duel
- dw .forced_switch
- dw .ko_switch
- dw .take_prize
-
-.do_turn ; 151b9 (5:51b9)
- call AIMainTurnLogic
- ret
-; 0x151bd
-
-.start_duel ; 151bd (5:51bd)
- call InitAIDuelVars
- call .store_list_pointers
- call SetUpBossStartingHandAndDeck
- call TrySetUpBossStartingPlayArea
- ret nc
- call AIPlayInitialBasicCards
- ret
-; 0x151ce
-
-.forced_switch ; 151ce (5:51ce)
- call AIDecideBenchPokemonToSwitchTo
- ret
-; 0x151d2
-
-.ko_switch ; 151d2 (5:51d2)
- call AIDecideBenchPokemonToSwitchTo
- ret
-; 0x151d6
-
-.take_prize ; 151d6 (5:51d6)
- call AIPickPrizeCards
- ret
-; 0x151da
-
-.list_arena ; 151da (5:51da)
- db MEWTWO1
- db MEWTWO3
- db MEWTWO2
- db GRIMER
- db KOFFING
- db PORYGON
- db $00
-
-.list_bench ; 151e1 (5:51e1)
- db GRIMER
- db KOFFING
- db MEWTWO3
- db MEWTWO2
- db MEWTWO1
- db PORYGON
- db $00
-
-.list_retreat ; 151e8 (5:51e8)
- db $00
-
-.list_energy ; 151e9 (5:51e9)
- ai_energy GRIMER, 3, +0
- ai_energy MUK, 4, +0
- ai_energy KOFFING, 2, +0
- ai_energy WEEZING, 3, +0
- ai_energy MEWTWO1, 2, -1
- ai_energy MEWTWO3, 2, -1
- ai_energy MEWTWO2, 2, -1
- ai_energy PORYGON, 2, -1
- db $00
-
-.list_prize ; 15202 (5:5202)
- db MUK
- db $00
-
-.store_list_pointers ; 15204 (5:5204)
- store_list_pointer wAICardListAvoidPrize, .list_prize
- store_list_pointer wAICardListArenaPriority, .list_arena
- store_list_pointer wAICardListBenchPriority, .list_bench
- store_list_pointer wAICardListPlayFromHandPriority, .list_bench
- ; missing store_list_pointer wAICardListRetreatBonus, .list_retreat
- store_list_pointer wAICardListEnergyBonus, .list_energy
- ret
-; 0x15232
+AIActionTable_WondersOfScience: ; 151ad (5:51ad) + dw .do_turn ; unused + dw .do_turn + dw .start_duel + dw .forced_switch + dw .ko_switch + dw .take_prize + +.do_turn ; 151b9 (5:51b9) + call AIMainTurnLogic + ret + +.start_duel ; 151bd (5:51bd) + call InitAIDuelVars + call .store_list_pointers + call SetUpBossStartingHandAndDeck + call TrySetUpBossStartingPlayArea + ret nc + call AIPlayInitialBasicCards + ret + +.forced_switch ; 151ce (5:51ce) + call AIDecideBenchPokemonToSwitchTo + ret + +.ko_switch ; 151d2 (5:51d2) + call AIDecideBenchPokemonToSwitchTo + ret + +.take_prize ; 151d6 (5:51d6) + call AIPickPrizeCards + ret + +.list_arena ; 151da (5:51da) + db MEWTWO1 + db MEWTWO3 + db MEWTWO2 + db GRIMER + db KOFFING + db PORYGON + db $00 + +.list_bench ; 151e1 (5:51e1) + db GRIMER + db KOFFING + db MEWTWO3 + db MEWTWO2 + db MEWTWO1 + db PORYGON + db $00 + +.list_retreat ; 151e8 (5:51e8) + db $00 + +.list_energy ; 151e9 (5:51e9) + ai_energy GRIMER, 3, +0 + ai_energy MUK, 4, +0 + ai_energy KOFFING, 2, +0 + ai_energy WEEZING, 3, +0 + ai_energy MEWTWO1, 2, -1 + ai_energy MEWTWO3, 2, -1 + ai_energy MEWTWO2, 2, -1 + ai_energy PORYGON, 2, -1 + db $00 + +.list_prize ; 15202 (5:5202) + db MUK + db $00 + +.store_list_pointers ; 15204 (5:5204) + store_list_pointer wAICardListAvoidPrize, .list_prize + store_list_pointer wAICardListArenaPriority, .list_arena + store_list_pointer wAICardListBenchPriority, .list_bench + store_list_pointer wAICardListPlayFromHandPriority, .list_bench + ; missing store_list_pointer wAICardListRetreatBonus, .list_retreat + store_list_pointer wAICardListEnergyBonus, .list_energy + ret +; 0x15232 diff --git a/src/engine/deck_ai/decks/zapping_selfdestruct.asm b/src/engine/deck_ai/decks/zapping_selfdestruct.asm index 6675c52..b924061 100644 --- a/src/engine/deck_ai/decks/zapping_selfdestruct.asm +++ b/src/engine/deck_ai/decks/zapping_selfdestruct.asm @@ -1,81 +1,76 @@ -AIActionTable_ZappingSelfdestruct: ; 15019 (5:5019)
- dw .do_turn ; unused
- dw .do_turn
- dw .start_duel
- dw .forced_switch
- dw .ko_switch
- dw .take_prize
-
-.do_turn ; 15025 (5:5025)
- call AIMainTurnLogic
- ret
-; 0x15029
-
-.start_duel ; 15029 (5:5029)
- call InitAIDuelVars
- call .store_list_pointers
- call SetUpBossStartingHandAndDeck
- call TrySetUpBossStartingPlayArea
- ret nc
- call AIPlayInitialBasicCards
- ret
-; 0x1503a
-
-.forced_switch ; 1503a (5:503a)
- call AIDecideBenchPokemonToSwitchTo
- ret
-; 0x1503e
-
-.ko_switch ; 1503e (5:503e)
- call AIDecideBenchPokemonToSwitchTo
- ret
-; 0x15042
-
-.take_prize ; 15042 (5:5042)
- call AIPickPrizeCards
- ret
-; 0x15046
-
-.list_arena ; 15046 (5:5046)
- db KANGASKHAN
- db ELECTABUZZ2
- db TAUROS
- db MAGNEMITE1
- db VOLTORB
- db $00
-
-.list_bench ; 1504c (5:504c)
- db MAGNEMITE1
- db VOLTORB
- db ELECTABUZZ2
- db TAUROS
- db KANGASKHAN
- db $00
-
-.list_retreat ; 15052 (5:5052)
- ai_retreat VOLTORB, -1
- db $00
-
-.list_energy ; 15055 (5:5055)
- ai_energy MAGNEMITE1, 3, +1
- ai_energy MAGNETON1, 4, +0
- ai_energy VOLTORB, 3, +1
- ai_energy ELECTRODE1, 3, +0
- ai_energy ELECTABUZZ2, 1, +0
- ai_energy KANGASKHAN, 2, -2
- ai_energy TAUROS, 3, +0
- db $00
-
-.list_prize ; 1506b (5:506b)
- db KANGASKHAN
- db $00
-
-.store_list_pointers ; 1506d (5:506d)
- store_list_pointer wAICardListAvoidPrize, .list_prize
- store_list_pointer wAICardListArenaPriority, .list_arena
- store_list_pointer wAICardListBenchPriority, .list_bench
- store_list_pointer wAICardListPlayFromHandPriority, .list_bench
- ; missing store_list_pointer wAICardListRetreatBonus, .list_retreat
- store_list_pointer wAICardListEnergyBonus, .list_energy
- ret
-; 0x1509b
+AIActionTable_ZappingSelfdestruct: ; 15019 (5:5019) + dw .do_turn ; unused + dw .do_turn + dw .start_duel + dw .forced_switch + dw .ko_switch + dw .take_prize + +.do_turn ; 15025 (5:5025) + call AIMainTurnLogic + ret + +.start_duel ; 15029 (5:5029) + call InitAIDuelVars + call .store_list_pointers + call SetUpBossStartingHandAndDeck + call TrySetUpBossStartingPlayArea + ret nc + call AIPlayInitialBasicCards + ret + +.forced_switch ; 1503a (5:503a) + call AIDecideBenchPokemonToSwitchTo + ret + +.ko_switch ; 1503e (5:503e) + call AIDecideBenchPokemonToSwitchTo + ret + +.take_prize ; 15042 (5:5042) + call AIPickPrizeCards + ret + +.list_arena ; 15046 (5:5046) + db KANGASKHAN + db ELECTABUZZ2 + db TAUROS + db MAGNEMITE1 + db VOLTORB + db $00 + +.list_bench ; 1504c (5:504c) + db MAGNEMITE1 + db VOLTORB + db ELECTABUZZ2 + db TAUROS + db KANGASKHAN + db $00 + +.list_retreat ; 15052 (5:5052) + ai_retreat VOLTORB, -1 + db $00 + +.list_energy ; 15055 (5:5055) + ai_energy MAGNEMITE1, 3, +1 + ai_energy MAGNETON1, 4, +0 + ai_energy VOLTORB, 3, +1 + ai_energy ELECTRODE1, 3, +0 + ai_energy ELECTABUZZ2, 1, +0 + ai_energy KANGASKHAN, 2, -2 + ai_energy TAUROS, 3, +0 + db $00 + +.list_prize ; 1506b (5:506b) + db KANGASKHAN + db $00 + +.store_list_pointers ; 1506d (5:506d) + store_list_pointer wAICardListAvoidPrize, .list_prize + store_list_pointer wAICardListArenaPriority, .list_arena + store_list_pointer wAICardListBenchPriority, .list_bench + store_list_pointer wAICardListPlayFromHandPriority, .list_bench + ; missing store_list_pointer wAICardListRetreatBonus, .list_retreat + store_list_pointer wAICardListEnergyBonus, .list_energy + ret +; 0x1509b |