summaryrefslogtreecommitdiff
path: root/src/engine/duel/effect_functions.asm
diff options
context:
space:
mode:
Diffstat (limited to 'src/engine/duel/effect_functions.asm')
-rw-r--r--src/engine/duel/effect_functions.asm11194
1 files changed, 11194 insertions, 0 deletions
diff --git a/src/engine/duel/effect_functions.asm b/src/engine/duel/effect_functions.asm
new file mode 100644
index 0000000..ce3a517
--- /dev/null
+++ b/src/engine/duel/effect_functions.asm
@@ -0,0 +1,11194 @@
+Poison50PercentEffect: ; 2c000 (b:4000)
+ ldtx de, PoisonCheckText
+ call TossCoin_BankB
+ ret nc
+
+PoisonEffect: ; 2c007 (b:4007)
+ lb bc, CNF_SLP_PRZ, POISONED
+ jr ApplyStatusEffect
+
+DoublePoisonEffect: ; 2c00c (b:400c)
+ lb bc, CNF_SLP_PRZ, DOUBLE_POISONED
+ jr ApplyStatusEffect
+
+Paralysis50PercentEffect: ; 2c011 (b:4011)
+ ldtx de, ParalysisCheckText
+ call TossCoin_BankB
+ ret nc
+
+ParalysisEffect: ; 2c018 (b:4018)
+ lb bc, PSN_DBLPSN, PARALYZED
+ jr ApplyStatusEffect
+
+Confusion50PercentEffect: ; 2c01d (b:401d)
+ ldtx de, ConfusionCheckText
+ call TossCoin_BankB
+ ret nc
+
+ConfusionEffect: ; 2c024 (b:4024)
+ lb bc, PSN_DBLPSN, CONFUSED
+ jr ApplyStatusEffect
+
+Sleep50PercentEffect: ; 2c029 (b:4029)
+ ldtx de, SleepCheckText
+ call TossCoin_BankB
+ ret nc
+
+SleepEffect: ; 2c030 (b:4030)
+ lb bc, PSN_DBLPSN, ASLEEP
+ jr ApplyStatusEffect
+
+ApplyStatusEffect: ; 2c035 (b:4035)
+ ldh a, [hWhoseTurn]
+ ld hl, wWhoseTurn
+ cp [hl]
+ jr nz, .can_induce_status
+ ld a, [wTempNonTurnDuelistCardID]
+ cp CLEFAIRY_DOLL
+ jr z, .cant_induce_status
+ cp MYSTERIOUS_FOSSIL
+ jr z, .cant_induce_status
+ ; Snorlax's Thick Skinned prevents it from being statused...
+ cp SNORLAX
+ jr nz, .can_induce_status
+ call SwapTurn
+ xor a
+ ; ...unless already so, or if affected by Muk's Toxic Gas
+ call CheckCannotUseDueToStatus_OnlyToxicGasIfANon0
+ call SwapTurn
+ jr c, .can_induce_status
+
+.cant_induce_status
+ ld a, c
+ ld [wNoEffectFromWhichStatus], a
+ call SetNoEffectFromStatus
+ or a
+ ret
+
+.can_induce_status
+ ld hl, wEffectFunctionsFeedbackIndex
+ push hl
+ ld e, [hl]
+ ld d, $0
+ ld hl, wEffectFunctionsFeedback
+ add hl, de
+ call SwapTurn
+ ldh a, [hWhoseTurn]
+ ld [hli], a
+ call SwapTurn
+ ld [hl], b ; mask of status conditions not to discard on the target
+ inc hl
+ ld [hl], c ; status condition to inflict to the target
+ pop hl
+ ; advance wEffectFunctionsFeedbackIndex
+ inc [hl]
+ inc [hl]
+ inc [hl]
+ scf
+ ret
+
+TossCoin_BankB: ; 2c07e (b:407e)
+ call TossCoin
+ ret
+
+TossCoinATimes_BankB: ; 2c082 (b:4082)
+ call TossCoinATimes
+ ret
+
+CommentedOut_2c086: ; 2c086 (b:4086)
+ ret
+
+Func_2c087: ; 2c087 (b:4087)
+ xor a
+ jr Func_2c08c
+
+Func_2c08a: ; 2c08a (b:408a)
+ ld a, $1
+
+Func_2c08c: ; 2c08c (b:408c)
+ push de
+ push af
+ ld a, OPPACTION_TOSS_COIN_A_TIMES
+ call SetOppAction_SerialSendDuelData
+ pop af
+ pop de
+ call SerialSend8Bytes
+ call TossCoinATimes
+ ret
+
+SetNoEffectFromStatus: ; 2c09c (b:409c)
+ ld a, EFFECT_FAILED_NO_EFFECT
+ ld [wEffectFailed], a
+ ret
+
+SetWasUnsuccessful: ; 2c0a2 (b:40a2)
+ ld a, EFFECT_FAILED_UNSUCCESSFUL
+ ld [wEffectFailed], a
+ ret
+
+Func_2c0a8: ; 2c0a8 (b:40a8)
+ ldh a, [hTemp_ffa0]
+ push af
+ ldh a, [hWhoseTurn]
+ ldh [hTemp_ffa0], a
+ ld a, OPPACTION_6B30
+ call SetOppAction_SerialSendDuelData
+ bank1call Func_4f2d
+ ld c, a
+ pop af
+ ldh [hTemp_ffa0], a
+ ld a, c
+ ret
+
+Func_2c0bd: ; 2c0bd (b:40bd)
+ call ExchangeRNG
+ bank1call Func_4f2d
+ call ShuffleDeck
+ ret
+
+; return carry if Player is the Turn Duelist
+IsPlayerTurn: ; 2c0c7 (b:40c7)
+ ld a, DUELVARS_DUELIST_TYPE
+ call GetTurnDuelistVariable
+ cp DUELIST_TYPE_PLAYER
+ jr z, .player
+ or a
+ ret
+.player
+ scf
+ ret
+
+; Stores information about the attack damage for AI purposes
+; taking into account poison damage between turns.
+; if target poisoned
+; [wAIMinDamage] <- [wDamage]
+; [wAIMaxDamage] <- [wDamage]
+; else
+; [wAIMinDamage] <- [wDamage] + d
+; [wAIMaxDamage] <- [wDamage] + e
+; [wDamage] <- [wDamage] + a
+UpdateExpectedAIDamage_AccountForPoison: ; 2c0d4 (b:40d4)
+ push af
+ ld a, DUELVARS_ARENA_CARD_STATUS
+ call GetNonTurnDuelistVariable
+ and POISONED | DOUBLE_POISONED
+ jr z, UpdateExpectedAIDamage.skip_push_af
+ pop af
+ ld a, [wDamage]
+ ld [wAIMinDamage], a
+ ld [wAIMaxDamage], a
+ ret
+
+; Sets some variables for AI use
+; [wAIMinDamage] <- [wDamage] + d
+; [wAIMaxDamage] <- [wDamage] + e
+; [wDamage] <- [wDamage] + a
+UpdateExpectedAIDamage: ; 2c0e9 (b:40e9)
+ push af
+
+.skip_push_af
+ ld hl, wDamage
+ ld a, [hl]
+ add d
+ ld [wAIMinDamage], a
+ ld a, [hl]
+ add e
+ ld [wAIMaxDamage], a
+ pop af
+ add [hl]
+ ld [hl], a
+ ret
+
+; Stores information about the attack damage for AI purposes
+; [wDamage] <- a (average amount of damage)
+; [wAIMinDamage] <- d (minimum)
+; [wAIMaxDamage] <- e (maximum)
+SetExpectedAIDamage: ; 2c0fb (b:40fb)
+ ld [wDamage], a
+ xor a
+ ld [wDamage + 1], a
+ ld a, d
+ ld [wAIMinDamage], a
+ ld a, e
+ ld [wAIMaxDamage], a
+ ret
+
+Func_2c10b: ; 2c10b (b:410b)
+ ldh [hTempPlayAreaLocation_ff9d], a
+ bank1call Func_61a1
+ bank1call PrintPlayAreaCardList_EnableLCD
+ bank1call Func_6194
+ ret
+
+; deal damage to all the turn holder's benched Pokemon
+; input: a = amount of damage to deal to each Pokemon
+DealDamageToAllBenchedPokemon: ; 2c117 (b:4117)
+ ld e, a
+ ld d, $00
+ ld a, DUELVARS_NUMBER_OF_POKEMON_IN_PLAY_AREA
+ call GetTurnDuelistVariable
+ ld c, a
+ ld b, PLAY_AREA_ARENA
+ jr .skip_to_bench
+.loop
+ push bc
+ call DealDamageToPlayAreaPokemon_RegularAnim
+ pop bc
+.skip_to_bench
+ inc b
+ dec c
+ jr nz, .loop
+ ret
+
+Func_2c12e: ; 2c12e (b:412e)
+ ld [wLoadedAttackAnimation], a
+ ldh a, [hTempPlayAreaLocation_ff9d]
+ ld b, a
+ ld c, $0 ; neither WEAKNESS nor RESISTANCE
+ ldh a, [hWhoseTurn]
+ ld h, a
+ bank1call PlayAttackAnimation
+ bank1call WaitAttackAnimation
+ ret
+
+; apply a status condition of type 1 identified by register a to the target
+ApplySubstatus1ToDefendingCard: ; 2c140 (b:4140)
+ push af
+ ld a, DUELVARS_ARENA_CARD_SUBSTATUS1
+ call GetTurnDuelistVariable
+ pop af
+ ld [hli], a
+ ret
+
+; apply a status condition of type 2 identified by register a to the target,
+; unless prevented by wNoDamageOrEffect
+ApplySubstatus2ToDefendingCard: ; 2c149 (b:4149)
+ push af
+ call CheckNoDamageOrEffect
+ jr c, .no_damage_orEffect
+ ld a, DUELVARS_ARENA_CARD_SUBSTATUS2
+ call GetNonTurnDuelistVariable
+ pop af
+ ld [hl], a
+ ld l, $f6
+ ld [hl], a
+ ret
+
+.no_damage_orEffect
+ pop af
+ push hl
+ bank1call DrawDuelMainScene
+ pop hl
+ ld a, l
+ or h
+ call nz, DrawWideTextBox_PrintText
+ ret
+
+; overwrites in wDamage, wAIMinDamage and wAIMaxDamage
+; with the value in a.
+SetDefiniteDamage: ; 2c166 (b:4166)
+ ld [wDamage], a
+ ld [wAIMinDamage], a
+ ld [wAIMaxDamage], a
+ xor a
+ ld [wDamage + 1], a
+ ret
+
+; overwrites wAIMinDamage and wAIMaxDamage
+; with value in wDamage.
+SetDefiniteAIDamage: ; 2c174 (b:4174)
+ ld a, [wDamage]
+ ld [wAIMinDamage], a
+ ld [wAIMaxDamage], a
+ ret
+
+; returns in a some random occupied Play Area location
+; in Turn Duelist's Play Area.
+PickRandomPlayAreaCard: ; 2c17e (b:417e)
+ ld a, DUELVARS_NUMBER_OF_POKEMON_IN_PLAY_AREA
+ call GetTurnDuelistVariable
+ call Random
+ or a
+ ret
+
+; outputs in hl the next position
+; in hTempList to place a new card,
+; and increments hCurSelectionItem.
+GetNextPositionInTempList: ; 2c188 (b:4188)
+ push de
+ ld hl, hCurSelectionItem
+ ld a, [hl]
+ inc [hl]
+ ld e, a
+ ld d, $00
+ ld hl, hTempList
+ add hl, de
+ pop de
+ ret
+
+; creates in wDuelTempList list of attached Fire Energy cards
+; that are attached to the Turn Duelist's Arena card.
+CreateListOfFireEnergyAttachedToArena: ; 2c197 (b:4197)
+ ld a, TYPE_ENERGY_FIRE
+ ; fallthrough
+
+; creates in wDuelTempList a list of cards that
+; are in the Arena of the same type as input a.
+; this is called to list Energy cards of a specific type
+; that are attached to the Arena Pokemon.
+; input:
+; a = TYPE_ENERGY_* constant
+; output:
+; a = number of cards in list;
+; wDuelTempList filled with cards, terminated by $ff
+CreateListOfEnergyAttachedToArena: ; 2c199 (b:4199)
+ ld b, a
+ ld c, 0
+ ld de, wDuelTempList
+ ld a, DUELVARS_CARD_LOCATIONS
+ call GetTurnDuelistVariable
+.loop
+ ld a, [hl]
+ cp CARD_LOCATION_ARENA
+ jr nz, .next
+ push de
+ ld a, l
+ call GetCardIDFromDeckIndex
+ call GetCardType
+ pop de
+ cp b
+ jr nz, .next ; is same as input type?
+ ld a, l
+ ld [de], a
+ inc de
+ inc c
+.next
+ inc l
+ ld a, l
+ cp DECK_SIZE
+ jr c, .loop
+
+ ld a, $ff
+ ld [de], a
+ ld a, c
+ ret
+
+; prints the text "<X> devolved to <Y>!" with
+; the proper card names and levels.
+; input:
+; d = deck index of the lower stage card
+; e = deck index of card that was devolved
+PrintDevolvedCardNameAndLevelText: ; 2c1c4 (b:41c4)
+ push de
+ ld a, e
+ call LoadCardDataToBuffer1_FromDeckIndex
+ ld bc, wTxRam2
+ ld hl, wLoadedCard1Name
+ ld a, [hli]
+ ld [bc], a
+ inc bc
+ ld a, [hl]
+ ld [bc], a
+
+ inc bc ; wTxRam2_b
+ xor a
+ ld [bc], a
+ inc bc
+ ld [bc], a
+
+ ld a, d
+ call LoadCardDataToBuffer1_FromDeckIndex
+ ld a, 18
+ call CopyCardNameAndLevel
+ ld [hl], $00
+ ldtx hl, PokemonDevolvedToText
+ call DrawWideTextBox_WaitForInput
+ pop de
+ ret
+
+HandleSwitchDefendingPokemonEffect: ; 2c1ec (b:41ec)
+ ld e, a
+ cp $ff
+ ret z
+
+; check Defending Pokemon's HP
+ ld a, DUELVARS_ARENA_CARD_HP
+ call GetNonTurnDuelistVariable
+ or a
+ jr nz, .switch
+
+; if 0, handle Destiny Bond first
+ push de
+ bank1call HandleDestinyBondSubstatus
+ pop de
+
+.switch
+ call HandleNoDamageOrEffect
+ ret c
+
+; attack was successful, switch Defending Pokemon
+ call SwapTurn
+ call SwapArenaWithBenchPokemon
+ call SwapTurn
+
+ xor a
+ ld [wccc5], a
+ ld [wDuelDisplayedScreen], a
+ inc a
+ ld [wccef], a
+ ret
+
+; returns carry if Defending has No Damage or Effect
+; if so, print its appropriate text.
+HandleNoDamageOrEffect: ; 2c216 (b:4216)
+ call CheckNoDamageOrEffect
+ ret nc
+ ld a, l
+ or h
+ call nz, DrawWideTextBox_PrintText
+ scf
+ ret
+
+; applies HP recovery on Pokemon after an attack
+; with HP recovery effect, and handles its animation.
+; input:
+; d = damage effectiveness
+; e = HP amount to recover
+ApplyAndAnimateHPRecovery: ; 2c221 (b:4221)
+ push de
+ ld hl, wccbd
+ ld [hl], e
+ inc hl
+ ld [hl], d
+
+; get Arena card's damage
+ ld e, PLAY_AREA_ARENA
+ call GetCardDamageAndMaxHP
+ pop de
+ or a
+ ret z ; return if no damage
+
+; load correct animation
+ push de
+ ld a, ATK_ANIM_HEAL
+ ld [wLoadedAttackAnimation], a
+ ld bc, $01 ; arrow
+ bank1call PlayAttackAnimation
+
+; compare HP to be restored with max HP
+; if HP to be restored would cause HP to
+; be larger than max HP, cap it accordingly
+ ld e, PLAY_AREA_ARENA
+ call GetCardDamageAndMaxHP
+ ld b, $00
+ pop de
+ ld a, DUELVARS_ARENA_CARD_HP
+ call GetTurnDuelistVariable
+ add e
+ ld e, a
+ ld a, 0
+ adc d
+ ld d, a
+ ; de = damage dealt + current HP
+ ; bc = max HP of card
+ call CompareDEtoBC
+ jr c, .skip_cap
+ ; cap de to value in bc
+ ld e, c
+ ld d, b
+
+.skip_cap
+ ld [hl], e ; apply new HP to arena card
+ bank1call WaitAttackAnimation
+ ret
+
+; returns carry if Play Area has no damage counters.
+CheckIfPlayAreaHasAnyDamage: ; 2c25b (b:425b)
+ ld a, DUELVARS_NUMBER_OF_POKEMON_IN_PLAY_AREA
+ call GetTurnDuelistVariable
+ ld d, a
+ ld e, PLAY_AREA_ARENA
+.loop_play_area
+ call GetCardDamageAndMaxHP
+ or a
+ ret nz ; found damage
+ inc e
+ dec d
+ jr nz, .loop_play_area
+ ; no damage found
+ scf
+ ret
+
+; makes a list in wDuelTempList with the deck indices
+; of Trainer cards found in Turn Duelist's Discard Pile.
+; returns carry set if no Trainer cards found, and loads
+; corresponding text to notify this.
+CreateTrainerCardListFromDiscardPile: ; 2c26e (b:426e)
+; get number of cards in Discard Pile
+; and have hl point to the end of the
+; Discard Pile list in wOpponentDeckCards.
+ ld a, DUELVARS_NUMBER_OF_CARDS_IN_DISCARD_PILE
+ call GetTurnDuelistVariable
+ ld b, a
+ add DUELVARS_DECK_CARDS
+ ld l, a
+
+ ld de, wDuelTempList
+ inc b
+ jr .next_card
+
+.check_trainer
+ ld a, [hl]
+ call LoadCardDataToBuffer2_FromDeckIndex
+ ld a, [wLoadedCard2Type]
+ cp TYPE_TRAINER
+ jr nz, .next_card
+
+ ld a, [hl]
+ ld [de], a
+ inc de
+
+.next_card
+ dec l
+ dec b
+ jr nz, .check_trainer
+
+ ld a, $ff ; terminating byte
+ ld [de], a
+ ld a, [wDuelTempList]
+ cp $ff
+ jr z, .no_trainers
+ or a
+ ret
+.no_trainers
+ ldtx hl, ThereAreNoTrainerCardsInDiscardPileText
+ scf
+ ret
+
+; makes a list in wDuelTempList with the deck indices
+; of all basic energy cards found in Turn Duelist's Discard Pile.
+CreateEnergyCardListFromDiscardPile_OnlyBasic: ; 2c2a0 (b:42a0)
+ ld c, $01
+ jr CreateEnergyCardListFromDiscardPile
+
+; makes a list in wDuelTempList with the deck indices
+; of all energy cards (including Double Colorless)
+; found in Turn Duelist's Discard Pile.
+CreateEnergyCardListFromDiscardPile_AllEnergy: ; 2c2a4 (b:42a4)
+ ld c, $00
+; fallthrough
+
+; makes a list in wDuelTempList with the deck indices
+; of energy cards found in Turn Duelist's Discard Pile.
+; if (c == 0), all energy cards are allowed;
+; if (c != 0), double colorless energy cards are not included.
+; returns carry if no energy cards were found.
+CreateEnergyCardListFromDiscardPile: ; 2c2a6 (b:42a6)
+; get number of cards in Discard Pile
+; and have hl point to the end of the
+; Discard Pile list in wOpponentDeckCards.
+ ld a, DUELVARS_NUMBER_OF_CARDS_IN_DISCARD_PILE
+ call GetTurnDuelistVariable
+ ld b, a
+ add DUELVARS_DECK_CARDS
+ ld l, a
+
+ ld de, wDuelTempList
+ inc b
+ jr .next_card
+
+.check_energy
+ ld a, [hl]
+ call LoadCardDataToBuffer2_FromDeckIndex
+ ld a, [wLoadedCard2Type]
+ and TYPE_ENERGY
+ jr z, .next_card
+
+; if (c != $00), then we dismiss Double Colorless
+; energy cards found.
+ ld a, c
+ or a
+ jr z, .copy
+ ld a, [wLoadedCard2Type]
+ cp TYPE_ENERGY_DOUBLE_COLORLESS
+ jr nc, .next_card
+
+.copy
+ ld a, [hl]
+ ld [de], a
+ inc de
+
+; goes through Discard Pile list
+; in wOpponentDeckCards in descending order.
+.next_card
+ dec l
+ dec b
+ jr nz, .check_energy
+
+; terminating byte on wDuelTempList
+ ld a, $ff
+ ld [de], a
+
+; check if any energy card was found
+; by checking whether the first byte
+; in wDuelTempList is $ff.
+; if none were found, return carry.
+ ld a, [wDuelTempList]
+ cp $ff
+ jr z, .set_carry
+ or a
+ ret
+
+.set_carry
+ scf
+ ret
+
+; returns carry if Deck is empty
+CheckIfDeckIsEmpty: ; 2c2e0 (b:42e0)
+ ld a, DUELVARS_NUMBER_OF_CARDS_NOT_IN_DECK
+ call GetTurnDuelistVariable
+ ldtx hl, NoCardsLeftInTheDeckText
+ cp DECK_SIZE
+ ccf
+ ret
+
+; searches through Deck in wDuelTempList looking for
+; a certain card or cards, and prints text depending
+; on whether at least one was found.
+; if none were found, asks the Player whether to look
+; in the Deck anyway, and returns carry if No is selected.
+; uses SEARCHEFFECT_* as input which determines what to search for:
+; SEARCHEFFECT_CARD_ID = search for card ID in e
+; SEARCHEFFECT_NIDORAN = search for either NidoranM or NidoranF
+; SEARCHEFFECT_BASIC_FIGHTING = search for any Basic Fighting Pokemon
+; SEARCHEFFECT_BASIC_ENERGY = search for any Basic Energy
+; SEARCHEFFECT_POKEMON = search for any Pokemon card
+; input:
+; d = SEARCHEFFECT_* constant
+; e = (optional) card ID to search for in deck
+; hl = text to print if Deck has card(s)
+; output:
+; carry set if refused to look at deck
+LookForCardsInDeck: ; 2c2ec (b:42ec)
+ push hl
+ push bc
+ ld a, [wDuelTempList]
+ cp $ff
+ jr z, .none_in_deck
+ ld a, d
+ ld hl, .search_table
+ call JumpToFunctionInTable
+ jr c, .none_in_deck
+ pop bc
+ pop hl
+ call DrawWideTextBox_WaitForInput
+ or a
+ ret
+
+.none_in_deck
+ pop hl
+ call LoadTxRam2
+ pop hl
+ ldtx hl, ThereIsNoInTheDeckText
+ call DrawWideTextBox_WaitForInput
+ ldtx hl, WouldYouLikeToCheckTheDeckText
+ call YesOrNoMenuWithText_SetCursorToYes
+ ret
+
+.search_table
+ dw .SearchDeckForCardID
+ dw .SearchDeckForNidoran
+ dw .SearchDeckForBasicFighting
+ dw .SearchDeckForBasicEnergy
+ dw .SearchDeckForPokemon
+
+.set_carry ; 2c321 (b:4321)
+ scf
+ ret
+
+; returns carry if no card with
+; same card ID as e is found in Deck
+.SearchDeckForCardID ; 2c323 (b:4323)
+ ld hl, wDuelTempList
+.loop_deck_e
+ ld a, [hli]
+ cp $ff
+ jr z, .set_carry
+ push de
+ call GetCardIDFromDeckIndex
+ ld a, e
+ pop de
+ cp e
+ jr nz, .loop_deck_e
+ or a
+ ret
+
+; returns carry if no NidoranM or NidoranF card is found in Deck
+.SearchDeckForNidoran ; 2c336 (b:4336)
+ ld hl, wDuelTempList
+.loop_deck_nidoran
+ ld a, [hli]
+ cp $ff
+ jr z, .set_carry
+ call GetCardIDFromDeckIndex
+ ld a, e
+ cp NIDORANF
+ jr z, .found_nidoran
+ cp NIDORANM
+ jr nz, .loop_deck_nidoran
+.found_nidoran
+ or a
+ ret
+
+; returns carry if no Basic Fighting Pokemon is found in Deck
+.SearchDeckForBasicFighting ; 2c34c (b:434c)
+ ld hl, wDuelTempList
+.loop_deck_fighting
+ ld a, [hli]
+ cp $ff
+ jr z, .set_carry
+ call LoadCardDataToBuffer2_FromDeckIndex
+ ld a, [wLoadedCard2Type]
+ cp TYPE_PKMN_FIGHTING
+ jr nz, .loop_deck_fighting
+ ld a, [wLoadedCard2Stage]
+ or a ; BASIC
+ jr nz, .loop_deck_fighting
+ ret
+
+; returns carry if no Basic Energy cards are found in Deck
+.SearchDeckForBasicEnergy ; 2c365 (b:4365)
+ ld hl, wDuelTempList
+.loop_deck_energy
+ ld a, [hli]
+ cp $ff
+ jr z, .set_carry
+ call GetCardIDFromDeckIndex
+ call GetCardType
+ cp TYPE_ENERGY_DOUBLE_COLORLESS
+ jr z, .loop_deck_energy
+ and TYPE_ENERGY
+ jr z, .loop_deck_energy
+ or a
+ ret
+
+; returns carry if no Pokemon cards are found in Deck
+.SearchDeckForPokemon ; 2c37d (b:437d)
+ ld hl, wDuelTempList
+.loop_deck_pkmn
+ ld a, [hli]
+ cp $ff
+ jr z, .set_carry
+ call GetCardIDFromDeckIndex
+ call GetCardType
+ cp TYPE_ENERGY
+ jr nc, .loop_deck_pkmn
+ or a
+ ret
+
+; handles the Player selection of attack
+; to use, i.e. Amnesia or Metronome on.
+; returns carry if none selected.
+; outputs:
+; d = card index of defending card
+; e = attack index selected
+HandleDefendingPokemonAttackSelection: ; 2c391 (b:4391)
+ bank1call DrawDuelMainScene
+ call SwapTurn
+ xor a
+ ldh [hCurSelectionItem], a
+
+.start
+ bank1call PrintAndLoadAttacksToDuelTempList
+ push af
+ ldh a, [hCurSelectionItem]
+ ld hl, .menu_parameters
+ call InitializeMenuParameters
+ pop af
+
+ ld [wNumMenuItems], a
+ call EnableLCD
+.loop_input
+ call DoFrame
+ ldh a, [hKeysPressed]
+ bit B_BUTTON_F, a
+ jr nz, .set_carry
+ and START
+ jr nz, .open_atk_page
+ call HandleMenuInput
+ jr nc, .loop_input
+ cp -1
+ jr z, .loop_input
+
+; an attack was selected
+ ldh a, [hCurMenuItem]
+ add a
+ ld e, a
+ ld d, $00
+ ld hl, wDuelTempList
+ add hl, de
+ ld d, [hl]
+ inc hl
+ ld e, [hl]
+ call SwapTurn
+ or a
+ ret
+
+.set_carry
+ call SwapTurn
+ scf
+ ret
+
+.open_atk_page
+ ldh a, [hCurMenuItem]
+ ldh [hCurSelectionItem], a
+ ld a, DUELVARS_ARENA_CARD
+ call GetTurnDuelistVariable
+ call LoadCardDataToBuffer1_FromDeckIndex
+ bank1call OpenAttackPage
+ call SwapTurn
+ bank1call DrawDuelMainScene
+ call SwapTurn
+ jr .start
+
+.menu_parameters
+ db 1, 13 ; cursor x, cursor y
+ db 2 ; y displacement between items
+ db 2 ; number of items
+ db SYM_CURSOR_R ; cursor tile number
+ db SYM_SPACE ; tile behind cursor
+ dw NULL ; function pointer if non-0
+
+; loads in hl the pointer to attack's name.
+; input:
+; d = deck index of card
+; e = attack index (0 = first attack, 1 = second attack)
+GetAttackName: ; 2c3fc (b:43fc)
+ ld a, d
+ call LoadCardDataToBuffer1_FromDeckIndex
+ ld hl, wLoadedCard1Atk1Name
+ inc e
+ dec e
+ jr z, .load_name
+ ld hl, wLoadedCard1Atk2Name
+.load_name
+ ld a, [hli]
+ ld h, [hl]
+ ld l, a
+ ret
+
+; returns carry if Defending Pokemon
+; doesn't have an attack.
+CheckIfDefendingPokemonHasAnyAttack: ; 2c40e (b:440e)
+ call SwapTurn
+ ld a, DUELVARS_ARENA_CARD
+ call GetTurnDuelistVariable
+ call LoadCardDataToBuffer2_FromDeckIndex
+ ld a, [wLoadedCard2Atk1Category]
+ cp POKEMON_POWER
+ jr nz, .has_attack
+ ld hl, wLoadedCard2Atk2Name
+ ld a, [hli]
+ or [hl]
+ jr nz, .has_attack
+ call SwapTurn
+ scf
+ ret
+.has_attack
+ call SwapTurn
+ or a
+ ret
+
+; overwrites HP and Stage data of the card that was
+; devolved in the Play Area to the values of new card.
+; if the damage exceeds HP of pre-evolution,
+; then HP is set to zero.
+; input:
+; a = card index of pre-evolved card
+UpdateDevolvedCardHPAndStage: ; 2c431 (b:4431)
+ push bc
+ push de
+ push af
+ ldh a, [hTempPlayAreaLocation_ff9d]
+ ld e, a
+ call GetCardDamageAndMaxHP
+ ld b, a ; store damage
+ ld a, e
+ add DUELVARS_ARENA_CARD
+ call GetTurnDuelistVariable
+ pop af
+
+ ld [hl], a
+ call LoadCardDataToBuffer2_FromDeckIndex
+ ld a, e
+ add DUELVARS_ARENA_CARD_HP
+ ld l, a
+ ld a, [wLoadedCard2HP]
+ sub b ; subtract damage from new HP
+ jr nc, .got_hp
+ ; damage exceeds HP
+ xor a ; 0 HP
+.got_hp
+ ld [hl], a
+ ld a, e
+; overwrite card stage
+ add DUELVARS_ARENA_CARD_STAGE
+ ld l, a
+ ld a, [wLoadedCard2Stage]
+ ld [hl], a
+ pop de
+ pop bc
+ ret
+
+; reset various status after devolving card.
+ResetDevolvedCardStatus: ; 2c45d (b:445d)
+; if it's Arena card, clear status conditions
+ ldh a, [hTempPlayAreaLocation_ff9d]
+ or a
+ jr nz, .skip_clear_status
+ call ClearAllStatusConditions
+.skip_clear_status
+; reset changed color status
+ ldh a, [hTempPlayAreaLocation_ff9d]
+ add DUELVARS_ARENA_CARD_CHANGED_TYPE
+ call GetTurnDuelistVariable
+ ld [hl], $00
+; reset C2 flags
+ ldh a, [hTempPlayAreaLocation_ff9d]
+ add DUELVARS_ARENA_CARD_FLAGS
+ ld l, a
+ ld [hl], $00
+ ret
+
+; prompts the Player with a Yes/No question
+; whether to quit the screen, even though
+; they can select more cards from list.
+; [hCurSelectionItem] holds number of cards
+; that were already selected by the Player.
+; input:
+; - a = total number of cards that can be selected
+; output:
+; - carry set if "No" was selected
+AskWhetherToQuitSelectingCards: ; 2c476 (b:4476)
+ ld hl, hCurSelectionItem
+ sub [hl]
+ ld l, a
+ ld h, $00
+ call LoadTxRam3
+ ldtx hl, YouCanSelectMoreCardsQuitText
+ call YesOrNoMenuWithText
+ ret
+
+; handles the selection of a forced switch by link/AI opponent or by the player.
+; outputs the Play Area location of the chosen bench card in hTempPlayAreaLocation_ff9d.
+DuelistSelectForcedSwitch: ; 2c487 (b:4487)
+ ld a, DUELVARS_DUELIST_TYPE
+ call GetNonTurnDuelistVariable
+ cp DUELIST_TYPE_LINK_OPP
+ jr z, .link_opp
+
+ cp DUELIST_TYPE_PLAYER
+ jr z, .player
+
+; AI opponent
+ call SwapTurn
+ bank1call AIDoAction_ForcedSwitch
+ call SwapTurn
+
+ ld a, [wPlayerAttackingAttackIndex]
+ ld e, a
+ ld a, [wPlayerAttackingCardIndex]
+ ld d, a
+ ld a, [wPlayerAttackingCardID]
+ call CopyAttackDataAndDamage_FromCardID
+ call Func_16f6
+ ret
+
+.player
+ ldtx hl, SelectPkmnOnBenchToSwitchWithActiveText
+ call DrawWideTextBox_WaitForInput
+ call SwapTurn
+ bank1call HasAlivePokemonInBench
+ ld a, $01
+ ld [wcbd4], a
+.asm_2c4c0
+ bank1call OpenPlayAreaScreenForSelection
+ jr c, .asm_2c4c0
+ call SwapTurn
+ ret
+
+.link_opp
+; get selection from link opponent
+ ld a, OPPACTION_FORCE_SWITCH_ACTIVE
+ call SetOppAction_SerialSendDuelData
+.loop
+ call SerialRecvByte
+ jr nc, .received
+ halt
+ nop
+ jr .loop
+.received
+ ldh [hTempPlayAreaLocation_ff9d], a
+ ret
+
+; returns in a the card index of energy card
+; attached to Defending Pokemon
+; that is to be discarded by the AI for an effect.
+; outputs $ff is none was found.
+; output:
+; a = deck index of attached energy card chosen
+AIPickEnergyCardToDiscardFromDefendingPokemon: ; 2c4da (b:44da)
+ call SwapTurn
+ ld e, PLAY_AREA_ARENA
+ call GetPlayAreaCardAttachedEnergies
+
+ xor a
+ call CreateArenaOrBenchEnergyCardList
+ jr nc, .has_energy
+ ; no energy, return
+ ld a, $ff
+ jr .done
+
+.has_energy
+ ld a, DUELVARS_ARENA_CARD
+ call GetTurnDuelistVariable
+ call LoadCardDataToBuffer1_FromDeckIndex
+ ld e, COLORLESS
+ ld a, [wAttachedEnergies + COLORLESS]
+ or a
+ jr nz, .pick_color ; has colorless attached?
+
+ ; no colorless energy attached.
+ ; if it's colorless Pokemon, just
+ ; pick any energy card at random...
+ ld a, [wLoadedCard1Type]
+ cp COLORLESS
+ jr nc, .choose_random
+
+ ; ...if not, check if it has its
+ ; own color energy attached.
+ ; if it doesn't, pick at random.
+ ld e, a
+ ld d, $00
+ ld hl, wAttachedEnergies
+ add hl, de
+ ld a, [hl]
+ or a
+ jr z, .choose_random
+
+; pick attached card with same color as e
+.pick_color
+ ld hl, wDuelTempList
+.loop_energy
+ ld a, [hli]
+ cp $ff
+ jr z, .choose_random
+ call LoadCardDataToBuffer2_FromDeckIndex
+ ld a, [wLoadedCard2Type]
+ and TYPE_PKMN
+ cp e
+ jr nz, .loop_energy
+ dec hl
+
+.done_chosen
+ ld a, [hl]
+.done
+ call SwapTurn
+ ret
+
+.choose_random
+ call CountCardsInDuelTempList
+ ld hl, wDuelTempList
+ call ShuffleCards
+ jr .done_chosen
+
+; handles AI logic to pick attack for Amnesia
+AIPickAttackForAmnesia: ; 2c532 (b:4532)
+; load Defending Pokemon attacks
+ call SwapTurn
+ ld e, PLAY_AREA_ARENA
+ call GetPlayAreaCardAttachedEnergies
+ call HandleEnergyBurn
+ ld a, DUELVARS_ARENA_CARD
+ call GetTurnDuelistVariable
+ ld d, a
+ call LoadCardDataToBuffer2_FromDeckIndex
+; if has no attack 1 name, return
+ ld hl, wLoadedCard2Atk1Name
+ ld a, [hli]
+ or [hl]
+ jr z, .chosen
+
+; if Defending Pokemon has enough energy for second attack, choose it
+ ld e, SECOND_ATTACK
+ bank1call _CheckIfEnoughEnergiesToAttack
+ jr nc, .chosen
+; otherwise if first attack isn't a Pkmn Power, choose it instead.
+ ld e, FIRST_ATTACK_OR_PKMN_POWER
+ ld a, [wLoadedCard2Atk1Category]
+ cp POKEMON_POWER
+ jr nz, .chosen
+; if it is a Pkmn Power, choose second attack.
+ ld e, SECOND_ATTACK
+.chosen
+ ld a, e
+ call SwapTurn
+ ret
+
+; Return in a the PLAY_AREA_* of the non-turn holder's Pokemon card in bench with the lowest (remaining) HP.
+; if multiple cards are tied for the lowest HP, the one with the highest PLAY_AREA_* is returned.
+GetBenchPokemonWithLowestHP: ; 2c564 (b:4564)
+ call SwapTurn
+ ld a, DUELVARS_NUMBER_OF_POKEMON_IN_PLAY_AREA
+ call GetTurnDuelistVariable
+ ld c, a
+ lb de, PLAY_AREA_ARENA, $ff
+ ld b, d
+ ld a, DUELVARS_BENCH1_CARD_HP
+ call GetTurnDuelistVariable
+ jr .start
+; find Play Area location with least amount of HP
+.loop_bench
+ ld a, e
+ cp [hl]
+ jr c, .next ; skip if HP is higher
+ ld e, [hl]
+ ld d, b
+
+.next
+ inc hl
+.start
+ inc b
+ dec c
+ jr nz, .loop_bench
+
+ ld a, d
+ call SwapTurn
+ ret
+
+; handles drawing and selection of screen for
+; choosing a color (excluding colorless), for use
+; of Shift Pkmn Power and Conversion attacks.
+; outputs in a the color that was selected or,
+; if B was pressed, returns carry.
+; input:
+; a = Play Area location (PLAY_AREA_*), with:
+; bit 7 not set if it's applying to opponent's card
+; bit 7 set if it's applying to player's card
+; hl = text to be printed in the bottom box
+; output:
+; a = color that was selected
+HandleColorChangeScreen: ; 2c588 (b:4588)
+ or a
+ call z, SwapTurn
+ push af
+ call .DrawScreen
+ pop af
+ call z, SwapTurn
+
+ ld hl, .menu_params
+ xor a
+ call InitializeMenuParameters
+ call EnableLCD
+
+.loop_input
+ call DoFrame
+ call HandleMenuInput
+ jr nc, .loop_input
+ cp -1 ; b pressed?
+ jr z, .set_carry
+ ld e, a
+ ld d, $00
+ ld hl, ShiftListItemToColor
+ add hl, de
+ ld a, [hl]
+ or a
+ ret
+.set_carry
+ scf
+ ret
+
+.menu_params
+ db 1, 1 ; cursor x, cursor y
+ db 2 ; y displacement between items
+ db MAX_PLAY_AREA_POKEMON ; number of items
+ db SYM_CURSOR_R ; cursor tile number
+ db SYM_SPACE ; tile behind cursor
+ dw NULL ; function pointer if non-0
+
+.DrawScreen: ; 2c5be (b:45be)
+ push hl
+ push af
+ call EmptyScreen
+ call ZeroObjectPositions
+ call LoadDuelCardSymbolTiles
+
+; load card data
+ pop af
+ and $7f
+ ld [wTempPlayAreaLocation_cceb], a
+ add DUELVARS_ARENA_CARD
+ call GetTurnDuelistVariable
+ call LoadCardDataToBuffer1_FromDeckIndex
+
+; draw card gfx
+ ld de, v0Tiles1 + $20 tiles ; destination offset of loaded gfx
+ ld hl, wLoadedCard1Gfx
+ ld a, [hli]
+ ld h, [hl]
+ ld l, a
+ lb bc, $30, TILE_SIZE
+ call LoadCardGfx
+ bank1call SetBGP6OrSGB3ToCardPalette
+ bank1call FlushAllPalettesOrSendPal23Packet
+ ld a, $a0
+ lb hl, 6, 1
+ lb de, 9, 2
+ lb bc, 8, 6
+ call FillRectangle
+ bank1call ApplyBGP6OrSGB3ToCardImage
+
+; print card name and level at the top
+ ld a, 16
+ call CopyCardNameAndLevel
+ ld [hl], $00
+ lb de, 7, 0
+ call InitTextPrinting
+ ld hl, wDefaultText
+ call ProcessText
+
+; list all the colors
+ ld hl, ShiftMenuData
+ call PlaceTextItems
+
+; print card's color, resistance and weakness
+ ld a, [wTempPlayAreaLocation_cceb]
+ call GetPlayAreaCardColor
+ inc a
+ lb bc, 15, 9
+ call WriteByteToBGMap0
+ ld a, [wTempPlayAreaLocation_cceb]
+ call GetPlayAreaCardWeakness
+ lb bc, 15, 10
+ bank1call PrintCardPageWeaknessesOrResistances
+ ld a, [wTempPlayAreaLocation_cceb]
+ call GetPlayAreaCardResistance
+ lb bc, 15, 11
+ bank1call PrintCardPageWeaknessesOrResistances
+
+ call DrawWideTextBox
+
+; print list of color names on all list items
+ lb de, 4, 1
+ ldtx hl, ColorListText
+ call InitTextPrinting_ProcessTextFromID
+
+; print input hl to text box
+ lb de, 1, 14
+ pop hl
+ call InitTextPrinting_ProcessTextFromID
+
+; draw and apply palette to color icons
+ ld hl, ColorTileAndBGP
+ lb de, 2, 0
+ ld c, NUM_COLORED_TYPES
+.loop_colors
+ ld a, [hli]
+ push de
+ push bc
+ push hl
+ lb hl, 1, 2
+ lb bc, 2, 2
+ call FillRectangle
+
+ ld a, [wConsole]
+ cp CONSOLE_CGB
+ jr nz, .skip_vram1
+ pop hl
+ push hl
+ call BankswitchVRAM1
+ ld a, [hl]
+ lb hl, 0, 0
+ lb bc, 2, 2
+ call FillRectangle
+ call BankswitchVRAM0
+
+.skip_vram1
+ pop hl
+ pop bc
+ pop de
+ inc hl
+ inc e
+ inc e
+ dec c
+ jr nz, .loop_colors
+ ret
+
+; loads wTxRam2 and wTxRam2_b:
+; [wTxRam2] <- wLoadedCard1Name
+; [wTxRam2_b] <- input color as text symbol
+; input:
+; a = type (color) constant
+LoadCardNameAndInputColor: ; 2c686 (b:4686)
+ add a
+ ld e, a
+ ld d, $00
+ ld hl, ColorToTextSymbol
+ add hl, de
+
+; load wTxRam2 with card's name
+ ld de, wTxRam2
+ ld a, [wLoadedCard1Name]
+ ld [de], a
+ inc de
+ ld a, [wLoadedCard1Name + 1]
+ ld [de], a
+
+; load wTxRam2_b with ColorToTextSymbol
+ inc de
+ ld a, [hli]
+ ld [de], a
+ inc de
+ ld a, [hli]
+ ld [de], a
+ ret
+
+ShiftMenuData: ; 2c6a1 (b:46a1)
+ ; x, y, text id
+ textitem 10, 9, TypeText
+ textitem 10, 10, WeaknessText
+ textitem 10, 11, ResistanceText
+ db $ff
+
+ColorTileAndBGP: ; 2c6ae (b:46ae)
+ ; tile, BG
+ db $e4, $02
+ db $e0, $01
+ db $eC, $02
+ db $e8, $01
+ db $f0, $03
+ db $f4, $03
+
+ShiftListItemToColor: ; 2c6ba (b:46ba)
+ db GRASS
+ db FIRE
+ db WATER
+ db LIGHTNING
+ db FIGHTING
+ db PSYCHIC
+
+ColorToTextSymbol: ; 2c6c0 (b:46c0)
+ tx FireSymbolText
+ tx GrassSymbolText
+ tx LightningSymbolText
+ tx WaterSymbolText
+ tx FightingSymbolText
+ tx PsychicSymbolText
+
+DrawSymbolOnPlayAreaCursor: ; 2c6cc (b:46cc)
+ ld c, a
+ add a
+ add c
+ add 2
+ ; a = 3*a + 2
+ ld c, a
+ ld a, b
+ ld b, 0
+ call WriteByteToBGMap0
+ ret
+
+; possibly unreferenced
+Func_2c6d9: ; 2c6d9 (b:46d9)
+ ldtx hl, IncompleteText
+ call DrawWideTextBox_WaitForInput
+ ret
+
+PlayAreaSelectionMenuParameters: ; 2c6e0 (b:46e0)
+ db 0, 0 ; cursor x, cursor y
+ db 3 ; y displacement between items
+ db MAX_PLAY_AREA_POKEMON ; number of items
+ db SYM_CURSOR_R ; cursor tile number
+ db SYM_SPACE ; tile behind cursor
+ dw NULL ; function pointer if non-0
+
+BenchSelectionMenuParameters: ; 2c6e8 (b:46e8)
+ db 0, 3 ; cursor x, cursor y
+ db 3 ; y displacement between items
+ db MAX_PLAY_AREA_POKEMON ; number of items
+ db SYM_CURSOR_R ; cursor tile number
+ db SYM_SPACE ; tile behind cursor
+ dw NULL ; function pointer if non-0
+
+SpitPoison_AIEffect: ; 2c6f0 (b:46f0)
+ ld a, 10 / 2
+ lb de, 0, 10
+ jp SetExpectedAIDamage
+
+; If heads, defending Pokemon becomes poisoned
+SpitPoison_Poison50PercentEffect: ; 2c6f8 (b:46f8)
+ ldtx de, PoisonCheckText
+ call TossCoin_BankB
+ jp c, PoisonEffect
+ ld a, ATK_ANIM_SPIT_POISON_SUCCESS
+ ld [wLoadedAttackAnimation], a
+ call SetNoEffectFromStatus
+ ret
+
+; outputs in hTemp_ffa0 the result of the coin toss (0 = tails, 1 = heads).
+; in case it was heads, stores in hTempPlayAreaLocation_ffa1
+; the PLAY_AREA_* location of the Bench Pokemon that was selected for switch.
+TerrorStrike_50PercentSelectSwitchPokemon: ; 2c70a (b:470a)
+ xor a
+ ldh [hTemp_ffa0], a
+
+; return failure if no Pokemon to switch to
+ ld a, DUELVARS_NUMBER_OF_POKEMON_IN_PLAY_AREA
+ call GetNonTurnDuelistVariable
+ cp 2
+ ret c
+
+; toss coin and store whether it was tails (0) or heads (1) in hTemp_ffa0.
+; return if it was tails.
+ ldtx de, IfHeadsChangeOpponentsActivePokemonText
+ call Func_2c08a
+ ldh [hTemp_ffa0], a
+ ret nc
+
+ call DuelistSelectForcedSwitch
+ ldh a, [hTempPlayAreaLocation_ff9d]
+ ldh [hTempPlayAreaLocation_ffa1], a
+ ret
+
+; if coin toss at hTemp_ffa0 was heads and it's possible,
+; switch the Defending Pokemon
+TerrorStrike_SwitchDefendingPokemon: ; 2c726 (b:4726)
+ ldh a, [hTemp_ffa0]
+ or a
+ ret z
+ ldh a, [hTempPlayAreaLocation_ffa1]
+ call HandleSwitchDefendingPokemonEffect
+ ret
+
+PoisonFang_AIEffect: ; 2c730 (b:4730)
+ ld a, 10
+ lb de, 10, 10
+ jp UpdateExpectedAIDamage_AccountForPoison
+
+WeepinbellPoisonPowder_AIEffect: ; 2c738 (b:4738)
+ ld a, 5
+ lb de, 0, 10
+ jp UpdateExpectedAIDamage_AccountForPoison
+
+; return carry if there are no Pokemon cards in the non-turn holder's bench
+VictreebelLure_AssertPokemonInBench: ; 2c740 (b:4740)
+ ld a, DUELVARS_NUMBER_OF_POKEMON_IN_PLAY_AREA
+ call GetNonTurnDuelistVariable
+ ldtx hl, EffectNoPokemonOnTheBenchText
+ cp 2
+ ret
+
+; return in hTempPlayAreaLocation_ffa1 the PLAY_AREA_* location
+; of the Bench Pokemon that was selected for switch
+VictreebelLure_SelectSwitchPokemon: ; 2c74b (b:474b)
+ ldtx hl, SelectPkmnOnBenchToSwitchWithActiveText
+ call DrawWideTextBox_WaitForInput
+ call SwapTurn
+ bank1call HasAlivePokemonInBench
+.select_pokemon
+ bank1call OpenPlayAreaScreenForSelection
+ jr c, .select_pokemon
+ ldh a, [hTempPlayAreaLocation_ff9d]
+ ldh [hTemp_ffa0], a
+ call SwapTurn
+ ret
+
+; Return in hTemp_ffa0 the PLAY_AREA_* of the non-turn holder's Pokemon card in bench with the lowest (remaining) HP.
+; if multiple cards are tied for the lowest HP, the one with the highest PLAY_AREA_* is returned.
+VictreebelLure_GetBenchPokemonWithLowestHP: ; 2c764 (b:4764)
+ call GetBenchPokemonWithLowestHP
+ ldh [hTemp_ffa0], a
+ ret
+
+; Defending Pokemon is swapped out for the one with the PLAY_AREA_* at hTemp_ffa0
+; unless Mew's Neutralizing Shield or Haunter's Transparency prevents it.
+VictreebelLure_SwitchDefendingPokemon: ; 2c76a (b:476a)
+ call SwapTurn
+ ldh a, [hTemp_ffa0]
+ ld e, a
+ call HandleNShieldAndTransparency
+ call nc, SwapArenaWithBenchPokemon
+ call SwapTurn
+ xor a
+ ld [wDuelDisplayedScreen], a
+ ret
+
+; If heads, defending Pokemon can't retreat next turn
+AcidEffect: ; 2c77e (b:477e)
+ ldtx de, AcidCheckText
+ call TossCoin_BankB
+ ret nc
+ ld a, SUBSTATUS2_UNABLE_RETREAT
+ call ApplySubstatus2ToDefendingCard
+ ret
+
+GloomPoisonPowder_AIEffect: ; 2c78b (b:478b)
+ ld a, 10
+ lb de, 10, 10
+ jp UpdateExpectedAIDamage_AccountForPoison
+
+; Defending Pokemon and user become confused
+FoulOdorEffect: ; 2c793 (b:4793)
+ call ConfusionEffect
+ call SwapTurn
+ call ConfusionEffect
+ call SwapTurn
+ ret
+
+; If heads, prevent all damage done to user next turn
+KakunaStiffenEffect: ; 2c7a0 (b:47a0)
+ ldtx de, IfHeadsNoDamageNextTurnText
+ call TossCoin_BankB
+ jp nc, SetWasUnsuccessful
+ ld a, ATK_ANIM_PROTECT
+ ld [wLoadedAttackAnimation], a
+ ld a, SUBSTATUS1_NO_DAMAGE_STIFFEN
+ call ApplySubstatus1ToDefendingCard
+ ret
+
+KakunaPoisonPowder_AIEffect: ; 2c7b4 (b:47b4)
+ ld a, 5
+ lb de, 0, 10
+ jp UpdateExpectedAIDamage_AccountForPoison
+
+GolbatLeechLifeEffect: ; 2c7bc (b:47bc)
+ ld hl, wDealtDamage
+ ld e, [hl]
+ inc hl ; wDamageEffectiveness
+ ld d, [hl]
+ call ApplyAndAnimateHPRecovery
+ ret
+
+VenonatLeechLifeEffect: ; 2c7c6 (b:47c6)
+ ld hl, wDealtDamage
+ ld e, [hl]
+ inc hl ; wDamageEffectiveness
+ ld d, [hl]
+ call ApplyAndAnimateHPRecovery
+ ret
+
+; During your next turn, double damage
+SwordsDanceEffect: ; 2c7d0 (b:47d0)
+ ld a, [wTempTurnDuelistCardID]
+ cp SCYTHER
+ ret nz
+ ld a, SUBSTATUS1_NEXT_TURN_DOUBLE_DAMAGE
+ call ApplySubstatus1ToDefendingCard
+ ret
+
+; If heads, defending Pokemon becomes confused
+ZubatSupersonicEffect: ; 2c7dc (b:47dc)
+ call Confusion50PercentEffect
+ call nc, SetNoEffectFromStatus
+ ret
+
+ZubatLeechLifeEffect: ; 2c7e3 (b:47e3)
+ ld hl, wDealtDamage
+ ld e, [hl]
+ inc hl
+ ld d, [hl]
+ call ApplyAndAnimateHPRecovery
+ ret
+
+Twineedle_AIEffect: ; 2c7ed (b:47ed)
+ ld a, 60 / 2
+ lb de, 0, 60
+ jp SetExpectedAIDamage
+
+; Flip 2 coins; deal 30x number of heads
+Twineedle_MultiplierEffect: ; 2c7f5 (b:47f5)
+ ld hl, 30
+ call LoadTxRam3
+ ldtx de, DamageCheckIfHeadsXDamageText
+ ld a, 2
+ call TossCoinATimes_BankB
+ ld e, a
+ add a
+ add e
+ call ATimes10
+ call SetDefiniteDamage
+ ret
+
+BeedrillPoisonSting_AIEffect: ; 2c80d (b:480d)
+ ld a, 5
+ lb de, 0, 10
+ jp UpdateExpectedAIDamage_AccountForPoison
+
+ExeggcuteLeechSeedEffect: ; 2c815 (b:4815)
+ ld hl, wDealtDamage
+ ld a, [hli]
+ or a
+ ret z ; return if no damage dealt
+ ld de, 10
+ call ApplyAndAnimateHPRecovery
+ ret
+
+FoulGas_AIEffect: ; 2c822 (b:4822)
+ ld a, 5
+ lb de, 0, 10
+ jp UpdateExpectedAIDamage
+
+; If heads, defending Pokemon becomes poisoned. If tails, defending Pokemon becomes confused
+FoulGas_PoisonOrConfusionEffect: ; 2c82a (b:482a)
+ ldtx de, PoisonedIfHeadsConfusedIfTailsText
+ call TossCoin_BankB
+ jp c, PoisonEffect
+ jp ConfusionEffect
+
+; an exact copy of KakunaStiffenEffect
+; If heads, prevent all damage done to user next turn
+MetapodStiffenEffect: ; 2c836 (b:4836)
+ ldtx de, IfHeadsNoDamageNextTurnText
+ call TossCoin_BankB
+ jp nc, SetWasUnsuccessful
+ ld a, ATK_ANIM_PROTECT
+ ld [wLoadedAttackAnimation], a
+ ld a, SUBSTATUS1_NO_DAMAGE_STIFFEN
+ call ApplySubstatus1ToDefendingCard
+ ret
+
+; returns carry if no cards in Deck or if
+; Play Area is full already.
+Sprout_CheckDeckAndPlayArea: ; 2c84a (b:484a)
+ call CheckIfDeckIsEmpty
+ ret c ; return if no cards in deck
+ ld a, DUELVARS_NUMBER_OF_POKEMON_IN_PLAY_AREA
+ call GetTurnDuelistVariable
+ ldtx hl, NoSpaceOnTheBenchText
+ cp MAX_PLAY_AREA_POKEMON
+ ccf
+ ret
+
+Sprout_PlayerSelectEffect: ; 2c85a (b:485a)
+ ld a, $ff
+ ldh [hTemp_ffa0], a
+
+ call CreateDeckCardList
+ ldtx hl, ChooseAnOddishFromDeckText
+ ldtx bc, OddishText
+ lb de, SEARCHEFFECT_CARD_ID, ODDISH
+ call LookForCardsInDeck
+ ret c
+
+; draw Deck list interface and print text
+ bank1call Func_5591
+ ldtx hl, ChooseAnOddishText
+ ldtx de, DuelistDeckText
+ bank1call SetCardListHeaderText
+
+.loop
+ bank1call DisplayCardList
+ jr c, .pressed_b
+ call GetCardIDFromDeckIndex
+ ld bc, ODDISH
+ call CompareDEtoBC
+ jr nz, .play_sfx
+
+; Oddish was selected
+ ldh a, [hTempCardIndex_ff98]
+ ldh [hTemp_ffa0], a
+ or a
+ ret
+
+.play_sfx
+ ; play SFX and loop back
+ call Func_3794
+ jr .loop
+
+.pressed_b
+; figure if Player can exit the screen without selecting,
+; that is, if the Deck has no Oddish card.
+ ld a, DUELVARS_CARD_LOCATIONS
+ call GetTurnDuelistVariable
+.loop_b_press
+ ld a, [hl]
+ cp CARD_LOCATION_DECK
+ jr nz, .next
+ ld a, l
+ call GetCardIDFromDeckIndex
+ ld bc, ODDISH
+ call CompareDEtoBC
+ jr z, .play_sfx ; found Oddish, go back to top loop
+.next
+ inc l
+ ld a, l
+ cp DECK_SIZE
+ jr c, .loop_b_press
+
+; no Oddish in Deck, can safely exit screen
+ ld a, $ff
+ ldh [hTemp_ffa0], a
+ or a
+ ret
+
+Sprout_AISelectEffect: ; 2c8b7 (b:48b7)
+ call CreateDeckCardList
+ ld hl, wDuelTempList
+.loop_deck
+ ld a, [hli]
+ ldh [hTemp_ffa0], a
+ cp $ff
+ ret z ; no Oddish
+ call GetCardIDFromDeckIndex
+ ld a, e
+ cp ODDISH
+ jr nz, .loop_deck
+ ret ; Oddish found
+
+Sprout_PutInPlayAreaEffect: ; 2c8cc (b:48cc)
+ ldh a, [hTemp_ffa0]
+ cp $ff
+ jr z, .shuffle
+ call SearchCardInDeckAndAddToHand
+ call AddCardToHand
+ call PutHandPokemonCardInPlayArea
+ call IsPlayerTurn
+ jr c, .shuffle
+ ; display card on screen
+ ldh a, [hTemp_ffa0]
+ ldtx hl, PlacedOnTheBenchText
+ bank1call DisplayCardDetailScreen
+.shuffle
+ call Func_2c0bd
+ ret
+
+; returns carry if no Pokemon on Bench
+Teleport_CheckBench: ; 2c8ec (b:48ec)
+ ld a, DUELVARS_NUMBER_OF_POKEMON_IN_PLAY_AREA
+ call GetTurnDuelistVariable
+ ldtx hl, ThereAreNoPokemonOnBenchText
+ cp 2
+ ret
+
+Teleport_PlayerSelectEffect: ; 2c8f7 (b:48f7)
+ ldtx hl, SelectPkmnOnBenchToSwitchWithActiveText
+ call DrawWideTextBox_WaitForInput
+ bank1call HasAlivePokemonInBench
+ ld a, $01
+ ld [wcbd4], a
+.loop
+ bank1call OpenPlayAreaScreenForSelection
+ jr c, .loop
+ ldh a, [hTempPlayAreaLocation_ff9d]
+ ldh [hTemp_ffa0], a
+ ret
+
+Teleport_AISelectEffect: ; 2c90f (b:490f)
+ ld a, DUELVARS_NUMBER_OF_POKEMON_IN_PLAY_AREA
+ call GetTurnDuelistVariable
+ call Random
+ ldh [hTemp_ffa0], a
+ ret
+
+Teleport_SwitchEffect: ; 2c91a (b:491a)
+ ldh a, [hTemp_ffa0]
+ ld e, a
+ call SwapArenaWithBenchPokemon
+ xor a
+ ld [wDuelDisplayedScreen], a
+ ret
+
+BigEggsplosion_AIEffect: ; 2c925 (b:4925)
+ ldh a, [hTempPlayAreaLocation_ff9d]
+ ld e, a
+ call GetPlayAreaCardAttachedEnergies
+ ld a, [wTotalAttachedEnergies]
+ call SetDamageToATimes20
+ inc h
+ jr nz, .capped
+ ld l, 255
+.capped
+ ld a, l
+ ld [wAIMaxDamage], a
+ srl a
+ ld [wDamage], a
+ xor a
+ ld [wAIMinDamage], a
+ ret
+
+; Flip coins equal to attached energies; deal 20x number of heads
+BigEggsplosion_MultiplierEffect: ; 2c944 (b:4944)
+ ld e, PLAY_AREA_ARENA
+ call GetPlayAreaCardAttachedEnergies
+ ld hl, 20
+ call LoadTxRam3
+ ld a, [wTotalAttachedEnergies]
+ ldtx de, DamageCheckIfHeadsXDamageText
+ call TossCoinATimes_BankB
+; fallthrough
+
+; set damage to 20*a. Also return result in hl
+SetDamageToATimes20: ; 2c958 (b:4958)
+ ld l, a
+ ld h, $00
+ ld e, l
+ ld d, h
+ add hl, hl
+ add hl, hl
+ add hl, de
+ add hl, hl
+ add hl, hl
+ ld a, l
+ ld [wDamage], a
+ ld a, h
+ ld [wDamage + 1], a
+ ret
+
+Thrash_AIEffect: ; 2c96b (b:496b)
+ ld a, (30 + 40) / 2
+ lb de, 30, 40
+ jp SetExpectedAIDamage
+
+; If heads 10 more damage; if tails, 10 damage to itself
+Thrash_ModifierEffect: ; 2c973 (b:4973)
+ ldtx de, IfHeadPlus10IfTails10ToYourselfText
+ call TossCoin_BankB
+ ldh [hTemp_ffa0], a
+ ret nc
+ ld a, 10
+ call AddToDamage
+ ret
+
+Thrash_RecoilEffect: ; 2c982 (b:4982)
+ ldh a, [hTemp_ffa0]
+ or a
+ ret nz
+ ld a, 10
+ call DealRecoilDamageToSelf
+ ret
+
+Toxic_AIEffect: ; 2c98c (b:498c)
+ ld a, 20
+ lb de, 20, 20
+ jp UpdateExpectedAIDamage
+
+; Defending Pokémon becomes double poisoned (takes 20 damage per turn rather than 10)
+Toxic_DoublePoisonEffect: ; 2c994 (b:4994)
+ call DoublePoisonEffect
+ ret
+
+BoyfriendsEffect: ; 2c998 (b:4998)
+ ld a, DUELVARS_ARENA_CARD
+ call GetTurnDuelistVariable
+ ld c, PLAY_AREA_ARENA
+.loop
+ ld a, [hl]
+ cp $ff
+ jr z, .done
+ call GetCardIDFromDeckIndex
+ ld a, e
+ cp NIDOKING
+ jr nz, .next
+ ld a, d
+ cp $00 ; why check d? Card IDs are only 1 byte long
+ jr nz, .next
+ inc c
+.next
+ inc hl
+ jr .loop
+.done
+; c holds number of Nidoking found in Play Area
+ ld a, c
+ add a
+ call ATimes10
+ call AddToDamage ; adds 2 * 10 * c
+ ret
+
+NidoranFFurySwipes_AIEffect: ; 2c9be (b:49be)
+ ld a, 30 / 2
+ lb de, 0, 30
+ jp SetExpectedAIDamage
+
+NidoranFFurySwipes_MultiplierEffect: ; 2c9c6 (b:49c6)
+ ld hl, 10
+ call LoadTxRam3
+ ldtx de, DamageCheckIfHeadsXDamageText
+ ld a, 3
+ call TossCoinATimes_BankB
+ call ATimes10
+ call SetDefiniteDamage
+ ret
+
+NidoranFCallForFamily_CheckDeckAndPlayArea: ; 2c9db (b:49db)
+ call CheckIfDeckIsEmpty
+ ret c ; return if no cards in deck
+ ld a, DUELVARS_NUMBER_OF_POKEMON_IN_PLAY_AREA
+ call GetTurnDuelistVariable
+ ldtx hl, NoSpaceOnTheBenchText
+ cp MAX_PLAY_AREA_POKEMON
+ ccf
+ ret
+
+NidoranFCallForFamily_PlayerSelectEffect: ; 2c9eb (b:49eb)
+ ld a, $ff
+ ldh [hTemp_ffa0], a
+
+ call CreateDeckCardList
+ ldtx hl, ChooseNidoranFromDeckText
+ ldtx bc, NidoranMNidoranFText
+ lb de, SEARCHEFFECT_NIDORAN, $00
+ call LookForCardsInDeck
+ ret c
+
+; draw Deck list interface and print text
+ bank1call Func_5591
+ ldtx hl, ChooseNidoranText
+ ldtx de, DuelistDeckText
+ bank1call SetCardListHeaderText
+
+.loop
+ bank1call DisplayCardList
+ jr c, .pressed_b
+ call GetCardIDFromDeckIndex
+ ld bc, NIDORANF
+ call CompareDEtoBC
+ jr z, .selected_nidoran
+ ld bc, NIDORANM
+ call CompareDEtoBC
+ jr nz, .loop ; .play_sfx would be more appropriate here
+
+.selected_nidoran
+ ldh a, [hTempCardIndex_ff98]
+ ldh [hTemp_ffa0], a
+ or a
+ ret
+
+.play_sfx
+ ; play SFX and loop back
+ call Func_3794
+ jr .loop
+
+.pressed_b
+; figure if Player can exit the screen without selecting,
+; that is, if the Deck has no NidoranF or NidoranM card.
+ ld a, DUELVARS_CARD_LOCATIONS
+ call GetTurnDuelistVariable
+.loop_b_press
+ ld a, [hl]
+ cp CARD_LOCATION_DECK
+ jr nz, .next
+ ld a, l
+ call GetCardIDFromDeckIndex
+ ld bc, NIDORANF
+ call CompareDEtoBC
+ jr z, .play_sfx ; found, go back to top loop
+ ld bc, NIDORANM
+ jr z, .play_sfx ; found, go back to top loop
+.next
+ inc l
+ ld a, l
+ cp DECK_SIZE
+ jr c, .loop_b_press
+
+; no Nidoran in Deck, can safely exit screen
+ ld a, $ff
+ ldh [hTemp_ffa0], a
+ or a
+ ret
+
+NidoranFCallForFamily_AISelectEffect: ; 2ca55 (b:4a55)
+ call CreateDeckCardList
+ ld hl, wDuelTempList
+.loop_deck
+ ld a, [hli]
+ ldh [hTemp_ffa0], a
+ cp $ff
+ ret z ; none found
+ call GetCardIDFromDeckIndex
+ ld a, e
+ cp NIDORANF
+ jr z, .found
+ cp NIDORANM
+ jr nz, .loop_deck
+.found
+ ret
+
+NidoranFCallForFamily_PutInPlayAreaEffect: ; 2ca6e (b:4a6e)
+ ldh a, [hTemp_ffa0]
+ cp $ff
+ jr z, .shuffle
+ call SearchCardInDeckAndAddToHand
+ call AddCardToHand
+ call PutHandPokemonCardInPlayArea
+ call IsPlayerTurn
+ jr c, .shuffle
+ ; display card on screen
+ ldh a, [hTemp_ffa0]
+ ldtx hl, PlacedOnTheBenchText
+ bank1call DisplayCardDetailScreen
+.shuffle
+ call Func_2c0bd
+ ret
+
+HornHazard_AIEffect: ; 2ca8e (b:4a8e)
+ ld a, 30 / 2
+ lb de, 0, 30
+ jp SetExpectedAIDamage
+
+HornHazard_NoDamage50PercentEffect: ; 2ca96 (b:4a96)
+ ldtx de, DamageCheckIfTailsNoDamageText
+ call TossCoin_BankB
+ jr c, .heads
+ xor a
+ call SetDefiniteDamage
+ call SetWasUnsuccessful
+ ret
+.heads
+ ld a, ATK_ANIM_HIT
+ ld [wLoadedAttackAnimation], a
+ ret
+
+NidorinaSupersonicEffect: ; 2caac (b:4aac)
+ call Confusion50PercentEffect
+ call nc, SetNoEffectFromStatus
+ ret
+
+NidorinaDoubleKick_AIEffect: ; 2cab3 (b:4ab3)
+ ld a, 60 / 2
+ lb de, 0, 60
+ jp SetExpectedAIDamage
+
+NidorinaDoubleKick_MultiplierEffect: ; 2cabb (b:4abb)
+ ld hl, 30
+ call LoadTxRam3
+ ldtx de, DamageCheckIfHeadsXDamageText
+ ld a, 2
+ call TossCoinATimes_BankB
+ ld e, a
+ add a
+ add e
+ call ATimes10
+ call SetDefiniteDamage
+ ret
+
+NidorinoDoubleKick_AIEffect: ; 2cad3 (b:4ad3)
+ ld a, 60 / 2
+ lb de, 0, 60
+ jp SetExpectedAIDamage
+
+NidorinoDoubleKick_MultiplierEffect: ; 2cabb (b:4abb)
+ ld hl, 30
+ call LoadTxRam3
+ ldtx de, DamageCheckIfHeadsXDamageText
+ ld a, 2
+ call TossCoinATimes_BankB
+ ld e, a
+ add a
+ add e
+ call ATimes10
+ call SetDefiniteDamage
+ ret
+
+ButterfreeWhirlwind_CheckBench: ; 2caf3 (b:4af3)
+ ld a, DUELVARS_NUMBER_OF_POKEMON_IN_PLAY_AREA
+ call GetNonTurnDuelistVariable
+ cp 2
+ jr nc, .has_bench
+ ; no bench, do not do effect
+ ld a, $ff
+ ldh [hTemp_ffa0], a
+ ret
+.has_bench
+ call DuelistSelectForcedSwitch
+ ldh a, [hTempPlayAreaLocation_ff9d]
+ ldh [hTemp_ffa0], a
+ ret
+
+ButterfreeWhirlwind_SwitchEffect: ; 2cb09 (b:4b09)
+ ldh a, [hTemp_ffa0]
+ call HandleSwitchDefendingPokemonEffect
+ ret
+
+ButterfreeMegaDrainEffect: ; 2cb0f (b:4b0f)
+ ld hl, wDealtDamage
+ ld a, [hli]
+ ld h, [hl]
+ ld l, a
+ srl h
+ rr l
+ bit 0, l
+ jr z, .rounded
+ ; round up to nearest 10
+ ld de, 10 / 2
+ add hl, de
+.rounded
+ ld e, l
+ ld d, h
+ call ApplyAndAnimateHPRecovery
+ ret
+
+WeedlePoisonSting_AIEffect: ; 2cb27 (b:4b27)
+ ld a, 5
+ lb de, 0, 10
+ jp UpdateExpectedAIDamage_AccountForPoison
+
+IvysaurPoisonPowder_AIEffect: ; 2cb2f (b:4b2f)
+ ld a, 10
+ lb de, 10, 10
+ jp UpdateExpectedAIDamage_AccountForPoison
+
+BulbasaurLeechSeedEffect: ; 2cb37 (b:4b37)
+ ld hl, wDealtDamage
+ ld a, [hli]
+ or [hl]
+ ret z ; return if no damage dealt
+ lb de, 0, 10
+ call ApplyAndAnimateHPRecovery
+ ret
+
+; returns carry if no Grass Energy in Play Area
+EnergyTrans_CheckPlayArea: ; 2cb44 (b:4b44)
+ ldh a, [hTempPlayAreaLocation_ff9d]
+ ldh [hTemp_ffa0], a
+ ldh a, [hTempPlayAreaLocation_ff9d]
+ call CheckCannotUseDueToStatus_OnlyToxicGasIfANon0
+ ret c ; cannot use Pkmn Power
+
+; search in Play Area for at least 1 Grass Energy type
+ ld a, DUELVARS_CARD_LOCATIONS
+ call GetTurnDuelistVariable
+.loop_deck
+ ld a, [hl]
+ and CARD_LOCATION_PLAY_AREA
+ jr z, .next
+ push hl
+ ld a, l
+ call GetCardIDFromDeckIndex
+ call GetCardType
+ pop hl
+ cp TYPE_ENERGY_GRASS
+ ret z
+.next
+ inc l
+ ld a, l
+ cp DECK_SIZE
+ jr c, .loop_deck
+
+; none found
+ ldtx hl, NoGrassEnergyText
+ scf
+ ret
+
+EnergyTrans_PrintProcedure: ; 2cb6f (b:4b6f)
+ ldtx hl, ProcedureForEnergyTransferText
+ bank1call DrawWholeScreenTextBox
+ or a
+ ret
+
+EnergyTrans_TransferEffect: ; 2cb77 (b:4b77)
+ ld a, DUELVARS_DUELIST_TYPE
+ call GetTurnDuelistVariable
+ cp DUELIST_TYPE_PLAYER
+ jr z, .player
+; not player
+ bank1call Func_61a1
+ bank1call PrintPlayAreaCardList_EnableLCD
+ ret
+
+.player
+ xor a
+ ldh [hCurSelectionItem], a
+ bank1call Func_61a1
+
+.draw_play_area
+ bank1call PrintPlayAreaCardList_EnableLCD
+ push af
+ ldh a, [hCurSelectionItem]
+ ld hl, PlayAreaSelectionMenuParameters
+ call InitializeMenuParameters
+ pop af
+ ld [wNumMenuItems], a
+
+; handle the action of taking a Grass Energy card
+.loop_input_take
+ call DoFrame
+ call HandleMenuInput
+ jr nc, .loop_input_take
+ cp -1 ; b press?
+ ret z
+
+; a press
+ ldh [hAIPkmnPowerEffectParam], a
+ ldh [hCurSelectionItem], a
+ call CheckIfCardHasGrassEnergyAttached
+ jr c, .play_sfx ; no Grass attached
+
+ ldh [hAIEnergyTransEnergyCard], a
+ ldh a, [hAIEnergyTransEnergyCard] ; useless
+ ; temporarily take card away to draw Play Area
+ call AddCardToHand
+ bank1call PrintPlayAreaCardList_EnableLCD
+ ldh a, [hAIPkmnPowerEffectParam]
+ ld e, a
+ ldh a, [hAIEnergyTransEnergyCard]
+ ; give card back
+ call PutHandCardInPlayArea
+
+ ; draw Grass symbol near cursor
+ ldh a, [hAIPkmnPowerEffectParam]
+ ld b, SYM_GRASS
+ call DrawSymbolOnPlayAreaCursor
+
+; handle the action of placing a Grass Energy card
+.loop_input_put
+ call DoFrame
+ call HandleMenuInput
+ jr nc, .loop_input_put
+ cp -1 ; b press?
+ jr z, .remove_symbol
+
+; a press
+ ldh [hCurSelectionItem], a
+ ldh [hAIEnergyTransPlayAreaLocation], a
+ ld a, OPPACTION_6B15
+ call SetOppAction_SerialSendDuelData
+ ldh a, [hAIEnergyTransPlayAreaLocation]
+ ld e, a
+ ldh a, [hAIEnergyTransEnergyCard]
+ ; give card being held to this Pokemon
+ call AddCardToHand
+ call PutHandCardInPlayArea
+
+.remove_symbol
+ ldh a, [hAIPkmnPowerEffectParam]
+ ld b, SYM_SPACE
+ call DrawSymbolOnPlayAreaCursor
+ call EraseCursor
+ jr .draw_play_area
+
+.play_sfx
+ call Func_3794
+ jr .loop_input_take
+
+EnergyTrans_AIEffect: ; 2cbfb (b:4bfb)
+ ldh a, [hAIEnergyTransPlayAreaLocation]
+ ld e, a
+ ldh a, [hAIEnergyTransEnergyCard]
+ call AddCardToHand
+ call PutHandCardInPlayArea
+ bank1call PrintPlayAreaCardList_EnableLCD
+ ret
+
+; returns carry if no Grass Energy cards
+; attached to card in Play Area location of a.
+; input:
+; a = PLAY_AREA_* of location to check
+CheckIfCardHasGrassEnergyAttached: ; 2cc0a (b:4c0a)
+ or CARD_LOCATION_PLAY_AREA
+ ld e, a
+
+ ld a, DUELVARS_CARD_LOCATIONS
+ call GetTurnDuelistVariable
+.loop
+ ld a, [hl]
+ cp e
+ jr nz, .next
+ push de
+ push hl
+ ld a, l
+ call GetCardIDFromDeckIndex
+ call GetCardType
+ pop hl
+ pop de
+ cp TYPE_ENERGY_GRASS
+ jr z, .no_carry
+.next
+ inc l
+ ld a, l
+ cp DECK_SIZE
+ jr c, .loop
+ scf
+ ret
+.no_carry
+ ld a, l
+ or a
+ ret
+
+GrimerMinimizeEffect: ; 2cc30 (b:4c30)
+ ld a, SUBSTATUS1_REDUCE_BY_20
+ call ApplySubstatus1ToDefendingCard
+ ret
+
+ToxicGasEffect: ; 2cc36 (b:4c36)
+ scf
+ ret
+
+Sludge_AIEffect: ; 2cc38 (b:4c38)
+ ld a, 5
+ lb de, 0, 10
+ jp UpdateExpectedAIDamage_AccountForPoison
+
+; returns carry if no cards in Deck
+; or if Play Area is full already.
+BellsproutCallForFamily_CheckDeckAndPlayArea: ; 2cc40 (b:4c40)
+ call CheckIfDeckIsEmpty
+ ret c ; return if no cards in deck
+ ld a, DUELVARS_NUMBER_OF_POKEMON_IN_PLAY_AREA
+ call GetTurnDuelistVariable
+ ldtx hl, NoSpaceOnTheBenchText
+ cp MAX_PLAY_AREA_POKEMON
+ ccf
+ ret
+
+BellsproutCallForFamily_PlayerSelectEffect: ; 2cc50 (b:4c50)
+ ld a, $ff
+ ldh [hTemp_ffa0], a
+
+ call CreateDeckCardList
+ ldtx hl, ChooseABellsproutFromDeckText
+ ldtx bc, BellsproutText
+ lb de, SEARCHEFFECT_CARD_ID, BELLSPROUT
+ call LookForCardsInDeck
+ ret c
+
+; draw Deck list interface and print text
+ bank1call Func_5591
+ ldtx hl, ChooseABellsproutText
+ ldtx de, DuelistDeckText
+ bank1call SetCardListHeaderText
+
+.loop
+ bank1call DisplayCardList
+ jr c, .pressed_b
+ call GetCardIDFromDeckIndex
+ ld bc, BELLSPROUT
+ call CompareDEtoBC
+ jr nz, .play_sfx
+
+; Bellsprout was selected
+ ldh a, [hTempCardIndex_ff98]
+ ldh [hTemp_ffa0], a
+ or a
+ ret
+
+.play_sfx
+ ; play SFX and loop back
+ call Func_3794
+ jr .loop
+
+.pressed_b
+; figure if Player can exit the screen without selecting,
+; that is, if the Deck has no Bellsprout card.
+ ld a, DUELVARS_CARD_LOCATIONS
+ call GetTurnDuelistVariable
+.loop_b_press
+ ld a, [hl]
+ cp CARD_LOCATION_DECK
+ jr nz, .next
+ ld a, l
+ call GetCardIDFromDeckIndex
+ ld bc, BELLSPROUT
+ call CompareDEtoBC
+ jr z, .play_sfx ; found Bellsprout, go back to top loop
+.next
+ inc l
+ ld a, l
+ cp DECK_SIZE
+ jr c, .loop_b_press
+
+; no Bellsprout in Deck, can safely exit screen
+ ld a, $ff
+ ldh [hTemp_ffa0], a
+ or a
+ ret
+
+BellsproutCallForFamily_AISelectEffect: ; 2ccad (b:4cad)
+ call CreateDeckCardList
+ ld hl, wDuelTempList
+.loop_deck
+ ld a, [hli]
+ ldh [hTemp_ffa0], a
+ cp $ff
+ ret z ; no Bellsprout
+ call GetCardIDFromDeckIndex
+ ld a, e
+ cp BELLSPROUT
+ jr nz, .loop_deck
+ ret ; Bellsprout found
+
+BellsproutCallForFamily_PutInPlayAreaEffect: ; 2ccc2 (b:4cc2)
+ ldh a, [hTemp_ffa0]
+ cp $ff
+ jr z, .shuffle
+ call SearchCardInDeckAndAddToHand
+ call AddCardToHand
+ call PutHandPokemonCardInPlayArea
+ call IsPlayerTurn
+ jr c, .shuffle
+ ldh a, [hTemp_ffa0]
+ ldtx hl, PlacedOnTheBenchText
+ bank1call DisplayCardDetailScreen
+.shuffle
+ call Func_2c0bd
+ ret
+
+WeezingSmog_AIEffect: ; 2cce2 (b:4ce2)
+ ld a, 5
+ lb de, 0, 10
+ jp UpdateExpectedAIDamage_AccountForPoison
+
+WeezingSelfdestructEffect: ; 2ccea (b:4cea)
+ ld a, 60
+ call DealRecoilDamageToSelf
+ ld a, $01
+ ld [wIsDamageToSelf], a
+ ld a, 10
+ call DealDamageToAllBenchedPokemon
+ call SwapTurn
+ xor a
+ ld [wIsDamageToSelf], a
+ ld a, 10
+ call DealDamageToAllBenchedPokemon
+ call SwapTurn
+ ret
+
+Shift_OncePerTurnCheck: ; 2cd09 (b:4d09)
+ ldh a, [hTempPlayAreaLocation_ff9d]
+ ldh [hTemp_ffa0], a
+ add DUELVARS_ARENA_CARD_FLAGS
+ call GetTurnDuelistVariable
+ and USED_PKMN_POWER_THIS_TURN
+ jr nz, .already_used
+ ldh a, [hTempPlayAreaLocation_ff9d]
+ call CheckCannotUseDueToStatus_OnlyToxicGasIfANon0
+ ret
+.already_used
+ ldtx hl, OnlyOncePerTurnText
+ scf
+ ret
+
+Shift_PlayerSelectEffect: ; 2cd21 (b:4d21)
+ ldtx hl, ChoosePokemonWishToColorChangeText
+ ldh a, [hTemp_ffa0]
+ or $80
+ call HandleColorChangeScreen
+ ldh [hAIPkmnPowerEffectParam], a
+ ret c ; cancelled
+
+; check whether the color selected is valid
+ ; look in Turn Duelist's Play Area
+ call .CheckColorInPlayArea
+ ret nc
+ ; look in NonTurn Duelist's Play Area
+ call SwapTurn
+ call .CheckColorInPlayArea
+ call SwapTurn
+ ret nc
+ ; not found in either Duelist's Play Area
+ ldtx hl, UnableToSelectText
+ call DrawWideTextBox_WaitForInput
+ jr Shift_PlayerSelectEffect ; loop back to start
+
+; checks in input color in a exists in Turn Duelist's Play Area
+; returns carry if not found.
+.CheckColorInPlayArea: ; 2cd44 (b:4d44)
+ ld a, DUELVARS_NUMBER_OF_POKEMON_IN_PLAY_AREA
+ call GetTurnDuelistVariable
+ ld c, a
+ ld b, PLAY_AREA_ARENA
+.loop_play_area
+ push bc
+ ld a, b
+ call GetPlayAreaCardColor
+ pop bc
+ ld hl, hAIPkmnPowerEffectParam
+ cp [hl]
+ ret z ; found
+ inc b
+ dec c
+ jr nz, .loop_play_area
+ ; not found
+ scf
+ ret
+
+Shift_ChangeColorEffect: ; 2cd5d (b:4d5d)
+ ldh a, [hTemp_ffa0]
+ add DUELVARS_ARENA_CARD
+ call GetTurnDuelistVariable
+ call LoadCardDataToBuffer1_FromDeckIndex
+
+ ldh a, [hTemp_ffa0]
+ add DUELVARS_ARENA_CARD_FLAGS
+ call GetTurnDuelistVariable
+ set USED_PKMN_POWER_THIS_TURN_F, [hl]
+
+ ldh a, [hTemp_ffa0]
+ add DUELVARS_ARENA_CARD_CHANGED_TYPE
+ ld l, a
+ ldh a, [hAIPkmnPowerEffectParam]
+ or HAS_CHANGED_COLOR
+ ld [hl], a
+ call LoadCardNameAndInputColor
+ ldtx hl, ChangedTheColorOfText
+ call DrawWideTextBox_WaitForInput
+ ret
+
+VenomPowder_AIEffect: ; 2cd84 (b:4d84)
+ ld a, 5
+ lb de, 0, 10
+ jp UpdateExpectedAIDamage
+
+VenomPowder_PoisonConfusion50PercentEffect: ; 2cd8c (b:4d8c)
+ ldtx de, VenomPowderCheckText
+ call TossCoin_BankB
+ ret nc ; return if tails
+
+; heads
+ call PoisonEffect
+ call ConfusionEffect
+ ret c
+ ld a, CONFUSED | POISONED
+ ld [wNoEffectFromWhichStatus], a
+ ret
+
+TangelaPoisonPowder_AIEffect: ; 2cda0 (b:4da0)
+ ld a, 5
+ lb de, 0, 10
+ jp UpdateExpectedAIDamage_AccountForPoison
+
+Heal_OncePerTurnCheck: ; 2cda8 (b:4da8)
+ ldh a, [hTempPlayAreaLocation_ff9d]
+ ldh [hTemp_ffa0], a
+ add DUELVARS_ARENA_CARD_FLAGS
+ call GetTurnDuelistVariable
+ and USED_PKMN_POWER_THIS_TURN
+ jr nz, .already_used
+
+ call CheckIfPlayAreaHasAnyDamage
+ ldtx hl, NoPokemonWithDamageCountersText
+ ret c ; no damage counters to heal
+
+ ldh a, [hTempPlayAreaLocation_ff9d]
+ call CheckCannotUseDueToStatus_OnlyToxicGasIfANon0
+ ret
+
+.already_used
+ ldtx hl, OnlyOncePerTurnText
+ scf
+ ret
+
+Heal_RemoveDamageEffect: ; 2cdc7 (b:4dc7)
+ ldtx de, IfHeadsHealIsSuccessfulText
+ call TossCoin_BankB
+ ldh [hAIPkmnPowerEffectParam], a
+ jr nc, .done
+
+ ld a, DUELVARS_DUELIST_TYPE
+ call GetTurnDuelistVariable
+ cp DUELIST_TYPE_LINK_OPP
+ jr z, .link_opp
+ and DUELIST_TYPE_AI_OPP
+ jr nz, .done
+
+; player
+ ldtx hl, ChoosePkmnToRemoveDamageCounterText
+ call DrawWideTextBox_WaitForInput
+ bank1call HasAlivePokemonInPlayArea
+.loop_input
+ bank1call OpenPlayAreaScreenForSelection
+ jr c, .loop_input
+ ldh a, [hTempPlayAreaLocation_ff9d]
+ ldh [hPlayAreaEffectTarget], a
+ ld e, a
+ call GetCardDamageAndMaxHP
+ or a
+ jr z, .loop_input ; has no damage counters
+ ldh a, [hTempPlayAreaLocation_ff9d]
+ call SerialSend8Bytes
+ jr .done
+
+.link_opp
+ call SerialRecv8Bytes
+ ldh [hPlayAreaEffectTarget], a
+ ; fallthrough
+
+.done
+; flag Pkmn Power as being used regardless of coin outcome
+ ldh a, [hTemp_ffa0]
+ add DUELVARS_ARENA_CARD_FLAGS
+ call GetTurnDuelistVariable
+ set USED_PKMN_POWER_THIS_TURN_F, [hl]
+ ldh a, [hAIPkmnPowerEffectParam]
+ or a
+ ret z ; return if coin was tails
+
+ ldh a, [hPlayAreaEffectTarget]
+ add DUELVARS_ARENA_CARD_HP
+ call GetTurnDuelistVariable
+ add 10 ; remove 1 damage counter
+ ld [hl], a
+ ldh a, [hPlayAreaEffectTarget]
+ call Func_2c10b
+ call ExchangeRNG
+ ret
+
+PetalDance_AIEffect: ; 2ce23 (b:4e23)
+ ld a, 120 / 2
+ lb de, 0, 120
+ jp SetExpectedAIDamage
+
+PetalDance_MultiplierEffect: ; 2ce2b (b:4e2b)
+ ld hl, 40
+ call LoadTxRam3
+ ldtx de, DamageCheckIfHeadsXDamageText
+ ld a, 3
+ call TossCoinATimes_BankB
+ add a
+ add a
+ call ATimes10
+ ; a = 4 * 10 * heads
+ call SetDefiniteDamage
+ call SwapTurn
+ call ConfusionEffect
+ call SwapTurn
+ ret
+
+PoisonWhip_AIEffect: ; 2ce4b (b:4e4b)
+ ld a, 10
+ lb de, 10, 10
+ jp UpdateExpectedAIDamage_AccountForPoison
+
+SolarPower_CheckUse: ; 2ce53 (b:4e53)
+ ldh a, [hTempPlayAreaLocation_ff9d]
+ ldh [hTemp_ffa0], a
+ add DUELVARS_ARENA_CARD_FLAGS
+ call GetTurnDuelistVariable
+ and USED_PKMN_POWER_THIS_TURN
+ jr nz, .already_used
+
+ ldh a, [hTempPlayAreaLocation_ff9d]
+ call CheckCannotUseDueToStatus_OnlyToxicGasIfANon0
+ ret c ; can't use PKMN due to status or Toxic Gas
+
+; return carry if none of the Arena cards have status conditions
+ ld a, DUELVARS_ARENA_CARD_STATUS
+ call GetTurnDuelistVariable
+ or a
+ jr nz, .has_status
+ ld a, DUELVARS_ARENA_CARD_STATUS
+ call GetNonTurnDuelistVariable
+ or a
+ jr z, .no_status
+.has_status
+ or a
+ ret
+.already_used
+ ldtx hl, OnlyOncePerTurnText
+ scf
+ ret
+.no_status
+ ldtx hl, NotAffectedByPoisonSleepParalysisOrConfusionText
+ scf
+ ret
+
+SolarPower_RemoveStatusEffect: ; 2ce82 (b:4e82)
+ ld a, ATK_ANIM_HEAL_BOTH_SIDES
+ ld [wLoadedAttackAnimation], a
+ bank1call Func_7415
+ ldh a, [hTempPlayAreaLocation_ff9d]
+ ld b, a
+ ld c, $00
+ ldh a, [hWhoseTurn]
+ ld h, a
+ bank1call PlayAttackAnimation
+ bank1call WaitAttackAnimation
+
+ ldh a, [hTemp_ffa0]
+ add DUELVARS_ARENA_CARD_FLAGS
+ call GetTurnDuelistVariable
+ set USED_PKMN_POWER_THIS_TURN_F, [hl]
+ ld l, DUELVARS_ARENA_CARD_STATUS
+ ld [hl], NO_STATUS
+
+ ld a, DUELVARS_ARENA_CARD_STATUS
+ call GetNonTurnDuelistVariable
+ ld [hl], NO_STATUS
+ bank1call DrawDuelHUDs
+ ret
+
+VenusaurMegaDrainEffect: ; 2ceb0 (b:4eb0)
+ ld hl, wDealtDamage
+ ld a, [hli]
+ ld h, [hl]
+ ld l, a
+ srl h
+ rr l
+ bit 0, l
+ jr z, .rounded
+ ; round up to nearest 10
+ ld de, 10 / 2
+ add hl, de
+.rounded
+ ld e, l
+ ld d, h
+ call ApplyAndAnimateHPRecovery
+ ret
+
+; applies the damage bonus for attacks that get bonus
+; from extra Water energy cards.
+; this bonus is always 10 more damage for each extra Water energy
+; and is always capped at a maximum of 20 damage.
+; input:
+; b = number of Water energy cards needed for paying Energy Cost
+; c = number of colorless energy cards needed for paying Energy Cost
+ApplyExtraWaterEnergyDamageBonus: ; 2cec8 (b:4ec8)
+ ld a, [wMetronomeEnergyCost]
+ or a
+ jr z, .not_metronome
+ ld c, a ; amount of colorless needed for Metronome
+ ld b, 0 ; no Water energy needed for Metronome
+
+.not_metronome
+ push bc
+ ldh a, [hTempPlayAreaLocation_ff9d]
+ ld e, a
+ call GetPlayAreaCardAttachedEnergies
+ pop bc
+
+ ld hl, wAttachedEnergies + WATER
+ ld a, c
+ or a
+ jr z, .check_bonus ; is Energy cost all water energy?
+
+ ; it's not, so we need to remove the
+ ; Water energy cards from calculations
+ ; if they pay for colorless instead.
+ ld a, [wTotalAttachedEnergies]
+ cp [hl]
+ jr nz, .check_bonus ; skip if at least 1 non-Water energy attached
+
+ ; Water is the only energy color attached
+ ld a, c
+ add b
+ ld b, a
+ ; b += c
+
+.check_bonus
+ ld a, [hl]
+ sub b
+ jr c, .skip_bonus ; is water energy < b?
+ jr z, .skip_bonus ; is water energy == b?
+
+; a holds number of water energy not payed for energy cost
+ cp 3
+ jr c, .less_than_3
+ ld a, 2 ; cap this to 2 for bonus effect
+.less_than_3
+ call ATimes10
+ call AddToDamage ; add 10 * a to damage
+
+.skip_bonus
+ ld a, [wDamage]
+ ld [wAIMinDamage], a
+ ld [wAIMaxDamage], a
+ ret
+
+OmastarWaterGunEffect: ; 2cf05 (b:4f05)
+ lb bc, 1, 1
+ jr ApplyExtraWaterEnergyDamageBonus
+
+OmastarSpikeCannon_AIEffect: ; 2cf0a (b:4f0a)
+ ld a, 60 / 2
+ lb de, 0, 60
+ jp SetExpectedAIDamage
+
+OmastarSpikeCannon_MultiplierEffect: ; 2cf12 (b:4f12)
+ ld hl, 30
+ call LoadTxRam3
+ ld a, 2
+ ldtx de, DamageCheckIfHeadsXDamageText
+ call TossCoinATimes_BankB
+ ld e, a
+ add a
+ add e
+ call ATimes10
+ call SetDefiniteDamage ; 3 * 10 * heads
+ ret
+
+ClairvoyanceEffect: ; 2cf2a (b:4f2a)
+ scf
+ ret
+
+OmanyteWaterGunEffect: ; 2cf2c (b:4f2c)
+ lb bc, 1, 0
+ jp ApplyExtraWaterEnergyDamageBonus
+
+WartortleWithdrawEffect: ; 2cf32 (b:4f32)
+ ldtx de, IfHeadsNoDamageNextTurnText
+ call TossCoin_BankB
+ jp nc, SetWasUnsuccessful
+ ld a, ATK_ANIM_PROTECT
+ ld [wLoadedAttackAnimation], a
+ ld a, SUBSTATUS1_NO_DAMAGE_10
+ call ApplySubstatus1ToDefendingCard
+ ret
+
+RainDanceEffect: ; 2cf46 (b:4f46)
+ scf
+ ret
+
+HydroPumpEffect: ; 2cf48 (b:4f48)
+ lb bc, 3, 0
+ jp ApplyExtraWaterEnergyDamageBonus
+
+KinglerFlail_AIEffect: ; 2cf4e (b:4f4e)
+ call KinglerFlail_HPCheck
+ jp SetDefiniteAIDamage
+
+KinglerFlail_HPCheck: ; 2cf54 (b:4f54)
+ ld e, PLAY_AREA_ARENA
+ call GetCardDamageAndMaxHP
+ call SetDefiniteDamage
+ ret
+
+; returns carry if no cards in Deck
+; or if Play Area is full already.
+KrabbyCallForFamily_CheckDeckAndPlayArea: ; 2cf5d (b:4f5d)
+ call CheckIfDeckIsEmpty
+ ret c ; return if no cards in deck
+ ld a, DUELVARS_NUMBER_OF_POKEMON_IN_PLAY_AREA
+ call GetTurnDuelistVariable
+ ldtx hl, NoSpaceOnTheBenchText
+ cp MAX_PLAY_AREA_POKEMON
+ ccf
+ ret
+
+KrabbyCallForFamily_PlayerSelectEffect: ; 2cf6d (b:4f6d)
+ ld a, $ff
+ ldh [hTemp_ffa0], a
+
+ call CreateDeckCardList
+ ldtx hl, ChooseAKrabbyFromDeckText
+ ldtx bc, KrabbyText
+ lb de, SEARCHEFFECT_CARD_ID, KRABBY
+ call LookForCardsInDeck
+ ret c
+
+; draw Deck list interface and print text
+ bank1call Func_5591
+ ldtx hl, ChooseAKrabbyText
+ ldtx de, DuelistDeckText
+ bank1call SetCardListHeaderText
+
+.loop
+ bank1call DisplayCardList
+ jr c, .pressed_b
+ call GetCardIDFromDeckIndex
+ ld bc, KRABBY
+ call CompareDEtoBC
+ jr nz, .play_sfx
+
+; Krabby was selected
+ ldh a, [hTempCardIndex_ff98]
+ ldh [hTemp_ffa0], a
+ or a
+ ret
+
+.play_sfx
+ ; play SFX and loop back
+ call Func_3794
+ jr .loop
+
+.pressed_b
+; figure if Player can exit the screen without selecting,
+; that is, if the Deck has no Krabby card.
+ ld a, DUELVARS_CARD_LOCATIONS
+ call GetTurnDuelistVariable
+.loop_b_press
+ ld a, [hl]
+ cp CARD_LOCATION_DECK
+ jr nz, .next
+ ld a, l
+ call GetCardIDFromDeckIndex
+ ld bc, KRABBY
+ call CompareDEtoBC
+ jr z, .play_sfx ; found Krabby, go back to top loop
+.next
+ inc l
+ ld a, l
+ cp DECK_SIZE
+ jr c, .loop_b_press
+
+; no Krabby in Deck, can safely exit screen
+ ld a, $ff
+ ldh [hTemp_ffa0], a
+ or a
+ ret
+
+KrabbyCallForFamily_AISelectEffect: ; 2cfdf (b:4fdf)
+ call CreateDeckCardList
+ ld hl, wDuelTempList
+.loop_deck
+ ld a, [hli]
+ ldh [hTemp_ffa0], a
+ cp $ff
+ ret z ; no Krabby
+ call GetCardIDFromDeckIndex
+ ld a, e
+ cp KRABBY
+ jr nz, .loop_deck
+ ret ; Krabby found
+
+KrabbyCallForFamily_PutInPlayAreaEffect: ; 2cfca (b:4fca)
+ ldh a, [hTemp_ffa0]
+ cp $ff
+ jr z, .shuffle
+ call SearchCardInDeckAndAddToHand
+ call AddCardToHand
+ call PutHandPokemonCardInPlayArea
+ call IsPlayerTurn
+ jr c, .shuffle
+ ldh a, [hTemp_ffa0]
+ ldtx hl, PlacedOnTheBenchText
+ bank1call DisplayCardDetailScreen
+.shuffle
+ call Func_2c0bd
+ ret
+
+MagikarpFlail_AIEffect: ; 2cfff (b:4fff)
+ call MagikarpFlail_HPCheck
+ jp SetDefiniteAIDamage
+
+MagikarpFlail_HPCheck: ; 2d005 (b:5005)
+ ld e, PLAY_AREA_ARENA
+ call GetCardDamageAndMaxHP
+ call SetDefiniteDamage
+ ret
+
+HeadacheEffect: ; 2d00e (b:500e)
+ ld a, DUELVARS_ARENA_CARD_SUBSTATUS3
+ call GetNonTurnDuelistVariable
+ set SUBSTATUS3_HEADACHE, [hl]
+ ret
+
+PsyduckFurySwipes_AIEffect: ; 2d016 (b:5016)
+ ld a, 30 / 2
+ lb de, 0, 30
+ jp SetExpectedAIDamage
+
+PsyduckFurySwipes_MultiplierEffect: ; 2d01e (b:501e)
+ ld hl, 10
+ call LoadTxRam3
+ ldtx de, DamageCheckIfHeadsXDamageText
+ ld a, 3
+ call TossCoinATimes_BankB
+ call ATimes10
+ call SetDefiniteDamage
+ ret
+
+GolduckHyperBeam_PlayerSelectEffect: ; 2d033 (b:5033)
+ call SwapTurn
+ ld e, PLAY_AREA_ARENA
+ call GetPlayAreaCardAttachedEnergies
+ ld a, [wTotalAttachedEnergies]
+ or a
+ jr z, .no_energy
+
+; draw Energy Card list screen
+ ldtx hl, ChooseDiscardEnergyCardFromOpponentText
+ call DrawWideTextBox_WaitForInput
+ xor a ; PLAY_AREA_ARENA
+ call CreateArenaOrBenchEnergyCardList
+ xor a ; PLAY_AREA_ARENA
+ bank1call DisplayEnergyDiscardScreen
+
+.loop_input
+ bank1call HandleEnergyDiscardMenuInput
+ jr c, .loop_input
+
+ call SwapTurn
+ ldh a, [hTempCardIndex_ff98]
+ ldh [hTemp_ffa0], a ; store selected card to discard
+ ret
+
+.no_energy
+ call SwapTurn
+ ld a, $ff
+ ldh [hTemp_ffa0], a
+ or a
+ ret
+
+GolduckHyperBeam_AISelectEffect: ; 2d065 (b:5065)
+ call AIPickEnergyCardToDiscardFromDefendingPokemon
+ ldh [hTemp_ffa0], a
+ ret
+
+GolduckHyperBeam_DiscardEffect: ; 2d06b (b:506b)
+ call HandleNoDamageOrEffect
+ ret c ; return if attack had no effect
+
+ ; check if energy card was chosen to discard
+ ldh a, [hTemp_ffa0]
+ cp $ff
+ ret z ; return if none selected
+
+ ; discard Defending card's energy
+ call SwapTurn
+ call PutCardInDiscardPile
+ ld a, DUELVARS_ARENA_CARD_LAST_TURN_EFFECT
+ call GetTurnDuelistVariable
+ ld [hl], LAST_TURN_EFFECT_DISCARD_ENERGY
+ call SwapTurn
+ ret
+
+SeadraWaterGunEffect: ; 2d085 (b:5085)
+ lb bc, 1, 1
+ jp ApplyExtraWaterEnergyDamageBonus
+
+SeadraAgilityEffect: ; 2d08b (b:508b)
+ ldtx de, IfHeadsDoNotReceiveDamageOrEffectText
+ call TossCoin_BankB
+ ret nc ; return if tails
+ ld a, ATK_ANIM_AGILITY_PROTECT
+ ld [wLoadedAttackAnimation], a
+ ld a, SUBSTATUS1_AGILITY
+ call ApplySubstatus1ToDefendingCard
+ ret
+
+ShellderSupersonicEffect: ; 2d09d (b:509d)
+ call Confusion50PercentEffect
+ call nc, SetNoEffectFromStatus
+ ret
+
+HideInShellEffect: ; 2d0a4 (b:50a4)
+ ldtx de, IfHeadsNoDamageNextTurnText
+ call TossCoin_BankB
+ jp nc, SetWasUnsuccessful
+ ld a, ATK_ANIM_PROTECT
+ ld [wLoadedAttackAnimation], a
+ ld a, SUBSTATUS1_NO_DAMAGE_11
+ call ApplySubstatus1ToDefendingCard
+ ret
+
+VaporeonQuickAttack_AIEffect: ; 2d0b8 (b:50b8)
+ ld a, (10 + 30) / 2
+ lb de, 10, 30
+ jp SetExpectedAIDamage
+
+VaporeonQuickAttack_DamageBoostEffect: ; 2d0c0 (b:50c0)
+ ld hl, 20
+ call LoadTxRam3
+ ldtx de, DamageCheckIfHeadsPlusDamageText
+ call TossCoin_BankB
+ ret nc ; return if tails
+ ld a, 20
+ call AddToDamage
+ ret
+
+VaporeonWaterGunEffect: ; 2d0d3 (b:50d3)
+ lb bc, 2, 1
+ jp ApplyExtraWaterEnergyDamageBonus
+
+; returns carry if Arena card has no Water Energy attached
+; or if it doesn't have any damage counters.
+StarmieRecover_CheckEnergyHP: ; 2d0d9 (b:50d9)
+ ld e, PLAY_AREA_ARENA
+ call GetPlayAreaCardAttachedEnergies
+ ld a, [wAttachedEnergies + WATER]
+ ldtx hl, NotEnoughWaterEnergyText
+ cp 1
+ ret c ; return if not enough energy
+ call GetCardDamageAndMaxHP
+ ldtx hl, NoDamageCountersText
+ cp 10
+ ret ; return carry if no damage
+
+StarmieRecover_PlayerSelectEffect: ; 2d0f0 (b:50f0)
+ ld a, TYPE_ENERGY_WATER
+ call CreateListOfEnergyAttachedToArena
+ xor a ; PLAY_AREA_ARENA
+ bank1call DisplayEnergyDiscardScreen
+.loop_input
+ bank1call HandleEnergyDiscardMenuInput
+ jr c, .loop_input
+ ldh a, [hTempCardIndex_ff98]
+ ldh [hTemp_ffa0], a ; store card chosen
+ ret
+
+StarmieRecover_AISelectEffect: ; 2d103 (b:5103)
+ ld a, TYPE_ENERGY_WATER
+ call CreateListOfEnergyAttachedToArena
+ ld a, [wDuelTempList] ; pick first card
+ ldh [hTemp_ffa0], a
+ ret
+
+StarmieRecover_DiscardEffect: ; 2d10e (b:510e)
+ ldh a, [hTemp_ffa0]
+ call PutCardInDiscardPile
+ ret
+
+StarmieRecover_HealEffect: ; 2d114 (b:5114)
+ ld e, PLAY_AREA_ARENA
+ call GetCardDamageAndMaxHP
+ ld e, a ; all damage for recovery
+ ld d, 0
+ call ApplyAndAnimateHPRecovery
+ ret
+
+SquirtleWithdrawEffect: ; 2d120 (b:5120)
+ ldtx de, IfHeadsNoDamageNextTurnText
+ call TossCoin_BankB
+ jp nc, SetWasUnsuccessful
+ ld a, ATK_ANIM_PROTECT
+ ld [wLoadedAttackAnimation], a
+ ld a, SUBSTATUS1_NO_DAMAGE_10
+ call ApplySubstatus1ToDefendingCard
+ ret
+
+HorseaSmokescreenEffect: ; 2d134 (b:5134)
+ ld a, SUBSTATUS2_SMOKESCREEN
+ call ApplySubstatus2ToDefendingCard
+ ret
+
+TentacruelSupersonicEffect: ; 2d13a (b:513a)
+ call Confusion50PercentEffect
+ call nc, SetNoEffectFromStatus
+ ret
+
+JellyfishSting_AIEffect: ; 2d141 (b:5141)
+ ld a, 10
+ lb de, 10, 10
+ jp UpdateExpectedAIDamage_AccountForPoison
+
+; returns carry if Defending Pokemon has no attacks
+PoliwhirlAmnesia_CheckAttacks: ; 2d149 (b:5149)
+ call SwapTurn
+ ld a, DUELVARS_ARENA_CARD
+ call GetTurnDuelistVariable
+ call LoadCardDataToBuffer2_FromDeckIndex
+ ld a, [wLoadedCard2Atk1Category]
+ cp POKEMON_POWER
+ jr nz, .has_attack
+ ld hl, wLoadedCard2Atk2Name
+ ld a, [hli]
+ or [hl]
+ jr nz, .has_attack
+; has no attack
+ call SwapTurn
+ ldtx hl, NoAttackMayBeChoosenText
+ scf
+ ret
+.has_attack
+ call SwapTurn
+ or a
+ ret
+
+PoliwhirlAmnesia_PlayerSelectEffect: ; 2d16f (b:516f)
+ call PlayerPickAttackForAmnesia
+ ret
+
+PoliwhirlAmnesia_AISelectEffect: ; 2d173 (b:5173)
+ call AIPickAttackForAmnesia
+ ldh [hTemp_ffa0], a
+ ret
+
+PoliwhirlAmnesia_DisableEffect: ; 2d179 (b:5179)
+ call ApplyAmnesiaToAttack
+ ret
+
+PlayerPickAttackForAmnesia: ; 2d17d (b:517d)
+ ldtx hl, ChooseAttackOpponentWillNotBeAbleToUseText
+ call DrawWideTextBox_WaitForInput
+ call HandleDefendingPokemonAttackSelection
+ ld a, e
+ ldh [hTemp_ffa0], a
+ ret
+
+; applies the Amnesia effect on the defending Pokemon,
+; for the attack index in hTemp_ffa0.
+ApplyAmnesiaToAttack: ; 2d18a (b:518a)
+ ld a, SUBSTATUS2_AMNESIA
+ call ApplySubstatus2ToDefendingCard
+ ld a, [wNoDamageOrEffect]
+ or a
+ ret nz ; no effect
+
+; set selected attack as disabled
+ ld a, DUELVARS_ARENA_CARD_DISABLED_ATTACK_INDEX
+ call GetNonTurnDuelistVariable
+ ldh a, [hTemp_ffa0]
+ ld [hl], a
+
+ ld l, DUELVARS_ARENA_CARD_LAST_TURN_EFFECT
+ ld [hl], LAST_TURN_EFFECT_AMNESIA
+
+ call IsPlayerTurn
+ ret c ; return if Player
+
+; the rest of the routine if for Opponent
+; to announce which attack was used for Amnesia.
+ call SwapTurn
+ ld a, DUELVARS_ARENA_CARD
+ call GetTurnDuelistVariable
+ ld d, a
+ ldh a, [hTemp_ffa0]
+ ld e, a
+ call GetAttackName
+ call LoadTxRam2
+ ldtx hl, WasChosenForTheEffectOfAmnesiaText
+ call DrawWideTextBox_WaitForInput
+ call SwapTurn
+ ret
+
+PoliwhirlDoubleslap_AIEffect: ; 2d1c0 (b:51c0)
+ ld a, 60 / 2
+ lb de, 0, 60
+ jp SetExpectedAIDamage
+
+PoliwhirlDoubleslap_MultiplierEffect: ; 2d1c8 (b:51c8)
+ ld hl, 30
+ call LoadTxRam3
+ ldtx de, DamageCheckIfHeadsXDamageText
+ ld a, 2
+ call TossCoinATimes_BankB
+ ld e, a
+ add a
+ add e
+ call ATimes10
+ call SetDefiniteDamage
+ ret
+
+PoliwrathWaterGunEffect: ; 2d1e0 (b:51e0)
+ lb bc, 2, 1
+ jp ApplyExtraWaterEnergyDamageBonus
+
+Whirlpool_PlayerSelectEffect: ; 2d1e6 (b:51e6)
+ call SwapTurn
+ xor a ; PLAY_AREA_ARENA
+ call CreateArenaOrBenchEnergyCardList
+ jr c, .no_energy
+
+ ldtx hl, ChooseDiscardEnergyCardFromOpponentText
+ call DrawWideTextBox_WaitForInput
+ xor a ; PLAY_AREA_ARENA
+ bank1call DisplayEnergyDiscardScreen
+.loop_input
+ bank1call HandleEnergyDiscardMenuInput
+ jr c, .loop_input
+
+ call SwapTurn
+ ldh a, [hTempCardIndex_ff98]
+ ldh [hTemp_ffa0], a ; store selected card to discard
+ ret
+
+.no_energy
+ call SwapTurn
+ ld a, $ff
+ ldh [hTemp_ffa0], a
+ ret
+
+Whirlpool_AISelectEffect: ; 2d20e (b:520e)
+ call AIPickEnergyCardToDiscardFromDefendingPokemon
+ ldh [hTemp_ffa0], a
+ ret
+
+Whirlpool_DiscardEffect: ; 2d214 (b:5214)
+ call HandleNoDamageOrEffect
+ ret c ; return if attack had no effect
+ ldh a, [hTemp_ffa0]
+ cp $ff
+ ret z ; return if none selected
+
+ ; discard Defending card's energy
+ ; this doesn't update DUELVARS_ARENA_CARD_LAST_TURN_EFFECT
+ call SwapTurn
+ call PutCardInDiscardPile
+ ; ld a, DUELVARS_ARENA_CARD_LAST_TURN_EFFECT
+ ; call GetTurnDuelistVariable
+ ; ld [hl], LAST_TURN_EFFECT_DISCARD_ENERGY
+ call SwapTurn
+ ret
+
+PoliwagWaterGunEffect: ; 2d227 (b:5227)
+ lb bc, 1, 0
+ jp ApplyExtraWaterEnergyDamageBonus
+
+ClampEffect: ; 2d22d (b:522d)
+ ld a, ATK_ANIM_HIT_EFFECT
+ ld [wLoadedAttackAnimation], a
+ ldtx de, SuccessCheckIfHeadsAttackIsSuccessfulText
+ call TossCoin_BankB
+ jp c, ParalysisEffect
+; unsuccessful
+ xor a ; ATK_ANIM_NONE
+ ld [wLoadedAttackAnimation], a
+ call SetDefiniteDamage
+ call SetWasUnsuccessful
+ ret
+
+CloysterSpikeCannon_AIEffect: ; 2d246 (b:5246)
+ ld a, 60 / 2
+ lb de, 0, 60
+ jp SetExpectedAIDamage
+
+CloysterSpikeCannon_MultiplierEffect: ; 2d24e (b:524e)
+ ld hl, 30
+ call LoadTxRam3
+ ldtx de, DamageCheckIfHeadsXDamageText
+ ld a, 2
+ call TossCoinATimes_BankB
+ ld e, a
+ add a
+ add e
+ call ATimes10
+ call SetDefiniteDamage
+ ret
+
+Blizzard_BenchDamage50PercentEffect: ; 2d266 (b:5266)
+ ldtx de, DamageToOppBenchIfHeadsDamageToYoursIfTailsText
+ call TossCoin_BankB
+ ldh [hTemp_ffa0], a ; store coin result
+ ret
+
+Blizzard_BenchDamageEffect: ; 2d26f (b:526f)
+ ldh a, [hTemp_ffa0]
+ or a
+ jr nz, .opp_bench
+
+; own bench
+ ld a, $01
+ ld [wIsDamageToSelf], a
+ ld a, 10
+ call DealDamageToAllBenchedPokemon
+ ret
+
+.opp_bench
+ call SwapTurn
+ ld a, 10
+ call DealDamageToAllBenchedPokemon
+ call SwapTurn
+ ret
+
+; return carry if can use Cowardice
+Cowardice_Check: ; 2d28b (b:528b)
+ ldh a, [hTempPlayAreaLocation_ff9d]
+ ldh [hTemp_ffa0], a
+ call CheckCannotUseDueToStatus_OnlyToxicGasIfANon0
+ ret c ; return if cannot use
+
+ ld a, DUELVARS_NUMBER_OF_POKEMON_IN_PLAY_AREA
+ call GetTurnDuelistVariable
+ ldtx hl, EffectNoPokemonOnTheBenchText
+ cp 2
+ ret c ; return if no bench
+
+ ldh a, [hTempPlayAreaLocation_ff9d]
+ add DUELVARS_ARENA_CARD_FLAGS
+ call GetTurnDuelistVariable
+ ldtx hl, CannotBeUsedInTurnWhichWasPlayedText
+ and CAN_EVOLVE_THIS_TURN
+ scf
+ ret z ; return if was played this turn
+
+ or a
+ ret
+
+Cowardice_PlayerSelectEffect: ; 2d2ae (b:52ae)
+ ldh a, [hTemp_ffa0]
+ or a
+ ret nz ; return if not Arena card
+ ldtx hl, SelectPokemonToPlaceInTheArenaText
+ call DrawWideTextBox_WaitForInput
+ bank1call HasAlivePokemonInBench
+ bank1call OpenPlayAreaScreenForSelection
+ ldh a, [hTempPlayAreaLocation_ff9d]
+ ldh [hAIPkmnPowerEffectParam], a
+ ret
+
+Cowardice_RemoveFromPlayAreaEffect: ; 2d2c3 (b:52c3)
+ ldh a, [hTemp_ffa0]
+ add DUELVARS_ARENA_CARD
+ call GetTurnDuelistVariable
+
+; put card in Discard Pile temporarily, so that
+; all cards attached are discarded as well.
+ push af
+ ldh a, [hTemp_ffa0]
+ ld e, a
+ call MovePlayAreaCardToDiscardPile
+
+; if card was in Arena, swap selected Bench
+; Pokemon with Arena, otherwise skip.
+ ldh a, [hTemp_ffa0]
+ or a
+ jr nz, .skip_switch
+ ldh a, [hAIPkmnPowerEffectParam]
+ ld e, a
+ call SwapArenaWithBenchPokemon
+
+.skip_switch
+; move card back to Hand from Discard Pile
+; and adjust Play Area
+ pop af
+ call MoveDiscardPileCardToHand
+ call AddCardToHand
+ call ShiftAllPokemonToFirstPlayAreaSlots
+
+ xor a
+ ld [wDuelDisplayedScreen], a
+ ret
+
+LaprasWaterGunEffect: ; 2d2eb (b:52eb)
+ lb bc, 1, 0
+ jp ApplyExtraWaterEnergyDamageBonus
+
+Quickfreeze_InitialEffect: ; 2d2f1 (b:52f1)
+ scf
+ ret
+
+Quickfreeze_Paralysis50PercentEffect: ; 2d2f3 (b:52f3)
+ ldtx de, ParalysisCheckText
+ call TossCoin_BankB
+ jr c, .heads
+
+; tails
+ call SetWasUnsuccessful
+ bank1call DrawDuelMainScene
+ bank1call Func_1bca
+ call WaitForWideTextBoxInput
+ ret
+
+.heads
+ call ParalysisEffect
+ ldh a, [hTempPlayAreaLocation_ff9d]
+ ld b, a
+ ld c, $00
+ ldh a, [hWhoseTurn]
+ ld h, a
+ bank1call PlayAttackAnimation
+ bank1call Func_741a
+ bank1call WaitAttackAnimation
+ bank1call Func_6df1
+ bank1call DrawDuelHUDs
+ bank1call Func_1bca
+ call c, WaitForWideTextBoxInput
+ ret
+
+IceBreath_ZeroDamage: ; 2d329 (b:5329)
+ xor a
+ call SetDefiniteDamage
+ ret
+
+IceBreath_RandomPokemonDamageEffect: ; 2d32e (b:532e)
+ call SwapTurn
+ call PickRandomPlayAreaCard
+ ld b, a
+ ld de, 40
+ call DealDamageToPlayAreaPokemon_RegularAnim
+ call SwapTurn
+ ret
+
+FocusEnergyEffect: ; 2d33f (b:533f)
+ ld a, [wTempTurnDuelistCardID]
+ cp VAPOREON1
+ ret nz ; return if no Vaporeon1
+ ld a, SUBSTATUS1_NEXT_TURN_DOUBLE_DAMAGE
+ call ApplySubstatus1ToDefendingCard
+ ret
+
+PlayerPickFireEnergyCardToDiscard: ; 2d34b (b:534b)
+ call CreateListOfFireEnergyAttachedToArena
+ xor a
+ bank1call DisplayEnergyDiscardScreen
+ bank1call HandleEnergyDiscardMenuInput
+ ldh a, [hTempCardIndex_ff98]
+ ldh [hTempList], a
+ ret
+
+AIPickFireEnergyCardToDiscard: ; 2d35a (b:535a)
+ call CreateListOfFireEnergyAttachedToArena
+ ld a, [wDuelTempList]
+ ldh [hTempList], a ; pick first in list
+ ret
+
+; returns carry if Arena card has no Fire Energy cards
+ArcanineFlamethrower_CheckEnergy: ; 2d363 (b:5363)
+ ld e, PLAY_AREA_ARENA
+ call GetPlayAreaCardAttachedEnergies
+ ld a, [wAttachedEnergies]
+ ldtx hl, NotEnoughFireEnergyText
+ cp 1
+ ret
+
+ArcanineFlamethrower_PlayerSelectEffect: ; 2d371 (b:5371)
+ call PlayerPickFireEnergyCardToDiscard
+ ret
+
+ArcanineFlamethrower_AISelectEffect: ; 2d375 (b:5375)
+ call AIPickFireEnergyCardToDiscard
+ ret
+
+ArcanineFlamethrower_DiscardEffect: ; 2d379 (b:5379)
+ ldh a, [hTempList]
+ call PutCardInDiscardPile
+ ret
+
+TakeDownEffect: ; 2d37f (b:537f)
+ ld a, 30
+ call DealRecoilDamageToSelf
+ ret
+
+ArcanineQuickAttack_AIEffect: ; 2d385 (b:5385)
+ ld a, (10 + 30) / 2
+ lb de, 10, 30
+ jp SetExpectedAIDamage
+
+ArcanineQuickAttack_DamageBoostEffect: ; 2d38d (b:538d)
+ ld hl, 20
+ call LoadTxRam3
+ ldtx de, DamageCheckIfHeadsPlusDamageText
+ call TossCoin_BankB
+ ret nc ; return if tails
+ ld a, 20
+ call AddToDamage
+ ret
+
+; return carry if has less than 2 Fire Energy cards
+FlamesOfRage_CheckEnergy: ; 2d3a0 (b:53a0)
+ ld e, PLAY_AREA_ARENA
+ call GetPlayAreaCardAttachedEnergies
+ ld a, [wAttachedEnergies]
+ ldtx hl, NotEnoughFireEnergyText
+ cp 2
+ ret
+
+FlamesOfRage_PlayerSelectEffect: ; 2d3ae (b:53ae)
+ ldtx hl, ChooseAndDiscard2FireEnergyCardsText
+ call DrawWideTextBox_WaitForInput
+
+ xor a
+ ldh [hCurSelectionItem], a
+ call CreateListOfFireEnergyAttachedToArena
+ xor a
+ bank1call DisplayEnergyDiscardScreen
+.loop_input
+ bank1call HandleEnergyDiscardMenuInput
+ ret c
+ call GetNextPositionInTempList
+ ldh a, [hTempCardIndex_ff98]
+ ld [hl], a
+ call RemoveCardFromDuelTempList
+ ldh a, [hCurSelectionItem]
+ cp 2
+ ret nc ; return when 2 have been chosen
+ bank1call DisplayEnergyDiscardMenu
+ jr .loop_input
+
+FlamesOfRage_AISelectEffect: ; 2d3d5 (b:53d5)
+ call AIPickFireEnergyCardToDiscard
+ ld a, [wDuelTempList + 1]
+ ldh [hTempList + 1], a
+ ret
+
+FlamesOfRage_DiscardEffect: ; 2d3de (b:53de)
+ ldh a, [hTempList]
+ call PutCardInDiscardPile
+ ldh a, [hTempList + 1]
+ call PutCardInDiscardPile
+ ret
+
+FlamesOfRage_AIEffect: ; 2d3e9 (b:53e9)
+ call FlamesOfRage_DamageBoostEffect
+ jp SetDefiniteAIDamage
+
+FlamesOfRage_DamageBoostEffect: ; 2d3ef (b:53ef)
+ ld e, PLAY_AREA_ARENA
+ call GetCardDamageAndMaxHP
+ call AddToDamage
+ ret
+
+RapidashStomp_AIEffect: ; 2d3f8 (b:53f8)
+ ld a, (20 + 30) / 2
+ lb de, 20, 30
+ jp SetExpectedAIDamage
+
+RapidashStomp_DamageBoostEffect: ; 2d400 (b:5400)
+ ld hl, 10
+ call LoadTxRam3
+ ldtx de, DamageCheckIfHeadsPlusDamageText
+ call TossCoin_BankB
+ ret nc ; return if tails
+ ld a, 10
+ call AddToDamage
+ ret
+
+RapidashAgilityEffect: ; 2d413 (b:5413)
+ ldtx de, IfHeadsDoNotReceiveDamageOrEffectText
+ call TossCoin_BankB
+ ret nc ; return if tails
+ ld a, ATK_ANIM_AGILITY_PROTECT
+ ld [wLoadedAttackAnimation], a
+ ld a, SUBSTATUS1_AGILITY
+ call ApplySubstatus1ToDefendingCard
+ ret
+
+; returns carry if Opponent has no Pokemon in bench
+NinetalesLure_CheckBench: ; 2d425 (b:5425)
+ ld a, DUELVARS_NUMBER_OF_POKEMON_IN_PLAY_AREA
+ call GetNonTurnDuelistVariable
+ ldtx hl, EffectNoPokemonOnTheBenchText
+ cp 2
+ ret
+
+NinetalesLure_PlayerSelectEffect: ; 2d430 (b:5430)
+ ldtx hl, SelectPkmnOnBenchToSwitchWithActiveText
+ call DrawWideTextBox_WaitForInput
+ call SwapTurn
+ bank1call HasAlivePokemonInBench
+.loop_input
+ bank1call OpenPlayAreaScreenForSelection
+ jr c, .loop_input
+ ldh a, [hTempPlayAreaLocation_ff9d]
+ ldh [hTemp_ffa0], a
+ call SwapTurn
+ ret
+
+NinetalesLure_AISelectEffect: ; 2d449 (b:5449)
+ call GetBenchPokemonWithLowestHP
+ ldh [hTemp_ffa0], a
+ ret
+
+NinetalesLure_SwitchEffect: ; 2d44f (b:544f)
+ call SwapTurn
+ ldh a, [hTemp_ffa0]
+ ld e, a
+ call HandleNShieldAndTransparency
+ call nc, SwapArenaWithBenchPokemon
+ call SwapTurn
+ xor a
+ ld [wDuelDisplayedScreen], a
+ ret
+
+; return carry if no Fire energy cards
+FireBlast_CheckEnergy: ; 2d463 (b:5463)
+ ld e, PLAY_AREA_ARENA
+ call GetPlayAreaCardAttachedEnergies
+ ldtx hl, NotEnoughFireEnergyText
+ ld a, [wAttachedEnergies]
+ cp 1
+ ret
+
+FireBlast_PlayerSelectEffect: ; 2d471 (b:5471)
+ call PlayerPickFireEnergyCardToDiscard
+ ret
+
+FireBlast_AISelectEffect: ; 2d475 (b:5475)
+ call AIPickFireEnergyCardToDiscard
+ ret
+
+FireBlast_DiscardEffect: ; 2d479 (b:5479)
+ ldh a, [hTempList]
+ call PutCardInDiscardPile
+ ret
+
+; return carry if no Fire energy cards
+Ember_CheckEnergy: ; 2d47f (b:547f)
+ ld e, PLAY_AREA_ARENA
+ call GetPlayAreaCardAttachedEnergies
+ ldtx hl, NotEnoughFireEnergyText
+ ld a, [wAttachedEnergies]
+ cp 1
+ ret
+
+Ember_PlayerSelectEffect: ; 2d48d (b:548d)
+ call PlayerPickFireEnergyCardToDiscard
+ ret
+
+Ember_AISelectEffect: ; 2d491 (b:5491)
+ call AIPickFireEnergyCardToDiscard
+ ret
+
+Ember_DiscardEffect: ; 2d495 (b:5495)
+ ldh a, [hTempList]
+ call PutCardInDiscardPile
+ ret
+
+; return carry if no Fire energy cards
+Wildfire_CheckEnergy: ; 2d49b (b:549b)
+ ld e, PLAY_AREA_ARENA
+ call GetPlayAreaCardAttachedEnergies
+ ldtx hl, NotEnoughFireEnergyText
+ ld a, [wAttachedEnergies]
+ cp 1
+ ret
+
+Wildfire_PlayerSelectEffect: ; 2d4a9 (b:54a9)
+ ldtx hl, DiscardOppDeckAsManyFireEnergyCardsText
+ call DrawWideTextBox_WaitForInput
+
+ xor a
+ ldh [hCurSelectionItem], a
+ call CreateListOfFireEnergyAttachedToArena
+ xor a
+ bank1call DisplayEnergyDiscardScreen
+
+; show list to Player and for each card selected to discard,
+; just increase a counter and store it.
+; this will be the output used by Wildfire_DiscardEnergyEffect.
+ xor a
+ ld [wEnergyDiscardMenuDenominator], a
+.loop
+ ldh a, [hCurSelectionItem]
+ ld [wEnergyDiscardMenuNumerator], a
+ bank1call HandleEnergyDiscardMenuInput
+ jr c, .done
+ ld hl, hCurSelectionItem
+ inc [hl]
+ call RemoveCardFromDuelTempList
+ jr c, .done
+ bank1call DisplayEnergyDiscardMenu
+ jr .loop
+
+.done
+; return carry if no cards were discarded
+; output the result in hTemp_ffa0
+ ldh a, [hCurSelectionItem]
+ ldh [hTemp_ffa0], a
+ or a
+ ret nz
+ scf
+ ret
+
+Wildfire_AISelectEffect: ; 2d4dd (b:54dd)
+; AI always chooses 0 cards to discard
+ xor a
+ ldh [hTempList], a
+ ret
+
+Wildfire_DiscardEnergyEffect: ; 2d4e1 (b:54e1)
+ call CreateListOfFireEnergyAttachedToArena
+ ldh a, [hTemp_ffa0]
+ or a
+ ret z ; no cards to discard
+
+; discard cards from wDuelTempList equal to the number
+; of cards that were input in hTemp_ffa0.
+; these are all the Fire Energy cards attached to Arena card
+; so it will discard the cards in order, regardless
+; of the actual order that was selected by Player.
+ ld c, a
+ ld hl, wDuelTempList
+.loop_discard
+ ld a, [hli]
+ call PutCardInDiscardPile
+ dec c
+ jr nz, .loop_discard
+ ret
+
+Wildfire_DiscardDeckEffect: ; 2d4f4 (b:54f4)
+ ldh a, [hTemp_ffa0]
+ ld c, a
+ ld b, $00
+ call SwapTurn
+ ld a, DUELVARS_NUMBER_OF_CARDS_NOT_IN_DECK
+ call GetTurnDuelistVariable
+ ld a, DECK_SIZE
+ sub [hl]
+ cp c
+ jr nc, .start_discard
+ ; only discard number of cards that are left in deck
+ ld c, a
+
+.start_discard
+ push bc
+ inc c
+ jr .check_remaining
+
+.loop
+ ; discard top card from deck
+ call DrawCardFromDeck
+ call nc, PutCardInDiscardPile
+.check_remaining
+ dec c
+ jr nz, .loop
+
+ pop hl
+ call LoadTxRam3
+ ldtx hl, DiscardedCardsFromDeckText
+ call DrawWideTextBox_PrintText
+ call SwapTurn
+ ret
+
+Moltres1DiveBomb_AIEffect: ; 2d523 (b:5523)
+ ld a, 80 / 2
+ lb de, 0, 80
+ jp SetExpectedAIDamage
+
+Moltres1DiveBomb_Success50PercentEffect: ; 2d52b (b:552b)
+ ldtx de, SuccessCheckIfHeadsAttackIsSuccessfulText
+ call TossCoin_BankB
+ jr c, .heads
+; tails
+ xor a
+ call SetDefiniteDamage
+ call SetWasUnsuccessful
+ ret
+.heads
+ ld a, ATK_ANIM_DIVE_BOMB
+ ld [wLoadedAttackAnimation], a
+ ret
+
+FlareonQuickAttack_AIEffect: ; 2d541 (b:5541)
+ ld a, (10 + 30) / 2
+ lb de, 10, 30
+ jp SetExpectedAIDamage
+
+FlareonQuickAttack_DamageBoostEffect: ; 2d549 (b:5549)
+ ld hl, 20
+ call LoadTxRam3
+ ldtx de, DamageCheckIfHeadsPlusDamageText
+ call TossCoin_BankB
+ ret nc ; return if tails
+ ld a, 20
+ call AddToDamage
+ ret
+
+; return carry if no Fire Energy attached
+FlareonFlamethrower_CheckEnergy: ; 2d55c (b:555c)
+ ld e, PLAY_AREA_ARENA
+ call GetPlayAreaCardAttachedEnergies
+ ldtx hl, NotEnoughFireEnergyText
+ ld a, [wAttachedEnergies]
+ cp 1
+ ret
+
+FlareonFlamethrower_PlayerSelectEffect: ; 2d56a (b:556a)
+ call PlayerPickFireEnergyCardToDiscard
+ ret
+
+FlareonFlamethrower_AISelectEffect: ; 2d56e (b:556e)
+ call AIPickFireEnergyCardToDiscard
+ ret
+
+FlareonFlamethrower_DiscardEffect: ; 2d572 (b:5572)
+ ldh a, [hTempList]
+ call PutCardInDiscardPile
+ ret
+
+; return carry if no Fire Energy attached
+MagmarFlamethrower_CheckEnergy: ; 2d578 (b:5578)
+ ld e, PLAY_AREA_ARENA
+ call GetPlayAreaCardAttachedEnergies
+ ldtx hl, NotEnoughFireEnergyText
+ ld a, [wAttachedEnergies]
+ cp 1
+ ret
+
+MagmarFlamethrower_PlayerSelectEffect: ; 2d586 (b:5586)
+ call PlayerPickFireEnergyCardToDiscard
+ ret
+
+MagmarFlamethrower_AISelectEffect: ; 2d58a (b:558a)
+ call AIPickFireEnergyCardToDiscard
+ ret
+
+MagmarFlamethrower_DiscardEffect: ; 2d58e (b:558e)
+ ldh a, [hTempList]
+ call PutCardInDiscardPile
+ ret
+
+MagmarSmokescreenEffect: ; 2d594 (b:5594)
+ ld a, SUBSTATUS2_SMOKESCREEN
+ call ApplySubstatus2ToDefendingCard
+ ret
+
+MagmarSmog_AIEffect: ; 2d59a (b:559a)
+ ld a, 5
+ lb de, 0, 10
+ jp UpdateExpectedAIDamage_AccountForPoison
+
+; return carry if no Fire Energy attached
+CharmeleonFlamethrower_CheckEnergy: ; 2d5a2 (b:55a2)
+ ld e, PLAY_AREA_ARENA
+ call GetPlayAreaCardAttachedEnergies
+ ldtx hl, NotEnoughFireEnergyText
+ ld a, [wAttachedEnergies]
+ cp 1
+ ret
+
+CharmeleonFlamethrower_PlayerSelectEffect: ; 2d5b0 (b:55b0)
+ call PlayerPickFireEnergyCardToDiscard
+ ret
+
+CharmeleonFlamethrower_AISelectEffect: ; 2d5b4 (b:55b4)
+ call AIPickFireEnergyCardToDiscard
+ ret
+
+CharmeleonFlamethrower_DiscardEffect: ; 2d5b8 (b:55b8)
+ ldh a, [hTempList]
+ call PutCardInDiscardPile
+ ret
+
+EnergyBurnEffect: ; 2d5be (b:55be)
+ scf
+ ret
+
+; return carry if has less than 2 Fire Energy cards
+FireSpin_CheckEnergy: ; 2d5c0 (b:55c0)
+ xor a ; PLAY_AREA_ARENA
+ call CreateArenaOrBenchEnergyCardList
+ call CountCardsInDuelTempList
+ ldtx hl, NotEnoughEnergyCardsText
+ cp 2
+ ret
+
+FireSpin_PlayerSelectEffect: ; 2d5cd (b:55cd)
+ ldtx hl, ChooseAndDiscard2EnergyCardsText
+ call DrawWideTextBox_WaitForInput
+
+ xor a
+ ldh [hCurSelectionItem], a
+ xor a
+ call CreateArenaOrBenchEnergyCardList
+ call SortCardsInDuelTempListByID
+ xor a
+ bank1call DisplayEnergyDiscardScreen
+
+ ld a, 2
+ ld [wEnergyDiscardMenuDenominator], a
+.loop_input
+ bank1call HandleEnergyDiscardMenuInput
+ ret c
+ call GetNextPositionInTempList
+ ldh a, [hTempCardIndex_ff98]
+ ld [hl], a
+ ld hl, wEnergyDiscardMenuNumerator
+ inc [hl]
+ ldh a, [hCurSelectionItem]
+ cp 2
+ jr nc, .done
+ ldh a, [hTempCardIndex_ff98]
+ call RemoveCardFromDuelTempList
+ bank1call DisplayEnergyDiscardMenu
+ jr .loop_input
+.done
+; return when 2 have been chosen
+ or a
+ ret
+
+FireSpin_AISelectEffect: ; 2d606 (b:5606)
+ xor a ; PLAY_AREA_ARENA
+ call CreateArenaOrBenchEnergyCardList
+ ld hl, wDuelTempList
+ ld a, [hli]
+ ldh [hTempList], a
+ ld a, [hl]
+ ldh [hTempList + 1], a
+ ret
+
+FireSpin_DiscardEffect: ; 2d614 (b:5614)
+ ld hl, hTempList
+ ld a, [hli]
+ call PutCardInDiscardPile
+ ld a, [hli]
+ call PutCardInDiscardPile
+ ret
+
+; returns carry if Pkmn Power cannot be used
+; or if Arena card is not Charizard.
+; this is unused.
+EnergyBurnCheck_Unreferenced: ; 2d620 (b:5620)
+ xor a
+ bank1call CheckCannotUseDueToStatus_OnlyToxicGasIfANon0
+ ret c
+ ld a, DUELVARS_ARENA_CARD
+ push de
+ call GetTurnDuelistVariable
+ call GetCardIDFromDeckIndex
+ ld a, e
+ pop de
+ cp CHARIZARD
+ jr nz, .not_charizard
+ or a
+ ret
+.not_charizard
+ scf
+ ret
+
+FlareonRage_AIEffect: ; 2d638 (b:5638)
+ call FlareonRage_DamageBoostEffect
+ jp SetDefiniteAIDamage
+
+FlareonRage_DamageBoostEffect: ; 2d63e (b:563e)
+ ld e, PLAY_AREA_ARENA
+ call GetCardDamageAndMaxHP
+ call AddToDamage
+ ret
+
+MixUpEffect: ; 2d647 (b:5647)
+ call SwapTurn
+ call CreateHandCardList
+ call SortCardsInDuelTempListByID
+
+; first go through Hand to place
+; all Pkmn cards in it in the Deck.
+ ld hl, wDuelTempList
+ ld c, 0
+.loop_hand
+ ld a, [hl]
+ cp $ff
+ jr z, .done_hand
+ call .CheckIfCardIsPkmnCard
+ jr nc, .next_hand
+ ; found Pkmn card, place in deck
+ inc c
+ ld a, [hl]
+ call RemoveCardFromHand
+ call ReturnCardToDeck
+.next_hand
+ inc hl
+ jr .loop_hand
+
+.done_hand
+ ld a, c
+ ldh [hCurSelectionItem], a
+ push bc
+ ldtx hl, ThePkmnCardsInHandAndDeckWereShuffledText
+ call DrawWideTextBox_WaitForInput
+
+ call Func_2c0bd
+ call CreateDeckCardList
+ pop bc
+ ldh a, [hCurSelectionItem]
+ or a
+ jr z, .done ; if no cards were removed from Hand, return
+
+; c holds the number of cards that were placed in the Deck.
+; now pick Pkmn cards from the Deck to place in Hand.
+ ld hl, wDuelTempList
+.loop_deck
+ ld a, [hl]
+ call .CheckIfCardIsPkmnCard
+ jr nc, .next_deck
+ dec c
+ ld a, [hl]
+ call SearchCardInDeckAndAddToHand
+ call AddCardToHand
+.next_deck
+ inc hl
+ ld a, c
+ or a
+ jr nz, .loop_deck
+.done
+ call SwapTurn
+ ret
+
+; returns carry if card index in a is Pkmn card
+.CheckIfCardIsPkmnCard: ; 2d69a (b:569a)
+ call LoadCardDataToBuffer2_FromDeckIndex
+ ld a, [wLoadedCard2Type]
+ cp TYPE_ENERGY
+ ret
+
+DancingEmbers_AIEffect: ; 2d6a3 (b:56a3)
+ ld a, 80 / 2
+ lb de, 0, 80
+ jp SetExpectedAIDamage
+
+DancingEmbers_MultiplierEffect: ; 2d6ab (b:56ab)
+ ld hl, 10
+ call LoadTxRam3
+ ldtx de, DamageCheckIfHeadsXDamageText
+ ld a, 8
+ call TossCoinATimes_BankB
+ call ATimes10
+ call SetDefiniteDamage
+ ret
+
+Firegiver_InitialEffect: ; 2d6c0 (b:56c0)
+ scf
+ ret
+
+Firegiver_AddToHandEffect: ; 2d6c2 (b:56c2)
+; fill wDuelTempList with all Fire Energy card
+; deck indices that are in the Deck.
+ ld a, DUELVARS_CARD_LOCATIONS
+ call GetTurnDuelistVariable
+ ld de, wDuelTempList
+ ld c, 0
+.loop_cards
+ ld a, [hl]
+ cp CARD_LOCATION_DECK
+ jr nz, .next
+ push hl
+ push de
+ ld a, l
+ call GetCardIDFromDeckIndex
+ call GetCardType
+ pop de
+ pop hl
+ cp TYPE_ENERGY_FIRE
+ jr nz, .next
+ ld a, l
+ ld [de], a
+ inc de
+ inc c
+.next
+ inc l
+ ld a, l
+ cp DECK_SIZE
+ jr c, .loop_cards
+ ld a, $ff
+ ld [de], a
+
+; check how many were found
+ ld a, c
+ or a
+ jr nz, .found
+ ; return if none found
+ ldtx hl, ThereWasNoFireEnergyText
+ call DrawWideTextBox_WaitForInput
+ call Func_2c0bd
+ ret
+
+.found
+; pick a random number between 1 and 4,
+; up to the maximum number of Fire Energy
+; cards that were found.
+ ld a, 4
+ call Random
+ inc a
+ cp c
+ jr c, .ok
+ ld a, c
+
+.ok
+ ldh [hCurSelectionItem], a
+; load correct attack animation depending
+; on what side the effect is from.
+ ld d, ATK_ANIM_FIREGIVER_PLAYER
+ ld a, [wDuelistType]
+ cp DUELIST_TYPE_PLAYER
+ jr z, .player_1
+; opponent
+ ld d, ATK_ANIM_FIREGIVER_OPP
+.player_1
+ ld a, d
+ ld [wLoadedAttackAnimation], a
+
+; start loop for adding Energy cards to hand
+ ldh a, [hCurSelectionItem]
+ ld c, a
+ ld hl, wDuelTempList
+.loop_energy
+ push hl
+ push bc
+ ld bc, $0
+ ldh a, [hWhoseTurn]
+ ld h, a
+ bank1call PlayAttackAnimation
+ bank1call WaitAttackAnimation
+
+; load correct coordinates to update the number of cards
+; in hand and deck during animation.
+ lb bc, 18, 7 ; x, y for hand number
+ ld e, 3 ; y for deck number
+ ld a, [wLoadedAttackAnimation]
+ cp ATK_ANIM_FIREGIVER_PLAYER
+ jr z, .player_2
+ lb bc, 4, 5 ; x, y for hand number
+ ld e, 10 ; y for deck number
+
+.player_2
+; update and print number of cards in hand
+ ld a, DUELVARS_NUMBER_OF_CARDS_IN_HAND
+ call GetTurnDuelistVariable
+ inc a
+ bank1call WriteTwoDigitNumberInTxSymbolFormat
+; update and print number of cards in deck
+ ld a, DUELVARS_NUMBER_OF_CARDS_NOT_IN_DECK
+ call GetTurnDuelistVariable
+ ld a, DECK_SIZE - 1
+ sub [hl]
+ ld c, e
+ bank1call WriteTwoDigitNumberInTxSymbolFormat
+
+; load Fire Energy card index and add to hand
+ pop bc
+ pop hl
+ ld a, [hli]
+ call SearchCardInDeckAndAddToHand
+ call AddCardToHand
+ dec c
+ jr nz, .loop_energy
+
+; load the number of cards added to hand and print text
+ ldh a, [hCurSelectionItem]
+ ld l, a
+ ld h, $00
+ call LoadTxRam3
+ ldtx hl, DrewFireEnergyFromTheHandText
+ call DrawWideTextBox_WaitForInput
+ call Func_2c0bd
+ ret
+
+Moltres2DiveBomb_AIEffect: ; 2d76e (b:576e)
+ ld a, 70 / 2
+ lb de, 0, 70
+ jp SetExpectedAIDamage
+
+Moltres2DiveBomb_Success50PercentEffect: ; 2d776 (b:5776)
+ ldtx de, SuccessCheckIfHeadsAttackIsSuccessfulText
+ call TossCoin_BankB
+ jr c, .heads
+; tails
+ xor a
+ call SetDefiniteDamage
+ call SetWasUnsuccessful
+ ret
+.heads
+ ld a, ATK_ANIM_DIVE_BOMB
+ ld [wLoadedAttackAnimation], a
+ ret
+
+; output in de the number of energy cards
+; attached to the Defending Pokemon times 10.
+; used for attacks that deal 10x number of energy
+; cards attached to the Defending card.
+GetEnergyAttachedMultiplierDamage: ; 2d78c (b:578c)
+ call SwapTurn
+ ld a, DUELVARS_CARD_LOCATIONS
+ call GetTurnDuelistVariable
+
+ ld c, 0
+.loop
+ ld a, [hl]
+ cp CARD_LOCATION_ARENA
+ jr nz, .next
+ ; is in Arena
+ ld a, l
+ call GetCardIDFromDeckIndex
+ call GetCardType
+ and TYPE_ENERGY
+ jr z, .next
+ ; is Energy attached to Arena card
+ inc c
+.next
+ inc l
+ ld a, l
+ cp DECK_SIZE
+ jr c, .loop
+
+ call SwapTurn
+ ld l, c
+ ld h, $00
+ ld b, $00
+ add hl, hl ; hl = 2 * c
+ add hl, hl ; hl = 4 * c
+ add hl, bc ; hl = 5 * c
+ add hl, hl ; hl = 10 * c
+ ld e, l
+ ld d, h
+ ret
+
+; draws list of Energy Cards in Discard Pile
+; for Player to select from.
+; the Player can select up to 2 cards from the list.
+; these cards are given in $ff-terminated list
+; in hTempList.
+HandleEnergyCardsInDiscardPileSelection: ; 2d7bc (b:57bc)
+ push hl
+ xor a
+ ldh [hCurSelectionItem], a
+ call CreateEnergyCardListFromDiscardPile_AllEnergy
+ pop hl
+ jr c, .finish
+
+ call DrawWideTextBox_WaitForInput
+.loop
+; draws Discard Pile screen and textbox,
+; and handles Player input
+ bank1call InitAndDrawCardListScreenLayout
+ ldtx hl, ChooseAnEnergyCardText
+ ldtx de, PlayerDiscardPileText
+ bank1call SetCardListHeaderText
+ bank1call DisplayCardList
+ jr nc, .selected
+
+; Player is trying to exit screen,
+; but can select up to 2 cards total.
+; prompt Player to confirm exiting screen.
+ ld a, 2
+ call AskWhetherToQuitSelectingCards
+ jr c, .loop
+ jr .finish
+
+.selected
+; a card was selected, so add it to list
+ call GetNextPositionInTempList
+ ldh a, [hTempCardIndex_ff98]
+ ld [hl], a
+ call RemoveCardFromDuelTempList
+ or a
+ jr z, .finish ; no more cards?
+ ldh a, [hCurSelectionItem]
+ cp 2
+ jr c, .loop ; already selected 2 cards?
+
+.finish
+; place terminating byte on list
+ call GetNextPositionInTempList
+ ld [hl], $ff
+ or a
+ ret
+
+; returns carry if Pkmn Power cannot be used, and
+; sets the correct text in hl for failure.
+Curse_CheckDamageAndBench: ; 2d7fc (b:57fc)
+ ldh a, [hTempPlayAreaLocation_ff9d]
+ ldh [hTemp_ffa0], a
+
+; fail if Pkmn Power has already been used
+ add DUELVARS_ARENA_CARD_FLAGS
+ call GetTurnDuelistVariable
+ ldtx hl, OnlyOncePerTurnText
+ and USED_PKMN_POWER_THIS_TURN
+ jr nz, .set_carry
+
+; fail if Opponent only has 1 Pokemon in Play Area
+ call SwapTurn
+ ld a, DUELVARS_NUMBER_OF_POKEMON_IN_PLAY_AREA
+ call GetTurnDuelistVariable
+ call SwapTurn
+ ldtx hl, CannotUseSinceTheresOnly1PkmnText
+ cp 2
+ jr c, .set_carry
+
+; fail if Opponent has no damage counters
+ call SwapTurn
+ call CheckIfPlayAreaHasAnyDamage
+ call SwapTurn
+ ldtx hl, NoPokemonWithDamageCountersText
+ jr c, .set_carry
+
+; return carry if Pkmn Power cannot be used due
+; to Toxic Gas or status.
+ ldh a, [hTempPlayAreaLocation_ff9d]
+ call CheckCannotUseDueToStatus_OnlyToxicGasIfANon0
+ ret
+
+.set_carry
+ scf
+ ret
+
+Curse_PlayerSelectEffect: ; 2d834 (b:5834)
+ ldtx hl, ProcedureForCurseText
+ bank1call DrawWholeScreenTextBox
+ call SwapTurn
+ xor a
+ ldh [hCurSelectionItem], a
+ bank1call Func_61a1
+.start
+ bank1call PrintPlayAreaCardList_EnableLCD
+ push af
+ ldh a, [hCurSelectionItem]
+ ld hl, PlayAreaSelectionMenuParameters
+ call InitializeMenuParameters
+ pop af
+ ld [wNumMenuItems], a
+
+; first pick a target to take 1 damage counter from.
+.loop_input_first
+ call DoFrame
+ call HandleMenuInput
+ jr nc, .loop_input_first
+ cp $ff
+ jr z, .cancel
+ ldh [hCurSelectionItem], a
+ ldh [hTempPlayAreaLocation_ffa1], a
+ call GetCardDamageAndMaxHP
+ or a
+ jr nz, .picked_first ; test if has damage
+ ; play sfx
+ call Func_3794
+ jr .loop_input_first
+
+.picked_first
+; give 10 HP to card selected, draw the scene,
+; then immediately revert this.
+ ldh a, [hTempPlayAreaLocation_ffa1]
+ add DUELVARS_ARENA_CARD_HP
+ call GetTurnDuelistVariable
+ push af
+ push hl
+ add 10
+ ld [hl], a
+ bank1call PrintPlayAreaCardList_EnableLCD
+ pop hl
+ pop af
+ ld [hl], a
+
+; draw damage counter on cursor
+ ldh a, [hTempPlayAreaLocation_ffa1]
+ ld b, SYM_HP_NOK
+ call DrawSymbolOnPlayAreaCursor
+
+; handle input to pick the target to receive the damage counter.
+.loop_input_second
+ call DoFrame
+ call HandleMenuInput
+ jr nc, .loop_input_second
+ ldh [hPlayAreaEffectTarget], a
+ cp $ff
+ jr nz, .a_press ; was a pressed?
+
+; b press
+; erase the damage counter symbol
+; and loop back up again.
+ ldh a, [hTempPlayAreaLocation_ffa1]
+ ld b, SYM_SPACE
+ call DrawSymbolOnPlayAreaCursor
+ call EraseCursor
+ jr .start
+
+.a_press
+ ld hl, hTempPlayAreaLocation_ffa1
+ cp [hl]
+ jr z, .loop_input_second ; same as first?
+; a different Pokemon was picked,
+; so store this Play Area location
+; and erase the damage counter in the cursor.
+ ldh a, [hTempPlayAreaLocation_ffa1]
+ ld b, SYM_SPACE
+ call DrawSymbolOnPlayAreaCursor
+ call EraseCursor
+ call SwapTurn
+ or a
+ ret
+
+.cancel
+; return carry if operation was cancelled.
+ call SwapTurn
+ scf
+ ret
+
+Curse_TransferDamageEffect: ; 2d8bb (b:58bb)
+; set Pkmn Power as used
+ ldh a, [hTempList]
+ add DUELVARS_ARENA_CARD_FLAGS
+ call GetTurnDuelistVariable
+ set USED_PKMN_POWER_THIS_TURN_F, [hl]
+
+; figure out the type of duelist that used Curse.
+; if it was the player, no need to draw the Play Area screen.
+ call SwapTurn
+ ld a, DUELVARS_DUELIST_TYPE
+ call GetNonTurnDuelistVariable
+ cp DUELIST_TYPE_PLAYER
+ jr z, .vs_player
+
+; vs. opponent
+ bank1call Func_61a1
+.vs_player
+; transfer the damage counter to the targets that were selected.
+ ldh a, [hPlayAreaEffectTarget]
+ add DUELVARS_ARENA_CARD_HP
+ call GetTurnDuelistVariable
+ sub 10
+ ld [hl], a
+ ldh a, [hTempPlayAreaLocation_ffa1]
+ add DUELVARS_ARENA_CARD_HP
+ ld l, a
+ ld a, 10
+ add [hl]
+ ld [hl], a
+
+ bank1call PrintPlayAreaCardList_EnableLCD
+ ld a, DUELVARS_DUELIST_TYPE
+ call GetNonTurnDuelistVariable
+ cp DUELIST_TYPE_PLAYER
+ jr z, .done
+; vs. opponent
+ ldh a, [hPlayAreaEffectTarget]
+ ldh [hTempPlayAreaLocation_ff9d], a
+ bank1call Func_6194
+
+.done
+ call SwapTurn
+ call ExchangeRNG
+ bank1call Func_6e49
+ ret
+
+GengarDarkMind_PlayerSelectEffect: ; 2d903 (b:5903)
+ ld a, DUELVARS_NUMBER_OF_POKEMON_IN_PLAY_AREA
+ call GetNonTurnDuelistVariable
+ cp 2
+ jr nc, .has_bench
+; no bench Pokemon to damage.
+ ld a, $ff
+ ldh [hTemp_ffa0], a
+ ret
+
+.has_bench
+; opens Play Area screen to select Bench Pokemon
+; to damage, and store it before returning.
+ ldtx hl, ChoosePkmnInTheBenchToGiveDamageText
+ call DrawWideTextBox_WaitForInput
+ call SwapTurn
+ bank1call HasAlivePokemonInBench
+.loop_input
+ bank1call OpenPlayAreaScreenForSelection
+ jr c, .loop_input
+ ldh a, [hTempPlayAreaLocation_ff9d]
+ ldh [hTemp_ffa0], a
+ call SwapTurn
+ ret
+
+GengarDarkMind_AISelectEffect: ; 2d92a (b:592a)
+ ld a, $ff
+ ldh [hTemp_ffa0], a
+ ld a, DUELVARS_NUMBER_OF_POKEMON_IN_PLAY_AREA
+ call GetNonTurnDuelistVariable
+ cp 2
+ ret c ; return if no Bench Pokemon
+; just pick Pokemon with lowest remaining HP.
+ call GetBenchPokemonWithLowestHP
+ ldh [hTemp_ffa0], a
+ ret
+
+GengarDarkMind_DamageBenchEffect: ; 2d93c (b:593c)
+ ldh a, [hTemp_ffa0]
+ cp $ff
+ ret z ; no target chosen
+ call SwapTurn
+ ld b, a
+ ld de, 10
+ call DealDamageToPlayAreaPokemon_RegularAnim
+ call SwapTurn
+ ret
+
+SleepingGasEffect: ; 2d94f (b:594f)
+ call Sleep50PercentEffect
+ call nc, SetNoEffectFromStatus
+ ret
+
+DestinyBond_CheckEnergy: ; 2d956 (b:5956)
+ ld e, PLAY_AREA_ARENA
+ call GetPlayAreaCardAttachedEnergies
+ ld a, [wAttachedEnergies + PSYCHIC]
+ ldtx hl, NotEnoughPsychicEnergyText
+ cp 1
+ ret
+
+DestinyBond_PlayerSelectEffect: ; 2d964 (b:5964)
+; handle input and display of Energy card list
+ ld a, TYPE_ENERGY_PSYCHIC
+ call CreateListOfEnergyAttachedToArena
+ xor a
+ bank1call DisplayEnergyDiscardScreen
+ bank1call HandleEnergyDiscardMenuInput
+ ret c
+ ldh a, [hTempCardIndex_ff98]
+ ldh [hTempList], a
+ ret
+
+DestinyBond_AISelectEffect: ; 2d976 (b:5976)
+; pick first card in list
+ ld a, TYPE_ENERGY_PSYCHIC
+ call CreateListOfEnergyAttachedToArena
+ ld a, [wDuelTempList]
+ ldh [hTempList], a
+ ret
+
+DestinyBond_DiscardEffect: ; 2d981 (b:5981)
+ ldh a, [hTempList]
+ call PutCardInDiscardPile
+ ret
+
+DestinyBond_DestinyBondEffect: ; 2d987 (b:5987)
+ ld a, SUBSTATUS1_DESTINY_BOND
+ call ApplySubstatus1ToDefendingCard
+ ret
+
+; returns carry if no Energy cards in Discard Pile.
+EnergyConversion_CheckEnergy: ; 2d98d (b:598d)
+ call CreateEnergyCardListFromDiscardPile_AllEnergy
+ ldtx hl, ThereAreNoEnergyCardsInDiscardPileText
+ ret
+
+EnergyConversion_PlayerSelectEffect: ; 2d994 (b:5994)
+ ldtx hl, Choose2EnergyCardsFromDiscardPileForHandText
+ call HandleEnergyCardsInDiscardPileSelection
+ ret
+
+EnergyConversion_AISelectEffect: ; 2d99b (b:599b)
+ call CreateEnergyCardListFromDiscardPile_AllEnergy
+ ld hl, wDuelTempList
+ ld de, hTempList
+ ld c, 2
+; select the first two energy cards found in Discard Pile
+.loop
+ ld a, [hli]
+ cp $ff
+ jr z, .done
+ ld [de], a
+ inc de
+ dec c
+ jr nz, .loop
+.done
+ ld a, $ff
+ ld [de], a
+ ret
+
+EnergyConversion_AddToHandEffect: ; 2d9b4 (b:59b4)
+; damage itself
+ ld a, 10
+ call DealRecoilDamageToSelf
+
+; loop cards that were chosen
+; until $ff is reached,
+; and move them to the hand.
+ ld hl, hTempList
+ ld de, wDuelTempList
+.loop_cards
+ ld a, [hli]
+ ld [de], a
+ inc de
+ cp $ff
+ jr z, .done
+ call MoveDiscardPileCardToHand
+ call AddCardToHand
+ jr .loop_cards
+
+.done
+ call IsPlayerTurn
+ ret c
+ bank1call Func_4b38
+ ret
+
+; return carry if Defending Pokemon is not asleep
+DreamEaterEffect: ; 2d9d6 (b:59d6)
+ ld a, DUELVARS_ARENA_CARD_STATUS
+ call GetNonTurnDuelistVariable
+ and CNF_SLP_PRZ
+ cp ASLEEP
+ ret z ; return if asleep
+; not asleep, set carry and load text
+ ldtx hl, OpponentIsNotAsleepText
+ scf
+ ret
+
+TransparencyEffect: ; 2d9e5 (b:59e5)
+ scf
+ ret
+
+; returns carry if neither the Turn Duelist or
+; the non-Turn Duelist have any deck cards.
+Prophecy_CheckDeck: ; 2d9e7 (b:59e7)
+ ld a, DUELVARS_NUMBER_OF_CARDS_NOT_IN_DECK
+ call GetTurnDuelistVariable
+ cp DECK_SIZE
+ jr c, .no_carry
+ ld a, DUELVARS_NUMBER_OF_CARDS_NOT_IN_DECK
+ call GetNonTurnDuelistVariable
+ cp DECK_SIZE
+ jr c, .no_carry
+ ldtx hl, NoCardsLeftInTheDeckText
+ scf
+ ret
+.no_carry
+ or a
+ ret
+
+Prophecy_PlayerSelectEffect: ; 2da00 (b:5a00)
+ ldtx hl, ProcedureForProphecyText
+ bank1call DrawWholeScreenTextBox
+.select_deck
+ bank1call DrawDuelMainScene
+ ldtx hl, PleaseSelectTheDeckText
+ call TwoItemHorizontalMenu
+ ldh a, [hKeysHeld]
+ and B_BUTTON
+ jr nz, Prophecy_PlayerSelectEffect ; loop back to start
+
+ ldh a, [hCurMenuItem]
+ ldh [hTempList], a ; store selection in first position in list
+ or a
+ jr z, .turn_duelist
+
+; non-turn duelist
+ ld a, DUELVARS_NUMBER_OF_CARDS_NOT_IN_DECK
+ call GetNonTurnDuelistVariable
+ cp DECK_SIZE
+ jr nc, .select_deck ; no cards, go back to deck selection
+ call SwapTurn
+ call HandleProphecyScreen
+ call SwapTurn
+ ret
+
+.turn_duelist
+ ld a, DUELVARS_NUMBER_OF_CARDS_NOT_IN_DECK
+ call GetTurnDuelistVariable
+ cp DECK_SIZE
+ jr nc, .select_deck ; no cards, go back to deck selection
+ call HandleProphecyScreen
+ ret
+
+Prophecy_AISelectEffect: ; 2da3c (b:5a3c)
+; AI doesn't ever choose this attack
+; so this it does no sorting.
+ ld a, $ff
+ ldh [hTemp_ffa0], a
+ ret
+
+Prophecy_ReorderDeckEffect: ; 2da41 (b:5a41)
+ ld hl, hTempList
+ ld a, [hli]
+ or a
+ jr z, .ReorderCards ; turn duelist's deck
+ cp $ff
+ ret z
+
+ ; non-turn duelist's deck
+ call SwapTurn
+ call .ReorderCards
+ call SwapTurn
+ ret
+
+.ReorderCards
+ ld c, 0
+; add selected cards to hand in the specified order
+.loop_add_hand
+ ld a, [hli]
+ cp $ff
+ jr z, .dec_hl
+ call SearchCardInDeckAndAddToHand
+ inc c
+ jr .loop_add_hand
+
+.dec_hl
+; go to last card that was in the list
+ dec hl
+ dec hl
+
+.loop_return_deck
+; return the cards to the top of the deck
+ ld a, [hld]
+ call ReturnCardToDeck
+ dec c
+ jr nz, .loop_return_deck
+ call IsPlayerTurn
+ ret c
+ ; print text in case it was the opponent
+ ldtx hl, ExchangedCardsInDuelistsHandText
+ call DrawWideTextBox_WaitForInput
+ ret
+
+; draw and handle Player selection for reordering
+; the top 3 cards of Deck.
+; the resulting list is output in order in hTempList.
+HandleProphecyScreen: ; 2da76 (b:5a76)
+ ld a, DUELVARS_NUMBER_OF_CARDS_NOT_IN_DECK
+ call GetTurnDuelistVariable
+ ld b, a
+ ld a, DECK_SIZE
+ sub [hl] ; a = number of cards in deck
+
+; store in c the number of cards that will be reordered.
+; this number is 3, unless the deck as fewer cards than
+; that in which case it will be the number of cards remaining.
+ ld c, 3
+ cp c
+ jr nc, .got_number_cards
+ ld c, a ; store number of remaining cards in c
+.got_number_cards
+ ld a, c
+ inc a
+ ld [wNumberOfCardsToOrder], a
+
+; store in wDuelTempList the cards
+; at top of Deck to be reordered.
+ ld a, b
+ add DUELVARS_DECK_CARDS
+ ld l, a
+ ld de, wDuelTempList
+.loop_top_cards
+ ld a, [hli]
+ ld [de], a
+ inc de
+ dec c
+ jr nz, .loop_top_cards
+ ld a, $ff ; terminating byte
+ ld [de], a
+
+.start
+ call CountCardsInDuelTempList
+ ld b, a
+ ld a, 1 ; start at 1
+ ldh [hCurSelectionItem], a
+
+; initialize buffer ahead in wDuelTempList.
+ ld hl, wDuelTempList + 10
+ xor a
+.loop_init_buffer
+ ld [hli], a
+ dec b
+ jr nz, .loop_init_buffer
+ ld [hl], $ff
+
+ bank1call InitAndDrawCardListScreenLayout
+ ldtx hl, ChooseTheOrderOfTheCardsText
+ ldtx de, DuelistDeckText
+ bank1call SetCardListHeaderText
+ bank1call Func_5735
+
+.loop_selection
+ bank1call DisplayCardList
+ jr c, .clear
+
+; first check if this card was already selected
+ ldh a, [hCurMenuItem]
+ ld e, a
+ ld d, $00
+ ld hl, wDuelTempList + 10
+ add hl, de
+ ld a, [hl]
+ or a
+ jr nz, .loop_selection ; already chosen
+
+; being here means card hasn't been selected yet,
+; so add its order number to buffer and increment
+; the sort number for the next card.
+ ldh a, [hCurSelectionItem]
+ ld [hl], a
+ inc a
+ ldh [hCurSelectionItem], a
+ bank1call Func_5744
+ ldh a, [hCurSelectionItem]
+ ld hl, wNumberOfCardsToOrder
+ cp [hl]
+ jr c, .loop_selection ; still more cards
+
+; confirm that the ordering has been completed
+ call EraseCursor
+ ldtx hl, IsThisOKText
+ call YesOrNoMenuWithText_LeftAligned
+ jr c, .start ; if not, return back to beginning of selection
+
+; write in hTempList the card list
+; in order that was selected.
+ ld hl, wDuelTempList + 10
+ ld de, wDuelTempList
+ ld c, 0
+.loop_order
+ ld a, [hli]
+ cp $ff
+ jr z, .done
+ push hl
+ push bc
+ ld c, a
+ ld b, $00
+ ld hl, hTempList
+ add hl, bc
+ ld a, [de]
+ ld [hl], a
+ pop bc
+ pop hl
+ inc de
+ inc c
+ jr .loop_order
+; now hTempList has the list of card deck indices
+; in the order selected to be place on top of the deck.
+
+.done
+ ld b, $00
+ ld hl, hTempList + 1
+ add hl, bc
+ ld [hl], $ff ; terminating byte
+ or a
+ ret
+
+.clear
+; check if any reordering was done.
+ ld hl, hCurSelectionItem
+ ld a, [hl]
+ cp 1
+ jr z, .loop_selection ; none done, go back
+; clear the order that was selected thus far.
+ dec a
+ ld [hl], a
+ ld c, a
+ ld hl, wDuelTempList + 10
+.loop_clear
+ ld a, [hli]
+ cp c
+ jr nz, .loop_clear
+ ; clear this byte
+ dec hl
+ ld [hl], $00
+ bank1call Func_5744
+ jr .loop_selection
+
+HypnoDarkMind_PlayerSelectEffect: ; 2db2b (b:5b2b)
+ ld a, DUELVARS_NUMBER_OF_POKEMON_IN_PLAY_AREA
+ call GetNonTurnDuelistVariable
+ cp 2
+ jr nc, .has_bench
+; no bench Pokemon to damage.
+ ld a, $ff
+ ldh [hTemp_ffa0], a
+ ret
+
+.has_bench
+; opens Play Area screen to select Bench Pokemon
+; to damage, and store it before returning.
+ ldtx hl, ChoosePkmnInTheBenchToGiveDamageText
+ call DrawWideTextBox_WaitForInput
+ call SwapTurn
+ bank1call HasAlivePokemonInBench
+.loop_input
+ bank1call OpenPlayAreaScreenForSelection
+ jr c, .loop_input
+ ldh a, [hTempPlayAreaLocation_ff9d]
+ ldh [hTemp_ffa0], a
+ call SwapTurn
+ ret
+
+HypnoDarkMind_AISelectEffect: ; 2db52 (b:5b52)
+ ld a, $ff
+ ldh [hTemp_ffa0], a
+ ld a, DUELVARS_NUMBER_OF_POKEMON_IN_PLAY_AREA
+ call GetNonTurnDuelistVariable
+ cp 2
+ ret c ; return if no Bench Pokemon
+; just pick Pokemon with lowest remaining HP.
+ call GetBenchPokemonWithLowestHP
+ ldh [hTemp_ffa0], a
+ ret
+
+HypnoDarkMind_DamageBenchEffect: ; 2db64 (b:5b64)
+ ldh a, [hTemp_ffa0]
+ cp $ff
+ ret z ; no target chosen
+ call SwapTurn
+ ld b, a
+ ld de, 10
+ call DealDamageToPlayAreaPokemon_RegularAnim
+ call SwapTurn
+ ret
+
+InvisibleWallEffect: ; 2db77 (b:5b77)
+ scf
+ ret
+
+MrMimeMeditate_AIEffect: ; 2db79 (b:5b79)
+ call MrMimeMeditate_DamageBoostEffect
+ jp SetDefiniteAIDamage
+
+MrMimeMeditate_DamageBoostEffect: ; 2db7f (b:5b7f)
+; add damage counters of Defending card to damage
+ call SwapTurn
+ ld e, PLAY_AREA_ARENA
+ call GetCardDamageAndMaxHP
+ call SwapTurn
+ call AddToDamage
+ ret
+
+; returns carry if Damage Swap cannot be used.
+DamageSwap_CheckDamage: ; 2db8e (b:5b8e)
+ ldh a, [hTempPlayAreaLocation_ff9d]
+ ldh [hTemp_ffa0], a
+ call CheckIfPlayAreaHasAnyDamage
+ jr c, .no_damage
+ ldh a, [hTempPlayAreaLocation_ff9d]
+ call CheckCannotUseDueToStatus_OnlyToxicGasIfANon0
+ ret
+.no_damage
+ ldtx hl, NoPokemonWithDamageCountersText
+ scf
+ ret
+
+DamageSwap_SelectAndSwapEffect: ; 2dba2 (b:5ba2)
+ ld a, DUELVARS_DUELIST_TYPE
+ call GetTurnDuelistVariable
+ cp DUELIST_TYPE_PLAYER
+ jr z, .player
+; non-player
+ bank1call Func_61a1
+ bank1call PrintPlayAreaCardList_EnableLCD
+ ret
+
+.player
+ ldtx hl, ProcedureForDamageSwapText
+ bank1call DrawWholeScreenTextBox
+ xor a
+ ldh [hCurSelectionItem], a
+ bank1call Func_61a1
+
+.start
+ bank1call PrintPlayAreaCardList_EnableLCD
+ push af
+ ldh a, [hCurSelectionItem]
+ ld hl, PlayAreaSelectionMenuParameters
+ call InitializeMenuParameters
+ pop af
+ ld [wNumMenuItems], a
+
+; handle selection of Pokemon to take damage from
+.loop_input_first
+ call DoFrame
+ call HandleMenuInput
+ jr nc, .loop_input_first
+ cp $ff
+ ret z ; quit when B button is pressed
+
+ ldh [hTempPlayAreaLocation_ffa1], a
+ ldh [hCurSelectionItem], a
+
+; if card has no damage, play sfx and return to start
+ call GetCardDamageAndMaxHP
+ or a
+ jr z, .no_damage
+
+; take damage away temporarily to draw UI.
+ ldh a, [hTempPlayAreaLocation_ffa1]
+ add DUELVARS_ARENA_CARD_HP
+ call GetTurnDuelistVariable
+ push af
+ push hl
+ add 10
+ ld [hl], a
+ bank1call PrintPlayAreaCardList_EnableLCD
+ pop hl
+ pop af
+ ld [hl], a
+
+; draw damage counter in cursor
+ ldh a, [hTempPlayAreaLocation_ffa1]
+ ld b, SYM_HP_NOK
+ call DrawSymbolOnPlayAreaCursor
+
+; handle selection of Pokemon to give damage to
+.loop_input_second
+ call DoFrame
+ call HandleMenuInput
+ jr nc, .loop_input_second
+ ; if B is pressed, return damage counter
+ ; to card that it was taken from
+ cp $ff
+ jr z, .update_ui
+
+; try to give the card selected the damage counter
+; if it would KO, ignore it.
+ ldh [hPlayAreaEffectTarget], a
+ ldh [hCurSelectionItem], a
+ call TryGiveDamageCounter_DamageSwap
+ jr c, .loop_input_second
+
+ ld a, OPPACTION_6B15
+ call SetOppAction_SerialSendDuelData
+
+.update_ui
+ ldh a, [hTempPlayAreaLocation_ffa1]
+ ld b, SYM_SPACE
+ call DrawSymbolOnPlayAreaCursor
+ call EraseCursor
+ jr .start
+
+.no_damage
+ call Func_3794
+ jr .loop_input_first
+
+; tries to give damage counter to hPlayAreaEffectTarget,
+; and if successful updates UI screen.
+DamageSwap_SwapEffect: ; 2dc27 (b:5c27)
+ call TryGiveDamageCounter_DamageSwap
+ ret c
+ bank1call PrintPlayAreaCardList_EnableLCD
+ or a
+ ret
+
+; tries to give the damage counter to the target
+; chosen by the Player (hPlayAreaEffectTarget).
+; if the damage counter would KO card, then do
+; not give the damage counter and return carry.
+TryGiveDamageCounter_DamageSwap: ; 2dc30 (b:5c30)
+ ldh a, [hPlayAreaEffectTarget]
+ add DUELVARS_ARENA_CARD_HP
+ call GetTurnDuelistVariable
+ sub 10
+ jr z, .set_carry ; would bring HP to zero?
+; has enough HP to receive a damage counter
+ ld [hl], a
+ ldh a, [hTempPlayAreaLocation_ffa1]
+ add DUELVARS_ARENA_CARD_HP
+ ld l, a
+ ld a, 10
+ add [hl]
+ ld [hl], a
+ or a
+ ret
+.set_carry
+ scf
+ ret
+
+PsywaveEffect: ; 2dc49 (b:5c49)
+ call GetEnergyAttachedMultiplierDamage
+ ld hl, wDamage
+ ld [hl], e
+ inc hl
+ ld [hl], d
+ ret
+
+; returns carry if neither Duelist has evolved Pokemon.
+DevolutionBeam_CheckPlayArea: ; 2dc53 (b:5c53)
+ call CheckIfTurnDuelistHasEvolvedCards
+ ret nc
+ call SwapTurn
+ call CheckIfTurnDuelistHasEvolvedCards
+ call SwapTurn
+ ldtx hl, ThereAreNoStage1PokemonText
+ ret
+
+; returns carry of Player cancelled selection.
+; otherwise, output in hTemp_ffa0 which Play Area
+; was selected ($0 = own Play Area, $1 = opp. Play Area)
+; and in hTempPlayAreaLocation_ffa1 selected card.
+DevolutionBeam_PlayerSelectEffect: ; 2dc64 (b:5c64)
+ ldtx hl, ProcedureForDevolutionBeamText
+ bank1call DrawWholeScreenTextBox
+
+.start
+ bank1call DrawDuelMainScene
+ ldtx hl, PleaseSelectThePlayAreaText
+ call TwoItemHorizontalMenu
+ ldh a, [hKeysHeld]
+ and B_BUTTON
+ jr nz, .set_carry
+
+; a Play Area was selected
+ ldh a, [hCurMenuItem]
+ or a
+ jr nz, .opp_chosen
+
+; player chosen
+ call HandleEvolvedCardSelection
+ jr c, .start
+
+ xor a
+.store_selection
+ ld hl, hTemp_ffa0
+ ld [hli], a ; store which Duelist Play Area selected
+ ldh a, [hTempPlayAreaLocation_ff9d]
+ ld [hl], a ; store which card selected
+ or a
+ ret
+
+.opp_chosen
+ call SwapTurn
+ call HandleEvolvedCardSelection
+ call SwapTurn
+ jr c, .start
+ ld a, $01
+ jr .store_selection
+
+.set_carry
+ scf
+ ret
+
+DevolutionBeam_AISelectEffect: ; 2dc9e (b:5c9e)
+ ld a, $01
+ ldh [hTemp_ffa0], a
+ call SwapTurn
+ call FindFirstNonBasicCardInPlayArea
+ call SwapTurn
+ jr c, .found
+ xor a
+ ldh [hTemp_ffa0], a
+ call FindFirstNonBasicCardInPlayArea
+.found
+ ldh [hTempPlayAreaLocation_ffa1], a
+ ret
+
+DevolutionBeam_LoadAnimation: ; 2dcb6 (b:5cb6)
+ xor a ; ATK_ANIM_NONE
+ ld [wLoadedAttackAnimation], a
+ ret
+
+DevolutionBeam_DevolveEffect: ; 2dcbb (b:5cbb)
+ ldh a, [hTemp_ffa0]
+ or a
+ jr z, .DevolvePokemon
+ cp $ff
+ ret z
+
+; opponent's Play Area
+ call SwapTurn
+ ldh a, [hTempPlayAreaLocation_ffa1]
+ jr nz, .skip_handle_no_damage_effect
+ call HandleNoDamageOrEffect
+ jr c, .unaffected
+.skip_handle_no_damage_effect
+ call .DevolvePokemon
+.unaffected
+ call SwapTurn
+ ret
+
+.DevolvePokemon
+ ld a, ATK_ANIM_DEVOLUTION_BEAM
+ ld [wLoadedAttackAnimation], a
+ ldh a, [hTempPlayAreaLocation_ffa1]
+ ld b, a
+ ld c, $00
+ ldh a, [hWhoseTurn]
+ ld h, a
+ bank1call PlayAttackAnimation
+ bank1call WaitAttackAnimation
+
+; load selected card's data
+ ldh a, [hTempPlayAreaLocation_ffa1]
+ ldh [hTempPlayAreaLocation_ff9d], a
+ ld [wTempPlayAreaLocation_cceb], a
+ add DUELVARS_ARENA_CARD
+ call GetTurnDuelistVariable
+ call LoadCardDataToBuffer1_FromDeckIndex
+
+; check if car is affected
+ ld a, [wLoadedCard1ID]
+ ld [wTempNonTurnDuelistCardID], a
+ ld de, $0
+ ldh a, [hTempPlayAreaLocation_ff9d]
+ or a
+ jr nz, .skip_substatus_check
+ call HandleNoDamageOrEffectSubstatus
+ jr c, .check_no_damage_effect
+.skip_substatus_check
+ call HandleDamageReductionOrNoDamageFromPkmnPowerEffects
+.check_no_damage_effect
+ call CheckNoDamageOrEffect
+ jr nc, .devolve
+ call DrawWideTextBox_WaitForInput
+ ret
+
+.devolve
+ ldh a, [hTempPlayAreaLocation_ffa1]
+ ldh [hTempPlayAreaLocation_ff9d], a
+ add DUELVARS_ARENA_CARD
+ call GetTurnDuelistVariable
+ bank1call GetCardOneStageBelow
+ call PrintDevolvedCardNameAndLevelText
+
+ ld a, d
+ call UpdateDevolvedCardHPAndStage
+ call ResetDevolvedCardStatus
+
+; add the evolved card to the hand
+ ld a, e
+ call AddCardToHand
+
+; check if this devolution KO's card
+ ldh a, [hTempPlayAreaLocation_ffa1]
+ call PrintPlayAreaCardKnockedOutIfNoHP
+
+ xor a
+ ld [wDuelDisplayedScreen], a
+ ret
+
+; returns carry if Turn Duelist
+; has no Stage1 or Stage2 cards in Play Area.
+CheckIfTurnDuelistHasEvolvedCards: ; 2dd3b (b:5d3b)
+ ld a, DUELVARS_ARENA_CARD
+ call GetTurnDuelistVariable
+ ld d, h
+ ld e, DUELVARS_ARENA_CARD_STAGE
+.loop
+ ld a, [hli]
+ cp $ff
+ jr z, .set_carry
+ ld a, [de]
+ inc de
+ or a
+ jr z, .loop ; is Basic Stage
+ ret
+.set_carry
+ scf
+ ret
+
+; handles Player selection of an evolved card in Play Area.
+; returns carry if Player cancelled operation.
+HandleEvolvedCardSelection: ; 2dd50 (b:5d50)
+ bank1call HasAlivePokemonInPlayArea
+.loop
+ bank1call OpenPlayAreaScreenForSelection
+ ret c
+ ldh a, [hTempPlayAreaLocation_ff9d]
+ add DUELVARS_ARENA_CARD_STAGE
+ call GetTurnDuelistVariable
+ or a
+ jr z, .loop ; if Basic, loop
+ ret
+
+; finds first occurrence in Play Area
+; of Stage 1 or 2 card, and outputs its
+; Play Area location in a, with carry set.
+; if none found, don't return carry set.
+FindFirstNonBasicCardInPlayArea: ; 2dd62 (b:5d62)
+ ld a, DUELVARS_NUMBER_OF_POKEMON_IN_PLAY_AREA
+ call GetTurnDuelistVariable
+ ld c, a
+
+ ld b, PLAY_AREA_ARENA
+ ld l, DUELVARS_ARENA_CARD_STAGE
+.loop
+ ld a, [hli]
+ or a
+ jr nz, .not_basic
+ inc b
+ dec c
+ jr nz, .loop
+ or a
+ ret
+.not_basic
+ ld a, b
+ scf
+ ret
+
+NeutralizingShieldEffect: ; 2dd79 (b:5d79)
+ scf
+ ret
+
+Psychic_AIEffect: ; 2dd7b (b:5d7b)
+ call Psychic_DamageBoostEffect
+ jp SetDefiniteAIDamage
+
+Psychic_DamageBoostEffect: ; 2dd81 (b:5d81)
+ call GetEnergyAttachedMultiplierDamage
+ ld hl, wDamage
+ ld a, e
+ add [hl]
+ ld [hli], a
+ ld a, d
+ adc [hl]
+ ld [hl], a
+ ret
+
+; return carry if no Psychic Energy attached
+Barrier_CheckEnergy: ; 2dd8e (b:5d8e)
+ ld e, PLAY_AREA_ARENA
+ call GetPlayAreaCardAttachedEnergies
+ ld a, [wAttachedEnergies + PSYCHIC]
+ ldtx hl, NotEnoughPsychicEnergyText
+ cp 1
+ ret
+
+Barrier_PlayerSelectEffect: ; 2dd9c (b:5d9c)
+ ld a, TYPE_ENERGY_PSYCHIC
+ call CreateListOfEnergyAttachedToArena
+ xor a ; PLAY_AREA_ARENA
+ bank1call DisplayEnergyDiscardScreen
+ bank1call HandleEnergyDiscardMenuInput
+ ret c
+ ldh a, [hTempCardIndex_ff98]
+ ldh [hTemp_ffa0], a
+ ret
+
+Barrier_AISelectEffect: ; 2ddae (b:5dae)
+; AI picks the first energy in list
+ ld a, TYPE_ENERGY_PSYCHIC
+ call CreateListOfEnergyAttachedToArena
+ ld a, [wDuelTempList]
+ ldh [hTemp_ffa0], a
+ ret
+
+Barrier_DiscardEffect: ; 2ddb9 (b:5db9)
+ ldh a, [hTemp_ffa0]
+ call PutCardInDiscardPile
+ ret
+
+Barrier_BarrierEffect: ; 2ddbf (b:5dbf)
+ ld a, SUBSTATUS1_BARRIER
+ call ApplySubstatus1ToDefendingCard
+ ret
+
+Mewtwo3EnergyAbsorption_CheckDiscardPile: ; 2ddc5 (b:5dc5)
+ call CreateEnergyCardListFromDiscardPile_AllEnergy
+ ldtx hl, ThereAreNoEnergyCardsInDiscardPileText
+ ret
+
+Mewtwo3EnergyAbsorption_PlayerSelectEffect: ; 2ddcc (b:5dcc)
+ ldtx hl, Choose2EnergyCardsFromDiscardPileToAttachText
+ call HandleEnergyCardsInDiscardPileSelection
+ ret
+
+Mewtwo3EnergyAbsorption_AISelectEffect: ; 2ddd3 (b:5dd3)
+; AI picks first 2 energy cards
+ call CreateEnergyCardListFromDiscardPile_AllEnergy
+ ld hl, wDuelTempList
+ ld de, hTempList
+ ld c, 2
+.loop
+ ld a, [hli]
+ cp $ff
+ jr z, .done
+ ld [de], a
+ inc de
+ dec c
+ jr nz, .loop
+.done
+ ld a, $ff ; terminating byte
+ ld [de], a
+ ret
+
+Mewtwo3EnergyAbsorption_AddToHandEffect: ; 2ddec (b:5dec)
+ ld hl, hTempList
+.loop
+ ld a, [hli]
+ cp $ff
+ ret z
+ push hl
+ call MoveDiscardPileCardToHand
+ call GetTurnDuelistVariable
+ ld [hl], CARD_LOCATION_ARENA
+ pop hl
+ jr .loop
+
+Mewtwo2EnergyAbsorption_CheckDiscardPile: ; 2ddff (b:5dff)
+ call CreateEnergyCardListFromDiscardPile_AllEnergy
+ ldtx hl, ThereAreNoEnergyCardsInDiscardPileText
+ ret
+
+Mewtwo2EnergyAbsorption_PlayerSelectEffect: ; 2de06 (b:5e06)
+ ldtx hl, Choose2EnergyCardsFromDiscardPileToAttachText
+ call HandleEnergyCardsInDiscardPileSelection
+ ret
+
+Mewtwo2EnergyAbsorption_AISelectEffect: ; 2de0d (b:5e0d)
+; AI picks first 2 energy cards
+ call CreateEnergyCardListFromDiscardPile_AllEnergy
+ ld hl, wDuelTempList
+ ld de, hTempList
+ ld c, 2
+.loop
+ ld a, [hli]
+ cp $ff
+ jr z, .done
+ ld [de], a
+ inc de
+ dec c
+ jr nz, .loop
+.done
+ ld a, $ff ; terminating byte
+ ld [de], a
+ ret
+
+Mewtwo2EnergyAbsorption_AddToHandEffect: ; 2de26 (b:5e26)
+ ld hl, hTempList
+.loop
+ ld a, [hli]
+ cp $ff
+ ret z
+ push hl
+ call MoveDiscardPileCardToHand
+ call GetTurnDuelistVariable
+ ld [hl], CARD_LOCATION_ARENA
+ pop hl
+ jr .loop
+
+; returns carry if Strange Behavior cannot be used.
+StrangeBehavior_CheckDamage: ; 2de39 (b:5e39)
+; does Play Area have any damage counters?
+ ldh a, [hTempPlayAreaLocation_ff9d]
+ ldh [hTemp_ffa0], a
+ call CheckIfPlayAreaHasAnyDamage
+ ldtx hl, NoPokemonWithDamageCountersText
+ jr c, .set_carry
+; can Slowbro receive any damage counters without KO-ing?
+ ldh a, [hTempPlayAreaLocation_ff9d]
+ add DUELVARS_ARENA_CARD_HP
+ call GetTurnDuelistVariable
+ ldtx hl, CannotUseBecauseItWillBeKnockedOutText
+ cp 10 + 10
+ jr c, .set_carry
+; can Pkmn Power be used?
+ ldh a, [hTempPlayAreaLocation_ff9d]
+ call CheckCannotUseDueToStatus_OnlyToxicGasIfANon0
+ ret
+
+.set_carry
+ scf
+ ret
+
+StrangeBehavior_SelectAndSwapEffect: ; 2de5b (b:5e5b)
+ ld a, DUELVARS_DUELIST_TYPE
+ call GetTurnDuelistVariable
+ cp DUELIST_TYPE_PLAYER
+ jr z, .player
+
+; not player
+ bank1call Func_61a1
+ bank1call PrintPlayAreaCardList_EnableLCD
+ ret
+
+.player
+ ldtx hl, ProcedureForStrangeBehaviorText
+ bank1call DrawWholeScreenTextBox
+
+ xor a
+ ldh [hCurSelectionItem], a
+ bank1call Func_61a1
+.start
+ bank1call PrintPlayAreaCardList_EnableLCD
+ push af
+ ldh a, [hCurSelectionItem]
+ ld hl, PlayAreaSelectionMenuParameters
+ call InitializeMenuParameters
+ pop af
+
+ ld [wNumMenuItems], a
+.loop_input
+ call DoFrame
+ call HandleMenuInput
+ jr nc, .loop_input
+ cp -1
+ ret z ; return when B button is pressed
+
+ ldh [hCurSelectionItem], a
+ ldh [hTempPlayAreaLocation_ffa1], a
+ ld hl, hTemp_ffa0
+ cp [hl]
+ jr z, .play_sfx ; can't select Slowbro itself
+
+ call GetCardDamageAndMaxHP
+ or a
+ jr z, .play_sfx ; can't select card without damage
+
+ call TryGiveDamageCounter_StrangeBehavior
+ jr c, .play_sfx
+ ld a, OPPACTION_6B15
+ call SetOppAction_SerialSendDuelData
+ jr .start
+
+.play_sfx
+ call Func_3794
+ jr .loop_input
+
+StrangeBehavior_SwapEffect: ; 2deb3 (b:5eb3)
+ call TryGiveDamageCounter_StrangeBehavior
+ ret c
+ bank1call PrintPlayAreaCardList_EnableLCD
+ or a
+ ret
+
+; tries to give the damage counter to the target
+; chosen by the Player (hTemp_ffa0).
+; if the damage counter would KO card, then do
+; not give the damage counter and return carry.
+TryGiveDamageCounter_StrangeBehavior: ; 2debc (b:5ebc)
+ ldh a, [hTemp_ffa0]
+ add DUELVARS_ARENA_CARD_HP
+ call GetTurnDuelistVariable
+ sub 10
+ jr z, .set_carry ; would bring HP to zero?
+; has enough HP to receive a damage counter
+ ld [hl], a
+ ldh a, [hTempPlayAreaLocation_ffa1]
+ add DUELVARS_ARENA_CARD_HP
+ ld l, a
+ ld a, 10
+ add [hl]
+ ld [hl], a
+ or a
+ ret
+.set_carry
+ scf
+ ret
+
+; returns carry if has no damage counters.
+SpacingOut_CheckDamage: ; 2ded5 (b:5ed5)
+ ld e, PLAY_AREA_ARENA
+ call GetCardDamageAndMaxHP
+ ldtx hl, NoDamageCountersText
+ cp 10
+ ret
+
+SpacingOut_Success50PercentEffect: ; 2dee0 (b:5ee0)
+ ldtx de, SuccessCheckIfHeadsAttackIsSuccessfulText
+ call TossCoin_BankB
+ ldh [hTemp_ffa0], a
+ jp nc, SetWasUnsuccessful
+ ld a, ATK_ANIM_RECOVER
+ ld [wLoadedAttackAnimation], a
+ ret
+
+SpacingOut_HealEffect: ; 2def1 (b:5ef1)
+ ldh a, [hTemp_ffa0]
+ or a
+ ret z ; coin toss was tails
+ ld e, PLAY_AREA_ARENA
+ call GetCardDamageAndMaxHP
+ or a
+ ret z ; no damage counters
+ ld a, DUELVARS_ARENA_CARD_HP
+ call GetTurnDuelistVariable
+ add 10
+ ld [hl], a
+ ret
+
+; sets carry if no Trainer cards in the Discard Pile.
+Scavenge_CheckDiscardPile: ; 2df05 (b:5f05)
+ ld e, PLAY_AREA_ARENA
+ call GetPlayAreaCardAttachedEnergies
+ ld a, [wAttachedEnergies + PSYCHIC]
+ ldtx hl, NotEnoughPsychicEnergyText
+ cp 1
+ ret c ; return if no Psychic energy attached
+ call CreateTrainerCardListFromDiscardPile
+ ldtx hl, ThereAreNoTrainerCardsInDiscardPileText ; this is redundant
+ ret
+
+Scavenge_PlayerSelectEnergyEffect: ; 2df1a (b:5f1a)
+ ld a, TYPE_ENERGY_PSYCHIC
+ call CreateListOfEnergyAttachedToArena
+ xor a ; PLAY_AREA_ARENA
+ bank1call DisplayEnergyDiscardScreen
+ bank1call HandleEnergyDiscardMenuInput
+ ret c
+ ldh a, [hTempCardIndex_ff98]
+ ldh [hTemp_ffa0], a
+ or a
+ ret
+
+Scavenge_AISelectEffect: ; 2df2d (b:5f2d)
+; AI picks first Energy card in list
+ ld a, TYPE_ENERGY_PSYCHIC
+ call CreateListOfEnergyAttachedToArena
+ ld a, [wDuelTempList]
+ ldh [hTemp_ffa0], a
+; AI picks first Trainer card in list
+ call CreateTrainerCardListFromDiscardPile
+ ld a, [wDuelTempList]
+ ldh [hTempPlayAreaLocation_ffa1], a
+ ret
+
+Scavenge_DiscardEffect: ; 2df40 (b:5f40)
+ ldh a, [hTemp_ffa0]
+ call PutCardInDiscardPile
+ ret
+
+Scavenge_PlayerSelectTrainerEffect: ; 2df46 (b:5f46)
+ call CreateTrainerCardListFromDiscardPile
+ bank1call Func_5591
+ ldtx hl, PleaseSelectCardText
+ ldtx de, PlayerDiscardPileText
+ bank1call SetCardListHeaderText
+.loop_input
+ bank1call DisplayCardList
+ jr c, .loop_input
+ ldh a, [hTempCardIndex_ff98]
+ ldh [hTempPlayAreaLocation_ffa1], a
+ ret
+
+Scavenge_AddToHandEffect: ; 2df5f (b:5f5f)
+ ldh a, [hTempPlayAreaLocation_ffa1]
+ call MoveDiscardPileCardToHand
+ call AddCardToHand
+ call IsPlayerTurn
+ ret c
+ ldh a, [hTempPlayAreaLocation_ffa1]
+ ldtx hl, WasPlacedInTheHandText
+ bank1call DisplayCardDetailScreen
+ ret
+
+; returns carry if Defending Pokemon has no attacks
+SlowpokeAmnesia_CheckAttacks: ; 2df74 (b:5f74)
+ call CheckIfDefendingPokemonHasAnyAttack
+ ldtx hl, NoAttackMayBeChoosenText
+ ret
+
+SlowpokeAmnesia_PlayerSelectEffect: ; 2df7b (b:5f7b)
+ call PlayerPickAttackForAmnesia
+ ret
+
+SlowpokeAmnesia_AISelectEffect: ; 2df7f (b:5f7f)
+ call AIPickAttackForAmnesia
+ ldh [hTemp_ffa0], a
+ ret
+
+SlowpokeAmnesia_DisableEffect: ; 2df85 (b:5f85)
+ call ApplyAmnesiaToAttack
+ ret
+
+; returns carry if Arena card has no Psychic Energy attached
+; or if it doesn't have any damage counters.
+KadabraRecover_CheckEnergyHP: ; 2df89 (b:5f89)
+ ld e, PLAY_AREA_ARENA
+ call GetPlayAreaCardAttachedEnergies
+ ld a, [wAttachedEnergies + PSYCHIC]
+ ldtx hl, NotEnoughPsychicEnergyText
+ cp 1
+ ret c ; return if not enough energy
+ call GetCardDamageAndMaxHP
+ ldtx hl, NoDamageCountersText
+ cp 10
+ ret ; return carry if no damage
+
+KadabraRecover_PlayerSelectEffect: ; 2dfa0 (b:5fa0)
+ ld a, TYPE_ENERGY_PSYCHIC
+ call CreateListOfEnergyAttachedToArena
+ xor a ; PLAY_AREA_ARENA
+ bank1call DisplayEnergyDiscardScreen
+ bank1call HandleEnergyDiscardMenuInput
+ ret c
+ ldh a, [hTempCardIndex_ff98]
+ ldh [hTemp_ffa0], a ; store card chosen
+ ret
+
+KadabraRecover_AISelectEffect: ; 2dfb2 (b:5fb2)
+ ld a, TYPE_ENERGY_PSYCHIC
+ call CreateListOfEnergyAttachedToArena
+ ld a, [wDuelTempList] ; pick first card
+ ldh [hTemp_ffa0], a
+ ret
+
+KadabraRecover_DiscardEffect: ; 2dfbd (b:5fbd)
+ ldh a, [hTemp_ffa0]
+ call PutCardInDiscardPile
+ ret
+
+KadabraRecover_HealEffect: ; 2dfc3 (b:5fc3)
+ ld e, PLAY_AREA_ARENA
+ call GetCardDamageAndMaxHP
+ ld e, a ; all damage for recovery
+ ld d, 0
+ call ApplyAndAnimateHPRecovery
+ ret
+
+JynxDoubleslap_AIEffect: ; 2dfd7 (b:5fd7)
+ ld a, 20 / 2
+ lb de, 0, 20
+ jp SetExpectedAIDamage
+
+JynxDoubleslap_MultiplierEffect: ; 2dfcf (b:5fcf)
+ ld hl, 10
+ call LoadTxRam3
+ ldtx de, DamageCheckIfHeadsXDamageText
+ ld a, 2
+ call TossCoinATimes_BankB
+ call ATimes10
+ call SetDefiniteDamage
+ ret
+
+JynxMeditate_AIEffect: ; 2dff2 (b:5ff2)
+ call JynxMeditate_DamageBoostEffect
+ jp SetDefiniteAIDamage
+
+JynxMeditate_DamageBoostEffect: ; 2dfec (b:5fec)
+; add damage counters of Defending card to damage
+ call SwapTurn
+ ld e, PLAY_AREA_ARENA
+ call GetCardDamageAndMaxHP
+ call SwapTurn
+ call AddToDamage
+ ret
+
+MysteryAttack_AIEffect: ; 2e001 (b:6001)
+ ld a, 10
+ lb de, 0, 20
+ jp SetExpectedAIDamage
+
+MysteryAttack_RandomEffect: ; 2e009 (b:6009)
+ ld a, 10
+ call SetDefiniteDamage
+
+; chooses a random effect from 8 possible options.
+ call UpdateRNGSources
+ and %111
+ ldh [hTemp_ffa0], a
+ ld hl, .random_effect
+ jp JumpToFunctionInTable
+
+.random_effect
+ dw ParalysisEffect
+ dw PoisonEffect
+ dw SleepEffect
+ dw ConfusionEffect
+ dw .no_effect ; this will actually activate recovery effect afterwards
+ dw .no_effect
+ dw .more_damage
+ dw .no_damage
+
+.more_damage
+ ld a, 20
+ call SetDefiniteDamage
+ ret
+
+.no_damage
+ ld a, ATK_ANIM_GLOW_EFFECT
+ ld [wLoadedAttackAnimation], a
+ xor a
+ call SetDefiniteDamage
+ call SetNoEffectFromStatus
+.no_effect
+ ret
+
+MysteryAttack_RecoverEffect: ; 2e03e (b:603e)
+; in case the 5th option was chosen for random effect,
+; trigger recovery effect for 10 HP.
+ ldh a, [hTemp_ffa0]
+ cp 4
+ ret nz
+ lb de, 0, 10
+ call ApplyAndAnimateHPRecovery
+ ret
+
+StoneBarrage_AIEffect: ; 2e04a (b:604a)
+ ld a, 10
+ lb de, 0, 100
+ jp SetExpectedAIDamage
+
+StoneBarrage_MultiplierEffect: ; 2e052 (b:6052)
+ xor a
+ ldh [hTemp_ffa0], a
+.loop_coin_toss
+ ldtx de, FlipUntilFailAppears10DamageForEachHeadsText
+ xor a
+ call TossCoinATimes_BankB
+ jr nc, .tails
+ ld hl, hTemp_ffa0
+ inc [hl] ; increase heads count
+ jr .loop_coin_toss
+
+.tails
+; store resulting damage
+ ldh a, [hTemp_ffa0]
+ ld l, a
+ ld h, 10
+ call HtimesL
+ ld de, wDamage
+ ld a, l
+ ld [de], a
+ inc de
+ ld a, h
+ ld [de], a
+ ret
+
+OnixHardenEffect: ; 2e075 (b:6075)
+ ld a, SUBSTATUS1_HARDEN
+ call ApplySubstatus1ToDefendingCard
+ ret
+
+PrimeapeFurySwipes_AIEffect: ; 2e07b (b:607b)
+ ld a, 60 / 2
+ lb de, 0, 60
+ jp SetExpectedAIDamage
+
+PrimeapeFurySwipes_MultiplierEffect: ; 2e083 (b:6083)
+ ld hl, 20
+ call LoadTxRam3
+ ldtx de, DamageCheckIfHeadsXDamageText
+ ld a, 3
+ call TossCoinATimes_BankB
+ add a
+ call ATimes10
+ call SetDefiniteDamage
+ ret
+
+TantrumEffect: ; 2e099 (b:6099)
+ ldtx de, IfTailsYourPokemonBecomesConfusedText
+ call TossCoin_BankB
+ ret c ; return if heads
+; confuse Pokemon
+ ld a, ATK_ANIM_MULTIPLE_SLASH
+ ld [wLoadedAttackAnimation], a
+ call SwapTurn
+ call ConfusionEffect
+ call SwapTurn
+ ret
+
+StrikesBackEffect: ; 2e0af (b:60af)
+ scf
+ ret
+
+KabutoArmorEffect: ; 2e0b1 (b:60b1)
+ scf
+ ret
+
+AbsorbEffect: ; 2e0b3 (b:60b3)
+ ld hl, wDealtDamage
+ ld a, [hli]
+ ld h, [hl]
+ ld l, a
+ srl h
+ rr l
+ bit 0, l
+ jr z, .rounded
+ ; round up to nearest 10
+ ld de, 5
+ add hl, de
+.rounded
+ ld e, l
+ ld d, h
+ call ApplyAndAnimateHPRecovery
+ ret
+
+SnivelEffect: ; 2e0cb (b:60cb)
+ ld a, SUBSTATUS2_REDUCE_BY_20
+ call ApplySubstatus2ToDefendingCard
+ ret
+
+CuboneRage_AIEffect: ; 2e0d1 (b:60d1)
+ call CuboneRage_DamageBoostEffect
+ jp SetDefiniteAIDamage
+
+CuboneRage_DamageBoostEffect: ; 2e0d7 (b:60d7)
+ ld e, PLAY_AREA_ARENA
+ call GetCardDamageAndMaxHP
+ call AddToDamage
+ ret
+
+Bonemerang_AIEffect: ; 2e0e0 (b:60e0)
+ ld a, 60 / 2
+ lb de, 0, 60
+ jp SetExpectedAIDamage
+
+Bonemerang_MultiplierEffect: ; 2e0e8 (b:60e8)
+ ld hl, 30
+ call LoadTxRam3
+ ldtx de, DamageCheckIfHeadsXDamageText
+ ld a, 2
+ call TossCoinATimes_BankB
+ ld e, a
+ add a ; a = 2 * heads
+ add e ; a = 3 * heads
+ call ATimes10
+ call SetDefiniteDamage
+ ret
+
+; returns carry if can't add Pokemon from deck
+MarowakCallForFamily_CheckDeckAndPlayArea: ; 2e100 (b:6100)
+ call CheckIfDeckIsEmpty
+ ret c ; no cards in deck
+ ld a, DUELVARS_NUMBER_OF_POKEMON_IN_PLAY_AREA
+ call GetTurnDuelistVariable
+ ldtx hl, NoSpaceOnTheBenchText
+ cp MAX_PLAY_AREA_POKEMON
+ ccf
+ ret
+
+MarowakCallForFamily_PlayerSelectEffect: ; 2e110 (b:6110)
+ ld a, $ff
+ ldh [hTemp_ffa0], a
+
+ call CreateDeckCardList
+ ldtx hl, ChooseBasicFightingPokemonFromDeckText
+ ldtx bc, FightingPokemonDeckText
+ lb de, SEARCHEFFECT_BASIC_FIGHTING, $00
+ call LookForCardsInDeck
+ ret c
+
+; draw Deck list interface and print text
+ bank1call Func_5591
+ ldtx hl, ChooseBasicFightingPokemonText
+ ldtx de, DuelistDeckText
+ bank1call SetCardListHeaderText
+
+.loop
+ bank1call DisplayCardList
+ jr c, .pressed_b
+
+ call LoadCardDataToBuffer2_FromDeckIndex
+ ld a, [wLoadedCard2Type]
+ cp FIGHTING
+ jr nz, .play_sfx ; is Fighting?
+ ld a, [wLoadedCard2Stage]
+ or a
+ jr nz, .play_sfx ; is Basic?
+ ldh a, [hTempCardIndex_ff98]
+ ldh [hTemp_ffa0], a
+ or a
+ ret
+
+.play_sfx
+ ; play SFX and loop back
+ call Func_3794
+ jr .loop
+
+.pressed_b
+; figure if Player can exit the screen without selecting,
+; that is, if the Deck has no Basic Fighting Pokemon.
+ ld a, DUELVARS_CARD_LOCATIONS
+ call GetTurnDuelistVariable
+.loop_b_press
+ ld a, [hl]
+ cp CARD_LOCATION_DECK
+ jr nz, .next
+ ld a, l
+ call LoadCardDataToBuffer2_FromDeckIndex
+ ld a, [wLoadedCard1Type]
+ cp FIGHTING
+ jr nz, .next ; found, go back to top loop
+ ld a, [wLoadedCard1Stage]
+ or a
+ jr z, .play_sfx ; found, go back to top loop
+.next
+ inc l
+ ld a, l
+ cp DECK_SIZE
+ jr c, .loop_b_press
+
+; no valid card in Deck, can safely exit screen
+ ld a, $ff
+ ldh [hTemp_ffa0], a
+ or a
+ ret
+
+MarowakCallForFamily_AISelectEffect: ; 2e177 (b:6177)
+ call CreateDeckCardList
+ ld hl, wDuelTempList
+.loop_deck
+ ld a, [hli]
+ ldh [hTemp_ffa0], a
+ cp $ff
+ ret z ; none found
+ call LoadCardDataToBuffer2_FromDeckIndex
+ ld a, [wLoadedCard2Type]
+ cp FIGHTING
+ jr nz, .loop_deck
+ ld a, [wLoadedCard2Stage]
+ or a
+ jr nz, .loop_deck
+; found
+ ret
+
+MarowakCallForFamily_PutInPlayAreaEffect: ; 2e194 (b:6194)
+ ldh a, [hTemp_ffa0]
+ cp $ff
+ jr z, .shuffle
+ call SearchCardInDeckAndAddToHand
+ call AddCardToHand
+ call PutHandPokemonCardInPlayArea
+ call IsPlayerTurn
+ jr c, .shuffle
+ ; display card on screen
+ ldh a, [hTemp_ffa0]
+ ldtx hl, PlacedOnTheBenchText
+ bank1call DisplayCardDetailScreen
+.shuffle
+ call Func_2c0bd
+ ret
+
+KarateChop_AIEffect: ; 2e1b4 (b:61b4)
+ call KarateChop_DamageSubtractionEffect
+ jp SetDefiniteAIDamage
+
+KarateChop_DamageSubtractionEffect: ; 2e1ba (b:61ba)
+ ld e, PLAY_AREA_ARENA
+ call GetCardDamageAndMaxHP
+ ld e, a
+ ld hl, wDamage
+ ld a, [hl]
+ sub e
+ ld [hli], a
+ ld a, [hl]
+ sbc 0
+ ld [hl], a
+ rla
+ ret nc
+; cap it to 0 damage
+ xor a
+ call SetDefiniteDamage
+ ret
+
+SubmissionEffect: ; 2e1d1 (b:61d1)
+ ld a, 20
+ call DealRecoilDamageToSelf
+ ret
+
+GolemSelfdestructEffect: ; 2e1d7 (b:61d7)
+ ld a, 100
+ call DealRecoilDamageToSelf
+ ld a, $01
+ ld [wIsDamageToSelf], a
+ ld a, 20
+ call DealDamageToAllBenchedPokemon
+ call SwapTurn
+ xor a
+ ld [wIsDamageToSelf], a
+ ld a, 20
+ call DealDamageToAllBenchedPokemon
+ call SwapTurn
+ ret
+
+GravelerHardenEffect: ; 2e1f6 (b:61f6)
+ ld a, SUBSTATUS1_HARDEN
+ call ApplySubstatus1ToDefendingCard
+ ret
+
+Ram_SelectSwitchEffect: ; 2e1fc (b:61fc)
+ ld a, DUELVARS_NUMBER_OF_POKEMON_IN_PLAY_AREA
+ call GetNonTurnDuelistVariable
+ cp 2
+ jr c, .no_bench
+ call DuelistSelectForcedSwitch
+ ldh a, [hTempPlayAreaLocation_ff9d]
+ ldh [hTemp_ffa0], a
+ ret
+.no_bench
+ ld a, $ff
+ ldh [hTemp_ffa0], a
+ ret
+
+Ram_RecoilSwitchEffect: ; 2e212 (b:6212)
+ ld a, 20
+ call DealRecoilDamageToSelf
+ ldh a, [hTemp_ffa0]
+ call HandleSwitchDefendingPokemonEffect
+ ret
+
+LeerEffect: ; 2e21d (b:621d)
+ ldtx de, IfHeadsOpponentCannotAttackText
+ call TossCoin_BankB
+ jp nc, SetWasUnsuccessful
+ ld a, ATK_ANIM_LEER
+ ld [wLoadedAttackAnimation], a
+ ld a, SUBSTATUS2_LEER
+ call ApplySubstatus2ToDefendingCard
+ ret
+
+; return carry if opponent has no Bench Pokemon.
+StretchKick_CheckBench: ; 2e231 (b:6231)
+ ld a, DUELVARS_NUMBER_OF_POKEMON_IN_PLAY_AREA
+ call GetNonTurnDuelistVariable
+ ldtx hl, EffectNoPokemonOnTheBenchText
+ cp 2
+ ret
+
+StretchKick_PlayerSelectEffect: ; 2e23c (b:623c)
+ ldtx hl, ChoosePkmnInTheBenchToGiveDamageText
+ call DrawWideTextBox_WaitForInput
+ call SwapTurn
+ bank1call HasAlivePokemonInBench
+.loop_input
+ bank1call OpenPlayAreaScreenForSelection
+ jr c, .loop_input
+ ldh a, [hTempPlayAreaLocation_ff9d]
+ ldh [hTemp_ffa0], a
+ call SwapTurn
+ ret
+
+StretchKick_AISelectEffect: ; 2e255 (b:6255)
+; chooses Bench Pokemon with least amount of remaining HP
+ call GetBenchPokemonWithLowestHP
+ ldh [hTemp_ffa0], a
+ ret
+
+StretchKick_BenchDamageEffect: ; 2e25b (b:625b)
+ call SwapTurn
+ ldh a, [hTemp_ffa0]
+ ld b, a
+ ld de, 20
+ call DealDamageToPlayAreaPokemon_RegularAnim
+ call SwapTurn
+ ret
+
+SandAttackEffect: ; 2e26b (b:626b)
+ ld a, SUBSTATUS2_SAND_ATTACK
+ call ApplySubstatus2ToDefendingCard
+ ret
+
+SandslashFurySwipes_AIEffect: ; 2e271 (b:6271)
+ ld a, 60 / 2
+ lb de, 0, 60
+ jp SetExpectedAIDamage
+
+SandslashFurySwipes_MultiplierEffect: ; 2e279 (b:6279)
+ ld hl, 20
+ call LoadTxRam3
+ ldtx de, DamageCheckIfHeadsXDamageText
+ ld a, 3
+ call TossCoinATimes_BankB
+ add a
+ call ATimes10
+ call SetDefiniteDamage
+ ret
+
+EarthquakeEffect: ; 2e28f (b:628f)
+ ld a, $01
+ ld [wIsDamageToSelf], a
+ ld a, 10
+ call DealDamageToAllBenchedPokemon
+ ret
+
+PrehistoricPowerEffect: ; 2e29a (b:629a)
+ scf
+ ret
+
+; returns carry if Pkmn Power can't be used.
+Peek_OncePerTurnCheck: ; 2e29c (b:629c)
+ ldh a, [hTempPlayAreaLocation_ff9d]
+ ldh [hTemp_ffa0], a
+ add DUELVARS_ARENA_CARD_FLAGS
+ call GetTurnDuelistVariable
+ and USED_PKMN_POWER_THIS_TURN
+ jr nz, .already_used
+ ldh a, [hTempPlayAreaLocation_ff9d]
+ call CheckCannotUseDueToStatus_OnlyToxicGasIfANon0
+ ret
+.already_used
+ ldtx hl, OnlyOncePerTurnText
+ scf
+ ret
+
+Peek_SelectEffect: ; 2e2b4 (b:62b4)
+; set Pkmn Power used flag
+ ldh a, [hTemp_ffa0]
+ add DUELVARS_ARENA_CARD_FLAGS
+ call GetTurnDuelistVariable
+ set USED_PKMN_POWER_THIS_TURN_F, [hl]
+
+ ld a, DUELVARS_DUELIST_TYPE
+ call GetTurnDuelistVariable
+ cp DUELIST_TYPE_LINK_OPP
+ jr z, .link_opp
+ and DUELIST_TYPE_AI_OPP
+ jr nz, .ai_opp
+
+; player
+ call Func_3b31
+ call HandlePeekSelection
+ ldh [hAIPkmnPowerEffectParam], a
+ call SerialSend8Bytes
+ ret
+
+.link_opp
+ call SerialRecv8Bytes
+ ldh [hAIPkmnPowerEffectParam], a
+
+.ai_opp
+ ldh a, [hAIPkmnPowerEffectParam]
+ bit AI_PEEK_TARGET_HAND_F, a
+ jr z, .prize_or_deck
+ and (~AI_PEEK_TARGET_HAND & $ff) ; unset bit to get deck index
+; if masked value is higher than $40, then it means
+; that AI chose to look at Player's deck.
+; all deck indices will be smaller than $40.
+ cp $40
+ jr c, .hand
+ ldh a, [hAIPkmnPowerEffectParam]
+ jr .prize_or_deck
+
+.hand
+; AI chose to look at random card in hand,
+; so display it to the Player on screen.
+ call SwapTurn
+ ldtx hl, PeekWasUsedToLookInYourHandText
+ bank1call DisplayCardDetailScreen
+ call SwapTurn
+ ret
+
+.prize_or_deck
+; AI chose either a prize card or Player's top deck card,
+; so show Play Area and draw cursor appropriately.
+ call Func_3b31
+ call SwapTurn
+ ldh a, [hAIPkmnPowerEffectParam]
+ xor $80
+ call DrawAIPeekScreen
+ call SwapTurn
+ ldtx hl, CardPeekWasUsedOnText
+ call DrawWideTextBox_WaitForInput
+ ret
+
+BoneAttackEffect: ; 2e30f (b:630f)
+ ldtx de, IfHeadsOpponentCannotAttackText
+ call TossCoin_BankB
+ ret nc
+ ld a, SUBSTATUS2_BONE_ATTACK
+ call ApplySubstatus2ToDefendingCard
+ ret
+
+; return carry if neither Play Area
+; has room for more Bench Pokemon.
+Wail_BenchCheck: ; 2e31c (b:631c)
+ ld a, DUELVARS_NUMBER_OF_POKEMON_IN_PLAY_AREA
+ call GetTurnDuelistVariable
+ cp MAX_PLAY_AREA_POKEMON
+ jr c, .no_carry
+ ld a, DUELVARS_NUMBER_OF_POKEMON_IN_PLAY_AREA
+ call GetNonTurnDuelistVariable
+ cp MAX_PLAY_AREA_POKEMON
+ jr c, .no_carry
+ ldtx hl, NoSpaceOnTheBenchText
+ scf
+ ret
+.no_carry
+ or a
+ ret
+
+Wail_FillBenchEffect: ; 2e335 (b:6335)
+ call SwapTurn
+ call .FillBench
+ call SwapTurn
+ call .FillBench
+
+; display both Play Areas
+ ldtx hl, BasicPokemonWasPlacedOnEachBenchText
+ call DrawWideTextBox_WaitForInput
+ bank1call HasAlivePokemonInPlayArea
+ bank1call OpenPlayAreaScreenForSelection
+ call SwapTurn
+ bank1call HasAlivePokemonInPlayArea
+ bank1call OpenPlayAreaScreenForSelection
+ call SwapTurn
+ ret
+
+.FillBench ; 2e35a (b:635a)
+ call CreateDeckCardList
+ ret c
+ ld hl, wDuelTempList
+ call ShuffleCards
+
+; if no more space in the Bench, then return.
+.check_bench
+ push hl
+ ld a, DUELVARS_NUMBER_OF_POKEMON_IN_PLAY_AREA
+ call GetTurnDuelistVariable
+ pop hl
+ cp MAX_PLAY_AREA_POKEMON
+ jr nc, .done
+
+; there's still space, so look for the next
+; Basic Pokemon card to put in the Bench.
+.loop
+ ld a, [hli]
+ ldh [hTempCardIndex_ff98], a
+ cp $ff
+ jr z, .done
+ call LoadCardDataToBuffer2_FromDeckIndex
+ ld a, [wLoadedCard2Type]
+ cp TYPE_ENERGY
+ jr nc, .loop ; is Pokemon card?
+ ld a, [wLoadedCard2Stage]
+ or a
+ jr nz, .loop ; is Basic?
+; place card in Bench
+ push hl
+ ldh a, [hTempCardIndex_ff98]
+ call SearchCardInDeckAndAddToHand
+ call AddCardToHand
+ call PutHandPokemonCardInPlayArea
+ pop hl
+ jr .check_bench
+
+.done
+ call Func_2c0bd
+ ret
+
+Thunderpunch_AIEffect: ; 2e399 (b:6399)
+ ld a, (30 + 40) / 2
+ lb de, 30, 40
+ jp SetExpectedAIDamage
+
+Thunderpunch_ModifierEffect: ; 2e3a1 (b:63a1)
+ ldtx de, IfHeadPlus10IfTails10ToYourselfText
+ call TossCoin_BankB
+ ldh [hTemp_ffa0], a
+ ret nc ; return if got tails
+ ld a, 10
+ call AddToDamage
+ ret
+
+Thunderpunch_RecoilEffect: ; 2e3b0 (b:63b0)
+ ldh a, [hTemp_ffa0]
+ or a
+ ret nz ; return if got heads
+ ld a, 10
+ call DealRecoilDamageToSelf
+ ret
+
+LightScreenEffect: ; 2e3ba (b:63ba)
+ ld a, SUBSTATUS1_HALVE_DAMAGE
+ call ApplySubstatus1ToDefendingCard
+ ret
+
+ElectabuzzQuickAttack_AIEffect: ; 2e3c0 (b:63c0)
+ ld a, (10 + 30) / 2
+ lb de, 10, 30
+ jp SetExpectedAIDamage
+
+ElectabuzzQuickAttack_DamageBoostEffect: ; 2e3c8 (b:63c8)
+ ld hl, 20
+ call LoadTxRam3
+ ldtx de, DamageCheckIfHeadsPlusDamageText
+ call TossCoin_BankB
+ ret nc ; return if tails
+ ld a, 20
+ call AddToDamage
+ ret
+
+MagnemiteSelfdestructEffect: ; 2e3db (b:63db)
+ ld a, 40
+ call DealRecoilDamageToSelf
+
+ ld a, $01
+ ld [wIsDamageToSelf], a
+ ld a, 10
+ call DealDamageToAllBenchedPokemon
+ call SwapTurn
+
+ xor a
+ ld [wIsDamageToSelf], a
+ ld a, 10
+ call DealDamageToAllBenchedPokemon
+ call SwapTurn
+ ret
+
+ZapdosThunder_Recoil50PercentEffect: ; 2e3fa (b:63fa)
+ ld hl, 30
+ call LoadTxRam3
+ ldtx de, IfTailsDamageToYourselfTooText
+ call TossCoin_BankB
+ ldh [hTemp_ffa0], a
+ ret
+
+ZapdosThunder_RecoilEffect: ; 2e409 (b:6409)
+ ld hl, 30
+ call LoadTxRam3
+ ldh a, [hTemp_ffa0]
+ or a
+ ret nz ; return if got heads
+ ld a, 30
+ call DealRecoilDamageToSelf
+ ret
+
+ThunderboltEffect: ; 2e419 (b:6419)
+ xor a
+ call CreateArenaOrBenchEnergyCardList
+ ld hl, wDuelTempList
+; put all energy cards in Discard Pile
+.loop
+ ld a, [hli]
+ cp $ff
+ ret z
+ call PutCardInDiscardPile
+ jr .loop
+
+ThunderstormEffect: ; 2e429 (b:6429)
+ ld a, 1
+ ldh [hCurSelectionItem], a
+
+ call SwapTurn
+ ld a, DUELVARS_NUMBER_OF_POKEMON_IN_PLAY_AREA
+ call GetTurnDuelistVariable
+ ld c, a
+ ld b, 0
+ ld e, b
+ jr .next_pkmn
+
+.check_damage
+ push de
+ push bc
+ call .DisplayText
+ ld de, $0
+ call SwapTurn
+ call TossCoin_BankB
+ call SwapTurn
+ push af
+ call GetNextPositionInTempList
+ pop af
+ ld [hl], a ; store result in list
+ pop bc
+ pop de
+ jr c, .next_pkmn
+ inc b ; increase number of tails
+
+.next_pkmn
+ inc e
+ dec c
+ jr nz, .check_damage
+
+; all coins were tossed for each Benched Pokemon
+ call GetNextPositionInTempList
+ ld [hl], $ff
+ ld a, b
+ ldh [hTemp_ffa0], a
+ call Func_3b21
+ call SwapTurn
+
+; tally recoil damage
+ ldh a, [hTemp_ffa0]
+ or a
+ jr z, .skip_recoil
+ ; deal number of tails times 10 to self
+ call ATimes10
+ call DealRecoilDamageToSelf
+.skip_recoil
+
+; deal damage for Bench Pokemon that got heads
+ call SwapTurn
+ ld hl, hTempPlayAreaLocation_ffa1
+ ld b, PLAY_AREA_BENCH_1
+.loop_bench
+ ld a, [hli]
+ cp $ff
+ jr z, .done
+ or a
+ jr z, .skip_damage ; skip if tails
+ ld de, 20
+ call DealDamageToPlayAreaPokemon_RegularAnim
+.skip_damage
+ inc b
+ jr .loop_bench
+
+.done
+ call SwapTurn
+ ret
+
+; displays text for current Bench Pokemon,
+; printing its Bench number and name.
+.DisplayText ; 2e491 (b:6491)
+ ld b, e
+ ldtx hl, BenchText
+ ld de, wDefaultText
+ call CopyText
+ ld a, $30 ; 0 FW character
+ add b
+ ld [de], a
+ inc de
+ ld a, $20 ; space FW character
+ ld [de], a
+ inc de
+
+ ld a, DUELVARS_ARENA_CARD
+ add b
+ call GetTurnDuelistVariable
+ call LoadCardDataToBuffer2_FromDeckIndex
+ ld hl, wLoadedCard2Name
+ ld a, [hli]
+ ld h, [hl]
+ ld l, a
+ call CopyText
+
+ xor a
+ ld [wDuelDisplayedScreen], a
+ ret
+
+JolteonQuickAttack_AIEffect: ; 2e4bb (b:64bb)
+ ld a, (10 + 30) / 2
+ lb de, 10, 30
+ jp SetExpectedAIDamage
+
+JolteonQuickAttack_DamageBoostEffect: ; 2e4c3 (b:64c3)
+ ld hl, 20
+ call LoadTxRam3
+ ldtx de, DamageCheckIfHeadsPlusDamageText
+ call TossCoin_BankB
+ ret nc ; return if tails
+ ld a, 20
+ call AddToDamage
+ ret
+
+PinMissile_AIEffect: ; 2e4d6 (b:64d6)
+ ld a, (20 * 4) / 2
+ lb de, 0, 80
+ jp SetExpectedAIDamage
+
+PinMissile_MultiplierEffect: ; 2e4de (b:64de)
+ ld hl, 20
+ call LoadTxRam3
+ ldtx de, DamageCheckIfHeadsXDamageText
+ ld a, 4
+ call TossCoinATimes_BankB
+ add a ; a = 2 * heads
+ call ATimes10
+ call SetDefiniteDamage
+ ret
+
+Fly_AIEffect: ; 2e4f4 (b:64f4)
+ ld a, 30 / 2
+ lb de, 0, 30
+ jp SetExpectedAIDamage
+
+Fly_Success50PercentEffect: ; 2e4fc (b:64fc)
+ ldtx de, SuccessCheckIfHeadsAttackIsSuccessfulText
+ call TossCoin_BankB
+ jr c, .heads
+ xor a ; ATK_ANIM_NONE
+ ld [wLoadedAttackAnimation], a
+ call SetDefiniteDamage
+ call SetWasUnsuccessful
+ ret
+.heads
+ ld a, ATK_ANIM_AGILITY_PROTECT
+ ld [wLoadedAttackAnimation], a
+ ld a, SUBSTATUS1_FLY
+ call ApplySubstatus1ToDefendingCard
+ ret
+
+ThunderJolt_Recoil50PercentEffect: ; 2e51a (b:651a)
+ ld hl, 10
+ call LoadTxRam3
+ ldtx de, IfTailsDamageToYourselfTooText
+ call TossCoin_BankB
+ ldh [hTemp_ffa0], a
+ ret
+
+ThunderJolt_RecoilEffect: ; 2e529 (b:6529)
+ ld hl, 10
+ call LoadTxRam3
+ ldh a, [hTemp_ffa0]
+ or a
+ ret nz ; return if was heads
+ ld a, 10
+ call DealRecoilDamageToSelf
+ ret
+
+Spark_PlayerSelectEffect: ; 2e539 (b:6539)
+ ld a, $ff
+ ldh [hTemp_ffa0], a
+ ld a, DUELVARS_NUMBER_OF_POKEMON_IN_PLAY_AREA
+ call GetNonTurnDuelistVariable
+ cp 2
+ ret c ; has no Bench Pokemon
+
+ ldtx hl, ChoosePkmnInTheBenchToGiveDamageText
+ call DrawWideTextBox_WaitForInput
+ call SwapTurn
+ bank1call HasAlivePokemonInBench
+
+ ; the following two instructions can be removed
+ ; since Player selection will overwrite it.
+ ld a, PLAY_AREA_BENCH_1
+ ldh [hTempPlayAreaLocation_ff9d], a
+
+.loop_input
+ bank1call OpenPlayAreaScreenForSelection
+ jr c, .loop_input
+ ldh a, [hTempPlayAreaLocation_ff9d]
+ ldh [hTemp_ffa0], a
+ call SwapTurn
+ ret
+
+Spark_AISelectEffect: ; 2e562 (b:6562)
+ ld a, $ff
+ ldh [hTemp_ffa0], a
+ ld a, DUELVARS_NUMBER_OF_POKEMON_IN_PLAY_AREA
+ call GetNonTurnDuelistVariable
+ cp 2
+ ret c ; has no Bench Pokemon
+; AI always picks Pokemon with lowest HP remaining
+ call GetBenchPokemonWithLowestHP
+ ldh [hTemp_ffa0], a
+ ret
+
+Spark_BenchDamageEffect: ; 2e574 (b:6574)
+ ldh a, [hTemp_ffa0]
+ cp $ff
+ ret z
+ call SwapTurn
+ ldh a, [hTemp_ffa0]
+ ld b, a
+ ld de, 10
+ call DealDamageToPlayAreaPokemon_RegularAnim
+ call SwapTurn
+ ret
+
+Pikachu3GrowlEffect: ; 2e589 (b:6589)
+ ld a, SUBSTATUS2_GROWL
+ call ApplySubstatus2ToDefendingCard
+ ret
+
+Pikachu4GrowlEffect: ; 2e58f (b:658f)
+ ld a, SUBSTATUS2_GROWL
+ call ApplySubstatus2ToDefendingCard
+ ret
+
+ChainLightningEffect: ; 2e595 (b:6595)
+ ld a, 10
+ call SetDefiniteDamage
+ call SwapTurn
+ call GetArenaCardColor
+ call SwapTurn
+ ldh [hCurSelectionItem], a
+ cp COLORLESS
+ ret z ; don't damage if colorless
+
+; opponent's Bench
+ call SwapTurn
+ call .DamageSameColorBench
+ call SwapTurn
+
+; own Bench
+ ld a, $01
+ ld [wIsDamageToSelf], a
+ call .DamageSameColorBench
+ ret
+
+.DamageSameColorBench ; 2e5ba (b:65ba)
+ ld a, DUELVARS_NUMBER_OF_POKEMON_IN_PLAY_AREA
+ call GetTurnDuelistVariable
+ ld e, a
+ ld d, PLAY_AREA_ARENA
+ jr .next_bench
+
+.check_damage
+ ld a, d
+ call GetPlayAreaCardColor
+ ld c, a
+ ldh a, [hCurSelectionItem]
+ cp c
+ jr nz, .next_bench ; skip if not same color
+; apply damage to this Bench card
+ push de
+ ld b, d
+ ld de, 10
+ call DealDamageToPlayAreaPokemon_RegularAnim
+ pop de
+
+.next_bench
+ inc d
+ dec e
+ jr nz, .check_damage
+ ret
+
+RaichuAgilityEffect: ; 2e5dc (b:65dc)
+ ldtx de, IfHeadsDoNotReceiveDamageOrEffectText
+ call TossCoin_BankB
+ ret nc ; skip if got tails
+ ld a, ATK_ANIM_AGILITY_PROTECT
+ ld [wLoadedAttackAnimation], a
+ ld a, SUBSTATUS1_AGILITY
+ call ApplySubstatus1ToDefendingCard
+ ret
+
+RaichuThunder_Recoil50PercentEffect: ; 2e5ee (b:65ee)
+ ld hl, 30
+ call LoadTxRam3
+ ldtx de, IfTailsDamageToYourselfTooText
+ call TossCoin_BankB
+ ldh [hTemp_ffa0], a
+ ret
+
+RaichuThunder_RecoilEffect: ; 2e5fd (b:65fd)
+ ld hl, 30
+ call LoadTxRam3
+ ldh a, [hTemp_ffa0]
+ or a
+ ret nz ; return if got heads
+ ld a, 30
+ call DealRecoilDamageToSelf
+ ret
+
+Gigashock_PlayerSelectEffect: ; 2e60d (b:660d)
+ call SwapTurn
+ ld a, DUELVARS_NUMBER_OF_POKEMON_IN_PLAY_AREA
+ call GetTurnDuelistVariable
+ cp 2
+ jr nc, .has_bench
+ call SwapTurn
+ ld a, $ff
+ ldh [hTempList], a
+ ret
+
+.has_bench
+ ldtx hl, ChooseUpTo3PkmnOnBenchToGiveDamageText
+ call DrawWideTextBox_WaitForInput
+
+; init number of items in list and cursor position
+ xor a
+ ldh [hCurSelectionItem], a
+ ld [wce72], a
+ bank1call Func_61a1
+.start
+ bank1call PrintPlayAreaCardList_EnableLCD
+ push af
+ ld a, [wce72]
+ ld hl, BenchSelectionMenuParameters
+ call InitializeMenuParameters
+ pop af
+
+; exclude Arena Pokemon from number of items
+ dec a
+ ld [wNumMenuItems], a
+
+.loop_input
+ call DoFrame
+ call HandleMenuInput
+ jr nc, .loop_input
+ cp -1
+ jr z, .try_cancel
+
+ ld [wce72], a
+ call .CheckIfChosenAlready
+ jr nc, .not_chosen
+ ; play SFX
+ call Func_3794
+ jr .loop_input
+
+.not_chosen
+; mark this Play Area location
+ ldh a, [hCurMenuItem]
+ inc a
+ ld b, SYM_LIGHTNING
+ call DrawSymbolOnPlayAreaCursor
+; store it in the list of chosen Bench Pokemon
+ call GetNextPositionInTempList
+ ldh a, [hCurMenuItem]
+ inc a
+ ld [hl], a
+
+; check if 3 were chosen already
+ ldh a, [hCurSelectionItem]
+ ld c, a
+ cp 3
+ jr nc, .chosen ; check if already chose 3
+
+ ld a, DUELVARS_NUMBER_OF_POKEMON_IN_PLAY_AREA
+ call GetTurnDuelistVariable
+ dec a
+ cp c
+ jr nz, .start ; if sill more options available, loop back
+ ; fallthrough if no other options available to choose
+
+.chosen
+ ldh a, [hCurMenuItem]
+ inc a
+ call Func_2c10b
+ ldh a, [hKeysPressed]
+ and B_BUTTON
+ jr nz, .try_cancel
+ call SwapTurn
+ call GetNextPositionInTempList
+ ld [hl], $ff ; terminating byte
+ ret
+
+.try_cancel
+ ldh a, [hCurSelectionItem]
+ or a
+ jr z, .start ; none selected, can safely loop back to start
+
+; undo last selection made
+ dec a
+ ldh [hCurSelectionItem], a
+ ld e, a
+ ld d, $00
+ ld hl, hTempList
+ add hl, de
+ ld a, [hl]
+
+ push af
+ ld b, SYM_SPACE
+ call DrawSymbolOnPlayAreaCursor
+ call EraseCursor
+ pop af
+
+ dec a
+ ld [wce72], a
+ jr .start
+
+; returns carry if Bench Pokemon
+; in register a was already chosen.
+.CheckIfChosenAlready: ; 2e6af (b:66af)
+ inc a
+ ld c, a
+ ldh a, [hCurSelectionItem]
+ ld b, a
+ ld hl, hTempList
+ inc b
+ jr .next_check
+.check_chosen
+ ld a, [hli]
+ cp c
+ scf
+ ret z ; return if chosen already
+.next_check
+ dec b
+ jr nz, .check_chosen
+ or a
+ ret
+
+Gigashock_AISelectEffect: ; 2e6c3 (b:66c3)
+; if Bench has 3 Pokemon or less, no need for selection,
+; since AI will choose them all.
+ ld a, DUELVARS_NUMBER_OF_POKEMON_IN_PLAY_AREA
+ call GetNonTurnDuelistVariable
+ cp MAX_PLAY_AREA_POKEMON - 1
+ jr nc, .start_selection
+
+; select them all
+ ld hl, hTempList
+ ld b, PLAY_AREA_ARENA
+ jr .next_bench
+.select_bench
+ ld [hl], b
+ inc hl
+.next_bench
+ inc b
+ dec a
+ jr nz, .select_bench
+ ld [hl], $ff ; terminating byte
+ ret
+
+.start_selection
+; has more than 3 Bench cards, proceed to sort them
+; by lowest remaining HP to highest, and pick first 3.
+ call SwapTurn
+ dec a
+ ld c, a
+ ld b, PLAY_AREA_BENCH_1
+
+; first select all of the Bench Pokemon and write to list
+ ld hl, hTempList
+.loop_all
+ ld [hl], b
+ inc hl
+ inc b
+ dec c
+ jr nz, .loop_all
+ ld [hl], $00 ; end list with $00
+
+; then check each of the Bench Pokemon HP
+; sort them from lowest remaining HP to highest.
+ ld de, hTempList
+.loop_outer
+ ld a, [de]
+ add DUELVARS_ARENA_CARD_HP
+ call GetTurnDuelistVariable
+ ld c, a
+ ld l, e
+ ld h, d
+ inc hl
+
+.loop_inner
+ ld a, [hli]
+ or a
+ jr z, .next ; reaching $00 means it's end of list
+
+ push hl
+ add DUELVARS_ARENA_CARD_HP
+ call GetTurnDuelistVariable
+ pop hl
+ cp c
+ jr c, .loop_inner
+ ; a Bench Pokemon was found with less HP
+ ld c, a ; store its HP
+
+; switch the two
+ dec hl
+ ld b, [hl]
+ ld a, [de]
+ ld [hli], a
+ ld a, b
+ ld [de], a
+ jr .loop_inner
+
+.next
+ inc de
+ ld a, [de]
+ or a
+ jr nz, .loop_outer
+
+; done
+ ld a, $ff ; terminating byte
+ ldh [hTempList + 3], a
+ call SwapTurn
+ ret
+
+Gigashock_BenchDamageEffect: ; 2e71f (b:671f)
+ call SwapTurn
+ ld hl, hTempList
+.loop_selection
+ ld a, [hli]
+ cp $ff
+ jr z, .done
+ push hl
+ ld b, a
+ ld de, 10
+ call DealDamageToPlayAreaPokemon_RegularAnim
+ pop hl
+ jr .loop_selection
+.done
+ call SwapTurn
+ ret
+
+Magneton1SelfdestructEffect: ; 2e739 (b:6739)
+ ld a, 80
+ call DealRecoilDamageToSelf
+
+; own bench
+ ld a, $01
+ ld [wIsDamageToSelf], a
+ ld a, 20
+ call DealDamageToAllBenchedPokemon
+
+; opponent's bench
+ call SwapTurn
+ xor a
+ ld [wIsDamageToSelf], a
+ ld a, 20
+ call DealDamageToAllBenchedPokemon
+ call SwapTurn
+ ret
+
+MagnetonSonicboom_UnaffectedByColorEffect: ; 2e758 (b:6758)
+ ld hl, wDamage + 1
+ set UNAFFECTED_BY_WEAKNESS_RESISTANCE_F, [hl]
+ ret
+
+MagnetonSonicboom_NullEffect: ; 2e75e (b:675e)
+ ret
+
+Magneton2SelfdestructEffect: ; 2e75f (b:675f)
+ ld a, 100
+ call DealRecoilDamageToSelf
+
+; own bench
+ ld a, $01
+ ld [wIsDamageToSelf], a
+ ld a, 20
+ call DealDamageToAllBenchedPokemon
+
+; opponent's bench
+ call SwapTurn
+ xor a
+ ld [wIsDamageToSelf], a
+ ld a, 20
+ call DealDamageToAllBenchedPokemon
+ call SwapTurn
+ ret
+
+PealOfThunder_InitialEffect: ; 2e77e (b:677e)
+ scf
+ ret
+
+PealOfThunder_RandomlyDamageEffect: ; 2e780 (b:6780)
+ call ExchangeRNG
+ ld de, 30 ; damage to inflict
+ call RandomlyDamagePlayAreaPokemon
+ bank1call Func_6e49
+ ret
+
+; randomly damages a Pokemon in play, except
+; card that is in [hTempPlayAreaLocation_ff9d].
+; plays thunder animation when Play Area is shown.
+; input:
+; de = amount of damage to deal
+RandomlyDamagePlayAreaPokemon: ; 2e78d (b:678d)
+ xor a
+ ld [wNoDamageOrEffect], a
+
+; choose randomly which Play Area to attack
+ call UpdateRNGSources
+ and 1
+ jr nz, .opp_play_area
+
+; own Play Area
+ ld a, $01
+ ld [wIsDamageToSelf], a
+ ld a, DUELVARS_NUMBER_OF_POKEMON_IN_PLAY_AREA
+ call GetTurnDuelistVariable
+ call Random
+ ld b, a
+ ; can't select Zapdos
+ ldh a, [hTempPlayAreaLocation_ff9d]
+ cp b
+ jr z, RandomlyDamagePlayAreaPokemon ; re-roll Pokemon to attack
+
+.damage
+ ld a, ATK_ANIM_THUNDER_PLAY_AREA
+ ld [wLoadedAttackAnimation], a
+ call DealDamageToPlayAreaPokemon
+ ret
+
+.opp_play_area
+ xor a
+ ld [wIsDamageToSelf], a
+ call SwapTurn
+ ld a, DUELVARS_NUMBER_OF_POKEMON_IN_PLAY_AREA
+ call GetTurnDuelistVariable
+ call Random
+ ld b, a
+ call .damage
+ call SwapTurn
+ ret
+
+BigThunderEffect: ; 2e7cb (b:67cb)
+ call ExchangeRNG
+ ld de, 70 ; damage to inflict
+ call RandomlyDamagePlayAreaPokemon
+ ret
+
+MagneticStormEffect: ; 2e7d5 (b:67d5)
+ ld a, DUELVARS_CARD_LOCATIONS
+ call GetTurnDuelistVariable
+
+; writes in wDuelTempList all deck indices
+; of Energy cards attached to Pokemon
+; in the Turn Duelist's Play Area.
+ ld de, wDuelTempList
+ ld c, 0
+.loop_card_locations
+ ld a, [hl]
+ and CARD_LOCATION_PLAY_AREA
+ jr z, .next_card_location
+
+; is a card that is in the Play Area
+ push hl
+ push de
+ push bc
+ ld a, l
+ call GetCardIDFromDeckIndex
+ call GetCardType
+ pop bc
+ pop de
+ pop hl
+ and TYPE_ENERGY
+ jr z, .next_card_location
+; is an Energy card attached to Pokemon in Play Area
+ ld a, l
+ ld [de], a
+ inc de
+ inc c
+.next_card_location
+ inc l
+ ld a, l
+ cp DECK_SIZE
+ jr c, .loop_card_locations
+ ld a, $ff ; terminating byte
+ ld [de], a
+
+; divide number of energy cards
+; by number of Pokemon in Play Area
+ ld a, DUELVARS_NUMBER_OF_POKEMON_IN_PLAY_AREA
+ call GetTurnDuelistVariable
+ ld b, a
+ ld a, c
+ ld c, -1
+.loop_division
+ inc c
+ sub b
+ jr nc, .loop_division
+ ; c = floor(a / b)
+
+; evenly divides the Energy cards randomly
+; to every Pokemon in the Play Area.
+ push bc
+ ld hl, wDuelTempList
+ call CountCardsInDuelTempList
+ call ShuffleCards
+ ld d, c
+ ld e, PLAY_AREA_ARENA
+.start_attach
+ ld c, d
+ inc c
+ jr .check_done
+.attach_energy
+ ld a, [hli]
+ push hl
+ push de
+ push bc
+ call AddCardToHand
+ call PutHandCardInPlayArea
+ pop bc
+ pop de
+ pop hl
+.check_done
+ dec c
+ jr nz, .attach_energy
+; go to next Pokemon in Play Area
+ inc e ; next in Play Area
+ dec b
+ jr nz, .start_attach
+ pop bc
+
+ push hl
+ ld hl, hTempList
+
+; fill hTempList with PLAY_AREA_* locations
+; that have Pokemon in them.
+ push hl
+ xor a
+.loop_init
+ ld [hli], a
+ inc a
+ cp b
+ jr nz, .loop_init
+ pop hl
+
+; shuffle them and distribute
+; the remaining cards in random order.
+ ld a, b
+ call ShuffleCards
+ pop hl
+ ld de, hTempList
+.next_random_pokemon
+ ld a, [hl]
+ cp $ff
+ jr z, .done
+ push hl
+ push de
+ ld a, [de]
+ ld e, a
+ ld a, [hl]
+ call AddCardToHand
+ call PutHandCardInPlayArea
+ pop de
+ pop hl
+ inc hl
+ inc de
+ jr .next_random_pokemon
+
+.done
+ bank1call DrawDuelMainScene
+ bank1call DrawDuelHUDs
+ ldtx hl, TheEnergyCardFromPlayAreaWasMovedText
+ call DrawWideTextBox_WaitForInput
+ xor a
+ call Func_2c10b
+ ret
+
+ElectrodeSonicboom_UnaffectedByColorEffect: ; 2e870 (b:6870)
+ ld hl, wDamage + 1
+ set UNAFFECTED_BY_WEAKNESS_RESISTANCE_F, [hl]
+ ret
+
+ElectrodeSonicboom_NullEffect: ; 2e876 (b:6876)
+ ret
+
+; return carry if no cards in Deck
+EnergySpike_DeckCheck: ; 2e877 (b:6877)
+ call CheckIfDeckIsEmpty
+ ret
+
+EnergySpike_PlayerSelectEffect: ; 2e87b (b:687b)
+ ld a, $ff
+ ldh [hTemp_ffa0], a
+
+; search cards in Deck
+ call CreateDeckCardList
+ ldtx hl, Choose1BasicEnergyCardFromDeckText
+ ldtx bc, BasicEnergyText
+ lb de, SEARCHEFFECT_BASIC_ENERGY, 0
+ call LookForCardsInDeck
+ ret c
+
+ bank1call Func_5591
+ ldtx hl, ChooseBasicEnergyCardText
+ ldtx de, DuelistDeckText
+ bank1call SetCardListHeaderText
+.select_card
+ bank1call DisplayCardList
+ jr c, .try_cancel
+ call GetCardIDFromDeckIndex
+ call GetCardType
+ cp TYPE_ENERGY_DOUBLE_COLORLESS
+ jr nc, .select_card ; not a Basic Energy card
+ and TYPE_ENERGY
+ jr z, .select_card ; not a Basic Energy card
+ ; Energy card selected
+
+ ldh a, [hTempCardIndex_ff98]
+ ldh [hTemp_ffa0], a
+ call EmptyScreen
+ ldtx hl, ChoosePokemonToAttachEnergyCardText
+ call DrawWideTextBox_WaitForInput
+
+; choose a Pokemon in Play Area to attach card
+ bank1call HasAlivePokemonInPlayArea
+.loop_input
+ bank1call OpenPlayAreaScreenForSelection
+ jr c, .loop_input
+ ldh a, [hTempPlayAreaLocation_ff9d]
+ ldh [hTempPlayAreaLocation_ffa1], a
+ ret
+
+.play_sfx
+ call Func_3794
+ jr .select_card
+
+.try_cancel
+; Player tried exiting screen, if there are
+; any Basic Energy cards, Player is forced to select them.
+; otherwise, they can safely exit.
+ ld a, DUELVARS_CARD_LOCATIONS
+ call GetTurnDuelistVariable
+.loop_deck
+ ld a, [hl]
+ cp CARD_LOCATION_DECK
+ jr nz, .next_card
+ ld a, l
+ call GetCardIDFromDeckIndex
+ call GetCardType
+ and TYPE_ENERGY
+ jr z, .next_card
+ cp TYPE_ENERGY_DOUBLE_COLORLESS
+ jr c, .play_sfx
+.next_card
+ inc l
+ ld a, l
+ cp DECK_SIZE
+ jr c, .loop_deck
+ ; can exit
+
+ ld a, $ff
+ ldh [hTemp_ffa0], a
+ ret
+
+EnergySpike_AISelectEffect: ; 2e8f1 (b:68f1)
+; AI doesn't select any card
+ ld a, $ff
+ ldh [hTemp_ffa0], a
+ ret
+
+EnergySpike_AttachEnergyEffect: ; 2e8f6 (b:68f6)
+ ldh a, [hTemp_ffa0]
+ cp $ff
+ jr z, .done
+
+; add card to hand and attach it to the selected Pokemon
+ call SearchCardInDeckAndAddToHand
+ call AddCardToHand
+ ldh a, [hTempPlayAreaLocation_ffa1]
+ ld e, a
+ ldh a, [hTemp_ffa0]
+ call PutHandCardInPlayArea
+ call IsPlayerTurn
+ jr c, .done
+
+; not Player, so show detail screen
+; and which Pokemon was chosen to attach Energy.
+ ldh a, [hTempPlayAreaLocation_ffa1]
+ add DUELVARS_ARENA_CARD
+ call GetTurnDuelistVariable
+ call LoadCardDataToBuffer1_FromDeckIndex
+ ld hl, wLoadedCard1Name
+ ld de, wTxRam2_b
+ ld a, [hli]
+ ld [de], a
+ inc de
+ ld a, [hli]
+ ld [de], a
+ ldh a, [hTemp_ffa0]
+ ldtx hl, AttachedEnergyToPokemonText
+ bank1call DisplayCardDetailScreen
+
+.done
+ call Func_2c0bd
+ ret
+
+JolteonDoubleKick_AIEffect: ; 2e930 (b:6930)
+ ld a, 40 / 2
+ lb de, 0, 40
+ jp SetExpectedAIDamage
+
+JolteonDoubleKick_MultiplierEffect: ; 2e938 (b:6938)
+ ld hl, 20
+ call LoadTxRam3
+ ldtx de, DamageCheckIfHeadsXDamageText
+ ld a, 2
+ call TossCoinATimes_BankB
+ add a ; a = 2 * heads
+ call ATimes10
+ call SetDefiniteDamage
+ ret
+
+TailWagEffect: ; 2e94e (b:694e)
+ ldtx de, IfHeadsOpponentCannotAttackText
+ call TossCoin_BankB
+ jp nc, SetWasUnsuccessful
+ ld a, ATK_ANIM_LURE
+ ld [wLoadedAttackAnimation], a
+ ld a, SUBSTATUS2_TAIL_WAG
+ call ApplySubstatus2ToDefendingCard
+ ret
+
+EeveeQuickAttack_AIEffect: ; 2e962 (b:5962)
+ ld a, (10 + 30) / 2
+ lb de, 10, 30
+ jp SetExpectedAIDamage
+
+EeveeQuickAttack_DamageBoostEffect: ; 2e96a (b:596a)
+ ld hl, 20
+ call LoadTxRam3
+ ldtx de, DamageCheckIfHeadsPlusDamageText
+ call TossCoin_BankB
+ ret nc ; return if tails
+ ld a, 20
+ call AddToDamage
+ ret
+
+SpearowMirrorMove_AIEffect: ; 2e97d (b:697d)
+ jr MirrorMoveEffects.AIEffect
+
+SpearowMirrorMove_InitialEffect1: ; 2e97f (b:697f)
+ jr MirrorMoveEffects.InitialEffect1
+
+SpearowMirrorMove_InitialEffect2: ; 2e981 (b:6981)
+ jr MirrorMoveEffects.InitialEffect2
+
+SpearowMirrorMove_PlayerSelection: ; 2e983 (b:6983)
+ jr MirrorMoveEffects.PlayerSelection
+
+SpearowMirrorMove_AISelection: ; 2e985 (b:6985)
+ jr MirrorMoveEffects.AISelection
+
+SpearowMirrorMove_BeforeDamage: ; 2e987 (b:6987)
+ jr MirrorMoveEffects.BeforeDamage
+
+SpearowMirrorMove_AfterDamage: ; 2e989 (b:6989)
+ jp MirrorMoveEffects.AfterDamage
+
+; these are effect commands that Mirror Move uses
+; in order to mimic last turn's attack.
+; it covers all possible effect steps to perform its commands
+; (i.e. selection for Amnesia and Energy discarding attacks, etc)
+MirrorMoveEffects: ; 2e98c (b:698c)
+.AIEffect
+ ld a, DUELVARS_ARENA_CARD_LAST_TURN_DAMAGE
+ call GetTurnDuelistVariable
+ ld a, [hl]
+ ld [wAIMinDamage], a
+ ld [wAIMaxDamage], a
+ ret
+
+.InitialEffect1
+ ld a, DUELVARS_ARENA_CARD_LAST_TURN_DAMAGE
+ call GetTurnDuelistVariable
+ ld a, [hli]
+ or [hl]
+ inc hl
+ or [hl]
+ inc hl
+ ret nz ; return if has last turn damage
+ ld a, [hli]
+ or a
+ ret nz ; return if has last turn status
+ ; no attack received last turn
+ ldtx hl, YouDidNotReceiveAnAttackToMirrorMoveText
+ scf
+ ret
+
+.InitialEffect2
+ ld a, $ff
+ ldh [hTemp_ffa0], a
+ ld a, DUELVARS_ARENA_CARD_LAST_TURN_EFFECT
+ call GetTurnDuelistVariable
+ or a
+ ret z ; no effect
+ cp LAST_TURN_EFFECT_AMNESIA
+ jp z, PlayerPickAttackForAmnesia
+ or a
+ ret
+
+.PlayerSelection
+ ld a, DUELVARS_ARENA_CARD_LAST_TURN_EFFECT
+ call GetTurnDuelistVariable
+ or a
+ ret z ; no effect
+; handle Energy card discard effect
+ cp LAST_TURN_EFFECT_DISCARD_ENERGY
+ jp z, HandleEnergyDiscardEffectSelection
+ ret
+
+.AISelection
+ ld a, $ff
+ ldh [hTemp_ffa0], a
+ ld a, DUELVARS_ARENA_CARD_LAST_TURN_EFFECT
+ call GetTurnDuelistVariable
+ or a
+ ret z ; no effect
+ cp LAST_TURN_EFFECT_DISCARD_ENERGY
+ jr z, .discard_energy
+ cp LAST_TURN_EFFECT_AMNESIA
+ jr z, .pick_amnesia_attack
+ ret
+
+.discard_energy
+ call AIPickEnergyCardToDiscardFromDefendingPokemon
+ ldh [hTemp_ffa0], a
+ ret
+
+.pick_amnesia_attack
+ call AIPickAttackForAmnesia
+ ldh [hTemp_ffa0], a
+ ret
+
+.BeforeDamage
+; if was attacked with Amnesia, apply it to the selected attack
+ ld a, DUELVARS_ARENA_CARD_LAST_TURN_EFFECT
+ call GetTurnDuelistVariable
+ cp LAST_TURN_EFFECT_AMNESIA
+ jr z, .apply_amnesia
+
+; otherwise, check if there was last turn damage,
+; and write it to wDamage.
+ ld a, DUELVARS_ARENA_CARD_LAST_TURN_DAMAGE
+ call GetTurnDuelistVariable
+ ld de, wDamage
+ ld a, [hli]
+ ld [de], a
+ inc de
+ ld a, [hld]
+ ld [de], a
+ or [hl]
+ jr z, .no_damage
+ ld a, ATK_ANIM_HIT
+ ld [wLoadedAttackAnimation], a
+.no_damage
+ inc hl
+ inc hl ; DUELVARS_ARENA_CARD_LAST_TURN_STATUS
+; check if there was a status applied to Defending Pokemon
+; from the attack it used.
+ push hl
+ ld a, DUELVARS_ARENA_CARD_STATUS
+ call GetNonTurnDuelistVariable
+ ld e, l
+ ld d, h
+ pop hl
+ ld a, [hli]
+ or a
+ jr z, .no_status
+ push hl
+ push de
+ call .ExecuteStatusEffect
+ pop de
+ pop hl
+.no_status
+; hl is at DUELVARS_ARENA_CARD_LAST_TURN_SUBSTATUS2
+; apply substatus2 to self
+ ld e, DUELVARS_ARENA_CARD_SUBSTATUS2
+ ld a, [hli]
+ ld [de], a
+ ret
+
+.apply_amnesia
+ call ApplyAmnesiaToAttack
+ ret
+
+.AfterDamage: ; 2ea28 (b:6a28)
+ ld a, [wNoDamageOrEffect]
+ or a
+ ret nz ; is unaffected
+ ld a, DUELVARS_ARENA_CARD_LAST_TURN_EFFECT
+ call GetTurnDuelistVariable
+ cp LAST_TURN_EFFECT_DISCARD_ENERGY
+ jr nz, .change_weakness
+
+; execute Energy discard effect for card chosen
+ call SwapTurn
+ ldh a, [hTemp_ffa0]
+ call PutCardInDiscardPile
+ ld a, DUELVARS_ARENA_CARD_LAST_TURN_EFFECT
+ call GetTurnDuelistVariable
+ ld [hl], LAST_TURN_EFFECT_DISCARD_ENERGY
+ call SwapTurn
+
+.change_weakness
+ ld a, DUELVARS_ARENA_CARD_LAST_TURN_CHANGE_WEAK
+ call GetTurnDuelistVariable
+ ld a, [hl]
+ or a
+ ret z ; weakness wasn't changed last turn
+
+ push hl
+ call SwapTurn
+ ld a, DUELVARS_ARENA_CARD
+ call GetTurnDuelistVariable
+ call LoadCardDataToBuffer2_FromDeckIndex
+ call SwapTurn
+ pop hl
+
+ ld a, [wLoadedCard2Weakness]
+ or a
+ ret z ; defending Pokemon has no weakness to change
+
+; apply same color weakness to Defending Pokemon
+ ld a, [hl]
+ push af
+ ld a, DUELVARS_ARENA_CARD_CHANGED_WEAKNESS
+ call GetNonTurnDuelistVariable
+ pop af
+ ld [hl], a
+
+; print message of weakness color change
+ ld c, -1
+.loop_color
+ inc c
+ rla
+ jr nc, .loop_color
+ ld a, c
+ call SwapTurn
+ push af
+ ld a, DUELVARS_ARENA_CARD
+ call GetTurnDuelistVariable
+ call LoadCardDataToBuffer1_FromDeckIndex
+ pop af
+ call LoadCardNameAndInputColor
+ ldtx hl, ChangedTheWeaknessOfPokemonToColorText
+ call DrawWideTextBox_PrintText
+ call SwapTurn
+ ret
+
+.ExecuteStatusEffect: ; 2ea8f (b:6a8f)
+ ld c, a
+ and PSN_DBLPSN
+ jr z, .cnf_slp_prz
+ ld b, a
+ cp DOUBLE_POISONED
+ push bc
+ call z, DoublePoisonEffect
+ pop bc
+ ld a, b
+ cp POISONED
+ push bc
+ call z, PoisonEffect
+ pop bc
+.cnf_slp_prz
+ ld a, c
+ and CNF_SLP_PRZ
+ ret z
+ cp CONFUSED
+ jp z, ConfusionEffect
+ cp ASLEEP
+ jp z, SleepEffect
+ cp PARALYZED
+ jp z, ParalysisEffect
+ ret
+
+FearowAgilityEffect: ; 2eab8 (b:6ab8)
+ ldtx de, IfHeadsDoNotReceiveDamageOrEffectText
+ call TossCoin_BankB
+ ret nc
+ ld a, ATK_ANIM_AGILITY_PROTECT
+ ld [wLoadedAttackAnimation], a
+ ld a, SUBSTATUS1_AGILITY
+ call ApplySubstatus1ToDefendingCard
+ ret
+
+; return carry if cannot use Step In
+StepIn_BenchCheck: ; 2eaca (b:6aca)
+ ldh a, [hTempPlayAreaLocation_ff9d]
+ ldh [hTemp_ffa0], a
+ ldtx hl, CanOnlyBeUsedOnTheBenchText
+ or a
+ jr z, .set_carry
+
+ add DUELVARS_ARENA_CARD_FLAGS
+ call GetTurnDuelistVariable
+ ldtx hl, OnlyOncePerTurnText
+ and USED_PKMN_POWER_THIS_TURN
+ jr nz, .set_carry
+
+ ldh a, [hTempPlayAreaLocation_ff9d]
+ call CheckCannotUseDueToStatus_OnlyToxicGasIfANon0
+ ret
+
+.set_carry
+ scf
+ ret
+
+StepIn_SwitchEffect: ; 2eae8 (b:6ae8)
+ ldh a, [hTemp_ffa0]
+ ld e, a
+ call SwapArenaWithBenchPokemon
+ ld a, DUELVARS_ARENA_CARD_FLAGS
+ call GetTurnDuelistVariable
+ set USED_PKMN_POWER_THIS_TURN_F, [hl]
+ ret
+
+Dragonite2Slam_AIEffect: ; 2eaf6 (b:6af6)
+ ld a, (40 * 2) / 2
+ lb de, 0, 80
+ jp SetExpectedAIDamage
+
+Dragonite2Slam_MultiplierEffect: ; 2eafe (b:6afe)
+ ld hl, 40
+ call LoadTxRam3
+ ldtx de, DamageCheckIfHeadsXDamageText
+ ld a, 2
+ call TossCoinATimes_BankB
+ add a
+ add a
+ call ATimes10
+ call SetDefiniteDamage
+ ret
+
+ThickSkinnedEffect: ; 2eb15 (b:6b15)
+ scf
+ ret
+
+LeekSlap_AIEffect: ; 2eb17 (b:6b17)
+ ld a, 30 / 2
+ lb de, 0, 30
+ jp SetExpectedAIDamage
+
+; return carry if already used attack in this duel
+LeekSlap_OncePerDuelCheck: ; 2eb1f (b:6b1f)
+; can only use attack if it was never used before this duel
+ ld a, DUELVARS_ARENA_CARD_FLAGS
+ call GetTurnDuelistVariable
+ and USED_LEEK_SLAP_THIS_DUEL
+ ret z
+ ldtx hl, ThisAttackCannotBeUsedTwiceText
+ scf
+ ret
+
+LeekSlap_SetUsedThisDuelFlag: ; 2eb2c (b:6b2c)
+ ld a, DUELVARS_ARENA_CARD_FLAGS
+ call GetTurnDuelistVariable
+ set USED_LEEK_SLAP_THIS_DUEL_F, [hl]
+ ret
+
+LeekSlap_NoDamage50PercentEffect: ; 2eb34 (b:6b34)
+ ldtx de, DamageCheckIfTailsNoDamageText
+ call TossCoin_BankB
+ ret c
+ xor a ; 0 damage
+ call SetDefiniteDamage
+ ret
+
+FetchEffect: ; 2eb40 (b:6b40)
+ ldtx hl, Draw1CardFromTheDeckText
+ call DrawWideTextBox_WaitForInput
+ bank1call DisplayDrawOneCardScreen
+ call DrawCardFromDeck
+ ret c ; return if deck is empty
+ call AddCardToHand
+ call LoadCardDataToBuffer1_FromDeckIndex
+ ld a, [wDuelistType]
+ cp DUELIST_TYPE_PLAYER
+ ret nz
+ ; show card on screen if it was Player
+ bank1call OpenCardPage_FromHand
+ ret
+
+CometPunch_AIEffect: ; 2eb5d (b:6b5d)
+ ld a, (20 * 4) / 2
+ lb de, 0, 80
+ jp SetExpectedAIDamage
+
+CometPunch_MultiplierEffect: ; 2eb65 (b:6b65)
+ ld hl, 20
+ call LoadTxRam3
+ ldtx de, DamageCheckIfHeadsXDamageText
+ ld a, 4
+ call TossCoinATimes_BankB
+ add a
+ call ATimes10
+ call SetDefiniteDamage
+ ret
+
+TaurosStomp_AIEffect: ; 2eb7b (b:6b7b)
+ ld a, (20 + 30) / 2
+ lb de, 20, 30
+ jp SetExpectedAIDamage
+
+TaurosStomp_DamageBoostEffect: ; 2eb83 (b:6b83)
+ ld hl, 10
+ call LoadTxRam3
+ ldtx de, DamageCheckIfHeadsPlusDamageText
+ call TossCoin_BankB
+ ret nc ; tails
+ ld a, 10
+ call AddToDamage
+ ret
+
+Rampage_AIEffect: ; 2eb96 (b:6b96)
+ ld e, PLAY_AREA_ARENA
+ call GetCardDamageAndMaxHP
+ call AddToDamage
+ jp SetDefiniteAIDamage
+
+Rampage_Confusion50PercentEffect: ; 2eba1 (b:6ba1)
+ ld e, PLAY_AREA_ARENA
+ call GetCardDamageAndMaxHP
+ call AddToDamage
+ ldtx de, IfTailsYourPokemonBecomesConfusedText
+ call TossCoin_BankB
+ ret c ; heads
+ call SwapTurn
+ call ConfusionEffect
+ call SwapTurn
+ ret
+
+FuryAttack_AIEffect: ; 2ebba (b:6bba)
+ ld a, (10 * 2) / 2
+ lb de, 0, 20
+ jp SetExpectedAIDamage
+
+FuryAttack_MultiplierEffect: ; 2ebc2 (b:6bc2)
+ ld hl, 10
+ call LoadTxRam3
+ ld a, 2
+ ldtx de, DamageCheckIfHeadsXDamageText
+ call TossCoinATimes_BankB
+ call ATimes10
+ call SetDefiniteDamage
+ ret
+
+RetreatAidEffect: ; 2ebd7 (b:6bd7)
+ scf
+ ret
+
+DodrioRage_AIEffect: ; 2ebd9 (b:6bd9)
+ call DodrioRage_DamageBoostEffect
+ jp SetDefiniteAIDamage
+
+DodrioRage_DamageBoostEffect: ; 2ebdf (b:6bdf)
+ ld e, PLAY_AREA_ARENA
+ call GetCardDamageAndMaxHP
+ call AddToDamage
+ ret
+
+PayDayEffect: ; 2ebe8 (b:6be8)
+ ldtx de, IfHeadsDraw1CardFromDeckText
+ call TossCoin_BankB
+ ret nc ; tails
+ ldtx hl, Draw1CardFromTheDeckText
+ call DrawWideTextBox_WaitForInput
+ bank1call DisplayDrawOneCardScreen
+ call DrawCardFromDeck
+ ret c ; empty deck
+ call AddCardToHand
+ call LoadCardDataToBuffer1_FromDeckIndex
+ ld a, [wDuelistType]
+ cp DUELIST_TYPE_PLAYER
+ ret nz
+ ; show card on screen if it was Player
+ bank1call OpenCardPage_FromHand
+ ret
+
+DragonairSlam_AIEffect: ; 2ec0c (b:6c0c)
+ ld a, (30 * 2) / 2
+ lb de, 0, 60
+ jp SetExpectedAIDamage
+
+DragonairSlam_MultiplierEffect: ; 2ec14 (b:6c14)
+ ld hl, 30
+ call LoadTxRam3
+ ld a, 2
+ ldtx de, DamageCheckIfHeadsXDamageText
+ call TossCoinATimes_BankB
+ ld e, a
+ add a
+ add e
+ call ATimes10
+ call SetDefiniteDamage
+ ret
+
+DragonairHyperBeam_PlayerSelectEffect: ; 2ec2c (b:6c2c)
+ jp HandleEnergyDiscardEffectSelection
+
+DragonairHyperBeam_AISelectEffect: ; 2ec2f (b:6c2f)
+ call AIPickEnergyCardToDiscardFromDefendingPokemon
+ ldh [hTemp_ffa0], a
+ ret
+
+DragonairHyperBeam_DiscardEffect: ; 2ec35 (b:6c35)
+ call HandleNoDamageOrEffect
+ ret c ; is unaffected
+ ldh a, [hTemp_ffa0]
+ cp $ff
+ ret z ; no energy card chosen
+ call SwapTurn
+ call PutCardInDiscardPile
+ ld a, DUELVARS_ARENA_CARD_LAST_TURN_EFFECT
+ call GetTurnDuelistVariable
+ ld [hl], LAST_TURN_EFFECT_DISCARD_ENERGY
+ call SwapTurn
+ ret
+
+; handles screen for selecting an Energy card to discard
+; that is attached to Defending Pokemon,
+; and store the Player selection in [hTemp_ffa0].
+HandleEnergyDiscardEffectSelection: ; 2ec4f (b:6c4f)
+ call SwapTurn
+ xor a ; PLAY_AREA_ARENA
+ call CreateArenaOrBenchEnergyCardList
+ jr c, .no_energy
+ ldtx hl, ChooseDiscardEnergyCardFromOpponentText
+ call DrawWideTextBox_WaitForInput
+ xor a ; PLAY_AREA_ARENA
+ bank1call DisplayEnergyDiscardScreen
+
+.loop_input
+ bank1call HandleEnergyDiscardMenuInput
+ jr c, .loop_input
+
+ call SwapTurn
+ ldh a, [hTempCardIndex_ff98]
+ ldh [hTemp_ffa0], a ; store selected card to discard
+ ret
+
+.no_energy
+ call SwapTurn
+ ld a, $ff
+ ldh [hTemp_ffa0], a
+ ret
+
+; return carry if Defending Pokemon has no attacks
+ClefableMetronome_CheckAttacks: ; 2ec77 (b:6c77)
+ call CheckIfDefendingPokemonHasAnyAttack
+ ldtx hl, NoAttackMayBeChoosenText
+ ret
+
+ClefableMetronome_AISelectEffect: ; 2ec7e (b:6c7e)
+ call HandleAIMetronomeEffect
+ ret
+
+ClefableMetronome_UseAttackEffect: ; 2ec82 (b:6c82)
+ ld a, 1 ; energy cost of this attack
+ call HandlePlayerMetronomeEffect
+ ret
+
+ClefableMinimizeEffect: ; 2ec88 (b:6c88)
+ ld a, SUBSTATUS1_REDUCE_BY_20
+ call ApplySubstatus1ToDefendingCard
+ ret
+
+HurricaneEffect: ; 2ec8e (b:6c8e)
+ call HandleNoDamageOrEffect
+ ret c ; is unaffected
+
+ ld a, DUELVARS_ARENA_CARD_HP
+ call GetNonTurnDuelistVariable
+ or a
+ ret z ; return if Pokemon was KO'd
+
+; look at all the card locations and put all cards
+; that are in the Arena in the hand.
+ call SwapTurn
+ ld a, DUELVARS_CARD_LOCATIONS
+ call GetTurnDuelistVariable
+.loop_locations
+ ld a, [hl]
+ cp CARD_LOCATION_ARENA
+ jr nz, .next_card
+ ; card in Arena found, put in hand
+ ld a, l
+ call AddCardToHand
+.next_card
+ inc l
+ ld a, l
+ cp DECK_SIZE
+ jr c, .loop_locations
+
+; empty the Arena card slot
+ ld l, DUELVARS_ARENA_CARD
+ ld a, [hl]
+ ld [hl], $ff
+ ld l, DUELVARS_ARENA_CARD_HP
+ ld [hl], 0
+ call LoadCardDataToBuffer1_FromDeckIndex
+ ld hl, wLoadedCard1Name
+ ld a, [hli]
+ ld h, [hl]
+ ld l, a
+ call LoadTxRam2
+ ldtx hl, PokemonAndAllAttachedCardsReturnedToHandText
+ call DrawWideTextBox_WaitForInput
+ xor a
+ ld [wDuelDisplayedScreen], a
+ call SwapTurn
+ ret
+
+PidgeottoWhirlwind_SelectEffect: ; 2ecd3 (b:6cd3)
+ ld a, DUELVARS_NUMBER_OF_POKEMON_IN_PLAY_AREA
+ call GetNonTurnDuelistVariable
+ cp 2
+ jr nc, .switch
+ ; no Bench Pokemon
+ ld a, $ff
+ ldh [hTemp_ffa0], a
+ ret
+.switch
+ call DuelistSelectForcedSwitch
+ ldh a, [hTempPlayAreaLocation_ff9d]
+ ldh [hTemp_ffa0], a
+ ret
+
+PidgeottoWhirlwind_SwitchEffect: ; 2ece9 (b:6ce9)
+ ldh a, [hTemp_ffa0]
+ call HandleSwitchDefendingPokemonEffect
+ ret
+
+PidgeottoMirrorMove_AIEffect: ; 2ecef (b:6cef)
+ jp MirrorMoveEffects.AIEffect
+
+PidgeottoMirrorMove_InitialEffect1: ; 2ecf2 (b:6cf2)
+ jp MirrorMoveEffects.InitialEffect1
+
+PidgeottoMirrorMove_InitialEffect2: ; 2ecf5 (b:6cf5)
+ jp MirrorMoveEffects.InitialEffect2
+
+PidgeottoMirrorMove_PlayerSelection: ; 2ecf8 (b:6cf8)
+ jp MirrorMoveEffects.PlayerSelection
+
+PidgeottoMirrorMove_AISelection: ; 2ecfb (b:6cfb)
+ jp MirrorMoveEffects.AISelection
+
+PidgeottoMirrorMove_BeforeDamage: ; 2ecfe (b:6cfe)
+ jp MirrorMoveEffects.BeforeDamage
+
+PidgeottoMirrorMove_AfterDamage: ; 2ed01 (b:6d01)
+ jp MirrorMoveEffects.AfterDamage
+
+SingEffect: ; 2ed04 (b:6d04)
+ call Sleep50PercentEffect
+ call nc, SetNoEffectFromStatus
+ ret
+
+; return carry if Defending Pokemon has no attacks
+ClefairyMetronome_CheckAttacks: ; 2ed0b (b:6d0b)
+ call CheckIfDefendingPokemonHasAnyAttack
+ ldtx hl, NoAttackMayBeChoosenText
+ ret
+
+ClefairyMetronome_AISelectEffect: ; 2ed12 (b:6d12)
+ call HandleAIMetronomeEffect
+ ret
+
+ClefairyMetronome_UseAttackEffect: ; 2ed16 (b:6d16)
+ ld a, 3 ; energy cost of this attack
+; fallthrough
+
+; handles Metronome selection, and validates
+; whether it can use the selected attack.
+; if unsuccessful, returns carry.
+; input:
+; a = amount of colorless energy needed for Metronome
+HandlePlayerMetronomeEffect: ; 2ed18 (b:6d18)
+ ld [wMetronomeEnergyCost], a
+ ldtx hl, ChooseOppAttackToBeUsedWithMetronomeText
+ call DrawWideTextBox_WaitForInput
+
+ call HandleDefendingPokemonAttackSelection
+ ret c ; return if operation cancelled
+
+; store this attack as selected attack to use
+ ld hl, wMetronomeSelectedAttack
+ ld [hl], d
+ inc hl
+ ld [hl], e
+
+; compare selected attack's name with
+; the attack that is loaded, which is Metronome.
+; if equal, then cannot select it.
+; (i.e. cannot use Metronome with Metronome.)
+ ld hl, wLoadedAttackName
+ ld a, [hli]
+ ld h, [hl]
+ ld l, a
+ push hl
+ call SwapTurn
+ call CopyAttackDataAndDamage_FromDeckIndex
+ call SwapTurn
+ pop de
+ ld hl, wLoadedAttackName
+ ld a, e
+ cp [hl]
+ jr nz, .try_use
+ inc hl
+ ld a, d
+ cp [hl]
+ jr nz, .try_use
+ ; cannot select Metronome
+ ldtx hl, UnableToSelectText
+.failed
+ call DrawWideTextBox_WaitForInput
+.set_carry
+ scf
+ ret
+
+.try_use
+; run the attack checks to determine
+; whether it can be used.
+ ld a, EFFECTCMDTYPE_INITIAL_EFFECT_1
+ call TryExecuteEffectCommandFunction
+ jr c, .failed
+ ld a, EFFECTCMDTYPE_INITIAL_EFFECT_2
+ call TryExecuteEffectCommandFunction
+ jr c, .set_carry
+ ; successful
+
+; send data to link opponent
+ bank1call SendAttackDataToLinkOpponent
+ ld a, OPPACTION_USE_METRONOME_ATTACK
+ call SetOppAction_SerialSendDuelData
+ ld hl, wMetronomeSelectedAttack
+ ld d, [hl]
+ inc hl
+ ld e, [hl]
+ ld a, [wMetronomeEnergyCost]
+ ld c, a
+ call SerialSend8Bytes
+
+ ldh a, [hTempCardIndex_ff9f]
+ ld [wPlayerAttackingCardIndex], a
+ ld a, [wSelectedAttack]
+ ld [wPlayerAttackingAttackIndex], a
+ ld a, [wTempCardID_ccc2]
+ ld [wPlayerAttackingCardID], a
+ or a
+ ret
+
+; does nothing for AI.
+HandleAIMetronomeEffect: ; 2ed86 (b:6d86)
+ ret
+
+DoTheWaveEffect: ; 2ed87 (b:6d87)
+ ld a, DUELVARS_NUMBER_OF_POKEMON_IN_PLAY_AREA
+ call GetTurnDuelistVariable
+ dec a ; don't count arena card
+ call ATimes10
+ call AddToDamage
+ ret
+
+; return carry if no damage counters
+FirstAid_DamageCheck: ; 2ed94 (b:6d94)
+ ld e, PLAY_AREA_ARENA
+ call GetCardDamageAndMaxHP
+ ldtx hl, NoDamageCountersText
+ cp 10
+ ret
+
+FirstAid_HealEffect: ; 2ed9f (b:6d9f)
+ lb de, 0, 10
+ call ApplyAndAnimateHPRecovery
+ ret
+
+JigglypuffDoubleEdgeEffect: ; 2eda6 (b:6da6)
+ ld a, 20
+ call DealRecoilDamageToSelf
+ ret
+
+PounceEffect: ; 2edac (b:6dac)
+ ld a, SUBSTATUS2_POUNCE
+ call ApplySubstatus2ToDefendingCard
+ ret
+
+LickitungSupersonicEffect: ; 2edb2 (b:6db2)
+ call Confusion50PercentEffect
+ call nc, SetNoEffectFromStatus
+ ret
+
+PidgeyWhirlwind_SelectEffect: ; 2edb9 (b:6db9)
+ ld a, DUELVARS_NUMBER_OF_POKEMON_IN_PLAY_AREA
+ call GetNonTurnDuelistVariable
+ cp 2
+ jr nc, .switch
+ ; no Bench Pokemon
+ ld a, $ff
+ ldh [hTemp_ffa0], a
+ ret
+.switch
+ call DuelistSelectForcedSwitch
+ ldh a, [hTempPlayAreaLocation_ff9d]
+ ldh [hTemp_ffa0], a
+ ret
+
+PidgeyWhirlwind_SwitchEffect: ; 2edcf (b:6dcf)
+ ldh a, [hTemp_ffa0]
+ call HandleSwitchDefendingPokemonEffect
+ ret
+
+; return carry if Defending card has no weakness
+Conversion1_WeaknessCheck: ; 2edd5 (b:6dd5)
+ call SwapTurn
+ ld a, DUELVARS_ARENA_CARD
+ call GetTurnDuelistVariable
+ call LoadCardDataToBuffer2_FromDeckIndex
+ call SwapTurn
+ ld a, [wLoadedCard2Weakness]
+ or a
+ ret nz
+ ldtx hl, NoWeaknessText
+ scf
+ ret
+
+Conversion1_PlayerSelectEffect: ; 2eded (b:6ded)
+ ldtx hl, ChooseWeaknessYouWishToChangeText
+ xor a ; PLAY_AREA_ARENA
+ call HandleColorChangeScreen
+ ldh [hTemp_ffa0], a
+ ret
+
+Conversion1_AISelectEffect: ; 2edf7 (b:6df7)
+ call AISelectConversionColor
+ ret
+
+Conversion1_ChangeWeaknessEffect: ; 2edfb (b:6dfb)
+ call HandleNoDamageOrEffect
+ ret c ; is unaffected
+
+; apply changed weakness
+ ld a, DUELVARS_ARENA_CARD_CHANGED_WEAKNESS
+ call GetNonTurnDuelistVariable
+ ldh a, [hTemp_ffa0]
+ call TranslateColorToWR
+ ld [hl], a
+ ld l, DUELVARS_ARENA_CARD_LAST_TURN_CHANGE_WEAK
+ ld [hl], a
+
+; print text box
+ call SwapTurn
+ ldtx hl, ChangedTheWeaknessOfPokemonToColorText
+ call PrintArenaCardNameAndColorText
+ call SwapTurn
+
+; apply substatus
+ ld a, SUBSTATUS2_CONVERSION2
+ call ApplySubstatus2ToDefendingCard
+ ret
+
+; returns carry if Active Pokemon has no Resistance.
+Conversion2_ResistanceCheck: ; 2ee1f (b:6e1f)
+ ld a, DUELVARS_ARENA_CARD
+ call GetTurnDuelistVariable
+ call LoadCardDataToBuffer2_FromDeckIndex
+ ld a, [wLoadedCard2Resistance]
+ or a
+ ret nz
+ ldtx hl, NoResistanceText
+ scf
+ ret
+
+Conversion2_PlayerSelectEffect: ; 2ee31 (b:6e31)
+ ldtx hl, ChooseResistanceYouWishToChangeText
+ ld a, $80
+ call HandleColorChangeScreen
+ ldh [hTemp_ffa0], a
+ ret
+
+Conversion2_AISelectEffect: ; 2ee3c (b:6e3c)
+; AI will choose Defending Pokemon's color
+; unless it is colorless.
+ call SwapTurn
+ ld a, DUELVARS_ARENA_CARD
+ call GetTurnDuelistVariable
+ call LoadCardDataToBuffer1_FromDeckIndex
+ call SwapTurn
+ ld a, [wLoadedCard1Type]
+ cp COLORLESS
+ jr z, .is_colorless
+ ldh [hTemp_ffa0], a
+ ret
+
+.is_colorless
+ call SwapTurn
+ call AISelectConversionColor
+ call SwapTurn
+ ret
+
+Conversion2_ChangeResistanceEffect: ; 2ee5e (b:6e5e)
+; apply changed resistance
+ ld a, DUELVARS_ARENA_CARD_CHANGED_RESISTANCE
+ call GetTurnDuelistVariable
+ ldh a, [hTemp_ffa0]
+ call TranslateColorToWR
+ ld [hl], a
+ ldtx hl, ChangedTheResistanceOfPokemonToColorText
+; fallthrough
+
+; prints text that requires card name and color,
+; with the card name of the Turn Duelist's Arena Pokemon
+; and color in [hTemp_ffa0].
+; input:
+; hl = text to print
+PrintArenaCardNameAndColorText: ; 2ee6c (b:6e6c)
+ push hl
+ ld a, DUELVARS_ARENA_CARD
+ call GetTurnDuelistVariable
+ call LoadCardDataToBuffer1_FromDeckIndex
+ ldh a, [hTemp_ffa0]
+ call LoadCardNameAndInputColor
+ pop hl
+ call DrawWideTextBox_PrintText
+ ret
+
+; handles AI logic for selecting a new color
+; for weakness/resistance.
+; - if within the context of Conversion1, looks
+; in own Bench for a non-colorless card that can attack.
+; - if within the context of Conversion2, looks
+; in Player's Bench for a non-colorless card that can attack.
+AISelectConversionColor: ; 2ee7f (b:6e7f)
+ ld a, DUELVARS_NUMBER_OF_POKEMON_IN_PLAY_AREA
+ call GetTurnDuelistVariable
+ ld d, a
+ ld e, PLAY_AREA_ARENA
+ jr .next_pkmn_atk
+
+; look for a non-colorless Bench Pokemon
+; that has enough energy to use an attack.
+.loop_atk
+ push de
+ call GetPlayAreaCardAttachedEnergies
+ ld a, e
+ add DUELVARS_ARENA_CARD
+ call GetTurnDuelistVariable
+ ld d, a
+ call LoadCardDataToBuffer1_FromDeckIndex
+ ld a, [wLoadedCard1Type]
+ cp COLORLESS
+ jr z, .skip_pkmn_atk ; skip colorless Pokemon
+ ld e, FIRST_ATTACK_OR_PKMN_POWER
+ bank1call _CheckIfEnoughEnergiesToAttack
+ jr nc, .found
+ ld e, SECOND_ATTACK
+ bank1call _CheckIfEnoughEnergiesToAttack
+ jr nc, .found
+.skip_pkmn_atk
+ pop de
+.next_pkmn_atk
+ inc e
+ dec d
+ jr nz, .loop_atk
+
+; none found in Bench.
+; next, look for a non-colorless Bench Pokemon
+; that has any Energy cards attached.
+ ld d, e ; number of Play Area Pokemon
+ ld e, PLAY_AREA_ARENA
+ jr .next_pkmn_energy
+
+.loop_energy
+ push de
+ call GetPlayAreaCardAttachedEnergies
+ ld a, [wTotalAttachedEnergies]
+ or a
+ jr z, .skip_pkmn_energy
+ ld a, e
+ add DUELVARS_ARENA_CARD
+ call GetTurnDuelistVariable
+ ld d, a
+ call LoadCardDataToBuffer1_FromDeckIndex
+ ld a, [wLoadedCard1Type]
+ cp COLORLESS
+ jr nz, .found
+.skip_pkmn_energy
+ pop de
+.next_pkmn_energy
+ inc e
+ dec d
+ jr nz, .loop_energy
+
+; otherwise, just select a random energy.
+ ld a, NUM_COLORED_TYPES
+ call Random
+ ldh [hTemp_ffa0], a
+ ret
+
+.found
+ pop de
+ ld a, [wLoadedCard1Type]
+ and TYPE_PKMN
+ ldh [hTemp_ffa0], a
+ ret
+
+ScrunchEffect: ; 2eee7 (b:6ee7)
+ ldtx de, IfHeadsNoDamageNextTurnText
+ call TossCoin_BankB
+ jp nc, SetWasUnsuccessful
+ ld a, ATK_ANIM_SCRUNCH
+ ld [wLoadedAttackAnimation], a
+ ld a, SUBSTATUS1_NO_DAMAGE_17
+ call ApplySubstatus1ToDefendingCard
+ ret
+
+ChanseyDoubleEdgeEffect: ; 2eefb (b:6efb)
+ ld a, 80
+ call DealRecoilDamageToSelf
+ ret
+
+SuperFang_AIEffect: ; 2ef01 (b:6f01)
+ call SuperFang_HalfHPEffect
+ jp SetDefiniteAIDamage
+
+SuperFang_HalfHPEffect: ; 2ef07 (b:6f07)
+ ld a, DUELVARS_ARENA_CARD_HP
+ call GetNonTurnDuelistVariable
+ srl a
+ bit 0, a
+ jr z, .rounded
+ ; round up
+ add 5
+.rounded
+ call SetDefiniteDamage
+ ret
+
+; return carry if no Pokemon in Bench
+TrainerCardAsPokemon_BenchCheck: ; 2ef18 (b:6f18)
+ ldh a, [hTempPlayAreaLocation_ff9d]
+ ldh [hTemp_ffa0], a
+ ld a, DUELVARS_NUMBER_OF_POKEMON_IN_PLAY_AREA
+ call GetTurnDuelistVariable
+ ldtx hl, EffectNoPokemonOnTheBenchText
+ cp 2
+ ret
+
+TrainerCardAsPokemon_PlayerSelectSwitch: ; 2ef27 (b:6f27)
+ ldh a, [hTemp_ffa0]
+ or a
+ ret nz ; no need to switch if it's not Arena card
+
+ ldtx hl, SelectPokemonToPlaceInTheArenaText
+ call DrawWideTextBox_WaitForInput
+ bank1call HasAlivePokemonInBench
+ bank1call OpenPlayAreaScreenForSelection
+ ldh a, [hTempPlayAreaLocation_ff9d]
+ ldh [hTempPlayAreaLocation_ffa1], a
+ ret
+
+TrainerCardAsPokemon_DiscardEffect: ; 2ef3c (b:6f3c)
+ ldh a, [hTemp_ffa0]
+ ld e, a
+ call MovePlayAreaCardToDiscardPile
+ ldh a, [hTemp_ffa0]
+ or a
+ jr nz, .shift_cards
+ ldh a, [hTempPlayAreaLocation_ffa1]
+ ld e, a
+ call SwapArenaWithBenchPokemon
+.shift_cards
+ call ShiftAllPokemonToFirstPlayAreaSlots
+ ret
+
+HealingWind_InitialEffect: ; 2ef51 (b:6f51)
+ scf
+ ret
+
+HealingWind_PlayAreaHealEffect: ; 2ef53 (b:6f53)
+; play initial animation
+ ldh a, [hTempPlayAreaLocation_ff9d]
+ ld b, a
+ ld c, $00
+ ldh a, [hWhoseTurn]
+ ld h, a
+ bank1call PlayAttackAnimation
+ bank1call WaitAttackAnimation
+ ld a, ATK_ANIM_HEALING_WIND_PLAY_AREA
+ ld [wLoadedAttackAnimation], a
+
+
+ ld a, DUELVARS_NUMBER_OF_POKEMON_IN_PLAY_AREA
+ call GetTurnDuelistVariable
+ ld d, a
+ ld e, PLAY_AREA_ARENA
+.loop_play_area
+ push de
+ ld a, e
+ ldh [hTempPlayAreaLocation_ff9d], a
+ call GetCardDamageAndMaxHP
+ or a
+ jr z, .next_pkmn ; skip if no damage
+
+; if less than 20 damage, cap recovery at 10 damage
+ ld de, 20
+ cp e
+ jr nc, .heal
+ ld e, a
+
+.heal
+; add HP to this card
+ ldh a, [hTempPlayAreaLocation_ff9d]
+ add DUELVARS_ARENA_CARD_HP
+ call GetTurnDuelistVariable
+ add e
+ ld [hl], a
+
+; play heal animation
+ ldh a, [hTempPlayAreaLocation_ff9d]
+ ld b, a
+ ld c, $01
+ ldh a, [hWhoseTurn]
+ ld h, a
+ bank1call PlayAttackAnimation
+ bank1call WaitAttackAnimation
+.next_pkmn
+ pop de
+ inc e
+ dec d
+ jr nz, .loop_play_area
+
+ ret
+
+Dragonite1Slam_AIEffect: ; 2ef9c (b:6f9c)
+ ld a, (30 * 2) / 2
+ lb de, 0, 60
+ jp SetExpectedAIDamage
+
+Dragonite1Slam_MultiplierEffect: ; 2efa4 (b:6fa4)
+ ld hl, 30
+ call LoadTxRam3
+ ldtx de, DamageCheckIfHeadsXDamageText
+ ld a, 2
+ call TossCoinATimes_BankB
+ ld c, a
+ add a
+ add c
+ call ATimes10
+ call SetDefiniteDamage
+ ret
+
+; possibly unreferenced
+Func_2efbc: ; 2efbc (b:6fbc)
+ ld a, DUELVARS_NUMBER_OF_POKEMON_IN_PLAY_AREA
+ call GetTurnDuelistVariable
+ ld c, a
+ ld l, DUELVARS_ARENA_CARD_HP
+ ld de, wce76
+.asm_2efc7
+ ld a, [hli]
+ ld [de], a
+ inc de
+ dec c
+ jr nz, .asm_2efc7
+ ret
+
+; possibly unreferenced
+Func_2efce: ; 2efce (b:6fce)
+ ld a, DUELVARS_NUMBER_OF_POKEMON_IN_PLAY_AREA
+ call GetTurnDuelistVariable
+ ld c, a
+ ld l, DUELVARS_ARENA_CARD_HP
+ ld de, wce76
+.asm_2efd9
+ ld a, [de]
+ inc de
+ ld [hli], a
+ dec c
+ jr nz, .asm_2efd9
+ ret
+
+CatPunchEffect: ; 2efe0 (b:6fe0)
+ call SwapTurn
+ call PickRandomPlayAreaCard
+ ld b, a
+ ld a, ATK_ANIM_CAT_PUNCH_PLAY_AREA
+ ld [wLoadedAttackAnimation], a
+ ld de, 20
+ call DealDamageToPlayAreaPokemon
+ call SwapTurn
+ ret
+
+MorphEffect: ; 2eff6 (b:6ff6)
+ call ExchangeRNG
+ call .PickRandomBasicPokemonFromDeck
+ jr nc, .successful
+ ldtx hl, AttackUnsuccessfulText
+ call DrawWideTextBox_WaitForInput
+ ret
+
+.successful
+ ld a, DUELVARS_ARENA_CARD_STAGE
+ call GetTurnDuelistVariable
+ or a
+ jr z, .skip_discard_stage_below
+
+; if this is a stage 1 Pokemon (in case it's used
+; by Clefable's Metronome attack) then first discard
+; the lower stage card.
+ push hl
+ xor a
+ ldh [hTempPlayAreaLocation_ff9d], a
+ bank1call GetCardOneStageBelow
+ ld a, d
+ call PutCardInDiscardPile
+ pop hl
+ ld [hl], BASIC
+
+.skip_discard_stage_below
+; overwrite card ID
+ ldh a, [hTempCardIndex_ff98]
+ call GetCardIDFromDeckIndex
+ ld a, DUELVARS_ARENA_CARD
+ call GetTurnDuelistVariable
+ ldh [hTempCardIndex_ff98], a
+ call _GetCardIDFromDeckIndex
+ ld [hl], e
+
+; overwrite HP to new card's maximum HP
+ ld e, PLAY_AREA_ARENA
+ call GetCardDamageAndMaxHP
+ ld a, DUELVARS_ARENA_CARD_HP
+ call GetTurnDuelistVariable
+ ld [hl], c
+
+; clear changed color and status
+ ld l, DUELVARS_ARENA_CARD_CHANGED_TYPE
+ ld [hl], $00
+ call ClearAllStatusConditions
+
+; load both card's names for printing text
+ ld a, [wTempTurnDuelistCardID]
+ ld e, a
+ ld d, $00
+ call LoadCardDataToBuffer2_FromCardID
+ ld hl, wLoadedCard2Name
+ ld de, wTxRam2
+ ld a, [hli]
+ ld [de], a
+ inc de
+ ld a, [hl]
+ ld [de], a
+ inc de
+ ldh a, [hTempCardIndex_ff98]
+ call LoadCardDataToBuffer2_FromDeckIndex
+ ld hl, wLoadedCard2Name
+ ld a, [hli]
+ ld [de], a
+ inc de
+ ld a, [hl]
+ ld [de], a
+ ldtx hl, MetamorphsToText
+ call DrawWideTextBox_WaitForInput
+
+ xor a
+ ld [wDuelDisplayedScreen], a
+ ret
+
+; picks a random Pokemon in the Deck to morph.
+; needs to be a Basic Pokemon that doesn't have
+; the same ID as the Arena card.
+; returns carry if no Pokemon were found.
+.PickRandomBasicPokemonFromDeck ; 2f06a (b:706a)
+ call CreateDeckCardList
+ ret c ; empty deck
+ ld hl, wDuelTempList
+ call ShuffleCards
+.loop_deck
+ ld a, [hli]
+ ldh [hTempCardIndex_ff98], a
+ cp $ff
+ jr z, .set_carry
+ call LoadCardDataToBuffer2_FromDeckIndex
+ ld a, [wLoadedCard2Type]
+ cp TYPE_ENERGY
+ jr nc, .loop_deck ; skip non-Pokemon cards
+ ld a, [wLoadedCard2Stage]
+ or a
+ jr nz, .loop_deck ; skip non-Basic cards
+ ld a, [wLoadedCard2ID]
+ cp DUELVARS_ARENA_CARD
+ jr z, .loop_deck ; skip cards with same ID as Arena card
+ ldh a, [hTempCardIndex_ff98]
+ or a
+ ret
+.set_carry
+ scf
+ ret
+
+; returns in a and [hTempCardIndex_ff98] the deck index
+; of random Basic Pokemon card in deck.
+; if none are found, return carry.
+PickRandomBasicCardFromDeck: ; 2f098 (b:7098)
+ call CreateDeckCardList
+ ret c ; return if empty deck
+ ld hl, wDuelTempList
+ call ShuffleCards
+.loop_deck
+ ld a, [hli]
+ ldh [hTempCardIndex_ff98], a
+ cp $ff
+ jr z, .set_carry
+ call LoadCardDataToBuffer2_FromDeckIndex
+ ld a, [wLoadedCard2Type]
+ cp TYPE_ENERGY
+ jr nc, .loop_deck ; skip if not Pokemon card
+ ld a, [wLoadedCard2Stage]
+ or a
+ jr nz, .loop_deck ; skip if not Basic stage
+ ldh a, [hTempCardIndex_ff98]
+ or a
+ ret
+.set_carry
+ scf
+ ret
+
+SlicingWindEffect: ; 2f0bf (b:70bf)
+ call SwapTurn
+ call PickRandomPlayAreaCard
+ ld b, a
+ ld de, 30
+ call DealDamageToPlayAreaPokemon_RegularAnim
+ call SwapTurn
+ ret
+
+Gale_LoadAnimation: ; 2f0d0 (b:70d0)
+ ld a, ATK_ANIM_GALE
+ ld [wLoadedAttackAnimation], a
+ ret
+
+Gale_SwitchEffect: ; 2f0d6 (b:70d6)
+; if Defending card is unaffected by attack
+; jump directly to switching this card only.
+ call HandleNoDamageOrEffect
+ jr c, .SwitchWithRandomBenchPokemon
+
+; handle switching Defending card
+ ld a, DUELVARS_ARENA_CARD_HP
+ call GetNonTurnDuelistVariable
+ or a
+ jr nz, .skip_destiny_bond
+ bank1call HandleDestinyBondSubstatus
+.skip_destiny_bond
+ call SwapTurn
+ call .SwitchWithRandomBenchPokemon
+ jr c, .skip_clear_damage
+; clear dealt damage because Pokemon was switched
+ xor a
+ ld hl, wDealtDamage
+ ld [hli], a
+ ld [hl], a
+.skip_clear_damage
+ call SwapTurn
+; fallthrough for attacking card switch
+
+.SwitchWithRandomBenchPokemon
+ ld a, DUELVARS_NUMBER_OF_POKEMON_IN_PLAY_AREA
+ call GetTurnDuelistVariable
+ cp 2
+ ret c ; return if no Bench Pokemon
+
+; get random Bench location and swap
+ dec a
+ call Random
+ inc a
+ ld e, a
+ call SwapArenaWithBenchPokemon
+
+ xor a
+ ld [wDuelDisplayedScreen], a
+ ret
+
+; return carry if Bench is full
+FriendshipSong_BenchCheck: ; 2f10d (b:710d)
+ ld a, DUELVARS_NUMBER_OF_POKEMON_IN_PLAY_AREA
+ call GetTurnDuelistVariable
+ ldtx hl, NoSpaceOnTheBenchText
+ cp MAX_PLAY_AREA_POKEMON
+ ccf
+ ret
+
+FriendshipSong_AddToBench50PercentEffect: ; 2f119 (b:7119)
+ ldtx de, SuccessCheckIfHeadsAttackIsSuccessfulText
+ call TossCoin_BankB
+ jr c, .successful
+
+.none_came_text
+ ldtx hl, NoneCameText
+ call DrawWideTextBox_WaitForInput
+ ret
+
+.successful
+ call PickRandomBasicCardFromDeck
+ jr nc, .put_in_bench
+ ld a, ATK_ANIM_FRIENDSHIP_SONG
+ call Func_2c12e
+ call .none_came_text
+ call Func_2c0bd
+ ret
+
+.put_in_bench
+ call SearchCardInDeckAndAddToHand
+ call AddCardToHand
+ call PutHandPokemonCardInPlayArea
+ ld a, ATK_ANIM_FRIENDSHIP_SONG
+ call Func_2c12e
+ ldh a, [hTempCardIndex_ff98]
+ ldtx hl, CameToTheBenchText
+ bank1call DisplayCardDetailScreen
+ call Func_2c0bd
+ ret
+
+ExpandEffect: ; 2f153 (b:7153)
+ ld a, SUBSTATUS1_REDUCE_BY_10
+ call ApplySubstatus1ToDefendingCard
+ ret
+
+; returns carry if either there are no damage counters
+; or no Energy cards attached in the Play Area.
+SuperPotion_DamageEnergyCheck: ; 2f159 (b:7159)
+ call CheckIfPlayAreaHasAnyDamage
+ ldtx hl, NoPokemonWithDamageCountersText
+ ret c ; no damage counters
+ call CheckIfThereAreAnyEnergyCardsAttached
+ ldtx hl, ThereIsNoEnergyCardAttachedText
+ ret
+
+SuperPotion_PlayerSelectEffect: ; 2f167 (b:7167)
+ ldtx hl, ChoosePokemonToRemoveDamageCounterFromText
+ call DrawWideTextBox_WaitForInput
+.start
+ bank1call HasAlivePokemonInPlayArea
+.read_input
+ bank1call OpenPlayAreaScreenForSelection
+ ret c ; exit if B is pressed
+ ld e, a
+ call GetCardDamageAndMaxHP
+ or a
+ jr z, .read_input ; Pokemon has no damage?
+ ldh a, [hCurMenuItem]
+ ld e, a
+ call GetPlayAreaCardAttachedEnergies
+ ld a, [wTotalAttachedEnergies]
+ or a
+ jr nz, .got_pkmn
+ ; no energy cards attached
+ ldtx hl, NoEnergyCardsText
+ call DrawWideTextBox_WaitForInput
+ jr .start
+
+.got_pkmn
+; Pokemon has damage and Energy cards attached,
+; prompt the Player for Energy selection to discard.
+ ldh a, [hCurMenuItem]
+ bank1call CreateArenaOrBenchEnergyCardList
+ ldh a, [hCurMenuItem]
+ bank1call DisplayEnergyDiscardScreen
+ bank1call HandleEnergyDiscardMenuInput
+ ret c ; exit if B was pressed
+
+ ldh a, [hTempCardIndex_ff98]
+ ldh [hTemp_ffa0], a
+ ldh a, [hTempPlayAreaLocation_ff9d]
+ ldh [hTempPlayAreaLocation_ffa1], a
+ ld e, a
+
+; cap the healing damage if
+; it would make it exceed max HP.
+ call GetCardDamageAndMaxHP
+ ld c, 40
+ cp 40
+ jr nc, .heal
+ ld c, a
+.heal
+ ld a, c
+ ldh [hPlayAreaEffectTarget], a
+ or a
+ ret
+
+SuperPotion_HealEffect: ; 2f1b5 (b:71b5)
+ ldh a, [hTemp_ffa0]
+ call PutCardInDiscardPile
+ ldh a, [hTempPlayAreaLocation_ffa1]
+ ldh [hTempPlayAreaLocation_ff9d], a
+ ldh a, [hPlayAreaEffectTarget]
+ call HealPlayAreaCardHP
+ ret
+
+; checks if there is at least one Energy card
+; attached to some card in the Turn Duelist's Play Area.
+; return no carry if one is found,
+; and returns carry set if none is found.
+CheckIfThereAreAnyEnergyCardsAttached: ; 2f1c4 (b:71c4)
+ ld a, DUELVARS_CARD_LOCATIONS
+ call GetTurnDuelistVariable
+.loop_deck
+ ld a, [hl]
+ bit CARD_LOCATION_PLAY_AREA_F, a
+ jr z, .next_card ; skip if not in Play Area
+ ld a, l
+ call LoadCardDataToBuffer2_FromDeckIndex
+ ld a, [wLoadedCard2Type]
+ cp TYPE_TRAINER
+ jr z, .next_card ; skip if it's a Trainer card
+ cp TYPE_ENERGY
+ jr nc, .found
+.next_card
+ inc l
+ ld a, l
+ cp DECK_SIZE
+ jr c, .loop_deck
+ scf
+ ret
+.found
+ or a
+ ret
+
+; handles Player selection for Pokemon in Play Area,
+; then opens screen to choose one of the energy cards
+; attached to that selected Pokemon.
+; outputs the selection in:
+; [hTemp_ffa0] = play area location
+; [hTempPlayAreaLocation_ffa1] = index of energy card
+HandlePokemonAndEnergySelectionScreen: ; 2f1e7 (b:71e7)
+ bank1call HasAlivePokemonInPlayArea
+ bank1call OpenPlayAreaScreenForSelection
+ ret c ; exit if B is pressed
+ ld e, a
+ call GetPlayAreaCardAttachedEnergies
+ ld a, [wTotalAttachedEnergies]
+ or a
+ jr nz, .has_energy
+ ldtx hl, NoEnergyCardsText
+ call DrawWideTextBox_WaitForInput
+ jr HandlePokemonAndEnergySelectionScreen ; loop back to start
+
+.has_energy
+ ldh a, [hCurMenuItem]
+ bank1call CreateArenaOrBenchEnergyCardList
+ ldh a, [hCurMenuItem]
+ bank1call DisplayEnergyDiscardScreen
+ bank1call HandleEnergyDiscardMenuInput
+ ldh a, [hTempPlayAreaLocation_ff9d]
+ ldh [hTemp_ffa0], a
+ ldh a, [hTempCardIndex_ff98]
+ ldh [hTempPlayAreaLocation_ffa1], a
+ ret
+
+ImakuniEffect: ; 2f216 (b:7216)
+ ld a, DUELVARS_ARENA_CARD
+ call GetTurnDuelistVariable
+ call LoadCardDataToBuffer1_FromDeckIndex
+ ld a, [wLoadedCard1ID]
+
+; cannot confuse Clefairy Doll and Mysterious Fossil
+ cp CLEFAIRY_DOLL
+ jr z, .failed
+ cp MYSTERIOUS_FOSSIL
+ jr z, .failed
+
+; cannot confuse Snorlax if its Pkmn Power is active
+ cp SNORLAX
+ jr nz, .success
+ xor a
+ call CheckCannotUseDueToStatus_OnlyToxicGasIfANon0
+ jr c, .success
+ ; fallthrough if Thick Skinned is active
+
+.failed
+; play confusion animation and print failure text
+ ld a, ATK_ANIM_IMAKUNI_CONFUSION
+ call Func_2fea9
+ ldtx hl, ThereWasNoEffectText
+ call DrawWideTextBox_WaitForInput
+ ret
+
+.success
+; play confusion animation and confuse card
+ ld a, ATK_ANIM_IMAKUNI_CONFUSION
+ call Func_2fea9
+ ld a, DUELVARS_ARENA_CARD_STATUS
+ call GetTurnDuelistVariable
+ and PSN_DBLPSN
+ or CONFUSED
+ ld [hl], a
+ bank1call DrawDuelHUDs
+ ret
+
+; returns carry if opponent has no energy cards attached
+EnergyRemoval_EnergyCheck: ; 2f252 (b:7252)
+ call SwapTurn
+ call CheckIfThereAreAnyEnergyCardsAttached
+ ldtx hl, NoEnergyAttachedToOpponentsActiveText
+ call SwapTurn
+ ret
+
+EnergyRemoval_PlayerSelection: ; 2f25f (b:725f)
+ ldtx hl, ChoosePokemonToRemoveEnergyFromText
+ call DrawWideTextBox_WaitForInput
+ call SwapTurn
+ call HandlePokemonAndEnergySelectionScreen
+ call SwapTurn
+ ret
+
+EnergyRemoval_AISelection: ; 2f26f (b:726f)
+ call AIPickEnergyCardToDiscardFromDefendingPokemon
+ ret
+
+EnergyRemoval_DiscardEffect: ; 2f273 (b:7273)
+ call SwapTurn
+ ldh a, [hTempPlayAreaLocation_ffa1]
+ call PutCardInDiscardPile
+ call SwapTurn
+ call IsPlayerTurn
+ ret c
+
+; show Player which Pokemon was affected
+ call SwapTurn
+ ldh a, [hTemp_ffa0]
+ call Func_2c10b
+ call SwapTurn
+ ret
+
+; return carry if no other card in hand to discard
+; or if there are no Basic Energy cards in Discard Pile.
+EnergyRetrieval_HandEnergyCheck: ; 2f28e (b:728e)
+ ld a, DUELVARS_NUMBER_OF_CARDS_IN_HAND
+ call GetTurnDuelistVariable
+ cp 2
+ ldtx hl, NotEnoughCardsInHandText
+ ret c ; return if doesn't have another card to discard
+ call CreateEnergyCardListFromDiscardPile_OnlyBasic
+ ldtx hl, ThereAreNoBasicEnergyCardsInDiscardPileText
+ ret
+
+EnergyRetrieval_PlayerHandSelection: ; 2f2a0 (b:72a0)
+ ldtx hl, ChooseCardToDiscardFromHandText
+ call DrawWideTextBox_WaitForInput
+ call CreateHandCardList
+ ldh a, [hTempCardIndex_ff9f]
+ call RemoveCardFromDuelTempList
+ bank1call Func_5591
+ bank1call DisplayCardList
+ ldh a, [hTempCardIndex_ff98]
+ ldh [hTempList], a
+ ret
+
+EnergyRetrieval_PlayerDiscardPileSelection: ; 2f2b9 (b:72b9)
+ ld a, 1 ; start at 1 due to card selected from hand
+ ldh [hCurSelectionItem], a
+ ldtx hl, Choose2BasicEnergyCardsFromDiscardPileText
+ call DrawWideTextBox_WaitForInput
+ call CreateEnergyCardListFromDiscardPile_OnlyBasic
+
+.select_card
+ bank1call InitAndDrawCardListScreenLayout
+ ldtx hl, PleaseSelectCardText
+ ldtx de, PlayerDiscardPileText
+ bank1call SetCardListHeaderText
+ bank1call DisplayCardList
+ jr nc, .selected
+ ; B was pressed
+ ld a, 2 + 1 ; includes the card selected from hand
+ call AskWhetherToQuitSelectingCards
+ jr c, .select_card ; player selected No
+ jr .done
+
+.selected
+ call GetNextPositionInTempList_TrainerEffects
+ ldh a, [hTempCardIndex_ff98]
+ ld [hl], a
+ call RemoveCardFromDuelTempList
+ jr c, .done
+ ldh a, [hCurSelectionItem]
+ cp 2 + 1 ; includes the card selected from hand
+ jr c, .select_card
+
+.done
+ call GetNextPositionInTempList_TrainerEffects
+ ld [hl], $ff ; terminating byte
+ or a
+ ret
+
+EnergyRetrieval_DiscardAndAddToHandEffect: ; 2f2f8 (b:72f8)
+ ld hl, hTempList
+ ld a, [hli]
+ call RemoveCardFromHand
+ call PutCardInDiscardPile
+ ld de, wDuelTempList
+.loop
+ ld a, [hli]
+ ld [de], a
+ inc de
+ cp $ff
+ jr z, .done
+ call MoveDiscardPileCardToHand
+ call AddCardToHand
+ jr .loop
+.done
+ call IsPlayerTurn
+ ret c
+ bank1call Func_4b38
+ ret
+
+; return carry if no cards left in Deck.
+EnergySearch_DeckCheck: ; 2f31c (b:731c)
+ ld a, DUELVARS_NUMBER_OF_CARDS_NOT_IN_DECK
+ call GetTurnDuelistVariable
+ cp DECK_SIZE
+ ccf
+ ldtx hl, NoCardsLeftInTheDeckText
+ ret
+
+EnergySearch_PlayerSelection: ; 2f328 (b:7328)
+ ld a, $ff
+ ldh [hTemp_ffa0], a
+ call CreateDeckCardList
+ ldtx hl, Choose1BasicEnergyCardFromDeckText
+ lb de, SEARCHEFFECT_BASIC_ENERGY, 0
+ ldtx bc, BasicEnergyText
+ call LookForCardsInDeck
+ ret c ; skip showing deck
+
+ bank1call Func_5591
+ ldtx hl, ChooseBasicEnergyCardText
+ ldtx de, DuelistDeckText
+ bank1call SetCardListHeaderText
+.read_input
+ bank1call DisplayCardList
+ jr c, .try_exit ; B pressed?
+ ldh a, [hTempCardIndex_ff98]
+ ldh [hTemp_ffa0], a
+ call CheckIfCardIsBasicEnergy
+ jr c, .play_sfx
+ or a
+ ret
+.play_sfx
+ call Func_3794
+ jr .read_input
+
+.try_exit
+; check if Player can exit without selecting anything
+ ld hl, wDuelTempList
+.next_card
+ ld a, [hli]
+ cp $ff
+ jr z, .exit
+ call CheckIfCardIsBasicEnergy
+ jr c, .next_card
+ jr .read_input ; no, has to select Energy card
+.exit
+ ld a, $ff
+ ldh [hTemp_ffa0], a
+ or a
+ ret
+
+EnergySearch_AddToHandEffect: ; 2f372 (b:7372)
+ ldh a, [hTemp_ffa0]
+ cp $ff
+ jr z, .done
+; add to hand
+ call SearchCardInDeckAndAddToHand
+ call AddCardToHand
+ call IsPlayerTurn
+ jr c, .done ; done if Player played card
+; display card in screen
+ ldh a, [hTemp_ffa0]
+ ldtx hl, WasPlacedInTheHandText
+ bank1call DisplayCardDetailScreen
+.done
+ call Func_2c0bd
+ ret
+
+; check if card index in a is a Basic Energy card.
+; returns carry in case it's not.
+CheckIfCardIsBasicEnergy: ; 2f38f (b:738f)
+ call LoadCardDataToBuffer2_FromDeckIndex
+ ld a, [wLoadedCard2Type]
+ cp TYPE_ENERGY
+ jr c, .not_basic_energy
+ cp TYPE_ENERGY_DOUBLE_COLORLESS
+ jr nc, .not_basic_energy
+; is basic energy
+ or a
+ ret
+.not_basic_energy
+ scf
+ ret
+
+ProfessorOakEffect: ; 2f3a1 (b:73a1)
+; discard hand
+ call CreateHandCardList
+ call SortCardsInDuelTempListByID
+ ld hl, wDuelTempList
+.discard_loop
+ ld a, [hli]
+ cp $ff
+ jr z, .draw_cards
+ call RemoveCardFromHand
+ call PutCardInDiscardPile
+ jr .discard_loop
+
+.draw_cards
+ ld a, 7
+ bank1call DisplayDrawNCardsScreen
+ ld c, 7
+.draw_loop
+ call DrawCardFromDeck
+ jr c, .done
+ call AddCardToHand
+ dec c
+ jr nz, .draw_loop
+.done
+ ret
+
+Potion_DamageCheck: ; 2f3ca (b:73ca)
+ call CheckIfPlayAreaHasAnyDamage
+ ldtx hl, NoPokemonWithDamageCountersText
+ ret
+
+Potion_PlayerSelection: ; 2f3d1 (b:73d1)
+ bank1call HasAlivePokemonInPlayArea
+.read_input
+ bank1call OpenPlayAreaScreenForSelection
+ ret c ; exit is B was pressed
+ ldh a, [hTempPlayAreaLocation_ff9d]
+ ldh [hTemp_ffa0], a
+ ld e, a
+ call GetCardDamageAndMaxHP
+ or a
+ jr z, .read_input ; no damage, loop back to start
+; cap damage
+ ld c, 20
+ cp 20
+ jr nc, .skip_cap
+ ld c, a
+.skip_cap
+ ld a, c
+ ldh [hTempPlayAreaLocation_ffa1], a
+ or a
+ ret
+
+Potion_HealEffect: ; 2f3ef (b:73ef)
+ ldh a, [hTemp_ffa0]
+ ldh [hTempPlayAreaLocation_ff9d], a
+ ldh a, [hTempPlayAreaLocation_ffa1]
+ call HealPlayAreaCardHP
+ ret
+
+GamblerEffect: ; 2f3f9 (b:73f9)
+ ldtx de, CardCheckIfHeads8CardsIfTails1CardText
+ call TossCoin_BankB
+ ldh [hTemp_ffa0], a
+; discard Gambler card from hand
+ ldh a, [hTempCardIndex_ff9f]
+ call RemoveCardFromHand
+ call PutCardInDiscardPile
+
+; shuffle cards into deck
+ call CreateHandCardList
+ call SortCardsInDuelTempListByID
+ ld hl, wDuelTempList
+.loop_return_deck
+ ld a, [hli]
+ cp $ff
+ jr z, .check_coin_toss
+ call RemoveCardFromHand
+ call ReturnCardToDeck
+ jr .loop_return_deck
+
+.check_coin_toss
+ call Func_2c0bd
+ ld c, 8
+ ldh a, [hTemp_ffa0]
+ or a
+ jr nz, .draw_cards ; coin toss was heads?
+ ; if tails, number of cards to draw is 1
+ ld c, 1
+
+; correct number of cards to draw is in c
+.draw_cards
+ ld a, c
+ bank1call DisplayDrawNCardsScreen
+.draw_loop
+ call DrawCardFromDeck
+ jr c, .done
+ call AddCardToHand
+ dec c
+ jr nz, .draw_loop
+.done
+ ret
+
+; return carry if not enough cards in hand to discard
+; or if there are no cards in the Discard Pile
+ItemFinder_HandDiscardPileCheck: ; 2f43b (b:743b)
+ ld a, DUELVARS_NUMBER_OF_CARDS_IN_HAND
+ call GetTurnDuelistVariable
+ ldtx hl, NotEnoughCardsInHandText
+ cp 3
+ ret c
+ call CreateTrainerCardListFromDiscardPile
+ ret
+
+ItemFinder_PlayerSelection: ; 2f44a (b:744a)
+ call HandlePlayerSelection2HandCardsToDiscard
+ ret c ; was operation cancelled?
+
+; cards were selected to discard from hand.
+; now to choose a Trainer card from Discard Pile.
+ call CreateTrainerCardListFromDiscardPile
+ bank1call Func_5591
+ ldtx hl, ChooseCardToPlaceInHandText
+ ldtx de, PlayerDiscardPileText
+ bank1call SetCardListHeaderText
+ bank1call DisplayCardList
+ ldh [hTempList + 2], a ; placed after the 2 cards selected to discard
+ ret
+
+ItemFinder_DiscardAddToHandEffect: ; 2f463 (b:7463)
+; discard cards from hand
+ ld hl, hTempList
+ ld a, [hli]
+ call RemoveCardFromHand
+ call PutCardInDiscardPile
+ ld a, [hli]
+ call RemoveCardFromHand
+ call PutCardInDiscardPile
+
+; place card from Discard Pile to hand
+ ld a, [hl]
+ call MoveDiscardPileCardToHand
+ call AddCardToHand
+ call IsPlayerTurn
+ ret c
+; display card in screen
+ ldh a, [hTempList + 2]
+ ldtx hl, WasPlacedInTheHandText
+ bank1call DisplayCardDetailScreen
+ ret
+
+Defender_PlayerSelection: ; 2f488 (b:7488)
+ ldtx hl, ChoosePokemonToAttachDefenderToText
+ call DrawWideTextBox_WaitForInput
+ bank1call HasAlivePokemonInPlayArea
+ bank1call OpenPlayAreaScreenForSelection
+ ldh a, [hTempPlayAreaLocation_ff9d]
+ ldh [hTemp_ffa0], a
+ ret
+
+Defender_AttachDefenderEffect: ; 2f499 (b:7499)
+; attach Trainer card to Play Area Pokemon
+ ldh a, [hTemp_ffa0]
+ ld e, a
+ ldh a, [hTempCardIndex_ff9f]
+ call PutHandCardInPlayArea
+
+; increase number of Defender cards of this location by 1
+ ldh a, [hTemp_ffa0]
+ add DUELVARS_ARENA_CARD_ATTACHED_DEFENDER
+ call GetTurnDuelistVariable
+ inc [hl]
+ call IsPlayerTurn
+ ret c
+
+ ldh a, [hTemp_ffa0]
+ call Func_2c10b
+ ret
+
+; return carry if Bench is full.
+MysteriousFossil_BenchCheck: ; 2f4b3 (b:74b3)
+ ld a, DUELVARS_NUMBER_OF_POKEMON_IN_PLAY_AREA
+ call GetTurnDuelistVariable
+ cp MAX_PLAY_AREA_POKEMON
+ ccf
+ ldtx hl, NoSpaceOnTheBenchText
+ ret
+
+MysteriousFossil_PlaceInPlayAreaEffect: ; 2f4bf (b:74bf)
+ ldh a, [hTempCardIndex_ff9f]
+ call PutHandPokemonCardInPlayArea
+ ret
+
+; return carry if Arena card has no status to heal.
+FullHeal_StatusCheck: ; 2f4c5 (b:74c5)
+ ld a, DUELVARS_ARENA_CARD_STATUS
+ call GetTurnDuelistVariable
+ or a
+ ret nz
+ ldtx hl, NotAffectedByPoisonSleepParalysisOrConfusionText
+ scf
+ ret
+
+FullHeal_ClearStatusEffect: ; 2f4d1 (b:74d1)
+ ld a, ATK_ANIM_FULL_HEAL
+ call Func_2fea9
+ ld a, DUELVARS_ARENA_CARD_STATUS
+ call GetTurnDuelistVariable
+ ld [hl], NO_STATUS
+ bank1call DrawDuelHUDs
+ ret
+
+ImposterProfessorOakEffect: ; 2f4e1 (b:74e1)
+ call SwapTurn
+ call CreateHandCardList
+ call SortCardsInDuelTempListByID
+
+; first return all cards in hand to the deck.
+ ld hl, wDuelTempList
+.loop_return_deck
+ ld a, [hli]
+ cp $ff
+ jr z, .done_return
+ call RemoveCardFromHand
+ call ReturnCardToDeck
+ jr .loop_return_deck
+
+; then draw 7 cards from the deck.
+.done_return
+ call Func_2c0bd
+ ld a, 7
+ bank1call DisplayDrawNCardsScreen
+ ld c, 7
+.loop_draw
+ call DrawCardFromDeck
+ jr c, .done
+ call AddCardToHand
+ dec c
+ jr nz, .loop_draw
+.done
+ call SwapTurn
+ ret
+
+; return carry if not enough cards in hand to discard
+; or if there are no cards left in the deck.
+ComputerSearch_HandDeckCheck: ; 2f513 (b:7513)
+ ld a, DUELVARS_NUMBER_OF_CARDS_IN_HAND
+ call GetTurnDuelistVariable
+ ldtx hl, NotEnoughCardsInHandText
+ cp 3
+ ret c
+ ld a, DUELVARS_NUMBER_OF_CARDS_NOT_IN_DECK
+ call GetTurnDuelistVariable
+ ldtx hl, NoCardsLeftInTheDeckText
+ cp DECK_SIZE
+ ccf
+ ret
+
+ComputerSearch_PlayerDiscardHandSelection: ; 2f52a (b:752a)
+ call HandlePlayerSelection2HandCardsToDiscard
+ ret
+
+ComputerSearch_PlayerDeckSelection: ; 2f52e (b:752e)
+ call CreateDeckCardList
+ bank1call Func_5591
+ ldtx hl, ChooseCardToPlaceInHandText
+ ldtx de, DuelistDeckText
+ bank1call SetCardListHeaderText
+.loop_input
+ bank1call DisplayCardList
+ jr c, .loop_input ; can't exit with B button
+ ldh [hTempList + 2], a
+ ret
+
+ComputerSearch_DiscardAddToHandEffect: ; 2f545 (b:7545)
+; discard cards from hand
+ ld hl, hTempList
+ ld a, [hli]
+ call RemoveCardFromHand
+ call PutCardInDiscardPile
+ ld a, [hli]
+ call RemoveCardFromHand
+ call PutCardInDiscardPile
+
+; add card from deck to hand
+ ld a, [hl]
+ call SearchCardInDeckAndAddToHand
+ call AddCardToHand
+ call Func_2c0bd
+ ret
+
+; return carry if Bench is full.
+ClefairyDoll_BenchCheck: ; 2f561 (b:7561)
+ ld a, DUELVARS_NUMBER_OF_POKEMON_IN_PLAY_AREA
+ call GetTurnDuelistVariable
+ ldtx hl, NoSpaceOnTheBenchText
+ cp MAX_PLAY_AREA_POKEMON
+ ccf
+ ret
+
+ClefairyDoll_PlaceInPlayAreaEffect: ; 2f56d (b:756d)
+ ldh a, [hTempCardIndex_ff9f]
+ call PutHandPokemonCardInPlayArea
+ ret
+
+; return carry if no Pokemon in the Bench.
+MrFuji_BenchCheck: ; 2f573 (b:7573)
+ ld a, DUELVARS_NUMBER_OF_POKEMON_IN_PLAY_AREA
+ call GetTurnDuelistVariable
+ ldtx hl, EffectNoPokemonOnTheBenchText
+ cp 2
+ ret
+
+MrFuji_PlayerSelection: ; 2f57e (b:757e)
+ ldtx hl, ChoosePokemonToReturnToTheDeckText
+ call DrawWideTextBox_WaitForInput
+ bank1call HasAlivePokemonInBench
+ bank1call OpenPlayAreaScreenForSelection
+ ldh a, [hTempPlayAreaLocation_ff9d]
+ ldh [hTemp_ffa0], a
+ ret
+
+MrFuji_ReturnToDeckEffect: ; 2f58f (b:758f)
+; get Play Area location's card index
+ ldh a, [hTemp_ffa0]
+ add DUELVARS_ARENA_CARD
+ call GetTurnDuelistVariable
+ ldh [hTempCardIndex_ff98], a
+
+; find all cards that are in the same location
+; (previous evolutions and energy cards attached)
+; and return them all to the deck.
+ ldh a, [hTemp_ffa0]
+ or CARD_LOCATION_PLAY_AREA
+ ld e, a
+ ld a, DUELVARS_CARD_LOCATIONS
+ call GetTurnDuelistVariable
+.loop_cards
+ push de
+ push hl
+ ld a, [hl]
+ cp e
+ jr nz, .next_card
+ ld a, l
+ call ReturnCardToDeck
+.next_card
+ pop hl
+ pop de
+ inc l
+ ld a, l
+ cp DECK_SIZE
+ jr c, .loop_cards
+
+; clear Play Area location of card
+ ldh a, [hTemp_ffa0]
+ ld e, a
+ call EmptyPlayAreaSlot
+ ld l, DUELVARS_NUMBER_OF_POKEMON_IN_PLAY_AREA
+ dec [hl]
+ call ShiftAllPokemonToFirstPlayAreaSlots
+
+; if Trainer card wasn't played by the Player,
+; print the selected Pokemon's name and show card on screen.
+ call IsPlayerTurn
+ jr c, .done
+ ldh a, [hTempCardIndex_ff98]
+ call LoadCardDataToBuffer1_FromDeckIndex
+ ld hl, wLoadedCard1Name
+ ld a, [hli]
+ ld h, [hl]
+ ld l, a
+ call LoadTxRam2
+ bank1call DrawLargePictureOfCard
+ ldtx hl, PokemonAndAllAttachedCardsWereReturnedToDeckText
+ call DrawWideTextBox_WaitForInput
+.done
+ call Func_2c0bd
+ ret
+
+PlusPowerEffect: ; 2f5e0 (b:75e0)
+; attach Trainer card to Arena Pokemon
+ ld e, PLAY_AREA_ARENA
+ ldh a, [hTempCardIndex_ff9f]
+ call PutHandCardInPlayArea
+
+; increase number of Defender cards of this location by 1
+ ld a, DUELVARS_ARENA_CARD_ATTACHED_PLUSPOWER
+ call GetTurnDuelistVariable
+ inc [hl]
+ ret
+
+; return carry if no Pokemon in the Bench.
+Switch_BenchCheck: ; 2f5ee (b:75ee)
+ ld a, DUELVARS_NUMBER_OF_POKEMON_IN_PLAY_AREA
+ call GetTurnDuelistVariable
+ ldtx hl, EffectNoPokemonOnTheBenchText
+ cp 2
+ ret
+
+Switch_PlayerSelection: ; 2f5f9 (b:75f9)
+ ldtx hl, SelectPkmnOnBenchToSwitchWithActiveText
+ call DrawWideTextBox_WaitForInput
+ bank1call HasAlivePokemonInBench
+ bank1call OpenPlayAreaScreenForSelection
+ ldh a, [hTempPlayAreaLocation_ff9d]
+ ldh [hTemp_ffa0], a
+ ret
+
+Switch_SwitchEffect: ; 2f60a (b:760a)
+ ldh a, [hTemp_ffa0]
+ ld e, a
+ call SwapArenaWithBenchPokemon
+ ret
+
+PokemonCenter_DamageCheck: ; 2f611 (b:7611)
+ call CheckIfPlayAreaHasAnyDamage
+ ldtx hl, NoPokemonWithDamageCountersText
+ ret
+
+PokemonCenter_HealDiscardEnergyEffect: ; 2f618 (b:7618)
+ ld a, DUELVARS_NUMBER_OF_POKEMON_IN_PLAY_AREA
+ call GetTurnDuelistVariable
+ ld d, a
+ ld e, PLAY_AREA_ARENA
+
+; go through every Pokemon in the Play Area
+; and heal all damage & discard their Energy cards.
+.loop_play_area
+; check its damage
+ ld a, e
+ ldh [hTempPlayAreaLocation_ff9d], a
+ call GetCardDamageAndMaxHP
+ or a
+ jr z, .next_pkmn ; if no damage, skip Pokemon
+
+; heal all its damage
+ push de
+ ld e, a
+ ld d, $00
+ call HealPlayAreaCardHP
+
+; loop all cards in deck and for all the Energy cards
+; that are attached to this Play Area location Pokemon,
+; place them in the Discard Pile.
+ ldh a, [hTempPlayAreaLocation_ff9d]
+ or CARD_LOCATION_PLAY_AREA
+ ld e, a
+ ld a, $00
+ call GetTurnDuelistVariable
+.loop_deck
+ ld a, [hl]
+ cp e
+ jr nz, .next_card_deck ; not attached to card, skip
+ ld a, l
+ call LoadCardDataToBuffer2_FromDeckIndex
+ ld a, [wLoadedCard2Type]
+ and TYPE_ENERGY
+ jr z, .next_card_deck ; not Energy, skip
+ ld a, l
+ call PutCardInDiscardPile
+.next_card_deck
+ inc l
+ ld a, l
+ cp DECK_SIZE
+ jr c, .loop_deck
+
+ pop de
+.next_pkmn
+ inc e
+ dec d
+ jr nz, .loop_play_area
+ ret
+
+; return carry if non-Turn Duelist has full Bench
+; or if they have no Basic Pokemon cards in Discard Pile.
+PokemonFlute_BenchCheck: ; 2f659 (b:7659)
+ ld a, DUELVARS_NUMBER_OF_POKEMON_IN_PLAY_AREA
+ call GetNonTurnDuelistVariable
+ ldtx hl, NoSpaceOnTheBenchText
+ cp MAX_PLAY_AREA_POKEMON
+ ccf
+ ret c ; not enough space in Bench
+ ; check Discard Pile
+ call SwapTurn
+ call CreateBasicPokemonCardListFromDiscardPile
+ ldtx hl, ThereAreNoPokemonInDiscardPileText
+ call SwapTurn
+ ret
+
+PokemonFlute_PlayerSelection: ; 2f672 (b:7672)
+; create Discard Pile list
+ call SwapTurn
+ call CreateBasicPokemonCardListFromDiscardPile
+
+; display selection screen and store Player's selection
+ bank1call Func_5591
+ ldtx hl, ChoosePokemonToPlaceInPlayText
+ ldtx de, PlayerDiscardPileText
+ bank1call SetCardListHeaderText
+ bank1call DisplayCardList
+ call SwapTurn
+ ldh a, [hTempCardIndex_ff98]
+ ldh [hTemp_ffa0], a
+ ret
+
+PokemonFlute_PlaceInPlayAreaText: ; 2f68f (b:768f)
+; place selected card in non-Turn Duelist's Bench
+ call SwapTurn
+ ldh a, [hTemp_ffa0]
+ call MoveDiscardPileCardToHand
+ call AddCardToHand
+ call PutHandPokemonCardInPlayArea
+ call SwapTurn
+
+; unless it was the Player who played the card,
+; display the Pokemon card on screen.
+ call IsPlayerTurn
+ ret c
+ call SwapTurn
+ ldh a, [hTemp_ffa0]
+ ldtx hl, CardWasChosenText
+ bank1call DisplayCardDetailScreen
+ call SwapTurn
+ ret
+
+PokemonBreeder_HandPlayAreaCheck: ; 2f6b3 (b:76b3)
+ call CreatePlayableStage2PokemonCardListFromHand
+ jr c, .cannot_evolve
+ bank1call IsPrehistoricPowerActive
+ ret
+.cannot_evolve
+ ldtx hl, ConditionsForEvolvingToStage2NotFulfilledText
+ scf
+ ret
+
+PokemonBreeder_PlayerSelection: ; 2f6c1 (b:76c1)
+; create hand list of playable Stage2 cards
+ call CreatePlayableStage2PokemonCardListFromHand
+ bank1call Func_5591
+
+; handle Player selection of Stage2 card
+ ldtx hl, PleaseSelectCardText
+ ldtx de, DuelistHandText
+ bank1call SetCardListHeaderText
+ bank1call DisplayCardList
+ ret c ; exit if B was pressed
+
+ ldh a, [hTempCardIndex_ff98]
+ ldh [hTemp_ffa0], a
+ ldtx hl, ChooseBasicPokemonToEvolveText
+ call DrawWideTextBox_WaitForInput
+
+; handle Player selection of Basic card to evolve
+ bank1call HasAlivePokemonInPlayArea
+.read_input
+ bank1call OpenPlayAreaScreenForSelection
+ ret c ; exit if B was pressed
+ ldh a, [hTempPlayAreaLocation_ff9d]
+ ldh [hTempPlayAreaLocation_ffa1], a
+ ld e, a
+ ldh a, [hTemp_ffa0]
+ ld d, a
+ call CheckIfCanEvolveInto_BasicToStage2
+ jr c, .read_input ; loop back if cannot evolve this card
+ or a
+ ret
+
+PokemonBreeder_EvolveEffect: ; 2f6f4 (b:76f4)
+ ldh a, [hTempCardIndex_ff9f]
+ push af
+ ld hl, hTemp_ffa0
+ ld a, [hli]
+ ldh [hTempCardIndex_ff98], a
+ ld a, [hl] ; hTempPlayAreaLocation_ffa1
+ ldh [hTempPlayAreaLocation_ff9d], a
+
+; load the Basic Pokemon card name to RAM
+ add DUELVARS_ARENA_CARD
+ call GetTurnDuelistVariable
+ call LoadCardDataToBuffer1_FromDeckIndex
+ ld hl, wLoadedCard1Name
+ ld a, [hli]
+ ld h, [hl]
+ ld l, a
+ call LoadTxRam2
+
+; evolve card and overwrite its stage as STAGE2_WITHOUT_STAGE1
+ ldh a, [hTempCardIndex_ff98]
+ call EvolvePokemonCard
+ ld [hl], STAGE2_WITHOUT_STAGE1
+
+; load Stage2 Pokemon card name to RAM
+ ldh a, [hTempCardIndex_ff98]
+ call LoadCardDataToBuffer1_FromDeckIndex
+ ld a, 18
+ call CopyCardNameAndLevel
+ xor a
+ ld [hl], a ; $0 character
+ ld hl, wTxRam2_b
+ ld [hli], a
+ ld [hl], a
+
+; display Pokemon picture and play sfx,
+; print the corresponding card names.
+ bank1call DrawLargePictureOfCard
+ ld a, $5e
+ call PlaySFX
+ ldtx hl, PokemonEvolvedIntoPokemonText
+ call DrawWideTextBox_WaitForInput
+ bank1call Func_161e
+ pop af
+ ldh [hTempCardIndex_ff9f], a
+ ret
+
+; creates list in wDuelTempList of all Stage2 Pokemon cards
+; in the hand that can evolve a Basic Pokemon card in Play Area
+; through use of Pokemon Breeder.
+; returns carry if that list is empty.
+CreatePlayableStage2PokemonCardListFromHand: ; 2f73e (b:773e)
+ call CreateHandCardList
+ ret c ; return if no hand cards
+
+; check if hand Stage2 Pokemon cards can be made
+; to evolve a Basic Pokemon in the Play Area and, if so,
+; add it to the wDuelTempList.
+ ld hl, wDuelTempList
+ ld e, l
+ ld d, h
+.loop_hand
+ ld a, [hl]
+ cp $ff
+ jr z, .done
+ call .CheckIfCanEvolveAnyPlayAreaBasicCard
+ jr c, .next_hand_card
+ ld a, [hl]
+ ld [de], a
+ inc de
+.next_hand_card
+ inc hl
+ jr .loop_hand
+
+.done
+ ld a, $ff ; terminating byte
+ ld [de], a
+ ld a, [wDuelTempList]
+ cp $ff
+ scf
+ ret z ; return carry if empty
+ ; not empty
+ or a
+ ret
+
+; return carry if Stage2 card in a cannot evolve any
+; of the Basic Pokemon in Play Area through Pokemon Breeder.
+.CheckIfCanEvolveAnyPlayAreaBasicCard
+ push de
+ ld d, a
+ call LoadCardDataToBuffer2_FromDeckIndex
+ ld a, [wLoadedCard2Type]
+ cp TYPE_ENERGY
+ jr nc, .set_carry ; skip if not Pokemon card
+ ld a, [wLoadedCard2Stage]
+ cp STAGE2
+ jr nz, .set_carry ; skip if not Stage2
+
+; check if can evolve any Play Area cards
+ push hl
+ push bc
+ ld a, DUELVARS_NUMBER_OF_POKEMON_IN_PLAY_AREA
+ call GetTurnDuelistVariable
+ ld c, a
+ ld e, PLAY_AREA_ARENA
+.loop_play_area
+ push bc
+ push de
+ call CheckIfCanEvolveInto_BasicToStage2
+ pop de
+ pop bc
+ jr nc, .done_play_area
+ inc e
+ dec c
+ jr nz, .loop_play_area
+; set carry
+ scf
+.done_play_area
+ pop bc
+ pop hl
+ pop de
+ ret
+.set_carry
+ pop de
+ scf
+ ret
+
+; return carry if no cards in the Bench.
+ScoopUp_BenchCheck: ; 2f795 (b:7795)
+ ld a, DUELVARS_NUMBER_OF_POKEMON_IN_PLAY_AREA
+ call GetTurnDuelistVariable
+ ldtx hl, EffectNoPokemonOnTheBenchText
+ cp 2
+ ret
+
+ScoopUp_PlayerSelection: ; 2f7a0 (b:77a0)
+; print text box
+ ldtx hl, ChoosePokemonToScoopUpText
+ call DrawWideTextBox_WaitForInput
+
+; handle Player selection
+ bank1call HasAlivePokemonInPlayArea
+ bank1call OpenPlayAreaScreenForSelection
+ ret c ; exit if B was pressed
+
+ ldh [hTemp_ffa0], a
+ or a
+ ret nz ; if it wasn't the Active Pokemon, we are done
+
+; handle switching to a Pokemon in Bench and store location selected.
+ call EmptyScreen
+ ldtx hl, SelectPokemonToPlaceInTheArenaText
+ call DrawWideTextBox_WaitForInput
+ bank1call HasAlivePokemonInBench
+ bank1call OpenPlayAreaScreenForSelection
+ ldh [hTempPlayAreaLocation_ffa1], a
+ ret
+
+ScoopUp_ReturnToHandEffect: ; 2f7c3 (b:77c3)
+; store chosen card location to Scoop Up
+ ldh a, [hTemp_ffa0]
+ or CARD_LOCATION_PLAY_AREA
+ ld e, a
+
+; find Basic Pokemon card that is in the selected Play Area location
+; and add it to the hand, discarding all cards attached.
+ ld a, DUELVARS_CARD_LOCATIONS
+ call GetTurnDuelistVariable
+.loop
+ ld a, [hl]
+ cp e
+ jr nz, .next_card ; skip if not in selected location
+ ld a, l
+ call LoadCardDataToBuffer2_FromDeckIndex
+ ld a, [wLoadedCard2Type]
+ cp TYPE_ENERGY
+ jr nc, .next_card ; skip if not Pokemon card
+ ld a, [wLoadedCard2Stage]
+ or a
+ jr nz, .next_card ; skip if not Basic stage
+; found
+ ld a, l
+ ldh [hTempCardIndex_ff98], a
+ call AddCardToHand
+ ; optimization: break loop here, since
+ ; no two Basic Pokemon cards may occupy
+ ; the same Play Area location.
+.next_card
+ inc l
+ ld a, l
+ cp DECK_SIZE
+ jr c, .loop
+
+; since the card has been moved to hand,
+; MovePlayAreaCardToDiscardPile will take care
+; of discarding every higher stage cards and other cards attached.
+ ldh a, [hTemp_ffa0]
+ ld e, a
+ call MovePlayAreaCardToDiscardPile
+
+; if the Pokemon was in the Arena, clear status
+ ldh a, [hTemp_ffa0]
+ or a
+ jr nz, .skip_clear_status
+ call ClearAllStatusConditions
+.skip_clear_status
+
+; if card was not played by Player, show detail screen
+; and print corresponding text.
+ call IsPlayerTurn
+ jr c, .shift_or_switch
+ ldtx hl, PokemonWasReturnedFromArenaToHandText
+ ldh a, [hTemp_ffa0]
+ or a
+ jr z, .display_detail_screen
+ ldtx hl, PokemonWasReturnedFromBenchToHandText
+.display_detail_screen
+ ldh a, [hTempCardIndex_ff98]
+ bank1call DisplayCardDetailScreen
+
+.shift_or_switch
+; if card was in Bench, simply shift Pokemon slots...
+ ldh a, [hTemp_ffa0]
+ or a
+ jr z, .switch
+ call ShiftAllPokemonToFirstPlayAreaSlots
+ ret
+
+.switch
+; ...if Pokemon was in Arena, then switch it with the selected Bench card.
+ ldh a, [hTempPlayAreaLocation_ffa1]
+ ld d, a
+ ld e, PLAY_AREA_ARENA
+ call SwapPlayAreaPokemon
+ call ShiftAllPokemonToFirstPlayAreaSlots
+ ret
+
+; return carry if no other cards in hand,
+; or if there are no Pokemon cards in hand.
+PokemonTrader_HandDeckCheck: ; 2f826 (b:7826)
+ ld a, DUELVARS_NUMBER_OF_CARDS_IN_HAND
+ call GetTurnDuelistVariable
+ ldtx hl, ThereAreNoCardsInHandThatYouCanChangeText
+ cp 2
+ ret c ; return if no other cards in hand
+ call CreatePokemonCardListFromHand
+ ldtx hl, ThereAreNoCardsInHandThatYouCanChangeText
+ ret
+
+PokemonTrader_PlayerHandSelection: ; 2f838 (b:7838)
+; print text box
+ ldtx hl, ChooseCardFromYourHandToSwitchText
+ call DrawWideTextBox_WaitForInput
+
+; create list with all Pokemon cards in hand
+ call CreatePokemonCardListFromHand
+ bank1call Func_5591
+
+; handle Player selection
+ ldtx hl, ChooseCardToSwitchText
+ ldtx de, DuelistHandText
+ bank1call SetCardListHeaderText
+ bank1call DisplayCardList
+ ldh [hTemp_ffa0], a
+ ret
+
+PokemonTrader_PlayerDeckSelection: ; 2f853 (b:7853)
+; temporarily place chosen hand card in deck
+; so it can be potentially chosen to be traded.
+ ldh a, [hTemp_ffa0]
+ call RemoveCardFromHand
+ call ReturnCardToDeck
+
+; display deck card list screen
+ ldtx hl, ChooseBasicOrEvolutionPokemonCardFromDeckText
+ call DrawWideTextBox_WaitForInput
+ call CreateDeckCardList
+ bank1call Func_5591
+ ldtx hl, ChoosePokemonCardText
+ ldtx de, DuelistDeckText
+ bank1call SetCardListHeaderText
+
+; handle Player selection
+.read_input
+ bank1call DisplayCardList
+ jr c, .read_input ; pressing B loops back to selection
+ call LoadCardDataToBuffer2_FromDeckIndex
+ ld a, [wLoadedCard2Type]
+ cp TYPE_ENERGY
+ jr nc, .read_input ; can't select non-Pokemon cards
+
+; a valid card was selected, store its card index and
+; place the selected hand card back to the hand.
+ ldh a, [hTempCardIndex_ff98]
+ ldh [hTempPlayAreaLocation_ffa1], a
+ ldh a, [hTemp_ffa0]
+ call SearchCardInDeckAndAddToHand
+ call AddCardToHand
+ or a
+ ret
+
+PokemonTrader_TradeCardsEffect: ; 2f88d (b:788d)
+; place hand card in deck
+ ldh a, [hTemp_ffa0]
+ call RemoveCardFromHand
+ call ReturnCardToDeck
+
+; place deck card in hand
+ ldh a, [hTempPlayAreaLocation_ffa1]
+ call SearchCardInDeckAndAddToHand
+ call AddCardToHand
+
+; display cards if the Pokemon Trader wasn't played by Player
+ call IsPlayerTurn
+ jr c, .done
+ ldh a, [hTemp_ffa0]
+ ldtx hl, PokemonWasReturnedToDeckText
+ bank1call DisplayCardDetailScreen
+ ldh a, [hTempPlayAreaLocation_ffa1]
+ ldtx hl, WasPlacedInTheHandText
+ bank1call DisplayCardDetailScreen
+.done
+ call Func_2c0bd
+ ret
+
+; makes list in wDuelTempList with all Pokemon cards
+; that are in Turn Duelist's hand.
+; if list turns out empty, return carry.
+CreatePokemonCardListFromHand: ; 2f8b6 (b:78b6)
+ ld a, DUELVARS_NUMBER_OF_CARDS_IN_HAND
+ call GetTurnDuelistVariable
+ ld c, a
+ ld l, DUELVARS_HAND
+ ld de, wDuelTempList
+.loop
+ ld a, [hl]
+ call LoadCardDataToBuffer2_FromDeckIndex
+ ld a, [wLoadedCard2Type]
+ cp TYPE_ENERGY
+ jr nc, .next_hand_card
+ ld a, [hl]
+ ld [de], a
+ inc de
+.next_hand_card
+ inc l
+ dec c
+ jr nz, .loop
+ ld a, $ff ; terminating byte
+ ld [de], a
+ ld a, [wDuelTempList]
+ cp $ff
+ jr z, .set_carry
+ or a
+ ret
+.set_carry
+ scf
+ ret
+
+; return carry if no cards in deck
+Pokedex_DeckCheck: ; 2f8e1 (b:78e1)
+ ld a, DUELVARS_NUMBER_OF_CARDS_NOT_IN_DECK
+ call GetTurnDuelistVariable
+ ldtx hl, NoCardsLeftInTheDeckText
+ cp DECK_SIZE
+ ccf
+ ret
+
+Pokedex_PlayerSelection: ; 2f8ed (b:78ed)
+; print text box
+ ldtx hl, RearrangeThe5CardsAtTopOfDeckText
+ call DrawWideTextBox_WaitForInput
+
+; cap the number of cards to reorder up to
+; number of cards left in the deck (maximum of 5)
+ ld a, DUELVARS_NUMBER_OF_CARDS_NOT_IN_DECK
+ call GetTurnDuelistVariable
+ ld b, a
+ ld a, DECK_SIZE
+ sub [hl]
+ ld c, 5
+ cp c
+ jr nc, .no_cap
+ ld c, a
+.no_cap
+
+; fill wDuelTempList with cards that are going to be sorted
+ ld a, c
+ inc a
+ ld [wNumberOfCardsToOrder], a
+ ld a, b
+ add DUELVARS_DECK_CARDS
+ ld l, a
+ ld de, wDuelTempList
+.loop_cards_to_order
+ ld a, [hli]
+ ld [de], a
+ inc de
+ dec c
+ jr nz, .loop_cards_to_order
+ ld a, $ff ; terminating byte
+ ld [de], a
+
+.clear_list
+; wDuelTempList + 10 will be filled with numbers from 1
+; to 5 (or whatever the maximum order card is).
+; so that the first item in that list corresponds to the first card
+; the second item corresponds to the second card, etc.
+; and the number in the list corresponds to the ordering number.
+ call CountCardsInDuelTempList
+ ld b, a
+ ld a, 1
+; fill order list with zeroes
+ ldh [hCurSelectionItem], a
+ ld hl, wDuelTempList + 10
+ xor a
+.loop_init
+ ld [hli], a
+ dec b
+ jr nz, .loop_init
+ ld [hl], $ff ; terminating byte
+
+; display card list to order
+ bank1call InitAndDrawCardListScreenLayout
+ ldtx hl, ChooseTheOrderOfTheCardsText
+ ldtx de, DuelistDeckText
+ bank1call SetCardListHeaderText
+ bank1call Func_5735
+
+.read_input
+ bank1call DisplayCardList
+ jr c, .undo ; if B is pressed, undo last order selection
+
+; a card was selected, check if it's already been selected
+ ldh a, [hCurMenuItem]
+ ld e, a
+ ld d, $00
+ ld hl, wDuelTempList + 10
+ add hl, de
+ ld a, [hl]
+ or a
+ jr nz, .read_input ; already has an ordering number
+
+; hasn't been ordered yet, apply to it current ordering number
+; and increase it by 1.
+ ldh a, [hCurSelectionItem]
+ ld [hl], a
+ inc a
+ ldh [hCurSelectionItem], a
+
+; refresh screen
+ push af
+ bank1call Func_5744
+ pop af
+
+; check if we're done ordering
+ ldh a, [hCurSelectionItem]
+ ld hl, wNumberOfCardsToOrder
+ cp [hl]
+ jr c, .read_input ; if still more cards to select, loop back up
+
+; we're done selecting cards
+ call EraseCursor
+ ldtx hl, IsThisOKText
+ call YesOrNoMenuWithText_LeftAligned
+ jr c, .clear_list ; "No" was selected, start over
+ ; selection was confirmed
+
+; now wDuelTempList + 10 will be overwritten with the
+; card indices in order of selection.
+ ld hl, wDuelTempList + 10
+ ld de, wDuelTempList
+ ld c, 0
+.loop_write_indices
+ ld a, [hli]
+ cp $ff
+ jr z, .done_write_indices
+ push hl
+ push bc
+ ld c, a
+ ld b, $00
+ ld hl, hTempCardIndex_ff9f
+ add hl, bc
+ ld a, [de]
+ ld [hl], a
+ pop bc
+ pop hl
+ inc de
+ inc c
+ jr .loop_write_indices
+
+.done_write_indices
+ ld b, $00
+ ld hl, hTempList
+ add hl, bc
+ ld [hl], $ff ; terminating byte
+ or a
+ ret
+
+.undo
+; undo last selection and get previous order number
+ ld hl, hCurSelectionItem
+ ld a, [hl]
+ cp 1
+ jr z, .read_input ; already at first input, nothing to undo
+ dec a
+ ld [hl], a
+ ld c, a
+ ld hl, wDuelTempList + 10
+.asm_2f99e
+ ld a, [hli]
+ cp c
+ jr nz, .asm_2f99e
+ dec hl
+ ld [hl], $00 ; overwrite order number with 0
+ bank1call Func_5744
+ jr .read_input
+
+Pokedex_OrderDeckCardsEffect: ; 2f9aa (b:79aa)
+; place cards in order to the hand.
+ ld hl, hTempList
+ ld c, 0
+.loop_place_hand
+ ld a, [hli]
+ cp $ff
+ jr z, .place_top_deck
+ call SearchCardInDeckAndAddToHand
+ inc c
+ jr .loop_place_hand
+
+.place_top_deck
+; go to last card in list and iterate in decreasing order
+; placing each card in top of deck.
+ dec hl
+ dec hl
+.loop_place_deck
+ ld a, [hld]
+ call ReturnCardToDeck
+ dec c
+ jr nz, .loop_place_deck
+ ret
+
+BillEffect: ; 2f9c4 (b:79c4)
+ ld a, 2
+ bank1call DisplayDrawNCardsScreen
+ ld c, 2
+.loop_draw
+ call DrawCardFromDeck
+ jr c, .done
+ ldh [hTempCardIndex_ff98], a
+ call AddCardToHand
+ call IsPlayerTurn
+ jr nc, .skip_display_screen
+ push bc
+ bank1call DisplayPlayerDrawCardScreen
+ pop bc
+.skip_display_screen
+ dec c
+ jr nz, .loop_draw
+.done
+ ret
+
+LassEffect: ; 2f9e3 (b:79e3)
+; first discard Lass card that was used
+ ldh a, [hTempCardIndex_ff9f]
+ call RemoveCardFromHand
+ call PutCardInDiscardPile
+
+ ldtx hl, PleaseCheckTheOpponentsHandText
+ call DrawWideTextBox_WaitForInput
+
+ call .DisplayLinkOrCPUHand
+ ; do for non-Turn Duelist
+ call SwapTurn
+ call .ShuffleDuelistHandTrainerCardsInDeck
+ call SwapTurn
+ ; do for Turn Duelist
+; fallthrough
+
+.ShuffleDuelistHandTrainerCardsInDeck
+ call CreateHandCardList
+ call SortCardsInDuelTempListByID
+ xor a
+ ldh [hCurSelectionItem], a
+ ld hl, wDuelTempList
+
+; go through all cards in hand
+; and any Trainer card is returned to deck.
+.loop_hand
+ ld a, [hli]
+ ldh [hTempCardIndex_ff98], a
+ cp $ff
+ jr z, .done
+ call GetCardIDFromDeckIndex
+ call GetCardType
+ cp TYPE_TRAINER
+ jr nz, .loop_hand
+ ldh a, [hTempCardIndex_ff98]
+ call RemoveCardFromHand
+ call ReturnCardToDeck
+ push hl
+ ld hl, hCurSelectionItem
+ inc [hl]
+ pop hl
+ jr .loop_hand
+.done
+; show card list
+ ldh a, [hCurSelectionItem]
+ or a
+ call nz, Func_2c0bd ; only show list if there were any Trainer cards
+ ret
+
+.DisplayLinkOrCPUHand ; 2fa31 (b:7a31)
+ ld a, [wDuelType]
+ or a
+ jr z, .cpu_opp
+
+; link duel
+ ldh a, [hWhoseTurn]
+ push af
+ ld a, OPPONENT_TURN
+ ldh [hWhoseTurn], a
+ call .DisplayOppHand
+ pop af
+ ldh [hWhoseTurn], a
+ ret
+
+.cpu_opp
+ call SwapTurn
+ call .DisplayOppHand
+ call SwapTurn
+ ret
+
+.DisplayOppHand ; 2fa4f (b:7a4f)
+ call CreateHandCardList
+ jr c, .no_cards
+ bank1call InitAndDrawCardListScreenLayout
+ ldtx hl, ChooseTheCardYouWishToExamineText
+ ldtx de, DuelistHandText
+ bank1call SetCardListHeaderText
+ ld a, A_BUTTON | START
+ ld [wNoItemSelectionMenuKeys], a
+ bank1call DisplayCardList
+ ret
+.no_cards
+ ldtx hl, DuelistHasNoCardsInHandText
+ call DrawWideTextBox_WaitForInput
+ ret
+
+; return carry if not enough cards in hand for effect
+Maintenance_HandCheck: ; 2fa70 (b:7a70)
+ ld a, DUELVARS_NUMBER_OF_CARDS_IN_HAND
+ call GetTurnDuelistVariable
+ ldtx hl, NotEnoughCardsInHandText
+ cp 3
+ ret
+
+Maintenance_PlayerSelection: ; 2fa7b (b:7a7b)
+ ldtx hl, Choose2HandCardsFromHandToReturnToDeckText
+ ldtx de, ChooseTheCardToPutBackText
+ call HandlePlayerSelection2HandCards
+ ret
+
+Maintenance_ReturnToDeckAndDrawEffect: ; 2fa85 (b:7a85)
+; return both selected cards to the deck
+ ldh a, [hTempList]
+ call RemoveCardFromHand
+ call ReturnCardToDeck
+ ldh a, [hTempList + 1]
+ call RemoveCardFromHand
+ call ReturnCardToDeck
+ call Func_2c0bd
+
+; draw one card
+ ld a, 1
+ bank1call DisplayDrawNCardsScreen
+ call DrawCardFromDeck
+ ldh [hTempCardIndex_ff98], a
+ call AddCardToHand
+ call IsPlayerTurn
+ ret nc
+ ; show card on screen if played by Player
+ bank1call DisplayPlayerDrawCardScreen
+ ret
+
+; return carry if no cards in deck
+PokeBall_DeckCheck: ; 2faad (b:7aad)
+ ld a, DUELVARS_NUMBER_OF_CARDS_NOT_IN_DECK
+ call GetTurnDuelistVariable
+ ldtx hl, NoCardsLeftInTheDeckText
+ cp DECK_SIZE
+ ccf
+ ret
+
+PokeBall_PlayerSelection: ; 2fab9 (b:7ab9)
+ ld de, DUELVARS_NUMBER_OF_POKEMON_IN_PLAY_AREA
+ call Func_2c08a
+ ldh [hTempList], a ; store coin result
+ ret nc
+
+; create list of all Pokemon cards in deck to search for
+ call CreateDeckCardList
+ ldtx hl, ChooseBasicOrEvolutionPokemonCardFromDeckText
+ ldtx bc, EvolutionCardText
+ lb de, SEARCHEFFECT_POKEMON, 0
+ call LookForCardsInDeck
+ jr c, .no_pkmn ; return if Player chose not to check deck
+
+; handle input
+ bank1call Func_5591
+ ldtx hl, ChoosePokemonCardText
+ ldtx de, DuelistDeckText
+ bank1call SetCardListHeaderText
+.read_input
+ bank1call DisplayCardList
+ jr c, .try_exit ; B was pressed, check if Player can cancel operation
+ ldh a, [hTempCardIndex_ff98]
+ call LoadCardDataToBuffer2_FromDeckIndex
+ ld a, [wLoadedCard2Type]
+ cp TYPE_ENERGY
+ jr nc, .play_sfx ; can't select non-Pokemon card
+ ldh a, [hTempCardIndex_ff98]
+ ldh [hTempList + 1], a
+ or a
+ ret
+
+.no_pkmn
+ ld a, $ff
+ ldh [hTempList + 1], a
+ or a
+ ret
+
+.play_sfx
+ call Func_3794
+ jr .read_input
+
+.try_exit
+; Player can only exit screen if there are no cards to choose
+ ld hl, wDuelTempList
+.loop
+ ld a, [hli]
+ cp $ff
+ jr z, .no_pkmn
+ call LoadCardDataToBuffer2_FromDeckIndex
+ ld a, [wLoadedCard2Type]
+ cp TYPE_ENERGY
+ jr nc, .loop
+ jr .read_input
+
+PokeBall_AddToHandEffect: ; 2fb15 (b:7b15)
+ ldh a, [hTempList]
+ or a
+ ret z ; return if coin toss was tails
+
+ ldh a, [hTempList + 1]
+ cp $ff
+ jr z, .done ; skip if no Pokemon was chosen
+
+; add Pokemon card to hand and show in screen if
+; it wasn't the Player who played the Trainer card.
+ call SearchCardInDeckAndAddToHand
+ call AddCardToHand
+ call IsPlayerTurn
+ jr c, .done
+ ldh a, [hTempList + 1]
+ ldtx hl, WasPlacedInTheHandText
+ bank1call DisplayCardDetailScreen
+.done
+ call Func_2c0bd
+ ret
+
+; return carry if no cards in the Discard Pile
+Recycle_DiscardPileCheck: ; 2fb36 (b:7b36)
+ ld a, DUELVARS_NUMBER_OF_CARDS_IN_DISCARD_PILE
+ call GetTurnDuelistVariable
+ ldtx hl, ThereAreNoCardsInTheDiscardPileText
+ cp 1
+ ret
+
+Recycle_PlayerSelection: ; 2fb41 (b:7b41)
+ ld de, DUELVARS_NUMBER_OF_POKEMON_IN_PLAY_AREA
+ call Func_2c08a
+ jr nc, .tails
+
+ call CreateDiscardPileCardList
+ bank1call Func_5591
+ ldtx hl, PleaseSelectCardText
+ ldtx de, PlayerDiscardPileText
+ bank1call SetCardListHeaderText
+.read_input
+ bank1call DisplayCardList
+ jr c, .read_input ; can't cancel with B button
+
+; Discard Pile card was chosen
+ ldh a, [hTempCardIndex_ff98]
+ ldh [hTempList], a
+ ret
+
+.tails
+ ld a, $ff
+ ldh [hTempList], a
+ or a
+ ret
+
+Recycle_AddToHandEffect: ; 2fb68 (b:7b68)
+ ldh a, [hTempList]
+ cp $ff
+ ret z ; return if no card was selected
+
+; add card to hand and show in screen if
+; it wasn't the Player who played the Trainer card.
+ call MoveDiscardPileCardToHand
+ call ReturnCardToDeck
+ call IsPlayerTurn
+ ret c
+ ldh a, [hTempList]
+ ldtx hl, CardWasChosenText
+ bank1call DisplayCardDetailScreen
+ ret
+
+; return carry if Bench is full or
+; if no Basic Pokemon cards in Discard Pile.
+Revive_BenchCheck: ; 2fb80 (b:7b80)
+ ld a, DUELVARS_NUMBER_OF_POKEMON_IN_PLAY_AREA
+ call GetTurnDuelistVariable
+ ldtx hl, NoSpaceOnTheBenchText
+ cp MAX_PLAY_AREA_POKEMON
+ ccf
+ ret c
+ call CreateBasicPokemonCardListFromDiscardPile
+ ldtx hl, ThereAreNoPokemonInDiscardPileText
+ ret
+
+Revive_PlayerSelection: ; 2fb93 (b:7b93)
+; create Basic Pokemon card list from Discard Pile
+ ldtx hl, ChooseBasicPokemonToPlaceOnBenchText
+ call DrawWideTextBox_WaitForInput
+ call CreateBasicPokemonCardListFromDiscardPile
+ bank1call Func_5591
+
+; display screen to select Pokemon
+ ldtx hl, PleaseSelectCardText
+ ldtx de, PlayerDiscardPileText
+ bank1call SetCardListHeaderText
+ bank1call DisplayCardList
+
+; store selection
+ ldh a, [hTempCardIndex_ff98]
+ ldh [hTemp_ffa0], a
+ ret
+
+Revive_PlaceInPlayAreaEffect: ; 2fbb0 (b:7bb0)
+; place selected Pokemon in the Bench
+ ldh a, [hTemp_ffa0]
+ call MoveDiscardPileCardToHand
+ call AddCardToHand
+ call PutHandPokemonCardInPlayArea
+
+; set HP to half, rounded up
+ add DUELVARS_ARENA_CARD_HP
+ call GetTurnDuelistVariable
+ srl a
+ bit 0, a
+ jr z, .rounded
+ add 5 ; round up HP to nearest 10
+.rounded
+ ld [hl], a
+ call IsPlayerTurn
+ ret c ; done if Player played Revive
+
+; display card
+ ldh a, [hTemp_ffa0]
+ ldtx hl, PlacedOnTheBenchText
+ bank1call DisplayCardDetailScreen
+ ret
+
+; makes list in wDuelTempList with all Basic Pokemon cards
+; that are in Turn Duelist's Discard Pile.
+; if list turns out empty, return carry.
+CreateBasicPokemonCardListFromDiscardPile: ; 2fbd6 (b:7bd6)
+; gets hl to point at end of Discard Pile cards
+; and iterates the cards in reverse order.
+ ld a, DUELVARS_NUMBER_OF_CARDS_IN_DISCARD_PILE
+ call GetTurnDuelistVariable
+ ld b, a
+ add DUELVARS_DECK_CARDS
+ ld l, a
+ ld de, wDuelTempList
+ inc b
+ jr .next_discard_pile_card
+
+.check_card
+ ld a, [hl]
+ call LoadCardDataToBuffer2_FromDeckIndex
+ ld a, [wLoadedCard2Type]
+ cp TYPE_ENERGY
+ jr nc, .next_discard_pile_card ; if not Pokemon card, skip
+ ld a, [wLoadedCard2Stage]
+ or a
+ jr nz, .next_discard_pile_card ; if not Basic stage, skip
+
+; write this card's index to wDuelTempList
+ ld a, [hl]
+ ld [de], a
+ inc de
+.next_discard_pile_card
+ dec l
+ dec b
+ jr nz, .check_card
+
+; done with the loop.
+ ld a, $ff ; terminating byte
+ ld [de], a
+ ld a, [wDuelTempList]
+ cp $ff
+ jr z, .set_carry
+ or a
+ ret
+.set_carry
+ scf
+ ret
+
+; return carry if Turn Duelist has no Evolution cards in Play Area
+DevolutionSpray_PlayAreaEvolutionCheck: ; 2fc0b (b:7c0b)
+ ld a, DUELVARS_NUMBER_OF_POKEMON_IN_PLAY_AREA
+ call GetTurnDuelistVariable
+ ld c, a
+ ld l, DUELVARS_ARENA_CARD
+.loop
+ ld a, [hli]
+ call LoadCardDataToBuffer2_FromDeckIndex
+ ld a, [wLoadedCard2Stage]
+ or a
+ ret nz ; found an Evolution card
+ dec c
+ jr nz, .loop
+
+ ldtx hl, ThereAreNoStage1PokemonText
+ scf
+ ret
+
+DevolutionSpray_PlayerSelection: ; 2fc24 (b:7c24)
+; display textbox
+ ldtx hl, ChooseEvolutionCardAndPressAButtonToDevolveText
+ call DrawWideTextBox_WaitForInput
+
+; have Player select an Evolution card in Play Area
+ ld a, 1
+ ldh [hCurSelectionItem], a
+ bank1call HasAlivePokemonInPlayArea
+.read_input
+ bank1call OpenPlayAreaScreenForSelection
+ ret c ; exit if B was pressed
+ bank1call GetCardOneStageBelow
+ jr c, .read_input ; can't select Basic cards
+
+; get pre-evolution card data
+ ldh a, [hTempPlayAreaLocation_ff9d]
+ add DUELVARS_ARENA_CARD_HP
+ call GetTurnDuelistVariable
+ push hl
+ push af
+ ldh a, [hTempPlayAreaLocation_ff9d]
+ add DUELVARS_ARENA_CARD_STAGE
+ ld l, a
+ ld a, [hl]
+ push hl
+ push af
+ ldh a, [hTempPlayAreaLocation_ff9d]
+ add DUELVARS_ARENA_CARD
+ ld l, a
+ ld a, [hl]
+ push hl
+ push af
+ jr .update_data
+
+.repeat_devolution
+; show Play Area screen with static cursor
+; so that the Player either presses A to do one more devolution
+; or presses B to finish selection.
+ bank1call Func_6194
+ jr c, .done_selection ; if B pressed, end selection instead
+ ; do one more devolution
+ bank1call GetCardOneStageBelow
+
+.update_data
+; overwrite the card data to new devolved stats
+ ld a, d
+ call UpdateDevolvedCardHPAndStage
+ call GetNextPositionInTempList_TrainerEffects
+ ld [hl], e
+ ld a, d
+ call LoadCardDataToBuffer2_FromDeckIndex
+ ld a, [wLoadedCard2Stage]
+ or a
+ jr nz, .repeat_devolution ; can do one more devolution
+
+.done_selection
+ call GetNextPositionInTempList_TrainerEffects
+ ld [hl], $ff ; terminating byte
+
+; store this Play Area location in first item of temp list
+ ldh a, [hTempPlayAreaLocation_ff9d]
+ ldh [hTempList], a
+
+; update Play Area location display of this Pokemon
+ call EmptyScreen
+ ldh a, [hTempPlayAreaLocation_ff9d]
+ ld hl, wHUDEnergyAndHPBarsX
+ ld [hli], a
+ ld [hl], $00
+ bank1call PrintPlayAreaCardInformationAndLocation
+ call EnableLCD
+ pop bc
+ pop hl
+
+; rewrite all duelvars from before the selection was done
+; this is so that if "No" is selected in confirmation menu,
+; then the Pokemon isn't devolved and remains unchanged.
+ ld [hl], b
+ ldtx hl, IsThisOKText
+ call YesOrNoMenuWithText
+ pop bc
+ pop hl
+
+ ld [hl], b
+ pop bc
+ pop hl
+
+ ld [hl], b
+ ret
+
+DevolutionSpray_DevolutionEffect: ; 2fc99 (b:7c99)
+; first byte in list is Play Area location chosen
+ ld hl, hTempList
+ ld a, [hli]
+ ldh [hTempPlayAreaLocation_ff9d], a
+ add DUELVARS_ARENA_CARD
+ call GetTurnDuelistVariable
+ push hl
+ push af
+
+; loop through devolutions selected
+ ld hl, hTempList + 1
+.loop_devolutions
+ ld a, [hl]
+ cp $ff
+ jr z, .check_ko ; list is over
+ ; devolve card to its stage below
+ push hl
+ bank1call GetCardOneStageBelow
+ ld a, d
+ call UpdateDevolvedCardHPAndStage
+ call ResetDevolvedCardStatus
+ pop hl
+ ld a, [hli]
+ call PutCardInDiscardPile
+ jr .loop_devolutions
+
+.check_ko
+ pop af
+ ld e, a
+ pop hl
+ ld d, [hl]
+ call PrintDevolvedCardNameAndLevelText
+ ldh a, [hTempList]
+ call PrintPlayAreaCardKnockedOutIfNoHP
+ bank1call Func_6e49
+ ret
+
+; returns carry if neither duelist has any energy cards attached
+SuperEnergyRemoval_EnergyCheck: ; 2fcd0 (b:7cd0)
+ call CheckIfThereAreAnyEnergyCardsAttached
+ ldtx hl, NoEnergyCardsAttachedToPokemonInYourPlayAreaText
+ ret c
+ call SwapTurn
+ call CheckIfThereAreAnyEnergyCardsAttached
+ ldtx hl, NoEnergyCardsAttachedToPokemonInOppPlayAreaText
+ call SwapTurn
+ ret
+
+SuperEnergyRemoval_PlayerSelection: ; 2fce4 (b:7ce4)
+; handle selection of Energy to discard in own Play Area
+ ldtx hl, ChoosePokemonInYourAreaThenPokemonInYourOppText
+ call DrawWideTextBox_WaitForInput
+ call HandlePokemonAndEnergySelectionScreen
+ ret c ; return if operation was cancelled
+
+ ldtx hl, ChoosePokemonToRemoveEnergyFromText
+ call DrawWideTextBox_WaitForInput
+
+ call SwapTurn
+ ld a, 3
+ ldh [hCurSelectionItem], a
+.select_opp_pkmn
+ bank1call HasAlivePokemonInPlayArea
+ bank1call OpenPlayAreaScreenForSelection
+ jr nc, .opp_pkmn_selected
+ ; B was pressed
+ call SwapTurn
+ ret ; return if operation was cancelled
+.opp_pkmn_selected
+ ld e, a
+ call GetPlayAreaCardAttachedEnergies
+ ld a, [wTotalAttachedEnergies]
+ or a
+ jr nz, .has_energy ; has any energy cards attached?
+ ; no energy, loop back
+ ldtx hl, NoEnergyCardsText
+ call DrawWideTextBox_WaitForInput
+ jr .select_opp_pkmn
+
+.has_energy
+; store this Pokemon's Play Area location
+ ldh a, [hTempPlayAreaLocation_ff9d]
+ ldh [hPlayAreaEffectTarget], a
+; store which energy card to discard from it
+ bank1call CreateArenaOrBenchEnergyCardList
+ ldh a, [hTempPlayAreaLocation_ff9d]
+ bank1call DisplayEnergyDiscardScreen
+ ld a, 2
+ ld [wEnergyDiscardMenuDenominator], a
+
+.loop_discard_energy_selection
+ bank1call HandleEnergyDiscardMenuInput
+ jr nc, .energy_selected
+ ; B pressed
+ ld a, 5
+ call AskWhetherToQuitSelectingCards
+ jr nc, .done ; finish operation
+ ; player selected to continue selection
+ ld a, [wEnergyDiscardMenuNumerator]
+ push af
+ ldh a, [hTempPlayAreaLocation_ff9d]
+ bank1call DisplayEnergyDiscardScreen
+ ld a, 2
+ ld [wEnergyDiscardMenuDenominator], a
+ pop af
+ ld [wEnergyDiscardMenuNumerator], a
+ jr .loop_discard_energy_selection
+
+.energy_selected
+; store energy cards to discard from opponent
+ call GetNextPositionInTempList_TrainerEffects
+ ldh a, [hTempCardIndex_ff98]
+ ld [hl], a
+ call RemoveCardFromDuelTempList
+ ld hl, wEnergyDiscardMenuNumerator
+ inc [hl]
+ ldh a, [hCurSelectionItem]
+ cp 5
+ jr nc, .done ; no more energy cards to select
+ ld a, [wDuelTempList]
+ cp $ff
+ jr z, .done ; no more energy cards to select
+ bank1call DisplayEnergyDiscardMenu
+ jr .loop_discard_energy_selection
+
+.done
+ call GetNextPositionInTempList_TrainerEffects
+ ld [hl], $ff
+ call SwapTurn
+ or a
+ ret
+
+SuperEnergyRemoval_DiscardEffect: ; 2fd73 (b:7d73)
+ ld hl, hTempList + 1
+
+; discard energy card of own Play Area
+ ld a, [hli]
+ call PutCardInDiscardPile
+
+; iterate and discard opponent's energy cards
+ inc hl
+ call SwapTurn
+.loop
+ ld a, [hli]
+ cp $ff
+ jr z, .done_discard
+ call PutCardInDiscardPile
+ jr .loop
+
+.done_discard
+; if it's Player's turn, return...
+ call SwapTurn
+ call IsPlayerTurn
+ ret c
+; ...otherwise show Play Area of affected Pokemon
+; in opponent's Play Area
+ ldh a, [hTemp_ffa0]
+ call Func_2c10b
+; in player's Play Area
+ xor a
+ ld [wDuelDisplayedScreen], a
+ call SwapTurn
+ ldh a, [hPlayAreaEffectTarget]
+ call Func_2c10b
+ call SwapTurn
+ ret
+
+; return carry if not enough cards in hand to
+; discard for Super Energy Retrieval effect
+; or if the Discard Pile has no basic Energy cards
+SuperEnergyRetrieval_HandEnergyCheck: ; 2fda4 (b:7da4)
+ ld a, DUELVARS_NUMBER_OF_CARDS_IN_HAND
+ call GetTurnDuelistVariable
+ ldtx hl, NotEnoughCardsInHandText
+ cp 3
+ ret c
+ call CreateEnergyCardListFromDiscardPile_OnlyBasic
+ ldtx hl, ThereAreNoBasicEnergyCardsInDiscardPileText
+ ret
+
+SuperEnergyRetrieval_PlayerHandSelection: ; 2fdb6 (b:7db6)
+ call HandlePlayerSelection2HandCardsToDiscard
+ ret
+
+SuperEnergyRetrieval_PlayerDiscardPileSelection: ; 2fdba (b:7dba)
+ ldtx hl, ChooseUpTo4FromDiscardPileText
+ call DrawWideTextBox_WaitForInput
+ call CreateEnergyCardListFromDiscardPile_OnlyBasic
+
+.loop_discard_pile_selection
+ bank1call InitAndDrawCardListScreenLayout
+ ldtx hl, PleaseSelectCardText
+ ldtx de, PlayerDiscardPileText
+ bank1call SetCardListHeaderText
+ bank1call DisplayCardList
+ jr nc, .store_selected_card
+ ; B pressed
+ ld a, 6
+ call AskWhetherToQuitSelectingCards
+ jr c, .loop_discard_pile_selection ; player selected to continue
+ jr .done
+
+.store_selected_card
+ ldh a, [hTempCardIndex_ff98]
+ call GetTurnDuelistVariable
+ call GetNextPositionInTempList_TrainerEffects
+ ldh a, [hTempCardIndex_ff98]
+ ld [hl], a ; store selected energy card
+ call RemoveCardFromDuelTempList
+ jr c, .done
+ ; this shouldn't happen
+ ldh a, [hCurSelectionItem]
+ cp 6
+ jr c, .loop_discard_pile_selection
+
+.done
+; insert terminating byte
+ call GetNextPositionInTempList_TrainerEffects
+ ld [hl], $ff
+ or a
+ ret
+
+SuperEnergyRetrieval_DiscardAndAddToHandEffect: ; 2fdfa (b:7dfa)
+; discard 2 cards selected from the hand
+ ld hl, hTemp_ffa0
+ ld a, [hli]
+ call RemoveCardFromHand
+ call PutCardInDiscardPile
+ ld a, [hli]
+ call RemoveCardFromHand
+ call PutCardInDiscardPile
+
+; put selected cards in hand
+ ld de, wDuelTempList
+.loop
+ ld a, [hli]
+ ld [de], a
+ inc de
+ cp $ff
+ jr z, .done
+ call MoveDiscardPileCardToHand
+ call AddCardToHand
+ jr .loop
+
+.done
+; if Player played the card, exit
+ call IsPlayerTurn
+ ret c
+; if not, show card list selected by Opponent
+ bank1call Func_4b38
+ ret
+
+; outputs in hl the next position
+; in hTempList to place a new card,
+; and increments hCurSelectionItem.
+; identical to GetNextPositionInTempList.
+GetNextPositionInTempList_TrainerEffects: ; 2fe25 (b:7e25)
+ push de
+ ld hl, hCurSelectionItem
+ ld a, [hl]
+ inc [hl]
+ ld e, a
+ ld d, $00
+ ld hl, hTempList
+ add hl, de
+ pop de
+ ret
+
+; handles screen for Player to select 2 cards from the hand to discard.
+; first prints text informing Player to choose cards to discard
+; then runs HandlePlayerSelection2HandCards routine.
+HandlePlayerSelection2HandCardsToDiscard: ; 2fe34 (b:7e34)
+ ldtx hl, Choose2CardsFromHandToDiscardText
+ ldtx de, ChooseTheCardToDiscardText
+; fallthrough
+
+; handles screen for Player to select 2 cards from the hand
+; to activate some Trainer card effect.
+; assumes Trainer card index being used is in [hTempCardIndex_ff9f].
+; stores selection of cards in hTempList.
+; returns carry if Player cancels operation.
+; input:
+; hl = text to print in text box;
+; de = text to print in screen header.
+HandlePlayerSelection2HandCards: ; 2fe3a (b:7e3a)
+ push de
+ call DrawWideTextBox_WaitForInput
+
+; remove the Trainer card being used from list
+; of cards to select from hand.
+ call CreateHandCardList
+ ldh a, [hTempCardIndex_ff9f]
+ call RemoveCardFromDuelTempList
+
+ xor a
+ ldh [hCurSelectionItem], a
+ pop hl
+.loop
+ push hl
+ bank1call Func_5591
+ pop hl
+ bank1call SetCardListInfoBoxText
+ push hl
+ bank1call DisplayCardList
+ pop hl
+ jr c, .set_carry ; was B pressed?
+ push hl
+ call GetNextPositionInTempList_TrainerEffects
+ ldh a, [hTempCardIndex_ff98]
+ ld [hl], a
+ call RemoveCardFromDuelTempList
+ pop hl
+ ldh a, [hCurSelectionItem]
+ cp 2
+ jr c, .loop ; is selection over?
+ or a
+ ret
+.set_carry
+ scf
+ ret
+
+; return carry if non-turn duelist has no benched Pokemon
+GustOfWind_BenchCheck: ; 2fe6e (b:7e6e)
+ ld a, DUELVARS_NUMBER_OF_POKEMON_IN_PLAY_AREA
+ call GetNonTurnDuelistVariable
+ ldtx hl, EffectNoPokemonOnTheBenchText
+ cp 2
+ ret
+
+GustOfWind_PlayerSelection: ; 2fe79 (b:7e79)
+ ldtx hl, ChooseAPokemonToSwitchWithActivePokemonText
+ call DrawWideTextBox_WaitForInput
+ call SwapTurn
+ bank1call HasAlivePokemonInBench
+ bank1call OpenPlayAreaScreenForSelection
+ ldh a, [hTempPlayAreaLocation_ff9d]
+ ldh [hTemp_ffa0], a
+ call SwapTurn
+ ret
+
+GustOfWind_SwitchEffect: ; 2fe90 (b:7e90)
+; play whirlwind animation
+ ld a, ATK_ANIM_GUST_OF_WIND
+ call Func_2fea9
+
+; switch Arena card
+ call SwapTurn
+ ldh a, [hTemp_ffa0]
+ ld e, a
+ call SwapArenaWithBenchPokemon
+ call SwapTurn
+ call ClearDamageReductionSubstatus2
+ xor a
+ ld [wDuelDisplayedScreen], a
+ ret
+
+; input:
+; a = attack animation to play
+Func_2fea9: ; 2fea9 (b:7ea9)
+ ld [wLoadedAttackAnimation], a
+ bank1call Func_7415
+ ld bc, $0
+ ldh a, [hWhoseTurn]
+ ld h, a
+ bank1call PlayAttackAnimation
+ bank1call WaitAttackAnimation
+ ret
+
+; heals amount of damage in register e for card in
+; Play Area location in [hTempPlayAreaLocation_ff9d].
+; plays healing animation and prints text with card's name.
+; input:
+; e = amount of HP to heal
+; [hTempPlayAreaLocation_ff9d] = Play Area location of card to heal
+HealPlayAreaCardHP: ; 2febc (b:7ebc)
+ ld e, a
+ ld d, $00
+
+; play heal animation
+ push de
+ bank1call Func_7415
+ ld a, ATK_ANIM_HEALING_WIND_PLAY_AREA
+ ld [wLoadedAttackAnimation], a
+ ldh a, [hTempPlayAreaLocation_ff9d]
+ ld b, a
+ ld c, $01
+ ldh a, [hWhoseTurn]
+ ld h, a
+ bank1call PlayAttackAnimation
+ bank1call WaitAttackAnimation
+ pop hl
+
+; print Pokemon card name and damage healed
+ push hl
+ call LoadTxRam3
+ ld hl, $0000
+ call LoadTxRam2
+ ldh a, [hTempPlayAreaLocation_ff9d]
+ add DUELVARS_ARENA_CARD
+ call GetTurnDuelistVariable
+ call LoadCardDataToBuffer1_FromDeckIndex
+ ld a, 18
+ call CopyCardNameAndLevel
+ ld [hl], $00 ; terminating character on end of the name
+ ldtx hl, PokemonHealedDamageText
+ call DrawWideTextBox_WaitForInput
+ pop de
+
+; heal the target Pokemon
+ ldh a, [hTempPlayAreaLocation_ff9d]
+ add DUELVARS_ARENA_CARD_HP
+ call GetTurnDuelistVariable
+ add e
+ ld [hl], a
+ ret