summaryrefslogtreecommitdiff
path: root/src/engine
diff options
context:
space:
mode:
authorxCrystal <rgr.crystal@gmail.com>2019-07-25 15:33:28 +0200
committerGitHub <noreply@github.com>2019-07-25 15:33:28 +0200
commitd2917adab14ca8ff842ddc6430acb20e11636361 (patch)
tree5895876e715fb66d83593a3d8282c404b871115d /src/engine
parent618a904a49ebe85e4c66c0081c71b7626baff7e6 (diff)
parentb7ee18f262b1d88582fdc55879f1abaad17cc5ce (diff)
Merge branch 'master' into master
Diffstat (limited to 'src/engine')
-rw-r--r--src/engine/bank01.asm733
-rw-r--r--src/engine/bank02.asm2004
-rw-r--r--src/engine/bank06.asm33
-rw-r--r--src/engine/bank07.asm2
-rw-r--r--src/engine/bank08.asm2
-rw-r--r--src/engine/effect_functions.asm295
-rw-r--r--src/engine/home.asm223
7 files changed, 2889 insertions, 403 deletions
diff --git a/src/engine/bank01.asm b/src/engine/bank01.asm
index ed02786..222ccf4 100644
--- a/src/engine/bank01.asm
+++ b/src/engine/bank01.asm
@@ -346,7 +346,7 @@ DuelMainInterface: ; 426d (1:426d)
cp DUELIST_TYPE_PLAYER
jr z, PrintDuelMenuAndHandleInput
cp DUELIST_TYPE_LINK_OPP
- jp z, Func_6911
+ jp z, DoLinkOpponentTurn
; DUELIST_TYPE_AI_OPP
xor a
ld [wVBlankCounter], a
@@ -417,8 +417,8 @@ DuelMenuFunctionTable: ; 42f1 (1:42f1)
Func_42fd: ; 42fd (1:42fd)
call DrawCardFromDeck
call nc, AddCardToHand
- ld a, $0b
- call SetAIAction_SerialSendDuelData
+ ld a, OPPACTION_DRAW_CARD
+ call SetOppAction_SerialSendDuelData
jp PrintDuelMenuAndHandleInput.menu_items_printed
; 0x430b
@@ -466,18 +466,17 @@ OpenNonTurnHolderDiscardPileScreen: ; 4339 (1:4339)
OpenTurnHolderDiscardPileScreen: ; 4342 (1:4342)
jp OpenDiscardPileScreen
-; draw the non-turn holder's hand screen.
-; simpler version of OpenPlayerHandScreen where any selected card is directly submitted
-; and the duelist could also be the opponent.
+; draw the non-turn holder's hand screen. simpler version of OpenPlayerHandScreen
+; used only for checking the cards rather than for playing them.
OpenNonTurnHolderHandScreen_Simple: ; 4345 (1:4345)
call SwapTurn
call OpenTurnHolderHandScreen_Simple
jp SwapTurn
; 0x434e
-; draw the turn holder's hand screen.
-; simpler version of OpenPlayerHandScreen where any selected card is directly submitted
-; and the duelist could also be the opponent.
+; draw the turn holder's hand screen. simpler version of OpenPlayerHandScreen
+; used only for checking the cards rather than for playing them.
+; used for example in the "Your Play Area" screen of the Check menu
OpenTurnHolderHandScreen_Simple: ; 434e (1:434e)
call CreateHandCardList
jr c, .no_cards_in_hand
@@ -533,8 +532,8 @@ DuelMenu_Done: ; 439a (1:439a)
call DoPracticeDuelAction
; always jumps on practice duel (no action requires player to select Done)
jp c, RestartPracticeDuelTurn
- ld a, $05
- call SetAIAction_SerialSendDuelData
+ ld a, OPPACTION_FINISH_NO_ATTACK
+ call SetOppAction_SerialSendDuelData
call ClearNonTurnTemporaryDuelvars
ret
@@ -560,8 +559,8 @@ DuelMenu_Retreat: ; 43ab (1:43ab)
ld [wBenchSelectedPokemon], a
ld a, [wBenchSelectedPokemon]
ldh [hTempPlayAreaLocation_ffa1], a
- ld a, $04
- call SetAIAction_SerialSendDuelData
+ ld a, OPPACTION_ATTEMPT_RETREAT
+ call SetOppAction_SerialSendDuelData
call AttemptRetreat
jr nc, .done
call DrawDuelMainScene
@@ -592,8 +591,8 @@ DuelMenu_Retreat: ; 43ab (1:43ab)
call ReturnRetreatCostCardsToArena
pop af
jp c, DuelMainInterface
- ld a, $04
- call SetAIAction_SerialSendDuelData
+ ld a, OPPACTION_ATTEMPT_RETREAT
+ call SetOppAction_SerialSendDuelData
call AttemptRetreat
.done
@@ -637,18 +636,18 @@ OpenPlayerHandScreen: ; 4436 (1:4436)
bit TYPE_TRAINER_F, c
jr nz, .trainer_card
bit TYPE_ENERGY_F, c
- jr nz, UseEnergyCard
- call UsePokemonCard
+ jr nz, PlayEnergyCard
+ call PlayPokemonCard
jr c, ReloadCardListScreen ; jump if card not played
jp DuelMainInterface
.trainer_card
- call UseTrainerCard
+ call PlayTrainerCard
jr c, ReloadCardListScreen ; jump if card not played
jp DuelMainInterface
-; use the energy card with deck index at hTempCardIndex_ff98
+; play the energy card with deck index at hTempCardIndex_ff98
; c contains the type of energy card being played
-UseEnergyCard: ; 4477 (1:4477)
+PlayEnergyCard: ; 4477 (1:4477)
ld a, c
cp TYPE_ENERGY_WATER
jr nz, .not_water_energy
@@ -673,8 +672,8 @@ UseEnergyCard: ; 4477 (1:4477)
ldh [hTemp_ffa0], a
call PutHandCardInPlayArea
call PrintPlayAreaCardList_EnableLCD
- ld a, $03
- call SetAIAction_SerialSendDuelData
+ ld a, OPPACTION_PLAY_ENERGY
+ call SetOppAction_SerialSendDuelData
call PrintAttachedEnergyToPokemon
jp DuelMainInterface
@@ -704,11 +703,11 @@ ReloadCardListScreen: ; 44d2 (1:44d2)
jp OpenPlayerHandScreen.handle_input
; 0x44db
-; use a basic Pokemon card on the arena or bench, or place an stage 1 or 2
+; place a basic Pokemon card on the arena or bench, or place an stage 1 or 2
; Pokemon card over a Pokemon card already in play to evolve it.
; the card to use is loaded in wLoadedCard1 and its deck index is at hTempCardIndex_ff98.
; return nc if the card was played, carry if it wasn't.
-UsePokemonCard: ; 44db (1:44db)
+PlayPokemonCard: ; 44db (1:44db)
ld a, [wLoadedCard1Stage]
or a ; BASIC
jr nz, .try_evolve ; jump if the card being played is a Stage 1 or 2 Pokemon
@@ -723,8 +722,8 @@ UsePokemonCard: ; 44db (1:44db)
add DUELVARS_ARENA_CARD_STAGE
call GetTurnDuelistVariable
ld [hl], BASIC
- ld a, $01
- call SetAIAction_SerialSendDuelData
+ ld a, OPPACTION_PLAY_BASIC_PKMN
+ call SetOppAction_SerialSendDuelData
ldh a, [hTempCardIndex_ff98]
call LoadCardDataToBuffer1_FromDeckIndex
ld a, 20
@@ -794,8 +793,8 @@ UsePokemonCard: ; 44db (1:44db)
ldh [hTempPlayAreaLocation_ffa1], a
call EvolvePokemonCard
jr c, .try_evolve_loop ; jump if evolution wasn't successsful somehow
- ld a, $02
- call SetAIAction_SerialSendDuelData
+ ld a, OPPACTION_EVOLVE_PKMN
+ call SetOppAction_SerialSendDuelData
call PrintPlayAreaCardList_EnableLCD
call PrintPokemonEvolvedIntoPokemon
call Func_161e
@@ -812,7 +811,7 @@ UsePokemonCard: ; 44db (1:44db)
; triggered by selecting the "Check" item in the duel menu
DuelMenu_Check: ; 4585 (1:4585)
call Func_3b31
- call Func_3096
+ call OpenDuelCheckMenu
jp DuelMainInterface
; triggered by pressing SELECT in the duel menu
@@ -853,7 +852,7 @@ CheckAbleToRetreat: ; 45bb (1:45bb)
ret c
call CheckIfActiveCardParalyzedOrAsleep
ret c
- call HasAlivePokemonOnBench
+ call HasAlivePokemonInBench
jr c, .unable_to_retreat
ld a, DUELVARS_ARENA_CARD
call GetTurnDuelistVariable
@@ -1546,7 +1545,7 @@ Func_49a8: ; 49a8 (1:49a8)
call DoFrame
call CheckSkipDelayAllowed
jr c, .asm_49c6
- call Func_3b52
+ call CheckAnyAnimationPlaying
jr c, .asm_49b9
.asm_49c6
call Func_3b31
@@ -2213,19 +2212,19 @@ Func_4e6e: ; 4e6e (1:4e6e)
ld b, $52
ld c, $57
.asm_4e7c
- ld hl, $63
- ld de, $67
+ ldtx hl, ShufflesTheDeckText
+ ldtx de, Drew7CardsText
jr Func_4e98
Func_4e84: ; 4e84 (1:4e84)
ld b, $53
ld c, $55
- ld hl, $65
- ld de, $66
+ ldtx hl, EachPlayerShuffleOpponentsDeckText
+ ldtx de, EachPlayerDraw7CardsText
ld a, [wDuelType]
cp DUELTYPE_PRACTICE
jr nz, Func_4e98
- ld hl, $64
+ ldtx hl, ThisIsJustPracticeDoNotShuffleText
; fallthrough
Func_4e98: ; 4e98 (1:4e98)
@@ -2243,10 +2242,10 @@ Func_4e98: ; 4e98 (1:4e98)
call EnableLCD
ld a, [wDuelType]
cp DUELTYPE_PRACTICE
- jr nz, .asm_4ebf
+ jr nz, .not_practice
call WaitForWideTextBoxInput
jr .asm_4ee0
-.asm_4ebf
+.not_practice
call Func_3b21
ld hl, sp+$03
ld a, [hl]
@@ -2259,7 +2258,7 @@ Func_4e98: ; 4e98 (1:4e98)
call DoFrame
call CheckSkipDelayAllowed
jr c, .asm_4edd
- call Func_3b52
+ call CheckAnyAnimationPlaying
jr c, .asm_4ed0
.asm_4edd
call Func_3b31
@@ -2278,7 +2277,7 @@ Func_4e98: ; 4e98 (1:4e98)
call DoFrame
call CheckSkipDelayAllowed
jr c, .asm_4f28
- call Func_3b52
+ call CheckAnyAnimationPlaying
jr c, .asm_4ef4
ld hl, wNumCardsBeingDrawn
inc [hl]
@@ -2343,7 +2342,7 @@ Func_4f2d: ; 4f2d (1:4f2d)
call DoFrame
call CheckSkipDelayAllowed
jr c, .asm_4f7d
- call Func_3b52
+ call CheckAnyAnimationPlaying
jr c, .asm_4f70
.asm_4f7d
call Func_3b31
@@ -2465,7 +2464,7 @@ DrawDuelHUDs: ; 503a (1:503a)
inc c
call CheckPrintPoisoned
inc c
- call CheckPrintDoublePoisoned
+ call CheckPrintDoublePoisoned ; if double poisoned, print a second poison icon
call SwapTurn
lb de, 7, 0 ; coordinates for opponent's arena card name and info icons
lb bc, 3, 1 ; coordinates for opponent's attached energies and HP bar
@@ -2478,7 +2477,7 @@ DrawDuelHUDs: ; 503a (1:503a)
dec c
call CheckPrintPoisoned
dec c
- call CheckPrintDoublePoisoned
+ call CheckPrintDoublePoisoned ; if double poisoned, print a second poison icon
call SwapTurn
ret
; 0x5093
@@ -2795,7 +2794,7 @@ PracticeDuel_ReplaceKnockedOutPokemon: ; 52b0 (1:52b0)
cp PLAY_AREA_BENCH_1
ret z
; if player selected Drowzee instead (which is at PLAY_AREA_BENCH_2)
- call HasAlivePokemonOnBench
+ call HasAlivePokemonInBench
ldtx hl, SelectStaryuPracticeDuelText
scf
; fallthrough
@@ -3701,8 +3700,100 @@ DisplayCardPageOnLeftOrRightPressed: ; 57cd (1:57cd)
ret
; 0x57df
-Func_57df:
- INCROM $57df, $5892
+Func_57df: ; 57df (1:57df)
+ push hl
+ call EmptyScreen
+ lb de, 0, 0
+ lb bc, 20, 18
+ call DrawRegularTextBox
+ ld a, 19
+ lb de, 1, 1
+ call InitTextPrintingInTextbox
+ call SetNoLineSeparation
+ pop hl
+ call ProcessTextFromID
+ call EnableLCD
+ call SetOneLineSeparation
+ call WaitForWideTextBoxInput
+ ret
+; 0x5805
+
+Func_5805: ; 5805 (1:5805)
+ call Func_3b31
+ ld a, [wccc8]
+ ld l, a
+ ld h, $00
+ call LoadTxRam3
+ ld a, DUELVARS_DUELIST_TYPE
+ call GetTurnDuelistVariable
+ cp DUELIST_TYPE_PLAYER
+ jr nz, .opponent
+
+ ldtx hl, WillDrawNPrizesText
+ call DrawWideTextBox_WaitForInput
+ ld a, [wccc8]
+ call Func_310a
+ ld hl, hTemp_ffa0
+ ld d, [hl]
+ inc hl
+ ld e, [hl]
+ call SerialSend8Bytes
+.asm_582f
+ call ExchangeRNG
+ ld a, DUELVARS_PRIZES
+ call GetTurnDuelistVariable
+ or a
+ ret nz
+ scf
+ ret
+
+.opponent
+ call Func_588a
+ ldtx hl, WillDrawNPrizesText
+ call DrawWideTextBox_PrintText
+ call CountPrizes
+ ld [wcbfc], a
+ ld a, DUELVARS_DUELIST_TYPE
+ call GetTurnDuelistVariable
+ cp DUELIST_TYPE_LINK_OPP
+ jr z, .link_opponent
+ call Func_2bd7
+ ld c, DECK_SIZE
+.asm_5858
+ call DoFrame
+ dec c
+ jr nz, .asm_5858
+ jr .asm_586f
+
+.link_opponent
+ call SerialRecv8Bytes
+ ld a, DUELVARS_PRIZES
+ call GetTurnDuelistVariable
+ ld [hl], d
+ ld a, e
+ cp $ff
+ call nz, AddCardToHand
+.asm_586f
+ ld a, [wcbfc]
+ ld hl, wccc8
+ cp [hl]
+ jr nc, .asm_587e
+ ld l, a
+ ld h, $00
+ call LoadTxRam3
+.asm_587e
+ farcall Func_82b6
+ ldtx hl, DrewNPrizesText
+ call DrawWideTextBox_WaitForInput
+ jr .asm_582f
+; 0x588a
+
+Func_588a: ; 588a (1:588a)
+ ld l, PLAYER_TURN
+ ldh a, [hWhoseTurn]
+ ld h, a
+ jp DrawYourOrOppPlayAreaScreen_Bank0
+; 0x5892
; display the previous valid card page
DisplayPreviousCardPage: ; 5892 (1:5892)
@@ -4986,7 +5077,7 @@ PrintPokemonCardLength: ; 5f9a (1:5f9a)
; return carry if the turn holder has any Pokemon with non-zero HP on the bench.
; return how many Pokemon with non-zero HP in b.
; does this by calculating how many Pokemon in play area minus one
-HasAlivePokemonOnBench: ; 5fd9 (1:5fd9)
+HasAlivePokemonInBench: ; 5fd9 (1:5fd9)
ld a, $01
jr _HasAlivePokemonInPlayArea
@@ -5187,7 +5278,7 @@ Func_60dd: ; 60dd (1:60dd)
and SELECT
jr z, .asm_60f2
.asm_6119
- call HasAlivePokemonOnBench
+ call HasAlivePokemonInBench
ld a, $01
ld [wcbd4], a
.asm_6121
@@ -5199,7 +5290,7 @@ Func_60dd: ; 60dd (1:60dd)
jr z, .asm_6119
or a
jr z, .asm_6132
- call Func_3096
+ call OpenDuelCheckMenu
jr .asm_60f2
.asm_6132
call OpenTurnHolderHandScreen_Simple
@@ -5646,9 +5737,9 @@ CheckPrintPoisoned: ; 63bb (1:63bb)
; given a card's status in a, print the Poison symbol at bc if it's double poisoned
CheckPrintDoublePoisoned: ; 63c7 (1:63c7)
push af
- and DOUBLE_POISONED - POISONED
- jr nz, CheckPrintPoisoned.poison ; double poison (print a second symbol)
- jr CheckPrintPoisoned.print ; not double poisoned
+ and DOUBLE_POISONED & (POISONED ^ $ff)
+ jr nz, CheckPrintPoisoned.poison ; double poisoned (print SYM_POISONED)
+ jr CheckPrintPoisoned.print ; not double poisoned (print SYM_SPACE)
; 0x63ce
; given a card's status in a, print the Confusion, Sleep, or Paralysis symbol at bc
@@ -5796,8 +5887,9 @@ ReturnRetreatCostCardsToArena: ; 6564 (1:6564)
jr .loop
; 0x657a
-; discard retreat cost energy cards and attempt retreat.
+; discard retreat cost energy cards and attempt retreat of the arena card.
; return carry if unable to retreat this turn due to unsuccessful confusion check
+; if successful, the retreated card is replaced with a bench Pokemon card
AttemptRetreat: ; 657a (1:657a)
call DiscardRetreatCostCards
ldh a, [hTemp_ffa0]
@@ -5935,7 +6027,9 @@ DrawHPBar: ; 6614 (1:6614)
ret
; 0x6635
-Func_6635: ; 6635 (1:6635)
+; when an opponent's Pokemon card attacks, this displays a screen
+; containing the description and information of the used move
+DisplayOpponentUsedMoveScreen: ; 6635 (1:6635)
call ZeroObjectPositionsAndToggleOAMCopy
call EmptyScreen
call LoadDuelCardSymbolTiles
@@ -6118,7 +6212,7 @@ DuelDataToSave: ; 6729 (1:6729)
; dw address, number_of_bytes_to_copy
dw wPlayerDuelVariables, wOpponentDuelVariables - wPlayerDuelVariables
dw wOpponentDuelVariables, wPlayerDeck - wOpponentDuelVariables
- dw wPlayerDeck, wNameBuffer + $10 - wPlayerDeck
+ dw wPlayerDeck, wDuelTempList - wPlayerDeck
dw wWhoseTurn, wDuelTheme + $1 - wWhoseTurn
dw hWhoseTurn, $1
dw wRNG1, wRNGCounter + $1 - wRNG1
@@ -6228,10 +6322,11 @@ CheckSkipDelayAllowed: ; 67b2 (1:67b2)
ret
; 0x67be
-; related to ai taking their turn in a duel
-; called multiple times during one ai turn
+; related to AI taking their turn in a duel
+; called multiple times during one AI turn
+; each call results in the execution of an OppActionTable function
AIMakeDecision: ; 67be (1:67be)
- ldh [hAIActionTableIndex], a
+ ldh [hOppActionTableIndex], a
ld hl, wSkipDuelistIsThinkingDelay
ld a, [hl]
ld [hl], $0
@@ -6244,13 +6339,13 @@ AIMakeDecision: ; 67be (1:67be)
jr c, .delay_loop
.skip_delay
- ldh a, [hAIActionTableIndex]
- ld hl, wAITurnEnded
+ ldh a, [hOppActionTableIndex]
+ ld hl, wOpponentTurnEnded
ld [hl], 0
- ld hl, AIActionTable
+ ld hl, OppActionTable
call JumpToFunctionInTable
ld a, [wDuelFinished]
- ld hl, wAITurnEnded
+ ld hl, wOpponentTurnEnded
or [hl]
jr nz, .turn_ended
ld a, [wSkipDuelistIsThinkingDelay]
@@ -6297,7 +6392,7 @@ Func_67fb: ; 67fb (1:67fb)
ld a, [wCurrentDuelMenuItem]
or a
jr z, .asm_6839
- call Func_3096
+ call OpenDuelCheckMenu
jr .asm_6829
.asm_6839
call OpenTurnHolderHandScreen_Simple
@@ -6439,12 +6534,14 @@ PrintPokemonEvolvedIntoPokemon: ; 68fa (1:68fa)
ret
; 0x6911
-Func_6911: ; 6911 (1:6911)
+; handle the opponent's turn in a link duel
+; loop until either [wOpponentTurnEnded] or [wDuelFinished] is non-0
+DoLinkOpponentTurn: ; 6911 (1:6911)
xor a
- ld [wAITurnEnded], a
+ ld [wOpponentTurnEnded], a
xor a
ld [wSkipDuelistIsThinkingDelay], a
-.asm_6919
+.link_opp_turn_loop
ld a, [wSkipDuelistIsThinkingDelay]
or a
jr nz, .asm_6932
@@ -6465,60 +6562,64 @@ Func_6911: ; 6911 (1:6911)
jp nz, DuelTransmissionError
xor a
ld [wSkipDuelistIsThinkingDelay], a
- ldh a, [hAIActionTableIndex]
+ ldh a, [hOppActionTableIndex]
cp $17
jp nc, DuelTransmissionError
- ld hl, AIActionTable
+ ld hl, OppActionTable
call JumpToFunctionInTable
- ld hl, wAITurnEnded
+ ld hl, wOpponentTurnEnded
ld a, [wDuelFinished]
or [hl]
- jr z, .asm_6919
+ jr z, .link_opp_turn_loop
ret
; 0x695e
-AIActionTable: ; 695e (1:695e)
+; actions for the opponent's turn
+; on a link duel, this is referenced by DoLinkOpponentTurn in a loop (on each opponent's HandleTurn)
+; on a non-link duel (vs AI opponent), this is referenced by AIMakeDecision
+OppActionTable: ; 695e (1:695e)
dw DuelTransmissionError
- dw AIAction_PlayBenchPokemon
- dw AIAction_EvolvePokemon
- dw AIAction_UseEnergyCard
- dw AIAction_TryRetreat
- dw AIAction_FinishedTurnNoAttack
- dw AIAction_UseTrainerCard
- dw AIAction_TryExecuteEffect
- dw AIAction_Attack
- dw AIAction_AttackEffect
- dw AIAction_AttackDamage
- dw AIAction_DrawCard
- dw AIAction_UsePokemonPower
- dw AIAction_6b07
- dw AIAction_ForceOpponentSwitchActive
- dw AIAction_NoAction
- dw AIAction_NoAction
- dw AIAction_TossCoinATimes
- dw AIAction_6b30
- dw AIAction_NoAction
- dw AIAction_6b3e
- dw AIAction_6b15
- dw AIAction_DrawDuelMainScene
-
-AIAction_DrawCard: ; 698c (1:698c)
+ dw OppAction_PlayBasicPokemonCard
+ dw OppAction_EvolvePokemonCard
+ dw OppAction_PlayEnergyCard
+ dw OppAction_AttemptRetreat
+ dw OppAction_FinishTurnWithoutAttacking
+ dw OppAction_PlayTrainerCard
+ dw OppAction_ExecuteTrainerCardEffectCommands
+ dw OppAction_BeginUseAttack
+ dw OppAction_UseAttack
+ dw OppAction_PlayAttackAnimationDealAttackDamage
+ dw OppAction_DrawCard
+ dw OppAction_UsePokemonPower
+ dw OppAction_ExecutePokemonPowerEffect
+ dw OppAction_ForceSwitchActive
+ dw OppAction_NoAction
+ dw OppAction_NoAction
+ dw OppAction_TossCoinATimes
+ dw OppAction_6b30
+ dw OppAction_NoAction
+ dw OppAction_6b3e
+ dw OppAction_6b15
+ dw OppAction_DrawDuelMainScene
+
+OppAction_DrawCard: ; 698c (1:698c)
call DrawCardFromDeck
call nc, AddCardToHand
ret
; 0x6993
-AIAction_FinishedTurnNoAttack: ; 6993 (1:6993)
+OppAction_FinishTurnWithoutAttacking: ; 6993 (1:6993)
call DrawDuelMainScene
call ClearNonTurnTemporaryDuelvars
ldtx hl, FinishedTurnWithoutAttackingText
call DrawWideTextBox_WaitForInput
ld a, 1
- ld [wAITurnEnded], a
+ ld [wOpponentTurnEnded], a
ret
; 0x69a5
-AIAction_UseEnergyCard: ; 69a5 (1:69a5)
+; attach an energy card from hand to the arena or a benched Pokemon
+OppAction_PlayEnergyCard: ; 69a5 (1:69a5)
ldh a, [hTempPlayAreaLocation_ffa1]
ldh [hTempPlayAreaLocation_ff9d], a
ld e, a
@@ -6535,7 +6636,8 @@ AIAction_UseEnergyCard: ; 69a5 (1:69a5)
ret
; 0x69c5
-AIAction_EvolvePokemon: ; 69c5 (1:69c5)
+; evolve a Pokemon card in the arena or in the bench
+OppAction_EvolvePokemonCard: ; 69c5 (1:69c5)
ldh a, [hTempPlayAreaLocation_ffa1]
ldh [hTempPlayAreaLocation_ff9d], a
ldh a, [hTemp_ffa0]
@@ -6549,7 +6651,8 @@ AIAction_EvolvePokemon: ; 69c5 (1:69c5)
ret
; 0x69e0
-AIAction_PlayBenchPokemon: ; 69e0 (1:69e0)
+; place a basic Pokemon card from hand in the bench
+OppAction_PlayBasicPokemonCard: ; 69e0 (1:69e0)
ldh a, [hTemp_ffa0]
ldh [hTempCardIndex_ff98], a
call PutHandPokemonCardInPlayArea
@@ -6565,7 +6668,10 @@ AIAction_PlayBenchPokemon: ; 69e0 (1:69e0)
ret
; 0x69ff
-AIAction_TryRetreat: ; 69ff (1:69ff)
+; attempt the retreat of the active Pokemon card
+; if successful, discard the required energy cards for retreat and
+; swap the retreated card with a Pokemon card from the bench
+OppAction_AttemptRetreat: ; 69ff (1:69ff)
ld a, DUELVARS_ARENA_CARD
call GetTurnDuelistVariable
push af
@@ -6587,7 +6693,8 @@ AIAction_TryRetreat: ; 69ff (1:69ff)
ret
; 0x6a23
-AIAction_UseTrainerCard: ; 6a23 (1:6a23)
+; play trainer card from hand
+OppAction_PlayTrainerCard: ; 6a23 (1:6a23)
call LoadNonPokemonCardEffectCommands
call DisplayUsedTrainerCardDetailScreen
call PrintUsedTrainerCardDescription
@@ -6597,11 +6704,12 @@ AIAction_UseTrainerCard: ; 6a23 (1:6a23)
ret
; 0x6a35
-; for trainer card effects
-AIAction_TryExecuteEffect: ; 6a35 (1:6a35)
- ld a, $06
+; execute the effect commands of the trainer card that is being played
+; used only for Trainer cards, as a continuation of OppAction_PlayTrainerCard
+OppAction_ExecuteTrainerCardEffectCommands: ; 6a35 (1:6a35)
+ ld a, EFFECTCMDTYPE_DISCARD_ENERGY
call TryExecuteEffectCommandFunction
- ld a, $03
+ ld a, EFFECTCMDTYPE_BEFORE_DAMAGE
call TryExecuteEffectCommandFunction
call DrawDuelMainScene
ldh a, [hTempCardIndex_ff9f]
@@ -6611,10 +6719,9 @@ AIAction_TryExecuteEffect: ; 6a35 (1:6a35)
ret
; 0x6a4e
-; determine if an attack is successful
-; if no, end the turn early
-; if yes, AIAction_AttackEffect and AIAction_AttackDamage can be called next
-AIAction_Attack: ; 6a4e (1:6a4e)
+; begin the execution of an attack and handle the attack being
+; possibly unsuccessful due to Sand Attack or Smokescreen
+OppAction_BeginUseAttack: ; 6a4e (1:6a4e)
ldh a, [hTempCardIndex_ff9f]
ld d, a
ldh a, [hTemp_ffa0]
@@ -6624,34 +6731,39 @@ AIAction_Attack: ; 6a4e (1:6a4e)
ld a, $01
ld [wSkipDuelistIsThinkingDelay], a
call CheckSandAttackOrSmokescreenSubstatus
- jr c, .has_status_effect
+ jr c, .has_status
ld a, DUELVARS_ARENA_CARD_STATUS
call GetTurnDuelistVariable
and CNF_SLP_PRZ
cp CONFUSED
- jr z, .has_status_effect
+ jr z, .has_status
call ExchangeRNG
ret
-.has_status_effect
+
+; we make it here is attacker is affected by
+; Sand Attack, Smokescreen, or confusion
+.has_status
call DrawDuelMainScene
call PrintPokemonsAttackText
call WaitForWideTextBoxInput
call ExchangeRNG
call HandleSandAttackOrSmokescreenSubstatus
- ret nc ; attack is successful
+ ret nc ; return if attack is successful (won the coin toss)
call ClearNonTurnTemporaryDuelvars
- ; only end the turn if the attack fails
+ ; end the turn if the attack fails
ld a, 1
- ld [wAITurnEnded], a
+ ld [wOpponentTurnEnded], a
ret
; 0x6a8c
-AIAction_AttackEffect: ; 6a8c (1:6a8c)
- ld a, $06
+; display the attack used by the opponent, and handle
+; EFFECTCMDTYPE_DISCARD_ENERGY and confusion damage to self
+OppAction_UseAttack: ; 6a8c (1:6a8c)
+ ld a, EFFECTCMDTYPE_DISCARD_ENERGY
call TryExecuteEffectCommandFunction
call CheckSelfConfusionDamage
jr c, .confusion_damage
- call Func_6635
+ call DisplayOpponentUsedMoveScreen
call PrintPokemonsAttackText
call WaitForWideTextBoxInput
call ExchangeRNG
@@ -6659,25 +6771,26 @@ AIAction_AttackEffect: ; 6a8c (1:6a8c)
ld [wSkipDuelistIsThinkingDelay], a
ret
.confusion_damage
- call DealConfusionDamageToSelf
- ; only end the turn if the attack fails
+ call HandleConfusionDamageToSelf
+ ; end the turn if dealing damage to self due to confusion
ld a, 1
- ld [wAITurnEnded], a
+ ld [wOpponentTurnEnded], a
ret
; 0x6ab1
-AIAction_AttackDamage: ; 6ab1 (1:6ab1)
- call Func_179a
+OppAction_PlayAttackAnimationDealAttackDamage: ; 6ab1 (1:6ab1)
+ call PlayAttackAnimation_DealAttackDamage
ld a, 1
- ld [wAITurnEnded], a
+ ld [wOpponentTurnEnded], a
ret
; 0x6aba
-AIAction_ForceOpponentSwitchActive: ; 6aba (1:6aba)
+; force the player to switch the active Pokemon with a benched Pokemon
+OppAction_ForceSwitchActive: ; 6aba (1:6aba)
ldtx hl, SelectPkmnOnBenchToSwitchWithActiveText
call DrawWideTextBox_WaitForInput
call SwapTurn
- call HasAlivePokemonOnBench
+ call HasAlivePokemonInBench
ld a, $01
ld [wcbd4], a
.force_selection
@@ -6689,7 +6802,7 @@ AIAction_ForceOpponentSwitchActive: ; 6aba (1:6aba)
ret
; 0x6ad9
-AIAction_UsePokemonPower: ; 6ad9 (1:6ad9)
+OppAction_UsePokemonPower: ; 6ad9 (1:6ad9)
ldh a, [hTempCardIndex_ff9f]
ld d, a
ld e, $00
@@ -6712,29 +6825,30 @@ AIAction_UsePokemonPower: ; 6ad9 (1:6ad9)
ret
; 0x6b07
-AIAction_6b07: ; 6b07 (1:6b07)
+; execute the EFFECTCMDTYPE_BEFORE_DAMAGE command of the used Pokemon Power
+OppAction_ExecutePokemonPowerEffect: ; 6b07 (1:6b07)
call Func_7415
- ld a, $03
+ ld a, EFFECTCMDTYPE_BEFORE_DAMAGE
call TryExecuteEffectCommandFunction
ld a, $01
ld [wSkipDuelistIsThinkingDelay], a
ret
; 0x6b15
-AIAction_6b15: ; 6b15 (1:6b15)
- ld a, $04
+OppAction_6b15: ; 6b15 (1:6b15)
+ ld a, EFFECTCMDTYPE_AFTER_DAMAGE
call TryExecuteEffectCommandFunction
ld a, $01
ld [wSkipDuelistIsThinkingDelay], a
ret
; 0x6b20
-AIAction_DrawDuelMainScene: ; 6b20 (1:6b20)
+OppAction_DrawDuelMainScene: ; 6b20 (1:6b20)
call DrawDuelMainScene
ret
; 0x6b24
-AIAction_TossCoinATimes: ; 6b24 (1:6b24)
+OppAction_TossCoinATimes: ; 6b24 (1:6b24)
call SerialRecv8Bytes
call TossCoinATimes
ld a, $01
@@ -6742,7 +6856,7 @@ AIAction_TossCoinATimes: ; 6b24 (1:6b24)
ret
; 0x6b30
-AIAction_6b30: ; 6b30 (1:6b30)
+OppAction_6b30: ; 6b30 (1:6b30)
ldh a, [hWhoseTurn]
push af
ldh a, [hTemp_ffa0]
@@ -6753,7 +6867,7 @@ AIAction_6b30: ; 6b30 (1:6b30)
ret
; 0x6b3e
-AIAction_6b3e: ; 6b3e (1:6b3e)
+OppAction_6b3e: ; 6b3e (1:6b3e)
call DrawDuelMainScene
ld a, DUELVARS_ARENA_CARD_STATUS
call GetTurnDuelistVariable
@@ -6783,7 +6897,7 @@ AIAction_6b3e: ; 6b3e (1:6b3e)
ret
; 0x6b7d
-AIAction_NoAction: ; 6b7d (1:6b7d)
+OppAction_NoAction: ; 6b7d (1:6b7d)
ret
; 0x6b7e
@@ -6825,12 +6939,12 @@ Func_6ba2: ; 6ba2 (1:6ba2)
; apply and/or refresh status conditions and other events that trigger between turns
HandleBetweenTurnsEvents: ; 6baf (1:6baf)
- call IsArenaPokemonAsleepOrDoublePoisoned
+ call IsArenaPokemonAsleepOrPoisoned
jr c, .something_to_handle
cp PARALYZED
jr z, .something_to_handle
call SwapTurn
- call IsArenaPokemonAsleepOrDoublePoisoned
+ call IsArenaPokemonAsleepOrPoisoned
call SwapTurn
jr c, .something_to_handle
call DiscardAttachedPluspowers
@@ -6840,8 +6954,8 @@ HandleBetweenTurnsEvents: ; 6baf (1:6baf)
ret
.something_to_handle
; either:
- ; 1. turn holder's arena Pokemon is paralyzed, asleep or double poisoned
- ; 2. non-turn holder's arena Pokemon is asleep or double poisoned
+ ; 1. turn holder's arena Pokemon is paralyzed, asleep, poisoned or double poisoned
+ ; 2. non-turn holder's arena Pokemon is asleep, poisoned or double poisoned
call Func_3b21
call ZeroObjectPositionsAndToggleOAMCopy
call EmptyScreen
@@ -6924,14 +7038,16 @@ DiscardAttachedDefenders: ; 6c56 (1:6c56)
jp MoveCardToDiscardPileIfInArena
; 0x6c68
-; return carry if the turn holder's arena Pokemon card is double poisoned or asleep.
+; return carry if the turn holder's arena Pokemon card is asleep, poisoned, or double poisoned.
; also, if confused, paralyzed, or asleep, return the status condition in a.
-IsArenaPokemonAsleepOrDoublePoisoned: ; 6c68 (1:6c68)
+IsArenaPokemonAsleepOrPoisoned: ; 6c68 (1:6c68)
ld a, DUELVARS_ARENA_CARD_STATUS
call GetTurnDuelistVariable
or a
ret z
- and DOUBLE_POISONED
+ ; note that POISONED | DOUBLE_POISONED is the same as just DOUBLE_POISONED ($c0)
+ ; poison status masking is normally done with PSN_DBLPSN ($f0)
+ and POISONED | DOUBLE_POISONED
jr nz, .set_carry
ld a, [hl]
and CNF_SLP_PRZ
@@ -6992,7 +7108,7 @@ Func_6cab: ; 6cab (1:6cab)
call Func_3b6a
.asm_6cd8
call DoFrame
- call Func_3b52
+ call CheckAnyAnimationPlaying
jr c, .asm_6cd8
call Func_6c7e.asm_6c98
ret
@@ -7187,12 +7303,289 @@ ApplyStatusConditionToArenaPokemon: ; 6e38 (1:6e38)
; 0x6e49
Func_6e49: ; 6e49 (1:6e49)
- INCROM $6e49, $700a
+ call HandleDestinyBondSubstatus
+ call ClearDamageReductionSubstatus2OfKnockedOutPokemon
+ xor a
+ ld [wcce8], a
+ call SwapTurn
+ call Func_6ef6
+ call SwapTurn
+ ld a, [wcce8]
+ or a
+ jr z, .asm_6e86
+ call Func_6ff7
+ jr c, .asm_6e86
+ call CountKnockedOutPokemon
+ ld c, a
+ call SwapTurn
+ call CountPrizes
+ call SwapTurn
+ dec a
+ cp c
+ jr c, .asm_6e86
+ ld a, c
+ call SwapTurn
+ call TakeAPrizes
+ call SwapTurn
+ ld a, $01
+ jr .asm_6ecc
+.asm_6e86
+ call Func_6ef6
+ ld a, [wcce8]
+ cp $01
+ jr nz, .asm_6e9f
+ call SwapTurn
+ call Func_6ff7
+ call SwapTurn
+ jr c, .asm_6e9f
+ ld a, $02
+ jr .asm_6ecc
+.asm_6e9f
+ call SwapTurn
+ call Func_6eff
+ call SwapTurn
+ call Func_6eff
+ ld a, [wcce8]
+ or a
+ jr nz, .asm_6ec4
+ xor a
+.asm_6eb2
+ push af
+ call MoveAllTurnHolderKnockedOutPokemonToDiscardPile
+ call SwapTurn
+ call MoveAllTurnHolderKnockedOutPokemonToDiscardPile
+ call SwapTurn
+ call ShiftAllPokemonToFirstPlayAreaSlots
+ pop af
+ ret
+.asm_6ec4
+ ld e, a
+ ld d, $00
+ ld hl, Data_6ed2
+ add hl, de
+ ld a, [hl]
+.asm_6ecc
+ ld [wDuelFinished], a
+ scf
+ jr .asm_6eb2
+; 0x6ed2
+
+Data_6ed2: ; 6ed2 (1:6ed2)
+ db DUEL_NOT_FINISHED, TURN_PLAYER_LOST, TURN_PLAYER_WON, TURN_PLAYER_TIED
+ db TURN_PLAYER_LOST, TURN_PLAYER_LOST, TURN_PLAYER_TIED, TURN_PLAYER_LOST
+ db TURN_PLAYER_WON, TURN_PLAYER_TIED, TURN_PLAYER_WON, TURN_PLAYER_WON
+ db TURN_PLAYER_TIED, TURN_PLAYER_LOST, TURN_PLAYER_WON, TURN_PLAYER_TIED
+
+; clears SUBSTATUS2_REDUCE_BY_20, SUBSTATUS2_POUNCE, SUBSTATUS2_GROWL,
+; SUBSTATUS2_TAIL_WAG, and SUBSTATUS2_LEER for each arena Pokemon with 0 HP
+ClearDamageReductionSubstatus2OfKnockedOutPokemon: ; 6ee2 (1:6ee2)
+ call SwapTurn
+ call .clear
+ call SwapTurn
+.clear
+ ld a, DUELVARS_ARENA_CARD_HP
+ call GetNonTurnDuelistVariable
+ or a
+ ret nz
+ call ClearDamageReductionSubstatus2
+ ret
+; 0x6ef6
+
+Func_6ef6: ; 6ef6 (1:6ef6)
+ call Func_6fa5
+ ld hl, wcce8
+ rl [hl]
+ ret
+; 0x6eff
+
+Func_6eff: ; 6eff (1:6eff)
+ call ReplaceKnockedOutPokemon
+ ld hl, wcce8
+ rl [hl]
+ ret
+; 0x6f08
+
+; for each Pokemon in the turn holder's play area (arena and bench),
+; move that card to the discard pile if its HP is 0
+MoveAllTurnHolderKnockedOutPokemonToDiscardPile: ; 6f08 (1:6f08)
+ ld a, DUELVARS_NUMBER_OF_POKEMON_IN_PLAY_AREA
+ call GetTurnDuelistVariable
+ ld d, a
+ ld l, DUELVARS_ARENA_CARD_HP
+ ld e, PLAY_AREA_ARENA
+.loop
+ ld a, [hl]
+ or a
+ jr nz, .next
+ push hl
+ push de
+ call MovePlayAreaCardToDiscardPile
+ pop de
+ pop hl
+.next
+ inc hl
+ inc e
+ dec d
+ jr nz, .loop
+ ret
+; 0x6f23
+
+; have the turn holder replace the arena Pokemon card when it's been knocked out.
+; if there are no Pokemon cards in the turn holder's bench, return carry.
+ReplaceKnockedOutPokemon: ; 6f23 (1:6f23)
+ ld a, DUELVARS_ARENA_CARD_HP
+ call GetTurnDuelistVariable
+ or a
+ ret nz
+ call ClearAllStatusConditions
+ call HasAlivePokemonInBench
+ jr nc, .can_replace_pokemon
+
+; if we made it here, the duelist can't replace the knocked out Pokemon
+ bank1call DrawDuelMainScene
+ ldtx hl, ThereAreNoPokemonInPlayAreaText
+ call DrawWideTextBox_WaitForInput
+ call ExchangeRNG
+ scf
+ ret
+
+.can_replace_pokemon
+ ld a, DUELVARS_DUELIST_TYPE
+ call GetTurnDuelistVariable
+ cp DUELIST_TYPE_PLAYER
+ jr nz, .opponent
+
+; prompt the player to replace the knocked out Pokemon with one from bench
+ bank1call DrawDuelMainScene
+ ldtx hl, SelectPokemonToPlaceInTheArenaText
+ call DrawWideTextBox_WaitForInput
+ ld a, $01
+ ld [wcbd4], a
+ ld a, PRACTICEDUEL_PLAY_STARYU_FROM_BENCH
+ call DoPracticeDuelAction
+.select_pokemon
+ call OpenPlayAreaScreenForSelection
+ jr c, .select_pokemon
+ ldh a, [hTempPlayAreaLocation_ff9d]
+ call SerialSend8Bytes
+
+; replace the arena Pokemon with the one at location [hTempPlayAreaLocation_ff9d]
+.replace_pokemon
+ call Func_3b31
+ ld a, PRACTICEDUEL_REPLACE_KNOCKED_OUT_POKEMON
+ call DoPracticeDuelAction
+ jr c, .select_pokemon
+ ldh a, [hTempPlayAreaLocation_ff9d]
+ ld d, a
+ ld e, PLAY_AREA_ARENA
+ call SwapPlayAreaPokemon
+ ld a, DUELVARS_ARENA_CARD
+ call GetTurnDuelistVariable
+ ldtx hl, DuelistPlacedACardText
+ bank1call DisplayCardDetailScreen
+ call ExchangeRNG
+ or a
+ ret
+
+; the AI opponent replaces the knocked out Pokemon with one from bench
+.opponent
+ cp DUELIST_TYPE_LINK_OPP
+ jr z, .link_opponent
+ call Func_2bcf
+ ldh a, [hTemp_ffa0]
+ ldh [hTempPlayAreaLocation_ff9d], a
+ jr .replace_pokemon
+
+; wait for link opponent to replace the knocked out Pokemon with one from bench
+.link_opponent
+ bank1call DrawDuelMainScene
+ ldtx hl, DuelistIsSelectingPokemonToPlaceInArenaText
+ call DrawWideTextBox_PrintText
+ call SerialRecv8Bytes
+ ldh [hTempPlayAreaLocation_ff9d], a
+ jr .replace_pokemon
+; 0x6fa5
+
+Func_6fa5: ; 6fa5 (1:6fa5)
+ call CountKnockedOutPokemon
+ ret nc
+ ; at least one Pokemon knocked out
+ call SwapTurn
+ bank1call Func_5805
+ call SwapTurn
+ ret nc
+ call SwapTurn
+ bank1call DrawDuelMainScene
+ ldtx hl, TookAllThePrizesText
+ call DrawWideTextBox_WaitForInput
+ call ExchangeRNG
+ call SwapTurn
+ scf
+ ret
+; 0x6fc7
+
+; return in wccc8 the amount of Pokemon in the turn holder's
+; play area that are still there despite having 0 HP.
+; that is, the number of Pokemon that have just been knocked out.
+; Clefairy Doll and Mysterious Fossil don't count.
+CountKnockedOutPokemon: ; 6fc7 (1:6fc7)
+ ld a, DUELVARS_ARENA_CARD_HP
+ call GetTurnDuelistVariable
+ ld d, h
+ ld e, DUELVARS_ARENA_CARD
+ ld b, PLAY_AREA_ARENA
+ ld c, MAX_PLAY_AREA_POKEMON
+.loop
+ ld a, [de]
+ cp -1
+ jr z, .next ; jump if no Pokemon in this location
+ ld a, [hl]
+ or a
+ jr nz, .next ; jump if this Pokemon's HP isn't 0
+ ; this Pokemon's HP has just become 0
+ ld a, [de]
+ push de
+ call GetCardIDFromDeckIndex
+ call GetCardType
+ pop de
+ cp TYPE_TRAINER
+ jr z, .next ; jump if this is a trainer card (Clefairy Doll or Mysterious Fossil)
+ inc b
+.next
+ inc hl
+ inc de
+ dec c
+ jr nz, .loop
+ ld a, b
+ ld [wccc8], a
+ or a
+ ret z
+ scf
+ ret
+; 0x6ff7
+
+Func_6ff7: ; 6ff7 (1:6ff7)
+ ld a, DUELVARS_NUMBER_OF_POKEMON_IN_PLAY_AREA
+ call GetTurnDuelistVariable
+ ld c, a
+ ld l, DUELVARS_ARENA_CARD_HP
+.loop
+ ld a, [hli]
+ or a
+ jr nz, .non_zero_hp
+ dec c
+ jr nz, .loop
+ scf
+ ret
+.non_zero_hp
+ or a
+ ret
+; 0x700a
; print one of the "There was no effect from" texts depending
-; on the value at wccf1 ($00 or a status condition constant)
+; on the value at wNoEffectFromStatus (NO_STATUS or a status condition constant)
PrintThereWasNoEffectFromStatusText: ; 700a (1:700a)
- ld a, [wccf1]
+ ld a, [wNoEffectFromStatus]
or a
jr nz, .status
ld hl, wLoadedMoveName
@@ -7367,15 +7760,17 @@ PrizeBitmasks: ; 715a (1:715a)
db %0, %1, %11, %111, %1111, %11111, %111111
; 0x7161
-Func_7161: ; 7161 (1:7161)
+; update the turn holder's DUELVARS_PRIZES following that duelist
+; drawing a number of prizes equal to register a
+TakeAPrizes: ; 7161 (1:7161)
or a
ret z
ld c, a
call CountPrizes
sub c
- jr nc, .asm_716b
+ jr nc, .no_underflow
xor a
-.asm_716b
+.no_underflow
ld c, a
ld b, $00
ld hl, PrizeBitmasks
@@ -7414,18 +7809,21 @@ ClearNonTurnTemporaryDuelvars_CopyStatus: ; 7189 (1:7189)
ret
; 0x7195
+; update non-turn holder's DUELVARS_ARENA_CARD_LAST_TURN_DAMAGE
+; if wccef == 0: set to [wDealtDamage]
+; if wceef != 0: set to 0
Func_7195: ; 7195 (1:7195)
ld a, DUELVARS_ARENA_CARD_LAST_TURN_DAMAGE
call GetNonTurnDuelistVariable
ld a, [wccef]
or a
- jr nz, .asm_71a9
+ jr nz, .zero
ld a, [wDealtDamage]
ld [hli], a
- ld a, [wccc0]
+ ld a, [wDealtDamage + 1]
ld [hl], a
ret
-.asm_71a9
+.zero
xor a
ld [hli], a
ld [hl], a
@@ -7528,7 +7926,7 @@ _TossCoin: ; 71ad (1:71ad)
.asm_725e
push de
call DoFrame
- call Func_3b52
+ call CheckAnyAnimationPlaying
pop de
jr c, .asm_725e
ld a, e
@@ -7689,11 +8087,14 @@ Func_741a: ; 741a (1:741a)
ret
; 0x7469
-Func_7469: ; 7469 (1:7469)
+; this is a simple version of PlayAttackAnimation_DealAttackDamage that doesn't
+; take into account status conditions, damage modifiers, etc, for damage calculation.
+; used for confusion damage to self and for damage to benched Pokemon, for example
+PlayAttackAnimation_DealAttackDamageSimple: ; 7469 (1:7469)
push hl
push de
- call Func_7494
- call Func_7484
+ call PlayMoveAnimation
+ call WaitMoveAnimation
pop de
pop hl
call SubstractHP
@@ -7708,20 +8109,26 @@ Func_7469: ; 7469 (1:7469)
ret
; 0x7484
-Func_7484: ; 7484 (1:7484)
+; if [wLoadedMoveAnimation] != 0, wait until the animation is over
+WaitMoveAnimation: ; 7484 (1:7484)
ld a, [wLoadedMoveAnimation]
or a
ret z
push de
-.asm_748a
+.anim_loop
call DoFrame
- call Func_3b52
- jr c, .asm_748a
+ call CheckAnyAnimationPlaying
+ jr c, .anim_loop
pop de
ret
; 0x7494
-Func_7494: ; 7494 (1:7494)
+; play move animation
+; input:
+; - [wLoadedMoveAnimation]: animation to play
+; - de: damage dealt by the move (to display the animation with the number)
+; - c: a wDamageEffectiveness constant (to print WEAK or RESIST if necessary)
+PlayMoveAnimation: ; 7494 (1:7494)
ldh a, [hWhoseTurn]
push af
push hl
diff --git a/src/engine/bank02.asm b/src/engine/bank02.asm
index 60d9826..a4a0f62 100644
--- a/src/engine/bank02.asm
+++ b/src/engine/bank02.asm
@@ -1,17 +1,1786 @@
-Func_8000: ; 8000 (2:4000)
- INCROM $8000, $8211
+_OpenDuelCheckMenu: ; 8000 (2:4000)
+ call ResetCheckMenuCursorPositionAndBlink
+ xor a
+ ld [wce5e], a
+ call DrawWideTextBox
+
+; reset cursor blink
+ xor a
+ ld [wCheckMenuCursorBlinkCounter], a
+ ld hl, CheckMenuData
+ call PlaceTextItems
+.loop
+ call DoFrame
+ call HandleCheckMenuInput
+ jr nc, .loop
+ cp $ff
+ ret z ; B pressed
+
+; A was pressed
+ ld a, [wCheckMenuCursorYPosition]
+ sla a
+ ld b, a
+ ld a, [wCheckMenuCursorXPosition]
+ add b
+ ld hl, .table
+ call JumpToFunctionInTable
+ jr _OpenDuelCheckMenu
+
+.table: ; 8031 (2:4031)
+ dw DuelCheckMenu_InPlayArea
+ dw DuelCheckMenu_Glossary
+ dw DuelCheckMenu_YourPlayArea
+ dw DuelCheckMenu_OppPlayArea
+
+; opens the In Play Area submenu
+DuelCheckMenu_InPlayArea: ; 8039 (2:4039)
+ xor a
+ ld [wce60], a
+ farcall Func_180d5
+ ret
+
+; opens the Glossary submenu
+DuelCheckMenu_Glossary: ; 8042 (2:4042)
+ farcall Func_006_44c8
+ ret
+
+; opens the Your Play Area submenu
+DuelCheckMenu_YourPlayArea: ; 8047 (2:4047)
+ call ResetCheckMenuCursorPositionAndBlink
+ xor a
+ ld [wce5e], a
+ ldh a, [hWhoseTurn]
+.draw
+ ld h, a
+ ld l, a
+ call DrawYourOrOppPlayAreaScreen
+
+ ld a, [wCheckMenuCursorYPosition]
+ sla a
+ ld b, a
+ ld a, [wCheckMenuCursorXPosition]
+ add b
+ ld [wYourOrOppPlayAreaLastCursorPosition], a
+ ld b, $f8 ; black arrow tile
+ call DrawYourOrOppPlayArea_DrawArrows
+
+ call DrawWideTextBox
+
+; reset cursor blink
+ xor a
+ ld [wCheckMenuCursorBlinkCounter], a
+ ld hl, YourPlayAreaMenuData
+ call PlaceTextItems
+
+.loop
+ call DoFrame
+ xor a
+ call DrawYourOrOppPlayArea_RefreshArrows
+ call HandleCheckMenuInput_YourOrOppPlayArea
+ jr nc, .loop
+
+ call DrawYourOrOppPlayArea_EraseArrows
+ cp $ff
+ ret z
+
+ ld a, [wCheckMenuCursorYPosition]
+ sla a
+ ld b, a
+ ld a, [wCheckMenuCursorXPosition]
+ add b
+ ld hl, .table
+ call JumpToFunctionInTable
+ jr .draw
-Func_8211: ; 8211 (2:4211)
- INCROM $8211, $833c
+.table ; 8098 (2:4098)
+ dw OpenYourOrOppPlayAreaScreen_TurnHolderPlayArea
+ dw OpenYourOrOppPlayAreaScreen_TurnHolderHand
+ dw OpenYourOrOppPlayAreaScreen_TurnHolderDiscardPile
-Func_833c: ; 833c (2:433c)
- INCROM $833c, $8764
+OpenYourOrOppPlayAreaScreen_TurnHolderPlayArea: ; 809e (2:409e)
+ ldh a, [hWhoseTurn]
+ push af
+ bank1call OpenTurnHolderPlayAreaScreen
+ pop af
+ ldh [hWhoseTurn], a
+ ret
+
+OpenYourOrOppPlayAreaScreen_NonTurnHolderPlayArea:
+ ldh a, [hWhoseTurn]
+ push af
+ bank1call OpenNonTurnHolderPlayAreaScreen
+ pop af
+ ldh [hWhoseTurn], a
+ ret
+
+OpenYourOrOppPlayAreaScreen_TurnHolderHand:
+ ldh a, [hWhoseTurn]
+ push af
+ bank1call OpenTurnHolderHandScreen_Simple
+ pop af
+ ldh [hWhoseTurn], a
+ ret
+
+OpenYourOrOppPlayAreaScreen_NonTurnHolderHand:
+ ldh a, [hWhoseTurn]
+ push af
+ bank1call OpenNonTurnHolderHandScreen_Simple
+ pop af
+ ldh [hWhoseTurn], a
+ ret
+
+OpenYourOrOppPlayAreaScreen_TurnHolderDiscardPile:
+ ldh a, [hWhoseTurn]
+ push af
+ bank1call OpenTurnHolderDiscardPileScreen
+ pop af
+ ldh [hWhoseTurn], a
+ ret
+
+OpenYourOrOppPlayAreaScreen_NonTurnHolderDiscardPile:
+ ldh a, [hWhoseTurn]
+ push af
+ bank1call OpenNonTurnHolderDiscardPileScreen
+ pop af
+ ldh [hWhoseTurn], a
+ ret
+
+; opens the Opp. Play Area submenu
+; if clairvoyance is active, add the option to check
+; opponent's hand
+DuelCheckMenu_OppPlayArea: ; 80da (2:40da)
+ call ResetCheckMenuCursorPositionAndBlink
+ call IsClairvoyanceActive
+ jr c, .clairvoyance1
+
+ ld a, %10000000
+ ld [wce5e], a
+ jr .begin
+.clairvoyance1
+ xor a
+ ld [wce5e], a
+
+.begin
+ ldh a, [hWhoseTurn]
+.turns
+ ld l, a
+ cp PLAYER_TURN
+ jr nz, .opponent
+ ld a, OPPONENT_TURN
+ ld h, a
+ jr .cursor
+.opponent
+ ld a, PLAYER_TURN
+ ld h, a
+.cursor
+ call DrawYourOrOppPlayAreaScreen
+
+; convert cursor position and
+; store it in wYourOrOppPlayAreaLastCursorPosition
+ ld a, [wCheckMenuCursorYPosition]
+ sla a
+ ld b, a
+ ld a, [wCheckMenuCursorXPosition]
+ add b
+ add 3
+ ld [wYourOrOppPlayAreaLastCursorPosition], a
+
+; draw black arrows in the Play Area
+ ld b, $f8 ; black arrow tile
+ call DrawYourOrOppPlayArea_DrawArrows
+ call DrawWideTextBox
+
+
+; reset cursor blink
+ xor a
+ ld [wCheckMenuCursorBlinkCounter], a
+
+; place text items depending on clairvoyance
+; when active, allows to look at opp. hand
+ call IsClairvoyanceActive
+ jr c, .clairvoyance2
+ ld hl, OppPlayAreaMenuData
+ call PlaceTextItems
+ jr .loop
+.clairvoyance2
+ ld hl, OppPlayAreaMenuData_WithClairvoyance
+ call PlaceTextItems
+
+; handle input
+.loop
+ call DoFrame
+ ld a, 1
+ call DrawYourOrOppPlayArea_RefreshArrows
+ call HandleCheckMenuInput_YourOrOppPlayArea
+ jr nc, .loop
+ call DrawYourOrOppPlayArea_EraseArrows
+ cp $ff
+ ret z ; B was pressed
+
+; A was pressed
+; jump to function corresponding to cursor position
+ ld a, [wCheckMenuCursorYPosition]
+ sla a
+ ld b, a
+ ld a, [wCheckMenuCursorXPosition]
+ add b
+ ld hl, .table
+ call JumpToFunctionInTable
+ jr .turns
+
+.table
+ dw OpenYourOrOppPlayAreaScreen_NonTurnHolderPlayArea
+ dw OpenYourOrOppPlayAreaScreen_NonTurnHolderHand
+ dw OpenYourOrOppPlayAreaScreen_NonTurnHolderDiscardPile
+
+CheckMenuData: ; (2:4158)
+ textitem 2, 14, InPlayAreaText
+ textitem 2, 16, YourPlayAreaText
+ textitem 12, 14, GlossaryText
+ textitem 12, 16, OppPlayAreaText
+ db $ff
+
+YourPlayAreaMenuData: ; (2:4169)
+ textitem 2, 14, YourPokemonText
+ textitem 12, 14, YourHandText
+ textitem 2, 16, YourDiscardPileText2
+ db $ff
+
+OppPlayAreaMenuData: ; (2:4176)
+ textitem 2, 14, OpponentsPokemonText
+ textitem 2, 16, OpponentsDiscardPileText2
+ db $ff
+
+OppPlayAreaMenuData_WithClairvoyance: ; (2:4176)
+ textitem 2, 14, OpponentsPokemonText
+ textitem 12, 14, OpponentsHandText
+ textitem 2, 16, OpponentsDiscardPileText2
+ db $ff
+
+; checks if arrows need to be erased in Your Play Area or Opp. Play Area
+; and draws new arrows upon cursor position change
+; input:
+; a = an initial offset applied to the cursor position (used to adjust
+; for the different layouts of the Your Play Area and Opp. Play Area screens)
+DrawYourOrOppPlayArea_RefreshArrows: ; 818c (2:418c)
+ push af
+ ld b, a
+ add b
+ add b
+ ld c, a
+ ld a, [wCheckMenuCursorYPosition]
+ sla a
+ ld b, a
+ ld a, [wCheckMenuCursorXPosition]
+ add b
+ add c
+; a = 2 * cursor ycoord + cursor xcoord + 3*a
+
+; if cursor position is different than
+; last position, then update arrows
+ ld hl, wYourOrOppPlayAreaLastCursorPosition
+ cp [hl]
+ jr z, .unchanged
+
+; erase and draw arrows
+ call DrawYourOrOppPlayArea_EraseArrows
+ ld [wYourOrOppPlayAreaLastCursorPosition], a
+ ld b, $f8 ; black arrow tile byte
+ call DrawYourOrOppPlayArea_DrawArrows
+
+.unchanged
+ pop af
+ ret
+
+; write SYM_SPACE to positions tabulated in
+; YourOrOppPlayAreaArrowPositions, with offset calculated from the
+; cursor x and y positions in [wYourOrOppPlayAreaLastCursorPosition]
+; input:
+; [wYourOrOppPlayAreaLastCursorPosition]: cursor position (2*y + x)
+DrawYourOrOppPlayArea_EraseArrows: ; 81af (2:41af)
+ push af
+ ld a, [wYourOrOppPlayAreaLastCursorPosition]
+ ld b, SYM_SPACE ; white tile
+ call DrawYourOrOppPlayArea_DrawArrows
+ pop af
+ ret
+
+; writes tile in b to positions tabulated in
+; YourOrOppPlayAreaArrowPositions, with offset calculated from the
+; cursor x and y positions in a
+; input:
+; a = cursor position (2*y + x)
+; b = byte to draw
+DrawYourOrOppPlayArea_DrawArrows: ; 81ba (2:41ba)
+ push bc
+ ld hl, YourOrOppPlayAreaArrowPositions
+ sla a
+ ld c, a
+ ld b, $00
+ add hl, bc
+; hl points to YourOrOppPlayAreaArrowPositions
+; plus offset corresponding to a
+
+; load hl with draw position pointer
+ ld a, [hli]
+ ld h, [hl]
+ ld l, a
+ pop de
+
+.loop
+ ld a, [hli]
+ cp $ff
+ jr z, .done
+ ld b, a
+ ld a, [hli]
+ ld c, a
+ ld a, d
+ call WriteByteToBGMap0
+ jr .loop
+.done
+ ret
+
+YourOrOppPlayAreaArrowPositions: ; 81d7 (2:41d7)
+ dw YourOrOppPlayAreaArrowPositions_PlayerPokemon
+ dw YourOrOppPlayAreaArrowPositions_PlayerHand
+ dw YourOrOppPlayAreaArrowPositions_PlayerDiscardPile
+ dw YourOrOppPlayAreaArrowPositions_OpponentPokemon
+ dw YourOrOppPlayAreaArrowPositions_OpponentHand
+ dw YourOrOppPlayAreaArrowPositions_OpponentDiscardPile
+
+YourOrOppPlayAreaArrowPositions_PlayerPokemon: ; 81e3 (2:41e3)
+; x and y coordinates to draw byte
+ db 5, 5
+ db 0, 10
+ db 4, 10
+ db 8, 10
+ db 12, 10
+ db 16, 10
+ db $ff
+
+YourOrOppPlayAreaArrowPositions_PlayerHand:
+ db 14, 7
+ db $ff
+
+YourOrOppPlayAreaArrowPositions_PlayerDiscardPile:
+ db 14, 5
+ db $ff
+
+YourOrOppPlayAreaArrowPositions_OpponentPokemon:
+ db 5, 7
+ db 0, 3
+ db 4, 3
+ db 8, 3
+ db 12, 3
+ db 16, 3
+ db $ff
+
+YourOrOppPlayAreaArrowPositions_OpponentHand:
+ db 0, 5
+ db $ff
+
+YourOrOppPlayAreaArrowPositions_OpponentDiscardPile:
+ db 0, 8
+ db $ff
+
+; loads tiles and icons to display Your Play Area / Opp. Play Area screen,
+; and draws the screen according to the turn player
+; input: h -> [wCheckMenuPlayAreaWhichDuelist] and l -> [wCheckMenuPlayAreaWhichLayout]
+DrawYourOrOppPlayAreaScreen: ; 8209 (2:4209)
+; loads the turn holders
+ ld a, h
+ ld [wCheckMenuPlayAreaWhichDuelist], a
+ ld a, l
+ ld [wCheckMenuPlayAreaWhichLayout], a
+; fallthrough
+
+; loads tiles and icons to display Your Play Area / Opp. Play Area screen,
+; and draws the screen according to the turn player
+; input: [wCheckMenuPlayAreaWhichDuelist] and [wCheckMenuPlayAreaWhichLayout]
+_DrawYourOrOppPlayAreaScreen: ; 8211 (2:4211)
+ xor a
+ ld [wTileMapFill], a
+ call ZeroObjectPositions
+
+ ld a, $01
+ ld [wVBlankOAMCopyToggle], a
+
+ call DoFrame
+ call EmptyScreen
+ call Set_OBJ_8x8
+ call LoadCursorTile
+ call LoadSymbolsFont
+ call LoadDeckAndDiscardPileIcons
+
+ ld a, [wCheckMenuPlayAreaWhichDuelist]
+ cp PLAYER_TURN
+ jr nz, .opp_turn1
+
+; print <RAMNAME>'s Play Area
+ ld de, wDefaultText
+ call CopyPlayerName
+ jr .get_text_length
+.opp_turn1
+ ld de, wDefaultText
+ call CopyOpponentName
+.get_text_length
+ ld hl, wDefaultText
+
+ call GetTextLengthInTiles
+ ld a, 6 ; max name size in tiles
+ sub b
+ srl a
+ add 4
+; a = (6 - name text in tiles) / 2 + 4
+ ld d, a ; text horizontal alignment
+
+ ld e, $00
+ call InitTextPrinting
+ ldtx hl, DuelistsPlayAreaText
+ ldh a, [hWhoseTurn]
+ cp PLAYER_TURN
+ jr nz, .opp_turn2
+ ld a, [wCheckMenuPlayAreaWhichDuelist]
+ cp PLAYER_TURN
+ jr nz, .swap
+.opp_turn2
+ call PrintTextNoDelay
+ jr .draw
+.swap
+ call SwapTurn
+ call PrintTextNoDelay
+ call SwapTurn
+
+.draw
+ ld a, [wCheckMenuPlayAreaWhichDuelist]
+ ld b, a
+ ld a, [wCheckMenuPlayAreaWhichLayout]
+ cp b
+ jr nz, .not_equal
+
+ ld hl, PrizeCardsCoordinateData_YourOrOppPlayArea.player
+ call DrawPlayArea_PrizeCards
+ lb de, 6, 2 ; coordinates of player's active card
+ call DrawYourOrOppPlayArea_ActiveCardGfx
+ lb de, 1, 9 ; coordinates of player's bench cards
+ ld c, 4 ; spacing
+ call DrawPlayArea_BenchCards
+ xor a
+ call DrawYourOrOppPlayArea_Icons
+ jr .done
+
+.not_equal
+ ld hl, PrizeCardsCoordinateData_YourOrOppPlayArea.opponent
+ call DrawPlayArea_PrizeCards
+ lb de, 6, 5 ; coordinates of opponent's active card
+ call DrawYourOrOppPlayArea_ActiveCardGfx
+ lb de, 1, 2 ; coordinates of opponent's bench cards
+ ld c, 4 ; spacing
+ call DrawPlayArea_BenchCards
+ ld a, $01
+ call DrawYourOrOppPlayArea_Icons
+
+.done
+ call EnableLCD
+ ret
+
+Func_82b6: ; 82b6 (2:42b6)
+ ld a, [wCheckMenuPlayAreaWhichDuelist]
+ ld b, a
+ ld a, [wCheckMenuPlayAreaWhichLayout]
+ cp b
+ jr nz, .not_equal
+
+ ld hl, PrizeCardsCoordinateData_YourOrOppPlayArea.player
+ call DrawPlayArea_PrizeCards
+ ret
+
+.not_equal
+ ld hl, PrizeCardsCoordinateData_YourOrOppPlayArea.opponent
+ call DrawPlayArea_PrizeCards
+ ret
+
+; loads tiles and icons to display the In Play Area screen,
+; and draws the screen
+DrawInPlayAreaScreen: ; 82ce (2:42ce)
+ xor a
+ ld [wTileMapFill], a
+ call ZeroObjectPositions
+
+ ld a, $01
+ ld [wVBlankOAMCopyToggle], a
+ call DoFrame
+ call EmptyScreen
+
+ ld a, $0a
+ ld [wDuelDisplayedScreen], a
+ call Set_OBJ_8x8
+ call LoadCursorTile
+ call LoadSymbolsFont
+ call LoadDeckAndDiscardPileIcons
+
+ lb de, $80, $9f
+ call SetupText
+
+; reset turn holders
+ ldh a, [hWhoseTurn]
+ ld [wCheckMenuPlayAreaWhichDuelist], a
+ ld [wCheckMenuPlayAreaWhichLayout], a
+
+; player prize cards
+ ld hl, PrizeCardsCoordinateData_InPlayArea.player
+ call DrawPlayArea_PrizeCards
+
+; player bench cards
+ lb de, 3, 15
+ ld c, 3
+ call DrawPlayArea_BenchCards
+
+ ld hl, PlayAreaIconCoordinates.player2
+ call DrawInPlayArea_Icons
+
+ call SwapTurn
+ ldh a, [hWhoseTurn]
+ ld [wCheckMenuPlayAreaWhichDuelist], a
+ call SwapTurn
+
+; opponent prize cards
+ ld hl, PrizeCardsCoordinateData_InPlayArea.opponent
+ call DrawPlayArea_PrizeCards
+
+; opponent bench cards
+ lb de, 3, 0
+ ld c, 3
+ call DrawPlayArea_BenchCards
+
+ call SwapTurn
+ ld hl, PlayAreaIconCoordinates.opponent2
+ call DrawInPlayArea_Icons
+
+ call SwapTurn
+ call DrawInPlayArea_ActiveCardGfx
+ ret
+
+; draws players prize cards and bench cards
+_DrawPlayersPrizeAndBenchCards: ; 833c (2:433c)
+ xor a
+ ld [wTileMapFill], a
+ call ZeroObjectPositions
+ ld a, $01
+ ld [wVBlankOAMCopyToggle], a
+ call DoFrame
+ call EmptyScreen
+ call LoadSymbolsFont
+ call LoadDeckAndDiscardPileIcons
+
+; player cards
+ ld a, PLAYER_TURN
+ ld [wCheckMenuPlayAreaWhichDuelist], a
+ ld [wCheckMenuPlayAreaWhichLayout], a
+ ld hl, PrizeCardsCoordinateData_2.player
+ call DrawPlayArea_PrizeCards
+ lb de, 5, 10 ; coordinates
+ ld c, 3 ; spacing
+ call DrawPlayArea_BenchCards
+
+; opponent cards
+ ld a, OPPONENT_TURN
+ ld [wCheckMenuPlayAreaWhichDuelist], a
+ ld hl, PrizeCardsCoordinateData_2.opponent
+ call DrawPlayArea_PrizeCards
+ lb de, 1, 0 ; coordinates
+ ld c, 3 ; spacing
+ call DrawPlayArea_BenchCards
+ ret
+
+; draws the active card gfx at coordinates de
+; of the player (or opponent) depending on wCheckMenuPlayAreaWhichDuelist
+; input:
+; de = coordinates
+DrawYourOrOppPlayArea_ActiveCardGfx: ; 837e (2:437e)
+ push de
+ ld a, DUELVARS_ARENA_CARD
+ ld l, a
+ ld a, [wCheckMenuPlayAreaWhichDuelist]
+ ld h, a
+ ld a, [hl]
+ cp -1
+ jr z, .no_pokemon
+
+ ld d, a
+ ld a, [wCheckMenuPlayAreaWhichDuelist]
+ ld b, a
+ ldh a, [hWhoseTurn]
+ cp b
+ jr nz, .swap
+ ld a, d
+ call LoadCardDataToBuffer1_FromDeckIndex
+ jr .draw
+.swap
+ call SwapTurn
+ ld a, d
+ call LoadCardDataToBuffer1_FromDeckIndex
+ call SwapTurn
+
+.draw
+ 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
+ pop de
+
+; draw card gfx
+ ld a, $a0
+ lb hl, 6, 1
+ lb bc, 8, 6
+ call FillRectangle
+ bank1call ApplyBGP6OrSGB3ToCardImage
+ ret
+
+.no_pokemon
+ pop de
+ ret
+
+; draws player and opponent arena card graphics
+; in the "In Play Area" screen
+DrawInPlayArea_ActiveCardGfx: ; 83cc (2:43cc)
+ xor a
+ ld [wArenaCardsInPlayArea], a
+
+ ld a, DUELVARS_ARENA_CARD
+ call GetTurnDuelistVariable
+ cp -1 ; no pokemon
+ jr z, .opponent1
+
+ push af
+ ld a, [wArenaCardsInPlayArea]
+ or %00000001 ; set the player arena Pokemon bit
+ ld [wArenaCardsInPlayArea], a
+ pop af
+
+; load card gfx
+ call LoadCardDataToBuffer1_FromDeckIndex
+ lb de, $8a, $00
+ ld hl, wLoadedCard1Gfx
+ ld a, [hli]
+ ld h, [hl]
+ ld l, a
+ lb bc, $30, TILE_SIZE
+ call LoadCardGfx
+ bank1call SetBGP6OrSGB3ToCardPalette
+
+.opponent1
+ ld a, DUELVARS_ARENA_CARD
+ call GetNonTurnDuelistVariable
+ cp -1 ; no pokemon
+ jr z, .draw
+
+ push af
+ ld a, [wArenaCardsInPlayArea]
+ or %00000010 ; set the opponent arena Pokemon bit
+ ld [wArenaCardsInPlayArea], a
+ pop af
+
+; load card gfx
+ call SwapTurn
+ call LoadCardDataToBuffer1_FromDeckIndex
+ lb de, $95, $00
+ ld hl, wLoadedCard1Gfx
+ ld a, [hli]
+ ld h, [hl]
+ ld l, a
+ lb bc, $30, TILE_SIZE
+ call LoadCardGfx
+ bank1call SetBGP7OrSGB2ToCardPalette
+ call SwapTurn
+
+.draw
+ ld a, [wArenaCardsInPlayArea]
+ or a
+ ret z ; no arena cards in play
+
+ bank1call FlushAllPalettesOrSendPal23Packet
+ ld a, [wArenaCardsInPlayArea]
+ and %00000001 ; test player arena card bit
+ jr z, .opponent2
+
+; draw player arena card
+ ld a, $a0
+ lb de, 6, 9
+ lb hl, 6, 1
+ lb bc, 8, 6
+ call FillRectangle
+ bank1call ApplyBGP6OrSGB3ToCardImage
+
+.opponent2
+ ld a, [wArenaCardsInPlayArea]
+ and %00000010 ; test opponent arena card bit
+ ret z
+
+; draw opponent arena card
+ call SwapTurn
+ ld a, $50
+ lb de, 6, 2
+ lb hl, 6, 1
+ lb bc, 8, 6
+ call FillRectangle
+ bank1call ApplyBGP7OrSGB2ToCardImage
+ call SwapTurn
+ ret
+
+; draws prize cards depending on the turn
+; loaded in wCheckMenuPlayAreaWhichDuelist
+; input:
+; hl = pointer to coordinates
+DrawPlayArea_PrizeCards: ; 8464 (2:4464)
+ push hl
+ call GetDuelInitialPrizesUpperBitsSet
+ ld a, [wCheckMenuPlayAreaWhichDuelist]
+ ld h, a
+ ld l, DUELVARS_PRIZES
+ ld a, [hl]
+
+ pop hl
+ ld b, 0
+ push af
+; loop each prize card
+.loop
+ inc b
+ ld a, [wDuelInitialPrizes]
+ inc a
+ cp b
+ jr z, .done
+
+ pop af
+ srl a ; right shift prize cards left
+ push af
+ jr c, .not_taken
+ ld a, $e0 ; tile byte for empty slot
+ jr .draw
+.not_taken
+ ld a, $dc ; tile byte for card
+.draw
+ ld e, [hl]
+ inc hl
+ ld d, [hl]
+ inc hl
+
+ push hl
+ push bc
+ lb hl, $01, $02 ; card tile gfx
+ lb bc, 2, 2 ; rectangle size
+ call FillRectangle
+
+ ld a, [wConsole]
+ cp CONSOLE_CGB
+ jr nz, .not_cgb
+ ld a, $02 ; blue colour
+ lb bc, 2, 2
+ lb hl, 0, 0
+ call BankswitchVRAM1
+ call FillRectangle
+ call BankswitchVRAM0
+.not_cgb
+ pop bc
+ pop hl
+ jr .loop
+.done
+ pop af
+ ret
+
+PrizeCardsCoordinateData_YourOrOppPlayArea: ; 0x84b4 (2:44b4)
+; x and y coordinates for player prize cards
+.player
+ db 2, 1
+ db 2, 3
+ db 4, 1
+ db 4, 3
+ db 6, 1
+ db 6, 3
+; x and y coordinates for opponent prize cards
+.opponent
+ db 9, 17
+ db 9, 15
+ db 7, 17
+ db 7, 15
+ db 5, 17
+ db 5, 15
+
+; used by Func_833c
+PrizeCardsCoordinateData_2: ; 0x84cc (2:44cc)
+; x and y coordinates for player prize cards
+.player
+ db 6, 0
+ db 6, 2
+ db 8, 0
+ db 8, 2
+ db 10, 0
+ db 10, 2
+; x and y coordinates for opponent prize cards
+.opponent
+ db 4, 18
+ db 4, 16
+ db 2, 18
+ db 2, 16
+ db 0, 18
+ db 0, 16
+
+PrizeCardsCoordinateData_InPlayArea: ; 0x84e4 (2:44e4)
+; x and y coordinates for player prize cards
+.player
+ db 9, 1
+ db 9, 3
+ db 11, 1
+ db 11, 3
+ db 13, 1
+ db 13, 3
+; x and y coordinates for opponent prize cards
+.opponent
+ db 6, 17
+ db 6, 15
+ db 4, 17
+ db 4, 15
+ db 2, 17
+ db 2, 15
+
+; calculates bits set up to the number of initial prizes, with upper 2 bits set, i.e:
+; 6 prizes: a = %11111111
+; 4 prizes: a = %11001111
+; 3 prizes: a = %11000111
+; 2 prizes: a = %11000011
+GetDuelInitialPrizesUpperBitsSet: ; 84fc (2:44fc)
+ ld a, [wDuelInitialPrizes]
+ ld b, $01
+.loop
+ or a
+ jr z, .done
+ sla b
+ dec a
+ jr .loop
+.done
+ dec b
+ ld a, b
+ or %11000000
+ ld [wDuelInitialPrizesUpperBitsSet], a
+ ret
+
+; draws filled and empty bench slots depending on the turn loaded in wCheckMenuPlayAreaWhichDuelist
+; if wCheckMenuPlayAreaWhichDuelist is different from wCheckMenuPlayAreaWhichLayout adjusts coordinates of the bench slots
+; input:
+; de = coordinates to draw bench
+; c = spacing between slots
+DrawPlayArea_BenchCards: ; 8511 (2:4511)
+ ld a, [wCheckMenuPlayAreaWhichLayout]
+ ld b, a
+ ld a, [wCheckMenuPlayAreaWhichDuelist]
+ cp b
+ jr z, .skip
+
+; adjust the starting bench position for opponent
+ ld a, d
+ add c
+ add c
+ add c
+ add c
+ ld d, a
+ ; d = d + 4 * c
+
+; have the spacing go to the left instead of right
+ xor a
+ sub c
+ ld c, a
+ ; c = $ff - c + 1
+
+ ld a, [wCheckMenuPlayAreaWhichDuelist]
+.skip
+ ld h, a
+ ld l, DUELVARS_NUMBER_OF_POKEMON_IN_PLAY_AREA
+ ld b, [hl]
+ ld l, DUELVARS_BENCH1_CARD_STAGE
+.loop_1
+ dec b ; num of Bench Pokemon left
+ jr z, .done
+
+ ld a, [hli]
+ push hl
+ push bc
+ sla a
+ sla a
+ add $e4
+; a holds the correct stage gfx tile
+ ld b, a
+ push bc
+
+ lb hl, 1, 2
+ lb bc, 2, 2
+ call FillRectangle
+
+ ld a, [wConsole]
+ cp CONSOLE_CGB
+ pop bc
+ jr nz, .next
+
+ ld a, b
+ cp $ec ; tile offset of 2 stage
+ jr z, .two_stage
+ cp $f0 ; tile offset of 2 stage with no 1 stage
+ jr z, .two_stage
+
+ ld a, $02 ; blue colour
+ jr .palette
+.two_stage
+ ld a, $01 ; red colour
+.palette
+ lb bc, 2, 2
+ lb hl, 0, 0
+ call BankswitchVRAM1
+ call FillRectangle
+ call BankswitchVRAM0
+
+.next ; adjust coordinates for next card
+ pop bc
+ pop hl
+ ld a, d
+ add c
+ ld d, a
+ ; d = d + c
+ jr .loop_1
+
+.done
+ ld a, [wCheckMenuPlayAreaWhichDuelist]
+ ld h, a
+ ld l, DUELVARS_NUMBER_OF_POKEMON_IN_PLAY_AREA
+ ld b, [hl]
+ ld a, MAX_PLAY_AREA_POKEMON
+ sub b
+ ret z ; return if already full
+
+ ld b, a
+ inc b
+.loop_2
+ dec b
+ ret z
+
+ push bc
+ ld a, $f4 ; empty bench slot tile
+ lb hl, 1, 2
+ lb bc, 2, 2
+ call FillRectangle
+
+ ld a, [wConsole]
+ cp CONSOLE_CGB
+ jr nz, .not_cgb
+
+ ld a, $02 ; colour
+ lb bc, 2, 2
+ lb hl, 0, 0
+ call BankswitchVRAM1
+ call FillRectangle
+ call BankswitchVRAM0
+
+.not_cgb
+ pop bc
+ ld a, d
+ add c
+ ld d, a
+ jr .loop_2
+
+; draws Your/Opp Play Area icons depending on value in a
+; the icons correspond to Deck, Discard Pile, and Hand
+; the corresponding number of cards is printed alongside each icon
+; for "Hand", text is displayed rather than an icon
+; input:
+; a = $00: draws player icons
+; a = $01: draws opponent icons
+DrawYourOrOppPlayArea_Icons: ; 85aa (2:45aa)
+ or a
+ jr nz, .opponent
+ ld hl, PlayAreaIconCoordinates.player1
+ jr .draw
+.opponent
+ ld hl, PlayAreaIconCoordinates.opponent1
+
+.draw
+; hand icon and value
+ ld a, [wCheckMenuPlayAreaWhichDuelist]
+ ld d, a
+ ld e, DUELVARS_NUMBER_OF_CARDS_IN_HAND
+ ld a, [de]
+ ld b, a
+ ld a, $d0 ; hand icon, unused?
+ call DrawPlayArea_HandText
+
+; deck icon and value
+ ld a, [wCheckMenuPlayAreaWhichDuelist]
+ ld d, a
+ ld e, DUELVARS_NUMBER_OF_CARDS_NOT_IN_DECK
+ ld a, [de]
+ ld b, a
+ ld a, DECK_SIZE
+ sub b
+ ld b, a
+ ld a, $d4 ; deck icon
+ call DrawPlayArea_IconWithValue
+
+; discard pile icon and value
+ ld a, [wCheckMenuPlayAreaWhichDuelist]
+ ld d, a
+ ld e, DUELVARS_NUMBER_OF_CARDS_IN_DISCARD_PILE
+ ld a, [de]
+ ld b, a
+ ld a, $d8 ; discard pile icon
+ call DrawPlayArea_IconWithValue
+ ret
+
+; draws the interface icon corresponding to the gfx tile in a
+; also prints the number in decimal corresponding to the value in b
+; the coordinates in screen are given by [hl]
+; input:
+; a = tile for the icon
+; b = value to print alongside icon
+; hl = pointer to coordinates
+DrawPlayArea_IconWithValue: ; 85e1 (2:45e1)
+; drawing the icon
+ ld d, [hl]
+ inc hl
+ ld e, [hl]
+ inc hl
+ push hl
+ push bc
+ lb hl, 1, 2
+ lb bc, 2, 2
+ call FillRectangle
+
+ ld a, [wConsole]
+ cp CONSOLE_CGB
+ jr nz, .skip
+
+ ld a, $02
+ lb bc, 2, 2
+ lb hl, 0, 0
+ call BankswitchVRAM1
+ call FillRectangle
+ call BankswitchVRAM0
+
+.skip
+; adjust coordinate to the lower right
+ inc d
+ inc d
+ inc e
+ call InitTextPrinting
+ pop bc
+ ld a, b
+ call CalculateOnesAndTensDigits
+
+ ld hl, wOnesAndTensPlace
+ ld a, [hli]
+ ld b, a
+ ld a, [hl]
+
+; loading numerical and cross symbols
+ ld hl, wDefaultText
+ ld [hl], TX_SYMBOL
+ inc hl
+ ld [hl], SYM_CROSS
+ inc hl
+ ld [hl], TX_SYMBOL
+ inc hl
+ ld [hli], a ; tens place
+ ld [hl], TX_SYMBOL
+ inc hl
+ ld a, b
+ ld [hli], a ; ones place
+ ld [hl], TX_END
+
+; printing the decimal value
+ ld hl, wDefaultText
+ call ProcessText
+ pop hl
+ ret
+
+PlayAreaIconCoordinates: ; 8635 (2:4635)
+; used for "Your/Opp. Play Area" screen
+.player1
+ db 15, 7 ; hand
+ db 15, 2 ; deck
+ db 15, 4 ; discard pile
+.opponent1
+ db 1, 5 ; hand
+ db 1, 9 ; deck
+ db 1, 7 ; discard pile
+
+; used for "In Play Area" screen
+.player2
+ db 15, 14
+ db 15, 9
+ db 15, 11
+.opponent2
+ db 0, 2
+ db 0, 6
+ db 0, 4
+
+; draws In Play Area icons depending on value in a
+; the icons correspond to Deck, Discard Pile, and Hand
+; the corresponding number of cards is printed alongside each icon
+; for "Hand", text is displayed rather than an icon
+; input:
+; a = $00: draws player icons
+; a = $01: draws opponent icons
+DrawInPlayArea_Icons: ; 864d (2:464d)
+ ldh a, [hWhoseTurn]
+ ld d, a
+ ld e, DUELVARS_NUMBER_OF_CARDS_IN_HAND
+ ld a, [de]
+ ld b, a
+ ld a, $d0 ; hand icon, unused?
+ call DrawPlayArea_HandText
+
+; deck
+ ldh a, [hWhoseTurn]
+ ld d, a
+ ld e, DUELVARS_NUMBER_OF_CARDS_NOT_IN_DECK
+ ld a, [de]
+ ld b, a
+ ld a, DECK_SIZE
+ sub b
+ ld b, a
+ ld a, $d4 ; deck tile
+ call DrawPlayArea_IconWithValue
+
+; discard pile
+ ldh a, [hWhoseTurn]
+ ld d, a
+ ld e, $ed
+ ld a, [de]
+ ld b, a
+ ld a, $d8 ; discard pile tile
+ call DrawPlayArea_IconWithValue
+ ret
+
+; prints text HandText_2 and a cross with decimal value of b
+; input
+; b = value to print alongside text
+DrawPlayArea_HandText: ; 8676 (2:4676)
+ ld d, [hl]
+ inc hl
+ ld e, [hl]
+ inc hl
+
+; text
+ push hl
+ push bc
+ call InitTextPrinting
+ ldtx hl, HandText_2
+ call ProcessTextFromID
+ pop bc
+
+; decimal value
+ ld a, b
+ call CalculateOnesAndTensDigits
+ ld hl, wOnesAndTensPlace
+ ld a, [hli]
+ ld b, a
+ ld a, [hl]
+
+ ld hl, wDefaultText
+ ld [hl], TX_SYMBOL
+ inc hl
+ ld [hl], SYM_CROSS
+ inc hl
+ ld [hl], TX_SYMBOL
+ inc hl
+ ld [hli], a
+ ld [hl], TX_SYMBOL
+ inc hl
+
+; draw to screen
+ ld a, b
+ ld [hli], a
+ ld [hl], TX_END
+ ld hl, wDefaultText
+ call ProcessText
+ pop hl
+ ret
+
+; handle player input in menu in Your or Opp. Play Area
+; works out which cursor coordinate to go to
+; and sets carry flag if A or B are pressed
+; returns a = $1 if A pressed
+; returns a = $ff if B pressed
+HandleCheckMenuInput_YourOrOppPlayArea: ; 86ac (2:46ac)
+ xor a
+ ld [wcfe3], a
+ ld a, [wCheckMenuCursorXPosition]
+ ld d, a
+ ld a, [wCheckMenuCursorYPosition]
+ ld e, a
+
+; d = cursor x position
+; e = cursor y position
+
+ ldh a, [hDPadHeld]
+ or a
+ jr z, .skip
+
+; pad is pressed
+ ld a, [wce5e]
+ and %10000000
+ ldh a, [hDPadHeld]
+ jr nz, .check_vertical
+ bit D_LEFT_F, a ; test left button
+ jr nz, .horizontal
+ bit D_RIGHT_F, a ; test right button
+ jr z, .check_vertical
+
+; handle horizontal input
+.horizontal
+ ld a, [wce5e]
+ and %01111111
+ or a
+ jr nz, .asm_86dd ; jump if wce5e's lower 7 bits aren't set
+ ld a, e
+ or a
+ jr z, .flip_x ; jump if y is 0
+
+; wce5e = %10000000
+; e = 1
+ dec e ; change y position
+ jr .flip_x
+
+.asm_86dd
+ ld a, e
+ or a
+ jr nz, .flip_x ; jump if y is not 0
+ inc e ; change y position
+.flip_x
+ ld a, d
+ xor $01 ; flip x position
+ ld d, a
+ jr .erase
+
+.check_vertical
+ bit D_UP_F, a
+ jr nz, .vertical
+ bit D_DOWN_F, a
+ jr z, .skip
+
+; handle vertical input
+.vertical
+ ld a, d
+ or a
+ jr z, .flip_y ; jump if x is 0
+ dec d
+.flip_y
+ ld a, e
+ xor $01 ; flip y position
+ ld e, a
+
+.erase
+ ld a, $01
+ ld [wcfe3], a
+ push de
+ call EraseCheckMenuCursor_YourOrOppPlayArea
+ pop de
+
+;update x and y cursor positions
+ ld a, d
+ ld [wCheckMenuCursorXPosition], a
+ ld a, e
+ ld [wCheckMenuCursorYPosition], a
+
+; reset cursor blink
+ xor a
+ ld [wCheckMenuCursorBlinkCounter], a
+
+.skip
+ ldh a, [hKeysPressed]
+ and A_BUTTON | B_BUTTON
+ jr z, .sfx
+ and A_BUTTON
+ jr nz, .a_pressed
+
+; B pressed
+ ld a, $ff ; cancel
+ call PlaySFXConfirmOrCancel
+ scf
+ ret
+
+.a_pressed
+ call DisplayCheckMenuCursor_YourOrOppPlayArea
+ ld a, $01
+ call PlaySFXConfirmOrCancel
+ scf
+ ret
+
+.sfx
+ ld a, [wcfe3]
+ or a
+ jr z, .draw_cursor
+ call PlaySFX
+
+.draw_cursor
+ ld hl, wCheckMenuCursorBlinkCounter
+ ld a, [hl]
+ inc [hl]
+ and %00001111
+ ret nz ; only update cursor if blink's lower nibble is 0
+
+ ld a, SYM_CURSOR_R ; cursor byte
+ bit 4, [hl] ; only draw cursor if blink counter's fourth bit is not set
+ jr z, DrawCheckMenuCursor_YourOrOppPlayArea
+; fallthrough
+
+; transforms cursor position into coordinates
+; in order to draw byte on menu cursor
+EraseCheckMenuCursor_YourOrOppPlayArea: ; 8741 (2:4741)
+ ld a, SYM_SPACE ; white tile
+; fallthrough
+
+; draws in the cursor position
+; input:
+; a = tile byte to draw
+DrawCheckMenuCursor_YourOrOppPlayArea: ; 8743 (2:4743)
+ ld e, a
+ ld a, 10
+ ld l, a
+ ld a, [wCheckMenuCursorXPosition]
+ ld h, a
+ call HtimesL
+; h = 10 * cursor x pos
+
+ ld a, l
+ add 1
+ ld b, a
+ ld a, [wCheckMenuCursorYPosition]
+ sla a
+ add 14
+ ld c, a
+; c = 11 + 2 * cursor y pos + 14
+
+; draw tile loaded in e
+ ld a, e
+ call WriteByteToBGMap0
+ or a
+ ret
+
+DisplayCheckMenuCursor_YourOrOppPlayArea: ; 8760 (2:4760)
+ ld a, SYM_CURSOR_R ; load cursor byte
+ jr DrawCheckMenuCursor_YourOrOppPlayArea
+
+; seems to be function to deal with the Peek menu
+; to select a prize card to view
Func_8764: ; 8764 (2:4764)
- INCROM $8764, $8932
+ call Set_OBJ_8x8
+ call LoadCursorTile
+; reset ce5c and ce56
+ xor a
+ ld [$ce5c], a
+ ld [$ce56], a
+
+; draw play area screen for the turn player
+ ldh a, [hWhoseTurn]
+ ld h, a
+ ld l, a
+ call DrawYourOrOppPlayAreaScreen
+
+.swap
+ ld a, [$ce56]
+ or a
+ jr z, .draw_menu
+; if ce56 != 0, swap turn
+ call SwapTurn
+ xor a
+ ld [$ce56], a
+
+.draw_menu
+ xor a
+ ld hl, PlayAreaMenuParameters
+ call InitializeMenuParameters
+ call DrawWideTextBox
+
+ ld hl, YourOrOppPlayAreaData
+ call PlaceTextItems
+
+.loop_1
+ call DoFrame
+ call HandleMenuInput ; await input
+ jr nc, .loop_1
+ cp $ff
+ jr z, .loop_1
+
+ call EraseCursor
+ ldh a, [hCurMenuItem]
+ or a
+ jp nz, Func_8883 ; jump if not first option
+
+; hCurMenuItem = 0
+ ld a, [wCheckMenuPlayAreaWhichDuelist]
+ ld b, a
+ ldh a, [hWhoseTurn]
+ cp b
+ jr z, .text
+
+; switch the play area to draw
+ ld h, a
+ ld l, a
+ call DrawYourOrOppPlayAreaScreen
+ xor a
+ ld [$ce56], a
+
+.text
+ call DrawWideTextBox
+ lb de, $01, $0e
+ call InitTextPrinting
+ ldtx hl, WhichCardWouldYouLikeToSeeText
+ call ProcessTextFromID
+
+ xor a
+ ld [wPrizeCardCursorPosition], a
+ ld de, Func_88c2
+ ld hl, wce53
+ ld [hl], e
+ inc hl
+ ld [hl], d
+
+.loop_2
+ ld a, $01
+ ld [wVBlankOAMCopyToggle], a
+ call DoFrame
+ call Func_89ae
+ jr c, .asm_87e7
+ jr .loop_2
+.asm_87e7
+ cp $ff
+ jr nz, .asm_87f0
+ call Func_8aa1
+ jr .swap
+.asm_87f0
+ ld hl, .asm_87f8
+ call JumpToFunctionInTable
+ jr .loop_2
+
+.asm_87f8
+rept 6
+ dw Func_8819
+endr
+ dw Func_883c
+ dw Func_8849
+
+YourOrOppPlayAreaData: ; 8808 (2:4808)
+ textitem 2, 14, YourPlayAreaText
+ textitem 2, 16, OppPlayAreaText
+ db $ff
+
+PlayAreaMenuParameters: ; 8811 (2:4811)
+ db 1, 14 ; 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
+
+Func_8819: ; 8819 (2:4819)
+ ld a, [wPrizeCardCursorPosition]
+ ld c, a
+ ld b, $01
+
+; left-shift b a number of times
+; corresponding to this prize card
+.loop
+ or a
+ jr z, .asm_8827
+ sla b
+ dec a
+ jr .loop
+
+.asm_8827
+ ld a, DUELVARS_PRIZES
+ call GetTurnDuelistVariable
+ and b
+ ret z ; return if prize card taken
+
+ ld a, c
+ add $40
+ ld [$ce5c], a
+ ld a, c
+ add DUELVARS_PRIZE_CARDS
+ call GetTurnDuelistVariable
+ jr Func_8855
+
+Func_883c:
+ call CreateHandCardList
+ ret c
+ ld hl, wDuelTempList
+ call ShuffleCards
+ ld a, [hl]
+ jr Func_8855
+
+Func_8849:
+ call CreateDeckCardList
+ ret c
+ ld a, %01111111
+ ld [$ce5c], a
+ ld a, [wDuelTempList]
+; fallthrough
+
+; input:
+; a = deck index of card to be loaded
+; output:
+; a = ce5c
+; with upper bit set if turn was swapped
+Func_8855:
+ ld b, a
+ ld a, [$ce5c]
+ or a
+ jr nz, .display
+ ld a, b
+ ld [$ce5c], a
+.display
+ ld a, b
+ call LoadCardDataToBuffer1_FromDeckIndex
+ call Set_OBJ_8x16
+ bank1call OpenCardPage_FromHand
+ ld a, $01
+ ld [wVBlankOAMCopyToggle], a
+ pop af
+
+; if ce56 != 0, swap turn
+ ld a, [$ce56]
+ or a
+ jr z, .dont_swap
+ call SwapTurn
+ ld a, [$ce5c]
+ or %10000000
+ ret
+.dont_swap
+ ld a, [$ce5c]
+ ret
+
+Func_8883: ; 8883 (2:4883)
+ ld a, [wCheckMenuPlayAreaWhichDuelist]
+ ld b, a
+ ldh a, [hWhoseTurn]
+ cp b
+ jr nz, .text
+
+ ld l, a
+ cp PLAYER_TURN
+ jr nz, .opponent
+ ld a, OPPONENT_TURN
+ jr .draw
+.opponent
+ ld a, PLAYER_TURN
+
+.draw
+ ld h, a
+ call DrawYourOrOppPlayAreaScreen
+
+.text
+ call DrawWideTextBox
+ lb de, $01, $0e
+ call InitTextPrinting
+ ldtx hl, WhichCardWouldYouLikeToSeeText
+ call ProcessTextFromID
+
+ xor a
+ ld [wPrizeCardCursorPosition], a
+ ld de, $48fa
+ ld hl, wce53
+ ld [hl], e
+ inc hl
+ ld [hl], d
+
+ call SwapTurn
+ ld a, $01
+ ld [$ce56], a
+ jp Func_8764.loop_2
+
+Func_88c2: ; 88c2 (2:48c2)
+ INCROM $88c2, $8932
Func_8932: ; 8932 (2:4932)
- INCROM $8932, $8aaa
+ INCROM $8932, $8992
+
+LoadCursorTile: ; 8992 (2:4992)
+ ld de, v0Tiles0
+ ld hl, .tile_data
+ ld b, 16
+ call SafeCopyDataHLtoDE
+ ret
+
+.tile_data: ; 899e (2:499e)
+ db $e0, $c0, $98, $b0, $84, $8c, $83, $82
+ db $86, $8f, $9d, $be, $f4, $f8, $50, $60
+
+Func_89ae: ; 89ae (2:49ae)
+ xor a
+ ld [wcfe3], a
+
+ ld hl, wce53
+ ld e, [hl]
+ inc hl
+ ld d, [hl]
+
+ ld a, [wPrizeCardCursorPosition]
+ ld [wce61], a
+ ld l, a
+ ld h, 7
+ call HtimesL
+ add hl, de
+; hl = [wce53] + 7 * wce52
+
+ ldh a, [hDPadHeld]
+ or a
+ jp z, .asm_8a4f
+
+ inc hl
+ inc hl
+ inc hl
+ bit D_UP_F, a
+ jr z, .asm_89d5
+ ld a, [hl]
+ jr .asm_89eb
+
+.asm_89d5
+ inc hl
+ bit D_DOWN_F, a
+ jr z, .asm_89dd
+ ld a, [hl]
+ jr .asm_89eb
+.asm_89dd
+ inc hl
+ bit D_RIGHT_F, a
+ jr z, .asm_89e5
+ ld a, [hl]
+ jr .asm_89eb
+.asm_89e5
+ inc hl
+ bit D_LEFT_F, a
+ jr z, .asm_8a4f
+ ld a, [hl]
+.asm_89eb
+ ld [wPrizeCardCursorPosition], a
+ cp $08
+ jr nc, .asm_8a46
+ ld b, $01
+.asm_89f4
+ or a
+ jr z, .asm_89fc
+ sla b
+ dec a
+ jr .asm_89f4
+.asm_89fc
+ ld a, [wDuelInitialPrizesUpperBitsSet]
+ and b
+ jr nz, .asm_8a46
+ ld a, [wce61]
+ cp $06
+ jr nz, Func_89ae
+ ldh a, [hDPadHeld]
+ bit 4, a
+ jr nz, .asm_8a13
+ bit 5, a
+ jr z, Func_89ae
+.asm_8a13
+ ld a, [wDuelInitialPrizes]
+ cp $05
+ jr nc, .asm_8a46
+ ld a, [wPrizeCardCursorPosition]
+ cp $05
+ jr nz, .asm_8a28
+ ld a, $03
+ ld [wPrizeCardCursorPosition], a
+ jr .asm_8a2d
+.asm_8a28
+ ld a, $02
+ ld [wPrizeCardCursorPosition], a
+.asm_8a2d
+ ld a, [wDuelInitialPrizes]
+ cp $03
+ jr nc, .asm_8a3c
+ ld a, [wPrizeCardCursorPosition]
+ sub $02
+ ld [wPrizeCardCursorPosition], a
+.asm_8a3c
+ ld a, [wPrizeCardCursorPosition]
+ ld [wce61], a
+ ld b, $01
+ jr .asm_89f4
+.asm_8a46
+ ld a, $01
+ ld [wcfe3], a
+
+; reset cursor blink
+ xor a
+ ld [wCheckMenuCursorBlinkCounter], a
+
+.asm_8a4f
+ ldh a, [hKeysPressed]
+ and A_BUTTON | B_BUTTON
+ jr z, .asm_8a6d
+ and A_BUTTON
+ jr nz, .asm_8a60
+ ld a, $ff ; cancel
+ call PlaySFXConfirmOrCancel
+ scf
+ ret
+
+.asm_8a60
+ call Func_8a82
+ ld a, $01
+ call PlaySFXConfirmOrCancel
+ ld a, [wPrizeCardCursorPosition]
+ scf
+ ret
+.asm_8a6d
+ ld a, [wcfe3]
+ or a
+ jr z, .asm_8a76
+ call PlaySFX
+.asm_8a76
+ ld hl, wCheckMenuCursorBlinkCounter
+ ld a, [hl]
+ inc [hl]
+ and $0f
+ ret nz
+ bit 4, [hl]
+ jr nz, Func_8aa1
+
+Func_8a82 ; 8a82 (2:4a82)
+ call ZeroObjectPositions
+ ld hl, wce53
+ ld e, [hl]
+ inc hl
+ ld d, [hl]
+ ld a, [wPrizeCardCursorPosition]
+ ld l, a
+ ld h, 7
+ call HtimesL
+ add hl, de
+; hl = [wce53] + 7 * wce52
+
+ ld d, [hl]
+ inc hl
+ ld e, [hl]
+ inc hl
+ ld b, [hl]
+ ld c, $00
+ call SetOneObjectAttributes
+ or a
+ ret
+
+Func_8aa1: ; 8aa1 (2:4aa1)
+ call ZeroObjectPositions
+ ld a, $01
+ ld [wVBlankOAMCopyToggle], a
+ ret
+; 0x8aaa
Func_8aaa: ; 8aaa (2:4aaa)
INCROM $8aaa, $8b85
@@ -126,15 +1895,15 @@ Func_8dea: ; 8dea (2:4dea)
ld [wceb1], a
call Func_8ff2
jp nc, Func_8e05
- ld a, $ff
- call Func_90fb
+ ld a, $ff ; cancel
+ call PlaySFXConfirmOrCancel
call Func_8fe8
scf
ret
Func_8e05: ; 8e05 (2:4e05)
ld a, $1
- call Func_90fb
+ call PlaySFXConfirmOrCancel
call GetPointerToDeckCards
push hl
call GetPointerToDeckName
@@ -167,21 +1936,21 @@ Func_8e42: ; 8e42 (2:4e42)
call DrawWideTextBox
ld hl, Unknown_9027
call PlaceTextItems
- call Func_905a
+ call ResetCheckMenuCursorPositionAndBlink
.asm_8e4e
call DoFrame
- call Func_9065
+ call HandleCheckMenuInput
jp nc, .asm_8e4e
cp $ff
jr nz, .asm_8e64
- call Func_90d8
+ call EraseCheckMenuCursor
ld a, [wceb1]
jp Func_8dbc
.asm_8e64
- ld a, [wceaf]
+ ld a, [wCheckMenuCursorXPosition]
or a
jp nz, Func_8f8a
- ld a, [wceb0]
+ ld a, [wCheckMenuCursorYPosition]
or a
jp nz, .asm_8ecf
call GetPointerToDeckCards
@@ -334,7 +2103,7 @@ Func_8f38: ; 8f38 (2:4f38)
ret
Func_8f8a: ; 8f8a (2:4f8a)
- ld a, [wceb0]
+ ld a, [wCheckMenuCursorYPosition]
or a
jp nz, Func_9026
call Func_8ff2
@@ -426,116 +2195,151 @@ GetPointerToDeckCards: ; 9048 (2:5048)
pop af
ret
-Func_905a: ; 905a (2:505a)
+ResetCheckMenuCursorPositionAndBlink: ; 905a (2:505a)
xor a
- ld [wceaf], a
- ld [wceb0], a
+ ld [wCheckMenuCursorXPosition], a
+ ld [wCheckMenuCursorYPosition], a
ld [wCheckMenuCursorBlinkCounter], a
ret
-Func_9065: ; 9065 (2:5065)
+; handle player input in check menu
+; works out which cursor coordinate to go to
+; and sets carry flag if A or B are pressed
+; returns a = $1 if A pressed
+; returns a = $ff if B pressed
+HandleCheckMenuInput: ; 9065 (2:5065)
xor a
ld [wcfe3], a
- ld a, [wceaf]
+ ld a, [wCheckMenuCursorXPosition]
ld d, a
- ld a, [wceb0]
+ ld a, [wCheckMenuCursorYPosition]
ld e, a
+
+; d = cursor x position
+; e = cursor y position
+
ldh a, [hDPadHeld]
or a
- jr z, .asm_90a6
+ jr z, .no_pad
bit D_LEFT_F, a
- jr nz, .asm_907e
+ jr nz, .horizontal
bit D_RIGHT_F, a
- jr z, .asm_9084
-.asm_907e
+ jr z, .check_vertical
+
+; handle horizontal input
+.horizontal
ld a, d
- xor $1
+ xor $1 ; flips x coordinate
ld d, a
- jr .asm_9090
-.asm_9084
+ jr .okay
+.check_vertical
bit D_UP_F, a
- jr nz, .asm_908c
+ jr nz, .vertical
bit D_DOWN_F, a
- jr z, .asm_90a6
-.asm_908c
+ jr z, .no_pad
+
+; handle vertical input
+.vertical
ld a, e
- xor $1
+ xor $01 ; flips y coordinate
ld e, a
-.asm_9090
- ld a, $1
+
+.okay
+ ld a, $01
ld [wcfe3], a
push de
- call Func_90d8
+ call EraseCheckMenuCursor
pop de
+
+;update x and y cursor positions
ld a, d
- ld [wceaf], a
+ ld [wCheckMenuCursorXPosition], a
ld a, e
- ld [wceb0], a
+ ld [wCheckMenuCursorYPosition], a
+
+; reset cursor blink
xor a
ld [wCheckMenuCursorBlinkCounter], a
-.asm_90a6
+.no_pad
ldh a, [hKeysPressed]
and A_BUTTON | B_BUTTON
- jr z, .asm_90c1
+ jr z, .no_input
and A_BUTTON
- jr nz, .asm_90b7
- ld a, $ff
- call Func_90fb
+ jr nz, .a_press
+ ld a, $ff ; cancel
+ call PlaySFXConfirmOrCancel
scf
ret
-.asm_90b7
- call Func_90f7
- ld a, $1
- call Func_90fb
+
+.a_press
+ call DisplayCheckMenuCursor
+ ld a, $01
+ call PlaySFXConfirmOrCancel
scf
ret
-.asm_90c1
+
+.no_input
ld a, [wcfe3]
or a
- jr z, .asm_90ca
+ jr z, .check_blink
call PlaySFX
-.asm_90ca
+
+.check_blink
ld hl, wCheckMenuCursorBlinkCounter
ld a, [hl]
inc [hl]
- and $f
- ret nz
- ld a, $f
- bit 4, [hl]
- jr z, asm_90da
-Func_90d8: ; 90d8 (2:50d8)
- ld a, $0
-asm_90da
+ and %00001111
+ ret nz ; only update cursor if blink's lower nibble is 0
+
+ ld a, SYM_CURSOR_R ; cursor byte
+ bit 4, [hl] ; only draw cursor if blink counter's fourth bit is not set
+ jr z, DrawCheckMenuCursor
+
+; draws in the cursor position
+EraseCheckMenuCursor: ; 90d8 (2:50d8)
+ ld a, SYM_SPACE ; empty cursor
+; fallthrough
+
+; draws in the cursor position
+; input:
+; a = tile byte to draw
+DrawCheckMenuCursor:
ld e, a
- ld a, $a
+ ld a, 10
ld l, a
- ld a, [wceaf]
+ ld a, [wCheckMenuCursorXPosition]
ld h, a
call HtimesL
+
ld a, l
- add $1
+ add 1
ld b, a
- ld a, [wceb0]
+ ld a, [wCheckMenuCursorYPosition]
sla a
- add $e
+ add 14
ld c, a
+
ld a, e
call WriteByteToBGMap0
or a
ret
-Func_90f7: ; 90f7 (2:50f7)
- ld a, $f
- jr asm_90da
+DisplayCheckMenuCursor: ; 90f7 (2:50f7)
+ ld a, SYM_CURSOR_R
+ jr DrawCheckMenuCursor
-Func_90fb: ; 90fb (2:50fb)
+; plays sound depending on value in a
+; input:
+; a = $ff: play cancel sound
+; a != $ff: play confirm sound
+PlaySFXConfirmOrCancel: ; 90fb (2:50fb)
push af
inc a
jr z, .asm_9103
- ld a, SFX_02
+ ld a, SFX_02 ; confirmation sfx
jr .asm_9105
.asm_9103
- ld a, SFX_03
+ ld a, SFX_03 ; cancellation sfx
.asm_9105
call PlaySFX
pop af
@@ -784,7 +2588,47 @@ Func_9345: ; 9345 (2:5345)
INCROM $9345, $9843
Func_9843: ; 9843 (2:5843)
- INCROM $9843, $9e41
+ INCROM $9843, $98a6
+
+; determines the ones and tens digits in a for printing
+; the ones place is added $20 (SYM_0) so that it maps to a numerical character
+; if the tens is 0, it maps to an empty character
+; a = value to calculate digits
+CalculateOnesAndTensDigits: ; 98a6 (2:58a6)
+ push af
+ push bc
+ push de
+ push hl
+ ld c, -1
+.loop
+ inc c
+ sub 10
+ jr nc, .loop
+ jr z, .zero1
+ add 10
+ ; a = a mod 10
+ ; c = floor(a / 10)
+.zero1
+; ones digit
+ add SYM_0
+ ld hl, wOnesAndTensPlace
+ ld [hli], a
+
+; tens digit
+ ld a, c
+ or a
+ jr z, .zero2
+ add SYM_0
+.zero2
+ ld [hl], a
+
+ pop hl
+ pop de
+ pop bc
+ pop af
+ ret
+
+ INCROM $98c7, $9e41
Func_9e41: ; 9e41 (2:5e41)
INCROM $9e41, $a288
@@ -824,12 +2668,12 @@ Func_b19d: ; b19d (2:719d)
ld a, [wcea1]
add b
ld [wd088], a
- call Func_905a
+ call ResetCheckMenuCursorPositionAndBlink
call DrawWideTextBox
ld hl, $7274
call PlaceTextItems
call DoFrame
- call Func_9065
+ call HandleCheckMenuInput
jp nc, $71e7
cp $ff
jr nz, .asm_b1fa
@@ -837,9 +2681,9 @@ Func_b19d: ; b19d (2:719d)
jp $71b3
.asm_b1fa
- ld a, [wceb0]
+ ld a, [wCheckMenuCursorYPosition]
sla a
- ld hl, wceaf
+ ld hl, wCheckMenuCursorXPosition
add [hl]
or a
jr nz, .asm_b22c
@@ -972,7 +2816,7 @@ Func_ba04: ; ba04 (2:7a04)
or a
jr z, .asm_ba40
ld a, $1
- call Func_90fb
+ call PlaySFXConfirmOrCancel
call $7653
call Func_8e1f
call $7644
@@ -992,7 +2836,7 @@ Func_ba04: ; ba04 (2:7a04)
cp $ff
jp z, $7b0d
ld [wd088], a
- call Func_905a
+ call ResetCheckMenuCursorPositionAndBlink
xor a
ld [wce5e], a
call DrawWideTextBox
@@ -1007,9 +2851,9 @@ Func_ba04: ; ba04 (2:7a04)
jp $7a25
.asm_badf
- ld a, [wceb0]
+ ld a, [wCheckMenuCursorYPosition]
sla a
- ld hl, wceaf
+ ld hl, wCheckMenuCursorXPosition
add [hl]
or a
jr nz, .asm_bb09
@@ -1069,7 +2913,7 @@ Func_ba04: ; ba04 (2:7a04)
or a
jp z, $7a40
ld a, $1
- call Func_90fb
+ call PlaySFXConfirmOrCancel
call $7653
xor a
call $6dfe
diff --git a/src/engine/bank06.asm b/src/engine/bank06.asm
index c3a26c4..d08e6e7 100644
--- a/src/engine/bank06.asm
+++ b/src/engine/bank06.asm
@@ -161,7 +161,7 @@ OpenInPlayAreaScreen: ; 180d5 (6:40d5)
.start
xor a
ld [wCheckMenuCursorBlinkCounter], a
- farcall $2, $42ce
+ farcall DrawInPlayAreaScreen
call EnableLCD
call IsClairvoyanceActive
jr c, .clairvoyance_on
@@ -564,7 +564,6 @@ OpenInPlayAreaScreen_HandleInput: ; 183bb (6:43bb)
pop af
ld [wInPlayAreaCursorPosition], a
-
cp $05
jr c, .player_area
cp $0b
@@ -651,14 +650,14 @@ OpenInPlayAreaScreen_HandleInput: ; 183bb (6:43bb)
; pressed b button
ld a, -1
- farcall Func_90fb
+ farcall PlaySFXConfirmOrCancel
scf
ret
.a_button
call .draw_cursor
ld a, $01
- farcall Func_90fb
+ farcall PlaySFXConfirmOrCancel
ld a, [wInPlayAreaCursorPosition]
scf
ret
@@ -706,7 +705,7 @@ OpenInPlayAreaScreen_HandleInput: ; 183bb (6:43bb)
ld [wVBlankOAMCopyToggle], a
ret
-Func_006_44c8: ; (6:44c8)
+Func_006_44c8: ; 184c8 (6:44c8)
xor a
ld [wGlossaryPageNo], a
call Func_006_452b
@@ -719,7 +718,7 @@ Func_006_44c8: ; (6:44c8)
inc hl
ld [hl], d
ld a, $ff
- ld [wce55], a
+ ld [wDuelInitialPrizesUpperBitsSet], a
xor a
ld [wCheckMenuCursorBlinkCounter], a
.next
@@ -755,7 +754,7 @@ Func_006_44c8: ; (6:44c8)
.on_select
ld a, $01
- farcall Func_90fb
+ farcall PlaySFXConfirmOrCancel
.change_page
ld a, [wGlossaryPageNo]
xor $01 ; swap page
@@ -894,7 +893,7 @@ Func_006_4598: ; 18598 (6:4598)
jr z, .loop
ld a, -1
- farcall Func_90fb
+ farcall PlaySFXConfirmOrCancel
ret
; unit: 5 bytes.
@@ -905,6 +904,7 @@ glossary_entry: MACRO
tx \2
tx \3
ENDM
+
GlossaryData_1:
glossary_entry 7, Text02fa, Text030c
glossary_entry 5, Text02fb, Text030d
@@ -915,6 +915,7 @@ GlossaryData_1:
glossary_entry 5, Text0300, Text0312
glossary_entry 7, Text0301, Text0313
glossary_entry 5, Text0302, Text0314
+
GlossaryData_2:
glossary_entry 5, Text0303, Text0315
glossary_entry 5, Text0304, Text0316
@@ -926,12 +927,12 @@ GlossaryData_2:
glossary_entry 6, Text030a, Text031c
glossary_entry 6, Text030b, Text031d
-; (6:4661)
+Func_006_4661: ; 18661 (6:4661)
xor a
ld [wcfe3], a
- ld a, [wceaf]
+ ld a, [wCheckMenuCursorXPosition]
ld d, a
- ld a, [wceb0]
+ ld a, [wCheckMenuCursorYPosition]
ld e, a
ldh a, [hDPadHeld]
or a
@@ -961,9 +962,9 @@ GlossaryData_2:
call .asm_006_46d4
pop de
ld a, d
- ld [wceaf], a
+ ld [wCheckMenuCursorXPosition], a
ld a, e
- ld [wceb0], a
+ ld [wCheckMenuCursorYPosition], a
xor a
ld [wCheckMenuCursorBlinkCounter], a
.asm_006_46a2
@@ -1002,13 +1003,13 @@ GlossaryData_2:
ld e, a
ld a, $0a
ld l, a
- ld a, [wceaf]
+ ld a, [wCheckMenuCursorXPosition]
ld h, a
call HtimesL
ld a, l
add $01
ld b, a
- ld a, [wceb0]
+ ld a, [wCheckMenuCursorYPosition]
sla a
add $0e
ld c, a
@@ -1261,7 +1262,7 @@ Func_006_50fb: ; 190fb (6:50fb)
ld a, [wWhoseTurn]
ld l, a
.asm_006_5127
- call Func_30bc
+ call DrawYourOrOppPlayAreaScreen_Bank0
pop af
ld [wDuelDisplayedScreen], a
.asm_006_512e
diff --git a/src/engine/bank07.asm b/src/engine/bank07.asm
index a79f27a..7c53b96 100644
--- a/src/engine/bank07.asm
+++ b/src/engine/bank07.asm
@@ -384,7 +384,7 @@ Func_1cb18: ; 1cb18 (7:4b18)
ld a, [wd42a]
cp $ff
call nz, $4cd4
- ld hl, wd423
+ ld hl, wAnimationQueue
ld c, $07
.asm_1cb3b
push bc
diff --git a/src/engine/bank08.asm b/src/engine/bank08.asm
index ca52ca5..a3614af 100644
--- a/src/engine/bank08.asm
+++ b/src/engine/bank08.asm
@@ -49,7 +49,7 @@ Func_200e5: ; 200e5 (8:40e5)
bank1call CheckCantUseTrainerDueToHeadache
jp c, $41a8
call LoadNonPokemonCardEffectCommands
- ld a, $1
+ ld a, EFFECTCMDTYPE_INITIAL_EFFECT_1
call TryExecuteEffectCommandFunction
jp c, $41a8
farcall $5, $743b
diff --git a/src/engine/effect_functions.asm b/src/engine/effect_functions.asm
index b3c707b..116d545 100644
--- a/src/engine/effect_functions.asm
+++ b/src/engine/effect_functions.asm
@@ -7,6 +7,7 @@ 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
@@ -56,7 +57,7 @@ ApplyStatusEffect:
.cant_induce_status
ld a, c
- ld [wccf1], a
+ ld [wNoEffectFromStatus], a
call SetNoEffectFromStatus
or a
ret
@@ -108,8 +109,8 @@ Func_2c08a: ; 2c08a (b:408a)
Func_2c08c:
push de
push af
- ld a, $11
- call SetAIAction_SerialSendDuelData
+ ld a, OPPACTION_TOSS_COIN_A_TIMES
+ call SetOppAction_SerialSendDuelData
pop af
pop de
call SerialSend8Bytes
@@ -118,49 +119,82 @@ Func_2c08c:
; 0x2c09c
SetNoEffectFromStatus: ; 2c09c (b:409c)
- ld a, $1
- ld [wcced], a
+ ld a, EFFECT_FAILED_NO_EFFECT
+ ld [wEffectFailed], a
ret
; 0x2c0a2
SetWasUnsuccessful: ; 2c0a2 (b:40a2)
- ld a, $2
- ld [wcced], a
+ ld a, EFFECT_FAILED_UNSUCCESSFUL
+ ld [wEffectFailed], a
ret
; 0x2c0a8
- INCROM $2c0a8, $2c0d4
+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
+; 0x2c0bd
+
+Func_2c0bd: ; 2c0bd (b:40bd)
+ call ExchangeRNG
+ bank1call Func_4f2d
+ call ShuffleDeck
+ ret
+; 0x2c0c7
+
+Func_2c0c7: ; 2c0c7 (b:40c7)
+ ld a, DUELVARS_DUELIST_TYPE
+ call GetTurnDuelistVariable
+ cp DUELIST_TYPE_PLAYER
+ jr z, .player
+ or a
+ ret
+.player
+ scf
+ ret
+; 0x2c0d4
; Sets some flags for AI use
-; if target double poisoned
-; [wccbb] <- [wDamage]
-; [wccbc] <- [wDamage]
+; if target poisoned
+; [wAIMinDamage] <- [wDamage]
+; [wAIMaxDamage] <- [wDamage]
; else
-; [wccbb] <- [wDamage] + d
-; [wccbc] <- [wDamage] + e
-; [wDamage] <- [wDamage] + a
+; [wAIMinDamage] <- [wDamage] + d
+; [wAIMaxDamage] <- [wDamage] + e
+; [wDamage] <- [wDamage] + a
Func_2c0d4: ; 2c0d4 (b:40d4)
push af
ld a, DUELVARS_ARENA_CARD_STATUS
call GetNonTurnDuelistVariable
- and DOUBLE_POISONED
- jr z, .not_double_poisoned
+ and POISONED | DOUBLE_POISONED
+ jr z, Func_2c0e9.skip_push_af
pop af
ld a, [wDamage]
- ld [wccbb], a
- ld [wccbc], a
+ ld [wAIMinDamage], a
+ ld [wAIMaxDamage], a
ret
+Func_2c0e9: ; 2c0e9 (b:40e9)
push af
-.not_double_poisoned
+.skip_push_af
ld hl, wDamage
ld a, [hl]
add d
- ld [wccbb], a
+ ld [wAIMinDamage], a
ld a, [hl]
add e
- ld [wccbc], a
+ ld [wAIMaxDamage], a
pop af
add [hl]
ld [hl], a
@@ -168,21 +202,60 @@ Func_2c0d4: ; 2c0d4 (b:40d4)
; 0x2c0fb
; Sets some flags for AI use
-; [wDamage] <- a
-; [wccbb] <- d
-; [wccbc] <- e
+; [wDamage] <- a
+; [wAIMinDamage] <- d
+; [wAIMaxDamage] <- e
Func_2c0fb: ; 2c0fb (b:40fb)
ld [wDamage], a
xor a
ld [wDamage + 1], a
ld a, d
- ld [wccbb], a
+ ld [wAIMinDamage], a
ld a, e
- ld [wccbc], a
+ ld [wAIMaxDamage], a
ret
; 0x2c10b
- INCROM $2c10b, $2c140
+Func_2c10b: ; 2c10b (b:410b)
+ ldh [hTempPlayAreaLocation_ff9d], a
+ bank1call Func_61a1
+ bank1call PrintPlayAreaCardList_EnableLCD
+ bank1call Func_6194
+ ret
+; 0x2c117
+
+; 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
+ pop bc
+.skip_to_bench
+ inc b
+ dec c
+ jr nz, .loop
+ ret
+; 0x2c12e
+
+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
+; 0x2c140
; apply a status condition of type 1 identified by register a to the target
ApplySubstatus1ToDefendingCard: ; 2c140 (b:4140)
@@ -219,14 +292,24 @@ ApplySubstatus2ToDefendingCard: ; 2c149 (b:4149)
ret
; 0x2c166
- INCROM $2c166, $2c6f0
+Func_2c166: ; 2c166 (b:4166)
+ ld [wDamage], a
+ ld [wAIMinDamage], a
+ ld [wAIMaxDamage], a
+ xor a
+ ld [wDamage + 1], a
+ ret
+; 0x2c174
+
+ INCROM $2c174, $2c6f0
SpitPoison_AIEffect: ; 2c6f0 (b:46f0)
- ld a, $5
- lb de, $0, $a
+ ld a, 5
+ lb de, 0, 10
jp Func_2c0fb
; 0x2c6f8
+; If heads, defending Pokemon becomes poisoned
SpitPoison_Poison50PercentEffect: ; 2c6f8 (b:46f8)
ldtx de, PoisonCheckText
call TossCoin_BankB
@@ -240,19 +323,20 @@ SpitPoison_Poison50PercentEffect: ; 2c6f8 (b:46f8)
INCROM $2c70a, $2c730
PoisonFang_AIEffect: ; 2c730 (b:4730)
- ld a, $a
- lb de, $a, $a
+ ld a, 10
+ lb de, 10, 10
jp Func_2c0d4
; 0x2c738
WeepinbellPoisonPowder_AIEffect: ; 2c738 (b:4738)
- ld a, $5
- lb de, $0, $a
+ ld a, 5
+ lb de, 0, 10
jp Func_2c0d4
; 0x2c740
INCROM $2c740, $2c77e
+; If heads, defending Pokemon can't retreat next turn
AcidEffect: ; 2c77e (b:477e)
ldtx de, AcidCheckText
call TossCoin_BankB
@@ -263,12 +347,12 @@ AcidEffect: ; 2c77e (b:477e)
; 0x2c78b
GloomPoisonPowder_AIEffect: ; 2c78b (b:478b)
- ld a, $a
- lb de, $a, $a
+ ld a, 10
+ lb de, 10, 10
jp Func_2c0d4
; 0x2c793
-; confuses both the target and the user
+; Defending Pokemon and user become confused
FoulOdorEffect: ; 2c793 (b:4793)
call ConfusionEffect
call SwapTurn
@@ -277,6 +361,7 @@ FoulOdorEffect: ; 2c793 (b:4793)
ret
; 0x2c7a0
+; If heads, prevent all damage done to user next turn
KakunaStiffenEffect: ; 2c7a0 (b:47a0)
ldtx de, IfHeadsNoDamageNextTurnText
call TossCoin_BankB
@@ -289,13 +374,14 @@ KakunaStiffenEffect: ; 2c7a0 (b:47a0)
; 0x2c7b4
KakunaPoisonPowder_AIEffect: ; 2c7b4 (b:47b4)
- ld a, $5
- lb de, $0, $a
+ ld a, 5
+ lb de, 0, 10
jp Func_2c0d4
; 0x2c7bc
INCROM $2c7bc, $2c7d0
+; During your next turn, double damage
SwordsDanceEffect: ; 2c7d0 (b:47d0)
ld a, [wTempTurnDuelistCardID]
cp SCYTHER
@@ -305,15 +391,54 @@ SwordsDanceEffect: ; 2c7d0 (b:47d0)
ret
; 0x2c7dc
+; If heads, defending Pokemon becomes confused
ZubatSupersonicEffect: ; 2c7dc (b:47dc)
call Confusion50PercentEffect
call nc, SetNoEffectFromStatus
ret
; 0x2c7e3
- INCROM $2c7e3, $2c836
+ INCROM $2c7e3, $2c7ed
+
+Twineedle_AIEffect: ; 2c7ed (b:47ed)
+ ld a, 30
+ lb de, 0, 60
+ jp Func_2c0fb
+; 0x2c7f5
+
+; 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 Func_2c166
+ ret
+; 0x2c80d
+
+ INCROM $2c80d, $2c822
+
+FoulGas_AIEffect: ; 2c822 (b:4822)
+ ld a, 5
+ lb de, 0, 10
+ jp Func_2c0e9
+; 0x2c82a
+
+; 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
+; 0x2c836
; 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
@@ -325,4 +450,92 @@ MetapodStiffenEffect: ; 2c836 (b:4836)
ret
; 0x2c84a
- INCROM $2c84a, $30000
+ INCROM $2c84a, $2c925
+
+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
+; 0x2c944
+
+; 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
+; 0x2c96b
+
+Thrash_AIEffect: ; 2c96b (b:496b)
+ ld a, 35
+ lb de, 30, 40
+ jp Func_2c0fb
+; 0x2c973
+
+; 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
+; 0x2c982
+
+Func_2c982: ; 2c982 (b:4982)
+ ldh a, [hTemp_ffa0]
+ or a
+ ret nz
+ ld a, 10
+ call Func_1955
+ ret
+; 0x2c98c
+
+Toxic_AIEffect: ; 2c98c (b:498c)
+ ld a, 20
+ lb de, 20, 20
+ jp Func_2c0e9
+; 0x2c994
+
+; Defending Pokémon becomes poisoned, but takes 20 damage (double poisoned)
+Toxic_DoublePoisonEffect: ; 2c994 (b:4994)
+ call DoublePoisonEffect
+ ret
+; 0x2c998
+
+ INCROM $2c998, $30000
diff --git a/src/engine/home.asm b/src/engine/home.asm
index 69cb3b5..cdb96c9 100644
--- a/src/engine/home.asm
+++ b/src/engine/home.asm
@@ -858,6 +858,7 @@ CallIndirect: ; 05b6 (0:05b6)
ld h, a
pop af
; fallthrough
+
CallHL: ; 05c1 (0:05c1)
jp hl
; 0x5c2
@@ -2811,19 +2812,21 @@ ExchangeRNG: ; 0f58 (0:0f58)
jp c, DuelTransmissionError
ret
-; sets hAIActionTableIndex to an AI action specified in register a.
-; send 10 bytes of data to the other game from hAIActionTableIndex, hTempCardIndex_ff9f,
+; sets hOppActionTableIndex to an AI action specified in register a.
+; send 10 bytes of data to the other game from hOppActionTableIndex, hTempCardIndex_ff9f,
; hTemp_ffa0, and hTempPlayAreaLocation_ffa1, and hTempRetreatCostCards.
; finally exchange RNG data.
-SetAIAction_SerialSendDuelData: ; 0f7f (0:0f7f)
+; the receiving side will use this data to read the OPP_ACTION_* value in
+; [hOppActionTableIndex] and match it by calling the correspoding OppAction* function
+SetOppAction_SerialSendDuelData: ; 0f7f (0:0f7f)
push hl
push bc
- ldh [hAIActionTableIndex], a
+ ldh [hOppActionTableIndex], a
ld a, DUELVARS_DUELIST_TYPE
call GetNonTurnDuelistVariable
cp DUELIST_TYPE_LINK_OPP
jr nz, .not_link
- ld hl, hAIActionTableIndex
+ ld hl, hOppActionTableIndex
ld bc, 10
call SerialSendBytes
call ExchangeRNG
@@ -2833,13 +2836,13 @@ SetAIAction_SerialSendDuelData: ; 0f7f (0:0f7f)
ret
; 0xf9b
-; receive 10 bytes of data from wSerialRecvBuf and store them into hAIActionTableIndex,
+; receive 10 bytes of data from wSerialRecvBuf and store them into hOppActionTableIndex,
; hTempCardIndex_ff9f, hTemp_ffa0, and hTempPlayAreaLocation_ffa1,
; and hTempRetreatCostCards. also exchange RNG data.
SerialRecvDuelData: ; 0f9b (0:0f9b)
push hl
push bc
- ld hl, hAIActionTableIndex
+ ld hl, hOppActionTableIndex
ld bc, 10
call SerialRecvBytes
call ExchangeRNG
@@ -3287,8 +3290,8 @@ MoveDiscardPileCardToHand: ; 1182 (0:1182)
ret
; 0x11a5
-; return in the z flag whether turn holder's prize a (0-7) has been taken or not
-; z: taken, nz: not taken
+; return in the z flag whether turn holder's prize a (0-7) has been drawn or not
+; z: drawn, nz: not drawn
CheckPrizeTaken: ; 11a5 (0:11a5)
ld e, a
ld d, 0
@@ -3788,8 +3791,8 @@ EvolvePokemonCard: ; 13a2 (0:13a2)
ldh a, [hTempCardIndex_ff98]
call PutHandCardInPlayArea
; update the Pokemon's HP with the difference
- ldh a, [hTempPlayAreaLocation_ff9d]
- ld a, e ; derp
+ ldh a, [hTempPlayAreaLocation_ff9d] ; derp
+ ld a, e
add DUELVARS_ARENA_CARD_HP
call GetTurnDuelistVariable
ld a, [wLoadedCard2HP]
@@ -4020,8 +4023,8 @@ PutHandCardInPlayArea: ; 14d2 (0:14d2)
ret
; 0x14dd
-; move the play area Pokemon card of the turn holder at CARD_LOCATION_PLAY_AREA + a
-; to the discard pile
+; move the Pokemon card of the turn holder in the
+; PLAY_AREA_* location given in e to the discard pile
MovePlayAreaCardToDiscardPile: ; 14dd (0:14dd)
call EmptyPlayAreaSlot
ld l, DUELVARS_NUMBER_OF_POKEMON_IN_PLAY_AREA
@@ -4290,9 +4293,9 @@ GetNonTurnDuelistVariable: ; 1611 (0:1611)
ldh a, [hWhoseTurn]
ld h, OPPONENT_TURN
cp PLAYER_TURN
- jr z, .asm_161c
+ jr z, .ok
ld h, PLAYER_TURN
-.asm_161c
+.ok
ld a, [hl]
ret
; 0x161e
@@ -4367,7 +4370,7 @@ Func_161e: ; 161e (0:161e)
call DrawWideTextBox_WaitForInput
call ExchangeRNG
call Func_7415
- ld a, $07
+ ld a, EFFECTCMDTYPE_PKMN_POWER_TRIGGER
call TryExecuteEffectCommandFunction
ret
; 0x16ad
@@ -4452,15 +4455,15 @@ Func_16f6: ; 16f6 (0:16f6)
xor a
ld [wccec], a
ld [wEffectFunctionsFeedbackIndex], a
- ld [wcced], a
+ ld [wEffectFailed], a
ld [wIsDamageToSelf], a
ld [wccef], a
ld [wccf0], a
- ld [wccf1], a
+ ld [wNoEffectFromStatus], a
bank1call ClearNonTurnTemporaryDuelvars_CopyStatus
ret
-; use attack or Pokemon Power
+; Use an attack (from DuelMenu_Attack) or a Pokemon Power (from DuelMenu_PkmnPower)
UseAttackOrPokemonPower: ; 1730 (0:1730)
ld a, [wSelectedMoveIndex]
ld [wPlayerAttackingMoveIndex], a
@@ -4472,52 +4475,51 @@ UseAttackOrPokemonPower: ; 1730 (0:1730)
cp POKEMON_POWER
jp z, UsePokemonPower
call Func_16f6
- ld a, $1
+ ld a, EFFECTCMDTYPE_INITIAL_EFFECT_1
call TryExecuteEffectCommandFunction
jp c, DrawWideTextBox_WaitForInput_ReturnCarry
call CheckSandAttackOrSmokescreenSubstatus
- jr c, .asm_1766
- ld a, $2
+ jr c, .sand_attack_smokescreen
+ ld a, EFFECTCMDTYPE_INITIAL_EFFECT_2
call TryExecuteEffectCommandFunction
jp c, ReturnCarry
- call Func_1874
- jr .asm_1777
-.asm_1766
- call Func_1874
+ call SendAttackDataToLinkOpponent
+ jr .next
+.sand_attack_smokescreen
+ call SendAttackDataToLinkOpponent
call HandleSandAttackOrSmokescreenSubstatus
jp c, ClearNonTurnTemporaryDuelvars_ResetCarry
- ld a, $2
+ ld a, EFFECTCMDTYPE_INITIAL_EFFECT_2
call TryExecuteEffectCommandFunction
jp c, ReturnCarry
-.asm_1777
- ld a, $9
- call SetAIAction_SerialSendDuelData
- ld a, $6
+.next
+ ld a, OPPACTION_USE_ATTACK
+ call SetOppAction_SerialSendDuelData
+ ld a, EFFECTCMDTYPE_DISCARD_ENERGY
call TryExecuteEffectCommandFunction
call CheckSelfConfusionDamage
- jp c, DealConfusionDamageToSelf
+ jp c, HandleConfusionDamageToSelf
call DrawDuelMainScene_PrintPokemonsAttackText
call WaitForWideTextBoxInput
call ExchangeRNG
- ld a, $5
+ ld a, EFFECTCMDTYPE_REQUIRE_SELECTION
call TryExecuteEffectCommandFunction
- ld a, $a
- call SetAIAction_SerialSendDuelData
+ ld a, OPPACTION_ATTACK_ANIM_AND_DAMAGE
+ call SetOppAction_SerialSendDuelData
; fallthrough
-; deal attack damage
-Func_179a: ; 179a (0:179a)
+PlayAttackAnimation_DealAttackDamage: ; 179a (0:179a)
call Func_7415
ld a, [wLoadedMoveCategory]
and RESIDUAL
- jr nz, .asm_17ad
+ jr nz, .deal_damage
call SwapTurn
call HandleNoDamageOrEffectSubstatus
call SwapTurn
-.asm_17ad
+.deal_damage
xor a
ldh [hTempPlayAreaLocation_ff9d], a
- ld a, $3
+ ld a, EFFECTCMDTYPE_BEFORE_DAMAGE
call TryExecuteEffectCommandFunction
call ApplyDamageModifiers_DamageToTarget
call Func_189d
@@ -4532,9 +4534,9 @@ Func_179a: ; 179a (0:179a)
call GetNonTurnDuelistVariable
push de
push hl
- call Func_7494
+ call PlayMoveAnimation
call Func_741a
- call Func_7484
+ call WaitMoveAnimation
pop hl
pop de
call SubstractHP
@@ -4561,7 +4563,7 @@ Func_17ed: ; 17ed (0:17ed)
Func_17fb: ; 17fb (0:17fb)
ld a, [wTempNonTurnDuelistCardID]
push af
- ld a, $4
+ ld a, EFFECTCMDTYPE_AFTER_DAMAGE
call TryExecuteEffectCommandFunction
pop af
ld [wTempNonTurnDuelistCardID], a
@@ -4577,9 +4579,11 @@ DisplayUsePokemonPowerScreen_WaitForInput: ; 1819 (0:1819)
push hl
call DisplayUsePokemonPowerScreen
pop hl
+; fallthrough
DrawWideTextBox_WaitForInput_ReturnCarry: ; 181e (0:181e)
call DrawWideTextBox_WaitForInput
+; fallthrough
ReturnCarry: ; 1821 (0:1821)
scf
@@ -4590,7 +4594,9 @@ ClearNonTurnTemporaryDuelvars_ResetCarry: ; 1823 (0:1823)
or a
ret
-DealConfusionDamageToSelf: ; 1828 (0:1828)
+; called when attacker deals damage to itself due to confusion
+; display the corresponding animation and deal damage to self
+HandleConfusionDamageToSelf: ; 1828 (0:1828)
bank1call DrawDuelMainScene
ld a, 1
ld [wIsDamageToSelf], a
@@ -4599,7 +4605,7 @@ DealConfusionDamageToSelf: ; 1828 (0:1828)
ld a, $75
ld [wLoadedMoveAnimation], a
ld a, 20 ; damage
- call Func_195c
+ call DealConfusionDamageToSelf
call Func_1bb4
call Func_6e49
bank1call ClearNonTurnTemporaryDuelvars
@@ -4609,24 +4615,27 @@ DealConfusionDamageToSelf: ; 1828 (0:1828)
; use Pokemon Power
UsePokemonPower: ; 184b (0:184b)
call Func_7415
- ld a, $2
+ ld a, EFFECTCMDTYPE_INITIAL_EFFECT_2
call TryExecuteEffectCommandFunction
jr c, DisplayUsePokemonPowerScreen_WaitForInput
- ld a, $5
+ ld a, EFFECTCMDTYPE_REQUIRE_SELECTION
call TryExecuteEffectCommandFunction
jr c, ReturnCarry
- ld a, $c
- call SetAIAction_SerialSendDuelData
+ ld a, OPPACTION_USE_PKMN_POWER
+ call SetOppAction_SerialSendDuelData
call ExchangeRNG
- ld a, $d
- call SetAIAction_SerialSendDuelData
- ld a, $3
+ ld a, OPPACTION_EXECUTE_PKMN_POWER_EFFECT
+ call SetOppAction_SerialSendDuelData
+ ld a, EFFECTCMDTYPE_BEFORE_DAMAGE
call TryExecuteEffectCommandFunction
- ld a, $16
- call SetAIAction_SerialSendDuelData
+ ld a, OPPACTION_DUEL_MAIN_SCENE
+ call SetOppAction_SerialSendDuelData
ret
-Func_1874: ; 1874 (0:1874)
+; called by UseAttackOrPokemonPower (on an attack only)
+; in a link duel, it's used to send the other game data about the
+; attack being in use, triggering a call to OppAction_BeginUseAttack in the receiver
+SendAttackDataToLinkOpponent: ; 1874 (0:1874)
ld a, [wccec]
or a
ret nz
@@ -4640,8 +4649,8 @@ Func_1874: ; 1874 (0:1874)
ldh [hTempCardIndex_ff9f], a
ld a, [wPlayerAttackingMoveIndex]
ldh [hTemp_ffa0], a
- ld a, $8
- call SetAIAction_SerialSendDuelData
+ ld a, OPPACTION_BEGIN_ATTACK
+ call SetOppAction_SerialSendDuelData
call ExchangeRNG
pop af
ldh [hTempCardIndex_ff9f], a
@@ -4706,10 +4715,10 @@ CheckSelfConfusionDamage: ; 18d7 (0:18d7)
ret
; 0x18f9
-; use the trainer card with deck index at hTempCardIndex_ff98.
+; play the trainer card with deck index at hTempCardIndex_ff98.
; a trainer card is like a move effect, with its own effect commands.
; return nc if the card was played, carry if it wasn't.
-UseTrainerCard: ; 18f9 (0:18f9)
+PlayTrainerCard: ; 18f9 (0:18f9)
call CheckCantUseTrainerDueToHeadache
jr c, .cant_use
ldh a, [hWhoseTurn]
@@ -4717,7 +4726,7 @@ UseTrainerCard: ; 18f9 (0:18f9)
ldh a, [hTempCardIndex_ff98]
ldh [hTempCardIndex_ff9f], a
call LoadNonPokemonCardEffectCommands
- ld a, $01
+ ld a, EFFECTCMDTYPE_INITIAL_EFFECT_1
call TryExecuteEffectCommandFunction
jr nc, .can_use
.cant_use
@@ -4725,20 +4734,20 @@ UseTrainerCard: ; 18f9 (0:18f9)
scf
ret
.can_use
- ld a, $02
+ ld a, EFFECTCMDTYPE_INITIAL_EFFECT_2
call TryExecuteEffectCommandFunction
jr c, .done
- ld a, $06
- call SetAIAction_SerialSendDuelData
+ ld a, OPPACTION_PLAY_TRAINER
+ call SetOppAction_SerialSendDuelData
call DisplayUsedTrainerCardDetailScreen
call ExchangeRNG
- ld a, $06
+ ld a, EFFECTCMDTYPE_DISCARD_ENERGY
call TryExecuteEffectCommandFunction
- ld a, $05
+ ld a, EFFECTCMDTYPE_REQUIRE_SELECTION
call TryExecuteEffectCommandFunction
- ld a, $07
- call SetAIAction_SerialSendDuelData
- ld a, $03
+ ld a, OPPACTION_EXECUTE_TRAINER_EFFECTS
+ call SetOppAction_SerialSendDuelData
+ ld a, EFFECTCMDTYPE_BEFORE_DAMAGE
call TryExecuteEffectCommandFunction
ldh a, [hTempCardIndex_ff9f]
call MoveHandCardToDiscardPile
@@ -4770,8 +4779,7 @@ Func_1955: ; 1955 (0:1955)
pop af
; fallthrough
-; this function appears to handle dealing damage to self due to confusion
-Func_195c: ; 195c (0:195c)
+DealConfusionDamageToSelf: ; 195c (0:195c)
ld hl, wDamage
ld [hli], a
ld [hl], 0
@@ -4784,13 +4792,13 @@ Func_195c: ; 195c (0:195c)
push af
ld a, [wTempTurnDuelistCardID]
ld [wTempNonTurnDuelistCardID], a
- bank1call ApplyDamageModifiers_DamageToSelf ; switch to bank 1, but call a home func
+ bank1call ApplyDamageModifiers_DamageToSelf ; this is at bank 0
ld a, [wDamageEffectiveness]
ld c, a
ld b, $0
ld a, DUELVARS_ARENA_CARD_HP
call GetTurnDuelistVariable
- bank1call Func_7469
+ bank1call PlayAttackAnimation_DealAttackDamageSimple
call PrintKnockedOutIfHLZero
pop af
ld [wTempNonTurnDuelistCardID], a
@@ -5037,11 +5045,11 @@ PrintKnockedOut: ; 1ad3 (0:1ad3)
ret
; 0x1af3
-; seems to be a function to deal damage to a card, but can be used
-; to deal damage to a benched Pokemon.
+; deal damage to turn holder's Pokemon card at play area location at b (PLAY_AREA_*).
+; damage to deal is given in de.
; shows the defending player's play area screen when dealing the damage
-; instead of the main duel interface, and has a fixed move animation
-Func_1af3: ; 1af3 (0:1af3)
+; instead of the main duel interface, and has a fixed move animation.
+DealDamageToPlayAreaPokemon: ; 1af3 (0:1af3)
ld a, $78
ld [wLoadedMoveAnimation], a
ld a, b
@@ -5105,7 +5113,7 @@ Func_1af3: ; 1af3 (0:1af3)
ld b, a
or a ; cp PLAY_AREA_ARENA
jr nz, .benched
- ; add damage at de to [wDealtDamage]
+ ; if arena Pokemon, add damage at de to [wDealtDamage]
ld hl, wDealtDamage
ld a, e
add [hl]
@@ -5118,7 +5126,7 @@ Func_1af3: ; 1af3 (0:1af3)
add DUELVARS_ARENA_CARD_HP
call GetTurnDuelistVariable
push af
- bank1call Func_7469
+ bank1call PlayAttackAnimation_DealAttackDamageSimple
pop af
or a
jr z, .skip_knocked_out
@@ -5174,10 +5182,10 @@ Func_1bb4: ; 1bb4 (0:1bb4)
call ExchangeRNG
ret
-; prints one of the ThereWasNoEffectFrom*Text if wcced contains $1,
-; and WasUnsuccessfulText if wcced contains $2
+; prints one of the ThereWasNoEffectFrom*Text if wEffectFailed contains EFFECT_FAILED_NO_EFFECT,
+; and prints WasUnsuccessfulText if wEffectFailed contains EFFECT_FAILED_UNSUCCESSFUL
Func_1bca: ; 1bca (0:1bca)
- ld a, [wcced]
+ ld a, [wEffectFailed]
or a
ret z
cp $1
@@ -6238,7 +6246,10 @@ LoadPlacingThePrizesScreenTiles: ; 20f0 (0:20f0)
ld de, v0Tiles1 + $20 tiles
ld b, $d
call CopyFontsOrDuelGraphicsTiles
- ; load the Deck and the Discard Pile icons
+; fallthrough
+
+; load the Deck and the Discard Pile icons
+LoadDeckAndDiscardPileIcons: ; 20fb (0:20fb)
ld hl, DuelDmgSgbSymbolGraphics + $54 tiles - $4000
ld a, [wConsole]
cp CONSOLE_CGB
@@ -9276,12 +9287,12 @@ CompareDEtoBC: ; 3090 (0:3090)
cp c
ret
-Func_3096: ; 3096 (0:3096)
+OpenDuelCheckMenu: ; 3096 (0:3096)
ldh a, [hBankROM]
push af
- ld a, BANK(Func_8000)
+ ld a, BANK(_OpenDuelCheckMenu)
call BankswitchROM
- call Func_8000
+ call _OpenDuelCheckMenu
pop af
call BankswitchROM
ret
@@ -9299,27 +9310,33 @@ OpenInPlayAreaScreen_FromSelectButton: ; 30a6 (0:30a6)
call BankswitchROM
ret
-Func_30bc: ; 30bc (0:30bc)
+; loads tiles and icons to display Your Play Area / Opp. Play Area screen,
+; and draws the screen according to the turn player
+; input: h -> [wCheckMenuPlayAreaWhichDuelist] and l -> [wCheckMenuPlayAreaWhichLayout]
+; similar to DrawYourOrOppPlayArea (bank 2) except it also draws a wide text box.
+; this is because bank 2's DrawYourOrOppPlayArea is supposed to come from the Check Menu,
+; so the text box is always already there.
+DrawYourOrOppPlayAreaScreen_Bank0: ; 30bc (0:30bc)
ld a, h
- ld [wce50], a
+ ld [wCheckMenuPlayAreaWhichDuelist], a
ld a, l
- ld [wce51], a
+ ld [wCheckMenuPlayAreaWhichLayout], a
ldh a, [hBankROM]
push af
- ld a, BANK(Func_8211)
+ ld a, BANK(_DrawYourOrOppPlayAreaScreen)
call BankswitchROM
- call Func_8211
+ call _DrawYourOrOppPlayAreaScreen
call DrawWideTextBox
pop af
call BankswitchROM
ret
-Func_30d7: ; 30d7 (0:30d7)
+DrawPlayersPrizeAndBenchCards: ; 30d7 (0:30d7)
ldh a, [hBankROM]
push af
- ld a, BANK(Func_833c)
+ ld a, BANK(_DrawPlayersPrizeAndBenchCards)
call BankswitchROM
- call Func_833c
+ call _DrawPlayersPrizeAndBenchCards
pop af
call BankswitchROM
ret
@@ -10197,8 +10214,10 @@ IsPrehistoricPowerActive: ; 35b7 (0:35b7)
ret
; 0x35c7
-; clears some SUBSTATUS2 conditions from the turn holder's active Pokemon
-Func_35c7: ; 35c7 (0:35c7)
+; clears some SUBSTATUS2 conditions from the turn holder's active Pokemon.
+; more specifically, those conditions that reduce the damage from an attack
+; or prevent the opposing Pokemon from attacking the substatus condition inducer.
+ClearDamageReductionSubstatus2: ; 35c7 (0:35c7)
ld a, DUELVARS_ARENA_CARD_SUBSTATUS2
call GetTurnDuelistVariable
or a
@@ -11201,19 +11220,21 @@ Func_3b31: ; 3b31 (0:3b31)
call BankswitchROM
ret
-Func_3b52: ; 3b52 (0:3b52)
+; return nc if wd42a, wd4c0, and wAnimationQueue[] are all equal to $ff
+; nc means no animation is playing (or animation(s) has/have ended)
+CheckAnyAnimationPlaying: ; 3b52 (0:3b52)
push hl
push bc
ld a, [wd42a]
ld hl, wd4c0
and [hl]
- ld hl, wd423
- ld c, $7
-.asm_3b60
+ ld hl, wAnimationQueue
+ ld c, ANIMATION_QUEUE_LENGTH
+.loop
and [hl]
inc hl
dec c
- jr nz, .asm_3b60
+ jr nz, .loop
cp $ff
pop bc
pop hl
@@ -11236,7 +11257,7 @@ Func_3b6a: ; 3b6a (0:3b6a)
ld a, [wd4ac]
cp [hl]
jr nz, .asm_3b90
- call Func_3b52
+ call CheckAnyAnimationPlaying
jr nc, .asm_3b95
.asm_3b90
call $4a31