mirror of
https://github.com/pret/poketcg.git
synced 2026-09-29 22:09:26 -04:00
11822 lines
243 KiB
NASM
11822 lines
243 KiB
NASM
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 [wLoadedMoveAnimation], a
|
|
ldh a, [hTempPlayAreaLocation_ff9d]
|
|
ld b, a
|
|
ld c, $0 ; neither WEAKNESS nor RESISTANCE
|
|
ldh a, [hWhoseTurn]
|
|
ld h, a
|
|
bank1call PlayMoveAnimation
|
|
bank1call WaitMoveAnimation
|
|
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
|
|
; 0x2c174
|
|
|
|
; overwrites wAIMinDamage and wAIMaxDamage
|
|
; with value in wDamage.
|
|
SetDefiniteAIDamage: ; 2c174 (b:4174)
|
|
ld a, [wDamage]
|
|
ld [wAIMinDamage], a
|
|
ld [wAIMaxDamage], a
|
|
ret
|
|
; 0x2c17e
|
|
|
|
; 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
|
|
; 0x2c188
|
|
|
|
; 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
|
|
; 0x2c197
|
|
|
|
; 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
|
|
; 0x2c1c4
|
|
|
|
; 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
|
|
; 0x2c1ec
|
|
|
|
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
|
|
; 0x2c221
|
|
|
|
; 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 [wLoadedMoveAnimation], a
|
|
ld bc, $01 ; arrow
|
|
bank1call PlayMoveAnimation
|
|
|
|
; 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 WaitMoveAnimation
|
|
ret
|
|
; 0x2c25b
|
|
|
|
; 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
|
|
; 0x2c26e
|
|
|
|
; 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
|
|
; 0x2c2a0
|
|
|
|
; 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
|
|
; 0x2c2e0
|
|
|
|
; 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
|
|
; 0x2c2ec
|
|
|
|
; 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
|
|
; 0x2c317
|
|
|
|
.search_table
|
|
dw .SearchDeckForCardID
|
|
dw .SearchDeckForNidoran
|
|
dw .SearchDeckForBasicFighting
|
|
dw .SearchDeckForBasicEnergy
|
|
dw .SearchDeckForPokemon
|
|
|
|
.set_carry ; 2c321 (b:4321)
|
|
scf
|
|
ret
|
|
; 0x2c323
|
|
|
|
; 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
|
|
; 0x2c336
|
|
|
|
; 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
|
|
; 0x2c34c
|
|
|
|
; 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
|
|
; 0x2c365
|
|
|
|
; 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
|
|
; 0x2c37d
|
|
|
|
; 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
|
|
; 0x2c391
|
|
|
|
; 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 PrintAndLoadMovesToDuelTempList
|
|
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_move_page
|
|
call HandleMenuInput
|
|
jr nc, .loop_input
|
|
cp -1
|
|
jr z, .loop_input
|
|
|
|
; a move 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_move_page
|
|
ldh a, [hCurMenuItem]
|
|
ldh [hCurSelectionItem], a
|
|
ld a, DUELVARS_ARENA_CARD
|
|
call GetTurnDuelistVariable
|
|
call LoadCardDataToBuffer1_FromDeckIndex
|
|
bank1call OpenMovePage
|
|
call SwapTurn
|
|
bank1call DrawDuelMainScene
|
|
call SwapTurn
|
|
jr .start
|
|
; 0x2c3f4
|
|
|
|
.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 $0000 ; function pointer if non-0
|
|
; 0x2c3fc
|
|
|
|
; 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, wLoadedCard1Move1Name
|
|
inc e
|
|
dec e
|
|
jr z, .load_name
|
|
ld hl, wLoadedCard1Move2Name
|
|
.load_name
|
|
ld a, [hli]
|
|
ld h, [hl]
|
|
ld l, a
|
|
ret
|
|
; 0x2c40e
|
|
|
|
; 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, [wLoadedCard2Move1Category]
|
|
cp POKEMON_POWER
|
|
jr nz, .has_attack
|
|
ld hl, wLoadedCard2Move2Name
|
|
ld a, [hli]
|
|
or [hl]
|
|
jr nz, .has_attack
|
|
call SwapTurn
|
|
scf
|
|
ret
|
|
.has_attack
|
|
call SwapTurn
|
|
or a
|
|
ret
|
|
; 0x2c431
|
|
|
|
; 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
|
|
; 0x2c45d
|
|
|
|
; 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
|
|
; 0x2c476
|
|
|
|
; 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
|
|
; 0x2c487
|
|
|
|
; 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, [wPlayerAttackingMoveIndex]
|
|
ld e, a
|
|
ld a, [wPlayerAttackingCardIndex]
|
|
ld d, a
|
|
ld a, [wPlayerAttackingCardID]
|
|
call CopyMoveDataAndDamage_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
|
|
; 0x2c4da
|
|
|
|
; 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
|
|
; 0x2c532
|
|
|
|
; 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, wLoadedCard2Move1Name
|
|
ld a, [hli]
|
|
or [hl]
|
|
jr z, .chosen
|
|
|
|
; if Defending Pokemon has enough energy for second attack, choose it
|
|
ld e, SECOND_ATTACK
|
|
bank1call _CheckIfEnoughEnergiesToMove
|
|
jr nc, .chosen
|
|
; otherwise if first attack isn't a Pkmn Power, choose it instead.
|
|
ld e, FIRST_ATTACK_OR_PKMN_POWER
|
|
ld a, [wLoadedCard2Move1Category]
|
|
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
|
|
; 0x2c564
|
|
|
|
; 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
|
|
; 0x2c588
|
|
|
|
; 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 $0000 ; function pointer if non-0
|
|
; 0x2c5be
|
|
|
|
.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 ; unnecessary
|
|
push hl ; unnecessary
|
|
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
|
|
; 0x2c686
|
|
|
|
; 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
|
|
; 0x2c6a1
|
|
|
|
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
|
|
; 0x2c6d9
|
|
|
|
; possibly unreferenced
|
|
Func_2c6d9: ; 2c6d9 (b:46d9)
|
|
ldtx hl, IncompleteText
|
|
call DrawWideTextBox_WaitForInput
|
|
ret
|
|
; 0x2c6e0
|
|
|
|
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 $0000 ; function pointer if non-0
|
|
; 0x2c6e8
|
|
|
|
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 $0000 ; function pointer if non-0
|
|
; 0x2c6f0
|
|
|
|
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 [wLoadedMoveAnimation], 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
|
|
; 0x2c740
|
|
|
|
; 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
|
|
; 0x2c74b
|
|
|
|
; 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
|
|
; 0x2c764
|
|
|
|
; 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
|
|
; 0x2c76a
|
|
|
|
; 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 [wLoadedMoveAnimation], 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
|
|
; 0x2c7bc
|
|
|
|
GolbatLeechLifeEffect: ; 2c7bc (b:47bc)
|
|
ld hl, wDealtDamage
|
|
ld e, [hl]
|
|
inc hl ; wDamageEffectiveness
|
|
ld d, [hl]
|
|
call ApplyAndAnimateHPRecovery
|
|
ret
|
|
; 0x2c7c6
|
|
|
|
VenonatLeechLifeEffect: ; 2c7c6 (b:47c6)
|
|
ld hl, wDealtDamage
|
|
ld e, [hl]
|
|
inc hl ; wDamageEffectiveness
|
|
ld d, [hl]
|
|
call ApplyAndAnimateHPRecovery
|
|
ret
|
|
; 0x2c7d0
|
|
|
|
; 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
|
|
; 0x2c7e3
|
|
|
|
ZubatLeechLifeEffect: ; 2c7e3 (b:47e3)
|
|
ld hl, wDealtDamage
|
|
ld e, [hl]
|
|
inc hl
|
|
ld d, [hl]
|
|
call ApplyAndAnimateHPRecovery
|
|
ret
|
|
; 0x2c7ed
|
|
|
|
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
|
|
; 0x2c80d
|
|
|
|
BeedrillPoisonSting_AIEffect: ; 2c80d (b:480d)
|
|
ld a, 5
|
|
lb de, 0, 10
|
|
jp UpdateExpectedAIDamage_AccountForPoison
|
|
; 0x2c815
|
|
|
|
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
|
|
; 0x2c822
|
|
|
|
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 [wLoadedMoveAnimation], a
|
|
ld a, SUBSTATUS1_NO_DAMAGE_STIFFEN
|
|
call ApplySubstatus1ToDefendingCard
|
|
ret
|
|
; 0x2c84a
|
|
|
|
; 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
|
|
; 0x2c85a
|
|
|
|
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
|
|
; 0x2c8b7
|
|
|
|
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
|
|
; 0x2c8cc
|
|
|
|
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
|
|
; 0x2c8ec
|
|
|
|
; 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
|
|
; 0x2c8f7
|
|
|
|
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
|
|
; 0x2c90f
|
|
|
|
Teleport_AISelectEffect: ; 2c90f (b:490f)
|
|
ld a, DUELVARS_NUMBER_OF_POKEMON_IN_PLAY_AREA
|
|
call GetTurnDuelistVariable
|
|
call Random
|
|
ldh [hTemp_ffa0], a
|
|
ret
|
|
; 0x2c91a
|
|
|
|
Teleport_SwitchEffect: ; 2c91a (b:491a)
|
|
ldh a, [hTemp_ffa0]
|
|
ld e, a
|
|
call SwapArenaWithBenchPokemon
|
|
xor a
|
|
ld [wDuelDisplayedScreen], a
|
|
ret
|
|
; 0x2c925
|
|
|
|
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
|
|
; 0x2c998
|
|
|
|
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
|
|
; 0x2c9be
|
|
|
|
NidoranFFurySwipes_AIEffect: ; 2c9be (b:49be)
|
|
ld a, 30 / 2
|
|
lb de, 0, 30
|
|
jp SetExpectedAIDamage
|
|
; 0x2c9c6
|
|
|
|
NidoranFFurySwipes_MultiplierEffect: ; 2c9c6 (b:49c6)
|
|
ld hl, 10
|
|
call LoadTxRam3
|
|
ldtx de, DamageCheckIfHeadsXDamageText
|
|
ld a, 3
|
|
call TossCoinATimes_BankB
|
|
call ATimes10
|
|
call SetDefiniteDamage
|
|
ret
|
|
; 0x2c9db
|
|
|
|
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
|
|
; 0x2c9eb
|
|
|
|
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
|
|
; 0x2ca55
|
|
|
|
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
|
|
; 0x2ca6e
|
|
|
|
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
|
|
; 0x2ca8e
|
|
|
|
HornHazard_AIEffect: ; 2ca8e (b:4a8e)
|
|
ld a, 30 / 2
|
|
lb de, 0, 30
|
|
jp SetExpectedAIDamage
|
|
; 0x2ca96
|
|
|
|
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 [wLoadedMoveAnimation], a
|
|
ret
|
|
; 0x2caac
|
|
|
|
NidorinaSupersonicEffect: ; 2caac (b:4aac)
|
|
call Confusion50PercentEffect
|
|
call nc, SetNoEffectFromStatus
|
|
ret
|
|
; 0x2cab3
|
|
|
|
NidorinaDoubleKick_AIEffect: ; 2cab3 (b:4ab3)
|
|
ld a, 60 / 2
|
|
lb de, 0, 60
|
|
jp SetExpectedAIDamage
|
|
; 0x2cabb
|
|
|
|
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
|
|
; 0x2cad3
|
|
|
|
NidorinoDoubleKick_AIEffect: ; 2cad3 (b:4ad3)
|
|
ld a, 60 / 2
|
|
lb de, 0, 60
|
|
jp SetExpectedAIDamage
|
|
; 0x2cadb
|
|
|
|
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
|
|
; 0x2caf3
|
|
|
|
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
|
|
; 0x2cb09
|
|
|
|
ButterfreeWhirlwind_SwitchEffect: ; 2cb09 (b:4b09)
|
|
ldh a, [hTemp_ffa0]
|
|
call HandleSwitchDefendingPokemonEffect
|
|
ret
|
|
; 0x2cb0f
|
|
|
|
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
|
|
; 0x2cb27
|
|
|
|
WeedlePoisonSting_AIEffect: ; 2cb27 (b:4b27)
|
|
ld a, 5
|
|
lb de, 0, 10
|
|
jp UpdateExpectedAIDamage_AccountForPoison
|
|
; 0x2cb2f
|
|
|
|
IvysaurPoisonPowder_AIEffect: ; 2cb2f (b:4b2f)
|
|
ld a, 10
|
|
lb de, 10, 10
|
|
jp UpdateExpectedAIDamage_AccountForPoison
|
|
; 0x2cb37
|
|
|
|
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
|
|
; 0x2cb44
|
|
|
|
; 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
|
|
; 0x2cb6f
|
|
|
|
EnergyTrans_PrintProcedure: ; 2cb6f (b:4b6f)
|
|
ldtx hl, ProcedureForEnergyTransferText
|
|
bank1call DrawWholeScreenTextBox
|
|
or a
|
|
ret
|
|
; 0x2cb77
|
|
|
|
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
|
|
; 0x2cbfb
|
|
|
|
EnergyTrans_AIEffect: ; 2cbfb (b:4bfb)
|
|
ldh a, [hAIEnergyTransPlayAreaLocation]
|
|
ld e, a
|
|
ldh a, [hAIEnergyTransEnergyCard]
|
|
call AddCardToHand
|
|
call PutHandCardInPlayArea
|
|
bank1call PrintPlayAreaCardList_EnableLCD
|
|
ret
|
|
; 0x2cc0a
|
|
|
|
; 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
|
|
; 0x2cc30
|
|
|
|
GrimerMinimizeEffect: ; 2cc30 (b:4c30)
|
|
ld a, SUBSTATUS1_REDUCE_BY_20
|
|
call ApplySubstatus1ToDefendingCard
|
|
ret
|
|
; 0x2cc36
|
|
|
|
ToxicGasEffect: ; 2cc36 (b:4c36)
|
|
scf
|
|
ret
|
|
; 0x2cc38
|
|
|
|
Sludge_AIEffect: ; 2cc38 (b:4c38)
|
|
ld a, 5
|
|
lb de, 0, 10
|
|
jp UpdateExpectedAIDamage_AccountForPoison
|
|
; 0x2cc40
|
|
|
|
; 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
|
|
; 0x2cc50
|
|
|
|
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
|
|
; 0x2ccad
|
|
|
|
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
|
|
; 0x2ccc2
|
|
|
|
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
|
|
; 0x2cce2
|
|
|
|
WeezingSmog_AIEffect: ; 2cce2 (b:4ce2)
|
|
ld a, 5
|
|
lb de, 0, 10
|
|
jp UpdateExpectedAIDamage_AccountForPoison
|
|
; 0x2ccea
|
|
|
|
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
|
|
; 0x2cd09
|
|
|
|
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
|
|
; 0x2cd21
|
|
|
|
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
|
|
; 0x2cd44
|
|
|
|
; 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
|
|
; 0x2cd5d
|
|
|
|
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
|
|
; 0x2cd84
|
|
|
|
VenomPowder_AIEffect: ; 2cd84 (b:4d84)
|
|
ld a, 5
|
|
lb de, 0, 10
|
|
jp UpdateExpectedAIDamage
|
|
; 0x2cd8c
|
|
|
|
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
|
|
; 0x2cda0
|
|
|
|
TangelaPoisonPowder_AIEffect: ; 2cda0 (b:4da0)
|
|
ld a, 5
|
|
lb de, 0, 10
|
|
jp UpdateExpectedAIDamage_AccountForPoison
|
|
; 0x2cda8
|
|
|
|
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
|
|
; 0x2cdc7
|
|
|
|
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
|
|
; 0x2ce23
|
|
|
|
PetalDance_AIEffect: ; 2ce23 (b:4e23)
|
|
ld a, 120 / 2
|
|
lb de, 0, 120
|
|
jp SetExpectedAIDamage
|
|
; 0x2ce2b
|
|
|
|
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
|
|
; 0x2ce4b
|
|
|
|
PoisonWhip_AIEffect: ; 2ce4b (b:4e4b)
|
|
ld a, 10
|
|
lb de, 10, 10
|
|
jp UpdateExpectedAIDamage_AccountForPoison
|
|
; 0x2ce53
|
|
|
|
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
|
|
; 0x2ce82
|
|
|
|
SolarPower_RemoveStatusEffect: ; 2ce82 (b:4e82)
|
|
ld a, ATK_ANIM_HEAL_BOTH_SIDES
|
|
ld [wLoadedMoveAnimation], a
|
|
bank1call Func_7415
|
|
ldh a, [hTempPlayAreaLocation_ff9d]
|
|
ld b, a
|
|
ld c, $00
|
|
ldh a, [hWhoseTurn]
|
|
ld h, a
|
|
bank1call PlayMoveAnimation
|
|
bank1call WaitMoveAnimation
|
|
|
|
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
|
|
; 0x2ceb0
|
|
|
|
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
|
|
; 0x2cec8
|
|
|
|
; 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
|
|
; 0x2cf05
|
|
|
|
OmastarWaterGunEffect: ; 2cf05 (b:4f05)
|
|
lb bc, 1, 1
|
|
jr ApplyExtraWaterEnergyDamageBonus
|
|
; 0x2cf0a
|
|
|
|
OmastarSpikeCannon_AIEffect: ; 2cf0a (b:4f0a)
|
|
ld a, 60 / 2
|
|
lb de, 0, 60
|
|
jp SetExpectedAIDamage
|
|
; 0x2cf12
|
|
|
|
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
|
|
; 0x2cf2a
|
|
|
|
ClairvoyanceEffect: ; 2cf2a (b:4f2a)
|
|
scf
|
|
ret
|
|
; 0x2cf2c
|
|
|
|
OmanyteWaterGunEffect: ; 2cf2c (b:4f2c)
|
|
lb bc, 1, 0
|
|
jp ApplyExtraWaterEnergyDamageBonus
|
|
; 0x2cf32
|
|
|
|
WartortleWithdrawEffect: ; 2cf32 (b:4f32)
|
|
ldtx de, IfHeadsNoDamageNextTurnText
|
|
call TossCoin_BankB
|
|
jp nc, SetWasUnsuccessful
|
|
ld a, ATK_ANIM_PROTECT
|
|
ld [wLoadedMoveAnimation], a
|
|
ld a, SUBSTATUS1_NO_DAMAGE_10
|
|
call ApplySubstatus1ToDefendingCard
|
|
ret
|
|
; 0x2cf46
|
|
|
|
RainDanceEffect: ; 2cf46 (b:4f46)
|
|
scf
|
|
ret
|
|
; 0x2cf48
|
|
|
|
HydroPumpEffect: ; 2cf48 (b:4f48)
|
|
lb bc, 3, 0
|
|
jp ApplyExtraWaterEnergyDamageBonus
|
|
; 0x2cf4e
|
|
|
|
KinglerFlail_AIEffect: ; 2cf4e (b:4f4e)
|
|
call KinglerFlail_HPCheck
|
|
jp SetDefiniteAIDamage
|
|
; 0x2cf54
|
|
|
|
KinglerFlail_HPCheck: ; 2cf54 (b:4f54)
|
|
ld e, PLAY_AREA_ARENA
|
|
call GetCardDamageAndMaxHP
|
|
call SetDefiniteDamage
|
|
ret
|
|
; 0x2cf5d
|
|
|
|
; 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
|
|
; 0x2cf6d
|
|
|
|
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
|
|
; 0x2cfdf
|
|
|
|
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
|
|
; 0x2cfca
|
|
|
|
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
|
|
; 0x2cfff
|
|
|
|
MagikarpFlail_AIEffect: ; 2cfff (b:4fff)
|
|
call MagikarpFlail_HPCheck
|
|
jp SetDefiniteAIDamage
|
|
; 0x2d005
|
|
|
|
MagikarpFlail_HPCheck: ; 2d005 (b:5005)
|
|
ld e, PLAY_AREA_ARENA
|
|
call GetCardDamageAndMaxHP
|
|
call SetDefiniteDamage
|
|
ret
|
|
; 0x2d00e
|
|
|
|
HeadacheEffect: ; 2d00e (b:500e)
|
|
ld a, DUELVARS_ARENA_CARD_SUBSTATUS3
|
|
call GetNonTurnDuelistVariable
|
|
set SUBSTATUS3_HEADACHE, [hl]
|
|
ret
|
|
; 0x2d016
|
|
|
|
PsyduckFurySwipes_AIEffect: ; 2d016 (b:5016)
|
|
ld a, 30 / 2
|
|
lb de, 0, 30
|
|
jp SetExpectedAIDamage
|
|
; 0x2d01e
|
|
|
|
PsyduckFurySwipes_MultiplierEffect: ; 2d01e (b:501e)
|
|
ld hl, 10
|
|
call LoadTxRam3
|
|
ldtx de, DamageCheckIfHeadsXDamageText
|
|
ld a, 3
|
|
call TossCoinATimes_BankB
|
|
call ATimes10
|
|
call SetDefiniteDamage
|
|
ret
|
|
; 0x2d033
|
|
|
|
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
|
|
; 0x2d065
|
|
|
|
GolduckHyperBeam_AISelectEffect: ; 2d065 (b:5065)
|
|
call AIPickEnergyCardToDiscardFromDefendingPokemon
|
|
ldh [hTemp_ffa0], a
|
|
ret
|
|
; 0x2d06b
|
|
|
|
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
|
|
; 0x2d085
|
|
|
|
SeadraWaterGunEffect: ; 2d085 (b:5085)
|
|
lb bc, 1, 1
|
|
jp ApplyExtraWaterEnergyDamageBonus
|
|
; 0x2d08b
|
|
|
|
SeadraAgilityEffect: ; 2d08b (b:508b)
|
|
ldtx de, IfHeadsDoNotReceiveDamageOrEffectText
|
|
call TossCoin_BankB
|
|
ret nc ; return if tails
|
|
ld a, ATK_ANIM_AGILITY_PROTECT
|
|
ld [wLoadedMoveAnimation], a
|
|
ld a, SUBSTATUS1_AGILITY
|
|
call ApplySubstatus1ToDefendingCard
|
|
ret
|
|
; 0x2d09d
|
|
|
|
ShellderSupersonicEffect: ; 2d09d (b:509d)
|
|
call Confusion50PercentEffect
|
|
call nc, SetNoEffectFromStatus
|
|
ret
|
|
; 0x2d0a4
|
|
|
|
HideInShellEffect: ; 2d0a4 (b:50a4)
|
|
ldtx de, IfHeadsNoDamageNextTurnText
|
|
call TossCoin_BankB
|
|
jp nc, SetWasUnsuccessful
|
|
ld a, ATK_ANIM_PROTECT
|
|
ld [wLoadedMoveAnimation], a
|
|
ld a, SUBSTATUS1_NO_DAMAGE_11
|
|
call ApplySubstatus1ToDefendingCard
|
|
ret
|
|
; 0x2d0b8
|
|
|
|
VaporeonQuickAttack_AIEffect: ; 2d0b8 (b:50b8)
|
|
ld a, (10 + 30) / 2
|
|
lb de, 10, 30
|
|
jp SetExpectedAIDamage
|
|
; 0x2d0c0
|
|
|
|
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
|
|
; 0x2d0d3
|
|
|
|
VaporeonWaterGunEffect: ; 2d0d3 (b:50d3)
|
|
lb bc, 2, 1
|
|
jp ApplyExtraWaterEnergyDamageBonus
|
|
; 0x2d0d9
|
|
|
|
; 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
|
|
; 0x2d0f0
|
|
|
|
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
|
|
; 0x2d103
|
|
|
|
StarmieRecover_AISelectEffect: ; 2d103 (b:5103)
|
|
ld a, TYPE_ENERGY_WATER
|
|
call CreateListOfEnergyAttachedToArena
|
|
ld a, [wDuelTempList] ; pick first card
|
|
ldh [hTemp_ffa0], a
|
|
ret
|
|
; 0x2d10e
|
|
|
|
StarmieRecover_DiscardEffect: ; 2d10e (b:510e)
|
|
ldh a, [hTemp_ffa0]
|
|
call PutCardInDiscardPile
|
|
ret
|
|
; 0x2d114
|
|
|
|
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
|
|
; 0x2d120
|
|
|
|
SquirtleWithdrawEffect: ; 2d120 (b:5120)
|
|
ldtx de, IfHeadsNoDamageNextTurnText
|
|
call TossCoin_BankB
|
|
jp nc, SetWasUnsuccessful
|
|
ld a, ATK_ANIM_PROTECT
|
|
ld [wLoadedMoveAnimation], a
|
|
ld a, SUBSTATUS1_NO_DAMAGE_10
|
|
call ApplySubstatus1ToDefendingCard
|
|
ret
|
|
; 0x2d134
|
|
|
|
HorseaSmokescreenEffect: ; 2d134 (b:5134)
|
|
ld a, SUBSTATUS2_SMOKESCREEN
|
|
call ApplySubstatus2ToDefendingCard
|
|
ret
|
|
; 0x2d13a
|
|
|
|
TentacruelSupersonicEffect: ; 2d13a (b:513a)
|
|
call Confusion50PercentEffect
|
|
call nc, SetNoEffectFromStatus
|
|
ret
|
|
; 0x2d141
|
|
|
|
JellyfishSting_AIEffect: ; 2d141 (b:5141)
|
|
ld a, 10
|
|
lb de, 10, 10
|
|
jp UpdateExpectedAIDamage_AccountForPoison
|
|
; 0x2d149
|
|
|
|
; 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, [wLoadedCard2Move1Category]
|
|
cp POKEMON_POWER
|
|
jr nz, .has_attack
|
|
ld hl, wLoadedCard2Move2Name
|
|
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
|
|
; 0x2d16f
|
|
|
|
PoliwhirlAmnesia_PlayerSelectEffect: ; 2d16f (b:516f)
|
|
call PlayerPickAttackForAmnesia
|
|
ret
|
|
; 0x2d173
|
|
|
|
PoliwhirlAmnesia_AISelectEffect: ; 2d173 (b:5173)
|
|
call AIPickAttackForAmnesia
|
|
ldh [hTemp_ffa0], a
|
|
ret
|
|
; 0x2d179
|
|
|
|
PoliwhirlAmnesia_DisableEffect: ; 2d179 (b:5179)
|
|
call ApplyAmnesiaToAttack
|
|
ret
|
|
; 0x2d17d
|
|
|
|
PlayerPickAttackForAmnesia: ; 2d17d (b:517d)
|
|
ldtx hl, ChooseAttackOpponentWillNotBeAbleToUseText
|
|
call DrawWideTextBox_WaitForInput
|
|
call HandleDefendingPokemonAttackSelection
|
|
ld a, e
|
|
ldh [hTemp_ffa0], a
|
|
ret
|
|
; 0x2d18a
|
|
|
|
; 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_MOVE_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 move 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
|
|
; 0x2d1c0
|
|
|
|
PoliwhirlDoubleslap_AIEffect: ; 2d1c0 (b:51c0)
|
|
ld a, 60 / 2
|
|
lb de, 0, 60
|
|
jp SetExpectedAIDamage
|
|
; 0x2d1c8
|
|
|
|
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
|
|
; 0x2d1e0
|
|
|
|
PoliwrathWaterGunEffect: ; 2d1e0 (b:51e0)
|
|
lb bc, 2, 1
|
|
jp ApplyExtraWaterEnergyDamageBonus
|
|
; 0x2d1e6
|
|
|
|
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
|
|
; 0x2d20e
|
|
|
|
Whirlpool_AISelectEffect: ; 2d20e (b:520e)
|
|
call AIPickEnergyCardToDiscardFromDefendingPokemon
|
|
ldh [hTemp_ffa0], a
|
|
ret
|
|
; 0x2d214
|
|
|
|
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
|
|
; 0x2d227
|
|
|
|
PoliwagWaterGunEffect: ; 2d227 (b:5227)
|
|
lb bc, 1, 0
|
|
jp ApplyExtraWaterEnergyDamageBonus
|
|
; 0x2d22d
|
|
|
|
ClampEffect: ; 2d22d (b:522d)
|
|
ld a, ATK_ANIM_HIT_EFFECT
|
|
ld [wLoadedMoveAnimation], a
|
|
ldtx de, SuccessCheckIfHeadsAttackIsSuccessfulText
|
|
call TossCoin_BankB
|
|
jp c, ParalysisEffect
|
|
; unsuccessful
|
|
xor a ; ATK_ANIM_NONE
|
|
ld [wLoadedMoveAnimation], a
|
|
call SetDefiniteDamage
|
|
call SetWasUnsuccessful
|
|
ret
|
|
; 0x2d246
|
|
|
|
CloysterSpikeCannon_AIEffect: ; 2d246 (b:5246)
|
|
ld a, 60 / 2
|
|
lb de, 0, 60
|
|
jp SetExpectedAIDamage
|
|
; 0x2d24e
|
|
|
|
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
|
|
; 0x2d266
|
|
|
|
Blizzard_BenchDamage50PercentEffect: ; 2d266 (b:5266)
|
|
ldtx de, DamageToOppBenchIfHeadsDamageToYoursIfTailsText
|
|
call TossCoin_BankB
|
|
ldh [hTemp_ffa0], a ; store coin result
|
|
ret
|
|
; 0x2d26f
|
|
|
|
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
|
|
; 0x2d28b
|
|
|
|
; 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
|
|
; 0x2d2ae
|
|
|
|
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
|
|
; 0x2d2c3
|
|
|
|
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
|
|
; 0x2d2eb
|
|
|
|
LaprasWaterGunEffect: ; 2d2eb (b:52eb)
|
|
lb bc, 1, 0
|
|
jp ApplyExtraWaterEnergyDamageBonus
|
|
; 0x2d2f1
|
|
|
|
Quickfreeze_InitialEffect: ; 2d2f1 (b:52f1)
|
|
scf
|
|
ret
|
|
; 0x2d2f3
|
|
|
|
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 PlayMoveAnimation
|
|
bank1call Func_741a
|
|
bank1call WaitMoveAnimation
|
|
bank1call Func_6df1
|
|
bank1call DrawDuelHUDs
|
|
bank1call Func_1bca
|
|
call c, WaitForWideTextBoxInput
|
|
ret
|
|
; 0x2d329
|
|
|
|
IceBreath_ZeroDamage: ; 2d329 (b:5329)
|
|
xor a
|
|
call SetDefiniteDamage
|
|
ret
|
|
; 0x2d32e
|
|
|
|
IceBreath_RandomPokemonDamageEffect: ; 2d32e (b:532e)
|
|
call SwapTurn
|
|
call PickRandomPlayAreaCard
|
|
ld b, a
|
|
ld de, 40
|
|
call DealDamageToPlayAreaPokemon_RegularAnim
|
|
call SwapTurn
|
|
ret
|
|
; 0x2d33f
|
|
|
|
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
|
|
; 0x2d34b
|
|
|
|
PlayerPickFireEnergyCardToDiscard: ; 2d34b (b:534b)
|
|
call CreateListOfFireEnergyAttachedToArena
|
|
xor a
|
|
bank1call DisplayEnergyDiscardScreen
|
|
bank1call HandleEnergyDiscardMenuInput
|
|
ldh a, [hTempCardIndex_ff98]
|
|
ldh [hTempList], a
|
|
ret
|
|
; 0x2d35a
|
|
|
|
AIPickFireEnergyCardToDiscard: ; 2d35a (b:535a)
|
|
call CreateListOfFireEnergyAttachedToArena
|
|
ld a, [wDuelTempList]
|
|
ldh [hTempList], a ; pick first in list
|
|
ret
|
|
; 0x2d363
|
|
|
|
; 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
|
|
; 0x2d371
|
|
|
|
ArcanineFlamethrower_PlayerSelectEffect: ; 2d371 (b:5371)
|
|
call PlayerPickFireEnergyCardToDiscard
|
|
ret
|
|
; 0x2d375
|
|
|
|
ArcanineFlamethrower_AISelectEffect: ; 2d375 (b:5375)
|
|
call AIPickFireEnergyCardToDiscard
|
|
ret
|
|
; 0x2d379
|
|
|
|
ArcanineFlamethrower_DiscardEffect: ; 2d379 (b:5379)
|
|
ldh a, [hTempList]
|
|
call PutCardInDiscardPile
|
|
ret
|
|
; 0x2d37f
|
|
|
|
TakeDownEffect: ; 2d37f (b:537f)
|
|
ld a, 30
|
|
call DealRecoilDamageToSelf
|
|
ret
|
|
; 0x2d385
|
|
|
|
ArcanineQuickAttack_AIEffect: ; 2d385 (b:5385)
|
|
ld a, (10 + 30) / 2
|
|
lb de, 10, 30
|
|
jp SetExpectedAIDamage
|
|
; 0x2d38d
|
|
|
|
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
|
|
; 0x2d3a0
|
|
|
|
; 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
|
|
; 0x2d3ae
|
|
|
|
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
|
|
; 0x2d3d5
|
|
|
|
FlamesOfRage_AISelectEffect: ; 2d3d5 (b:53d5)
|
|
call AIPickFireEnergyCardToDiscard
|
|
ld a, [wDuelTempList + 1]
|
|
ldh [hTempList + 1], a
|
|
ret
|
|
; 0x2d3de
|
|
|
|
FlamesOfRage_DiscardEffect: ; 2d3de (b:53de)
|
|
ldh a, [hTempList]
|
|
call PutCardInDiscardPile
|
|
ldh a, [hTempList + 1]
|
|
call PutCardInDiscardPile
|
|
ret
|
|
; 0x2d3e9
|
|
|
|
FlamesOfRage_AIEffect: ; 2d3e9 (b:53e9)
|
|
call FlamesOfRage_DamageBoostEffect
|
|
jp SetDefiniteAIDamage
|
|
; 0x2d3ef
|
|
|
|
FlamesOfRage_DamageBoostEffect: ; 2d3ef (b:53ef)
|
|
ld e, PLAY_AREA_ARENA
|
|
call GetCardDamageAndMaxHP
|
|
call AddToDamage
|
|
ret
|
|
; 0x2d3f8
|
|
|
|
RapidashStomp_AIEffect: ; 2d3f8 (b:53f8)
|
|
ld a, (20 + 30) / 2
|
|
lb de, 20, 30
|
|
jp SetExpectedAIDamage
|
|
; 0x2d400
|
|
|
|
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
|
|
; 0x2d413
|
|
|
|
RapidashAgilityEffect: ; 2d413 (b:5413)
|
|
ldtx de, IfHeadsDoNotReceiveDamageOrEffectText
|
|
call TossCoin_BankB
|
|
ret nc ; return if tails
|
|
ld a, ATK_ANIM_AGILITY_PROTECT
|
|
ld [wLoadedMoveAnimation], a
|
|
ld a, SUBSTATUS1_AGILITY
|
|
call ApplySubstatus1ToDefendingCard
|
|
ret
|
|
; 0x2d425
|
|
|
|
; returns carry if Opponent has no Pokemon in bench
|
|
NinetailsLure_CheckBench: ; 2d425 (b:5425)
|
|
ld a, DUELVARS_NUMBER_OF_POKEMON_IN_PLAY_AREA
|
|
call GetNonTurnDuelistVariable
|
|
ldtx hl, EffectNoPokemonOnTheBenchText
|
|
cp 2
|
|
ret
|
|
; 0x2d430
|
|
|
|
NinetailsLure_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
|
|
; 0x2d449
|
|
|
|
NinetailsLure_AISelectEffect: ; 2d449 (b:5449)
|
|
call GetBenchPokemonWithLowestHP
|
|
ldh [hTemp_ffa0], a
|
|
ret
|
|
; 0x2d44f
|
|
|
|
NinetailsLure_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
|
|
; 0x2d463
|
|
|
|
; 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
|
|
; 0x2d471
|
|
|
|
FireBlast_PlayerSelectEffect: ; 2d471 (b:5471)
|
|
call PlayerPickFireEnergyCardToDiscard
|
|
ret
|
|
; 0x2d475
|
|
|
|
FireBlast_AISelectEffect: ; 2d475 (b:5475)
|
|
call AIPickFireEnergyCardToDiscard
|
|
ret
|
|
; 0x2d479
|
|
|
|
FireBlast_DiscardEffect: ; 2d479 (b:5479)
|
|
ldh a, [hTempList]
|
|
call PutCardInDiscardPile
|
|
ret
|
|
; 0x2d47f
|
|
|
|
; 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
|
|
; 0x2d48d
|
|
|
|
Ember_PlayerSelectEffect: ; 2d48d (b:548d)
|
|
call PlayerPickFireEnergyCardToDiscard
|
|
ret
|
|
; 0x2d491
|
|
|
|
Ember_AISelectEffect: ; 2d491 (b:5491)
|
|
call AIPickFireEnergyCardToDiscard
|
|
ret
|
|
; 0x2d495
|
|
|
|
Ember_DiscardEffect: ; 2d495 (b:5495)
|
|
ldh a, [hTempList]
|
|
call PutCardInDiscardPile
|
|
ret
|
|
; 0x2d49b
|
|
|
|
; 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
|
|
; 0x2d4a9
|
|
|
|
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 [wcbfa], a
|
|
.loop
|
|
ldh a, [hCurSelectionItem]
|
|
ld [wcbfb], 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
|
|
; 0x2d4dd
|
|
|
|
Wildfire_AISelectEffect: ; 2d4dd (b:54dd)
|
|
; AI always chooses 0 cards to discard
|
|
xor a
|
|
ldh [hTempList], a
|
|
ret
|
|
; 0x2d4e1
|
|
|
|
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
|
|
; 0x2d4f4
|
|
|
|
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
|
|
; 0x2d523
|
|
|
|
Moltres1DiveBomb_AIEffect: ; 2d523 (b:5523)
|
|
ld a, 80 / 2
|
|
lb de, 0, 80
|
|
jp SetExpectedAIDamage
|
|
; 0x2d52b
|
|
|
|
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 [wLoadedMoveAnimation], a
|
|
ret
|
|
; 0x2d541
|
|
|
|
FlareonQuickAttack_AIEffect: ; 2d541 (b:5541)
|
|
ld a, (10 + 30) / 2
|
|
lb de, 10, 30
|
|
jp SetExpectedAIDamage
|
|
; 0x2d549
|
|
|
|
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
|
|
; 0x2d55c
|
|
|
|
; 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
|
|
; 0x2d56a
|
|
|
|
FlareonFlamethrower_PlayerSelectEffect: ; 2d56a (b:556a)
|
|
call PlayerPickFireEnergyCardToDiscard
|
|
ret
|
|
; 0x2d56e
|
|
|
|
FlareonFlamethrower_AISelectEffect: ; 2d56e (b:556e)
|
|
call AIPickFireEnergyCardToDiscard
|
|
ret
|
|
; 0x2d572
|
|
|
|
FlareonFlamethrower_DiscardEffect: ; 2d572 (b:5572)
|
|
ldh a, [hTempList]
|
|
call PutCardInDiscardPile
|
|
ret
|
|
; 0x2d578
|
|
|
|
; 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
|
|
; 0x2d586
|
|
|
|
MagmarFlamethrower_PlayerSelectEffect: ; 2d586 (b:5586)
|
|
call PlayerPickFireEnergyCardToDiscard
|
|
ret
|
|
; 0x2d58a
|
|
|
|
MagmarFlamethrower_AISelectEffect: ; 2d58a (b:558a)
|
|
call AIPickFireEnergyCardToDiscard
|
|
ret
|
|
; 0x2d58e
|
|
|
|
MagmarFlamethrower_DiscardEffect: ; 2d58e (b:558e)
|
|
ldh a, [hTempList]
|
|
call PutCardInDiscardPile
|
|
ret
|
|
; 0x2d594
|
|
|
|
MagmarSmokescreenEffect: ; 2d594 (b:5594)
|
|
ld a, SUBSTATUS2_SMOKESCREEN
|
|
call ApplySubstatus2ToDefendingCard
|
|
ret
|
|
; 0x2d59a
|
|
|
|
MagmarSmog_AIEffect: ; 2d59a (b:559a)
|
|
ld a, 5
|
|
lb de, 0, 10
|
|
jp UpdateExpectedAIDamage_AccountForPoison
|
|
; 0x2d5a2
|
|
|
|
; 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
|
|
; 0x2d5b0
|
|
|
|
CharmeleonFlamethrower_PlayerSelectEffect: ; 2d5b0 (b:55b0)
|
|
call PlayerPickFireEnergyCardToDiscard
|
|
ret
|
|
; 0x2d5b4
|
|
|
|
CharmeleonFlamethrower_AISelectEffect: ; 2d5b4 (b:55b4)
|
|
call AIPickFireEnergyCardToDiscard
|
|
ret
|
|
; 0x2d5b8
|
|
|
|
CharmeleonFlamethrower_DiscardEffect: ; 2d5b8 (b:55b8)
|
|
ldh a, [hTempList]
|
|
call PutCardInDiscardPile
|
|
ret
|
|
; 0x2d5be
|
|
|
|
EnergyBurnEffect: ; 2d5be (b:55be)
|
|
scf
|
|
ret
|
|
; 0x2d5c0
|
|
|
|
; 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
|
|
; 0x2d5cd
|
|
|
|
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 [wcbfa], a
|
|
.loop_input
|
|
bank1call HandleEnergyDiscardMenuInput
|
|
ret c
|
|
call GetNextPositionInTempList
|
|
ldh a, [hTempCardIndex_ff98]
|
|
ld [hl], a
|
|
ld hl, wcbfb
|
|
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
|
|
; 0x2d606
|
|
|
|
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
|
|
; 0x2d614
|
|
|
|
FireSpin_DiscardEffect: ; 2d614 (b:5614)
|
|
ld hl, hTempList
|
|
ld a, [hli]
|
|
call PutCardInDiscardPile
|
|
ld a, [hli]
|
|
call PutCardInDiscardPile
|
|
ret
|
|
; 0x2d620
|
|
|
|
; 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
|
|
; 0x2d638
|
|
|
|
FlareonRage_AIEffect: ; 2d638 (b:5638)
|
|
call FlareonRage_DamageBoostEffect
|
|
jp SetDefiniteAIDamage
|
|
; 0x2d63e
|
|
|
|
FlareonRage_DamageBoostEffect: ; 2d63e (b:563e)
|
|
ld e, PLAY_AREA_ARENA
|
|
call GetCardDamageAndMaxHP
|
|
call AddToDamage
|
|
ret
|
|
; 0x2d647
|
|
|
|
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
|
|
; 0x2d69a
|
|
|
|
; returns carry if card index in a is Pkmn card
|
|
.CheckIfCardIsPkmnCard: ; 2d69a (b:569a)
|
|
call LoadCardDataToBuffer2_FromDeckIndex
|
|
ld a, [wLoadedCard2Type]
|
|
cp TYPE_ENERGY
|
|
ret
|
|
; 0x2d6a3
|
|
|
|
DancingEmbers_AIEffect: ; 2d6a3 (b:56a3)
|
|
ld a, 80 / 2
|
|
lb de, 0, 80
|
|
jp SetExpectedAIDamage
|
|
; 0x2d6ab
|
|
|
|
DancingEmbers_MultiplierEffect: ; 2d6ab (b:56ab)
|
|
ld hl, 10
|
|
call LoadTxRam3
|
|
ldtx de, DamageCheckIfHeadsXDamageText
|
|
ld a, 8
|
|
call TossCoinATimes_BankB
|
|
call ATimes10
|
|
call SetDefiniteDamage
|
|
ret
|
|
; 0x2d6c0
|
|
|
|
Firegiver_InitialEffect: ; 2d6c0 (b:56c0)
|
|
scf
|
|
ret
|
|
; 0x2d6c2
|
|
|
|
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 [wLoadedMoveAnimation], 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 PlayMoveAnimation
|
|
bank1call WaitMoveAnimation
|
|
|
|
; 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, [wLoadedMoveAnimation]
|
|
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
|
|
; 0x2d76e
|
|
|
|
Moltres2DiveBomb_AIEffect: ; 2d76e (b:576e)
|
|
ld a, 70 / 2
|
|
lb de, 0, 70
|
|
jp SetExpectedAIDamage
|
|
; 0x2d776
|
|
|
|
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 [wLoadedMoveAnimation], a
|
|
ret
|
|
; 0x2d78c
|
|
|
|
; 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
|
|
; 0x2d7bc
|
|
|
|
; 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
|
|
; 0x2d7fc
|
|
|
|
; 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
|
|
; 0x2d834
|
|
|
|
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
|
|
; 0x2d8bb
|
|
|
|
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
|
|
; 0x2d903
|
|
|
|
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
|
|
; 0x2d92a
|
|
|
|
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
|
|
; 0x2d93c
|
|
|
|
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
|
|
; 0x2d94f
|
|
|
|
SleepingGasEffect: ; 2d94f (b:594f)
|
|
call Sleep50PercentEffect
|
|
call nc, SetNoEffectFromStatus
|
|
ret
|
|
; 0x2d956
|
|
|
|
DestinyBond_CheckEnergy: ; 2d956 (b:5956)
|
|
ld e, PLAY_AREA_ARENA
|
|
call GetPlayAreaCardAttachedEnergies
|
|
ld a, [wAttachedEnergies + PSYCHIC]
|
|
ldtx hl, NotEnoughPsychicEnergyText
|
|
cp 1
|
|
ret
|
|
; 0x2d964
|
|
|
|
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
|
|
; 0x2d976
|
|
|
|
DestinyBond_AISelectEffect: ; 2d976 (b:5976)
|
|
; pick first card in list
|
|
ld a, TYPE_ENERGY_PSYCHIC
|
|
call CreateListOfEnergyAttachedToArena
|
|
ld a, [wDuelTempList]
|
|
ldh [hTempList], a
|
|
ret
|
|
; 0x2d981
|
|
|
|
DestinyBond_DiscardEffect: ; 2d981 (b:5981)
|
|
ldh a, [hTempList]
|
|
call PutCardInDiscardPile
|
|
ret
|
|
; 0x2d987
|
|
|
|
DestinyBond_DestinyBondEffect: ; 2d987 (b:5987)
|
|
ld a, SUBSTATUS1_DESTINY_BOND
|
|
call ApplySubstatus1ToDefendingCard
|
|
ret
|
|
; 0x2d98d
|
|
|
|
; returns carry if no Energy cards in Discard Pile.
|
|
EnergyConversion_CheckEnergy: ; 2d98d (b:598d)
|
|
call CreateEnergyCardListFromDiscardPile_AllEnergy
|
|
ldtx hl, ThereAreNoEnergyCardsInDiscardPileText
|
|
ret
|
|
; 0x2d994
|
|
|
|
EnergyConversion_PlayerSelectEffect: ; 2d994 (b:5994)
|
|
ldtx hl, Choose2EnergyCardsFromDiscardPileForHandText
|
|
call HandleEnergyCardsInDiscardPileSelection
|
|
ret
|
|
; 0x2d99b
|
|
|
|
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
|
|
; 0x2d9b4
|
|
|
|
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
|
|
; 0x2d9d6
|
|
|
|
; 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
|
|
; 0x2d9e5
|
|
|
|
TransparencyEffect: ; 2d9e5 (b:59e5)
|
|
scf
|
|
ret
|
|
; 0x2d9e7
|
|
|
|
; 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
|
|
; 0x2da00
|
|
|
|
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
|
|
; 0x2da3c
|
|
|
|
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
|
|
; 0x2da41
|
|
|
|
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
|
|
; 0x2da76
|
|
|
|
; 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
|
|
; 0x2db2b
|
|
|
|
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
|
|
; 0x2db52
|
|
|
|
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
|
|
; 0x2db64
|
|
|
|
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
|
|
; 0x2db77
|
|
|
|
InvisibleWallEffect: ; 2db77 (b:5b77)
|
|
scf
|
|
ret
|
|
; 0x2db79
|
|
|
|
MrMimeMeditate_AIEffect: ; 2db79 (b:5b79)
|
|
call MrMimeMeditate_DamageBoostEffect
|
|
jp SetDefiniteAIDamage
|
|
; 0x2db7f
|
|
|
|
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
|
|
; 0x2db8e
|
|
|
|
; 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
|
|
; 0x2dba2
|
|
|
|
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
|
|
; 0x2dc27
|
|
|
|
; 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
|
|
; 0x2dc30
|
|
|
|
; 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
|
|
; 0x2dc49
|
|
|
|
PsywaveEffect: ; 2dc49 (b:5c49)
|
|
call GetEnergyAttachedMultiplierDamage
|
|
ld hl, wDamage
|
|
ld [hl], e
|
|
inc hl
|
|
ld [hl], d
|
|
ret
|
|
; 0x2dc53
|
|
|
|
; 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
|
|
; 0x2dc64
|
|
|
|
; 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
|
|
; 0x2dc9e
|
|
|
|
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
|
|
; 0x2dcb6
|
|
|
|
DevolutionBeam_LoadAnimation: ; 2dcb6 (b:5cb6)
|
|
xor a ; ATK_ANIM_NONE
|
|
ld [wLoadedMoveAnimation], a
|
|
ret
|
|
; 0x2dcbb
|
|
|
|
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 [wLoadedMoveAnimation], a
|
|
ldh a, [hTempPlayAreaLocation_ffa1]
|
|
ld b, a
|
|
ld c, $00
|
|
ldh a, [hWhoseTurn]
|
|
ld h, a
|
|
bank1call PlayMoveAnimation
|
|
bank1call WaitMoveAnimation
|
|
|
|
; 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
|
|
; 0x2dd3b
|
|
|
|
; 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
|
|
; 0x2dd50
|
|
|
|
; 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
|
|
; 0x2dd62
|
|
|
|
; 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
|
|
; 0x2dd79
|
|
|
|
NeutralizingShieldEffect: ; 2dd79 (b:5d79)
|
|
scf
|
|
ret
|
|
; 0x2dd7b
|
|
|
|
Psychic_AIEffect: ; 2dd7b (b:5d7b)
|
|
call Psychic_DamageBoostEffect
|
|
jp SetDefiniteAIDamage
|
|
; 0x2dd81
|
|
|
|
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
|
|
; 0x2dd8e
|
|
|
|
; 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
|
|
; 0x2dd9c
|
|
|
|
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
|
|
; 0x2ddae
|
|
|
|
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
|
|
; 0x2ddb9
|
|
|
|
Barrier_DiscardEffect: ; 2ddb9 (b:5db9)
|
|
ldh a, [hTemp_ffa0]
|
|
call PutCardInDiscardPile
|
|
ret
|
|
; 0x2ddbf
|
|
|
|
Barrier_BarrierEffect: ; 2ddbf (b:5dbf)
|
|
ld a, SUBSTATUS1_BARRIER
|
|
call ApplySubstatus1ToDefendingCard
|
|
ret
|
|
; 0x2ddc5
|
|
|
|
Mewtwo3EnergyAbsorption_CheckDiscardPile: ; 2ddc5 (b:5dc5)
|
|
call CreateEnergyCardListFromDiscardPile_AllEnergy
|
|
ldtx hl, ThereAreNoEnergyCardsInDiscardPileText
|
|
ret
|
|
; 0x2ddcc
|
|
|
|
Mewtwo3EnergyAbsorption_PlayerSelectEffect: ; 2ddcc (b:5dcc)
|
|
ldtx hl, Choose2EnergyCardsFromDiscardPileToAttachText
|
|
call HandleEnergyCardsInDiscardPileSelection
|
|
ret
|
|
; 0x2ddd3
|
|
|
|
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
|
|
; 0x2ddec
|
|
|
|
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
|
|
; 0x2ddff
|
|
|
|
Mewtwo2EnergyAbsorption_CheckDiscardPile: ; 2ddff (b:5dff)
|
|
call CreateEnergyCardListFromDiscardPile_AllEnergy
|
|
ldtx hl, ThereAreNoEnergyCardsInDiscardPileText
|
|
ret
|
|
; 0x2de06
|
|
|
|
Mewtwo2EnergyAbsorption_PlayerSelectEffect: ; 2de06 (b:5e06)
|
|
ldtx hl, Choose2EnergyCardsFromDiscardPileToAttachText
|
|
call HandleEnergyCardsInDiscardPileSelection
|
|
ret
|
|
; 0x2de0d
|
|
|
|
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
|
|
; 0x2de26
|
|
|
|
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
|
|
; 0x2de39
|
|
|
|
; 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
|
|
; 0x2de5b
|
|
|
|
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
|
|
; 0x2deb3
|
|
|
|
StrangeBehavior_SwapEffect: ; 2deb3 (b:5eb3)
|
|
call TryGiveDamageCounter_StrangeBehavior
|
|
ret c
|
|
bank1call PrintPlayAreaCardList_EnableLCD
|
|
or a
|
|
ret
|
|
; 0x2debc
|
|
|
|
; 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
|
|
; 0x2ded5
|
|
|
|
; 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
|
|
; 0x2dee0
|
|
|
|
SpacingOut_Success50PercentEffect: ; 2dee0 (b:5ee0)
|
|
ldtx de, SuccessCheckIfHeadsAttackIsSuccessfulText
|
|
call TossCoin_BankB
|
|
ldh [hTemp_ffa0], a
|
|
jp nc, SetWasUnsuccessful
|
|
ld a, ATK_ANIM_RECOVER
|
|
ld [wLoadedMoveAnimation], a
|
|
ret
|
|
; 0x2def1
|
|
|
|
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
|
|
; 0x2df05
|
|
|
|
; 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
|
|
; 0x2df1a
|
|
|
|
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
|
|
; 0x2df2d
|
|
|
|
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
|
|
; 0x2df40
|
|
|
|
Scavenge_DiscardEffect: ; 2df40 (b:5f40)
|
|
ldh a, [hTemp_ffa0]
|
|
call PutCardInDiscardPile
|
|
ret
|
|
; 0x2df46
|
|
|
|
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
|
|
; 0x2df5f
|
|
|
|
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
|
|
; 0x2df74
|
|
|
|
; returns carry if Defending Pokemon has no attacks
|
|
SlowpokeAmnesia_CheckAttacks: ; 2df74 (b:5f74)
|
|
call CheckIfDefendingPokemonHasAnyAttack
|
|
ldtx hl, NoAttackMayBeChoosenText
|
|
ret
|
|
; 0x2df7b
|
|
|
|
SlowpokeAmnesia_PlayerSelectEffect: ; 2df7b (b:5f7b)
|
|
call PlayerPickAttackForAmnesia
|
|
ret
|
|
; 0x2df7f
|
|
|
|
SlowpokeAmnesia_AISelectEffect: ; 2df7f (b:5f7f)
|
|
call AIPickAttackForAmnesia
|
|
ldh [hTemp_ffa0], a
|
|
ret
|
|
; 0x2df85
|
|
|
|
SlowpokeAmnesia_DisableEffect: ; 2df85 (b:5f85)
|
|
call ApplyAmnesiaToAttack
|
|
ret
|
|
; 0x2df89
|
|
|
|
; 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
|
|
; 0x2dfa0
|
|
|
|
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
|
|
; 0x2dfb2
|
|
|
|
KadabraRecover_AISelectEffect: ; 2dfb2 (b:5fb2)
|
|
ld a, TYPE_ENERGY_PSYCHIC
|
|
call CreateListOfEnergyAttachedToArena
|
|
ld a, [wDuelTempList] ; pick first card
|
|
ldh [hTemp_ffa0], a
|
|
ret
|
|
; 0x2dfbd
|
|
|
|
KadabraRecover_DiscardEffect: ; 2dfbd (b:5fbd)
|
|
ldh a, [hTemp_ffa0]
|
|
call PutCardInDiscardPile
|
|
ret
|
|
; 0x2dfc3
|
|
|
|
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
|
|
; 0x2dfd7
|
|
|
|
JynxDoubleslap_AIEffect: ; 2dfd7 (b:5fd7)
|
|
ld a, 20 / 2
|
|
lb de, 0, 20
|
|
jp SetExpectedAIDamage
|
|
; 0x2dfcf
|
|
|
|
JynxDoubleslap_MultiplierEffect: ; 2dfcf (b:5fcf)
|
|
ld hl, 10
|
|
call LoadTxRam3
|
|
ldtx de, DamageCheckIfHeadsXDamageText
|
|
ld a, 2
|
|
call TossCoinATimes_BankB
|
|
call ATimes10
|
|
call SetDefiniteDamage
|
|
ret
|
|
; 0x2dff2
|
|
|
|
JynxMeditate_AIEffect: ; 2dff2 (b:5ff2)
|
|
call JynxMeditate_DamageBoostEffect
|
|
jp SetDefiniteAIDamage
|
|
; 0x2dfec
|
|
|
|
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
|
|
; 0x2e001
|
|
|
|
MysteryAttack_AIEffect: ; 2e001 (b:6001)
|
|
ld a, 10
|
|
lb de, 0, 20
|
|
jp SetExpectedAIDamage
|
|
; 0x2e009
|
|
|
|
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 [wLoadedMoveAnimation], a
|
|
xor a
|
|
call SetDefiniteDamage
|
|
call SetNoEffectFromStatus
|
|
.no_effect
|
|
ret
|
|
; 0x2e03e
|
|
|
|
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
|
|
; 0x2e04a
|
|
|
|
StoneBarrage_AIEffect: ; 2e04a (b:604a)
|
|
ld a, 10
|
|
lb de, 0, 100
|
|
jp SetExpectedAIDamage
|
|
; 0x2e052
|
|
|
|
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
|
|
; 0x2e075
|
|
|
|
OnixHardenEffect: ; 2e075 (b:6075)
|
|
ld a, SUBSTATUS1_HARDEN
|
|
call ApplySubstatus1ToDefendingCard
|
|
ret
|
|
; 0x2e07b
|
|
|
|
PrimeapeFurySwipes_AIEffect: ; 2e07b (b:607b)
|
|
ld a, 60 / 2
|
|
lb de, 0, 60
|
|
jp SetExpectedAIDamage
|
|
; 0x2e083
|
|
|
|
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
|
|
; 0x2e099
|
|
|
|
TantrumEffect: ; 2e099 (b:6099)
|
|
ldtx de, IfTailsYourPokemonBecomesConfusedText
|
|
call TossCoin_BankB
|
|
ret c ; return if heads
|
|
; confuse Pokemon
|
|
ld a, ATK_ANIM_MULTIPLE_SLASH
|
|
ld [wLoadedMoveAnimation], a
|
|
call SwapTurn
|
|
call ConfusionEffect
|
|
call SwapTurn
|
|
ret
|
|
; 0x2e0af
|
|
|
|
StrikesBackEffect: ; 2e0af (b:60af)
|
|
scf
|
|
ret
|
|
; 0x2e0b1
|
|
|
|
KabutoArmorEffect: ; 2e0b1 (b:60b1)
|
|
scf
|
|
ret
|
|
; 0x2e0b3
|
|
|
|
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
|
|
; 0x2e0cb
|
|
|
|
SnivelEffect: ; 2e0cb (b:60cb)
|
|
ld a, SUBSTATUS2_REDUCE_BY_20
|
|
call ApplySubstatus2ToDefendingCard
|
|
ret
|
|
; 0x2e0d1
|
|
|
|
CuboneRage_AIEffect: ; 2e0d1 (b:60d1)
|
|
call CuboneRage_DamageBoostEffect
|
|
jp SetDefiniteAIDamage
|
|
; 0x2e0d7
|
|
|
|
CuboneRage_DamageBoostEffect: ; 2e0d7 (b:60d7)
|
|
ld e, PLAY_AREA_ARENA
|
|
call GetCardDamageAndMaxHP
|
|
call AddToDamage
|
|
ret
|
|
; 0x2e0e0
|
|
|
|
Bonemerang_AIEffect: ; 2e0e0 (b:60e0)
|
|
ld a, 60 / 2
|
|
lb de, 0, 60
|
|
jp SetExpectedAIDamage
|
|
; 0x2e0e8
|
|
|
|
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
|
|
; 0x2e100
|
|
|
|
; 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
|
|
; 0x2e110
|
|
|
|
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
|
|
; 0x2e177
|
|
|
|
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
|
|
; 0x2e194
|
|
|
|
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
|
|
; 0x2c1b4
|
|
|
|
KarateChop_AIEffect: ; 2e1b4 (b:61b4)
|
|
call KarateChop_DamageSubtractionEffect
|
|
jp SetDefiniteAIDamage
|
|
; 0x2e1ba
|
|
|
|
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
|
|
; 0x2e1d1
|
|
|
|
SubmissionEffect: ; 2e1d1 (b:61d1)
|
|
ld a, 20
|
|
call DealRecoilDamageToSelf
|
|
ret
|
|
; 0x2e1d7
|
|
|
|
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
|
|
; 0x2e1f6
|
|
|
|
GravelerHardenEffect: ; 2e1f6 (b:61f6)
|
|
ld a, SUBSTATUS1_HARDEN
|
|
call ApplySubstatus1ToDefendingCard
|
|
ret
|
|
; 0x2e1fc
|
|
|
|
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
|
|
; 0x2e212
|
|
|
|
Ram_RecoilSwitchEffect: ; 2e212 (b:6212)
|
|
ld a, 20
|
|
call DealRecoilDamageToSelf
|
|
ldh a, [hTemp_ffa0]
|
|
call HandleSwitchDefendingPokemonEffect
|
|
ret
|
|
; 0x2e21d
|
|
|
|
LeerEffect: ; 2e21d (b:621d)
|
|
ldtx de, IfHeadsOpponentCannotAttackText
|
|
call TossCoin_BankB
|
|
jp nc, SetWasUnsuccessful
|
|
ld a, ATK_ANIM_LEER
|
|
ld [wLoadedMoveAnimation], a
|
|
ld a, SUBSTATUS2_LEER
|
|
call ApplySubstatus2ToDefendingCard
|
|
ret
|
|
; 0x2e231
|
|
|
|
; 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
|
|
; 0x2e23c
|
|
|
|
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
|
|
; 0x2e255
|
|
|
|
StretchKick_AISelectEffect: ; 2e255 (b:6255)
|
|
; chooses Bench Pokemon with least amount of remaining HP
|
|
call GetBenchPokemonWithLowestHP
|
|
ldh [hTemp_ffa0], a
|
|
ret
|
|
; 0x2e25b
|
|
|
|
StretchKick_BenchDamageEffect: ; 2e25b (b:625b)
|
|
call SwapTurn
|
|
ldh a, [hTemp_ffa0]
|
|
ld b, a
|
|
ld de, 20
|
|
call DealDamageToPlayAreaPokemon_RegularAnim
|
|
call SwapTurn
|
|
ret
|
|
; 0x2e26b
|
|
|
|
SandAttackEffect: ; 2e26b (b:626b)
|
|
ld a, SUBSTATUS2_SAND_ATTACK
|
|
call ApplySubstatus2ToDefendingCard
|
|
ret
|
|
; 0x2e271
|
|
|
|
SandslashFurySwipes_AIEffect: ; 2e271 (b:6271)
|
|
ld a, 60 / 2
|
|
lb de, 0, 60
|
|
jp SetExpectedAIDamage
|
|
; 0x2e279
|
|
|
|
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
|
|
; 0x2e28f
|
|
|
|
EarthquakeEffect: ; 2e28f (b:628f)
|
|
ld a, $01
|
|
ld [wIsDamageToSelf], a
|
|
ld a, 10
|
|
call DealDamageToAllBenchedPokemon
|
|
ret
|
|
; 0x2e29a
|
|
|
|
PrehistoricPowerEffect: ; 2e29a (b:629a)
|
|
scf
|
|
ret
|
|
; 0x2e29c
|
|
|
|
; 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
|
|
; 0x2e2b4
|
|
|
|
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 Func_30e7
|
|
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 Func_30f9
|
|
call SwapTurn
|
|
ldtx hl, CardPeekWasUsedOnText
|
|
call DrawWideTextBox_WaitForInput
|
|
ret
|
|
; 0x2e30f
|
|
|
|
BoneAttackEffect: ; 2e30f (b:630f)
|
|
ldtx de, IfHeadsOpponentCannotAttackText
|
|
call TossCoin_BankB
|
|
ret nc
|
|
ld a, SUBSTATUS2_BONE_ATTACK
|
|
call ApplySubstatus2ToDefendingCard
|
|
ret
|
|
; 0x2e31c
|
|
|
|
; 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
|
|
; 0x2e335
|
|
|
|
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
|
|
; 0x2e399
|
|
|
|
Thunderpunch_AIEffect: ; 2e399 (b:6399)
|
|
ld a, (30 + 40) / 2
|
|
lb de, 30, 40
|
|
jp SetExpectedAIDamage
|
|
; 0x2e3a1
|
|
|
|
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
|
|
; 0x2e3b0
|
|
|
|
Thunderpunch_RecoilEffect: ; 2e3b0 (b:63b0)
|
|
ldh a, [hTemp_ffa0]
|
|
or a
|
|
ret nz ; return if got heads
|
|
ld a, 10
|
|
call DealRecoilDamageToSelf
|
|
ret
|
|
; 0x2e3ba
|
|
|
|
LightScreenEffect: ; 2e3ba (b:63ba)
|
|
ld a, SUBSTATUS1_HALVE_DAMAGE
|
|
call ApplySubstatus1ToDefendingCard
|
|
ret
|
|
; 0x2e3c0
|
|
|
|
ElectabuzzQuickAttack_AIEffect: ; 2e3c0 (b:63c0)
|
|
ld a, (10 + 30) / 2
|
|
lb de, 10, 30
|
|
jp SetExpectedAIDamage
|
|
; 0x2e3c8
|
|
|
|
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
|
|
; 0x2e3db
|
|
|
|
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
|
|
; 0x2e3fa
|
|
|
|
ZapdosThunder_Recoil50PercentEffect: ; 2e3fa (b:63fa)
|
|
ld hl, 30
|
|
call LoadTxRam3
|
|
ldtx de, IfTailsDamageToYourselfTooText
|
|
call TossCoin_BankB
|
|
ldh [hTemp_ffa0], a
|
|
ret
|
|
; 0x2e409
|
|
|
|
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
|
|
; 0x2e419
|
|
|
|
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
|
|
; 0x2e429
|
|
|
|
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
|
|
; 0x2e491
|
|
|
|
; 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
|
|
; 0x2e4bb
|
|
|
|
JolteonQuickAttack_AIEffect: ; 2e4bb (b:64bb)
|
|
ld a, (10 + 30) / 2
|
|
lb de, 10, 30
|
|
jp SetExpectedAIDamage
|
|
; 0x2e4c3
|
|
|
|
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
|
|
; 0x2e3d6
|
|
|
|
PinMissile_AIEffect: ; 2e4d6 (b:64d6)
|
|
ld a, (20 * 4) / 2
|
|
lb de, 0, 80
|
|
jp SetExpectedAIDamage
|
|
; 0x2e4de
|
|
|
|
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
|
|
; 0x2e4f4
|
|
|
|
Fly_AIEffect: ; 2e4f4 (b:64f4)
|
|
ld a, 30 / 2
|
|
lb de, 0, 30
|
|
jp SetExpectedAIDamage
|
|
; 0x2e4fc
|
|
|
|
Fly_Success50PercentEffect: ; 2e4fc (b:64fc)
|
|
ldtx de, SuccessCheckIfHeadsAttackIsSuccessfulText
|
|
call TossCoin_BankB
|
|
jr c, .heads
|
|
xor a ; ATK_ANIM_NONE
|
|
ld [wLoadedMoveAnimation], a
|
|
call SetDefiniteDamage
|
|
call SetWasUnsuccessful
|
|
ret
|
|
.heads
|
|
ld a, ATK_ANIM_AGILITY_PROTECT
|
|
ld [wLoadedMoveAnimation], a
|
|
ld a, SUBSTATUS1_FLY
|
|
call ApplySubstatus1ToDefendingCard
|
|
ret
|
|
; 0x2e51a
|
|
|
|
ThunderJolt_Recoil50PercentEffect: ; 2e51a (b:651a)
|
|
ld hl, 10
|
|
call LoadTxRam3
|
|
ldtx de, IfTailsDamageToYourselfTooText
|
|
call TossCoin_BankB
|
|
ldh [hTemp_ffa0], a
|
|
ret
|
|
; 0x2e529
|
|
|
|
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
|
|
; 0x2e539
|
|
|
|
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
|
|
; 0x2e562
|
|
|
|
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
|
|
; 0x2e574
|
|
|
|
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
|
|
; 0x2e589
|
|
|
|
Pikachu3GrowlEffect: ; 2e589 (b:6589)
|
|
ld a, SUBSTATUS2_GROWL
|
|
call ApplySubstatus2ToDefendingCard
|
|
ret
|
|
; 0x2e58f
|
|
|
|
Pikachu4GrowlEffect: ; 2e58f (b:658f)
|
|
ld a, SUBSTATUS2_GROWL
|
|
call ApplySubstatus2ToDefendingCard
|
|
ret
|
|
; 0x2e595
|
|
|
|
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
|
|
; 0x2e5ba
|
|
|
|
.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
|
|
; 0x2e5dc
|
|
|
|
RaichuAgilityEffect: ; 2e5dc (b:65dc)
|
|
ldtx de, IfHeadsDoNotReceiveDamageOrEffectText
|
|
call TossCoin_BankB
|
|
ret nc ; skip if got tails
|
|
ld a, ATK_ANIM_AGILITY_PROTECT
|
|
ld [wLoadedMoveAnimation], a
|
|
ld a, SUBSTATUS1_AGILITY
|
|
call ApplySubstatus1ToDefendingCard
|
|
ret
|
|
; 0x2e5ee
|
|
|
|
RaichuThunder_Recoil50PercentEffect: ; 2e5ee (b:65ee)
|
|
ld hl, 30
|
|
call LoadTxRam3
|
|
ldtx de, IfTailsDamageToYourselfTooText
|
|
call TossCoin_BankB
|
|
ldh [hTemp_ffa0], a
|
|
ret
|
|
; 0x2e5fd
|
|
|
|
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
|
|
; 0x2e60d
|
|
|
|
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
|
|
; 0x2e6af
|
|
|
|
; 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
|
|
; 0x2e6c3
|
|
|
|
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
|
|
; 0x2e71f
|
|
|
|
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
|
|
; 0x2e739
|
|
|
|
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
|
|
; 0x2e758
|
|
|
|
MagnetonSonicboom_UnaffectedByColorEffect: ; 2e758 (b:6758)
|
|
ld hl, wDamage + 1
|
|
set UNAFFECTED_BY_WEAKNESS_RESISTANCE_F, [hl]
|
|
ret
|
|
; 0x2e75e
|
|
|
|
MagnetonSonicboom_NullEffect: ; 2e75e (b:675e)
|
|
ret
|
|
; 0x2e75f
|
|
|
|
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
|
|
; 0x2e77e
|
|
|
|
PealOfThunder_InitialEffect: ; 2e77e (b:677e)
|
|
scf
|
|
ret
|
|
; 0x2e780
|
|
|
|
PealOfThunder_RandomlyDamageEffect: ; 2e780 (b:6780)
|
|
call ExchangeRNG
|
|
ld de, 30 ; damage to inflict
|
|
call RandomlyDamagePlayAreaPokemon
|
|
bank1call Func_6e49
|
|
ret
|
|
; 0x2e78d
|
|
|
|
; 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 [wLoadedMoveAnimation], 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
|
|
; 0x2e7cb
|
|
|
|
BigThunderEffect: ; 2e7cb (b:67cb)
|
|
call ExchangeRNG
|
|
ld de, 70 ; damage to inflict
|
|
call RandomlyDamagePlayAreaPokemon
|
|
ret
|
|
; 0x2e7d5
|
|
|
|
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
|
|
; 0x2e870
|
|
|
|
ElectrodeSonicboom_UnaffectedByColorEffect: ; 2e870 (b:6870)
|
|
ld hl, wDamage + 1
|
|
set UNAFFECTED_BY_WEAKNESS_RESISTANCE_F, [hl]
|
|
ret
|
|
; 0x2e876
|
|
|
|
ElectrodeSonicboom_NullEffect: ; 2e876 (b:6876)
|
|
ret
|
|
; 0x2e877
|
|
|
|
; return carry if no cards in Deck
|
|
EnergySpike_DeckCheck: ; 2e877 (b:6877)
|
|
call CheckIfDeckIsEmpty
|
|
ret
|
|
; 0x2e87b
|
|
|
|
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
|
|
; 0x2e8f1
|
|
|
|
EnergySpike_AISelectEffect: ; 2e8f1 (b:68f1)
|
|
; AI doesn't select any card
|
|
ld a, $ff
|
|
ldh [hTemp_ffa0], a
|
|
ret
|
|
; 0x2e8f6
|
|
|
|
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
|
|
; 0x2e930
|
|
|
|
JolteonDoubleKick_AIEffect: ; 2e930 (b:6930)
|
|
ld a, 40 / 2
|
|
lb de, 0, 40
|
|
jp SetExpectedAIDamage
|
|
; 0x2e938
|
|
|
|
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
|
|
; 0x2e94e
|
|
|
|
TailWagEffect: ; 2e94e (b:694e)
|
|
ldtx de, IfHeadsOpponentCannotAttackText
|
|
call TossCoin_BankB
|
|
jp nc, SetWasUnsuccessful
|
|
ld a, ATK_ANIM_LURE
|
|
ld [wLoadedMoveAnimation], a
|
|
ld a, SUBSTATUS2_TAIL_WAG
|
|
call ApplySubstatus2ToDefendingCard
|
|
ret
|
|
; 0x2e962
|
|
|
|
EeveeQuickAttack_AIEffect: ; 2e962 (b:5962)
|
|
ld a, (10 + 30) / 2
|
|
lb de, 10, 30
|
|
jp SetExpectedAIDamage
|
|
; 0x2e96a
|
|
|
|
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
|
|
; 0x2e97d
|
|
|
|
SpearowMirrorMove_AIEffect: ; 2e97d (b:697d)
|
|
jr MirrorMoveEffects.AIEffect
|
|
; 0x2e97f
|
|
|
|
SpearowMirrorMove_InitialEffect1: ; 2e97f (b:697f)
|
|
jr MirrorMoveEffects.InitialEffect1
|
|
; 0x2e981
|
|
|
|
SpearowMirrorMove_InitialEffect2: ; 2e981 (b:6981)
|
|
jr MirrorMoveEffects.InitialEffect2
|
|
; 0x2e983
|
|
|
|
SpearowMirrorMove_PlayerSelection: ; 2e983 (b:6983)
|
|
jr MirrorMoveEffects.PlayerSelection
|
|
; 0x2e985
|
|
|
|
SpearowMirrorMove_AISelection: ; 2e985 (b:6985)
|
|
jr MirrorMoveEffects.AISelection
|
|
; 0x2e987
|
|
|
|
SpearowMirrorMove_BeforeDamage: ; 2e987 (b:6987)
|
|
jr MirrorMoveEffects.BeforeDamage
|
|
; 0x2e989
|
|
|
|
SpearowMirrorMove_AfterDamage: ; 2e989 (b:6989)
|
|
jp MirrorMoveEffects.AfterDamage
|
|
; 0x2e98c
|
|
|
|
; 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 [wLoadedMoveAnimation], 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
|
|
; 0x2ea28
|
|
|
|
.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
|
|
; 0x2ea8f
|
|
|
|
.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
|
|
; 0x2eab8
|
|
|
|
FearowAgilityEffect: ; 2eab8 (b:6ab8)
|
|
ldtx de, IfHeadsDoNotReceiveDamageOrEffectText
|
|
call TossCoin_BankB
|
|
ret nc
|
|
ld a, ATK_ANIM_AGILITY_PROTECT
|
|
ld [wLoadedMoveAnimation], a
|
|
ld a, SUBSTATUS1_AGILITY
|
|
call ApplySubstatus1ToDefendingCard
|
|
ret
|
|
; 0x2eaca
|
|
|
|
; 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
|
|
; 0x2eae8
|
|
|
|
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
|
|
; 0x2eaf6
|
|
|
|
Dragonite2Slam_AIEffect: ; 2eaf6 (b:6af6)
|
|
ld a, (40 * 2) / 2
|
|
lb de, 0, 80
|
|
jp SetExpectedAIDamage
|
|
; 0x2eafe
|
|
|
|
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
|
|
; 0x2eb15
|
|
|
|
ThickSkinnedEffect: ; 2eb15 (b:6b15)
|
|
scf
|
|
ret
|
|
; 0x2eb17
|
|
|
|
LeekSlap_AIEffect: ; 2eb17 (b:6b17)
|
|
ld a, 30 / 2
|
|
lb de, 0, 30
|
|
jp SetExpectedAIDamage
|
|
; 0x2eb1f
|
|
|
|
; 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
|
|
; 0x2eb2c
|
|
|
|
LeekSlap_SetUsedThisDuelFlag: ; 2eb2c (b:6b2c)
|
|
ld a, DUELVARS_ARENA_CARD_FLAGS
|
|
call GetTurnDuelistVariable
|
|
set USED_LEEK_SLAP_THIS_DUEL_F, [hl]
|
|
ret
|
|
; 0x2eb34
|
|
|
|
LeekSlap_NoDamage50PercentEffect: ; 2eb34 (b:6b34)
|
|
ldtx de, DamageCheckIfTailsNoDamageText
|
|
call TossCoin_BankB
|
|
ret c
|
|
xor a ; 0 damage
|
|
call SetDefiniteDamage
|
|
ret
|
|
; 0x2eb40
|
|
|
|
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
|
|
; 0x2eb5d
|
|
|
|
CometPunch_AIEffect: ; 2eb5d (b:6b5d)
|
|
ld a, (20 * 4) / 2
|
|
lb de, 0, 80
|
|
jp SetExpectedAIDamage
|
|
; 0x2eb65
|
|
|
|
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
|
|
; 0x2eb7b
|
|
|
|
TaurosStomp_AIEffect: ; 2eb7b (b:6b7b)
|
|
ld a, (20 + 30) / 2
|
|
lb de, 20, 30
|
|
jp SetExpectedAIDamage
|
|
; 0x2eb83
|
|
|
|
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
|
|
; 0x2eb96
|
|
|
|
Rampage_AIEffect: ; 2eb96 (b:6b96)
|
|
ld e, PLAY_AREA_ARENA
|
|
call GetCardDamageAndMaxHP
|
|
call AddToDamage
|
|
jp SetDefiniteAIDamage
|
|
; 0x2eba1
|
|
|
|
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
|
|
; 0x2ebba
|
|
|
|
FuryAttack_AIEffect: ; 2ebba (b:6bba)
|
|
ld a, (10 * 2) / 2
|
|
lb de, 0, 20
|
|
jp SetExpectedAIDamage
|
|
; 0x2ebc2
|
|
|
|
FuryAttack_MultiplierEffect: ; 2ebc2 (b:6bc2)
|
|
ld hl, 10
|
|
call LoadTxRam3
|
|
ld a, 2
|
|
ldtx de, DamageCheckIfHeadsXDamageText
|
|
call TossCoinATimes_BankB
|
|
call ATimes10
|
|
call SetDefiniteDamage
|
|
ret
|
|
; 0x2ebd7
|
|
|
|
RetreatAidEffect: ; 2ebd7 (b:6bd7)
|
|
scf
|
|
ret
|
|
; 0x2ebd9
|
|
|
|
DodrioRage_AIEffect: ; 2ebd9 (b:6bd9)
|
|
call DodrioRage_DamageBoostEffect
|
|
jp SetDefiniteAIDamage
|
|
; 0x2ebdf
|
|
|
|
DodrioRage_DamageBoostEffect: ; 2ebdf (b:6bdf)
|
|
ld e, PLAY_AREA_ARENA
|
|
call GetCardDamageAndMaxHP
|
|
call AddToDamage
|
|
ret
|
|
; 0x2ebe8
|
|
|
|
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
|
|
; 0x2ec0c
|
|
|
|
DragonairSlam_AIEffect: ; 2ec0c (b:6c0c)
|
|
ld a, (30 * 2) / 2
|
|
lb de, 0, 60
|
|
jp SetExpectedAIDamage
|
|
; 0x2ec14
|
|
|
|
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
|
|
; 0x2ec2c
|
|
|
|
DragonairHyperBeam_PlayerSelectEffect: ; 2ec2c (b:6c2c)
|
|
jp HandleEnergyDiscardEffectSelection
|
|
; 0x2ec2f
|
|
|
|
DragonairHyperBeam_AISelectEffect: ; 2ec2f (b:6c2f)
|
|
call AIPickEnergyCardToDiscardFromDefendingPokemon
|
|
ldh [hTemp_ffa0], a
|
|
ret
|
|
; 0x2ec35
|
|
|
|
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
|
|
; 0x2ec4f
|
|
|
|
; 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
|
|
; 0x2ec77
|
|
|
|
; return carry if Defending Pokemon has no attacks
|
|
ClefableMetronome_CheckAttacks: ; 2ec77 (b:6c77)
|
|
call CheckIfDefendingPokemonHasAnyAttack
|
|
ldtx hl, NoAttackMayBeChoosenText
|
|
ret
|
|
; 0x2ec7e
|
|
|
|
ClefableMetronome_AISelectEffect: ; 2ec7e (b:6c7e)
|
|
call HandleAIMetronomeEffect
|
|
ret
|
|
; 0x2ec82
|
|
|
|
ClefableMetronome_UseAttackEffect: ; 2ec82 (b:6c82)
|
|
ld a, 1 ; energy cost of this attack
|
|
call HandlePlayerMetronomeEffect
|
|
ret
|
|
; 0x2ec88
|
|
|
|
ClefableMinimizeEffect: ; 2ec88 (b:6c88)
|
|
ld a, SUBSTATUS1_REDUCE_BY_20
|
|
call ApplySubstatus1ToDefendingCard
|
|
ret
|
|
; 0x2ec8e
|
|
|
|
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
|
|
; 0x2ecd3
|
|
|
|
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
|
|
; 0x2ece9
|
|
|
|
PidgeottoWhirlwind_SwitchEffect: ; 2ece9 (b:6ce9)
|
|
ldh a, [hTemp_ffa0]
|
|
call HandleSwitchDefendingPokemonEffect
|
|
ret
|
|
; 0x2ecef
|
|
|
|
PidgeottoMirrorMove_AIEffect: ; 2ecef (b:6cef)
|
|
jp MirrorMoveEffects.AIEffect
|
|
; 0x2ecf2
|
|
|
|
PidgeottoMirrorMove_InitialEffect1: ; 2ecf2 (b:6cf2)
|
|
jp MirrorMoveEffects.InitialEffect1
|
|
; 0x2ecf5
|
|
|
|
PidgeottoMirrorMove_InitialEffect2: ; 2ecf5 (b:6cf5)
|
|
jp MirrorMoveEffects.InitialEffect2
|
|
; 0x2ecf8
|
|
|
|
PidgeottoMirrorMove_PlayerSelection: ; 2ecf8 (b:6cf8)
|
|
jp MirrorMoveEffects.PlayerSelection
|
|
; 0x2ecfb
|
|
|
|
PidgeottoMirrorMove_AISelection: ; 2ecfb (b:6cfb)
|
|
jp MirrorMoveEffects.AISelection
|
|
; 0x2ecfe
|
|
|
|
PidgeottoMirrorMove_BeforeDamage: ; 2ecfe (b:6cfe)
|
|
jp MirrorMoveEffects.BeforeDamage
|
|
; 0x2ed01
|
|
|
|
PidgeottoMirrorMove_AfterDamage: ; 2ed01 (b:6d01)
|
|
jp MirrorMoveEffects.AfterDamage
|
|
; 0x2ed04
|
|
|
|
SingEffect: ; 2ed04 (b:6d04)
|
|
call Sleep50PercentEffect
|
|
call nc, SetNoEffectFromStatus
|
|
ret
|
|
; 0x2ed0b
|
|
|
|
; return carry if Defending Pokemon has no attacks
|
|
ClefairyMetronome_CheckAttacks: ; 2ed0b (b:6d0b)
|
|
call CheckIfDefendingPokemonHasAnyAttack
|
|
ldtx hl, NoAttackMayBeChoosenText
|
|
ret
|
|
; 0x2ed12
|
|
|
|
ClefairyMetronome_AISelectEffect: ; 2ed12 (b:6d12)
|
|
call HandleAIMetronomeEffect
|
|
ret
|
|
; 0x2ed16
|
|
|
|
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, wLoadedMoveName
|
|
ld a, [hli]
|
|
ld h, [hl]
|
|
ld l, a
|
|
push hl
|
|
call SwapTurn
|
|
call CopyMoveDataAndDamage_FromDeckIndex
|
|
call SwapTurn
|
|
pop de
|
|
ld hl, wLoadedMoveName
|
|
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 [wPlayerAttackingMoveIndex], a
|
|
ld a, [wTempCardID_ccc2]
|
|
ld [wPlayerAttackingCardID], a
|
|
or a
|
|
ret
|
|
; 0x2ed86
|
|
|
|
; does nothing for AI.
|
|
HandleAIMetronomeEffect: ; 2ed86 (b:6d86)
|
|
ret
|
|
; 0x2ed87
|
|
|
|
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
|
|
; 0x2ed94
|
|
|
|
; return carry if no damage counters
|
|
FirstAid_DamageCheck: ; 2ed94 (b:6d94)
|
|
ld e, PLAY_AREA_ARENA
|
|
call GetCardDamageAndMaxHP
|
|
ldtx hl, NoDamageCountersText
|
|
cp 10
|
|
ret
|
|
; 0x2ed9f
|
|
|
|
FirstAid_HealEffect: ; 2ed9f (b:6d9f)
|
|
lb de, 0, 10
|
|
call ApplyAndAnimateHPRecovery
|
|
ret
|
|
; 0x2eda6
|
|
|
|
JigglypuffDoubleEdgeEffect: ; 2eda6 (b:6da6)
|
|
ld a, 20
|
|
call DealRecoilDamageToSelf
|
|
ret
|
|
; 0x2edac
|
|
|
|
PounceEffect: ; 2edac (b:6dac)
|
|
ld a, SUBSTATUS2_POUNCE
|
|
call ApplySubstatus2ToDefendingCard
|
|
ret
|
|
; 0x2edb2
|
|
|
|
LickitungSupersonicEffect: ; 2edb2 (b:6db2)
|
|
call Confusion50PercentEffect
|
|
call nc, SetNoEffectFromStatus
|
|
ret
|
|
; 0x2edb9
|
|
|
|
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
|
|
; 0x2edcf
|
|
|
|
PidgeyWhirlwind_SwitchEffect: ; 2edcf (b:6dcf)
|
|
ldh a, [hTemp_ffa0]
|
|
call HandleSwitchDefendingPokemonEffect
|
|
ret
|
|
; 0x2edd5
|
|
|
|
; 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
|
|
; 0x2eded
|
|
|
|
Conversion1_PlayerSelectEffect: ; 2eded (b:6ded)
|
|
ldtx hl, ChooseWeaknessYouWishToChangeText
|
|
xor a ; PLAY_AREA_ARENA
|
|
call HandleColorChangeScreen
|
|
ldh [hTemp_ffa0], a
|
|
ret
|
|
; 0x2edf7
|
|
|
|
Conversion1_AISelectEffect: ; 2edf7 (b:6df7)
|
|
call AISelectConversionColor
|
|
ret
|
|
; 0x2edfb
|
|
|
|
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
|
|
; 0x2ee1f
|
|
|
|
; 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
|
|
; 0x2ee31
|
|
|
|
Conversion2_PlayerSelectEffect: ; 2ee31 (b:6e31)
|
|
ldtx hl, ChooseResistanceYouWishToChangeText
|
|
ld a, $80
|
|
call HandleColorChangeScreen
|
|
ldh [hTemp_ffa0], a
|
|
ret
|
|
; 0x2ee3c
|
|
|
|
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
|
|
; 0x2ee5e
|
|
|
|
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
|
|
; 0x2ee7f
|
|
|
|
; 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 _CheckIfEnoughEnergiesToMove
|
|
jr nc, .found
|
|
ld e, SECOND_ATTACK
|
|
bank1call _CheckIfEnoughEnergiesToMove
|
|
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
|
|
; 0x2eee7
|
|
|
|
ScrunchEffect: ; 2eee7 (b:6ee7)
|
|
ldtx de, IfHeadsNoDamageNextTurnText
|
|
call TossCoin_BankB
|
|
jp nc, SetWasUnsuccessful
|
|
ld a, ATK_ANIM_SCRUNCH
|
|
ld [wLoadedMoveAnimation], a
|
|
ld a, SUBSTATUS1_NO_DAMAGE_17
|
|
call ApplySubstatus1ToDefendingCard
|
|
ret
|
|
; 0x2eefb
|
|
|
|
ChanseyDoubleEdgeEffect: ; 2eefb (b:6efb)
|
|
ld a, 80
|
|
call DealRecoilDamageToSelf
|
|
ret
|
|
; 0x2ef01
|
|
|
|
SuperFang_AIEffect: ; 2ef01 (b:6f01)
|
|
call SuperFang_HalfHPEffect
|
|
jp SetDefiniteAIDamage
|
|
; 0x2ef07
|
|
|
|
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
|
|
; 0x2ef18
|
|
|
|
; 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
|
|
; 0x2ef27
|
|
|
|
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
|
|
; 0x2ef3c
|
|
|
|
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
|
|
; 0x2ef51
|
|
|
|
HealingWind_InitialEffect: ; 2ef51 (b:6f51)
|
|
scf
|
|
ret
|
|
; 0x2ef53
|
|
|
|
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 PlayMoveAnimation
|
|
bank1call WaitMoveAnimation
|
|
ld a, ATK_ANIM_HEALING_WIND_PLAY_AREA
|
|
ld [wLoadedMoveAnimation], 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 PlayMoveAnimation
|
|
bank1call WaitMoveAnimation
|
|
.next_pkmn
|
|
pop de
|
|
inc e
|
|
dec d
|
|
jr nz, .loop_play_area
|
|
|
|
ret
|
|
; 0x2ef9c
|
|
|
|
Dragonite1Slam_AIEffect: ; 2ef9c (b:6f9c)
|
|
ld a, (30 * 2) / 2
|
|
lb de, 0, 60
|
|
jp SetExpectedAIDamage
|
|
; 0x2efa4
|
|
|
|
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
|
|
; 0x2efbc
|
|
|
|
; 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
|
|
; 0x2efce
|
|
|
|
; 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
|
|
; 0x2efe0
|
|
|
|
CatPunchEffect: ; 2efe0 (b:6fe0)
|
|
call SwapTurn
|
|
call PickRandomPlayAreaCard
|
|
ld b, a
|
|
ld a, ATK_ANIM_CAT_PUNCH_PLAY_AREA
|
|
ld [wLoadedMoveAnimation], a
|
|
ld de, 20
|
|
call DealDamageToPlayAreaPokemon
|
|
call SwapTurn
|
|
ret
|
|
; 0x2eff6
|
|
|
|
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
|
|
; 0x2f06a
|
|
|
|
; 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
|
|
; 0x2f098
|
|
|
|
; 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
|
|
; 0x2f0bf
|
|
|
|
SlicingWindEffect: ; 2f0bf (b:70bf)
|
|
call SwapTurn
|
|
call PickRandomPlayAreaCard
|
|
ld b, a
|
|
ld de, 30
|
|
call DealDamageToPlayAreaPokemon_RegularAnim
|
|
call SwapTurn
|
|
ret
|
|
; 0x2f0d0
|
|
|
|
Gale_LoadAnimation: ; 2f0d0 (b:70d0)
|
|
ld a, ATK_ANIM_GALE
|
|
ld [wLoadedMoveAnimation], a
|
|
ret
|
|
; 0x2f0d6
|
|
|
|
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
|
|
; 0x2f10d
|
|
|
|
; 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
|
|
; 0x2f119
|
|
|
|
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
|
|
; 0x2f153
|
|
|
|
ExpandEffect: ; 2f153 (b:7153)
|
|
ld a, SUBSTATUS1_REDUCE_BY_10
|
|
call ApplySubstatus1ToDefendingCard
|
|
ret
|
|
; 0x2f159
|
|
|
|
; 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
|
|
; 0x2f167
|
|
|
|
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
|
|
; 0x2f1b5
|
|
|
|
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
|
|
; 0x2f1c4
|
|
|
|
; 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
|
|
; 0x2f1e7
|
|
|
|
; 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
|
|
; 0x2f216
|
|
|
|
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
|
|
; 0x2f252
|
|
|
|
; returns carry if opponent has no energy cards attached
|
|
EnergyRemoval_EnergyCheck: ; 2f252 (b:7252)
|
|
call SwapTurn
|
|
call CheckIfThereAreAnyEnergyCardsAttached
|
|
ldtx hl, NoEnergyAttachedToOpponentsActiveText
|
|
call SwapTurn
|
|
ret
|
|
; 0x2f25f
|
|
|
|
EnergyRemoval_PlayerSelection: ; 2f25f (b:725f)
|
|
ldtx hl, ChoosePokemonToRemoveEnergyFromText
|
|
call DrawWideTextBox_WaitForInput
|
|
call SwapTurn
|
|
call HandlePokemonAndEnergySelectionScreen
|
|
call SwapTurn
|
|
ret
|
|
; 0x2f26f
|
|
|
|
EnergyRemoval_AISelection: ; 2f26f (b:726f)
|
|
call AIPickEnergyCardToDiscardFromDefendingPokemon
|
|
ret
|
|
; 0x2f273
|
|
|
|
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
|
|
; 0x2f28e
|
|
|
|
; 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
|
|
; 0x2f2a0
|
|
|
|
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
|
|
; 0x2f2b9
|
|
|
|
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
|
|
; 0x2f2f8
|
|
|
|
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
|
|
; 0x2f31c
|
|
|
|
; 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
|
|
; 0x2f328
|
|
|
|
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
|
|
; 0x2f372
|
|
|
|
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
|
|
; 0x2f3a1
|
|
|
|
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
|
|
; 0x2f3ca
|
|
|
|
Potion_DamageCheck: ; 2f3ca (b:73ca)
|
|
call CheckIfPlayAreaHasAnyDamage
|
|
ldtx hl, NoPokemonWithDamageCountersText
|
|
ret
|
|
; 0x2f3d1
|
|
|
|
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
|
|
; 0x2f3ef
|
|
|
|
Potion_HealEffect: ; 2f3ef (b:73ef)
|
|
ldh a, [hTemp_ffa0]
|
|
ldh [hTempPlayAreaLocation_ff9d], a
|
|
ldh a, [hTempPlayAreaLocation_ffa1]
|
|
call HealPlayAreaCardHP
|
|
ret
|
|
; 0x2f3f9
|
|
|
|
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
|
|
; 0x2f43b
|
|
|
|
; 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
|
|
; 0x2f44a
|
|
|
|
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
|
|
; 0x2f463
|
|
|
|
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
|
|
; 0x2f488
|
|
|
|
Defender_PlayerSelection: ; 2f488 (b:7488)
|
|
ldtx hl, ChoosePokemonToAttachDefenderToText
|
|
call DrawWideTextBox_WaitForInput
|
|
bank1call HasAlivePokemonInPlayArea
|
|
bank1call OpenPlayAreaScreenForSelection
|
|
ldh a, [hTempPlayAreaLocation_ff9d]
|
|
ldh [hTemp_ffa0], a
|
|
ret
|
|
; 0x2f499
|
|
|
|
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
|
|
; 0x2f4b3
|
|
|
|
; 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
|
|
; 0x2f4bf
|
|
|
|
MysteriousFossil_PlaceInPlayAreaEffect: ; 2f4bf (b:74bf)
|
|
ldh a, [hTempCardIndex_ff9f]
|
|
call PutHandPokemonCardInPlayArea
|
|
ret
|
|
; 0x2f4c5
|
|
|
|
; 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
|
|
; 0x2f4d1
|
|
|
|
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
|
|
; 0x2f4e1
|
|
|
|
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
|
|
; 0x2f513
|
|
|
|
; 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
|
|
; 0x2f52a
|
|
|
|
ComputerSearch_PlayerDiscardHandSelection: ; 2f52a (b:752a)
|
|
call HandlePlayerSelection2HandCardsToDiscard
|
|
ret
|
|
; 0x2f52e
|
|
|
|
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
|
|
; 0x2f545
|
|
|
|
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
|
|
; 0x2f561
|
|
|
|
; 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
|
|
; 0x2f56d
|
|
|
|
ClefairyDoll_PlaceInPlayAreaEffect: ; 2f56d (b:756d)
|
|
ldh a, [hTempCardIndex_ff9f]
|
|
call PutHandPokemonCardInPlayArea
|
|
ret
|
|
; 0x2f573
|
|
|
|
; 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
|
|
; 0x2f57e
|
|
|
|
MrFuji_PlayerSelection: ; 2f57e (b:757e)
|
|
ldtx hl, ChoosePokemonToReturnToTheDeckText
|
|
call DrawWideTextBox_WaitForInput
|
|
bank1call HasAlivePokemonInBench
|
|
bank1call OpenPlayAreaScreenForSelection
|
|
ldh a, [hTempPlayAreaLocation_ff9d]
|
|
ldh [hTemp_ffa0], a
|
|
ret
|
|
; 0x2f58f
|
|
|
|
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
|
|
; 0x2f5e0
|
|
|
|
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
|
|
; 0x2f5ee
|
|
|
|
; 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
|
|
; 0x2f5f9
|
|
|
|
Switch_PlayerSelection: ; 2f5f9 (b:75f9)
|
|
ldtx hl, SelectPkmnOnBenchToSwitchWithActiveText
|
|
call DrawWideTextBox_WaitForInput
|
|
bank1call HasAlivePokemonInBench
|
|
bank1call OpenPlayAreaScreenForSelection
|
|
ldh a, [hTempPlayAreaLocation_ff9d]
|
|
ldh [hTemp_ffa0], a
|
|
ret
|
|
; 0x2f60a
|
|
|
|
Switch_SwitchEffect: ; 2f60a (b:760a)
|
|
ldh a, [hTemp_ffa0]
|
|
ld e, a
|
|
call SwapArenaWithBenchPokemon
|
|
ret
|
|
; 0x2f611
|
|
|
|
PokemonCenter_DamageCheck: ; 2f611 (b:7611)
|
|
call CheckIfPlayAreaHasAnyDamage
|
|
ldtx hl, NoPokemonWithDamageCountersText
|
|
ret
|
|
; 0x2f618
|
|
|
|
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
|
|
; 0x2f659
|
|
|
|
; 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
|
|
; 0x2f672
|
|
|
|
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
|
|
; 0x2f68f
|
|
|
|
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
|
|
; 0x2f6b3
|
|
|
|
PokemonBreeder_HandPlayAreaCheck: ; 2f6b3 (b:76b3)
|
|
call CreatePlayableStage2PokemonCardListFromHand
|
|
jr c, .cannot_evolve
|
|
bank1call IsPrehistoricPowerActive
|
|
ret
|
|
.cannot_evolve
|
|
ldtx hl, ConditionsForEvolvingToStage2NotFulfilledText
|
|
scf
|
|
ret
|
|
; 0x2f6c1
|
|
|
|
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
|
|
; 0x2f6f4
|
|
|
|
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
|
|
; 0x2f73e
|
|
|
|
; 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
|
|
; 0x2f795
|
|
|
|
; 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
|
|
; 0x2f7a0
|
|
|
|
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
|
|
; 0x2f7c3
|
|
|
|
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
|
|
; 0x2f826
|
|
|
|
; 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
|
|
; 0x2f838
|
|
|
|
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
|
|
; 0x2f853
|
|
|
|
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
|
|
; 0x2f88d
|
|
|
|
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
|
|
; 0x2f8b6
|
|
|
|
; 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
|
|
; 0x2f8e1
|
|
|
|
; 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
|
|
; 0x2f8ed
|
|
|
|
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
|
|
; 0x2f9aa
|
|
|
|
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
|
|
; 0x2f9c4
|
|
|
|
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
|
|
; 0x2f9e3
|
|
|
|
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
|
|
; 0x2fa31
|
|
|
|
.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
|
|
; 0x2fa4f
|
|
|
|
.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
|
|
; 0x2fa70
|
|
|
|
; 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
|
|
; 0x2fa7b
|
|
|
|
Maintenance_PlayerSelection: ; 2fa7b (b:7a7b)
|
|
ldtx hl, Choose2HandCardsFromHandToReturnToDeckText
|
|
ldtx de, ChooseTheCardToPutBackText
|
|
call HandlePlayerSelection2HandCards
|
|
ret
|
|
; 0x2fa85
|
|
|
|
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
|
|
; 0x2faad
|
|
|
|
; 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
|
|
; 0x2fab9
|
|
|
|
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
|
|
; 0x2fb15
|
|
|
|
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
|
|
; 0x2fb36
|
|
|
|
; 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
|
|
; 0x2fb41
|
|
|
|
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
|
|
; 0x2fb68
|
|
|
|
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
|
|
; 0x2fb80
|
|
|
|
; 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
|
|
; 0x2fb93
|
|
|
|
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
|
|
; 0x2fbb0
|
|
|
|
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
|
|
; 0x2fbd6
|
|
|
|
; 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
|
|
; 0x2fc0b
|
|
|
|
; 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
|
|
; 0x2fc24
|
|
|
|
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
|
|
; 0x2fc99
|
|
|
|
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
|
|
; 0x2fcd0
|
|
|
|
; 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
|
|
; 0x2fce4
|
|
|
|
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 [wcbfa], 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, [wcbfb]
|
|
push af
|
|
ldh a, [hTempPlayAreaLocation_ff9d]
|
|
bank1call DisplayEnergyDiscardScreen
|
|
ld a, 2
|
|
ld [wcbfa], a
|
|
pop af
|
|
ld [wcbfb], 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, wcbfb
|
|
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
|
|
; 0x2fd73
|
|
|
|
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
|
|
; 0x2fda4
|
|
|
|
; 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
|
|
; 0x2fdb6
|
|
|
|
SuperEnergyRetrieval_PlayerHandSelection: ; 2fdb6 (b:7db6)
|
|
call HandlePlayerSelection2HandCardsToDiscard
|
|
ret
|
|
; 0x2fdba
|
|
|
|
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
|
|
; 0x2fdfa
|
|
|
|
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
|
|
; 0x2fe25
|
|
|
|
; 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
|
|
; 0x2fe34
|
|
|
|
; 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
|
|
; 0x2fe6e
|
|
|
|
; 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
|
|
; 0x2fe79
|
|
|
|
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
|
|
; 0x2fe90
|
|
|
|
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
|
|
; 0x2fea9
|
|
|
|
; input:
|
|
; a = attack animation to play
|
|
Func_2fea9: ; 2fea9 (b:7ea9)
|
|
ld [wLoadedMoveAnimation], a
|
|
bank1call Func_7415
|
|
ld bc, $0
|
|
ldh a, [hWhoseTurn]
|
|
ld h, a
|
|
bank1call PlayMoveAnimation
|
|
bank1call WaitMoveAnimation
|
|
ret
|
|
; 0x2febc
|
|
|
|
; 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 [wLoadedMoveAnimation], a
|
|
ldh a, [hTempPlayAreaLocation_ff9d]
|
|
ld b, a
|
|
ld c, $01
|
|
ldh a, [hWhoseTurn]
|
|
ld h, a
|
|
bank1call PlayMoveAnimation
|
|
bank1call WaitMoveAnimation
|
|
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
|
|
; 0x2ff03
|
|
|
|
rept $fd
|
|
db $ff
|
|
endr
|