summaryrefslogtreecommitdiff
path: root/engine/battle
diff options
context:
space:
mode:
authorU-Fish-PC\Daniel <corrnondacqb@yahoo.com>2014-05-22 18:13:20 -0400
committerU-Fish-PC\Daniel <corrnondacqb@yahoo.com>2014-05-22 18:13:20 -0400
commit15427f532085846ab6b51719be687951a094cb6c (patch)
treeedea9b189e91641a12dd521756894df84aeeace7 /engine/battle
parentea3ba4cde3706b7c77efb705555ec0c86321cbe2 (diff)
Pull a lot of engine out of main.asm
Diffstat (limited to 'engine/battle')
-rwxr-xr-xengine/battle/1.asm105
-rwxr-xr-xengine/battle/14.asm94
-rwxr-xr-xengine/battle/15.asm366
-rwxr-xr-xengine/battle/16.asm238
-rwxr-xr-xengine/battle/1a.asm40
-rwxr-xr-xengine/battle/1c.asm911
-rwxr-xr-xengine/battle/4.asm78
-rwxr-xr-xengine/battle/4_2.asm409
-rwxr-xr-xengine/battle/5.asm77
-rwxr-xr-xengine/battle/9.asm182
-rwxr-xr-xengine/battle/a.asm39
-rwxr-xr-xengine/battle/animations.asm2908
-rwxr-xr-xengine/battle/b.asm18
-rwxr-xr-xengine/battle/b_2.asm130
-rwxr-xr-xengine/battle/c.asm58
-rwxr-xr-xengine/battle/core.asm8547
-rwxr-xr-xengine/battle/d.asm25
-rwxr-xr-xengine/battle/e.asm1563
-rwxr-xr-xengine/battle/e_2.asm305
-rwxr-xr-xengine/battle/safari_zone.asm36
20 files changed, 16129 insertions, 0 deletions
diff --git a/engine/battle/1.asm b/engine/battle/1.asm
new file mode 100755
index 00000000..91f7d3b1
--- /dev/null
+++ b/engine/battle/1.asm
@@ -0,0 +1,105 @@
+DrainHPEffect_: ; 783f (1:783f)
+ ld hl, W_DAMAGE ; $d0d7
+ ld a, [hl]
+ srl a ; divide damage by 2
+ ld [hli], a
+ ld a, [hl]
+ rr a
+ ld [hld], a
+ or [hl]
+ jr nz, .asm_784f
+ inc hl
+ inc [hl]
+.asm_784f
+ ld hl, W_PLAYERMONCURHP ; $d015
+ ld de, W_PLAYERMONMAXHP ; $d023
+ ld a, [H_WHOSETURN] ; $fff3
+ and a
+ jp z, Func_7861
+ ld hl, W_ENEMYMONCURHP ; $cfe6
+ ld de, W_ENEMYMONMAXHP ; $cff4
+
+Func_7861: ; 7861 (1:7861)
+ ld bc, wHPBarOldHP+1
+ ld a, [hli]
+ ld [bc], a
+ ld a, [hl]
+ dec bc
+ ld [bc], a
+ ld a, [de]
+ dec bc
+ ld [bc], a
+ inc de
+ ld a, [de]
+ dec bc
+ ld [bc], a
+ ld a, [$d0d8]
+ ld b, [hl]
+ add b
+ ld [hld], a
+ ld [wHPBarNewHP], a
+ ld a, [W_DAMAGE] ; $d0d7
+ ld b, [hl]
+ adc b
+ ld [hli], a
+ ld [wHPBarNewHP+1], a
+ jr c, .asm_7890
+ ld a, [hld]
+ ld b, a
+ ld a, [de]
+ dec de
+ sub b
+ ld a, [hli]
+ ld b, a
+ ld a, [de]
+ inc de
+ sbc b
+ jr nc, .asm_789c
+.asm_7890
+ ld a, [de]
+ ld [hld], a
+ ld [wHPBarNewHP], a
+ dec de
+ ld a, [de]
+ ld [hli], a
+ ld [wHPBarNewHP+1], a
+ inc de
+.asm_789c
+ ld a, [H_WHOSETURN] ; $fff3
+ and a
+ FuncCoord 10, 9 ; $c45e
+ ld hl, Coord
+ ld a, $1
+ jr z, .asm_78aa
+ FuncCoord 2, 2 ; $c3ca
+ ld hl, Coord
+ xor a
+.asm_78aa
+ ld [wListMenuID], a ; $cf94
+ ld a, $48
+ call Predef ; indirect jump to UpdateHPBar (fa1d (3:7a1d))
+ ld a, $0
+ call Predef ; indirect jump to Func_3cd60 (3cd60 (f:4d60))
+ ld a, $49
+ call Predef ; indirect jump to Func_3cdec (3cdec (f:4dec))
+ callab ReadPlayerMonCurHPAndStatus
+ ld hl, SuckedHealthText ; $78dc
+ ld a, [H_WHOSETURN] ; $fff3
+ and a
+ ld a, [W_PLAYERMOVEEFFECT] ; $cfd3
+ jr z, .asm_78d2
+ ld a, [W_ENEMYMOVEEFFECT] ; $cfcd
+.asm_78d2
+ cp DREAM_EATER_EFFECT
+ jr nz, .asm_78d9
+ ld hl, DreamWasEatenText
+.asm_78d9
+ jp PrintText
+
+SuckedHealthText: ; 78dc (1:78dc)
+ TX_FAR _SuckedHealthText
+ db "@"
+
+DreamWasEatenText: ; 78e1 (1:78e1)
+ TX_FAR _DreamWasEatenText
+ db "@"
diff --git a/engine/battle/14.asm b/engine/battle/14.asm
new file mode 100755
index 00000000..209135af
--- /dev/null
+++ b/engine/battle/14.asm
@@ -0,0 +1,94 @@
+Func_525af: ; 525af (14:65af)
+ ld a, [$ffd7]
+ ld [$d0d4], a
+ xor a
+ ld [$cd6a], a
+ ld [$cf0b], a
+ ld hl, $cc2b
+ ld [hli], a
+ ld [hli], a
+ ld [hli], a
+ ld [hl], a
+ ld [wListScrollOffset], a ; $cc36
+ ld [$d05e], a
+ ld [W_PLAYERMONID], a
+ ld [W_PLAYERMONSALIVEFLAGS], a
+ ld [wPlayerMonNumber], a ; $cc2f
+ ld [$d078], a
+ ld [$d35d], a
+ ld hl, $cf1d
+ ld [hli], a
+ ld [hl], a
+ ld hl, $ccd3
+ ld b, $3c
+.asm_525e1
+ ld [hli], a
+ dec b
+ jr nz, .asm_525e1
+ inc a
+ ld [$ccd9], a
+ ld a, [W_CURMAP] ; $d35e
+ cp SAFARI_ZONE_EAST
+ jr c, .asm_525f9
+ cp SAFARI_ZONE_REST_HOUSE_1
+ jr nc, .asm_525f9
+ ld a, $2
+ ld [W_BATTLETYPE], a ; $d05a
+.asm_525f9
+ ld hl, PlayBattleMusic
+ ld b, BANK(PlayBattleMusic)
+ jp Bankswitch
+
+ParalyzeEffect_: ; 52601 (14:6601)
+ ld hl, W_ENEMYMONSTATUS ; $cfe9
+ ld de, W_PLAYERMOVETYPE ; $cfd5
+ ld a, [H_WHOSETURN] ; $fff3
+ and a
+ jp z, .asm_52613
+ ld hl, W_PLAYERMONSTATUS ; $d018
+ ld de, W_ENEMYMOVETYPE ; $cfcf
+
+.asm_52613
+ ld a, [hl]
+ and a
+ jr nz, .asm_52659
+ ld a, [de]
+ cp EVASION_DOWN1_EFFECT
+ jr nz, .asm_5262a
+ ld b, h
+ ld c, l
+ inc bc
+ ld a, [bc]
+ cp $4
+ jr z, .asm_52666
+ inc bc
+ ld a, [bc]
+ cp $4
+ jr z, .asm_52666
+.asm_5262a
+ push hl
+ callab MoveHitTest
+ pop hl
+ ld a, [W_MOVEMISSED] ; $d05f
+ and a
+ jr nz, .asm_52659
+ set 6, [hl]
+ callab Func_3ed27
+ ld c, $1e
+ call DelayFrames
+ callab Func_3fba8
+ ld hl, PrintMayNotAttackText
+ ld b, BANK(PrintMayNotAttackText)
+ jp Bankswitch
+.asm_52659
+ ld c, $32
+ call DelayFrames
+ ld hl, PrintDidntAffectText
+ ld b, BANK(PrintDidntAffectText)
+ jp Bankswitch
+.asm_52666
+ ld c, $32
+ call DelayFrames
+ ld hl, PrintDoesntAffectText
+ ld b, BANK(PrintDoesntAffectText)
+ jp Bankswitch
diff --git a/engine/battle/15.asm b/engine/battle/15.asm
new file mode 100755
index 00000000..d2e93ab1
--- /dev/null
+++ b/engine/battle/15.asm
@@ -0,0 +1,366 @@
+GainExperience: ; 5524f (15:524f)
+ ld a, [W_ISLINKBATTLE] ; $d12b
+ cp $4
+ ret z
+ call Func_5546c
+ ld hl, W_PARTYMON1_NUM ; $d16b (aliases: W_PARTYMON1DATA)
+ xor a
+ ld [wWhichPokemon], a ; $cf92
+
+Func_5525f: ; 5525f (15:525f)
+ inc hl
+ ld a, [hli]
+ or [hl]
+ jp z, Func_55436
+ push hl
+ ld hl, W_PLAYERMONSALIVEFLAGS
+ ld a, [wWhichPokemon] ; $cf92
+ ld c, a
+ ld b, $2
+ ld a, $10
+ call Predef ; indirect jump to HandleBitArray (f666 (3:7666))
+ ld a, c
+ and a
+ pop hl
+ jp z, Func_55436
+ ld de, $10
+ add hl, de
+ ld d, h
+ ld e, l
+ ld hl, $d002
+ ld c, $5
+.asm_55285
+ ld a, [hli]
+ ld b, a
+ ld a, [de]
+ add b
+ ld [de], a
+ jr nc, .asm_5529a
+ dec de
+ ld a, [de]
+ inc a
+ jr z, .asm_55295
+ ld [de], a
+ inc de
+ jr .asm_5529a
+.asm_55295
+ ld a, $ff
+ ld [de], a
+ inc de
+ ld [de], a
+.asm_5529a
+ dec c
+ jr z, .asm_552a1
+ inc de
+ inc de
+ jr .asm_55285
+.asm_552a1
+ xor a
+ ld [H_NUMTOPRINT], a ; $ff96 (aliases: H_MULTIPLICAND)
+ ld [$ff97], a
+ ld a, [$d008]
+ ld [$ff98], a
+ ld a, [W_ENEMYMONLEVEL] ; $cff3
+ ld [H_REMAINDER], a ; $ff99 (aliases: H_DIVISOR, H_MULTIPLIER, H_POWEROFTEN)
+ call Multiply
+ ld a, $7
+ ld [H_REMAINDER], a ; $ff99 (aliases: H_DIVISOR, H_MULTIPLIER, H_POWEROFTEN)
+ ld b, $4
+ call Divide
+ ld hl, $fff2
+ add hl, de
+ ld b, [hl]
+ inc hl
+ ld a, [wPlayerID] ; $d359
+ cp b
+ jr nz, .asm_552d1
+ ld b, [hl]
+ ld a, [wPlayerID + 1] ; $d35a
+ cp b
+ ld a, $0
+ jr z, .asm_552d6
+.asm_552d1
+ call Func_5549f
+ ld a, $1
+.asm_552d6
+ ld [$cf4d], a
+ ld a, [W_ISINBATTLE] ; $d057
+ dec a
+ call nz, Func_5549f
+ inc hl
+ inc hl
+ inc hl
+ ld b, [hl]
+ ld a, [$ff98]
+ ld [$cf4c], a
+ add b
+ ld [hld], a
+ ld b, [hl]
+ ld a, [$ff97]
+ ld [$cf4b], a
+ adc b
+ ld [hl], a
+ jr nc, .asm_552f8
+ dec hl
+ inc [hl]
+ inc hl
+.asm_552f8
+ inc hl
+ push hl
+ ld a, [wWhichPokemon] ; $cf92
+ ld c, a
+ ld b, $0
+ ld hl, W_PARTYMON1 ; $d164
+ add hl, bc
+ ld a, [hl]
+ ld [$d0b5], a
+ call GetMonHeader
+ ld d, $64
+ callab CalcExperience
+ ld a, [H_NUMTOPRINT] ; $ff96 (aliases: H_MULTIPLICAND)
+ ld b, a
+ ld a, [$ff97]
+ ld c, a
+ ld a, [$ff98]
+ ld d, a
+ pop hl
+ ld a, [hld]
+ sub d
+ ld a, [hld]
+ sbc c
+ ld a, [hl]
+ sbc b
+ jr c, .asm_5532e
+ ld a, b
+ ld [hli], a
+ ld a, c
+ ld [hli], a
+ ld a, d
+ ld [hld], a
+ dec hl
+.asm_5532e
+ push hl
+ ld a, [wWhichPokemon] ; $cf92
+ ld hl, W_PARTYMON1NAME ; $d2b5
+ call GetPartyMonName
+ ld hl, GainedText
+ call PrintText
+ xor a
+ ld [$cc49], a
+ call LoadMonData
+ pop hl
+ ld bc, $13
+ add hl, bc
+ push hl
+ callba Func_58f43
+ pop hl
+ ld a, [hl]
+ cp d
+ jp z, Func_55436
+ ld a, [W_CURENEMYLVL] ; $d127
+ push af
+ push hl
+ ld a, d
+ ld [W_CURENEMYLVL], a ; $d127
+ ld [hl], a
+ ld bc, $ffdf
+ add hl, bc
+ ld a, [hl]
+ ld [$d0b5], a
+ ld [$d11e], a
+ call GetMonHeader
+ ld bc, $23
+ add hl, bc
+ push hl
+ ld a, [hld]
+ ld c, a
+ ld b, [hl]
+ push bc
+ ld d, h
+ ld e, l
+ ld bc, $ffee
+ add hl, bc
+ ld b, $1
+ call CalcStats
+ pop bc
+ pop hl
+ ld a, [hld]
+ sub c
+ ld c, a
+ ld a, [hl]
+ sbc b
+ ld b, a
+ ld de, $ffe0
+ add hl, de
+ ld a, [hl]
+ add c
+ ld [hld], a
+ ld a, [hl]
+ adc b
+ ld [hl], a
+ ld a, [wPlayerMonNumber] ; $cc2f
+ ld b, a
+ ld a, [wWhichPokemon] ; $cf92
+ cp b
+ jr nz, .asm_553f7
+ ld de, W_PLAYERMONCURHP ; $d015
+ ld a, [hli]
+ ld [de], a
+ inc de
+ ld a, [hl]
+ ld [de], a
+ ld bc, $1f
+ add hl, bc
+ push hl
+ ld de, W_PLAYERMONLEVEL ; $d022
+ ld bc, $b
+ call CopyData
+ pop hl
+ ld a, [W_PLAYERBATTSTATUS3] ; $d064
+ bit 3, a
+ jr nz, .asm_553c8
+ ld de, $cd0f
+ ld bc, $b
+ call CopyData
+.asm_553c8
+ xor a
+ ld [$d11e], a
+ callab Func_3ed99
+ callab Func_3ed1a
+ callab Func_3ee19
+ callab Func_3cd60
+ callab Func_3ee94
+ call SaveScreenTilesToBuffer1
+.asm_553f7
+ ld hl, GrewLevelText
+ call PrintText
+ xor a
+ ld [$cc49], a
+ call LoadMonData
+ ld d, $1
+ callab PrintStatsBox
+ call WaitForTextScrollButtonPress
+ call LoadScreenTilesFromBuffer1
+ xor a
+ ld [$cc49], a
+ ld a, [$d0b5]
+ ld [$d11e], a
+ ld a, $1a
+ call Predef ; indirect jump to Func_3af5b (3af5b (e:6f5b))
+ ld hl, $ccd3
+ ld a, [wWhichPokemon] ; $cf92
+ ld c, a
+ ld b, $1
+ ld a, $10
+ call Predef ; indirect jump to HandleBitArray (f666 (3:7666))
+ pop hl
+ pop af
+ ld [W_CURENEMYLVL], a ; $d127
+
+Func_55436: ; 55436 (15:5436)
+ ld a, [W_NUMINPARTY] ; $d163
+ ld b, a
+ ld a, [wWhichPokemon] ; $cf92
+ inc a
+ cp b
+ jr z, .asm_55450
+ ld [wWhichPokemon], a ; $cf92
+ ld bc, $2c
+ ld hl, W_PARTYMON1_NUM ; $d16b (aliases: W_PARTYMON1DATA)
+ call AddNTimes
+ jp Func_5525f
+.asm_55450
+ ld hl, W_PLAYERMONSALIVEFLAGS
+ xor a
+ ld [hl], a
+ ld a, [wPlayerMonNumber] ; $cc2f
+ ld c, a
+ ld b, $1
+ push bc
+ ld a, $10
+ call Predef ; indirect jump to HandleBitArray (f666 (3:7666))
+ ld hl, $ccf5
+ xor a
+ ld [hl], a
+ pop bc
+ ld a, $10
+ jp Predef ; indirect jump to HandleBitArray (f666 (3:7666))
+
+Func_5546c: ; 5546c (15:546c)
+ ld a, [W_PLAYERMONSALIVEFLAGS]
+ ld b, a
+ xor a
+ ld c, $8
+ ld d, $0
+.asm_55475
+ xor a
+ srl b
+ adc d
+ ld d, a
+ dec c
+ jr nz, .asm_55475
+ cp $2
+ ret c
+ ld [$d11e], a
+ ld hl, $d002
+ ld c, $7
+.asm_55488
+ xor a
+ ld [H_DIVIDEND], a ; $ff95 (aliases: H_PRODUCT, H_PASTLEADINGZEROES, H_QUOTIENT)
+ ld a, [hl]
+ ld [H_NUMTOPRINT], a ; $ff96 (aliases: H_MULTIPLICAND)
+ ld a, [$d11e]
+ ld [H_REMAINDER], a ; $ff99 (aliases: H_DIVISOR, H_MULTIPLIER, H_POWEROFTEN)
+ ld b, $2
+ call Divide
+ ld a, [$ff98]
+ ld [hli], a
+ dec c
+ jr nz, .asm_55488
+ ret
+
+Func_5549f: ; 5549f (15:549f)
+ ld a, [$ff97]
+ ld b, a
+ ld a, [$ff98]
+ ld c, a
+ srl b
+ rr c
+ add c
+ ld [$ff98], a
+ ld a, [$ff97]
+ adc b
+ ld [$ff97], a
+ ret
+
+GainedText: ; 554b2 (15:54b2)
+ TX_FAR _GainedText
+ db $08 ; asm
+ ld a, [$cc5b]
+ ld hl, WithExpAllText
+ and a
+ ret nz
+ ld hl, ExpPointsText
+ ld a, [$cf4d]
+ and a
+ ret z
+ ld hl, BoostedText
+ ret
+
+WithExpAllText: ; 554cb (15:54cb)
+ TX_FAR _WithExpAllText
+ db $08 ; asm
+ ld hl, ExpPointsText
+ ret
+
+BoostedText: ; 554d4 (15:54d4)
+ TX_FAR _BoostedText
+
+ExpPointsText: ; 554d8 (15:54d8)
+ TX_FAR _ExpPointsText
+ db "@"
+
+GrewLevelText: ; 554dd (15:54dd)
+ TX_FAR _GrewLevelText
+ db $0b
+ db "@"
diff --git a/engine/battle/16.asm b/engine/battle/16.asm
new file mode 100755
index 00000000..f2f4ada9
--- /dev/null
+++ b/engine/battle/16.asm
@@ -0,0 +1,238 @@
+PrintBeginningBattleText: ; 58d99 (16:4d99)
+ ld a, [W_ISINBATTLE] ; $d057
+ dec a
+ jr nz, .trainerBattle
+ ld a, [W_CURMAP] ; $d35e
+ cp POKEMONTOWER_3
+ jr c, .notPokemonTower
+ cp LAVENDER_HOUSE_1
+ jr c, .pokemonTower
+.notPokemonTower
+ ld a, [W_ENEMYMONID]
+ call PlayCry
+ ld hl, WildMonAppearedText
+ ld a, [W_MOVEMISSED] ; $d05f
+ and a
+ jr z, .notFishing
+ ld hl, HookedMonAttackedText
+.notFishing
+ jr .wildBattle
+.trainerBattle
+ call .playSFX
+ ld c, $14
+ call DelayFrames
+ ld hl, TrainerWantsToFightText
+.wildBattle
+ push hl
+ callab DrawAllPokeballs
+ pop hl
+ call PrintText
+ jr .done
+.pokemonTower
+ ld b, SILPH_SCOPE
+ call IsItemInBag
+ ld a, [W_ENEMYMONID]
+ ld [$cf91], a
+ cp MAROWAK
+ jr z, .isMarowak
+ ld a, b
+ and a
+ jr z, .noSilphScope
+ callab Func_3eb01
+ jr .notPokemonTower
+.noSilphScope
+ ld hl, EnemyAppearedText
+ call PrintText
+ ld hl, GhostCantBeIDdText
+ call PrintText
+ jr .done
+.isMarowak
+ ld a, b
+ and a
+ jr z, .noSilphScope
+ ld hl, EnemyAppearedText
+ call PrintText
+ ld hl, UnveiledGhostText
+ call PrintText
+ callab Func_3eb01
+ callab Func_708ca
+ ld hl, WildMonAppearedText
+ call PrintText
+
+.playSFX
+ xor a
+ ld [$c0f1], a
+ ld a, $80
+ ld [$c0f2], a
+ ld a, (SFX_08_77 - SFX_Headers_08) / 3
+ call PlaySound
+ jp WaitForSoundToFinish
+.done
+ ret
+
+WildMonAppearedText: ; 58e3b (16:4e3b)
+ TX_FAR _WildMonAppearedText
+ db "@"
+
+HookedMonAttackedText: ; 58e40 (16:4e40)
+ TX_FAR _HookedMonAttackedText
+ db "@"
+
+EnemyAppearedText: ; 58e45 (16:4e45)
+ TX_FAR _EnemyAppearedText
+ db "@"
+
+TrainerWantsToFightText: ; 58e4a (16:4e4a)
+ TX_FAR _TrainerWantsToFightText
+ db "@"
+
+UnveiledGhostText: ; 58e4f (16:4e4f)
+ TX_FAR _UnveiledGhostText
+ db "@"
+
+GhostCantBeIDdText: ; 58e54 (16:4e54)
+ TX_FAR _GhostCantBeIDdText
+ db "@"
+
+SendOutMon: ; 58e59 (16:4e59)
+ ld hl, W_ENEMYMONCURHP ; $cfe6
+ ld a, [hli]
+ or [hl]
+ ld hl, GoText
+ jr z, .printText
+ xor a
+ ld [H_NUMTOPRINT], a ; $ff96 (aliases: H_MULTIPLICAND)
+ ld hl, W_ENEMYMONCURHP ; $cfe6
+ ld a, [hli]
+ ld [$cce3], a
+ ld [$ff97], a
+ ld a, [hl]
+ ld [$cce4], a
+ ld [$ff98], a
+ ld a, $19
+ ld [H_REMAINDER], a ; $ff99 (aliases: H_DIVISOR, H_MULTIPLIER, H_POWEROFTEN)
+ call Multiply
+ ld hl, W_ENEMYMONMAXHP ; $cff4
+ ld a, [hli]
+ ld b, [hl]
+ srl a
+ rr b
+ srl a
+ rr b
+ ld a, b
+ ld b, $4
+ ld [H_REMAINDER], a ; $ff99 (aliases: H_DIVISOR, H_MULTIPLIER, H_POWEROFTEN)
+ call Divide
+ ld a, [$ff98]
+ ld hl, GoText
+ cp $46
+ jr nc, .printText
+ ld hl, DoItText
+ cp $28
+ jr nc, .printText
+ ld hl, GetmText
+ cp $a
+ jr nc, .printText
+ ld hl, EnemysWeakText
+.printText
+ jp PrintText
+
+GoText: ; 58eae (16:4eae)
+ TX_FAR _GoText
+ db $08 ; asm
+ jr PrintPlayerMon1Text
+
+DoItText: ; 58eb5 (16:4eb5)
+ TX_FAR _DoItText
+ db $08 ; asm
+ jr PrintPlayerMon1Text
+
+GetmText: ; 58ebc (16:4ebc)
+ TX_FAR _GetmText
+ db $08 ; asm
+ jr PrintPlayerMon1Text
+
+EnemysWeakText: ; 58ec3 (16:4ec3)
+ TX_FAR _EnemysWeakText
+ db $08 ; asm
+
+PrintPlayerMon1Text:
+ ld hl, PlayerMon1Text
+ ret
+
+PlayerMon1Text: ; 58ecc (16:4ecc)
+ TX_FAR _PlayerMon1Text
+ db "@"
+
+RetreatMon: ; 58ed1 (16:4ed1)
+ ld hl, PlayerMon2Text
+ jp PrintText
+
+PlayerMon2Text: ; 58ed7 (16:4ed7)
+ TX_FAR _PlayerMon2Text
+ db $08 ; asm
+ push de
+ push bc
+ ld hl, $cfe7
+ ld de, $cce4
+ ld b, [hl]
+ dec hl
+ ld a, [de]
+ sub b
+ ld [$ff98], a
+ dec de
+ ld b, [hl]
+ ld a, [de]
+ sbc b
+ ld [$ff97], a
+ ld a, $19
+ ld [H_POWEROFTEN], a
+ call Multiply
+ ld hl, W_ENEMYMONMAXHP
+ ld a, [hli]
+ ld b, [hl]
+ srl a
+ rr b
+ srl a
+ rr b
+ ld a, b
+ ld b, $4
+ ld [H_POWEROFTEN], a
+ call Divide
+ pop bc
+ pop de
+ ld a, [$ff98]
+ ld hl, EnoughText
+ and a
+ ret z
+ ld hl, ComeBackText
+ cp $1e
+ ret c
+ ld hl, OKExclamationText
+ cp $46
+ ret c
+ ld hl, GoodText
+ ret
+
+EnoughText: ; 58f25 (16:4f25)
+ TX_FAR _EnoughText
+ db $08 ; asm
+ jr PrintComeBackText
+
+OKExclamationText: ; 58f2c (16:4f2c)
+ TX_FAR _OKExclamationText
+ db $08 ; asm
+ jr PrintComeBackText
+
+GoodText: ; 58f33 (16:4f33)
+ TX_FAR _GoodText
+ db $08 ; asm
+ jr PrintComeBackText
+
+PrintComeBackText: ; 58f3a (16:4f3a)
+ ld hl, ComeBackText
+ ret
+
+ComeBackText: ; 58f3e (16:4f3e)
+ TX_FAR _ComeBackText
+ db "@"
diff --git a/engine/battle/1a.asm b/engine/battle/1a.asm
new file mode 100755
index 00000000..2770a459
--- /dev/null
+++ b/engine/battle/1a.asm
@@ -0,0 +1,40 @@
+DecrementPP: ; 68000 (1a:4000)
+; after using a move, decrement pp in battle and (if not transformed?) in party
+ ld a, [de]
+ cp a, STRUGGLE
+ ret z ; if the pokemon is using "struggle", there's nothing to do
+ ; we don't decrement PP for "struggle"
+ ld hl, W_PLAYERBATTSTATUS1
+ ld a, [hli] ; load the W_PLAYERBATTSTATUS1 pokemon status flags and increment hl to load the
+ ; W_PLAYERBATTSTATUS2 status flags later
+ and a, 7 ; check to see if bits 0, 1, or 2 are set
+ ret nz ; if any of these statuses are true, don't decrement PP
+ bit 6, [hl] ; check 6th bit status flag on W_PLAYERBATTSTATUS2
+ ret nz ; and return if it is set
+ ld hl, $D02D ; PP of first move (in battle)
+ call .DecrementPP
+
+ ld a, [$D064] ; load pokemon status bits?
+ bit 3, a ; XXX transform status?
+ ret nz ; If it is, return. Pokemon Red stores the "current pokemon's" PP
+ ; separately from the "Pokemon in your party's" PP. This is
+ ; duplication -- in all cases *other* than Pokemon with Transform.
+ ; Normally, this means we have to go on and make the same
+ ; modification to the "party's pokemon" PP that we made to the
+ ; "current pokemon's" PP. But, if we're dealing with a Transformed
+ ; Pokemon, it has separate PP for the move set that it copied from
+ ; its opponent, which is *not* the same as its real PP as part of your
+ ; party. So we return, and don't do that part.
+
+ ld hl, $D188 ; PP of first move (in party)
+ ld a, [$CC2F] ; which mon in party is active
+ ld bc, $2C ; XXX probably size of party pokemon's data structure
+ call AddNTimes ; calculate address of the mon to modify
+.DecrementPP
+ ld a, [$CC2E] ; which move (0, 1, 2, 3) did we use?
+ ld c, a
+ ld b, 0
+ add hl ,bc ; calculate the address in memory of the PP we need to decrement
+ ; based on the move chosen.
+ dec [hl] ; Decrement PP
+ ret
diff --git a/engine/battle/1c.asm b/engine/battle/1c.asm
new file mode 100755
index 00000000..1f07807a
--- /dev/null
+++ b/engine/battle/1c.asm
@@ -0,0 +1,911 @@
+Func_708ca: ; 708ca (1c:48ca)
+ ld a, $e4
+ ld [rOBP1], a ; $ff49
+ call Func_7092a
+ FuncCoord 12, 0 ; $c3ac
+ ld hl, Coord
+ ld bc, $707
+ call ClearScreenArea
+ call Delay3
+ xor a
+ ld [H_AUTOBGTRANSFERENABLED], a ; $ffba
+ ld a, $91
+ ld [$cee9], a
+ ld a, $1
+ ld [H_WHOSETURN], a ; $fff3
+ callab Func_79793
+ ld d, $80
+ call Func_704f3
+.asm_708f6
+ ld c, $a
+ call DelayFrames
+ ld a, [rOBP1] ; $ff49
+ sla a
+ sla a
+ ld [rOBP1], a ; $ff49
+ jr nz, .asm_708f6
+ call CleanLCD_OAM
+ call Func_7092a
+ ld b, $e4
+.asm_7090d
+ ld c, $a
+ call DelayFrames
+ ld a, [rOBP1] ; $ff49
+ srl b
+ rra
+ srl b
+ rra
+ ld [rOBP1], a ; $ff49
+ ld a, b
+ and a
+ jr nz, .asm_7090d
+ ld a, $1
+ ld [H_AUTOBGTRANSFERENABLED], a ; $ffba
+ call Delay3
+ jp CleanLCD_OAM
+
+Func_7092a: ; 7092a (1c:492a)
+ ld de, $9000
+ ld hl, $8000
+ ld bc, $31
+ call CopyVideoData
+ ld a, $10
+ ld [W_BASECOORDY], a ; $d082
+ ld a, $70
+ ld [W_BASECOORDX], a ; $d081
+ ld hl, wOAMBuffer
+ ld bc, $606
+ ld d, $8
+.asm_70948
+ push bc
+ ld a, [W_BASECOORDY] ; $d082
+ ld e, a
+.asm_7094d
+ ld a, e
+ add $8
+ ld e, a
+ ld [hli], a
+ ld a, [W_BASECOORDX] ; $d081
+ ld [hli], a
+ ld a, d
+ ld [hli], a
+ ld a, $10
+ ld [hli], a
+ inc d
+ dec c
+ jr nz, .asm_7094d
+ inc d
+ ld a, [W_BASECOORDX] ; $d081
+ add $8
+ ld [W_BASECOORDX], a ; $d081
+ pop bc
+ dec b
+ jr nz, .asm_70948
+ ret
+
+Func_7096d: ; 7096d (1c:496d)
+ ld a, $1
+ ld [H_AUTOBGTRANSFERENABLED], a ; $ffba
+ call Delay3
+ xor a
+ ld [$ffb0], a
+ dec a
+ ld [$cfcb], a
+ call DelayFrame
+ ld hl, $c102
+ ld a, [H_DOWNARROWBLINKCNT2] ; $ff8c
+ ld c, a
+ ld b, $0
+ ld de, $10
+.asm_70989
+ ld a, [hl]
+ cp $ff
+ jr z, .asm_7098f
+ inc b
+.asm_7098f
+ add hl, de
+ dec c
+ jr nz, .asm_70989
+ ld hl, $c310
+ ld c, $9
+.asm_70998
+ ld a, b
+ swap a
+ cp l
+ jr z, .asm_709a9
+ push hl
+ push bc
+ ld bc, $10
+ xor a
+ call FillMemory
+ pop bc
+ pop hl
+.asm_709a9
+ ld de, $10
+ add hl, de
+ dec c
+ jr nz, .asm_70998
+ call Delay3
+ call LoadBattleTransitionTile
+ ld bc, $0
+ ld a, [W_ISLINKBATTLE] ; $d12b
+ cp $4
+ jr z, .asm_709c9
+ call Func_709e2
+ call Func_709ef
+ call Func_70a19
+.asm_709c9
+ ld hl, PointerTable_709d2 ; $49d2
+ add hl, bc
+ add hl, bc
+ ld a, [hli]
+ ld h, [hl]
+ ld l, a
+ jp [hl]
+
+PointerTable_709d2: ; 709d2 (1c:49d2)
+ dw Func_70d24
+ dw Func_70a72
+ dw Func_70ce4
+ dw Func_70a72
+ dw Func_70cb4
+ dw Func_70b7f
+ dw Func_70c7e
+ dw Func_70bca
+
+Func_709e2: ; 709e2 (1c:49e2)
+ ld a, [W_CUROPPONENT] ; $d059
+ cp $c8
+ jr nc, .asm_709ec
+ res 0, c
+ ret
+.asm_709ec
+ set 0, c
+ ret
+
+Func_709ef: ; 709ef (1c:49ef)
+ ld hl, W_PARTYMON1_HP ; $d16c
+.asm_709f2
+ ld a, [hli]
+ or [hl]
+ jr nz, .asm_709fc
+ ld de, $2b
+ add hl, de
+ jr .asm_709f2
+.asm_709fc
+ ld de, $1f
+ add hl, de
+ ld a, [hl]
+ add $3
+ ld e, a
+ ld a, [W_CURENEMYLVL] ; $d127
+ sub e
+ jr nc, .asm_70a12
+ res 1, c
+ ld a, $1
+ ld [$cd47], a
+ ret
+.asm_70a12
+ set 1, c
+ xor a
+ ld [$cd47], a
+ ret
+
+Func_70a19: ; 70a19 (1c:4a19)
+ ld a, [W_CURMAP] ; $d35e
+ ld e, a
+ ld hl, MapIDList_70a3f ; $4a3f
+.asm_70a20
+ ld a, [hli]
+ cp $ff
+ jr z, .asm_70a2b
+ cp e
+ jr nz, .asm_70a20
+.asm_70a28
+ set 2, c
+ ret
+.asm_70a2b
+ ld hl, MapIDList_70a44 ; $4a44
+.asm_70a2e
+ ld a, [hli]
+ cp $ff
+ jr z, .asm_70a3c
+ ld d, a
+ ld a, [hli]
+ cp e
+ jr c, .asm_70a2e
+ ld a, e
+ cp d
+ jr nc, .asm_70a28
+.asm_70a3c
+ res 2, c
+ ret
+
+; Func_70a19 checks if W_CURMAP is equal to one of these maps
+MapIDList_70a3f: ; 70a3f (1c:4a3f)
+ db VIRIDIAN_FOREST
+ db ROCK_TUNNEL_1
+ db SEAFOAM_ISLANDS_1
+ db ROCK_TUNNEL_2
+ db $FF
+
+; Func_70a19 checks if W_CURMAP is in between or equal to each pair of maps
+MapIDList_70a44: ; 70a44 (1c:4a44)
+ ; all MT_MOON maps
+ db MT_MOON_1
+ db MT_MOON_3
+
+ ; all SS_ANNE maps, VICTORY_ROAD_1, LANCES_ROOM, and HALL_OF_FAME
+ db SS_ANNE_1
+ db HALL_OF_FAME
+
+ ; all POKEMONTOWER maps and Lavender Town buildings
+ db LAVENDER_POKECENTER
+ db LAVENDER_HOUSE_2
+
+ ; all SILPH_CO, MANSION, SAFARI_ZONE, and UNKNOWN_DUNGEON maps,
+ ; except for SILPH_CO_1F
+ db SILPH_CO_2F
+ db UNKNOWN_DUNGEON_1
+ db $FF
+
+LoadBattleTransitionTile: ; 70a4d (1c:4a4d)
+ ld hl, $8ff0
+ ld de, BattleTransitionTile ; $4a59
+ ld bc, (BANK(BattleTransitionTile) << 8) + $01
+ jp CopyVideoData
+
+BattleTransitionTile: ; 70a59 (1c:4a59)
+ INCBIN "gfx/battle_transition.2bpp"
+
+Func_70a69: ; 70a69 (1c:4a69)
+ ld a, $ff
+ ld [rBGP], a ; $ff47
+ ld [rOBP0], a ; $ff48
+ ld [rOBP1], a ; $ff49
+ ret
+
+Func_70a72: ; 70a72 (1c:4a72)
+ ld a, [$cd47]
+ and a
+ jr z, .asm_70a7d
+ call Func_70aaa
+ jr .asm_70a9f
+.asm_70a7d
+ FuncCoord 10, 10 ; $c472
+ ld hl, Coord
+ ld a, $3
+ ld [$d09f], a
+ ld a, l
+ ld [$d09b], a
+ ld a, h
+ ld [$d09a], a
+ ld b, $78
+.asm_70a8f
+ ld c, $3
+.asm_70a91
+ push bc
+ call Func_70af9
+ pop bc
+ dec c
+ jr nz, .asm_70a91
+ call DelayFrame
+ dec b
+ jr nz, .asm_70a8f
+.asm_70a9f
+ call Func_70a69
+ xor a
+ ld [$d09b], a
+ ld [$d09a], a
+ ret
+
+Func_70aaa: ; 70aaa (1c:4aaa)
+ ld a, $7
+ ld [wWhichTrade], a ; $cd3d
+ ld hl, wTileMap
+ ld c, $11
+ ld de, $14
+ call Func_70ae0
+ inc c
+ jr .asm_70ac3
+.asm_70abd
+ ld de, $14
+ call Func_70ae0
+.asm_70ac3
+ inc c
+ ld de, $1
+ call Func_70ae0
+ dec c
+ dec c
+ ld de, $ffec
+ call Func_70ae0
+ inc c
+ ld de, rIE ; $ffff
+ call Func_70ae0
+ dec c
+ dec c
+ ld a, c
+ and a
+ jr nz, .asm_70abd
+ ret
+
+Func_70ae0: ; 70ae0 (1c:4ae0)
+ push bc
+.asm_70ae1
+ ld [hl], $ff
+ add hl, de
+ push bc
+ ld a, [wWhichTrade] ; $cd3d
+ dec a
+ jr nz, .asm_70af0
+ call Func_70d19
+ ld a, $7
+.asm_70af0
+ ld [wWhichTrade], a ; $cd3d
+ pop bc
+ dec c
+ jr nz, .asm_70ae1
+ pop bc
+ ret
+
+Func_70af9: ; 70af9 (1c:4af9)
+ ld bc, $ffec
+ ld de, $14
+ ld a, [$d09b]
+ ld l, a
+ ld a, [$d09a]
+ ld h, a
+ ld a, [$d09f]
+ cp $0
+ jr z, .asm_70b25
+ cp $1
+ jr z, .asm_70b2f
+ cp $2
+ jr z, .asm_70b39
+ cp $3
+ jr z, .asm_70b43
+.asm_70b1a
+ ld [hl], $ff
+.asm_70b1c
+ ld a, l
+ ld [$d09b], a
+ ld a, h
+ ld [$d09a], a
+ ret
+.asm_70b25
+ dec hl
+ ld a, [hl]
+ cp $ff
+ jr nz, .asm_70b4d
+ inc hl
+ add hl, bc
+ jr .asm_70b1a
+.asm_70b2f
+ add hl, de
+ ld a, [hl]
+ cp $ff
+ jr nz, .asm_70b4d
+ add hl, bc
+ dec hl
+ jr .asm_70b1a
+.asm_70b39
+ inc hl
+ ld a, [hl]
+ cp $ff
+ jr nz, .asm_70b4d
+ dec hl
+ add hl, de
+ jr .asm_70b1a
+.asm_70b43
+ add hl, bc
+ ld a, [hl]
+ cp $ff
+ jr nz, .asm_70b4d
+ add hl, de
+ inc hl
+ jr .asm_70b1a
+.asm_70b4d
+ ld [hl], $ff
+ ld a, [$d09f]
+ inc a
+ cp $4
+ jr nz, .asm_70b58
+ xor a
+.asm_70b58
+ ld [$d09f], a
+ jr .asm_70b1c
+
+Func_70b5d: ; 70b5d (1c:4b5d)
+ ld hl, DataTable_70b72 ; $4b72
+.asm_70b60
+ ld a, [hli]
+ cp $1
+ jr z, .asm_70b6e
+ ld [rBGP], a ; $ff47
+ ld c, $2
+ call DelayFrames
+ jr .asm_70b60
+.asm_70b6e
+ dec b
+ jr nz, Func_70b5d
+ ret
+
+DataTable_70b72: ; 70b72 (1c:4b72)
+ db $F9,$FE,$FF,$FE,$F9,$E4,$90,$40,$00,$40,$90,$E4
+ db $01 ; terminator
+
+Func_70b7f: ; 70b7f (1c:4b7f)
+ ld c, $9
+.asm_70b81
+ push bc
+ xor a
+ ld [H_AUTOBGTRANSFERENABLED], a ; $ffba
+ FuncCoord 0, 7 ; $c42c
+ ld hl, Coord
+ FuncCoord 0, 8 ; $c440
+ ld de, Coord
+ ld bc, $ffd8
+ call Func_70c12
+ FuncCoord 0, 10 ; $c468
+ ld hl, Coord
+ FuncCoord 0, 9 ; $c454
+ ld de, Coord
+ ld bc, $28
+ call Func_70c12
+ FuncCoord 8, 0 ; $c3a8
+ ld hl, Coord
+ FuncCoord 9, 0 ; $c3a9
+ ld de, Coord
+ ld bc, $fffe
+ call Func_70c3f
+ FuncCoord 11, 0 ; $c3ab
+ ld hl, Coord
+ FuncCoord 10, 0 ; $c3aa
+ ld de, Coord
+ ld bc, $2
+ call Func_70c3f
+ ld a, $1
+ ld [H_AUTOBGTRANSFERENABLED], a ; $ffba
+ ld c, $6
+ call DelayFrames
+ pop bc
+ dec c
+ jr nz, .asm_70b81
+ call Func_70a69
+ ld c, $a
+ jp DelayFrames
+
+Func_70bca: ; 70bca (1c:4bca)
+ ld c, $9
+ xor a
+ ld [H_AUTOBGTRANSFERENABLED], a ; $ffba
+.asm_70bcf
+ push bc
+ FuncCoord 0, 16 ; $c4e0
+ ld hl, Coord
+ FuncCoord 0, 17 ; $c4f4
+ ld de, Coord
+ ld bc, $ffd8
+ call Func_70c12
+ FuncCoord 0, 1 ; $c3b4
+ ld hl, Coord
+ ld de, wTileMap
+ ld bc, $28
+ call Func_70c12
+ FuncCoord 18, 0 ; $c3b2
+ ld hl, Coord
+ FuncCoord 19, 0 ; $c3b3
+ ld de, Coord
+ ld bc, $fffe
+ call Func_70c3f
+ FuncCoord 1, 0 ; $c3a1
+ ld hl, Coord
+ ld de, wTileMap
+ ld bc, $2
+ call Func_70c3f
+ call Func_70d19
+ call Delay3
+ pop bc
+ dec c
+ jr nz, .asm_70bcf
+ call Func_70a69
+ ld c, $a
+ jp DelayFrames
+
+Func_70c12: ; 70c12 (1c:4c12)
+ ld a, c
+ ld [wWhichTrade], a ; $cd3d
+ ld a, b
+ ld [$cd3e], a
+ ld c, $8
+.asm_70c1c
+ push bc
+ push hl
+ push de
+ ld bc, $14
+ call CopyData
+ pop hl
+ pop de
+ ld a, [wWhichTrade] ; $cd3d
+ ld c, a
+ ld a, [$cd3e]
+ ld b, a
+ add hl, bc
+ pop bc
+ dec c
+ jr nz, .asm_70c1c
+ ld l, e
+ ld h, d
+ ld a, $ff
+ ld c, $14
+.asm_70c3a
+ ld [hli], a
+ dec c
+ jr nz, .asm_70c3a
+ ret
+
+Func_70c3f: ; 70c3f (1c:4c3f)
+ ld a, c
+ ld [wWhichTrade], a ; $cd3d
+ ld a, b
+ ld [$cd3e], a
+ ld c, $9
+.asm_70c49
+ push bc
+ push hl
+ push de
+ ld c, $12
+.asm_70c4e
+ ld a, [hl]
+ ld [de], a
+ ld a, e
+ add $14
+ jr nc, .asm_70c56
+ inc d
+.asm_70c56
+ ld e, a
+ ld a, l
+ add $14
+ jr nc, .asm_70c5d
+ inc h
+.asm_70c5d
+ ld l, a
+ dec c
+ jr nz, .asm_70c4e
+ pop hl
+ pop de
+ ld a, [wWhichTrade] ; $cd3d
+ ld c, a
+ ld a, [$cd3e]
+ ld b, a
+ add hl, bc
+ pop bc
+ dec c
+ jr nz, .asm_70c49
+ ld l, e
+ ld h, d
+ ld de, $14
+ ld c, $12
+.asm_70c77
+ ld [hl], $ff
+ add hl, de
+ dec c
+ jr nz, .asm_70c77
+ ret
+
+Func_70c7e: ; 70c7e (1c:4c7e)
+ ld c, $12
+ ld hl, wTileMap
+ FuncCoord 1, 17 ; $c4f5
+ ld de, Coord
+ xor a
+ ld [H_AUTOBGTRANSFERENABLED], a ; $ffba
+.asm_70c89
+ push bc
+ push hl
+ push de
+ push de
+ call Func_70caa
+ pop hl
+ call Func_70caa
+ call Func_70d19
+ pop hl
+ ld bc, $ffec
+ add hl, bc
+ ld e, l
+ ld d, h
+ pop hl
+ ld bc, $14
+ add hl, bc
+ pop bc
+ dec c
+ jr nz, .asm_70c89
+ jp Func_70a69
+
+Func_70caa: ; 70caa (1c:4caa)
+ ld c, $a
+.asm_70cac
+ ld [hl], $ff
+ inc hl
+ inc hl
+ dec c
+ jr nz, .asm_70cac
+ ret
+
+Func_70cb4: ; 70cb4 (1c:4cb4)
+ ld c, $14
+ ld hl, wTileMap
+ FuncCoord 19, 1 ; $c3c7
+ ld de, Coord
+ xor a
+ ld [H_AUTOBGTRANSFERENABLED], a ; $ffba
+.asm_70cbf
+ push bc
+ push hl
+ push de
+ push de
+ call Func_70cd8
+ pop hl
+ call Func_70cd8
+ call Func_70d19
+ pop de
+ pop hl
+ pop bc
+ inc hl
+ dec de
+ dec c
+ jr nz, .asm_70cbf
+ jp Func_70a69
+
+Func_70cd8: ; 70cd8 (1c:4cd8)
+ ld c, $9
+ ld de, $28
+.asm_70cdd
+ ld [hl], $ff
+ add hl, de
+ dec c
+ jr nz, .asm_70cdd
+ ret
+
+Func_70ce4: ; 70ce4 (1c:4ce4)
+ call Func_70cfd
+ ld bc, $000a
+ ld hl, Unknown_70d61
+ call Func_70d06
+ ld c, $a
+ ld b, $1
+ ld hl, Unknown_70d93
+ call Func_70d06
+ jp Func_70a69
+
+Func_70cfd: ; 70cfd (1c:4cfd)
+ ld b, $3
+ call Func_70b5d
+ xor a
+ ld [H_AUTOBGTRANSFERENABLED], a ; $ffba
+ ret
+
+Func_70d06: ; 70d06 (1c:4d06)
+ push bc
+ push hl
+ ld a, b
+ call Func_70d50
+ pop hl
+ ld bc, $0005
+ add hl, bc
+ call Func_70d19
+ pop bc
+ dec c
+ jr nz, Func_70d06
+ ret
+
+Func_70d19: ; 70d19 (1c:4d19)
+ ld a, $1
+ ld [H_AUTOBGTRANSFERENABLED], a ; $ffba
+ call Delay3
+ xor a
+ ld [H_AUTOBGTRANSFERENABLED], a ; $ffba
+ ret
+
+Func_70d24: ; 70d24 (1c:4d24)
+ call Func_70cfd
+ ld c, $a
+ ld hl, Unknown_70d61 ; $4d61
+ ld de, Unknown_70d93 ; $4d93
+.asm_70d2f
+ push bc
+ push hl
+ push de
+ push de
+ xor a
+ call Func_70d50
+ pop hl
+ ld a, $1
+ call Func_70d50
+ pop hl
+ ld bc, $5
+ add hl, bc
+ ld e, l
+ ld d, h
+ pop hl
+ add hl, bc
+ call Func_70d19
+ pop bc
+ dec c
+ jr nz, .asm_70d2f
+ jp Func_70a69
+
+Func_70d50: ; 70d50 (1c:4d50)
+ ld [wWhichTrade], a ; $cd3d
+ ld a, [hli]
+ ld [$cd3e], a
+ ld a, [hli]
+ ld e, a
+ ld a, [hli]
+ ld d, a
+ ld a, [hli]
+ ld h, [hl]
+ ld l, a
+ jp Func_70dc5
+
+Unknown_70d61: ; 70d61 (1c:4d61)
+ db $01
+ dw Unknown_70dfe
+ FuncCoord 18, 6
+ dw Coord
+
+ db $01
+ dw Unknown_70e04
+ FuncCoord 19, 3
+ dw Coord
+
+ db $01
+ dw Unknown_70e0e
+ FuncCoord 18, 0
+ dw Coord
+
+ db $01
+ dw Unknown_70e20
+ FuncCoord 14, 0
+ dw Coord
+
+ db $01
+ dw Unknown_70e2e
+ FuncCoord 10, 0
+ dw Coord
+
+ db $00
+ dw Unknown_70e2e
+ FuncCoord 9, 0
+ dw Coord
+
+ db $00
+ dw Unknown_70e20
+ FuncCoord 5, 0
+ dw Coord
+
+ db $00
+ dw Unknown_70e0e
+ FuncCoord 1, 0
+ dw Coord
+
+ db $00
+ dw Unknown_70e04
+ FuncCoord 0, 3
+ dw Coord
+
+ db $00
+ dw Unknown_70dfe
+ FuncCoord 1, 6
+ dw Coord
+
+Unknown_70d93: ; 70d93 (1c:4d93)
+ db $00
+ dw Unknown_70dfe
+ FuncCoord 1, 11
+ dw Coord
+
+ db $00
+ dw Unknown_70e04
+ FuncCoord 0, 14
+ dw Coord
+
+ db $00
+ dw Unknown_70e0e
+ FuncCoord 1, 17
+ dw Coord
+
+ db $00
+ dw Unknown_70e20
+ FuncCoord 5, 17
+ dw Coord
+
+ db $00
+ dw Unknown_70e2e
+ FuncCoord 9, 17
+ dw Coord
+
+ db $01
+ dw Unknown_70e2e
+ FuncCoord 10, 17
+ dw Coord
+
+ db $01
+ dw Unknown_70e20
+ FuncCoord 14, 17
+ dw Coord
+
+ db $01
+ dw Unknown_70e0e
+ FuncCoord 18, 17
+ dw Coord
+
+ db $01
+ dw Unknown_70e04
+ FuncCoord 19, 14
+ dw Coord
+
+ db $01
+ dw Unknown_70dfe
+ FuncCoord 18, 11
+ dw Coord
+
+Func_70dc5: ; 70dc5 (1c:4dc5)
+ push hl
+ ld a, [de]
+ ld c, a
+ inc de
+.asm_70dc9
+ ld [hl], $ff
+ ld a, [$cd3e]
+ and a
+ jr z, .asm_70dd4
+ inc hl
+ jr .asm_70dd5
+.asm_70dd4
+ dec hl
+.asm_70dd5
+ dec c
+ jr nz, .asm_70dc9
+ pop hl
+ ld a, [wWhichTrade] ; $cd3d
+ and a
+ ld bc, $14
+ jr z, .asm_70de5
+ ld bc, $ffec
+.asm_70de5
+ add hl, bc
+ ld a, [de]
+ inc de
+ cp $ff
+ ret z
+ and a
+ jr z, Func_70dc5
+ ld c, a
+.asm_70def
+ ld a, [$cd3e]
+ and a
+ jr z, .asm_70df8
+ dec hl
+ jr .asm_70df9
+.asm_70df8
+ inc hl
+.asm_70df9
+ dec c
+ jr nz, .asm_70def
+ jr Func_70dc5
+
+Unknown_70dfe: ; 70dfe (1c:4dfe)
+ db $02,$03,$05,$04,$09,$FF
+
+Unknown_70e04: ; 70e04 (1c:4e04)
+ db $01,$01,$02,$02,$04,$02,$04,$02,$03,$FF
+
+Unknown_70e0e: ; 70e0e (1c:4e0e)
+ db $02,$01,$03,$01,$04,$01,$04,$01,$04,$01,$03,$01,$02,$01,$01,$01,$01,$FF
+
+Unknown_70e20: ; 70e20 (1c:4e20)
+ db $04,$01,$04,$00,$03,$01,$03,$00,$02,$01,$02,$00,$01,$FF
+
+Unknown_70e2e: ; 70e2e (1c:4e2e)
+ db $04,$00,$03,$00,$03,$00,$02,$00,$02,$00,$01,$00,$01,$00,$01,$FF
diff --git a/engine/battle/4.asm b/engine/battle/4.asm
new file mode 100755
index 00000000..b19b3b49
--- /dev/null
+++ b/engine/battle/4.asm
@@ -0,0 +1,78 @@
+Func_128d8: ; 128d8 (4:68d8)
+ ld a, [W_YCOORD] ; $d361
+ ld b, a
+ ld a, [W_CURMAPHEIGHT] ; $d368
+ call Func_128ea
+ ret z
+ ld a, [W_XCOORD] ; $d362
+ ld b, a
+ ld a, [W_CURMAPWIDTH] ; $d369
+
+Func_128ea: ; 128ea (4:68ea)
+ add a
+ cp b
+ ret z
+ inc b
+ ret
+
+Func_128ef: ; 128ef (4:68ef)
+ call Load16BitRegisters
+ ld a, $1
+ jr asm_128fb
+
+Func_128f6: ; 128f6 (4:68f6)
+ call Load16BitRegisters
+ ld a, $2
+asm_128fb: ; 128fb (4:68fb)
+ ld [wListMenuID], a ; $cf94
+ push hl
+ ld a, [$cf99]
+ ld b, a
+ ld a, [$cf9a]
+ ld c, a
+ or b
+ jr nz, .asm_12913
+ xor a
+ ld c, a
+ ld e, a
+ ld a, $6
+ ld d, a
+ jp Func_12924
+.asm_12913
+ ld a, [$cfba]
+ ld d, a
+ ld a, [$cfbb]
+ ld e, a
+ ld a, $26
+ call Predef ; indirect jump to UpdateHPBar_LoadRegisters (f9dc (3:79dc))
+ ld a, $6
+ ld d, a
+ ld c, a
+
+Func_12924: ; 12924 (4:6924)
+ pop hl
+ push de
+ push hl
+ push hl
+ call DrawHPBar
+ pop hl
+ ld a, [$fff6]
+ bit 0, a
+ jr z, .asm_12937
+ ld bc, $9
+ jr .asm_1293a
+.asm_12937
+ ld bc, $15
+.asm_1293a
+ add hl, bc
+ ld de, $cf99
+ ld bc, $203
+ call PrintNumber
+ ld a, "/"
+ ld [hli], a
+ ld de, $cfba
+ ld bc, $203
+ call PrintNumber
+ pop hl
+ pop de
+ ret
diff --git a/engine/battle/4_2.asm b/engine/battle/4_2.asm
new file mode 100755
index 00000000..de9aa7be
--- /dev/null
+++ b/engine/battle/4_2.asm
@@ -0,0 +1,409 @@
+Func_137aa: ; 137aa (4:77aa)
+ ld a, [W_ISLINKBATTLE] ; $d12b
+ cp $4
+ jr nz, .asm_137eb
+ ld a, [W_ENEMYMONNUMBER] ; $cfe8
+ ld hl, $d8a8
+ ld bc, $2c
+ call AddNTimes
+ ld a, [W_ENEMYMONSTATUS] ; $cfe9
+ ld [hl], a
+ call ClearScreen
+ callab Func_372d6
+ ld a, [$cf0b]
+ cp $1
+ ld de, YouWinText
+ jr c, .asm_137de
+ ld de, YouLoseText
+ jr z, .asm_137de
+ ld de, DrawText
+.asm_137de
+ FuncCoord 6, 8 ; $c446
+ ld hl, Coord
+ call PlaceString
+ ld c, $c8
+ call DelayFrames
+ jr .asm_1380a
+.asm_137eb
+ ld a, [$cf0b]
+ and a
+ jr nz, .asm_13813
+ ld hl, $cce5
+ ld a, [hli]
+ or [hl]
+ inc hl
+ or [hl]
+ jr z, .asm_1380a
+ ld de, wPlayerMoney + 2 ; $d349
+ ld c, $3
+ ld a, $b
+ call Predef ; indirect jump to Func_f81d (f81d (3:781d))
+ ld hl, PickUpPayDayMoneyText
+ call PrintText
+.asm_1380a
+ xor a
+ ld [$ccd4], a
+ ld a, $2a
+ call Predef ; indirect jump to Func_3ad1c (3ad1c (e:6d1c))
+.asm_13813
+ xor a
+ ld [$d083], a
+ ld [$c02a], a
+ ld [W_ISINBATTLE], a ; $d057
+ ld [W_BATTLETYPE], a ; $d05a
+ ld [W_MOVEMISSED], a ; $d05f
+ ld [W_CUROPPONENT], a ; $d059
+ ld [$d11f], a
+ ld [$d120], a
+ ld [$d078], a
+ ld hl, $cc2b
+ ld [hli], a
+ ld [hli], a
+ ld [hli], a
+ ld [hl], a
+ ld [wListScrollOffset], a ; $cc36
+ ld hl, $d060
+ ld b, $18
+.asm_1383e
+ ld [hli], a
+ dec b
+ jr nz, .asm_1383e
+ ld hl, $d72c
+ set 0, [hl]
+ call WaitForSoundToFinish
+ call GBPalWhiteOut
+ ld a, $ff
+ ld [$d42f], a
+ ret
+
+YouWinText: ; 13853 (4:7853)
+ db "YOU WIN@"
+
+YouLoseText: ; 1385b (4:785b)
+ db "YOU LOSE@"
+
+DrawText: ; 13864 (4:7864)
+ db " DRAW@"
+
+PickUpPayDayMoneyText: ; 1386b (4:786b)
+ TX_FAR _PickUpPayDayMoneyText
+ db "@"
+
+Func_13870: ; 13870 (4:7870)
+ ld a, [$cc57]
+ and a
+ ret nz
+ ld a, [$d736]
+ and a
+ ret nz
+ callab Func_c49d
+ jr nc, .asm_13888
+.asm_13884
+ ld a, $1
+ and a
+ ret
+.asm_13888
+ callab Func_128d8
+ jr z, .asm_13884
+ ld a, [$d0db]
+ and a
+ jr z, .asm_1389e
+ dec a
+ jr z, .asm_13905
+ ld [$d0db], a
+.asm_1389e
+ FuncCoord 9, 9 ; $c45d
+ ld hl, Coord
+ ld c, [hl]
+ ld a, [W_GRASSTILE]
+ cp c
+ ld a, [W_GRASSRATE] ; $d887
+ jr z, .asm_138c4
+ ld a, $14
+ cp c
+ ld a, [W_WATERRATE] ; $d8a4
+ jr z, .asm_138c4
+ ld a, [W_CURMAP] ; $d35e
+ cp REDS_HOUSE_1F
+ jr c, .asm_13912
+ ld a, [W_CURMAPTILESET] ; $d367
+ cp FOREST ; Viridian Forest/Safari Zone
+ jr z, .asm_13912
+ ld a, [W_GRASSRATE] ; $d887
+.asm_138c4
+ ld b, a
+ ld a, [H_RAND1] ; $ffd3
+ cp b
+ jr nc, .asm_13912
+ ld a, [H_RAND2] ; $ffd4
+ ld b, a
+ ld hl, WildMonEncounterSlotChances ; $7918
+.asm_138d0
+ ld a, [hli]
+ cp b
+ jr nc, .asm_138d7
+ inc hl
+ jr .asm_138d0
+.asm_138d7
+ ld c, [hl]
+ ld hl, W_GRASSMONS ; $d888
+ FuncCoord 8, 9 ; $c45c
+ ld a, [Coord]
+ cp $14
+ jr nz, .asm_138e5
+ ld hl, W_WATERMONS ; $d8a5 (aliases: W_ENEMYMON1HP)
+.asm_138e5
+ ld b, $0
+ add hl, bc
+ ld a, [hli]
+ ld [W_CURENEMYLVL], a ; $d127
+ ld a, [hl]
+ ld [$cf91], a
+ ld [W_ENEMYMONID], a
+ ld a, [$d0db]
+ and a
+ jr z, .asm_13916
+ ld a, [W_PARTYMON1_LEVEL] ; $d18c
+ ld b, a
+ ld a, [W_CURENEMYLVL] ; $d127
+ cp b
+ jr c, .asm_13912
+ jr .asm_13916
+.asm_13905
+ ld [$d0db], a
+ ld a, $d2
+ ld [H_DOWNARROWBLINKCNT2], a ; $ff8c
+ call EnableAutoTextBoxDrawing
+ call DisplayTextID
+.asm_13912
+ ld a, $1
+ and a
+ ret
+.asm_13916
+ xor a
+ ret
+
+WildMonEncounterSlotChances: ; 13918 (4:7918)
+; There are 10 slots for wild pokemon, and this is the table that defines how common each of
+; those 10 slots is. A random number is generated and then the first byte of each pair in this
+; table is compared against that random number. If the random number is less than or equal
+; to the first byte, then that slot is chosen. The second byte is double the slot number.
+ db $32, $00 ; 51/256 = 19.9% chance of slot 0
+ db $65, $02 ; 51/256 = 19.9% chance of slot 1
+ db $8C, $04 ; 39/256 = 15.2% chance of slot 2
+ db $A5, $06 ; 25/256 = 9.8% chance of slot 3
+ db $BE, $08 ; 25/256 = 9.8% chance of slot 4
+ db $D7, $0A ; 25/256 = 9.8% chance of slot 5
+ db $E4, $0C ; 13/256 = 5.1% chance of slot 6
+ db $F1, $0E ; 13/256 = 5.1% chance of slot 7
+ db $FC, $10 ; 11/256 = 4.3% chance of slot 8
+ db $FF, $12 ; 3/256 = 1.2% chance of slot 9
+
+RecoilEffect_: ; 1392c (4:792c)
+ ld a, [H_WHOSETURN] ; $fff3
+ and a
+ ld a, [W_PLAYERMOVENUM] ; $cfd2
+ ld hl, W_PLAYERMONMAXHP ; $d023
+ jr z, .asm_1393d
+ ld a, [W_ENEMYMOVENUM] ; $cfcc
+ ld hl, W_ENEMYMONMAXHP ; $cff4
+.asm_1393d
+ ld d, a
+ ld a, [W_DAMAGE] ; $d0d7
+ ld b, a
+ ld a, [W_DAMAGE + 1]
+ ld c, a
+ srl b
+ rr c
+ ld a, d
+ cp STRUGGLE
+ jr z, .asm_13953
+ srl b
+ rr c
+.asm_13953
+ ld a, b
+ or c
+ jr nz, .asm_13958
+ inc c
+.asm_13958
+ ld a, [hli]
+ ld [wHPBarMaxHP+1], a
+ ld a, [hl]
+ ld [wHPBarMaxHP], a
+ push bc
+ ld bc, $fff2
+ add hl, bc
+ pop bc
+ ld a, [hl]
+ ld [wHPBarOldHP], a
+ sub c
+ ld [hld], a
+ ld [wHPBarNewHP], a
+ ld a, [hl]
+ ld [wHPBarOldHP+1], a
+ sbc b
+ ld [hl], a
+ ld [wHPBarNewHP+1], a
+ jr nc, .asm_13982
+ xor a
+ ld [hli], a
+ ld [hl], a
+ ld hl, wHPBarNewHP
+ ld [hli], a
+ ld [hl], a
+.asm_13982
+ FuncCoord 10, 9 ; $c45e
+ ld hl, Coord
+ ld a, [H_WHOSETURN] ; $fff3
+ and a
+ ld a, $1
+ jr z, .asm_13990
+ FuncCoord 2, 2 ; $c3ca
+ ld hl, Coord
+ xor a
+.asm_13990
+ ld [wListMenuID], a ; $cf94
+ ld a, $48
+ call Predef ; indirect jump to UpdateHPBar (fa1d (3:7a1d))
+ ld hl, HitWithRecoilText ; $799e
+ jp PrintText
+HitWithRecoilText: ; 1399e (4:799e)
+ TX_FAR _HitWithRecoilText
+ db "@"
+
+ConversionEffect_: ; 139a3 (4:79a3)
+ ld hl, W_ENEMYMONTYPE1
+ ld de, W_PLAYERMONTYPE1
+ ld a, [H_WHOSETURN]
+ and a
+ ld a, [W_ENEMYBATTSTATUS1]
+ jr z, .asm_139b8
+ push hl
+ ld h, d
+ ld l, e
+ pop de
+ ld a, [W_PLAYERBATTSTATUS1]
+.asm_139b8
+ bit 6, a ; is mon immune to typical attacks (dig/fly)
+ jr nz, PrintButItFailedText
+ ld a, [hli]
+ ld [de], a
+ inc de
+ ld a, [hl]
+ ld [de], a
+ ld hl, Func_3fba8
+ call Func_139d5
+ ld hl, ConvertedTypeText
+ jp PrintText
+
+ConvertedTypeText: ; 139cd (4:79cd)
+ TX_FAR _ConvertedTypeText
+ db "@"
+
+PrintButItFailedText: ; 139d2 (4:79d2)
+ ld hl, PrintButItFailedText_
+Func_139d5: ; 139d5 (4:79d5)
+ ld b, BANK(PrintButItFailedText_)
+ jp Bankswitch
+
+HazeEffect_: ; 139da (4:79da)
+ ld a, $7
+ ld hl, wPlayerMonAttackMod
+ call Func_13a43
+ ld hl, wEnemyMonAttackMod
+ call Func_13a43
+ ld hl, $cd12
+ ld de, W_PLAYERMONATK
+ call Func_13a4a
+ ld hl, $cd26
+ ld de, W_ENEMYMONATTACK
+ call Func_13a4a
+ ld hl, W_ENEMYMONSTATUS
+ ld de, wEnemySelectedMove
+ ld a, [H_WHOSETURN]
+ and a
+ jr z, .asm_13a09
+ ld hl, W_PLAYERMONSTATUS
+ dec de
+
+.asm_13a09
+ ld a, [hl]
+ ld [hl], $0
+ and $27
+ jr z, .asm_13a13
+ ld a, $ff
+ ld [de], a
+
+.asm_13a13
+ xor a
+ ld [W_PLAYERDISABLEDMOVE], a
+ ld [W_ENEMYDISABLEDMOVE], a
+ ld hl, $ccee
+ ld [hli], a
+ ld [hl], a
+ ld hl, W_PLAYERBATTSTATUS1
+ call Func_13a37
+ ld hl, W_ENEMYBATTSTATUS1
+ call Func_13a37
+ ld hl, Func_3fba8
+ call Func_139d5
+ ld hl, StatusChangesEliminatedText
+ jp PrintText
+
+Func_13a37: ; 13a37 (4:7a37)
+ res 7, [hl]
+ inc hl
+ ld a, [hl]
+ and $78
+ ld [hli], a
+ ld a, [hl]
+ and $f8
+ ld [hl], a
+ ret
+
+Func_13a43: ; 13a43 (4:7a43)
+ ld b, $8
+.loop
+ ld [hli], a
+ dec b
+ jr nz, .loop
+ ret
+
+Func_13a4a: ; 13a4a (4:7a4a)
+ ld b, $8
+.loop
+ ld a, [hli]
+ ld [de], a
+ inc de
+ dec b
+ jr nz, .loop
+ ret
+
+StatusChangesEliminatedText: ; 13a53 (4:7a53)
+ TX_FAR _StatusChangesEliminatedText
+ db "@"
+
+GetTrainerName_: ; 13a58 (4:7a58)
+ ld hl, W_GRASSRATE ; $d887
+ ld a, [W_ISLINKBATTLE] ; $d12b
+ and a
+ jr nz, .rival
+ ld hl, W_RIVALNAME ; $d34a
+ ld a, [W_TRAINERCLASS] ; $d031
+ cp SONY1
+ jr z, .rival
+ cp SONY2
+ jr z, .rival
+ cp SONY3
+ jr z, .rival
+ ld [$d0b5], a
+ ld a, TRAINER_NAME
+ ld [W_LISTTYPE], a
+ ld a, $e
+ ld [$d0b7], a
+ call GetName
+ ld hl, $cd6d
+.rival
+ ld de, W_TRAINERNAME
+ ld bc, $d
+ jp CopyData
diff --git a/engine/battle/5.asm b/engine/battle/5.asm
new file mode 100755
index 00000000..4dbfb4df
--- /dev/null
+++ b/engine/battle/5.asm
@@ -0,0 +1,77 @@
+SubstituteEffectHandler: ; 17dad (5:7dad)
+ ld c, 50
+ call DelayFrames
+ ld hl, W_PLAYERMONMAXHP
+ ld de, wPlayerSubstituteHP
+ ld bc, W_PLAYERBATTSTATUS2
+ ld a, [$fff3] ;whose turn?
+ and a
+ jr z, .notEnemy
+ ld hl, W_ENEMYMONMAXHP
+ ld de, wEnemySubstituteHP
+ ld bc, W_ENEMYBATTSTATUS2
+.notEnemy
+ ld a, [bc] ;load flags
+ bit 4, a ;user already has substitute?
+ jr nz, .alreadyHasSubstitute ;skip this code if so
+ ;user doesn't have a substitute [yet]
+ push bc
+ ld a, [hli] ;load max hp
+ ld b, [hl]
+ srl a ;max hp / 4, [quarter health to remove from user]
+ rr b
+ srl a
+ rr b
+ push de
+ ld de, $fff2 ;subtract 8 to point to [current hp] instead of [max hp]
+ add hl, de ;HL -= 8
+ pop de
+ ld a, b
+ ld [de], a ;save copy of HP to subtract in ccd7/ccd8 [how much HP substitute has]
+ ld a, [hld] ;load current hp
+ sub b ;subtract [max hp / 4]
+ ld d, a ;save low byte result in D
+ ld a, [hl]
+ sbc a, 0 ;borrow from high byte if needed
+ pop bc
+ jr c, .notEnoughHP ;underflow means user would be left with negative health
+ ;bug: note since it only brances on carry, it will possibly leave user with 0HP
+.userHasZeroOrMoreHP
+ ldi [hl], a ;store high byte HP
+ ld [hl], d ;store low byte HP
+ ld h, b
+ ld l, c
+ set 4, [hl] ;set bit 4 of flags, user now has substitute
+ ld a, [$d355] ;load options
+ bit 7, a ;battle animation is enabled?
+ ld hl, Func_3fba8 ; $7ba8 ;animation enabled: 0F:7BA8
+ ld b, BANK(Func_3fba8)
+ jr z, .animationEnabled
+ ld hl, AnimationSubstitute ;animation disabled: 1E:56E0
+ ld b, BANK(AnimationSubstitute)
+.animationEnabled
+ call Bankswitch ;jump to routine depending on animation setting
+ ld hl, SubstituteText
+ call PrintText
+ ld hl, Func_3cd5a
+ ld b, BANK(Func_3cd5a)
+ jp Bankswitch
+.alreadyHasSubstitute
+ ld hl, HasSubstituteText
+ jr .printText
+.notEnoughHP
+ ld hl, TooWeakSubstituteText
+.printText
+ jp PrintText
+
+SubstituteText: ; 17e1d (5:7e1d)
+ TX_FAR _SubstituteText
+ db "@"
+
+HasSubstituteText: ; 17e22 (5:7e22)
+ TX_FAR _HasSubstituteText
+ db "@"
+
+TooWeakSubstituteText: ; 17e27 (5:7e27)
+ TX_FAR _TooWeakSubstituteText
+ db "@"
diff --git a/engine/battle/9.asm b/engine/battle/9.asm
new file mode 100755
index 00000000..79624d34
--- /dev/null
+++ b/engine/battle/9.asm
@@ -0,0 +1,182 @@
+Func_27d6b: ; 27d6b (9:7d6b)
+ call Load16BitRegisters
+ push hl
+ call GetMonHeader
+ pop hl
+ push hl
+ ld a, [W_MONHTYPE1]
+ call Func_27d89
+ ld a, [W_MONHTYPE1]
+ ld b, a
+ ld a, [W_MONHTYPE2]
+ cp b
+ pop hl
+ jr z, asm_27d8c
+ ld bc, $28
+ add hl, bc
+
+Func_27d89: ; 27d89 (9:7d89)
+ push hl
+ jr asm_27d9f
+asm_27d8c: ; 27d8c (9:7d8c)
+ ld a, $7f
+ ld bc, $13
+ add hl, bc
+ ld bc, $6
+ jp FillMemory
+
+Func_27d98: ; 27d98 (9:7d98)
+ call Load16BitRegisters
+ push hl
+ ld a, [W_PLAYERMOVETYPE] ; $cfd5
+asm_27d9f: ; 27d9f (9:7d9f)
+ add a
+ ld hl, TypeNamePointers ; $7dae
+ ld e, a
+ ld d, $0
+ add hl, de
+ ld a, [hli]
+ ld e, a
+ ld d, [hl]
+ pop hl
+ jp PlaceString
+
+INCLUDE "text/type_names.asm"
+
+SaveTrainerName: ; 27e4a (9:7e4a)
+ ld hl,TrainerNamePointers
+ ld a,[W_TRAINERCLASS]
+ dec a
+ ld c,a
+ ld b,0
+ add hl,bc
+ add hl,bc
+ ld a,[hli]
+ ld h,[hl]
+ ld l,a
+ ld de,$CD6D
+.CopyCharacter
+ ld a,[hli]
+ ld [de],a
+ inc de
+ cp "@"
+ jr nz,.CopyCharacter
+ ret
+
+TrainerNamePointers: ; 27e64 (9:7e64)
+; what is the point of these?
+ dw YoungsterName
+ dw BugCatcherName
+ dw LassName
+ dw W_TRAINERNAME
+ dw JrTrainerMName
+ dw JrTrainerFName
+ dw PokemaniacName
+ dw SuperNerdName
+ dw W_TRAINERNAME
+ dw W_TRAINERNAME
+ dw BurglarName
+ dw EngineerName
+ dw JugglerXName
+ dw W_TRAINERNAME
+ dw SwimmerName
+ dw W_TRAINERNAME
+ dw W_TRAINERNAME
+ dw BeautyName
+ dw W_TRAINERNAME
+ dw RockerName
+ dw JugglerName
+ dw W_TRAINERNAME
+ dw W_TRAINERNAME
+ dw BlackbeltName
+ dw W_TRAINERNAME
+ dw ProfOakName
+ dw ChiefName
+ dw ScientistName
+ dw W_TRAINERNAME
+ dw RocketName
+ dw CooltrainerMName
+ dw CooltrainerFName
+ dw W_TRAINERNAME
+ dw W_TRAINERNAME
+ dw W_TRAINERNAME
+ dw W_TRAINERNAME
+ dw W_TRAINERNAME
+ dw W_TRAINERNAME
+ dw W_TRAINERNAME
+ dw W_TRAINERNAME
+ dw W_TRAINERNAME
+ dw W_TRAINERNAME
+ dw W_TRAINERNAME
+ dw W_TRAINERNAME
+ dw W_TRAINERNAME
+ dw W_TRAINERNAME
+ dw W_TRAINERNAME
+
+YoungsterName: ; 27ec2 (9:7ec2)
+ db "YOUNGSTER@"
+BugCatcherName: ; 27ecc (9:7ecc)
+ db "BUG CATCHER@"
+LassName: ; 27ed8 (9:7ed8)
+ db "LASS@"
+JrTrainerMName: ; 27edd (9:7edd)
+ db "JR.TRAINER♂@"
+JrTrainerFName: ; 27ee9 (9:7ee9)
+ db "JR.TRAINER♀@"
+PokemaniacName: ; 27ef5 (9:7ef5)
+ db "POKéMANIAC@"
+SuperNerdName: ; 27f00 (9:7f00)
+ db "SUPER NERD@"
+BurglarName: ; 27f0b (9:7f0b)
+ db "BURGLAR@"
+EngineerName: ; 27f13 (9:7f13)
+ db "ENGINEER@"
+JugglerXName: ; 27f1c (9:7f1c)
+ db "JUGGLER@"
+SwimmerName: ; 27f24 (9:7f24)
+ db "SWIMMER@"
+BeautyName: ; 27f2c (9:7f2c)
+ db "BEAUTY@"
+RockerName: ; 27f33 (9:7f33)
+ db "ROCKER@"
+JugglerName: ; 27f3a (9:7f3a)
+ db "JUGGLER@"
+BlackbeltName: ; 27f42 (9:7f42)
+ db "BLACKBELT@"
+ProfOakName: ; 27f4c (9:7f4c)
+ db "PROF.OAK@"
+ChiefName: ; 27f55 (9:7f55)
+ db "CHIEF@"
+ScientistName: ; 27f5b (9:7f5b)
+ db "SCIENTIST@"
+RocketName: ; 27f65 (9:7f65)
+ db "ROCKET@"
+CooltrainerMName: ; 27f6c (9:7f6c)
+ db "COOLTRAINER♂@"
+CooltrainerFName: ; 27f79 (9:7f79)
+ db "COOLTRAINER♀@"
+
+FocusEnergyEffect_: ; 27f86 (9:7f86)
+ ld hl, W_PLAYERBATTSTATUS2 ; $d063
+ ld a, [H_WHOSETURN] ; $fff3
+ and a
+ jr z, .asm_27f91
+ ld hl, W_ENEMYBATTSTATUS2 ; $d068
+.asm_27f91
+ bit 2, [hl] ; is mon already using focus energy?
+ jr nz, .asm_27fa5
+ set 2, [hl] ; mon is now using focus energy
+ callab Func_3fba8
+ ld hl, GettingPumpedText ; $7fb2
+ jp PrintText
+.asm_27fa5
+ ld c, $32
+ call DelayFrames
+ ld hl, PrintButItFailedText_
+ ld b, BANK(PrintButItFailedText_)
+ jp Bankswitch
+
+GettingPumpedText: ; 27fb3 (9:7fb3)
+ db $0a
+ TX_FAR _GettingPumpedText
+ db "@"
diff --git a/engine/battle/a.asm b/engine/battle/a.asm
new file mode 100755
index 00000000..2e409b57
--- /dev/null
+++ b/engine/battle/a.asm
@@ -0,0 +1,39 @@
+LeechSeedEffect_: ; 2bea9 (a:7ea9)
+ callab MoveHitTest
+ ld a, [W_MOVEMISSED] ; $d05f
+ and a
+ jr nz, .asm_2bee7
+ ld hl, W_ENEMYBATTSTATUS2 ; $d068
+ ld de, W_ENEMYMONTYPE1 ; $cfea (aliases: W_ENEMYMONTYPES)
+ ld a, [H_WHOSETURN] ; $fff3
+ and a
+ jr z, .asm_2bec8
+ ld hl, W_PLAYERBATTSTATUS2 ; $d063
+ ld de, W_PLAYERMONTYPE1 ; $d019 (aliases: W_PLAYERMONTYPES)
+.asm_2bec8
+ ld a, [de]
+ cp GRASS
+ jr z, .asm_2bee7
+ inc de
+ ld a, [de]
+ cp GRASS
+ jr z, .asm_2bee7
+ bit 7, [hl]
+ jr nz, .asm_2bee7
+ set 7, [hl]
+ callab Func_3fba8
+ ld hl, WasSeededText ; $7ef2
+ jp PrintText
+.asm_2bee7
+ ld c, $32
+ call DelayFrames
+ ld hl, EvadedAttackText ; $7ef7
+ jp PrintText
+
+WasSeededText: ; 2bef2 (a:7ef2)
+ TX_FAR _WasSeededText
+ db "@"
+
+EvadedAttackText: ; 2bef7 (a:7ef7)
+ TX_FAR _EvadedAttackText
+ db "@"
diff --git a/engine/battle/animations.asm b/engine/battle/animations.asm
new file mode 100755
index 00000000..aaa65bbb
--- /dev/null
+++ b/engine/battle/animations.asm
@@ -0,0 +1,2908 @@
+; Draws a "frame block". Frame blocks are blocks of tiles that are put
+; together to form frames in battle animations.
+DrawFrameBlock: ; 78000 (1e:4000)
+ ld l,c
+ ld h,b
+ ld a,[hli]
+ ld [W_NUMFBTILES],a
+ ld a,[W_FBDESTADDR + 1]
+ ld e,a
+ ld a,[W_FBDESTADDR]
+ ld d,a
+ xor a
+ ld [W_FBTILECOUNTER],a ; loop counter
+.loop
+ ld a,[W_FBTILECOUNTER]
+ inc a
+ ld [W_FBTILECOUNTER],a
+ ld a,[W_SUBANIMTRANSFORM]
+ dec a
+ jr z,.flipHorizontalAndVertical ; 1
+ dec a
+ jp z,.flipHorizontalTranslateDown ; 2
+ dec a
+ jr z,.flipBaseCoords ; 3
+.noTransformation
+ ld a,[W_BASECOORDY]
+ add [hl]
+ ld [de],a ; store Y
+ inc hl
+ inc de
+ ld a,[W_BASECOORDX]
+ jr .finishCopying
+.flipBaseCoords
+ ld a,[W_BASECOORDY]
+ ld b,a
+ ld a,136
+ sub b ; flip Y base coordinate
+ add [hl] ; Y offset
+ ld [de],a ; store Y
+ inc hl
+ inc de
+ ld a,[W_BASECOORDX]
+ ld b,a
+ ld a,168
+ sub b ; flip X base coordinate
+.finishCopying ; finish copying values to OAM (when [W_SUBANIMTRANSFORM] not 1 or 2)
+ add [hl] ; X offset
+ ld [de],a ; store X
+ inc hl
+ inc de
+ ld a,[hli]
+ add a,$31 ; base tile ID for battle animations
+ ld [de],a ; store tile ID
+ inc de
+ ld a,[hli]
+ ld [de],a ; store flags
+ inc de
+ jp .nextTile
+.flipHorizontalAndVertical
+ ld a,[W_BASECOORDY]
+ add [hl] ; Y offset
+ ld b,a
+ ld a,136
+ sub b ; flip Y coordinate
+ ld [de],a ; store Y
+ inc hl
+ inc de
+ ld a,[W_BASECOORDX]
+ add [hl] ; X offset
+ ld b,a
+ ld a,168
+ sub b ; flip X coordinate
+ ld [de],a ; store X
+ inc hl
+ inc de
+ ld a,[hli]
+ add a,$31 ; base tile ID for battle animations
+ ld [de],a ; store tile ID
+ inc de
+; toggle horizontal and vertical flip
+ ld a,[hli] ; flags
+ and a
+ ld b,OAM_VFLIP | OAM_HFLIP
+ jr z,.storeFlags1
+ cp a,OAM_HFLIP
+ ld b,OAM_VFLIP
+ jr z,.storeFlags1
+ cp a,OAM_VFLIP
+ ld b,OAM_HFLIP
+ jr z,.storeFlags1
+ ld b,0
+.storeFlags1
+ ld a,b
+ ld [de],a
+ inc de
+ jp .nextTile
+.flipHorizontalTranslateDown
+ ld a,[W_BASECOORDY]
+ add [hl]
+ add a,40 ; translate Y coordinate downwards
+ ld [de],a ; store Y
+ inc hl
+ inc de
+ ld a,[W_BASECOORDX]
+ add [hl]
+ ld b,a
+ ld a,168
+ sub b ; flip X coordinate
+ ld [de],a ; store X
+ inc hl
+ inc de
+ ld a,[hli]
+ add a,$31 ; base tile ID for battle animations
+ ld [de],a ; store tile ID
+ inc de
+ ld a,[hli]
+ bit 5,a ; is horizontal flip enabled?
+ jr nz,.disableHorizontalFlip
+.enableHorizontalFlip
+ set 5,a
+ jr .storeFlags2
+.disableHorizontalFlip
+ res 5,a
+.storeFlags2
+ ld [de],a
+ inc de
+.nextTile
+ ld a,[W_FBTILECOUNTER]
+ ld c,a
+ ld a,[W_NUMFBTILES]
+ cp c
+ jp nz,.loop ; go back up if there are more tiles to draw
+.afterDrawingTiles
+ ld a,[W_FBMODE]
+ cp a,2
+ jr z,.advanceFrameBlockDestAddr; skip delay and don't clean OAM buffer
+ ld a,[W_SUBANIMFRAMEDELAY]
+ ld c,a
+ call DelayFrames
+ ld a,[W_FBMODE]
+ cp a,3
+ jr z,.advanceFrameBlockDestAddr ; skip cleaning OAM buffer
+ cp a,4
+ jr z,.done ; skip cleaning OAM buffer and don't advance the frame block destination address
+ ld a,[W_ANIMATIONID]
+ cp a,GROWL
+ jr z,.resetFrameBlockDestAddr
+ call AnimationCleanOAM
+.resetFrameBlockDestAddr
+ ld hl,wOAMBuffer ; OAM buffer
+ ld a,l
+ ld [W_FBDESTADDR + 1],a
+ ld a,h
+ ld [W_FBDESTADDR],a ; set destination address to beginning of OAM buffer
+ ret
+.advanceFrameBlockDestAddr
+ ld a,e
+ ld [W_FBDESTADDR + 1],a
+ ld a,d
+ ld [W_FBDESTADDR],a
+.done
+ ret
+
+PlayAnimation: ; 780f1 (1e:40f1)
+ xor a
+ ld [$FF8B],a
+ ld [W_SUBANIMTRANSFORM],a
+ ld a,[W_ANIMATIONID] ; get animation number
+ dec a
+ ld l,a
+ ld h,0
+ add hl,hl
+ ld de,AttackAnimationPointers ; $607d ; animation command stream pointers
+ add hl,de
+ ld a,[hli]
+ ld h,[hl]
+ ld l,a
+.animationLoop
+ ld a,[hli]
+ cp a,$FF
+ jr z,.AnimationOver
+ cp a,$C0 ; is this subanimation or a special effect?
+ jr c,.playSubanimation
+.doSpecialEffect
+ ld c,a
+ ld de,SpecialEffectPointers
+.searchSpecialEffectTableLoop
+ ld a,[de]
+ cp c
+ jr z,.foundMatch
+ inc de
+ inc de
+ inc de
+ jr .searchSpecialEffectTableLoop
+.foundMatch
+ ld a,[hli]
+ cp a,$FF ; is there a sound to play?
+ jr z,.skipPlayingSound
+ ld [wAnimSoundID],a ; store sound
+ push hl
+ push de
+ call Func_7986f
+ call PlaySound
+ pop de
+ pop hl
+.skipPlayingSound
+ push hl
+ inc de
+ ld a,[de]
+ ld l,a
+ inc de
+ ld a,[de]
+ ld h,a
+ ld de,.nextAnimationCommand
+ push de
+ jp [hl] ; jump to special effect function
+.playSubanimation
+ ld c,a
+ and a,%00111111
+ ld [W_SUBANIMFRAMEDELAY],a
+ xor a
+ sla c
+ rla
+ sla c
+ rla
+ ld [$D09F],a ; tile select
+ ld a,[hli] ; sound
+ ld [wAnimSoundID],a ; store sound
+ ld a,[hli] ; subanimation ID
+ ld c,l
+ ld b,h
+ ld l,a
+ ld h,0
+ add hl,hl
+ ld de,SubanimationPointers
+ add hl,de
+ ld a,l
+ ld [W_SUBANIMADDRPTR],a
+ ld a,h
+ ld [W_SUBANIMADDRPTR + 1],a
+ ld l,c
+ ld h,b
+ push hl
+ ld a,[rOBP0]
+ push af
+ ld a,[$CC79]
+ ld [rOBP0],a
+ call LoadAnimationTileset
+ call LoadSubanimation
+ call PlaySubanimation
+ pop af
+ ld [rOBP0],a
+.nextAnimationCommand
+ pop hl
+ jr .animationLoop
+.AnimationOver ; 417B
+ ret
+
+LoadSubanimation: ; 7817c (1e:417c)
+ ld a,[W_SUBANIMADDRPTR + 1]
+ ld h,a
+ ld a,[W_SUBANIMADDRPTR]
+ ld l,a
+ ld a,[hli]
+ ld e,a
+ ld a,[hl]
+ ld d,a ; de = address of subanimation
+ ld a,[de]
+ ld b,a
+ and a,31
+ ld [W_SUBANIMCOUNTER],a ; number of frame blocks
+ ld a,b
+ and a,%11100000
+ cp a,5 << 5 ; is subanimation type 5?
+ jr nz,.isNotType5
+.isType5
+ call GetSubanimationTransform2
+ jr .saveTransformation
+.isNotType5
+ call GetSubanimationTransform1
+.saveTransformation
+; place the upper 3 bits of a into bits 0-2 of a before storing
+ srl a
+ swap a
+ ld [W_SUBANIMTRANSFORM],a
+ cp a,4 ; is the animation reversed?
+ ld hl,0
+ jr nz,.storeSubentryAddr
+; if the animation is reversed, then place the initial subentry address at the end of the list of subentries
+ ld a,[W_SUBANIMCOUNTER]
+ dec a
+ ld bc,3
+.loop
+ add hl,bc
+ dec a
+ jr nz,.loop
+.storeSubentryAddr
+ inc de
+ add hl,de
+ ld a,l
+ ld [W_SUBANIMSUBENTRYADDR],a
+ ld a,h
+ ld [W_SUBANIMSUBENTRYADDR + 1],a
+ ret
+
+; called if the subanimation type is not 5
+; sets the transform to 0 (i.e. no transform) if it's the player's turn
+; sets the transform to the subanimation type if it's the enemy's turn
+GetSubanimationTransform1: ; 781c2 (1e:41c2)
+ ld b,a
+ ld a,[H_WHOSETURN]
+ and a
+ ld a,b
+ ret nz
+ xor a
+ ret
+
+; called if the subanimation type is 5
+; sets the transform to 2 (i.e. horizontal and vertical flip) if it's the player's turn
+; sets the transform to 0 (i.e. no transform) if it's the enemy's turn
+GetSubanimationTransform2: ; 781ca (1e:41ca)
+ ld a,[H_WHOSETURN]
+ and a
+ ld a,2 << 5
+ ret z
+ xor a
+ ret
+
+; loads tile patterns for battle animations
+LoadAnimationTileset: ; 781d2 (1e:41d2)
+ ld a,[$D09F] ; tileset select
+ add a
+ add a
+ ld hl,AnimationTilesetPointers
+ ld e,a
+ ld d,0
+ add hl,de
+ ld a,[hli]
+ ld [$D07D],a ; number of tiles
+ ld a,[hli]
+ ld e,a
+ ld a,[hl]
+ ld d,a ; de = address of tileset
+ ld hl,$8310 ; destination address in VRAM
+ ld b, BANK(AnimationTileset1) ; ROM bank
+ ld a,[$D07D]
+ ld c,a ; number of tiles
+ jp CopyVideoData ; load tileset
+
+AnimationTilesetPointers: ; 781f2 (1e:41f2)
+ db 79 ; number of tiles
+ dw AnimationTileset1
+ db $FF
+
+ db 79 ; number of tiles
+ dw AnimationTileset2
+ db $FF
+
+ db 64 ; number of tiles
+ dw AnimationTileset1
+ db $FF
+
+AnimationTileset1: ; 781fe (1e:41fe)
+ INCBIN "gfx/attack_anim_1.2bpp"
+
+AnimationTileset2: ; 786ee (1e:46ee)
+ INCBIN "gfx/attack_anim_2.2bpp"
+
+SlotMachineTiles2: ; 78bde (1e:4bde)
+IF _RED
+ INCBIN "gfx/red/slotmachine2.2bpp"
+ENDC
+IF _BLUE
+ INCBIN "gfx/blue/slotmachine2.2bpp"
+ENDC
+
+MoveAnimation: ; 78d5e (1e:4d5e)
+ push hl
+ push de
+ push bc
+ push af
+ call WaitForSoundToFinish
+ call Func_78e23
+ ld a,[W_ANIMATIONID]
+ and a
+ jr z,.AnimationFinished
+
+ ; if throwing a Poké Ball, skip the regular animation code
+ cp a,TOSS_ANIM
+ jr nz,.MoveAnimation
+ ld de,.AnimationFinished
+ push de
+ jp TossBallAnimation
+
+.MoveAnimation
+ ; check if battle animations are disabled in the options
+ ld a,[$D355]
+ bit 7,a
+ jr nz,.AnimationsDisabled
+ call ShareMoveAnimations
+ call PlayAnimation
+ jr .next4
+.AnimationsDisabled
+ ld c,30
+ call DelayFrames
+.next4
+ call Func_78dbd ; reload pic and flash the pic in and out (to show damage)
+.AnimationFinished
+ call WaitForSoundToFinish
+ xor a
+ ld [$D096],a
+ ld [$D09B],a
+ ld [$D08B],a
+ dec a
+ ld [$CF07],a
+ pop af
+ pop bc
+ pop de
+ pop hl
+ ret
+
+ShareMoveAnimations: ; 78da6 (1e:4da6)
+; some moves just reuse animations from status conditions
+ ld a,[H_WHOSETURN]
+ and a
+ ret z
+
+ ; opponent’s turn
+
+ ld a,[W_ANIMATIONID]
+
+ cp a,AMNESIA
+ ld b,CONF_ANIM
+ jr z,.Replace
+
+ cp a,REST
+ ld b,SLP_ANIM
+ ret nz
+
+.Replace
+ ld a,b
+ ld [W_ANIMATIONID],a
+ ret
+
+Func_78dbd: ; 78dbd (1e:4dbd)
+ ld a,[$CC5B]
+ and a
+ ret z
+ dec a
+ add a
+ ld c,a
+ ld b,0
+ ld hl,PointerTable_78dcf
+ add hl,bc
+ ld a,[hli]
+ ld h,[hl]
+ ld l,a
+ jp [hl]
+
+PointerTable_78dcf: ; 78dcf (1e:4dcf)
+ dw Func_78ddb
+ dw Func_78de3
+ dw Func_78deb
+ dw Func_78df0
+ dw Func_78df6
+ dw Func_78dfe
+
+Func_78ddb: ; 78ddb (1e:4ddb)
+ call Func_79e6a
+ ld b, $8
+ jp Func_79209
+
+Func_78de3: ; 78de3 (1e:4de3)
+ call Func_79e6a
+ ld b, $8
+ jp Func_79210
+
+Func_78deb: ; 78deb (1e:4deb)
+ ld bc, $602
+ jr Func_78e01
+
+Func_78df0: ; 78df0 (1e:4df0)
+ call Func_79e6a
+ jp AnimationBlinkEnemyMon
+
+Func_78df6: ; 78df6 (1e:4df6)
+ call Func_79e6a
+ ld b, $2
+ jp Func_79210
+
+Func_78dfe: ; 78dfe (1e:4dfe)
+ ld bc, $302
+
+Func_78e01: ; 78e01 (1e:4e01)
+ push bc
+ push bc
+.asm_78e03
+ ld a, [rWX] ; $ff4b
+ inc a
+ ld [rWX], a ; $ff4b
+ ld c, $2
+ call DelayFrames
+ dec b
+ jr nz, .asm_78e03
+ pop bc
+.asm_78e11
+ ld a, [rWX] ; $ff4b
+ dec a
+ ld [rWX], a ; $ff4b
+ ld c, $2
+ call DelayFrames
+ dec b
+ jr nz, .asm_78e11
+ pop bc
+ dec c
+ jr nz, Func_78e01
+ ret
+
+Func_78e23: ; 78e23 (1e:4e23)
+ ld a, [$cf1b]
+ and a
+ ld a, $e4
+ jr z, .asm_78e47
+ ld a, $f0
+ ld [$cc79], a
+ ld b, $e4
+ ld a, [W_ANIMATIONID] ; $d07c
+ cp $aa
+ jr c, .asm_78e3f
+ cp $ae
+ jr nc, .asm_78e3f
+ ld b, $f0
+.asm_78e3f
+ ld a, b
+ ld [rOBP0], a ; $ff48
+ ld a, $6c
+ ld [rOBP1], a ; $ff49
+ ret
+.asm_78e47
+ ld a, $e4
+ ld [$cc79], a
+ ld [rOBP0], a ; $ff48
+ ld a, $6c
+ ld [rOBP1], a ; $ff49
+ ret
+
+PlaySubanimation: ; 78e53 (1e:4e53)
+ ld a,[wAnimSoundID]
+ cp a,$FF
+ jr z,.skipPlayingSound
+ call Func_7986f
+ call PlaySound ; play sound effect
+.skipPlayingSound
+ ld hl,wOAMBuffer ; base address of OAM buffer
+ ld a,l
+ ld [W_FBDESTADDR + 1],a
+ ld a,h
+ ld [W_FBDESTADDR],a
+ ld a,[W_SUBANIMSUBENTRYADDR + 1]
+ ld h,a
+ ld a,[W_SUBANIMSUBENTRYADDR]
+ ld l,a
+.loop
+ push hl
+ ld c,[hl] ; frame block ID
+ ld b,0
+ ld hl,FrameBlockPointers
+ add hl,bc
+ add hl,bc
+ ld a,[hli]
+ ld c,a
+ ld a,[hli]
+ ld b,a
+ pop hl
+ inc hl
+ push hl
+ ld e,[hl] ; base coordinate ID
+ ld d,0
+ ld hl,FrameBlockBaseCoords ; $7c85 ; base coordinate table
+ add hl,de
+ add hl,de
+ ld a,[hli]
+ ld [W_BASECOORDY],a
+ ld a,[hl]
+ ld [W_BASECOORDX],a
+ pop hl
+ inc hl
+ ld a,[hl] ; frame block mode
+ ld [W_FBMODE],a
+ call DrawFrameBlock
+ call DoSpecialEffectByAnimationId ; run animation-specific function (if there is one)
+ ld a,[W_SUBANIMCOUNTER]
+ dec a
+ ld [W_SUBANIMCOUNTER],a
+ ret z
+ ld a,[W_SUBANIMSUBENTRYADDR + 1]
+ ld h,a
+ ld a,[W_SUBANIMSUBENTRYADDR]
+ ld l,a
+ ld a,[W_SUBANIMTRANSFORM]
+ cp a,4 ; is the animation reversed?
+ ld bc,3
+ jr nz,.nextSubanimationSubentry
+ ld bc,-3
+.nextSubanimationSubentry
+ add hl,bc
+ ld a,h
+ ld [W_SUBANIMSUBENTRYADDR + 1],a
+ ld a,l
+ ld [W_SUBANIMSUBENTRYADDR],a
+ jp .loop
+
+AnimationCleanOAM: ; 78ec8 (1e:4ec8)
+ push hl
+ push de
+ push bc
+ push af
+ call DelayFrame
+ call CleanLCD_OAM
+ pop af
+ pop bc
+ pop de
+ pop hl
+ ret
+
+; this runs after each frame block is drawn in a subanimation
+; it runs a particular special effect based on the animation ID
+DoSpecialEffectByAnimationId: ; 78ed7 (1e:4ed7)
+ push hl
+ push de
+ push bc
+ ld a,[W_ANIMATIONID]
+ ld hl,AnimationIdSpecialEffects
+ ld de,3
+ call IsInArray
+ jr nc,.done
+ inc hl
+ ld a,[hli]
+ ld h,[hl]
+ ld l,a
+ ld de,.done
+ push de
+ jp [hl]
+.done
+ pop bc
+ pop de
+ pop hl
+ ret
+
+; Format: Animation ID (1 byte), Address (2 bytes)
+AnimationIdSpecialEffects: ; 78ef5 (1e:4ef5)
+ db MEGA_PUNCH
+ dw AnimationFlashScreen
+
+ db GUILLOTINE
+ dw AnimationFlashScreen
+
+ db MEGA_KICK
+ dw AnimationFlashScreen
+
+ db HEADBUTT
+ dw AnimationFlashScreen
+
+ db TAIL_WHIP
+ dw Func_790d0
+
+ db GROWL
+ dw DoGrowlSpecialEffects
+
+ db DISABLE
+ dw AnimationFlashScreen
+
+ db BLIZZARD
+ dw DoBlizzardSpecialEffects
+
+ db BUBBLEBEAM
+ dw AnimationFlashScreen
+
+ db HYPER_BEAM
+ dw FlashScreenEveryFourFrameBlocks
+
+ db THUNDERBOLT
+ dw FlashScreenEveryEightFrameBlocks
+
+ db REFLECT
+ dw AnimationFlashScreen
+
+ db SELFDESTRUCT
+ dw DoExplodeSpecialEffects
+
+ db SPORE
+ dw AnimationFlashScreen
+
+ db EXPLOSION
+ dw DoExplodeSpecialEffects
+
+ db ROCK_SLIDE
+ dw DoRockSlideSpecialEffects
+
+ db $AA
+ dw Func_79041
+
+ db $AB
+ dw Func_7904c
+
+ db $AC
+ dw Func_7907c
+
+ db TOSS_ANIM
+ dw DoBallTossSpecialEffects
+
+ db SHAKE_ANIM
+ dw DoBallShakeSpecialEffects
+
+ db POOF_ANIM
+ dw DoPoofSpecialEffects
+
+ db GREATTOSS_ANIM
+ dw DoBallTossSpecialEffects
+
+ db ULTRATOSS_ANIM
+ dw DoBallTossSpecialEffects
+
+ db $FF ; terminator
+
+DoBallTossSpecialEffects: ; 78f3e (1e:4f3e)
+ ld a,[$CF91]
+ cp a,3 ; is it a Master Ball or Ultra Ball?
+ jr nc,.skipFlashingEffect
+.flashingEffect ; do a flashing effect if it's Master Ball or Ultra Ball
+ ld a,[rOBP0]
+ xor a,%00111100 ; complement colors 1 and 2
+ ld [rOBP0],a
+.skipFlashingEffect
+ ld a,[W_SUBANIMCOUNTER]
+ cp a,11 ; is it the beginning of the subanimation?
+ jr nz,.skipPlayingSound
+; if it is the beginning of the subanimation, play a sound
+ ld a,(SFX_08_41 - SFX_Headers_08) / 3
+ call PlaySound ; play sound
+.skipPlayingSound
+ ld a,[W_ISINBATTLE]
+ cp a,02 ; is it a trainer battle?
+ jr z,.isTrainerBattle
+ ld a,[$d11e]
+ cp a,$10 ; is the enemy pokemon the Ghost Marowak?
+ ret nz
+; if the enemy pokemon is the Ghost Marowak, make it dodge during the last 3 frames
+ ld a,[W_SUBANIMCOUNTER]
+ cp a,3
+ jr z,.moveGhostMarowakLeft
+ cp a,2
+ jr z,.moveGhostMarowakLeft
+ cp a,1
+ ret nz
+.moveGhostMarowakLeft
+ FuncCoord 17,0
+ ld hl,Coord
+ ld de,20
+ ld bc,$0707 ; 7 rows and 7 columns
+.loop
+ push hl
+ push bc
+ call Func_79862 ; move row of tiles left
+ pop bc
+ pop hl
+ add hl,de
+ dec b
+ jr nz,.loop
+ ld a,%00001000
+ ld [$ff10],a ; Channel 1 sweep register
+ ret
+.isTrainerBattle ; if it's a trainer battle, shorten the animation by one frame
+ ld a,[W_SUBANIMCOUNTER]
+ cp a,3
+ ret nz
+ dec a
+ ld [W_SUBANIMCOUNTER],a
+ ret
+
+DoBallShakeSpecialEffects: ; 78f96 (1e:4f96)
+ ld a,[W_SUBANIMCOUNTER]
+ cp a,4 ; is it the beginning of a shake?
+ jr nz,.skipPlayingSound
+; if it is the beginning of a shake, play a sound and wait 2/3 of a second
+ ld a,(SFX_08_3c - SFX_Headers_08) / 3
+ call PlaySound ; play sound
+ ld c,40
+ call DelayFrames
+.skipPlayingSound
+ ld a,[W_SUBANIMCOUNTER]
+ dec a
+ ret nz
+; if it's the end of the ball shaking subanimation, check if more shakes are left and restart the subanimation
+ ld a,[$cd3d] ; number of shakes
+ dec a ; decrement number of shakes
+ ld [$cd3d],a
+ ret z
+; if there are shakes left, restart the subanimation
+ ld a,[W_SUBANIMSUBENTRYADDR]
+ ld l,a
+ ld a,[W_SUBANIMSUBENTRYADDR + 1]
+ ld h,a
+ ld de,-(4 * 3) ; 4 subentries and 3 bytes per subentry
+ add hl,de
+ ld a,l
+ ld [W_SUBANIMSUBENTRYADDR],a
+ ld a,h
+ ld [W_SUBANIMSUBENTRYADDR + 1],a
+ ld a,5 ; number of subentries in the ball shaking subanimation plus one
+ ld [W_SUBANIMCOUNTER],a
+ ret
+
+; plays a sound after the second frame of the poof animation
+DoPoofSpecialEffects: ; 78fce (1e:4fce)
+ ld a,[W_SUBANIMCOUNTER]
+ cp a,5
+ ret nz
+ ld a,(SFX_08_42 - SFX_Headers_08) / 3
+ jp PlaySound
+
+DoRockSlideSpecialEffects: ; 78fd9 (1e:4fd9)
+ ld a,[W_SUBANIMCOUNTER]
+ cp a,12
+ ret nc
+ cp a,8
+ jr nc,.shakeScreen
+ cp a,1
+ jp z,AnimationFlashScreen ; if it's the end of the subanimation, flash the screen
+ ret
+; if the subaninmation counter is between 8 and 11, shake the screen horizontally and vertically
+.shakeScreen
+ ld b,1
+ ld a,$24
+ call Predef ; shake horizontally
+ ld b,1
+ ld a,$21
+ jp Predef ; shake vertically
+
+FlashScreenEveryEightFrameBlocks: ; 78ff7 (1e:4ff7)
+ ld a,[W_SUBANIMCOUNTER]
+ and a,7 ; is the subanimation counter exactly 8?
+ call z,AnimationFlashScreen ; if so, flash the screen
+ ret
+
+; flashes the screen if the subanimation counter is divisible by 4
+FlashScreenEveryFourFrameBlocks: ; 79000 (1e:5000)
+ ld a,[W_SUBANIMCOUNTER]
+ and a,3
+ call z,AnimationFlashScreen
+ ret
+
+; used for Explosion and Selfdestruct
+DoExplodeSpecialEffects: ; 79009 (1e:5009)
+ ld a,[W_SUBANIMCOUNTER]
+ cp a,1 ; is it the end of the subanimation?
+ jr nz,FlashScreenEveryFourFrameBlocks
+; if it's the end of the subanimation, make the attacking pokemon disappear
+ FuncCoord 1, 5 ; $c405
+ ld hl,Coord
+ jp AnimationHideMonPic ; make pokemon disappear
+
+; flashes the screen when subanimation counter is 1 modulo 4
+DoBlizzardSpecialEffects: ; 79016 (1e:5016)
+ ld a,[W_SUBANIMCOUNTER]
+ cp a,13
+ jp z,AnimationFlashScreen
+ cp a,9
+ jp z,AnimationFlashScreen
+ cp a,5
+ jp z,AnimationFlashScreen
+ cp a,1
+ jp z,AnimationFlashScreen
+ ret
+
+; flashes the screen at 3 points in the subanimation
+; XXX is this unused?
+Func_7902e: ; 7902e (1e:502e)
+ ld a,[W_SUBANIMCOUNTER]
+ cp a,14
+ jp z,AnimationFlashScreen
+ cp a,9
+ jp z,AnimationFlashScreen
+ cp a,2
+ jp z,AnimationFlashScreen
+ ret
+
+; function to make the pokemon disappear at the beginning of the animation
+; XXX probably a trade-related animation
+Func_79041: ; 79041 (1e:5041)
+ ld a,[W_SUBANIMCOUNTER]
+ cp a,6
+ ret nz
+ ld a,$2F
+ jp Func_7980c ; make pokemon disappear
+
+; function to make a shaking pokeball jump up at the end of the animation
+; XXX probably a trade-related animation
+Func_7904c: ; 7904c (1e:504c)
+ ld a,[W_SUBANIMCOUNTER]
+ cp a,1
+ ret nz
+; if it's the end of the animation, make the ball jump up
+ ld de,BallMoveDistances1
+.loop
+ ld hl,wOAMBuffer ; OAM buffer
+ ld bc,4
+.innerLoop
+ ld a,[de]
+ cp a,$ff
+ jr z,.done
+ add [hl] ; add to Y value of OAM entry
+ ld [hl],a
+ add hl,bc
+ ld a,l
+ cp a,4 * 4 ; there are 4 entries, each 4 bytes
+ jr nz,.innerLoop
+ inc de
+ push bc
+ call Delay3
+ pop bc
+ jr .loop
+.done
+ call AnimationCleanOAM
+ ld a,(SFX_02_44 - SFX_Headers_02) / 3
+ jp PlaySound ; play sound
+
+BallMoveDistances1: ; 79078 (1e:5078)
+ db -12,-12,-8
+ db $ff ; terminator
+
+; function to make the pokeball jump up
+; XXX probably a trade-related animation
+Func_7907c ; 507C
+ ld de,BallMoveDistances2
+.loop
+ ld hl,wOAMBuffer ; OAM buffer
+ ld bc,4
+.innerLoop
+ ld a,[de]
+ cp a,$ff
+ jp z,ClearScreen
+ add [hl]
+ ld [hl],a
+ add hl,bc
+ ld a,l
+ cp a,4 * 4 ; there are 4 entries, each 4 bytes
+ jr nz,.innerLoop
+ inc de
+ push de
+ ld a,[de]
+ cp a,12
+ jr z,.playSound
+ cp a,$ff
+ jr nz,.skipPlayingSound
+.playSound ; play sound if next move distance is 12 or this is the last one
+ ld a,(SFX_08_58 - SFX_Headers_08) / 3
+ call PlaySound
+.skipPlayingSound
+ push bc
+ ld c,5
+ call DelayFrames
+ pop bc
+ ld a,[$ffae] ; background scroll X
+ sub a,8 ; scroll to the left
+ ld [$ffae],a
+ pop de
+ jr .loop
+
+BallMoveDistances2: ; 790b3 (1e:50b3)
+ db 11,12,-12,-7,7,12,-8,8
+ db $ff ; terminator
+
+; this function copies the current musical note graphic
+; so that there are two musical notes flying towards the defending pokemon
+DoGrowlSpecialEffects: ; 790bc (1e:50bc)
+ ld hl,wOAMBuffer ; OAM buffer
+ ld de,$c310
+ ld bc,$10
+ call CopyData ; copy the musical note graphic
+ ld a,[W_SUBANIMCOUNTER]
+ dec a
+ call z,AnimationCleanOAM ; clean up at the end of the subanimation
+ ret
+
+; this is associated with Tail Whip, but Tail Whip doesn't use any subanimations
+Func_790d0: ; 790d0 (1e:50d0)
+ ld a,1
+ ld [W_SUBANIMCOUNTER],a
+ ld c,20
+ jp DelayFrames
+
+; Format: Special Effect ID (1 byte), Address (2 bytes)
+SpecialEffectPointers: ; 790da (1e:50da)
+ db SE_DARK_SCREEN_FLASH ; $FE
+ dw AnimationFlashScreen
+ db SE_DARK_SCREEN_PALETTE ; $FD
+ dw AnimationDarkScreenPalette
+ db SE_RESET_SCREEN_PALETTE ; $FC
+ dw AnimationResetScreenPalette
+ db SE_SHAKE_SCREEN ; $FB
+ dw AnimationShakeScreen
+ db SE_WATER_DROPLETS_EVERYWHERE ; $FA
+ dw AnimationWaterDropletsEverywhere
+ db SE_DARKEN_MON_PALETTE ; $F9
+ dw AnimationDarkenMonPalette
+ db SE_FLASH_SCREEN_LONG ; $F8
+ dw AnimationFlashScreenLong
+ db SE_SLIDE_MON_UP ; $F7
+ dw AnimationSlideMonUp
+ db SE_SLIDE_MON_DOWN ; $F6
+ dw AnimationSlideMonDown
+ db SE_FLASH_MON_PIC ; $F5
+ dw AnimationFlashMonPic
+ db SE_SLIDE_MON_OUT ; $F4
+ dw AnimationSlideMonOut
+ db SE_BLINK_MON ; $F3
+ dw AnimationBlinkMon
+ db SE_MOVE_MON_HORIZONTALLY ; $F2
+ dw AnimationMoveMonHorizontally
+ db SE_RESET_MON_POSITION ; $F1
+ dw AnimationResetMonPosition
+ db SE_LIGHT_SCREEN_PALETTE ; $F0
+ dw AnimationLightScreenPalette
+ db SE_HIDE_MON_PIC ; $EF
+ dw AnimationHideMonPic
+ db SE_SQUISH_MON_PIC ; $EE
+ dw AnimationSquishMonPic
+ db SE_SHOOT_BALLS_UPWARD ; $ED
+ dw AnimationShootBallsUpward
+ db SE_SHOOT_MANY_BALLS_UPWARD ; $EC
+ dw AnimationShootManyBallsUpward
+ db SE_BOUNCE_UP_AND_DOWN ; $EB
+ dw AnimationBoundUpAndDown
+ db SE_MINIMIZE_MON ; $EA
+ dw AnimationMinimizeMon
+ db SE_SLIDE_MON_DOWN_AND_HIDE ; $E9
+ dw AnimationSlideMonDownAndHide
+ db SE_TRANSFORM_MON ; $E8
+ dw AnimationTransformMon
+ db SE_LEAVES_FALLING ; $E7
+ dw AnimationLeavesFalling
+ db SE_PETALS_FALLING ; $E6
+ dw AnimationPetalsFalling
+ db SE_SLIDE_MON_HALF_LEFT ; $E5
+ dw AnimationSlideMonHalfLeft
+ db SE_SHAKE_ENEMY_HUD ; $E4
+ dw AnimationShakeEnemyHUD
+ db SE_SHAKE_ENEMY_HUD_2 ; unused--same pointer as SE_SHAKE_ENEMY_HUD ($E4)
+ dw AnimationShakeEnemyHUD
+ db SE_SPIRAL_BALLS_INWARD ; $E2
+ dw AnimationSpiralBallsInward
+ db SE_DELAY_ANIMATION_10 ; $E1
+ dw AnimationDelay10
+ db SE_FLASH_ENEMY_MON_PIC ; unused--same as SE_FLASH_MON_PIC ($F5), but for the enemy mon
+ dw AnimationFlashEnemyMonPic
+ db SE_HIDE_ENEMY_MON_PIC ; $DF
+ dw AnimationHideEnemyMonPic
+ db SE_BLINK_ENEMY_MON ; $DE
+ dw AnimationBlinkEnemyMon
+ db SE_SHOW_MON_PIC ; $DD
+ dw AnimationShowMonPic
+ db SE_SHOW_ENEMY_MON_PIC ; $DC
+ dw AnimationShowEnemyMonPic
+ db SE_SLIDE_ENEMY_MON_OUT ; $DB
+ dw AnimationSlideEnemyMonOut
+ db SE_SHAKE_BACK_AND_FORTH ; $DA
+ dw AnimationShakeBackAndForth
+ db SE_SUBSTITUTE_MON ; $D9
+ dw AnimationSubstitute
+ db SE_WAVY_SCREEN ; $D8
+ dw AnimationWavyScreen
+ db $FF
+
+AnimationDelay10: ; 79150 (1e:5150)
+ ld c,10
+ jp DelayFrames
+
+; calls a function with the turn flipped from player to enemy or vice versa
+; input - hl - address of function to call
+CallWithTurnFlipped: ; 79155 (1e:5155)
+ ld a,[H_WHOSETURN]
+ push af
+ xor a,1
+ ld [H_WHOSETURN],a
+ ld de,.returnAddress
+ push de
+ jp [hl]
+.returnAddress
+ pop af
+ ld [H_WHOSETURN],a
+ ret
+
+; flashes the screen for an extended period (48 frames)
+AnimationFlashScreenLong: ; 79165 (1e:5165)
+ ld a,3 ; cycle through the palettes 3 times
+ ld [$D08A],a
+ ld a,[$cf1b] ; running on SGB?
+ and a
+ ld hl,FlashScreenLongMonochrome
+ jr z,.loop
+ ld hl,FlashScreenLongSGB
+.loop
+ push hl
+.innerLoop
+ ld a,[hli]
+ cp a,$01 ; is it the end of the palettes?
+ jr z,.endOfPalettes
+ ld [rBGP],a
+ call FlashScreenLongDelay
+ jr .innerLoop
+.endOfPalettes
+ ld a,[$D08A]
+ dec a
+ ld [$D08A],a
+ pop hl
+ jr nz,.loop
+ ret
+
+; BG palettes
+FlashScreenLongMonochrome: ; 7918e (1e:518e)
+ db %11111001 ; 3, 3, 2, 1
+ db %11111110 ; 3, 3, 3, 2
+ db %11111111 ; 3, 3, 3, 3
+ db %11111110 ; 3, 3, 3, 2
+ db %11111001 ; 3, 3, 2, 1
+ db %11100100 ; 3, 2, 1, 0
+ db %10010000 ; 2, 1, 0, 0
+ db %01000000 ; 1, 0, 0, 0
+ db %00000000 ; 0, 0, 0, 0
+ db %01000000 ; 1, 0, 0, 0
+ db %10010000 ; 2, 1, 0, 0
+ db %11100100 ; 3, 2, 1, 0
+ db $01 ; terminator
+
+; BG palettes
+FlashScreenLongSGB: ; 7919b (1e:519b)
+ db %11111000 ; 3, 3, 2, 0
+ db %11111100 ; 3, 3, 3, 0
+ db %11111111 ; 3, 3, 3, 3
+ db %11111100 ; 3, 3, 3, 0
+ db %11111000 ; 3, 3, 2, 0
+ db %11100100 ; 3, 2, 1, 0
+ db %10010000 ; 2, 1, 0, 0
+ db %01000000 ; 1, 0, 0, 0
+ db %00000000 ; 0, 0, 0, 0
+ db %01000000 ; 1, 0, 0, 0
+ db %10010000 ; 2, 1, 0, 0
+ db %11100100 ; 3, 2, 1, 0
+ db $01 ; terminator
+
+; causes a delay of 2 frames for the first cycle
+; causes a delay of 1 frame for the second and third cycles
+FlashScreenLongDelay: ; 791a8 (1e:51a8)
+ ld a,[$D08A]
+ cp a,4 ; never true since [$D08A] starts at 3
+ ld c,4
+ jr z,.delayFrames
+ cp a,3
+ ld c,2
+ jr z,.delayFrames
+ cp a,2 ; nothing is done with this
+ ld c,1
+.delayFrames
+ jp DelayFrames
+
+AnimationFlashScreen: ; 791be (1e:51be)
+ ld a,[rBGP]
+ push af ; save initial palette
+ ld a,%00011011 ; 0, 1, 2, 3 (inverted colors)
+ ld [rBGP],a
+ ld c,2
+ call DelayFrames
+ xor a ; white out background
+ ld [rBGP],a
+ ld c,2
+ call DelayFrames
+ pop af
+ ld [rBGP],a ; restore initial palette
+ ret
+
+AnimationDarkScreenPalette: ; 791d6 (1e:51d6)
+; Changes the screen's palette to a dark palette.
+ ld bc, $6f6f
+ jr Func_791fc
+
+AnimationDarkenMonPalette: ; 791db (1e:51db)
+; Darkens the mon sprite's palette.
+ ld bc, $f9f4
+ jr Func_791fc
+
+Func_791e0: ; 791e0 (1e:51e0)
+ ld bc, $fef8
+ jr Func_791fc
+
+Func_791e5: ; 791e5 (1e:51e5)
+ ld bc, $ffff
+ jr Func_791fc
+
+AnimationResetScreenPalette: ; 791ea (1e:51ea)
+; Restores the screen's palette to the normal palette.
+ ld bc, $e4e4
+ jr Func_791fc
+
+Func_791ef: ; 791ef (1e:51ef)
+ ld bc, $0000
+ jr Func_791fc
+
+AnimationLightScreenPalette: ; 791f4 (1e:51f4)
+; Changes the screen to use a palette with light colors.
+ ld bc, $9090
+ jr Func_791fc
+
+Func_791f9: ; 791f9 (1e:51f9)
+ ld bc, $4040
+
+Func_791fc: ; 791fc (1e:51fc)
+ ld a, [$cf1b]
+ and a
+ ld a, b
+ jr z, .asm_79204
+ ld a, c
+.asm_79204
+ ld [rBGP], a ; $ff47
+ ret
+
+ ld b, $5
+
+Func_79209: ; 79209 (1e:5209)
+ ld a, $21
+ jp Predef ; indirect jump to Func_480ff (480ff (12:40ff))
+
+AnimationShakeScreen: ; 7920e (1e:520e)
+; Shakes the screen for a while. Used in Earthquake/Fissure/etc. animations.
+ ld b, $8
+
+Func_79210: ; 79210 (1e:5210)
+ ld a, $24
+ jp Predef ; indirect jump to Func_48125 (48125 (12:4125))
+
+AnimationWaterDropletsEverywhere: ; 79215 (1e:5215)
+; Draws water droplets all over the screen and makes them
+; scroll. It's hard to describe, but it's the main animation
+; in Surf/Mist/Toxic.
+ xor a
+ ld [$d09f], a
+ call LoadAnimationTileset
+ ld d, $20
+ ld a, $f0
+ ld [W_BASECOORDX], a ; $d081
+ ld a, $71
+ ld [$d09f], a
+.asm_79228
+ ld a, $10
+ ld [W_BASECOORDY], a ; $d082
+ ld a, $0
+ ld [$d08a], a
+ call Func_79246
+ ld a, $18
+ ld [W_BASECOORDY], a ; $d082
+ ld a, $20
+ ld [$d08a], a
+ call Func_79246
+ dec d
+ jr nz, .asm_79228
+ ret
+
+Func_79246: ; 79246 (1e:5246)
+ ld hl, wOAMBuffer
+.asm_79249
+ ld a, [W_BASECOORDY] ; $d082
+ ld [hli], a
+ ld a, [W_BASECOORDX] ; $d081
+ add $1b
+ ld [W_BASECOORDX], a ; $d081
+ ld [hli], a
+ ld a, [$d09f]
+ ld [hli], a
+ xor a
+ ld [hli], a
+ ld a, [W_BASECOORDX] ; $d081
+ cp $90
+ jr c, .asm_79249
+ sub $a8
+ ld [W_BASECOORDX], a ; $d081
+ ld a, [W_BASECOORDY] ; $d082
+ add $10
+ ld [W_BASECOORDY], a ; $d082
+ cp $70
+ jr c, .asm_79249
+ call AnimationCleanOAM
+ jp DelayFrame
+
+AnimationSlideMonUp: ; 7927a (1e:527a)
+; Slides the mon's sprite upwards.
+ ld c, $7
+ ld a, [H_WHOSETURN]
+ and a
+ ld hl, $c419
+ ld de, $c405
+ ld a, $30
+ jr z, .asm_79291
+ ld hl, $c3c0
+ ld de, $c3ac
+ ld a, $ff
+.asm_79291
+ ld [$d09f], a
+ jp Func_792bf
+
+AnimationSlideMonDown: ; 79297 (1e:5297)
+; Slides the mon's sprite down out of the screen.
+ xor a
+ call Func_79842
+.asm_7929b
+ call Func_79820
+ push bc
+ push de
+ call Func_79aae
+ call Delay3
+ call AnimationHideMonPic
+ pop de
+ pop bc
+ dec b
+ jr nz, .asm_7929b
+ ret
+
+AnimationSlideMonOut: ; 792af (1e:52af)
+; Slides the mon's sprite out of the screen horizontally.
+ ld e, $8
+ ld a, $3
+ ld [W_SUBANIMTRANSFORM], a ; $d08b
+ jp Func_795f8
+
+AnimationSlideEnemyMonOut: ; 792b9 (1e:52b9)
+; Slides the enemy mon out of the screen horizontally.
+ ld hl, AnimationSlideMonOut ; $52af
+ jp CallWithTurnFlipped
+
+Func_792bf: ; 792bf (1e:52bf)
+ push de
+ push hl
+ push bc
+ ld b, $6
+.asm_792c4
+ push bc
+ push de
+ push hl
+ ld bc, $0007
+ call CopyData
+ pop de
+ pop hl
+ ld bc, $0028
+ add hl, bc
+ pop bc
+ dec b
+ jr nz, .asm_792c4
+ ld a, [H_WHOSETURN]
+ and a
+ ld hl, $c47d
+ jr z, .asm_792e2
+ ld hl, $c424
+.asm_792e2
+ ld a, [$d09f]
+ inc a
+ ld [$d09f], a
+ ld c, $7
+.asm_792eb
+ ld [hli], a
+ add $7
+ dec c
+ jr nz, .asm_792eb
+ ld c, $2
+ call DelayFrames
+ pop bc
+ pop hl
+ pop de
+ dec c
+ jr nz, Func_792bf
+ ret
+
+Func_792fd: ; 792fd (1e:52fd)
+ ld a, $10
+ ld [W_BASECOORDX], a
+ ld a, $30
+ ld [W_BASECOORDY], a
+ ld hl, wOAMBuffer
+ ld d, $0
+ ld c, $7
+.asm_7930e
+ ld a, [W_BASECOORDY]
+ ld e, a
+ ld b, $5
+.asm_79314
+ call Func_79329
+ inc d
+ dec b
+ jr nz, .asm_79314
+ dec c
+ ret z
+ inc d
+ inc d
+ ld a, [W_BASECOORDX]
+ add $8
+ ld [W_BASECOORDX], a
+ jr .asm_7930e
+
+Func_79329: ; 79329 (1e:5329)
+ ld a, e
+ add $8
+ ld e, a
+ ld [hli], a
+ ld a, [W_BASECOORDX] ; $d081
+ ld [hli], a
+ ld a, d
+ ld [hli], a
+ xor a
+ ld [hli], a
+ ret
+
+Func_79337: ; 79337 (1e:5337)
+ ld l, e
+ ld h, d
+
+Func_79339: ; 79339 (1e:5339)
+ ld de, $4
+.asm_7933c
+ ld a, [$d08a]
+ ld b, a
+ ld a, [hl]
+ add b
+ cp $a8
+ jr c, .asm_7934a
+ dec hl
+ ld a, $a0
+ ld [hli], a
+.asm_7934a
+ ld [hl], a
+ add hl, de
+ dec c
+ jr nz, .asm_7933c
+ ret
+
+Func_79350: ; 79350 (1e:5350)
+ ld l, e
+ ld h, d
+
+Func_79352: ; 79352 (1e:5352)
+ ld de, $4
+.asm_79355
+ ld a, [$d08a]
+ ld b, a
+ ld a, [hl]
+ add b
+ cp $70
+ jr c, .asm_79363
+ dec hl
+ ld a, $a0
+ ld [hli], a
+.asm_79363
+ ld [hl], a
+ add hl, de
+ dec c
+ jr nz, .asm_79355
+ ret
+
+AnimationBlinkEnemyMon: ; 79369 (1e:5369)
+; Make the enemy mon's sprite blink on and off for a second or two
+ ld hl, AnimationBlinkMon ; $536f
+ jp CallWithTurnFlipped
+
+AnimationBlinkMon: ; 7936f (1e:536f)
+; Make the mon's sprite blink on and off for a second or two.
+ push af
+ ld c, $6
+.asm_79372
+ push bc
+ call AnimationHideMonPic
+ ld c, $5
+ call DelayFrames
+ call AnimationShowMonPic
+ ld c, $5
+ call DelayFrames
+ pop bc
+ dec c
+ jr nz, .asm_79372
+ pop af
+ ret
+
+AnimationFlashMonPic: ; 79389 (1e:5389)
+; Flashes the mon's sprite on and off
+ ld a, [W_PLAYERMONID]
+ ld [$ceea], a
+ ld a, [$cfe5]
+ ld [$cee9], a
+ jp Func_79793
+
+AnimationFlashEnemyMonPic: ; 79398 (1e:5398)
+; Flashes the enemy mon's sprite on and off
+ ld hl, AnimationFlashMonPic
+ jp CallWithTurnFlipped
+
+AnimationShowMonPic: ; 7939e (1e:539e)
+ xor a
+ call Func_79842
+ call Func_79820
+ call Func_79aae
+ jp Delay3
+
+AnimationShowEnemyMonPic: ; 793ab (1e:53ab)
+; Shows the emenmy mon's front sprite. Used in animations like Seismic Toss
+; to make the mon's sprite reappear after disappears offscreen.
+ ld hl, AnimationShowMonPic
+ jp CallWithTurnFlipped
+
+AnimationShakeBackAndForth: ; 793b1 (1e:53b1)
+; Shakes the mon's sprite back and forth rapidly. This is used in Double Team.
+; The mon's sprite disappears after this animation.
+ ld a, [H_WHOSETURN]
+ and a
+ ld hl, $c404
+ ld de, $c406
+ jr z, .asm_793c2
+ ld hl, $c3ab
+ ld de, $c3ad
+
+.asm_793c2
+ xor a
+ ld c, $10
+.asm_793c5
+ push af
+ push bc
+ push de
+ push hl
+ push hl
+ push de
+ push af
+ push hl
+ push hl
+ call Func_79842
+ pop hl
+ call Func_79aae
+ call Delay3
+ pop hl
+ ld bc, $0709
+ call ClearScreenArea
+ pop af
+ call Func_79842
+ pop hl
+ call Func_79aae
+ call Delay3
+ pop hl
+ ld bc, $0709
+ call ClearScreenArea
+ pop hl
+ pop de
+ pop bc
+ pop af
+ dec c
+ jr nz, .asm_793c5
+ ret
+
+AnimationMoveMonHorizontally: ; 793f9 (1e:53f9)
+; Shifts the mon's sprite horizontally to a fixed location. Used by lots of
+; animations like Tackle/Body Slam.
+ call AnimationHideMonPic
+ ld a, [H_WHOSETURN] ; $fff3
+ and a
+ FuncCoord 2, 5 ; $c406
+ ld hl, Coord
+ jr z, .asm_79407
+ FuncCoord 11, 0 ; $c3ab
+ ld hl, Coord
+.asm_79407
+ xor a
+ push hl
+ call Func_79842
+ pop hl
+ call Func_79aae
+ ld c, $3
+ jp DelayFrames
+
+AnimationResetMonPosition: ; 79415 (1e:5415)
+; Resets the mon's sprites to be located at the normal coordinates.
+ ld a, [H_WHOSETURN] ; $fff3
+ and a
+ ld a, $66
+ jr z, .asm_7941e
+ ld a, $b
+.asm_7941e
+ call Func_7980c
+ jp AnimationShowMonPic
+
+AnimationSpiralBallsInward: ; 79424 (1e:5424)
+; Creates an effect that looks like energy balls sprialing into the
+; player mon's sprite. Used in Focus Energy, for example.
+ ld a, [H_WHOSETURN] ; $fff3
+ and a
+ jr z, .asm_79435
+ ld a, $d8
+ ld [$d08a], a
+ ld a, $50
+ ld [W_SUBANIMTRANSFORM], a ; $d08b
+ jr .asm_7943c
+.asm_79435
+ xor a
+ ld [$d08a], a
+ ld [W_SUBANIMTRANSFORM], a ; $d08b
+.asm_7943c
+ ld d, $7a
+ ld c, $3
+ xor a
+ call Func_797e8
+ ld hl, SpiralBallAnimationCoordinates ; $5476
+.asm_79447
+ push hl
+ ld c, $3
+ ld de, wOAMBuffer
+.asm_7944d
+ ld a, [hl]
+ cp $ff
+ jr z, .asm_7946f
+ ld a, [$d08a]
+ add [hl]
+ ld [de], a
+ inc de
+ inc hl
+ ld a, [W_SUBANIMTRANSFORM] ; $d08b
+ add [hl]
+ ld [de], a
+ inc hl
+ inc de
+ inc de
+ inc de
+ dec c
+ jr nz, .asm_7944d
+ ld c, $5
+ call DelayFrames
+ pop hl
+ inc hl
+ inc hl
+ jr .asm_79447
+.asm_7946f
+ pop hl
+ call AnimationCleanOAM
+ jp AnimationFlashScreen
+
+SpiralBallAnimationCoordinates: ; 79476 (1e:5476)
+; y, x pairs
+; This is the sequence of screen coordinates that the spiraling
+; balls are positioned at.
+ db $38, $28
+ db $40, $18
+ db $50, $10
+ db $60, $18
+ db $68, $28
+ db $60, $38
+ db $50, $40
+ db $40, $38
+ db $40, $28
+ db $46, $1E
+ db $50, $18
+ db $5B, $1E
+ db $60, $28
+ db $5B, $32
+ db $50, $38
+ db $46, $32
+ db $48, $28
+ db $50, $20
+ db $58, $28
+ db $50, $30
+ db $50, $28
+ db $FF ; list terminator
+
+AnimationSquishMonPic: ; 794a1 (1e:54a1)
+; Squishes the mon's sprite horizontally making it
+; disappear. Used by Teleport/Sky Attack animations.
+ ld c, $4
+.asm_794a3
+ push bc
+ ld a, [H_WHOSETURN] ; $fff3
+ and a
+ jr z, .asm_794b1
+ FuncCoord 16, 0 ; $c3b0
+ ld hl, Coord
+ FuncCoord 14, 0 ; $c3ae
+ ld de, Coord
+ jr .asm_794b7
+.asm_794b1
+ FuncCoord 5, 5 ; $c409
+ ld hl, Coord
+ FuncCoord 3, 5 ; $c407
+ ld de, Coord
+.asm_794b7
+ push de
+ xor a
+ ld [$d09f], a
+ call Func_794d4
+ pop hl
+ ld a, $1
+ ld [$d09f], a
+ call Func_794d4
+ pop bc
+ dec c
+ jr nz, .asm_794a3
+ call AnimationHideMonPic
+ ld c, $2
+ jp DelayFrame
+
+Func_794d4: ; 794d4 (1e:54d4)
+ ld c, $7
+.asm_794d6
+ push bc
+ push hl
+ ld c, $3
+ ld a, [$d09f]
+ cp $0
+ jr nz, .asm_794e7
+ call Func_7985b
+ dec hl
+ jr .asm_794eb
+.asm_794e7
+ call Func_79862
+ inc hl
+.asm_794eb
+ ld [hl], $7f
+ pop hl
+ ld de, $14
+ add hl, de
+ pop bc
+ dec c
+ jr nz, .asm_794d6
+ jp Delay3
+
+AnimationShootBallsUpward: ; 794f9 (1e:54f9)
+; Shoots one pillar of "energy" balls upwards. Used in Teleport/Sky Attack
+; animations.
+ ld a, [H_WHOSETURN] ; $fff3
+ and a
+ jr z, .asm_79503
+ ld bc, $80
+ jr .asm_79506
+.asm_79503
+ ld bc, $3028
+.asm_79506
+ ld a, b
+ ld [W_BASECOORDY], a ; $d082
+ ld a, c
+ ld [W_BASECOORDX], a ; $d081
+ ld bc, $501
+ call Func_79517
+ jp AnimationCleanOAM
+
+Func_79517: ; 79517 (1e:5517)
+ push bc
+ xor a
+ ld [$d09f], a
+ call LoadAnimationTileset
+ pop bc
+ ld d, $7a
+ ld hl, wOAMBuffer
+ push bc
+ ld a, [W_BASECOORDY] ; $d082
+ ld e, a
+.asm_7952a
+ call Func_79329
+ dec b
+ jr nz, .asm_7952a
+ call DelayFrame
+ pop bc
+ ld a, b
+ ld [$d08a], a
+.asm_79538
+ push bc
+ ld hl, wOAMBuffer
+.asm_7953c
+ ld a, [W_BASECOORDY] ; $d082
+ add $8
+ ld e, a
+ ld a, [hl]
+ cp e
+ jr z, .asm_7954b
+ add $fc
+ ld [hl], a
+ jr .asm_79554
+.asm_7954b
+ ld [hl], $0
+ ld a, [$d08a]
+ dec a
+ ld [$d08a], a
+.asm_79554
+ ld de, $4
+ add hl, de
+ dec b
+ jr nz, .asm_7953c
+ call DelayFrames
+ pop bc
+ ld a, [$d08a]
+ and a
+ jr nz, .asm_79538
+ ret
+
+AnimationShootManyBallsUpward: ; 79566 (1e:5566)
+; Shoots several pillars of "energy" balls upward.
+ ld a, [H_WHOSETURN]
+ and a
+ ld hl, UpwardBallsAnimXCoordinatesPlayerTurn
+ ld a, $50 ; y coordinate for "energy" ball pillar
+ jr z, .player
+ ld hl, UpwardBallsAnimXCoordinatesEnemyTurn
+ ld a, $28 ; y coordinate for "energy" ball pillar
+.player
+ ld [wTrainerSpriteOffset], a
+.loop
+ ld a, [wTrainerSpriteOffset]
+ ld [W_BASECOORDY], a
+ ld a, [hli]
+ cp $ff
+ jp z, AnimationCleanOAM
+ ld [W_BASECOORDX], a
+ ld bc, $0401
+ push hl
+ call Func_79517
+ pop hl
+ jr .loop
+
+UpwardBallsAnimXCoordinatesPlayerTurn: ; 79591 (1e:5591)
+; List of x coordinates for each pillar of "energy" balls in the
+; AnimationShootManyBallsUpward animation. It's unused in the game.
+ db $10, $40, $28, $18, $38, $30
+ db $FF ; list terminator
+
+UpwardBallsAnimXCoordinatesEnemyTurn: ; 79598 (1e:5598)
+; List of x coordinates for each pillar of "energy" balls in the
+; AnimationShootManyBallsUpward animation. It's unused in the game.
+ db $60, $90, $78, $68, $88, $80
+ db $FF ; list terminator
+
+AnimationMinimizeMon: ; 7959f (1e:559f)
+; Changes the mon's sprite to a mini black sprite. Used by the
+; Minimize animation.
+ ld hl, $c6e8
+ push hl
+ xor a
+ ld bc, $310
+ call FillMemory
+ pop hl
+ ld de, $194
+ add hl, de
+ ld de, MinimizedMonSprite ; $55c4
+ ld c, $5
+.asm_795b4
+ ld a, [de]
+ ld [hli], a
+ ld [hli], a
+ inc de
+ dec c
+ jr nz, .asm_795b4
+ call Func_79652
+ call Delay3
+ jp AnimationShowMonPic
+
+MinimizedMonSprite: ; 795c4 (1e:55c4)
+ INCBIN "gfx/minimized_mon_sprite.1bpp"
+
+AnimationSlideMonDownAndHide: ; 795c9 (1e:55c9)
+; Slides the mon's sprite down and disappears. Used in Acid Armor.
+ ld a, $1
+ ld c, $2
+.asm_795cd
+ push bc
+ push af
+ call AnimationHideMonPic
+ pop af
+ push af
+ call Func_79842
+ call Func_79820
+ call Func_79aae
+ ld c, $8
+ call DelayFrames
+ pop af
+ inc a
+ pop bc
+ dec c
+ jr nz, .asm_795cd
+ call AnimationHideMonPic
+ ld hl, $c6e8
+ ld bc, $0310
+ xor a
+ call FillMemory
+ jp Func_79652
+
+Func_795f8: ; 795f8 (1e:55f8)
+ ld a, [H_WHOSETURN] ; $fff3
+ and a
+ jr z, .asm_79602
+ FuncCoord 12, 0 ; $c3ac
+ ld hl, Coord
+ jr .asm_79605
+.asm_79602
+ FuncCoord 0, 5 ; $c404
+ ld hl, Coord
+.asm_79605
+ ld d, $8
+.asm_79607
+ push hl
+ ld b, $7
+.asm_7960a
+ ld c, $8
+.asm_7960c
+ ld a, [H_WHOSETURN] ; $fff3
+ and a
+ jr z, .asm_79616
+ call Func_7963c
+ jr .asm_79619
+.asm_79616
+ call Func_79633
+.asm_79619
+ ld [hli], a
+ dec c
+ jr nz, .asm_7960c
+ push de
+ ld de, $c
+ add hl, de
+ pop de
+ dec b
+ jr nz, .asm_7960a
+ ld a, [W_SUBANIMTRANSFORM] ; $d08b
+ ld c, a
+ call DelayFrames
+ pop hl
+ dec d
+ dec e
+ jr nz, .asm_79607
+ ret
+
+Func_79633: ; 79633 (1e:5633)
+ ld a, [hl]
+ add $7
+ cp $61
+ ret c
+ ld a, $7f
+ ret
+
+Func_7963c: ; 7963c (1e:563c)
+ ld a, [hl]
+ sub $7
+ cp $30
+ ret c
+ ld a, $7f
+ ret
+
+AnimationSlideMonHalfLeft: ; 79645 (1e:5645)
+; Slides the mon's sprite halfway out of the screen. It's used in Softboiled.
+ ld e, $4
+ ld a, $4
+ ld [W_SUBANIMTRANSFORM], a
+ call Func_795f8
+ jp Delay3
+
+Func_79652: ; 79652 (1e:5652)
+ ld a, [H_WHOSETURN] ; $fff3
+ and a
+ ld hl, $9310
+ jr z, .asm_7965d
+ ld hl, $9000
+.asm_7965d
+ ld de, $c6e8
+ ld bc, $31
+ jp CopyVideoData
+
+AnimationWavyScreen: ; 79666 (1e:5666)
+; used in Psywave/Psychic etc.
+ ld hl, $9800
+ call Func_79e0d
+ call Delay3
+ xor a
+ ld [H_AUTOBGTRANSFERENABLED], a
+ ld a, $90
+ ld [$ffb0], a
+ ld d, $80
+ ld e, $8f
+ ld c, $ff
+ ld hl, WavyScreenLineOffsets
+.asm_7967f
+ push hl
+.asm_79680
+ call Func_796ae
+ ld a, [$ff44]
+ cp e
+ jr nz, .asm_79680
+ pop hl
+ inc hl
+ ld a, [hl]
+ cp d
+ jr nz, .asm_79691
+ ld hl, WavyScreenLineOffsets
+.asm_79691
+ dec c
+ jr nz, .asm_7967f
+ xor a
+ ld [$ffb0], a
+ call SaveScreenTilesToBuffer2
+ call ClearScreen
+ ld a, $1
+ ld [H_AUTOBGTRANSFERENABLED], a
+ call Delay3
+ call LoadScreenTilesFromBuffer2
+ ld hl, $9c00
+ call Func_79e0d
+ ret
+
+Func_796ae: ; 796ae (1e:56ae)
+ ld a, [$ff41]
+ and $3
+ jr nz, Func_796ae
+ ld a, [hl]
+ ld [$ff43], a
+ inc hl
+ ld a, [hl]
+ cp d
+ ret nz
+ ld hl, WavyScreenLineOffsets
+ ret
+
+WavyScreenLineOffsets: ; 796bf (1e:56bf)
+; Sequence of horizontal line pixel offsets for the wavy screen animation.
+; This sequence vaguely resembles a sine wave.
+ db 0, 0, 0, 0, 0, 1, 1, 1, 2, 2, 2, 2, 2, 1, 1, 1
+ db 0, 0, 0, 0, 0, -1, -1, -1, -2, -2, -2, -2, -2, -1, -1, -1
+ db $80 ; terminator
+
+AnimationSubstitute: ; 796e0 (1e:56e0)
+; Changes the pokemon's sprite to the mini sprite
+ ld hl, $c6e8
+ xor a
+ ld bc, $0310
+ call FillMemory
+ ld a, [$fff3]
+ and a
+ jr z, .asm_79715 ; 0x796ed $26
+ ld hl, SlowbroSprite ; $4780 ; facing down sprite
+ ld de, $c808
+ call CopySlowbroSpriteData
+ ld hl, SlowbroSprite + $10 ; $4790
+ ld de, $c878
+ call CopySlowbroSpriteData
+ ld hl, SlowbroSprite + $20 ; $47a0
+ ld de, $c818
+ call CopySlowbroSpriteData
+ ld hl, SlowbroSprite + $30 ; $47b0
+ ld de, $c888
+ call CopySlowbroSpriteData
+ jr .asm_79739 ; 0x79713 $24
+.asm_79715
+ ld hl, SlowbroSprite + $40 ; $47c0 ; facing up sprite
+ ld de, $c878
+ call CopySlowbroSpriteData
+ ld hl, SlowbroSprite + $50 ; $47d0
+ ld de, $c8e8
+ call CopySlowbroSpriteData
+ ld hl, SlowbroSprite + $60 ; $47e0
+ ld de, $c888
+ call CopySlowbroSpriteData
+ ld hl, SlowbroSprite + $70 ; $47f0
+ ld de, $c8f8
+ call CopySlowbroSpriteData
+.asm_79739
+ call Func_79652
+ jp AnimationShowMonPic
+
+CopySlowbroSpriteData: ; 7973f (1e:573f)
+ ld bc, $0010
+ ld a, BANK(SlowbroSprite)
+ jp FarCopyData2
+
+Func_79747: ; 79747 (1e:5747)
+ ld a, [H_WHOSETURN] ; $fff3
+ and a
+ ld hl, $ccf7
+ ld a, [W_PLAYERBATTSTATUS2] ; $d063
+ jr z, .asm_79758
+ ld hl, $ccf3
+ ld a, [W_ENEMYBATTSTATUS2] ; $d068
+.asm_79758
+ push hl
+ bit 4, a
+ jr nz, .asm_79762
+ call AnimationSlideMonDown
+ jr .asm_79765
+.asm_79762
+ call AnimationSlideMonOut
+.asm_79765
+ pop hl
+ ld a, [hl]
+ and a
+ jp nz, AnimationMinimizeMon
+ call AnimationFlashMonPic
+ jp AnimationShowMonPic
+
+Func_79771: ; 79771 (1e:5771)
+ call AnimationSlideMonOut
+ call AnimationSubstitute
+ jp AnimationShowMonPic
+
+AnimationBoundUpAndDown: ; 7977a (1e:577a)
+; Bounces the mon's sprite up and down several times. It is used
+; by Splash's animation.
+ ld c, $5
+.asm_7977c
+ push bc
+ call AnimationSlideMonDown
+ pop bc
+ dec c
+ jr nz, .asm_7977c ; 0x79782 $f8
+ jp AnimationShowMonPic
+
+AnimationTransformMon: ; 79787 (1e:5787)
+; Redraws this mon's sprite as the back/front sprite of the opposing mon.
+; Used in Transform.
+ ld a, [$cfe5]
+ ld [$ceea], a
+ ld a, [W_PLAYERMONID]
+ ld [$cee9], a
+
+Func_79793: ; 79793 (1e:5793)
+ ld a, [H_WHOSETURN] ; $fff3
+ and a
+ jr z, .asm_797b0
+ ld a, [$cee9]
+ ld [$cf91], a
+ ld [$d0b5], a
+ xor a
+ ld [W_SPRITEFLIPPED], a
+ call GetMonHeader
+ FuncCoord 12, 0 ; $c3ac
+ ld hl, Coord
+ call LoadFrontSpriteByMonIndex
+ jr .asm_797d3
+.asm_797b0
+ ld a, [$cfd9]
+ push af
+ ld a, [$ceea]
+ ld [$cfd9], a
+ ld [$d0b5], a
+ call GetMonHeader
+ ld a, $4
+ call Predef ; indirect jump to LoadMonBackSprite (3f103 (f:7103))
+ xor a
+ call Func_79842
+ call Func_79820
+ call Func_79aae
+ pop af
+ ld [$cfd9], a
+.asm_797d3
+ ld b, $1
+ jp GoPAL_SET
+
+AnimationHideEnemyMonPic: ; 797d8 (1e:57d8)
+; Hides the enemy mon's sprite
+ xor a
+ ld [H_AUTOBGTRANSFERENABLED], a ; $ffba
+ ld hl, AnimationHideMonPic ; $5801
+ call CallWithTurnFlipped
+ ld a, $1
+ ld [H_AUTOBGTRANSFERENABLED], a ; $ffba
+ jp Delay3
+
+Func_797e8: ; 797e8 (1e:57e8)
+ push bc
+ push de
+ ld [$d09f], a
+ call LoadAnimationTileset
+ pop de
+ pop bc
+ xor a
+ ld e, a
+ ld [W_BASECOORDX], a ; $d081
+ ld hl, wOAMBuffer
+.asm_797fa
+ call Func_79329
+ dec c
+ jr nz, .asm_797fa
+ ret
+
+AnimationHideMonPic: ; 79801 (1e:5801)
+; Hides the mon's sprite.
+ ld a, [H_WHOSETURN] ; $fff3
+ and a
+ jr z, .asm_7980a
+ ld a, $c
+ jr Func_7980c
+.asm_7980a
+ ld a, $65
+
+Func_7980c: ; 7980c (1e:580c)
+ push hl
+ push de
+ push bc
+ ld e, a
+ ld d, $0
+ ld hl, wTileMap
+ add hl, de
+ ld bc, $707
+ call ClearScreenArea
+ pop bc
+ pop de
+ pop hl
+ ret
+
+Func_79820: ; 79820 (1e:5820)
+ push de
+ ld a, [H_WHOSETURN] ; $fff3
+ and a
+ jr nz, .asm_7982a
+ ld a, $65
+ jr .asm_7982c
+.asm_7982a
+ ld a, $c
+.asm_7982c
+ ld hl, wTileMap
+ ld e, a
+ ld d, $0
+ add hl, de
+ ld a, $7
+ sub b
+ and a
+ jr z, .asm_79840
+ ld de, $14
+.asm_7983c
+ add hl, de
+ dec a
+ jr nz, .asm_7983c
+.asm_79840
+ pop de
+ ret
+
+Func_79842: ; 79842 (1e:5842)
+ ld hl, PointerTable_79aea ; $5aea
+ ld e, a
+ ld d, $0
+ add hl, de
+ add hl, de
+ add hl, de
+ ld a, [hli]
+ ld e, a
+ ld a, [hli]
+ ld d, a
+ ld a, [hli]
+ ld b, a
+ and $f
+ ld c, a
+ ld a, b
+ swap a
+ and $f
+ ld b, a
+ ret
+
+Func_7985b: ; 7985b (1e:585b)
+ ld a, [hld]
+ ld [hli], a
+ inc hl
+ dec c
+ jr nz, Func_7985b
+ ret
+
+Func_79862: ; 79862 (1e:5862)
+ ld a, [hli]
+ ld [hld], a
+ dec hl
+ dec c
+ jr nz, Func_79862
+ ret
+
+Func_79869: ; 79869 (1e:5869)
+ ld a, b
+ call Func_7986f
+ ld b, a
+ ret
+
+Func_7986f: ; 7986f (1e:586f)
+ ld hl,MoveSoundTable
+ ld e,a
+ ld d,0
+ add hl,de
+ add hl,de
+ add hl,de
+ ld a,[hli]
+ ld b,a
+ call IsCryMove
+ jr nc,.NotCryMove
+ ld a,[H_WHOSETURN]
+ and a
+ jr nz,.next
+ ld a,[W_PLAYERMONID] ; get number of current monster
+ jr .Continue
+.next
+ ld a,[$CFE5]
+.Continue
+ push hl
+ call GetCryData
+ ld b,a
+ pop hl
+ ld a,[$C0F1]
+ add [hl]
+ ld [$C0F1],a
+ inc hl
+ ld a,[$C0F2]
+ add [hl]
+ ld [$C0F2],a
+ jr .done
+.NotCryMove
+ ld a,[hli]
+ ld [$C0F1],a
+ ld a,[hli]
+ ld [$C0F2],a
+.done
+ ld a,b
+ ret
+
+IsCryMove: ; 798ad (1e:58ad)
+; set carry if the move animation involves playing a monster cry
+ ld a,[W_ANIMATIONID]
+ cp a,GROWL
+ jr z,.CryMove
+ cp a,ROAR
+ jr z,.CryMove
+ and a ; clear carry
+ ret
+.CryMove
+ scf
+ ret
+
+MoveSoundTable: ; 798bc (1e:58bc)
+ db $a0,$00,$80
+ db $a2,$10,$80
+ db $b3,$00,$80
+ db $a1,$01,$80
+ db $a3,$00,$40
+ db $e9,$00,$ff
+ db $a3,$10,$60
+ db $a3,$20,$80
+ db $a3,$00,$a0
+ db $a6,$00,$80
+ db $a5,$20,$40
+ db $a5,$00,$80
+ db $a4,$00,$a0
+ db $a7,$10,$c0
+ db $a7,$00,$a0
+ db $a8,$00,$c0
+ db $a8,$10,$a0
+ db $a9,$00,$e0
+ db $a7,$20,$c0
+ db $aa,$00,$80
+ db $b9,$00,$80
+ db $ab,$01,$80
+ db $b7,$00,$80
+ db $ad,$f0,$40
+ db $b0,$00,$80
+ db $ad,$00,$80
+ db $b8,$10,$80
+ db $b1,$01,$a0
+ db $ae,$00,$80
+ db $b4,$00,$60
+ db $b4,$01,$40
+ db $b6,$00,$a0
+ db $b0,$10,$a0
+ db $b7,$00,$c0
+ db $aa,$10,$60
+ db $b0,$00,$a0
+ db $b9,$11,$c0
+ db $b0,$20,$c0
+ db $b8,$00,$80
+ db $b1,$00,$80
+ db $b1,$20,$c0
+ db $af,$00,$80
+ db $db,$ff,$40
+ db $b4,$00,$80
+ db $a1,$00,$c0
+ db $a1,$00,$40
+ db $e4,$00,$80
+ db $bf,$40,$60
+ db $bf,$00,$80
+ db $bf,$ff,$40
+ db $c7,$80,$c0
+ db $af,$10,$a0
+ db $af,$21,$e0
+ db $c5,$00,$80
+ db $bb,$20,$60
+ db $c7,$00,$80
+ db $cc,$00,$80
+ db $c2,$40,$80
+ db $c5,$f0,$e0
+ db $cf,$00,$80
+ db $c7,$f0,$60
+ db $c2,$00,$80
+ db $e6,$00,$80
+ db $9d,$01,$a0
+ db $a9,$f0,$20
+ db $ba,$01,$c0
+ db $ba,$00,$80
+ db $b0,$00,$e0
+ db $be,$01,$60
+ db $be,$20,$40
+ db $bb,$00,$80
+ db $bb,$40,$c0
+ db $b1,$03,$60
+ db $bd,$11,$e0
+ db $a8,$20,$e0
+ db $d2,$00,$80
+ db $b2,$00,$80
+ db $b2,$11,$a0
+ db $b2,$01,$c0
+ db $a9,$14,$c0
+ db $b1,$02,$a0
+ db $c5,$f0,$80
+ db $c5,$20,$c0
+ db $d5,$00,$20
+ db $d5,$20,$80
+ db $d2,$12,$60
+ db $be,$00,$80
+ db $aa,$01,$e0
+ db $c5,$0f,$e0
+ db $c5,$11,$20
+ db $a6,$10,$40
+ db $a5,$10,$c0
+ db $aa,$00,$20
+ db $d8,$00,$80
+ db $e4,$11,$18
+ db $9f,$20,$c0
+ db $9e,$20,$c0
+ db $bd,$00,$10
+ db $be,$f0,$20
+ db $df,$f0,$c0
+ db $a7,$f0,$e0
+ db $9f,$f0,$40
+ db $db,$00,$80
+ db $df,$80,$40
+ db $df,$00,$80
+ db $aa,$11,$20
+ db $aa,$22,$10
+ db $b1,$f1,$ff
+ db $a9,$f1,$ff
+ db $aa,$33,$30
+ db $dd,$40,$c0
+ db $a4,$20,$20
+ db $a4,$f0,$10
+ db $a5,$f8,$10
+ db $a7,$f0,$10
+ db $bd,$00,$80
+ db $ae,$00,$c0
+ db $dd,$c0,$ff
+ db $9f,$f2,$20
+ db $e1,$00,$80
+ db $e1,$00,$40
+ db $9f,$00,$40
+ db $a7,$10,$ff
+ db $c7,$20,$20
+ db $dd,$00,$80
+ db $c5,$1f,$20
+ db $bd,$2f,$80
+ db $a5,$1f,$ff
+ db $ca,$1f,$60
+ db $be,$1e,$20
+ db $be,$1f,$18
+ db $aa,$0f,$80
+ db $9f,$f8,$10
+ db $9e,$18,$20
+ db $dd,$08,$40
+ db $ad,$01,$e0
+ db $a7,$09,$ff
+ db $e4,$42,$01
+ db $b2,$00,$ff
+ db $dd,$08,$e0
+ db $bb,$00,$80
+ db $9f,$88,$10
+ db $bd,$48,$ff
+ db $9e,$ff,$ff
+ db $bb,$ff,$10
+ db $9e,$ff,$04
+ db $b2,$01,$ff
+ db $a9,$f8,$ff
+ db $a2,$f0,$f0
+ db $a5,$08,$10
+ db $a3,$f0,$ff
+ db $b0,$f0,$ff
+ db $e1,$10,$ff
+ db $a4,$f0,$20
+ db $ca,$f0,$60
+ db $b8,$12,$10
+ db $e6,$f0,$20
+ db $b4,$12,$ff
+ db $db,$80,$04
+ db $df,$f0,$10
+ db $c5,$f8,$ff
+ db $be,$f0,$ff
+ db $a7,$01,$ff
+ db $cc,$d8,$04
+ db $a1,$00,$80
+ db $a1,$00,$80
+
+Func_79aae: ; 79aae (1e:5aae)
+ ld a, [H_WHOSETURN] ; $fff3
+ and a
+ ld a, $31
+ jr z, .asm_79ab6
+ xor a
+.asm_79ab6
+ ld [H_DOWNARROWBLINKCNT1], a ; $ff8b
+ jr asm_79acb
+
+Func_79aba: ; 79aba (1e:5aba)
+ call Load16BitRegisters
+ ld a, [$cd6c]
+ and a
+ jr nz, .asm_79ac8
+ ld de, Unknown_79b02 ; $5b02
+ jr asm_79acb
+.asm_79ac8
+ ld de, Unknown_79b1b ; $5b1b
+asm_79acb: ; 79acb (1e:5acb)
+ xor a
+ ld [H_AUTOBGTRANSFERENABLED], a ; $ffba
+
+Func_79ace: ; 79ace (1e:5ace)
+ push hl
+.asm_79acf
+ push bc
+ push hl
+ ld a, [H_DOWNARROWBLINKCNT1] ; $ff8b
+ ld b, a
+.asm_79ad4
+ ld a, [de]
+ add b
+ inc de
+ ld [hli], a
+ dec c
+ jr nz, .asm_79ad4
+ pop hl
+ ld bc, $14
+ add hl, bc
+ pop bc
+ dec b
+ jr nz, .asm_79acf
+ ld a, $1
+ ld [H_AUTOBGTRANSFERENABLED], a ; $ffba
+ pop hl
+ ret
+
+PointerTable_79aea: ; 79aea (1e:5aea)
+ dw Unknown_79b24
+ db $77
+ dw Unknown_79b55
+ db $57
+ dw Unknown_79b78
+ db $37
+ dw Unknown_79b8d
+ db $77
+ dw Unknown_79bbe
+ db $77
+ dw Unknown_79bef
+ db $77
+ dw Unknown_79c20
+ db $86
+ dw Unknown_79c50
+ db $3C
+
+Unknown_79b02: ; 79b02 (1e:5b02)
+ db $31,$38,$46,$54,$5B,$32,$39,$47,$55,$5C,$34,$3B,$49,$57,$5E,$36,$3D,$4B,$59,$60,$37,$3E,$4C,$5A,$61
+
+Unknown_79b1b: ; 79b1b (1e:5b1b)
+ db $31,$46,$5B,$34,$49,$5E,$37,$4C,$61
+
+Unknown_79b24: ; 79b24 (1e:5b24)
+ db $00,$07,$0E,$15,$1C,$23,$2A,$01,$08,$0F,$16,$1D,$24,$2B,$02,$09,$10,$17,$1E,$25,$2C,$03,$0A,$11,$18,$1F,$26,$2D,$04,$0B,$12,$19,$20,$27,$2E,$05,$0C,$13,$1A,$21,$28,$2F,$06,$0D,$14,$1B,$22,$29,$30
+
+Unknown_79b55: ; 79b55 (1e:5b55)
+ db $00,$07,$0E,$15,$1C,$23,$2A,$01,$08,$0F,$16,$1D,$24,$2B,$03,$0A,$11,$18,$1F,$26,$2D,$04,$0B,$12,$19,$20,$27,$2E,$05,$0C,$13,$1A,$21,$28,$2F
+
+Unknown_79b78: ; 79b78 (1e:5b78)
+ db $00,$07,$0E,$15,$1C,$23,$2A,$02,$09,$10,$17,$1E,$25,$2C,$04,$0B,$12,$19,$20,$27,$2E
+
+Unknown_79b8d: ; 79b8d (1e:5b8d)
+ db $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$19,$00,$02,$06,$0B,$10,$14,$1A,$00,$00,$07,$0C,$11,$15,$1B,$00,$03,$08,$0D,$12,$16,$1C,$00,$04,$09,$0E,$13,$17,$1D,$1F,$05,$0A,$0F,$01,$18,$1E,$20
+
+Unknown_79bbe: ; 79bbe (1e:5bbe)
+ db $00,$00,$00,$30,$00,$37,$00,$00,$00,$2B,$31,$34,$38,$3D,$21,$26,$2C,$01,$35,$39,$3E,$22,$27,$2D,$32,$36,$01,$00,$23,$28,$2E,$33,$01,$3A,$00,$24,$29,$2F,$01,$01,$3B,$00,$25,$2A,$01,$01,$01,$3C,$00
+
+Unknown_79bef: ; 79bef (1e:5bef)
+ db $00,$00,$00,$00,$00,$00,$00,$00,$00,$47,$4D,$00,$00,$00,$00,$00,$48,$4E,$52,$56,$5B,$3F,$43,$49,$4F,$53,$57,$5C,$40,$44,$4A,$50,$54,$58,$00,$41,$45,$4B,$51,$4C,$59,$5D,$42,$46,$4C,$4C,$55,$5A,$5E
+
+Unknown_79c20: ; 79c20 (1e:5c20)
+ db $31,$32,$32,$32,$32,$33,$34,$35,$36,$36,$37,$38,$34,$39,$3A,$3A,$3B,$38,$3C,$3D,$3E,$3E,$3F,$40,$41,$42,$43,$43,$44,$45,$46,$47,$43,$48,$49,$4A,$41,$43,$4B,$4C,$4D,$4E,$4F,$50,$50,$50,$51,$52
+
+Unknown_79c50: ; 79c50 (1e:5c50)
+ db $43,$55,$56,$53,$53,$53,$53,$53,$53,$53,$53,$53,$43,$57,$58,$54,$54,$54,$54,$54,$54,$54,$54,$54,$43,$59,$5A,$43,$43,$43,$43,$43,$43,$43,$43,$43
+
+AnimationLeavesFalling: ; 79c74 (1e:5c74)
+; Makes leaves float down from the top of the screen. This is used
+; in Razor Leaf's animation.
+ ld a, [$ff48]
+ push af
+ ld a, [$cc79]
+ ld [$ff48], a
+ ld d, $37
+ ld a, $3
+ ld [W_SUBANIMTRANSFORM], a
+ call Func_79c97
+ pop af
+ ld [$ff48], a
+ ret
+
+AnimationPetalsFalling: ; 79c8a (1e:5c8a)
+; Makes lots of petals fall down from the top of the screen. It's used in
+; the animation for Petal Dance.
+ ld d, $71
+ ld a, $14
+ ld [W_SUBANIMTRANSFORM], a
+ call Func_79c97
+ jp CleanLCD_OAM
+
+Func_79c97: ; 79c97 (1e:5c97)
+ ld c, a
+ ld a, $1
+ call Func_797e8
+ call Func_79d2a
+ call Func_79d52
+ ld hl, wOAMBuffer
+ ld [hl], $0
+.asm_79ca8
+ ld hl, wTrainerSpriteOffset
+ ld de, $0000
+ ld a, [W_SUBANIMTRANSFORM]
+ ld c, a
+.asm_79cb2
+ push bc
+ push hl
+ push de
+ ld a, [hl]
+ ld [$d08a], a
+ call Func_79d16
+ call Func_79cdb
+ pop de
+ ld hl, $0004
+ add hl, de
+ ld e, l
+ ld d, h
+ pop hl
+ ld a, [$d08a]
+ ld [hli], a
+ pop bc
+ dec c
+ jr nz, .asm_79cb2
+ call Delay3
+ ld hl, wOAMBuffer
+ ld a, [hl]
+ cp $68
+ jr nz, .asm_79ca8
+ ret
+
+Func_79cdb: ; 79cdb (1e:5cdb)
+ ld hl, wOAMBuffer
+ add hl, de
+ ld a, [hl]
+ inc a
+ inc a
+ cp $70
+ jr c, .asm_79ce8
+ ld a, $a0
+.asm_79ce8
+ ld [hli], a
+ ld a, [$d08a]
+ ld b, a
+ ld de, Unknown_79d0d
+ and $7f
+ add e
+ jr nc, .asm_79cf6
+ inc d
+.asm_79cf6
+ ld e, a
+ ld a, b
+ and $80
+ jr nz, .asm_79d03
+ ld a, [de]
+ add [hl]
+ ld [hli], a
+ inc hl
+ xor a
+ jr .asm_79d0b
+.asm_79d03
+ ld a, [de]
+ ld b, a
+ ld a, [hl]
+ sub b
+ ld [hli], a
+ inc hl
+ ld a, $20
+.asm_79d0b
+ ld [hl], a
+ ret
+
+Unknown_79d0d: ; 79d0d (1e:5d0d)
+ db $00,$01,$03,$05,$07,$09,$0B,$0D,$0F
+
+Func_79d16: ; 79d16 (1e:5d16)
+ ld a, [$d08a]
+ inc a
+ ld b, a
+ and $7f
+ cp $9
+ ld a, b
+ jr nz, .asm_79d26
+ and $80
+ xor $80
+.asm_79d26
+ ld [$d08a], a
+ ret
+
+Func_79d2a: ; 79d2a (1e:5d2a)
+ ld hl, $c301
+ ld de, Unknown_79d3e
+ ld a, [W_SUBANIMTRANSFORM]
+ ld c, a
+.asm_79d34
+ ld a, [de]
+ ld [hli], a
+ inc hl
+ inc hl
+ inc hl
+ inc de
+ dec c
+ jr nz, .asm_79d34
+ ret
+
+Unknown_79d3e: ; 79d3e (1e:5d3e)
+ db $38,$40,$50,$60,$70,$88,$90,$56,$67,$4A,$77,$84,$98,$32,$22,$5C,$6C,$7D,$8E,$99
+
+Func_79d52: ; 79d52 (1e:5d52)
+ ld hl, wTrainerSpriteOffset
+ ld de, Unknown_79d63
+ ld a, [W_SUBANIMTRANSFORM]
+ ld c, a
+.asm_79d5c
+ ld a, [de]
+ ld [hli], a
+ inc de
+ dec c
+ jr nz, .asm_79d5c
+ ret
+
+Unknown_79d63: ; 79d63 (1e:5d63)
+ db $00,$84,$06,$81,$02,$88,$01,$83,$05,$89,$09,$80,$07,$87,$03,$82,$04,$85,$08,$86
+
+AnimationShakeEnemyHUD: ; 79d77 (1e:5d77)
+ ld de, $9310
+ ld hl, $8000
+ ld bc, $0031
+ call CopyVideoData
+ xor a
+ ld [$ffae], a
+ ld hl, $9800
+ call Func_79e0d
+ ld a, $90
+ ld [$ffb0], a
+ ld hl, $9b20
+ call Func_79e0d
+ ld a, $38
+ ld [$ffb0], a
+ call Func_792fd
+ ld hl, $9800
+ call Func_79e0d
+ call AnimationHideMonPic
+ call Delay3
+ ld de, $0208
+ call Func_79de9
+ call AnimationShowMonPic
+ call CleanLCD_OAM
+ ld a, $90
+ ld [$ffb0], a
+ ld hl, $9c00
+ call Func_79e0d
+ xor a
+ ld [$ffb0], a
+ call SaveScreenTilesToBuffer1
+ ld hl, $9800
+ call Func_79e0d
+ call ClearScreen
+ call Delay3
+ call LoadScreenTilesFromBuffer1
+ ld hl, $9c00
+ jp Func_79e0d
+
+Func_79dda: ; 79dda (1e:5dda)
+ call Load16BitRegisters
+ ld a, c
+ ld [H_DOWNARROWBLINKCNT1], a ; $ff8b
+ ld a, b
+ push hl
+ call Func_79842
+ pop hl
+ jp Func_79ace
+
+Func_79de9: ; 79de9 (1e:5de9)
+ ld a, [$ffae]
+ ld [wTrainerSpriteOffset], a
+.asm_79dee
+ ld a, [wTrainerSpriteOffset]
+ add d
+ ld [$ffae], a
+ ld c, $2
+ call DelayFrames
+ ld a, [wTrainerSpriteOffset]
+ sub d
+ ld [$ffae], a
+ ld c, $2
+ call DelayFrames
+ dec e
+ jr nz, .asm_79dee
+ ld a, [wTrainerSpriteOffset]
+ ld [$ffae], a
+ ret
+
+Func_79e0d: ; 79e0d (1e:5e0d)
+ ld a, h
+ ld [$ffbd], a
+ ld a, l
+ ld [H_AUTOBGTRANSFERDEST], a
+ jp Delay3
+
+TossBallAnimation: ; 79e16 (1e:5e16)
+ ld a,[W_ISINBATTLE]
+ cp a,2
+ jr z,.BlockBall ; if in trainer battle, play different animation
+ ld a,[$D11E]
+ ld b,a
+
+ ; upper nybble: how many animations (from PokeBallAnimations) to play
+ ; this will be 4 for successful capture, 6 for breakout
+ and a,$F0
+ swap a
+ ld c,a
+
+ ; lower nybble: number of shakes
+ ; store these for later
+ ld a,b
+ and a,$F
+ ld [$CD3D],a
+
+ ld hl,.PokeBallAnimations
+ ; choose which toss animation to use
+ ld a,[$CF91]
+ cp a,POKE_BALL
+ ld b,TOSS_ANIM
+ jr z,.done
+ cp a,GREAT_BALL
+ ld b,GREATTOSS_ANIM
+ jr z,.done
+ ld b,ULTRATOSS_ANIM
+.done
+ ld a,b
+.PlayNextAnimation
+ ld [W_ANIMATIONID],a
+ push bc
+ push hl
+ call PlayAnimation
+ pop hl
+ ld a,[hli]
+ pop bc
+ dec c
+ jr nz,.PlayNextAnimation
+ ret
+
+.PokeBallAnimations: ; 79e50 (1e:5e50)
+; sequence of animations that make up the Poké Ball toss
+ db POOF_ANIM,HIDEPIC_ANIM,$C2,POOF_ANIM,SHOWPIC_ANIM
+
+.BlockBall ; 5E55
+ ld a,$C1
+ ld [W_ANIMATIONID],a
+ call PlayAnimation
+ ld a,(SFX_08_43 - SFX_Headers_08) / 3
+ call PlaySound ; play sound effect
+ ld a,BLOCKBALL_ANIM
+ ld [W_ANIMATIONID],a
+ jp PlayAnimation
+
+Func_79e6a: ; 79e6a (1e:5e6a)
+ call WaitForSoundToFinish
+ ld a, [$d05b]
+ and $7f
+ ret z
+ cp $a
+ ld a, $20
+ ld b, $30
+ ld c, (SFX_08_50 - SFX_Headers_08) / 3
+ jr z, .asm_79e8b
+ ld a, $e0
+ ld b, $ff
+ ld c, (SFX_08_5a - SFX_Headers_08) / 3
+ jr nc, .asm_79e8b
+ ld a, $50
+ ld b, $1
+ ld c, (SFX_08_51 - SFX_Headers_08) / 3
+.asm_79e8b
+ ld [$c0f1], a
+ ld a, b
+ ld [$c0f2], a
+ ld a, c
+ jp PlaySound
diff --git a/engine/battle/b.asm b/engine/battle/b.asm
new file mode 100755
index 00000000..7269e48c
--- /dev/null
+++ b/engine/battle/b.asm
@@ -0,0 +1,18 @@
+DisplayEffectiveness: ; 2fb7b (b:7b7b)
+ ld a, [$D05B]
+ and a, $7F
+ cp a, $0A
+ ret z
+ ld hl, SupperEffectiveText
+ jr nc, .done
+ ld hl, NotVeryEffectiveText
+.done
+ jp PrintText
+
+SupperEffectiveText: ; 2fb8e (b:7b8e)
+ TX_FAR _SupperEffectiveText
+ db "@"
+
+NotVeryEffectiveText: ; 2fb93 (b:7b93)
+ TX_FAR _NotVeryEffectiveText
+ db "@"
diff --git a/engine/battle/b_2.asm b/engine/battle/b_2.asm
new file mode 100755
index 00000000..b71ca40d
--- /dev/null
+++ b/engine/battle/b_2.asm
@@ -0,0 +1,130 @@
+; scales both uncompressed sprite chunks by two in every dimension (creating 2x2 output pixels per input pixel)
+; assumes that input sprite chunks are 4x4 tiles, and the rightmost and bottommost 4 pixels will be ignored
+; resulting in a 7*7 tile output sprite chunk
+ScaleSpriteByTwo: ; 2fe40 (b:7e40)
+ ld de, S_SPRITEBUFFER1 + (4*4*8) - 5 ; last byte of input data, last 4 rows already skipped
+ ld hl, S_SPRITEBUFFER0 + SPRITEBUFFERSIZE - 1 ; end of destination buffer
+ call ScaleLastSpriteColumnByTwo ; last tile column is special case
+ call ScaleFirstThreeSpriteColumnsByTwo ; scale first 3 tile columns
+ ld de, S_SPRITEBUFFER2 + (4*4*8) - 5 ; last byte of input data, last 4 rows already skipped
+ ld hl, S_SPRITEBUFFER1 + SPRITEBUFFERSIZE - 1 ; end of destination buffer
+ call ScaleLastSpriteColumnByTwo ; last tile column is special case
+
+ScaleFirstThreeSpriteColumnsByTwo: ; 2fe55 (b:7e55)
+ ld b, $3 ; 3 tile columns
+.columnLoop
+ ld c, 4*8 - 4 ; $1c, 4 tiles minus 4 unused rows
+.columnInnerLoop
+ push bc
+ ld a, [de]
+ ld bc, -(7*8)+1 ; $ffc9, scale lower nybble and seek to previous output column
+ call ScalePixelsByTwo
+ ld a, [de]
+ dec de
+ swap a
+ ld bc, 7*8+1-2 ; $37, scale upper nybble and seek back to current output column and to the next 2 rows
+ call ScalePixelsByTwo
+ pop bc
+ dec c
+ jr nz, .columnInnerLoop
+ dec de
+ dec de
+ dec de
+ dec de
+ ld a, b
+ ld bc, -7*8 ; $ffc8, skip one output column (which has already been written along with the current one)
+ add hl, bc
+ ld b, a
+ dec b
+ jr nz, .columnLoop
+ ret
+
+ScaleLastSpriteColumnByTwo: ; 2fe7d (b:7e7d)
+ ld a, 4*8 - 4 ; $1c, 4 tiles minus 4 unused rows
+ ld [H_SPRITEINTERLACECOUNTER], a ; $ff8b
+ ld bc, -1 ; $ffff
+.columnInnerLoop
+ ld a, [de]
+ dec de
+ swap a ; only high nybble contains information
+ call ScalePixelsByTwo
+ ld a, [H_SPRITEINTERLACECOUNTER] ; $ff8b
+ dec a
+ ld [H_SPRITEINTERLACECOUNTER], a ; $ff8b
+ jr nz, .columnInnerLoop
+ dec de ; skip last 4 rows of new column
+ dec de
+ dec de
+ dec de
+ ret
+
+; scales the given 4 bits in a (4x1 pixels) to 2 output bytes (8x2 pixels)
+; hl: destination pointer
+; bc: destination pointer offset (added after the two bytes have been written)
+ScalePixelsByTwo: ; 2fe97 (b:7e97)
+ push hl
+ and $f
+ ld hl, DuplicateBitsTable
+ add l
+ ld l, a
+ jr nc, .noCarry
+ inc h
+.noCarry
+ ld a, [hl]
+ pop hl
+ ld [hld], a ; write output byte twice to make it 2 pixels high
+ ld [hl], a
+ add hl, bc ; add offset
+ ret
+
+; repeats each input bit twice
+DuplicateBitsTable: ; 2fea8 (b:7ea8)
+ db $00, $03, $0c, $0f
+ db $30, $33, $3c, $3f
+ db $c0, $c3, $cc, $cf
+ db $f0, $f3, $fc, $ff
+
+PayDayEffect_ ; 2feb8 (b:7eb8)
+ xor a
+ ld hl, $cd6d
+ ld [hli], a
+ ld a, [$fff3]
+ and a
+ ld a, [$d022]
+ jr z, .asm_2fec8 ; 0x2fec3 $3
+ ld a, [$cff3]
+.asm_2fec8
+ add a
+ ld [$ff98], a
+ xor a
+ ld [$ff95], a
+ ld [$ff96], a
+ ld [$ff97], a
+ ld a, $64
+ ld [$ff99], a
+ ld b, $4
+ call Divide
+ ld a, [$ff98]
+ ld [hli], a
+ ld a, [$ff99]
+ ld [$ff98], a
+ ld a, $a
+ ld [$ff99], a
+ ld b, $4
+ call Divide
+ ld a, [$ff98]
+ swap a
+ ld b, a
+ ld a, [$ff99]
+ add b
+ ld [hl], a
+ ld de, $cce7
+ ld c, $3
+ ld a, $b
+ call Predef
+ ld hl, CoinsScatteredText ; $7f04
+ jp PrintText
+
+CoinsScatteredText: ; 2ff04 (b:7f04)
+ TX_FAR _CoinsScatteredText
+ db "@"
diff --git a/engine/battle/c.asm b/engine/battle/c.asm
new file mode 100755
index 00000000..b93cc273
--- /dev/null
+++ b/engine/battle/c.asm
@@ -0,0 +1,58 @@
+MistEffect_: ; 33f2b (c:7f2b)
+ ld hl, W_PLAYERBATTSTATUS2
+ ld a, [$fff3]
+ and a
+ jr z, .asm_33f36
+ ld hl, W_ENEMYBATTSTATUS2
+.asm_33f36
+ bit 1, [hl] ; is mon protected by mist?
+ jr nz, .asm_33f4a
+ set 1, [hl] ; mon is now protected by mist
+ callab Func_3fba8
+ ld hl, ShroudedInMistText
+ jp PrintText
+.asm_33f4a
+ ld hl, PrintButItFailedText_
+ ld b, BANK(PrintButItFailedText_)
+ jp Bankswitch
+
+ShroudedInMistText: ; 33f52 (c:7f52)
+ TX_FAR _ShroudedInMistText
+ db "@"
+
+OneHitKOEffect_: ; 33f57 (c:7f57)
+ ld hl, W_DAMAGE ; $d0d7
+ xor a
+ ld [hli], a
+ ld [hl], a ; set the damage output to zero
+ dec a
+ ld [$d05e], a
+ ld hl, $d02a
+ ld de, $cffb
+ ld a, [H_WHOSETURN] ; $fff3
+ and a
+ jr z, .asm_33f72
+ ld hl, $cffb
+ ld de, $d02a
+.asm_33f72
+ ld a, [de]
+ dec de
+ ld b, a
+ ld a, [hld]
+ sub b
+ ld a, [de]
+ ld b, a
+ ld a, [hl]
+ sbc b
+ jr c, .asm_33f8a
+ ld hl, W_DAMAGE ; $d0d7
+ ld a, $ff
+ ld [hli], a
+ ld [hl], a
+ ld a, $2
+ ld [$d05e], a
+ ret
+.asm_33f8a
+ ld a, $1
+ ld [W_MOVEMISSED], a ; $d05f
+ ret
diff --git a/engine/battle/core.asm b/engine/battle/core.asm
new file mode 100755
index 00000000..a19919f4
--- /dev/null
+++ b/engine/battle/core.asm
@@ -0,0 +1,8547 @@
+BattleCore:
+
+; These are move effects (second value from the Moves table in bank $E).
+EffectsArray1: ; 3c000 (f:4000)
+ db CONVERSION_EFFECT
+ db HAZE_EFFECT
+ db SWITCH_AND_TELEPORT_EFFECT
+ db MIST_EFFECT
+ db FOCUS_ENERGY_EFFECT
+ db CONFUSION_EFFECT
+ db HEAL_EFFECT
+ db TRANSFORM_EFFECT
+ db LIGHT_SCREEN_EFFECT
+ db REFLECT_EFFECT
+ db POISON_EFFECT
+ db PARALYZE_EFFECT
+ db SUBSTITUTE_EFFECT
+ db MIMIC_EFFECT
+ db LEECH_SEED_EFFECT
+ db SPLASH_EFFECT
+ db -1
+EffectsArray2: ; 3c011 (f:4011)
+; moves that do damage but not through normal calculations
+; e.g., Super Fang, Psywave
+ db SUPER_FANG_EFFECT
+ db SPECIAL_DAMAGE_EFFECT
+ db -1
+EffectsArray3: ; 3c014 (f:4014)
+; non-damaging, stat‐affecting or status‐causing moves?
+; e.g., Meditate, Bide, Hypnosis
+ db $01
+ db ATTACK_UP1_EFFECT
+ db DEFENSE_UP1_EFFECT
+ db SPEED_UP1_EFFECT
+ db SPECIAL_UP1_EFFECT
+ db ACCURACY_UP1_EFFECT
+ db EVASION_UP1_EFFECT
+ db ATTACK_DOWN1_EFFECT
+ db DEFENSE_DOWN1_EFFECT
+ db SPEED_DOWN1_EFFECT
+ db SPECIAL_DOWN1_EFFECT
+ db ACCURACY_DOWN1_EFFECT
+ db EVASION_DOWN1_EFFECT
+ db BIDE_EFFECT
+ db SLEEP_EFFECT
+ db ATTACK_UP2_EFFECT
+ db DEFENSE_UP2_EFFECT
+ db SPEED_UP2_EFFECT
+ db SPECIAL_UP2_EFFECT
+ db ACCURACY_UP2_EFFECT
+ db EVASION_UP2_EFFECT
+ db ATTACK_DOWN2_EFFECT
+ db DEFENSE_DOWN2_EFFECT
+ db SPEED_DOWN2_EFFECT
+ db SPECIAL_DOWN2_EFFECT
+ db ACCURACY_DOWN2_EFFECT
+ db EVASION_DOWN2_EFFECT
+ db -1
+EffectsArray4: ; 3c030 (f:4030)
+; Attacks that aren't finished after they faint the opponent.
+ db DRAIN_HP_EFFECT
+ db EXPLODE_EFFECT
+ db DREAM_EATER_EFFECT
+ db PAY_DAY_EFFECT
+ db TWO_TO_FIVE_ATTACKS_EFFECT
+ db $1E
+ db ATTACK_TWICE_EFFECT
+ db RECOIL_EFFECT
+ db TWINEEDLE_EFFECT
+ db RAGE_EFFECT
+ db -1
+EffectsArray5: ; 3c03b (f:403b)
+ db DRAIN_HP_EFFECT
+ db EXPLODE_EFFECT
+ db DREAM_EATER_EFFECT
+ db PAY_DAY_EFFECT
+ db SWIFT_EFFECT
+ db TWO_TO_FIVE_ATTACKS_EFFECT
+ db $1E
+ db CHARGE_EFFECT
+ db SUPER_FANG_EFFECT
+ db SPECIAL_DAMAGE_EFFECT
+ db FLY_EFFECT
+ db ATTACK_TWICE_EFFECT
+ db JUMP_KICK_EFFECT
+ db RECOIL_EFFECT
+ ; fallthrough to Next EffectsArray
+EffectsArray5B: ; 3c049 (f:4049)
+; moves that prevent the player from switching moves?
+ db THRASH_PETAL_DANCE_EFFECT
+ db TRAPPING_EFFECT
+ db -1
+
+Func_3c04c: ; 3c04c (f:404c)
+ call Func_3ec92
+ ld a, $1
+ ld [$d125], a
+ call DisplayTextBoxID
+ FuncCoord 1, 5 ; $c405
+ ld hl, Coord
+ ld bc, $307
+ call ClearScreenArea
+ call DisableLCD
+ call LoadFontTilePatterns
+ call Func_3ee58
+ ld hl, $9800
+ ld bc, $400
+.asm_3c06f
+ ld a, $7f
+ ld [hli], a
+ dec bc
+ ld a, b
+ or c
+ jr nz, .asm_3c06f
+ ld hl, wTileMap
+ ld de, $9800
+ ld b, $12
+.asm_3c07f
+ ld c, $14
+.asm_3c081
+ ld a, [hli]
+ ld [de], a
+ inc e
+ dec c
+ jr nz, .asm_3c081
+ ld a, $c
+ add e
+ ld e, a
+ jr nc, .asm_3c08e
+ inc d
+.asm_3c08e
+ dec b
+ jr nz, .asm_3c07f
+ call EnableLCD
+ ld a, $90
+ ld [$ffb0], a
+ ld [rWY], a ; $ff4a
+ xor a
+ ld [$ffd7], a
+ ld [$ffaf], a
+ dec a
+ ld [$cfcb], a
+ call Delay3
+ xor a
+ ld [H_AUTOBGTRANSFERENABLED], a ; $ffba
+ ld b, $70
+ ld c, $90
+ ld a, c
+ ld [$ffae], a
+ call DelayFrame
+ ld a, $e4
+ ld [rBGP], a ; $ff47
+ ld [rOBP0], a ; $ff48
+ ld [rOBP1], a ; $ff49
+.asm_3c0bb
+ ld h, b
+ ld l, $40
+ call Func_3c110
+ inc b
+ inc b
+ ld h, $0
+ ld l, $60
+ call Func_3c110
+ call Func_3c0ff
+ ld a, c
+ ld [$ffae], a
+ dec c
+ dec c
+ jr nz, .asm_3c0bb
+ ld a, $1
+ ld [H_AUTOBGTRANSFERENABLED], a ; $ffba
+ ld a, $31
+ ld [$ffe1], a
+ FuncCoord 1, 5 ; $c405
+ ld hl, Coord
+ ld a, $1
+ call Predef ; indirect jump to Func_3f0c6 (3f0c6 (f:70c6))
+ xor a
+ ld [$ffb0], a
+ ld [rWY], a ; $ff4a
+ inc a
+ ld [H_AUTOBGTRANSFERENABLED], a ; $ffba
+ call Delay3
+ ld b, $1
+ call GoPAL_SET
+ call ResetLCD_OAM
+ ld hl, PrintBeginningBattleText
+ ld b, BANK(PrintBeginningBattleText)
+ jp Bankswitch
+
+Func_3c0ff: ; 3c0ff (f:40ff)
+ push bc
+ ld hl, $c301
+ ld c, $15
+ ld de, $4
+.asm_3c108
+ dec [hl]
+ dec [hl]
+ add hl, de
+ dec c
+ jr nz, .asm_3c108
+ pop bc
+ ret
+
+Func_3c110: ; 3c110 (f:4110)
+ ld a, [$ff44]
+ cp l
+ jr nz, Func_3c110
+ ld a, h
+ ld [rSCX], a ; $ff43
+.asm_3c118
+ ld a, [$ff44]
+ cp h
+ jr z, .asm_3c118
+ ret
+
+Func_3c11e: ; 3c11e (f:411e)
+ xor a
+ ld [W_PLAYERMONSALIVEFLAGS], a
+ ld [$ccf5], a
+ ld [$cd6a], a
+ inc a
+ ld [$d11d], a
+ ld hl, W_ENEMYMON1HP ; $d8a5
+ ld bc, $2b
+ ld d, $3
+.asm_3c134
+ inc d
+ ld a, [hli]
+ or [hl]
+ jr nz, .asm_3c13c
+ add hl, bc
+ jr .asm_3c134
+.asm_3c13c
+ ld a, d
+ ld [$cc3e], a
+ ld a, [W_ISINBATTLE] ; $d057
+ dec a
+ call nz, Func_3c92a
+ ld c, $28
+ call DelayFrames
+ call SaveScreenTilesToBuffer1
+.asm_3c14f
+ call AnyPlayerPokemonAliveCheck
+ ld a, d
+ and a
+ jp z, HandlePlayerBlackOut
+ call LoadScreenTilesFromBuffer1
+ ld a, [W_BATTLETYPE] ; $d05a
+ and a
+ jp z, Func_3c1ad
+.asm_3c161
+ call InitBattleMenu
+ ret c
+ ld a, [$cd6a]
+ and a
+ jr z, .asm_3c161
+ ld a, [W_NUMSAFARIBALLS] ; $da47
+ and a
+ jr nz, .asm_3c17a
+ call LoadScreenTilesFromBuffer1
+ ld hl, OutOfSafariBallsText
+ jp PrintText
+.asm_3c17a
+ callab PrintSafariZoneBattleText
+ ld a, [$cffb]
+ add a
+ ld b, a
+ jp c, asm_3c202
+ ld a, [$cce9]
+ and a
+ jr z, .asm_3c194
+ srl b
+ srl b
+.asm_3c194
+ ld a, [$cce8]
+ and a
+ jr z, .asm_3c1a0
+ sla b
+ jr nc, .asm_3c1a0
+ ld b, $ff
+.asm_3c1a0
+ call GenRandom
+ cp b
+ jr nc, .asm_3c14f
+ jr asm_3c202
+
+OutOfSafariBallsText: ; 3c1a8 (f:41a8)
+ TX_FAR _OutOfSafariBallsText
+ db "@"
+
+Func_3c1ad: ; 3c1ad (f:41ad)
+ xor a
+ ld [wWhichPokemon], a ; $cf92
+.asm_3c1b1
+ call Func_3ca97
+ jr nz, .asm_3c1bc
+ ld hl, wWhichPokemon ; $cf92
+ inc [hl]
+ jr .asm_3c1b1
+.asm_3c1bc
+ ld a, [wWhichPokemon] ; $cf92
+ ld [wPlayerMonNumber], a ; $cc2f
+ inc a
+ ld hl, W_NUMINPARTY ; $d163
+ ld c, a
+ ld b, $0
+ add hl, bc
+ ld a, [hl]
+ ld [$cf91], a
+ ld [$cfd9], a
+ call LoadScreenTilesFromBuffer1
+ FuncCoord 1, 5 ; $c405
+ ld hl, Coord
+ ld a, $9
+ call Func_3c8df
+ call SaveScreenTilesToBuffer1
+ ld a, [wWhichPokemon] ; $cf92
+ ld c, a
+ ld b, $1
+ push bc
+ ld hl, W_PLAYERMONSALIVEFLAGS
+ ld a, $10
+ call Predef ; indirect jump to HandleBitArray (f666 (3:7666))
+ ld hl, $ccf5
+ pop bc
+ ld a, $10
+ call Predef ; indirect jump to HandleBitArray (f666 (3:7666))
+ call Func_3cba6
+ call LoadScreenTilesFromBuffer1
+ call Func_3cc91
+ jr MainInBattleLoop
+asm_3c202: ; 3c202 (f:4202)
+ call LoadScreenTilesFromBuffer1
+ ld a, [W_ISLINKBATTLE] ; $d12b
+ cp $4
+ ld hl, WildRanText
+ jr nz, .asm_3c216
+ xor a
+ ld [$cf0b], a
+ ld hl, EnemyRanText
+.asm_3c216
+ call PrintText
+ ld a, (SFX_08_44 - SFX_Headers_08) / 3
+ call PlaySoundWaitForCurrent
+ xor a
+ ld [H_WHOSETURN], a ; $fff3
+ ld hl, AnimationSlideEnemyMonOut
+ ld b, BANK(AnimationSlideEnemyMonOut)
+ jp Bankswitch
+
+WildRanText: ; 3c229 (f:4229)
+ TX_FAR _WildRanText
+ db "@"
+
+EnemyRanText: ; 3c22e (f:422e)
+ TX_FAR _EnemyRanText
+ db "@"
+
+MainInBattleLoop: ; 3c233 (f:4233)
+ call ReadPlayerMonCurHPAndStatus
+ ld hl, W_PLAYERMONCURHP
+ ld a, [hli]
+ or [hl]
+ jp z, HandlePlayerMonFainted ; test if current player mon is fainted
+ ld hl, $cfe6
+ ld a, [hli]
+ or [hl]
+ jp z, HandleEnemyMonFainted
+ call SaveScreenTilesToBuffer1
+ xor a
+ ld [$d11d], a
+ ld a, [$d063]
+ and $60
+ jr nz, .asm_3c2a6 ; 0x3c252 $52
+ ld hl, $d067
+ res 3, [hl]
+ ld hl, $d062
+ res 3, [hl]
+ ld a, [hl]
+ and $12
+ jr nz, .asm_3c2a6 ; 0x3c261 $43
+ call InitBattleMenu ; show battle menu
+ ret c
+ ld a, [$d078]
+ and a
+ ret nz
+ ld a, [$d018]
+ and $27
+ jr nz, .asm_3c2a6 ; 0x3c271 $33
+ ld a, [$d062]
+ and $21
+ jr nz, .asm_3c2a6 ; 0x3c278 $2c
+ ld a, [$d067]
+ bit 5, a
+ jr z, .asm_3c288 ; 0x3c27f $7
+ ld a, $ff
+ ld [$ccdc], a
+ jr .asm_3c2a6 ; 0x3c286 $1e
+.asm_3c288
+ ld a, [$cd6a]
+ and a
+ jr nz, .asm_3c2a6 ; 0x3c28c $18
+ ld [$ccdb], a
+ inc a
+ ld [$d07c], a
+ xor a
+ ld [$cc35], a
+ call MoveSelectionMenu
+ push af
+ call LoadScreenTilesFromBuffer1
+ call Func_3cd5a
+ pop af
+ jr nz, MainInBattleLoop
+.asm_3c2a6
+ call SelectEnemyMove
+ ld a, [W_ISLINKBATTLE]
+ cp $4
+ jr nz, .noLinkBattle
+ ld a, [$cc3e]
+ cp $f
+ jp z, asm_3c202
+ cp $e
+ jr z, .noLinkBattle
+ cp $d
+ jr z, .noLinkBattle
+ sub $4
+ jr c, .noLinkBattle
+ ld a, [$d062]
+ bit 5, a
+ jr z, .asm_3c2dd ; 0x3c2c9 $12
+ ld a, [$cc2e]
+ ld hl, W_PLAYERMONMOVES
+ ld c, a
+ ld b, $0
+ add hl, bc
+ ld a, [hl]
+ cp $76
+ jr nz, .asm_3c2dd ; 0x3c2d8 $3
+ ld [wPlayerSelectedMove], a
+.asm_3c2dd
+ callab Func_3a74b
+.noLinkBattle
+ ld a, [wPlayerSelectedMove]
+ cp QUICK_ATTACK
+ jr nz, .playerDidNotUseQuickAttack
+ ld a, [wEnemySelectedMove]
+ cp QUICK_ATTACK
+ jr z, .compareSpeed ; both used Quick Attack
+ jp .playerMovesFirst ; player used Quick Attack
+.playerDidNotUseQuickAttack
+ ld a, [wEnemySelectedMove]
+ cp QUICK_ATTACK
+ jr z, .enemyMovesFirst
+ ld a, [wPlayerSelectedMove]
+ cp COUNTER
+ jr nz, .playerDidNotUseCounter
+ ld a, [wEnemySelectedMove]
+ cp COUNTER
+ jr z, .compareSpeed ; both used Counter
+ jr .enemyMovesFirst ; player used Counter
+.playerDidNotUseCounter
+ ld a, [wEnemySelectedMove]
+ cp COUNTER
+ jr z, .playerMovesFirst
+.compareSpeed
+ ld de, W_PLAYERMONSPEED ; player speed value
+ ld hl, W_ENEMYMONSPEED ; enemy speed value
+ ld c, $2
+ call StringCmp ; compare speed values
+ jr z, .speedEqual
+ jr nc, .playerMovesFirst
+ jr .enemyMovesFirst
+.speedEqual
+ ld a, [$ffaa]
+ cp $2
+ jr z, .invertOutcome
+ call GenRandomInBattle
+ cp $80
+ jr c, .playerMovesFirst
+ jr .enemyMovesFirst
+.invertOutcome
+ call GenRandomInBattle
+ cp $80
+ jr c, .enemyMovesFirst
+ jr .playerMovesFirst
+.enemyMovesFirst
+ ld a, $1
+ ld [H_WHOSETURN], a
+ callab TrainerAI
+ jr c, .AIActionUsedEnemyFirst
+ call Func_3e6bc ; execute enemy move
+ ld a, [$d078]
+ and a
+ ret nz
+ ld a, b
+ and a
+ jp z, HandlePlayerMonFainted
+.AIActionUsedEnemyFirst
+ call HandlePoisonBurnLeechSeed
+ jp z, HandleEnemyMonFainted
+ call Func_3cd5a
+ call Func_3d65e ; execute player move
+ ld a, [$d078]
+ and a
+ ret nz
+ ld a, b
+ and a
+ jp z, HandleEnemyMonFainted
+ call HandlePoisonBurnLeechSeed
+ jp z, HandlePlayerMonFainted
+ call Func_3cd5a
+ call Func_3c50f
+ jp MainInBattleLoop
+.playerMovesFirst
+ call Func_3d65e ; execute player move
+ ld a, [$d078]
+ and a
+ ret nz
+ ld a, b
+ and a
+ jp z, HandleEnemyMonFainted
+ call HandlePoisonBurnLeechSeed
+ jp z, HandlePlayerMonFainted
+ call Func_3cd5a
+ ld a, $1
+ ld [H_WHOSETURN], a
+ callab TrainerAI
+ jr c, .AIActionUsedPlayerFirst
+ call Func_3e6bc ; execute enemy move
+ ld a, [$d078]
+ and a
+ ret nz
+ ld a, b
+ and a
+ jp z, HandlePlayerMonFainted
+.AIActionUsedPlayerFirst
+ call HandlePoisonBurnLeechSeed
+ jp z, HandleEnemyMonFainted
+ call Func_3cd5a
+ call Func_3c50f
+ jp MainInBattleLoop
+
+HandlePoisonBurnLeechSeed: ; 3c3bd (f:43bd)
+ ld hl, W_PLAYERMONCURHP ; $d015
+ ld de, W_PLAYERMONSTATUS ; $d018
+ ld a, [H_WHOSETURN] ; $fff3
+ and a
+ jr z, .playersTurn
+ ld hl, W_ENEMYMONCURHP ; $cfe6
+ ld de, W_ENEMYMONSTATUS ; $cfe9
+.playersTurn
+ ld a, [de]
+ and (1 << BRN) | (1 << PSN)
+ jr z, .notBurnedOrPoisoned
+ push hl
+ ld hl, HurtByPoisonText
+ ld a, [de]
+ and 1 << BRN
+ jr z, .poisoned
+ ld hl, HurtByBurnText
+.poisoned
+ call PrintText
+ xor a
+ ld [$cc5b], a
+ ld a,BURN_PSN_ANIM
+ call PlayMoveAnimation ; play burn/poison animation
+ pop hl
+ call HandlePoisonBurnLeechSeed_DecreaseOwnHP
+.notBurnedOrPoisoned
+ ld de, W_PLAYERBATTSTATUS2 ; $d063
+ ld a, [H_WHOSETURN] ; $fff3
+ and a
+ jr z, .playersTurn2
+ ld de, W_ENEMYBATTSTATUS2 ; $d068
+.playersTurn2
+ ld a, [de]
+ add a
+ jr nc, .notLeechSeeded
+ push hl
+ ld a, [H_WHOSETURN] ; $fff3
+ push af
+ xor $1
+ ld [H_WHOSETURN], a ; $fff3
+ xor a
+ ld [$cc5b], a
+ ld a,ABSORB
+ call PlayMoveAnimation ; play leech seed animation (from opposing mon)
+ pop af
+ ld [H_WHOSETURN], a ; $fff3
+ pop hl
+ call HandlePoisonBurnLeechSeed_DecreaseOwnHP
+ call HandlePoisonBurnLeechSeed_IncreaseEnemyHP
+ push hl
+ ld hl, HurtByLeechSeedText
+ call PrintText
+ pop hl
+.notLeechSeeded
+ ld a, [hli]
+ or [hl]
+ ret nz ; test if fainted
+ call Func_3cd5a
+ ld c, $14
+ call DelayFrames
+ xor a
+ ret
+
+HurtByPoisonText: ; 3c42e (f:442e)
+ TX_FAR _HurtByPoisonText
+ db "@"
+
+HurtByBurnText: ; 3c433 (f:4433)
+ TX_FAR _HurtByBurnText
+ db "@"
+
+HurtByLeechSeedText: ; 3c438 (f:4438)
+ TX_FAR _HurtByLeechSeedText
+ db "@"
+
+; decreases the mon's current HP by 1/16 of the Max HP (multiplied by number of toxic ticks if active)
+; note that the toxic ticks are considered even if the damage is not poison (hence the Leech Seed glitch)
+; hl: HP pointer
+; bc (out): total damage
+HandlePoisonBurnLeechSeed_DecreaseOwnHP: ; 3c43d (f:443d)
+ push hl
+ push hl
+ ld bc, $e ; skip to max HP
+ add hl, bc
+ ld a, [hli] ; load max HP
+ ld [wHPBarMaxHP+1], a
+ ld b, a
+ ld a, [hl]
+ ld [wHPBarMaxHP], a
+ ld c, a
+ srl b
+ rr c
+ srl b
+ rr c
+ srl c
+ srl c ; c = max HP/16 (assumption: HP < 1024)
+ ld a, c
+ and a
+ jr nz, .nonZeroDamage
+ inc c ; damage is at least 1
+.nonZeroDamage
+ ld hl, W_PLAYERBATTSTATUS3 ; $d064
+ ld de, W_PLAYERTOXICCOUNTER ; $d06c
+ ld a, [H_WHOSETURN] ; $fff3
+ and a
+ jr z, .playersTurn
+ ld hl, W_ENEMYBATTSTATUS3 ; $d069
+ ld de, W_ENEMYTOXICCOUNTER ; $d071
+.playersTurn
+ bit 0, [hl]
+ jr z, .noToxic
+ ld a, [de] ; increment toxic counter
+ inc a
+ ld [de], a
+ ld hl, $0000
+.toxicTicksLoop
+ add hl, bc
+ dec a
+ jr nz, .toxicTicksLoop
+ ld b, h ; bc = damage * toxic counter
+ ld c, l
+.noToxic
+ pop hl
+ inc hl
+ ld a, [hl] ; subtract total damage from current HP
+ ld [wHPBarOldHP], a
+ sub c
+ ld [hld], a
+ ld [wHPBarNewHP], a
+ ld a, [hl]
+ ld [wHPBarOldHP+1], a
+ sbc b
+ ld [hl], a
+ ld [wHPBarNewHP+1], a
+ jr nc, .noOverkill
+ xor a ; overkill: zero HP
+ ld [hli], a
+ ld [hl], a
+ ld [wHPBarNewHP], a
+ ld [wHPBarNewHP+1], a
+.noOverkill
+ call UpdateCurMonHPBar
+ pop hl
+ ret
+
+; adds bc to enemy HP
+HandlePoisonBurnLeechSeed_IncreaseEnemyHP: ; 3c4a3 (f:44a3)
+ push hl
+ ld hl, W_ENEMYMONMAXHP ; $cff4
+ ld a, [H_WHOSETURN] ; $fff3
+ and a
+ jr z, .playersTurn
+ ld hl, W_PLAYERMONMAXHP ; $d023
+.playersTurn
+ ld a, [hli]
+ ld [wHPBarMaxHP+1], a
+ ld a, [hl]
+ ld [wHPBarMaxHP], a
+ ld de, $fff2
+ add hl, de ; skip back fomr max hp to current hp
+ ld a, [hl]
+ ld [wHPBarOldHP], a ; add bc to current HP
+ add c
+ ld [hld], a
+ ld [wHPBarNewHP], a
+ ld a, [hl]
+ ld [wHPBarOldHP+1], a
+ adc b
+ ld [hli], a
+ ld [wHPBarNewHP+1], a
+ ld a, [wHPBarMaxHP]
+ ld c, a
+ ld a, [hld]
+ sub c
+ ld a, [wHPBarMaxHP+1]
+ ld b, a
+ ld a, [hl]
+ sbc b
+ jr c, .noOverfullHeal
+ ld a, b ; overfull heal, set HP to max HP
+ ld [hli], a
+ ld [wHPBarNewHP+1], a
+ ld a, c
+ ld [hl], a
+ ld [wHPBarNewHP], a
+.noOverfullHeal
+ ld a, [H_WHOSETURN] ; $fff3
+ xor $1
+ ld [H_WHOSETURN], a ; $fff3
+ call UpdateCurMonHPBar
+ ld a, [H_WHOSETURN] ; $fff3
+ xor $1
+ ld [H_WHOSETURN], a ; $fff3
+ pop hl
+ ret
+
+UpdateCurMonHPBar: ; 3c4f6 (f:44f6)
+ FuncCoord 10, 9 ; $c45e
+ ld hl, Coord ; tile pointer to player HP bar
+ ld a, [H_WHOSETURN] ; $fff3
+ and a
+ ld a, $1
+ jr z, .playersTurn
+ FuncCoord 2, 2 ; $c3ca
+ ld hl, Coord ; tile pointer to enemy HP bar
+ xor a
+.playersTurn
+ push bc
+ ld [wListMenuID], a ; $cf94
+ ld a, $48
+ call Predef ; indirect jump to UpdateHPBar (fa1d (3:7a1d))
+ pop bc
+ ret
+
+Func_3c50f: ; 3c50f (f:450f)
+ ld a, [$d06a]
+ and a
+ jr nz, .asm_3c51a
+ ld hl, W_PLAYERBATTSTATUS1 ; $d062
+ res 5, [hl]
+.asm_3c51a
+ ld a, [$d06f]
+ and a
+ ret nz
+ ld hl, W_ENEMYBATTSTATUS1 ; $d067
+ res 5, [hl]
+ ret
+
+HandleEnemyMonFainted: ; 3c525 (f:4525)
+ xor a
+ ld [$ccf0], a
+ call FaintEnemyPokemon
+ call AnyPlayerPokemonAliveCheck
+ ld a, d
+ and a
+ jp z, HandlePlayerBlackOut
+ ld hl, W_PLAYERMONCURHP ; $d015
+ ld a, [hli]
+ or [hl]
+ call nz, Func_3cd60
+ ld a, [W_ISINBATTLE] ; $d057
+ dec a
+ ret z
+ call AnyEnemyPokemonAliveCheck
+ jp z, TrainerBattleVictory
+ ld hl, W_PLAYERMONCURHP ; $d015
+ ld a, [hli]
+ or [hl]
+ jr nz, .asm_3c555
+ call Func_3c79b
+ ret c
+ call Func_3c7d8
+.asm_3c555
+ ld a, $1
+ ld [$cd6a], a
+ call Func_3c664
+ jp z, asm_3c202
+ xor a
+ ld [$cd6a], a
+ jp MainInBattleLoop
+
+FaintEnemyPokemon ; 0x3c567
+ call ReadPlayerMonCurHPAndStatus
+ ld a, [W_ISINBATTLE] ; $d057
+ dec a
+ jr z, .wild
+ ld a, [W_ENEMYMONNUMBER] ; $cfe8
+ ld hl, W_ENEMYMON1HP
+ ld bc, $2c ; mon struct len
+ call AddNTimes
+ xor a
+ ld [hli], a
+ ld [hl], a
+.wild
+ ld hl, W_PLAYERBATTSTATUS1 ; $d062
+ res 2, [hl]
+ xor a
+ ld [W_NUMHITS], a ; $d074
+ ld hl, $d065 ; enemy statuses
+ ld [hli], a
+ ld [hli], a
+ ld [hli], a
+ ld [hli], a
+ ld [hl], a
+ ld [W_ENEMYDISABLEDMOVE], a ; $d072
+ ld [$ccef], a
+ ld [$ccf3], a
+ ld hl, $ccf1
+ ld [hli], a
+ ld [hl], a
+ FuncCoord 12, 5 ; $c410
+ ld hl, Coord
+ FuncCoord 12, 6 ; $c424
+ ld de, Coord
+ call Func_3c893
+ ld hl, wTileMap
+ ld bc, $40b
+ call ClearScreenArea
+ ld a, [W_ISINBATTLE] ; $d057
+ dec a
+ jr z, .wild_win
+ xor a
+ ld [$c0f1], a
+ ld [$c0f2], a
+ ld a, (SFX_08_48 - SFX_Headers_08) / 3 ; SFX_FALL?
+ call PlaySoundWaitForCurrent
+.sfxwait
+ ld a, [$c02a]
+ cp (SFX_08_48 - SFX_Headers_08) / 3
+ jr z, .sfxwait
+ ld a, (SFX_08_43 - SFX_Headers_08) / 3 ; SFX_DROP
+ call PlaySound
+ call WaitForSoundToFinish
+ jr .sfxplayed
+.wild_win
+ call Func_3c643
+ ld a, MUSIC_DEFEATED_WILD_MON
+ call PlayBattleVictoryMusic
+.sfxplayed
+ ld hl, W_PLAYERMONCURHP ; $d015
+ ld a, [hli]
+ or [hl]
+ jr nz, .playermonnotfaint
+ ld a, [$ccf0]
+ and a
+ jr nz, .playermonnotfaint
+ call Func_3c741
+.playermonnotfaint
+ call AnyPlayerPokemonAliveCheck
+ ld a, d
+ and a
+ ret z
+ ld hl, EnemyMonFaintedText
+ call PrintText
+ call Func_3ee94
+ call SaveScreenTilesToBuffer1
+ xor a
+ ld [$cf0b], a
+ ld b, EXP__ALL
+ call IsItemInBag
+ push af
+ jr z, .no_exp_all
+ ld hl, $d002
+ ld b, $7
+.exp_all_loop
+ srl [hl]
+ inc hl
+ dec b
+ jr nz, .exp_all_loop
+.no_exp_all
+ xor a
+ ld [$cc5b], a
+ callab GainExperience
+ pop af
+ ret z
+ ld a, $1
+ ld [$cc5b], a
+ ld a, [W_NUMINPARTY] ; $d163
+ ld b, $0
+.asm_3c62c
+ scf
+ rl b
+ dec a
+ jr nz, .asm_3c62c
+ ld a, b
+ ld [W_PLAYERMONSALIVEFLAGS], a
+ ld hl, GainExperience
+ ld b, BANK(GainExperience)
+ jp Bankswitch
+
+EnemyMonFaintedText: ; 0x3c63e
+ TX_FAR _EnemyMonFaintedText
+ db "@"
+
+Func_3c643: ; 3c643 (f:4643)
+ xor a
+ ld [$d083], a
+ ld [$c02a], a
+ inc a
+ ld [$ccf6], a
+ ret
+
+AnyEnemyPokemonAliveCheck: ; 3c64f (f:464f)
+ ld a, [wEnemyPartyCount] ; $d89c
+ ld b, a
+ xor a
+ ld hl, W_ENEMYMON1HP ; $d8a5
+ ld de, $2c
+.asm_3c65a
+ or [hl]
+ inc hl
+ or [hl]
+ dec hl
+ add hl, de
+ dec b
+ jr nz, .asm_3c65a
+ and a
+ ret
+
+Func_3c664: ; 3c664 (f:4664)
+ ld hl, $cf1e
+ ld e, $30
+ call GetBattleHealthBarColor
+ callab DrawEnemyPokeballs
+ ld a, [W_ISLINKBATTLE] ; $d12b
+ cp $4
+ jr nz, .asm_3c687
+ call Func_3d605
+ ld a, [$cc3e]
+ cp $f
+ ret z
+ call LoadScreenTilesFromBuffer1
+.asm_3c687
+ call EnemySendOut
+ xor a
+ ld [W_ENEMYMOVENUM], a ; $cfcc
+ ld [$cd6a], a
+ ld [$ccd5], a
+ inc a
+ ret
+
+TrainerBattleVictory: ; 3c696 (f:4696)
+ call Func_3c643
+ ld b, MUSIC_DEFEATED_GYM_LEADER
+ ld a, [W_GYMLEADERNO] ; $d05c
+ and a
+ jr nz, .gymleader
+ ld b, MUSIC_DEFEATED_TRAINER
+.gymleader
+ ld a, [W_TRAINERCLASS] ; $d031
+ cp SONY3 ; final battle against rival
+ jr nz, .notrival
+ ld b, MUSIC_DEFEATED_GYM_LEADER
+ ld hl, W_FLAGS_D733
+ set 1, [hl]
+.notrival
+ ld a, [W_ISLINKBATTLE] ; $d12b
+ cp $4
+ ld a, b
+ call nz, PlayBattleVictoryMusic
+ ld hl, TrainerDefeatedText
+ call PrintText
+ ld a, [W_ISLINKBATTLE] ; $d12b
+ cp $4
+ ret z
+ call ScrollTrainerPicAfterBattle
+ ld c, $28
+ call DelayFrames
+ call Func_3381
+ ld hl, MoneyForWinningText
+ call PrintText
+ ld de, wPlayerMoney + 2 ; $d349
+ ld hl, $d07b
+ ld c, $3
+ ld a, $b
+ jp Predef ; indirect jump to Func_f81d (f81d (3:781d))
+
+MoneyForWinningText: ; 3c6e4 (f:46e4)
+ TX_FAR _MoneyForWinningText
+ db "@"
+
+TrainerDefeatedText: ; 3c6e9 (f:46e9)
+ TX_FAR _TrainerDefeatedText
+ db "@"
+
+PlayBattleVictoryMusic: ; 3c6ee (f:46ee)
+ push af
+ ld a, $ff
+ ld [$c0ee], a
+ call PlaySoundWaitForCurrent
+ ld c, BANK(Music_DefeatedTrainer)
+ pop af
+ call PlayMusic
+ jp Delay3
+
+HandlePlayerMonFainted: ; 3c700 (f:4700)
+ ld a, $1
+ ld [$ccf0], a
+ call Func_3c741
+ call AnyPlayerPokemonAliveCheck ; test if any more mons are alive
+ ld a, d
+ and a
+ jp z, HandlePlayerBlackOut
+ ld hl, W_ENEMYMONCURHP ; $cfe6
+ ld a, [hli]
+ or [hl]
+ jr nz, .enemyMonNotFainted
+ call FaintEnemyPokemon
+ ld a, [W_ISINBATTLE] ; $d057
+ dec a
+ ret z ; if wild encounter, battle is over
+ call AnyEnemyPokemonAliveCheck
+ jp z, TrainerBattleVictory
+.enemyMonNotFainted
+ call Func_3c79b
+ ret c
+ call Func_3c7d8
+ jp nz, MainInBattleLoop
+ ld a, $1
+ ld [$cd6a], a
+ call Func_3c664
+ jp z, asm_3c202
+ xor a
+ ld [$cd6a], a
+ jp MainInBattleLoop
+
+Func_3c741: ; 3c741 (f:4741)
+ ld a, [wPlayerMonNumber] ; $cc2f
+ ld c, a
+ ld hl, W_PLAYERMONSALIVEFLAGS ; clear fainted mon's alive flag
+ ld b, $0
+ ld a, $10
+ call Predef ; indirect jump to HandleBitArray (f666 (3:7666))
+ ld hl, W_ENEMYBATTSTATUS1 ; $d067
+ res 2, [hl] ; reset "attacking multiple times" flag
+ ld a, [$d083]
+ bit 7, a ; skip sound flag (red bar (?))
+ jr z, .skipWaitForSound
+ ld a, $ff
+ ld [$d083], a
+ call WaitForSoundToFinish
+.skipWaitForSound
+ ld hl, $cd05
+ ld [hli], a
+ ld [hl], a
+ ld [W_PLAYERMONSTATUS], a ; $d018
+ call ReadPlayerMonCurHPAndStatus
+ FuncCoord 9, 7 ; $c435
+ ld hl, Coord
+ ld bc, $50b
+ call ClearScreenArea
+ FuncCoord 1, 10 ; $c469
+ ld hl, Coord
+ FuncCoord 1, 11 ; $c47d
+ ld de, Coord
+ call Func_3c893
+ ld a, $1
+ ld [$cf0b], a
+ ld a, [$ccf0]
+ and a
+ ret z
+ ld a, [W_PLAYERMONID]
+ call PlayCry
+ ld hl, PlayerMonFaintedText
+ jp PrintText
+
+PlayerMonFaintedText: ; 3c796 (f:4796)
+ TX_FAR _PlayerMonFaintedText
+ db "@"
+
+Func_3c79b: ; 3c79b (f:479b)
+ call Func_3ee94
+ call SaveScreenTilesToBuffer1
+ ld a, [W_ISINBATTLE] ; $d057
+ and a
+ dec a
+ ret nz
+ ld hl, UseNextMonText
+ call PrintText
+.asm_3c7ad
+ FuncCoord 13, 9 ; $c461
+ ld hl, Coord
+ ld bc, $a0e
+ ld a, $14
+ ld [$d125], a
+ call DisplayTextBoxID
+ ld a, [$d12e]
+ cp $2
+ jr z, .asm_3c7c4
+ and a
+ ret
+.asm_3c7c4
+ ld a, [wCurrentMenuItem] ; $cc26
+ and a
+ jr z, .asm_3c7ad
+ ld hl, W_PARTYMON1_SPEED ; $d193
+ ld de, W_ENEMYMONSPEED
+ jp Func_3cab9
+
+UseNextMonText: ; 3c7d3 (f:47d3)
+ TX_FAR _UseNextMonText
+ db "@"
+
+Func_3c7d8: ; 3c7d8 (f:47d8)
+ ld a, $2
+ ld [$d07d], a
+ call DisplayPartyMenu
+.asm_3c7e0
+ jr nc, .asm_3c7e7
+.asm_3c7e2
+ call GoBackToPartyMenu
+ jr .asm_3c7e0
+.asm_3c7e7
+ call Func_3ca97
+ jr z, .asm_3c7e2
+ ld a, [W_ISLINKBATTLE] ; $d12b
+ cp $4
+ jr nz, .asm_3c7fa
+ inc a
+ ld [$cd6a], a
+ call Func_3d605
+.asm_3c7fa
+ xor a
+ ld [$cd6a], a
+ call CleanLCD_OAM
+ ld a, [wWhichPokemon] ; $cf92
+ ld [wPlayerMonNumber], a ; $cc2f
+ ld c, a
+ ld hl, W_PLAYERMONSALIVEFLAGS
+ ld b, $1
+ push bc
+ ld a, $10
+ call Predef ; indirect jump to HandleBitArray (f666 (3:7666))
+ pop bc
+ ld hl, $ccf5
+ ld a, $10
+ call Predef ; indirect jump to HandleBitArray (f666 (3:7666))
+ call Func_3cba6
+ call GBPalWhiteOut
+ call Func_3ee5b
+ call LoadScreenTilesFromBuffer1
+ call GoPAL_SET_CF1C
+ call GBPalNormal
+ call Func_3cc91
+ ld hl, W_ENEMYMONCURHP ; $cfe6
+ ld a, [hli]
+ or [hl]
+ ret
+
+; called when player is out of usable mons.
+; prints approriate lose message, sets carry flag if player blacked out (special case for initial rival fight)
+HandlePlayerBlackOut: ; 3c837 (f:4837)
+ ld a, [W_ISLINKBATTLE] ; $d12b
+ cp $4
+ jr z, .notSony1Battle
+ ld a, [W_CUROPPONENT] ; $d059
+ cp $c8 + SONY1
+ jr nz, .notSony1Battle
+ ld hl, wTileMap ; sony 1 battle
+ ld bc, $815
+ call ClearScreenArea
+ call ScrollTrainerPicAfterBattle
+ ld c, $28
+ call DelayFrames
+ ld hl, Sony1WinText
+ call PrintText
+ ld a, [W_CURMAP]
+ cp OAKS_LAB
+ ret z ; starter battle in oak's lab: don't black out
+.notSony1Battle
+ ld b, $0
+ call GoPAL_SET
+ ld hl, PlayerBlackedOutText2
+ ld a, [W_ISLINKBATTLE] ; $d12b
+ cp $4
+ jr nz, .noLinkBattle
+ ld hl, LinkBattleLostText
+.noLinkBattle
+ call PrintText
+ ld a, [$d732]
+ res 5, a
+ ld [$d732], a
+ call ClearScreen
+ scf
+ ret
+
+Sony1WinText: ; 3c884 (f:4884)
+ TX_FAR _Sony1WinText
+ db "@"
+
+PlayerBlackedOutText2: ; 3c889 (f:4889)
+ TX_FAR _PlayerBlackedOutText2
+ db "@"
+
+LinkBattleLostText: ; 3c88e (f:488e)
+ TX_FAR _LinkBattleLostText
+ db "@"
+
+Func_3c893: ; 3c893 (f:4893)
+ ld a, [$d730]
+ push af
+ set 6, a
+ ld [$d730], a
+ ld b, $7
+.asm_3c89e
+ push bc
+ push de
+ push hl
+ ld b, $6
+.asm_3c8a3
+ push bc
+ push hl
+ push de
+ ld bc, $7
+ call CopyData
+ pop de
+ pop hl
+ ld bc, $ffec
+ add hl, bc
+ push hl
+ ld h, d
+ ld l, e
+ add hl, bc
+ ld d, h
+ ld e, l
+ pop hl
+ pop bc
+ dec b
+ jr nz, .asm_3c8a3
+ ld bc, $14
+ add hl, bc
+ ld de, SevenSpacesText
+ call PlaceString
+ ld c, $2
+ call DelayFrames
+ pop hl
+ pop de
+ pop bc
+ dec b
+ jr nz, .asm_3c89e
+ pop af
+ ld [$d730], a
+ ret
+
+SevenSpacesText: ; 3c8d7 (f:48d7)
+ db " @"
+
+Func_3c8df: ; 3c8df (f:48df)
+ ld [H_DOWNARROWBLINKCNT1], a ; $ff8b
+ ld c, a
+.asm_3c8e2
+ push bc
+ push hl
+ ld b, $7
+.asm_3c8e6
+ push hl
+ ld a, [H_DOWNARROWBLINKCNT1] ; $ff8b
+ ld c, a
+.asm_3c8ea
+ ld a, [H_DOWNARROWBLINKCNT1] ; $ff8b
+ cp $8
+ jr z, .asm_3c8f5
+ ld a, [hld]
+ ld [hli], a
+ inc hl
+ jr .asm_3c8f8
+.asm_3c8f5
+ ld a, [hli]
+ ld [hld], a
+ dec hl
+.asm_3c8f8
+ dec c
+ jr nz, .asm_3c8ea
+ pop hl
+ ld de, $14
+ add hl, de
+ dec b
+ jr nz, .asm_3c8e6
+ ld c, $2
+ call DelayFrames
+ pop hl
+ pop bc
+ dec c
+ jr nz, .asm_3c8e2
+ ret
+
+; XXX this needs cleaning up. it's what runs when a juggler switches pokemon
+EnemySendOut: ; 3c90e (f:490e)
+ ld hl,W_PLAYERMONSALIVEFLAGS
+ xor a
+ ld [hl],a
+ ld a,[$CC2F]
+ ld c,a
+ ld b,1
+ push bc
+ ld a,$10
+ call Predef
+ ld hl,$CCF5
+ xor a
+ ld [hl],a
+ pop bc
+ ld a,$10
+ call Predef
+Func_3c92a: ; 3c92a (f:492a)
+ xor a
+ ld hl,$D065
+ ld [hli],a
+ ld [hli],a
+ ld [hli],a
+ ld [hli],a
+ ld [hl],a
+ ld [$D072],a
+ ld [$CCEF],a
+ ld [$CCF3],a
+ ld hl,$CCF1
+ ld [hli],a
+ ld [hl],a
+ dec a
+ ld [wAICount],a
+ ld hl,W_PLAYERBATTSTATUS1
+ res 5,[hl]
+ FuncCoord 18, 0 ; $c3b2
+ ld hl,Coord
+ ld a,8
+ call Func_3c8df
+ call Func_3ee94
+ call SaveScreenTilesToBuffer1
+ ld a,[$D12B]
+ cp 4
+ jr nz,.next
+ ld a,[$CC3E]
+ sub 4
+ ld [wWhichPokemon],a
+ jr .next3
+.next
+ ld b,$FF
+.next2
+ inc b
+ ld a,[$CFE8]
+ cp b
+ jr z,.next2
+ ld hl,$D8A4
+ ld a,b
+ ld [wWhichPokemon],a
+ push bc
+ ld bc,$2C
+ call AddNTimes
+ pop bc
+ inc hl
+ ld a,[hli]
+ ld c,a
+ ld a,[hl]
+ or c
+ jr z,.next2
+.next3
+ ld a,[wWhichPokemon]
+ ld hl,$D8C5
+ ld bc,$2C
+ call AddNTimes
+ ld a,[hl]
+ ld [$D127],a
+ ld a,[wWhichPokemon]
+ inc a
+ ld hl,$D89C
+ ld c,a
+ ld b,0
+ add hl,bc
+ ld a,[hl]
+ ld [W_ENEMYMONID],a
+ ld [$CF91],a
+ call Func_3eb01
+ ld hl,$CFE6
+ ld a,[hli]
+ ld [$CCE3],a
+ ld a,[hl]
+ ld [$CCE4],a
+ ld a,1
+ ld [$CC26],a
+ ld a,[$D11D]
+ dec a
+ jr z,.next4
+ ld a,[W_NUMINPARTY]
+ dec a
+ jr z,.next4
+ ld a,[$D12B]
+ cp 4
+ jr z,.next4
+ ld a,[$D355]
+ bit 6,a
+ jr nz,.next4
+ ld hl, TrainerAboutToUseText
+ call PrintText
+ FuncCoord 0, 7 ; $c42c
+ ld hl,Coord
+ ld bc,$0801
+ ld a,$14
+ ld [$D125],a
+ call DisplayTextBoxID
+ ld a,[$CC26]
+ and a
+ jr nz,.next4
+ ld a,2
+ ld [$D07D],a
+ call DisplayPartyMenu
+.next9
+ ld a,1
+ ld [$CC26],a
+ jr c,.next7
+ ld hl,$CC2F
+ ld a,[wWhichPokemon]
+ cp [hl]
+ jr nz,.next6
+ ld hl,AlreadyOutText
+ call PrintText
+.next8
+ call GoBackToPartyMenu
+ jr .next9
+.next6
+ call Func_3ca97
+ jr z,.next8
+ xor a
+ ld [$CC26],a
+.next7
+ call GBPalWhiteOut
+ call Func_3ee5b
+ call LoadScreenTilesFromBuffer1
+.next4
+ call CleanLCD_OAM
+ ld hl,wTileMap
+ ld bc,$040B
+ call ClearScreenArea
+ ld b,1
+ call GoPAL_SET
+ call GBPalNormal
+ ld hl,TrainerSentOutText
+ call PrintText
+ ld a,[W_ENEMYMONID]
+ ld [$CF91],a
+ ld [$D0B5],a
+ call GetMonHeader
+ ld de,$9000
+ call LoadMonFrontSprite
+ ld a,$CF
+ ld [$FFE1],a
+ FuncCoord 15, 6 ; $c427
+ ld hl,Coord
+ ld a,2
+ call Predef
+ ld a,[W_ENEMYMONID]
+ call PlayCry
+ call Func_3cdec
+ ld a,[$CC26]
+ and a
+ ret nz
+ xor a
+ ld [W_PLAYERMONSALIVEFLAGS],a
+ ld [$CCF5],a
+ call SaveScreenTilesToBuffer1
+ jp Func_3d1ba
+
+TrainerAboutToUseText: ; 3ca79 (f:4a79)
+ TX_FAR _TrainerAboutToUseText
+ db "@"
+
+TrainerSentOutText: ; 3ca7e (f:4a7e)
+ TX_FAR _TrainerSentOutText
+ db "@"
+
+; tests if the player has any pokemon that are not fainted
+; sets d = 0 if all fainted, d != 0 if some mons are still alive
+AnyPlayerPokemonAliveCheck: ; 3ca83 (f:4a83)
+ ld a, [W_NUMINPARTY] ; $d163
+ ld e, a
+ xor a
+ ld hl, W_PARTYMON1_HP ; $d16c
+ ld bc, W_PARTYMON2DATA - W_PARTYMON1DATA - 1
+.partyMonsLoop
+ or [hl]
+ inc hl
+ or [hl]
+ add hl, bc
+ dec e
+ jr nz, .partyMonsLoop
+ ld d, a
+ ret
+
+Func_3ca97: ; 3ca97 (f:4a97)
+ ld a, [wWhichPokemon] ; $cf92
+ ld hl, W_PARTYMON1_HP ; $d16c
+ ld bc, $2c
+ call AddNTimes
+ ld a, [hli]
+ or [hl]
+ ret nz
+ ld a, [$d11d]
+ and a
+ jr nz, .asm_3cab2
+ ld hl, NoWillText
+ call PrintText
+.asm_3cab2
+ xor a
+ ret
+
+NoWillText: ; 3cab4 (f:4ab4)
+ TX_FAR _NoWillText
+ db "@"
+
+Func_3cab9: ; 3cab9 (f:4ab9)
+ call IsGhostBattle
+ jp z, .asm_3cb5c
+ ld a, [W_BATTLETYPE] ; $d05a
+ cp $2
+ jp z, .asm_3cb5c
+ ld a, [W_ISLINKBATTLE] ; $d12b
+ cp $4
+ jp z, .asm_3cb5c
+ ld a, [W_ISINBATTLE] ; $d057
+ dec a
+ jr nz, .asm_3cb4c
+ ld a, [$d120]
+ inc a
+ ld [$d120], a
+ ld a, [hli]
+ ld [$ff97], a
+ ld a, [hl]
+ ld [$ff98], a
+ ld a, [de]
+ ld [$ff8d], a
+ inc de
+ ld a, [de]
+ ld [$ff8e], a
+ call LoadScreenTilesFromBuffer1
+ ld de, $ff97
+ ld hl, $ff8d
+ ld c, $2
+ call StringCmp
+ jr nc, .asm_3cb5c
+ xor a
+ ld [H_NUMTOPRINT], a ; $ff96 (aliases: H_MULTIPLICAND)
+ ld a, $20
+ ld [H_REMAINDER], a ; $ff99 (aliases: H_DIVISOR, H_MULTIPLIER, H_POWEROFTEN)
+ call Multiply
+ ld a, [$ff97]
+ ld [H_DIVIDEND], a ; $ff95 (aliases: H_PRODUCT, H_PASTLEADINGZEROES, H_QUOTIENT)
+ ld a, [$ff98]
+ ld [H_NUMTOPRINT], a ; $ff96 (aliases: H_MULTIPLICAND)
+ ld a, [$ff8d]
+ ld b, a
+ ld a, [$ff8e]
+ srl b
+ rr a
+ srl b
+ rr a
+ and a
+ jr z, .asm_3cb5c
+ ld [H_REMAINDER], a ; $ff99 (aliases: H_DIVISOR, H_MULTIPLIER, H_POWEROFTEN)
+ ld b, $2
+ call Divide
+ ld a, [$ff97]
+ and a
+ jr nz, .asm_3cb5c
+ ld a, [$d120]
+ ld c, a
+.asm_3cb2b
+ dec c
+ jr z, .asm_3cb39
+ ld b, $1e
+ ld a, [$ff98]
+ add b
+ ld [$ff98], a
+ jr c, .asm_3cb5c
+ jr .asm_3cb2b
+.asm_3cb39
+ call GenRandomInBattle
+ ld b, a
+ ld a, [$ff98]
+ cp b
+ jr nc, .asm_3cb5c
+ ld a, $1
+ ld [$cd6a], a
+ ld hl, CantEscapeText
+ jr .asm_3cb4f
+.asm_3cb4c
+ ld hl, NoRunningText
+.asm_3cb4f
+ call PrintText
+ ld a, $1
+ ld [$d11f], a
+ call SaveScreenTilesToBuffer1
+ and a
+ ret
+.asm_3cb5c
+ ld a, [W_ISLINKBATTLE] ; $d12b
+ cp $4
+ ld a, $2
+ jr nz, .asm_3cb81
+ call SaveScreenTilesToBuffer1
+ xor a
+ ld [$cd6a], a
+ ld a, $f
+ ld [wPlayerMoveListIndex], a ; $cc2e
+ call Func_3d605
+ call LoadScreenTilesFromBuffer1
+ ld a, [$cc3e]
+ cp $f
+ ld a, $2
+ jr z, .asm_3cb81
+ dec a
+.asm_3cb81
+ ld [$cf0b], a
+ ld a, (SFX_08_44 - SFX_Headers_08) / 3
+ call PlaySoundWaitForCurrent
+ ld hl, GotAwayText
+ call PrintText
+ call WaitForSoundToFinish
+ call SaveScreenTilesToBuffer1
+ scf
+ ret
+
+CantEscapeText: ; 3cb97 (f:4b97)
+ TX_FAR _CantEscapeText
+ db "@"
+
+NoRunningText: ; 3cb9c (f:4b9c)
+ TX_FAR _NoRunningText
+ db "@"
+
+GotAwayText: ; 3cba1 (f:4ba1)
+ TX_FAR _GotAwayText
+ db "@"
+
+Func_3cba6: ; 3cba6 (f:4ba6)
+ ld a, [wWhichPokemon] ; $cf92
+ ld bc, $2c
+ ld hl, W_PARTYMON1_NUM ; $d16b (aliases: W_PARTYMON1DATA)
+ call AddNTimes
+ ld de, W_PLAYERMONID
+ ld bc, $c
+ call CopyData
+ ld bc, $f
+ add hl, bc
+ ld de, W_PLAYERMONIVS
+ ld bc, $2
+ call CopyData
+ ld de, W_PLAYERMONPP ; $d02d
+ ld bc, $4
+ call CopyData
+ ld de, W_PLAYERMONLEVEL ; $d022
+ ld bc, $b
+ call CopyData
+ ld a, [$cfd9]
+ ld [$d0b5], a
+ call GetMonHeader
+ ld hl, W_PARTYMON1NAME ; $d2b5
+ ld a, [wPlayerMonNumber] ; $cc2f
+ call SkipFixedLengthTextEntries
+ ld de, W_PLAYERMONNAME
+ ld bc, $b
+ call CopyData
+ ld hl, W_PLAYERMONLEVEL ; $d022
+ ld de, $cd0f
+ ld bc, $b
+ call CopyData
+ call Func_3ed1a
+ call Func_3ee19
+ ld a, $7
+ ld b, $8
+ ld hl, wPlayerMonAttackMod ; $cd1a
+.asm_3cc0e
+ ld [hli], a
+ dec b
+ jr nz, .asm_3cc0e
+ ret
+
+Func_3cc13: ; 3cc13 (f:4c13)
+ ld a, [wWhichPokemon] ; $cf92
+ ld bc, $2c
+ ld hl, wEnemyMons ; $d8a4
+ call AddNTimes
+ ld de, $cfe5
+ ld bc, $c
+ call CopyData
+ ld bc, $f
+ add hl, bc
+ ld de, $cff1
+ ld bc, $2
+ call CopyData
+ ld de, W_ENEMYMONPP ; $cffe
+ ld bc, $4
+ call CopyData
+ ld de, W_ENEMYMONLEVEL ; $cff3
+ ld bc, $b
+ call CopyData
+ ld a, [$cfe5]
+ ld [$d0b5], a
+ call GetMonHeader
+ ld hl, $d9ee
+ ld a, [wWhichPokemon] ; $cf92
+ call SkipFixedLengthTextEntries
+ ld de, W_ENEMYMONNAME
+ ld bc, $b
+ call CopyData
+ ld hl, W_ENEMYMONLEVEL ; $cff3
+ ld de, $cd23
+ ld bc, $b
+ call CopyData
+ call Func_3ed1e
+ ld hl, W_MONHBASESTATS
+ ld de, $d002
+ ld b, $5
+.asm_3cc79
+ ld a, [hli]
+ ld [de], a
+ inc de
+ dec b
+ jr nz, .asm_3cc79
+ ld a, $7
+ ld b, $8
+ ld hl, wEnemyMonStatMods ; $cd2e
+.asm_3cc86
+ ld [hli], a
+ dec b
+ jr nz, .asm_3cc86
+ ld a, [wWhichPokemon] ; $cf92
+ ld [W_ENEMYMONNUMBER], a ; $cfe8
+ ret
+
+Func_3cc91: ; 3cc91 (f:4c91)
+ callab SendOutMon
+ ld hl, W_ENEMYMONCURHP ; $cfe6
+ ld a, [hli]
+ or [hl]
+ jp z, Func_3cca4
+ call Func_3cdec
+
+Func_3cca4: ; 3cca4 (f:4ca4)
+ call Func_3cd60
+ ld a, $4
+ call Predef ; indirect jump to LoadMonBackSprite (3f103 (f:7103))
+ xor a
+ ld [$ffe1], a
+ ld hl, $cc2d
+ ld [hli], a
+ ld [hl], a
+ ld [$cc5b], a
+ ld [$d05b], a
+ ld [W_PLAYERMOVENUM], a ; $cfd2
+ ld hl, $ccf1
+ ld [hli], a
+ ld [hl], a
+ ld hl, $d060
+ ld [hli], a
+ ld [hli], a
+ ld [hli], a
+ ld [hli], a
+ ld [hl], a
+ ld [W_PLAYERDISABLEDMOVE], a ; $d06d
+ ld [$ccee], a
+ ld [$ccf7], a
+ ld b, $1
+ call GoPAL_SET
+ ld hl, W_ENEMYBATTSTATUS1 ; $d067
+ res 5, [hl]
+ ld a, $1
+ ld [H_WHOSETURN], a ; $fff3
+ ld a, POOF_ANIM
+ call PlayMoveAnimation
+ FuncCoord 4, 11 ; $c480
+ ld hl, Coord
+ ld a, $2
+ call Predef ; indirect jump to Func_3f073 (3f073 (f:7073))
+ ld a, [$cf91]
+ call PlayCry
+ call Func_3ee94
+ jp SaveScreenTilesToBuffer1
+
+Func_3ccfa: ; 3ccfa (f:4cfa)
+ FuncCoord 1, 5 ; $c405
+ ld hl, Coord
+ ld bc, $707
+ call ClearScreenArea
+ FuncCoord 3, 7 ; $c42f
+ ld hl, Coord
+ ld bc, $505
+ xor a
+ ld [$cd6c], a
+ ld [H_DOWNARROWBLINKCNT1], a ; $ff8b
+ ld a, $5
+ call Predef ; indirect jump to Func_79aba (79aba (1e:5aba))
+ ld c, $4
+ call DelayFrames
+ call Func_3cd3a
+ FuncCoord 4, 9 ; $c458
+ ld hl, Coord
+ ld bc, $303
+ ld a, $1
+ ld [$cd6c], a
+ xor a
+ ld [H_DOWNARROWBLINKCNT1], a ; $ff8b
+ ld a, $5
+ call Predef ; indirect jump to Func_79aba (79aba (1e:5aba))
+ call Delay3
+ call Func_3cd3a
+ ld a, $4c
+ FuncCoord 5, 11 ; $c481
+ ld [Coord], a
+
+Func_3cd3a: ; 3cd3a (f:4d3a)
+ FuncCoord 1, 5 ; $c405
+ ld hl, Coord
+ ld bc, $707
+ jp ClearScreenArea
+
+; reads player's current mon's HP into W_PLAYERMONCURHP
+ReadPlayerMonCurHPAndStatus: ; 3cd43 (f:4d43)
+ ld a, [wPlayerMonNumber] ; $cc2f
+ ld hl, W_PARTYMON1_HP ; $d16c
+ ld bc, W_PARTYMON2DATA - W_PARTYMON1DATA
+ call AddNTimes
+ ld d, h
+ ld e, l
+ ld hl, W_PLAYERMONCURHP ; $d015
+ ld bc, $4 ; 2 bytes HP, 1 byte unknown (unused?), 1 byte status
+ jp CopyData
+
+Func_3cd5a: ; 3cd5a (f:4d5a)
+ call Func_3cd60
+ jp Func_3cdec
+
+Func_3cd60: ; 3cd60 (f:4d60)
+ xor a
+ ld [H_AUTOBGTRANSFERENABLED], a ; $ffba
+ FuncCoord 9, 7 ; $c435
+ ld hl, Coord
+ ld bc, $50b
+ call ClearScreenArea
+ callab PlacePlayerHUDTiles
+ FuncCoord 18, 9 ; $c466
+ ld hl, Coord
+ ld [hl], $73
+ ld de, W_PLAYERMONNAME
+ FuncCoord 10, 7 ; $c436
+ ld hl, Coord
+ call Func_3ce9c
+ call PlaceString
+ ld hl, W_PLAYERMONID
+ ld de, $cf98
+ ld bc, $c
+ call CopyData
+ ld hl, W_PLAYERMONLEVEL ; $d022
+ ld de, $cfb9
+ ld bc, $b
+ call CopyData
+ FuncCoord 14, 8 ; $c44e
+ ld hl, Coord
+ push hl
+ inc hl
+ ld de, $cf9c
+ call PrintStatusConditionNotFainted
+ pop hl
+ jr nz, .asm_3cdae
+ call PrintLevel
+.asm_3cdae
+ ld a, [$cf98]
+ ld [$cf91], a
+ FuncCoord 10, 9 ; $c45e
+ ld hl, Coord
+ ld a, $5f
+ call Predef ; indirect jump to Func_128ef (128ef (4:68ef))
+ ld a, $1
+ ld [H_AUTOBGTRANSFERENABLED], a ; $ffba
+ ld hl, $cf1d
+ call GetBattleHealthBarColor
+ ld hl, W_PLAYERMONCURHP ; $d015
+ ld a, [hli]
+ or [hl]
+ jr z, .asm_3cdd9
+ ld a, [$ccf6]
+ and a
+ ret nz
+ ld a, [$cf1d]
+ cp $2
+ jr z, .asm_3cde6
+.asm_3cdd9
+ ld hl, $d083
+ bit 7, [hl]
+ ld [hl], $0
+ ret z
+ xor a
+ ld [$c02a], a
+ ret
+.asm_3cde6
+ ld hl, $d083
+ set 7, [hl]
+ ret
+
+Func_3cdec: ; 3cdec (f:4dec)
+ xor a
+ ld [H_AUTOBGTRANSFERENABLED], a ; $ffba
+ ld hl, wTileMap
+ ld bc, $40c
+ call ClearScreenArea
+ callab PlaceEnemyHUDTiles
+ ld de, W_ENEMYMONNAME
+ FuncCoord 1, 0 ; $c3a1
+ ld hl, Coord
+ call Func_3ce9c
+ call PlaceString
+ FuncCoord 4, 1 ; $c3b8
+ ld hl, Coord
+ push hl
+ inc hl
+ ld de, W_ENEMYMONSTATUS ; $cfe9
+ call PrintStatusConditionNotFainted
+ pop hl
+ jr nz, .asm_3ce23
+ ld a, [W_ENEMYMONLEVEL] ; $cff3
+ ld [$cfb9], a
+ call PrintLevel
+.asm_3ce23
+ ld hl, W_ENEMYMONCURHP ; $cfe6
+ ld a, [hli]
+ ld [$ff97], a
+ ld a, [hld]
+ ld [$ff98], a
+ or [hl]
+ jr nz, .asm_3ce36
+ ld c, a
+ ld e, a
+ ld d, $6
+ jp Func_3ce7f
+.asm_3ce36
+ xor a
+ ld [H_NUMTOPRINT], a ; $ff96 (aliases: H_MULTIPLICAND)
+ ld a, $30
+ ld [H_REMAINDER], a ; $ff99 (aliases: H_DIVISOR, H_MULTIPLIER, H_POWEROFTEN)
+ call Multiply
+ ld hl, W_ENEMYMONMAXHP ; $cff4
+ ld a, [hli]
+ ld b, a
+ ld a, [hl]
+ ld [H_REMAINDER], a ; $ff99 (aliases: H_DIVISOR, H_MULTIPLIER, H_POWEROFTEN)
+ ld a, b
+ and a
+ jr z, .asm_3ce6a
+ ld a, [H_REMAINDER] ; $ff99 (aliases: H_DIVISOR, H_MULTIPLIER, H_POWEROFTEN)
+ srl b
+ rr a
+ srl b
+ rr a
+ ld [H_REMAINDER], a ; $ff99 (aliases: H_DIVISOR, H_MULTIPLIER, H_POWEROFTEN)
+ ld a, [$ff97]
+ ld b, a
+ srl b
+ ld a, [$ff98]
+ rr a
+ srl b
+ rr a
+ ld [$ff98], a
+ ld a, b
+ ld [$ff97], a
+.asm_3ce6a
+ ld a, [$ff97]
+ ld [H_DIVIDEND], a ; $ff95 (aliases: H_PRODUCT, H_PASTLEADINGZEROES, H_QUOTIENT)
+ ld a, [$ff98]
+ ld [H_NUMTOPRINT], a ; $ff96 (aliases: H_MULTIPLICAND)
+ ld a, $2
+ ld b, a
+ call Divide
+ ld a, [$ff98]
+ ld e, a
+ ld a, $6
+ ld d, a
+ ld c, a
+
+Func_3ce7f: ; 3ce7f (f:4e7f)
+ xor a
+ ld [wListMenuID], a ; $cf94
+ FuncCoord 2, 2 ; $c3ca
+ ld hl, Coord
+ call DrawHPBar
+ ld a, $1
+ ld [H_AUTOBGTRANSFERENABLED], a ; $ffba
+ ld hl, $cf1e
+
+GetBattleHealthBarColor: ; 3ce90 (f:4e90)
+ ld b, [hl]
+ call GetHealthBarColor
+ ld a, [hl]
+ cp b
+ ret z
+ ld b, $1
+ jp GoPAL_SET
+
+Func_3ce9c: ; 3ce9c (f:4e9c)
+ push de
+ inc hl
+ inc hl
+ ld b, $2
+.asm_3cea1
+ inc de
+ ld a, [de]
+ cp $50
+ jr z, .asm_3ceb1
+ inc de
+ ld a, [de]
+ cp $50
+ jr z, .asm_3ceb1
+ dec hl
+ dec b
+ jr nz, .asm_3cea1
+.asm_3ceb1
+ pop de
+ ret
+
+InitBattleMenu: ; 3ceb3 (f:4eb3)
+ call LoadScreenTilesFromBuffer1 ; restore saved screen
+ ld a, [W_BATTLETYPE] ; $d05a
+ and a
+ jr nz, .nonstandardbattle
+ call Func_3cd5a ; redraw names and HP bars?
+ call Func_3ee94
+ call SaveScreenTilesToBuffer1
+.nonstandardbattle
+ ld a, [W_BATTLETYPE] ; $d05a
+ cp $2 ; safari
+ ld a, $b ; safari menu id
+ jr nz, .menuselected
+ ld a, $1b ; regular menu id
+.menuselected
+ ld [$d125], a
+ call DisplayTextBoxID
+ ld a, [W_BATTLETYPE] ; $d05a
+ dec a
+ jp nz, RegularBattleMenu ; regular battle
+ ; the following happens for the old man tutorial
+ ld hl, W_PLAYERNAME ; $d158
+ ld de, W_GRASSRATE ; $d887
+ ld bc, $b
+ call CopyData ; temporarily save the player name in unused space,
+ ; which is supposed to get overwritten when entering a
+ ; map with wild pokémon. due to an oversight, the data
+ ; may not get overwritten (cinnabar) and the infamous
+ ; missingno. glitch can show up.
+ ld hl, OldManName ; $4f12
+ ld de, W_PLAYERNAME ; $d158
+ ld bc, $b
+ call CopyData
+ ; the following simulates the keystrokes by drawing menus on screen
+ FuncCoord 9, 14 ; $c4c1
+ ld hl, Coord
+ ld [hl], "▶"
+ ld c, $50
+ call DelayFrames
+ ld [hl], $7f
+ FuncCoord 9, 16 ; $c4e9
+ ld hl, Coord
+ ld [hl], "▶"
+ ld c, $32
+ call DelayFrames
+ ld [hl], $ec
+ ld a, $2
+ jp Func_3cfe8
+
+OldManName: ; 3cf12 (f:4f12)
+ db "OLD MAN@"
+
+RegularBattleMenu: ; 3cf1a (f:4f1a)
+ ld a, [$cc2d]
+ ld [wCurrentMenuItem], a ; $cc26
+ ld [wLastMenuItem], a ; $cc2a
+ sub $2
+ jr c, .leftcolumn
+ ld [wCurrentMenuItem], a ; $cc26
+ ld [wLastMenuItem], a ; $cc2a
+ jr .rightcolumn
+.leftcolumn
+ ld a, [W_BATTLETYPE] ; $d05a
+ cp $2
+ ld a, " "
+ jr z, .safaribattle
+ FuncCoord 15, 14 ; $c4c7
+ ld [Coord], a
+ FuncCoord 15, 16 ; $c4ef
+ ld [Coord], a
+ ld b, $9
+ jr .notsafari
+.safaribattle
+ FuncCoord 13, 14 ; $c4c5
+ ld [Coord], a
+ FuncCoord 13, 16 ; $c4ed
+ ld [Coord], a
+ FuncCoord 7, 14 ; $c4bf
+ ld hl, Coord
+ ld de, W_NUMSAFARIBALLS ; $da47
+ ld bc, $102
+ call PrintNumber
+ ld b, $1
+.notsafari
+ ld hl, wTopMenuItemY ; $cc24
+ ld a, $e
+ ld [hli], a
+ ld a, b
+ ld [hli], a
+ inc hl
+ inc hl
+ ld a, $1
+ ld [hli], a
+ ld [hl], $11
+ call HandleMenuInput
+ bit 4, a
+ jr nz, .rightcolumn
+ jr .selection
+.rightcolumn
+ ld a, [W_BATTLETYPE] ; $d05a
+ cp $2
+ ld a, " "
+ jr z, .safarirightcolumn
+ FuncCoord 9, 14 ; $c4c1
+ ld [Coord], a
+ FuncCoord 9, 16 ; $c4e9
+ ld [Coord], a
+ ld b, $f
+ jr .notsafarirightcolumn
+.safarirightcolumn
+ FuncCoord 1, 14 ; $c4b9
+ ld [Coord], a
+ FuncCoord 1, 16 ; $c4e1
+ ld [Coord], a
+ FuncCoord 7, 14 ; $c4bf
+ ld hl, Coord
+ ld de, W_NUMSAFARIBALLS ; $da47
+ ld bc, $102
+ call PrintNumber
+ ld b, $d
+.notsafarirightcolumn
+ ld hl, wTopMenuItemY ; $cc24
+ ld a, $e
+ ld [hli], a
+ ld a, b
+ ld [hli], a
+ inc hl
+ inc hl
+ ld a, $1
+ ld [hli], a
+ ld a, $21
+ ld [hli], a
+ call HandleMenuInput
+ bit 5, a
+ jr nz, .leftcolumn
+ ld a, [wCurrentMenuItem] ; $cc26
+ add $2 ; if we're in the right column, the actual id is +2
+ ld [wCurrentMenuItem], a ; $cc26
+.selection
+ call PlaceUnfilledArrowMenuCursor
+ ld a, [W_BATTLETYPE] ; $d05a
+ cp $2
+ ld a, [wCurrentMenuItem] ; $cc26
+ ld [$cc2d], a
+ jr z, .asm_3cfd0
+ cp $1
+ jr nz, .asm_3cfcb
+ inc a
+ jr .asm_3cfd0
+.asm_3cfcb
+ cp $2 ; what
+ jr nz, .asm_3cfd0
+ dec a
+.asm_3cfd0
+ and a
+ jr nz, Func_3cfe8
+ ; first option was selected...
+ ld a, [W_BATTLETYPE] ; $d05a
+ cp $2
+ jr z, .safari1
+ xor a
+ ld [$d120], a
+ jp LoadScreenTilesFromBuffer1 ; restore saved screen and return??
+.safari1 ; safari first option??
+ ld a, SAFARI_BALL
+ ld [$cf91], a
+ jr asm_3d05f
+
+Func_3cfe8: ; 3cfe8 (f:4fe8)
+ cp $2
+ jp nz, Func_3d0ca
+ ld a, [W_ISLINKBATTLE] ; $d12b
+ cp $4
+ jr nz, .asm_3cffd
+ ld hl, ItemsCantBeUsedHereText
+ call PrintText
+ jp InitBattleMenu
+.asm_3cffd ; bag?
+ call SaveScreenTilesToBuffer2 ; copy bg?
+ ld a, [W_BATTLETYPE] ; $d05a
+ cp $2
+ jr nz, asm_3d00e
+ ld a, SAFARI_BAIT
+ ld [$cf91], a
+ jr asm_3d05f
+asm_3d00e: ; 3d00e (f:500e)
+ call LoadScreenTilesFromBuffer1
+ ld a, [W_BATTLETYPE] ; $d05a
+ and a
+ jr nz, .asm_3d01a
+ call Func_3cd5a
+.asm_3d01a
+ ld a, [W_BATTLETYPE] ; $d05a
+ dec a
+ jr nz, Func_3d031
+ ld hl, OldManItemList
+ ld a, l
+ ld [$cf8b], a
+ ld a, h
+ ld [$cf8c], a
+ jr Func_3d03c
+
+OldManItemList: ; 3d02d (f:502d)
+ db $01, POKE_BALL, 50, $ff
+
+Func_3d031
+ ld hl, wNumBagItems ; $d31d
+ ld a, l
+ ld [$cf8b], a
+ ld a, h
+ ld [$cf8c], a
+Func_3d03c
+ xor a
+ ld [$cf93], a
+ ld a, $3
+ ld [wListMenuID], a ; $cf94
+ ld a, [$cc2c]
+ ld [wCurrentMenuItem], a ; $cc26
+ call DisplayListMenuID
+ ld a, [wCurrentMenuItem] ; $cc26
+ ld [$cc2c], a
+ ld a, $0
+ ld [$cc37], a
+ ld [$cc35], a
+ jp c, InitBattleMenu
+asm_3d05f: ; 3d05f (f:505f)
+ ld a, [$cf91]
+ ld [$d11e], a
+ call GetItemName
+ call CopyStringToCF4B ; copy name
+ xor a
+ ld [$d152], a
+ call UseItem
+ call Func_3ee5b
+ call CleanLCD_OAM
+ xor a
+ ld [wCurrentMenuItem], a ; $cc26
+ ld a, [W_BATTLETYPE] ; $d05a
+ cp $2
+ jr z, .asm_3d09c
+ ld a, [$cd6a]
+ and a
+ jp z, asm_3d00e
+ ld a, [W_PLAYERBATTSTATUS1] ; $d062
+ bit 5, a
+ jr z, .asm_3d09c
+ ld hl, $d06a
+ dec [hl]
+ jr nz, .asm_3d09c
+ ld hl, W_PLAYERBATTSTATUS1 ; $d062
+ res 5, [hl]
+.asm_3d09c
+ ld a, [$d11c]
+ and a
+ jr nz, .asm_3d0b7
+ ld a, [W_BATTLETYPE] ; $d05a
+ cp $2
+ jr z, .asm_3d0b2
+ call LoadScreenTilesFromBuffer1
+ call Func_3cd5a ; redraw name and hp bar?
+ call Delay3
+.asm_3d0b2
+ call GBPalNormal
+ and a
+ ret
+.asm_3d0b7
+ call GBPalNormal
+ xor a
+ ld [$d11c], a
+ ld a, $2
+ ld [$cf0b], a
+ scf
+ ret
+
+ItemsCantBeUsedHereText: ; 3d0c5 (f:50c5)
+ TX_FAR _ItemsCantBeUsedHereText
+ db "@"
+
+Func_3d0ca: ; 3d0ca (f:50ca)
+ dec a
+ jp nz, Func_3d1fa
+ call SaveScreenTilesToBuffer2
+ ld a, [W_BATTLETYPE] ; $d05a
+ cp $2
+ jr nz, Func_3d0e0
+ ld a, SAFARI_ROCK
+ ld [$cf91], a
+ jp asm_3d05f
+
+Func_3d0e0: ; 3d0e0 (f:50e0)
+ call LoadScreenTilesFromBuffer1
+ xor a
+ ld [$d07d], a
+ ld [$cc35], a
+ call DisplayPartyMenu
+asm_3d0ed: ; 3d0ed (f:50ed)
+ jp nc, Func_3d119
+asm_3d0f0: ; 3d0f0 (f:50f0)
+ call CleanLCD_OAM
+ call GBPalWhiteOut
+ call Func_3ee5b
+ call LoadScreenTilesFromBuffer2
+ call GoPAL_SET_CF1C
+ call GBPalNormal
+ jp InitBattleMenu
+
+Func_3d105: ; 3d105 (f:5105)
+ FuncCoord 11, 11 ; $c487
+ ld hl, Coord
+ ld bc, $81
+ ld a, $7f
+ call FillMemory
+ xor a
+ ld [$d07d], a
+ call GoBackToPartyMenu
+ jr asm_3d0ed
+
+Func_3d119: ; 3d119 (f:5119)
+ ld a, $c
+ ld [$d125], a
+ call DisplayTextBoxID
+ ld hl, wTopMenuItemY ; $cc24
+ ld a, $c
+ ld [hli], a
+ ld [hli], a
+ xor a
+ ld [hli], a
+ inc hl
+ ld a, $2
+ ld [hli], a
+ ld a, $3
+ ld [hli], a
+ xor a
+ ld [hl], a
+ call HandleMenuInput
+ bit 1, a
+ jr nz, Func_3d105
+ call PlaceUnfilledArrowMenuCursor
+ ld a, [wCurrentMenuItem] ; $cc26
+ cp $2
+ jr z, asm_3d0f0
+ and a
+ jr z, .asm_3d18a
+ xor a
+ ld [$cc49], a
+ ld hl, W_PARTYMON1_NUM ; $d16b (aliases: W_PARTYMON1DATA)
+ call CleanLCD_OAM
+ ld a, $36
+ call Predef ; indirect jump to StatusScreen (12953 (4:6953))
+ ld a, $37
+ call Predef ; indirect jump to StatusScreen2 (12b57 (4:6b57))
+ ld a, [W_ENEMYBATTSTATUS2] ; $d068
+ bit 4, a
+ ld hl, AnimationSubstitute
+ jr nz, .asm_3d182
+ ld a, [$ccf3]
+ and a
+ ld hl, AnimationMinimizeMon
+ jr nz, .asm_3d182
+ ld a, [$cfe5]
+ ld [$cf91], a
+ ld [$d0b5], a
+ call GetMonHeader
+ ld de, $9000
+ call LoadMonFrontSprite
+ jr .asm_3d187
+.asm_3d182
+ ld b, BANK(AnimationSubstitute) ; BANK(AnimationMinimizeMon)
+ call Bankswitch
+.asm_3d187
+ jp Func_3d0e0
+.asm_3d18a
+ ld a, [wPlayerMonNumber] ; $cc2f
+ ld d, a
+ ld a, [wWhichPokemon] ; $cf92
+ cp d
+ jr nz, .asm_3d19d
+ ld hl, AlreadyOutText
+ call PrintText
+ jp Func_3d105
+.asm_3d19d
+ call Func_3ca97
+ jp z, Func_3d105
+ ld a, $1
+ ld [$cd6a], a
+ call GBPalWhiteOut
+ call CleanLCD_OAM
+ call Func_3ee5b
+ call LoadScreenTilesFromBuffer1
+ call GoPAL_SET_CF1C
+ call GBPalNormal
+
+Func_3d1ba: ; 3d1ba (f:51ba)
+ callab RetreatMon
+ ld c, $32
+ call DelayFrames
+ call Func_3ccfa
+ ld a, [wWhichPokemon] ; $cf92
+ ld [wPlayerMonNumber], a ; $cc2f
+ ld c, a
+ ld b, $1
+ push bc
+ ld hl, W_PLAYERMONSALIVEFLAGS
+ ld a, $10
+ call Predef ; indirect jump to HandleBitArray (f666 (3:7666))
+ pop bc
+ ld hl, $ccf5
+ ld a, $10
+ call Predef ; indirect jump to HandleBitArray (f666 (3:7666))
+ call Func_3cba6
+ call Func_3cc91
+ call SaveScreenTilesToBuffer1
+ ld a, $2
+ ld [wCurrentMenuItem], a ; $cc26
+ and a
+ ret
+
+AlreadyOutText: ; 3d1f5 (f:51f5)
+ TX_FAR _AlreadyOutText
+ db "@"
+
+Func_3d1fa: ; 3d1fa (f:51fa)
+ call LoadScreenTilesFromBuffer1
+ ld a, $3
+ ld [wCurrentMenuItem], a ; $cc26
+ ld hl, W_PLAYERMONSPEED
+ ld de, W_ENEMYMONSPEED
+ call Func_3cab9
+ ld a, $0
+ ld [$d11f], a
+ ret c
+ ld a, [$cd6a]
+ and a
+ ret nz
+ jp InitBattleMenu
+
+MoveSelectionMenu: ; 3d219 (f:5219)
+ ld a, [wMoveMenuType]
+ dec a
+ jr z, .mimicmenu
+ dec a
+ jr z, .relearnmenu
+ jr .regularmenu
+
+.loadmoves
+ ld de, $d0dc
+ ld bc, $4
+ call CopyData
+ callab Func_39b87
+ ret
+
+.writemoves
+ ld de, $d0e1
+ ld a, [$fff6]
+ set 2, a
+ ld [$fff6], a
+ call PlaceString
+ ld a, [$fff6]
+ res 2, a
+ ld [$fff6], a
+ ret
+
+.regularmenu
+ call Func_3d3f5
+ ret z
+ ld hl, W_PLAYERMONMOVES
+ call .loadmoves
+ FuncCoord 4, 12 ; $c494
+ ld hl, Coord
+ ld b, $4
+ ld c, $e
+ di
+ call TextBoxBorder
+ FuncCoord 4, 12 ; $c494
+ ld hl, Coord
+ ld [hl], $7a
+ FuncCoord 10, 12 ; $c49a
+ ld hl, Coord
+ ld [hl], $7e
+ ei
+ FuncCoord 6, 13 ; $c4aa
+ ld hl, Coord
+ call .writemoves
+ ld b, $5
+ ld a, $c
+ jr .menuset
+.mimicmenu
+ ld hl, W_ENEMYMONMOVES
+ call .loadmoves
+ FuncCoord 0, 7 ; $c42c
+ ld hl, Coord
+ ld b, $4
+ ld c, $e
+ call TextBoxBorder
+ FuncCoord 2, 8 ; $c442
+ ld hl, Coord
+ call .writemoves
+ ld b, $1
+ ld a, $7
+ jr .menuset
+.relearnmenu
+ ld a, [wWhichPokemon] ; $cf92
+ ld hl, W_PARTYMON1_MOVE1 ; $d173
+ ld bc, $2c
+ call AddNTimes
+ call .loadmoves
+ FuncCoord 4, 7 ; $c430
+ ld hl, Coord
+ ld b, $4
+ ld c, $e
+ call TextBoxBorder
+ FuncCoord 6, 8 ; $c446
+ ld hl, Coord
+ call .writemoves
+ ld b, $5
+ ld a, $7
+.menuset
+ ld hl, wTopMenuItemY ; $cc24
+ ld [hli], a
+ ld a, b
+ ld [hli], a ; wTopMenuItemX
+ ld a, [wMoveMenuType]
+ cp $1
+ jr z, .selectedmoveknown
+ ld a, $1
+ jr nc, .selectedmoveknown
+ ld a, [wPlayerMoveListIndex] ; $cc2e
+ inc a
+.selectedmoveknown
+ ld [hli], a ; wCurrentMenuItem
+ inc hl ; wTileBehindCursor untouched
+ ld a, [$cd6c]
+ inc a
+ inc a
+ ld [hli], a ; wMaxMenuItem
+ ld a, [wMoveMenuType]
+ dec a
+ ld b, $c1 ; can't use B
+ jr z, .matchedkeyspicked
+ dec a
+ ld b, $c3
+ jr z, .matchedkeyspicked
+ ld a, [W_ISLINKBATTLE] ; $d12b
+ cp $4
+ jr z, .matchedkeyspicked
+ ld a, [W_FLAGS_D733]
+ bit 0, a
+ ld b, $c7
+ jr z, .matchedkeyspicked
+ ld b, $ff
+.matchedkeyspicked
+ ld a, b
+ ld [hli], a ; wMenuWatchedKeys
+ ld a, [wMoveMenuType]
+ cp $1
+ jr z, .movelistindex1
+ ld a, [wPlayerMoveListIndex] ; $cc2e
+ inc a
+.movelistindex1
+ ld [hl], a ; wLastMenuItem
+
+Func_3d2fe: ; 3d2fe (f:52fe)
+ ld a, [wMoveMenuType]
+ and a
+ jr z, .battleselect
+ dec a
+ jr nz, .select
+ FuncCoord 1, 14 ; $c4b9
+ ld hl, Coord
+ ld de, WhichTechniqueString ; $53b8
+ call PlaceString
+ jr .select
+.battleselect
+ ld a, [W_FLAGS_D733]
+ bit 0, a
+ jr nz, .select
+ call Func_3d4b6
+ ld a, [$cc35]
+ and a
+ jr z, .select
+ FuncCoord 5, 13 ; $c4a9
+ ld hl, Coord
+ dec a
+ ld bc, $14
+ call AddNTimes
+ ld [hl], $ec
+.select
+ ld hl, $fff6
+ set 1, [hl]
+ call HandleMenuInput
+ ld hl, $fff6
+ res 1, [hl]
+ bit 6, a
+ jp nz, Func_3d3c9 ; up
+ bit 7, a
+ jp nz, Func_3d3dd ; down
+ bit 2, a
+ jp nz, Func_3d435 ; select
+ bit 1, a ; B, but was it reset above?
+ push af
+ xor a
+ ld [$cc35], a
+ ld a, [wCurrentMenuItem] ; $cc26
+ dec a
+ ld [wCurrentMenuItem], a ; $cc26
+ ld b, a
+ ld a, [wMoveMenuType]
+ dec a ; if not mimic
+ jr nz, .nob
+ pop af
+ ret
+.nob
+ dec a
+ ld a, b
+ ld [wPlayerMoveListIndex], a ; $cc2e
+ jr nz, .moveselected
+ pop af
+ ret
+.moveselected
+ pop af
+ ret nz
+ ld hl, W_PLAYERMONPP ; $d02d
+ ld a, [wCurrentMenuItem] ; $cc26
+ ld c, a
+ ld b, $0
+ add hl, bc
+ ld a, [hl]
+ and $3f
+ jr z, .nopp
+ ld a, [W_PLAYERDISABLEDMOVE] ; $d06d
+ swap a
+ and $f
+ dec a
+ cp c
+ jr z, .disabled
+ ld a, [W_PLAYERBATTSTATUS3] ; $d064
+ bit 3, a ; transformed
+ jr nz, .dummy ; game freak derp
+.dummy
+ ld a, [wCurrentMenuItem] ; $cc26
+ ld hl, W_PLAYERMONMOVES
+ ld c, a
+ ld b, $0
+ add hl, bc
+ ld a, [hl]
+ ld [wPlayerSelectedMove], a ; $ccdc
+ xor a
+ ret
+.disabled
+ ld hl, MoveDisabledText
+ jr .print
+.nopp
+ ld hl, MoveNoPPText
+.print
+ call PrintText
+ call LoadScreenTilesFromBuffer1
+ jp MoveSelectionMenu
+
+MoveNoPPText: ; 3d3ae (f:53ae)
+ TX_FAR _MoveNoPPText
+ db "@"
+
+MoveDisabledText: ; 3d3b3 (f:53b3)
+ TX_FAR _MoveDisabledText
+ db "@"
+
+WhichTechniqueString: ; 3d3b8 (f:53b8)
+ db "WHICH TECHNIQUE?@"
+
+Func_3d3c9: ; 3d3c9 (f:53c9)
+ ld a, [wCurrentMenuItem] ; $cc26
+ and a
+ jp nz, Func_3d2fe
+ call EraseMenuCursor
+ ld a, [$cd6c]
+ inc a
+ ld [wCurrentMenuItem], a ; $cc26
+ jp Func_3d2fe
+
+Func_3d3dd: ; 3d3dd (f:53dd)
+ ld a, [wCurrentMenuItem] ; $cc26
+ ld b, a
+ ld a, [$cd6c]
+ inc a
+ inc a
+ cp b
+ jp nz, Func_3d2fe
+ call EraseMenuCursor
+ ld a, $1
+ ld [wCurrentMenuItem], a ; $cc26
+ jp Func_3d2fe
+
+Func_3d3f5: ; 3d3f5 (f:53f5)
+ ld a, $a5
+ ld [wPlayerSelectedMove], a ; $ccdc
+ ld a, [W_PLAYERDISABLEDMOVE] ; $d06d
+ and a
+ ld hl, W_PLAYERMONPP ; $d02d
+ jr nz, .asm_3d40e
+ ld a, [hli]
+ or [hl]
+ inc hl
+ or [hl]
+ inc hl
+ or [hl]
+ and $3f
+ ret nz
+ jr .asm_3d423
+.asm_3d40e
+ swap a
+ and $f
+ ld b, a
+ ld d, $5
+ xor a
+.asm_3d416
+ dec d
+ jr z, .asm_3d421
+ ld c, [hl]
+ inc hl
+ dec b
+ jr z, .asm_3d416
+ or c
+ jr .asm_3d416
+.asm_3d421
+ and a
+ ret nz
+.asm_3d423
+ ld hl, NoMovesLeftText
+ call PrintText
+ ld c, $3c
+ call DelayFrames
+ xor a
+ ret
+
+NoMovesLeftText: ; 3d430 (f:5430)
+ TX_FAR _NoMovesLeftText
+ db "@"
+
+Func_3d435: ; 3d435 (f:5435)
+ ld a, [$cc35]
+ and a
+ jr z, asm_3d4ad
+ ld hl, W_PLAYERMONMOVES
+ call Func_3d493
+ ld hl, W_PLAYERMONPP ; $d02d
+ call Func_3d493
+ ld hl, W_PLAYERDISABLEDMOVE ; $d06d
+ ld a, [hl]
+ swap a
+ and $f
+ ld b, a
+ ld a, [wCurrentMenuItem] ; $cc26
+ cp b
+ jr nz, .asm_3d463
+ ld a, [hl]
+ and $f
+ ld b, a
+ ld a, [$cc35]
+ swap a
+ add b
+ ld [hl], a
+ jr .asm_3d474
+.asm_3d463
+ ld a, [$cc35]
+ cp b
+ jr nz, .asm_3d474
+ ld a, [hl]
+ and $f
+ ld b, a
+ ld a, [wCurrentMenuItem] ; $cc26
+ swap a
+ add b
+ ld [hl], a
+.asm_3d474
+ ld hl, W_PARTYMON1_MOVE1 ; $d173
+ ld a, [wPlayerMonNumber] ; $cc2f
+ ld bc, $2c
+ call AddNTimes
+ push hl
+ call Func_3d493
+ pop hl
+ ld bc, $15
+ add hl, bc
+ call Func_3d493
+ xor a
+ ld [$cc35], a
+ jp MoveSelectionMenu
+
+Func_3d493: ; 3d493 (f:5493)
+ push hl
+ ld a, [$cc35]
+ dec a
+ ld c, a
+ ld b, $0
+ add hl, bc
+ ld d, h
+ ld e, l
+ pop hl
+ ld a, [wCurrentMenuItem] ; $cc26
+ dec a
+ ld c, a
+ ld b, $0
+ add hl, bc
+ ld a, [de]
+ ld b, [hl]
+ ld [hl], a
+ ld a, b
+ ld [de], a
+ ret
+asm_3d4ad: ; 3d4ad (f:54ad)
+ ld a, [wCurrentMenuItem] ; $cc26
+ ld [$cc35], a
+ jp MoveSelectionMenu
+
+Func_3d4b6: ; 3d4b6 (f:54b6)
+ xor a
+ ld [H_AUTOBGTRANSFERENABLED], a ; $ffba
+ FuncCoord 0, 8 ; $c440
+ ld hl, Coord
+ ld b, $3
+ ld c, $9
+ call TextBoxBorder
+ ld a, [W_PLAYERDISABLEDMOVE] ; $d06d
+ and a
+ jr z, .asm_3d4df
+ swap a
+ and $f
+ ld b, a
+ ld a, [wCurrentMenuItem] ; $cc26
+ cp b
+ jr nz, .asm_3d4df
+ FuncCoord 1, 10 ; $c469
+ ld hl, Coord
+ ld de, DisabledText
+ call PlaceString
+ jr .asm_3d54e
+.asm_3d4df
+ ld hl, wCurrentMenuItem ; $cc26
+ dec [hl]
+ xor a
+ ld [H_WHOSETURN], a ; $fff3
+ ld hl, W_PLAYERMONMOVES
+ ld a, [wCurrentMenuItem] ; $cc26
+ ld c, a
+ ld b, $0
+ add hl, bc
+ ld a, [hl]
+ ld [wPlayerSelectedMove], a ; $ccdc
+ ld a, [wPlayerMonNumber] ; $cc2f
+ ld [wWhichPokemon], a ; $cf92
+ ld a, $4
+ ld [$cc49], a
+ callab GetMaxPP
+ ld hl, wCurrentMenuItem ; $cc26
+ ld c, [hl]
+ inc [hl]
+ ld b, $0
+ ld hl, W_PLAYERMONPP ; $d02d
+ add hl, bc
+ ld a, [hl]
+ and $3f
+ ld [$cd6d], a
+ FuncCoord 1, 9 ; $c455
+ ld hl, Coord
+ ld de, TypeText
+ call PlaceString
+ FuncCoord 7, 11 ; $c483
+ ld hl, Coord
+ ld [hl], "/"
+ FuncCoord 5, 9 ; $c459
+ ld hl, Coord
+ ld [hl], "/"
+ FuncCoord 5, 11 ; $c481
+ ld hl, Coord
+ ld de, $cd6d
+ ld bc, $102
+ call PrintNumber
+ FuncCoord 8, 11 ; $c484
+ ld hl, Coord
+ ld de, $d11e
+ ld bc, $102
+ call PrintNumber
+ call GetCurrentMove
+ FuncCoord 2, 10 ; $c46a
+ ld hl, Coord
+ ld a, $5d
+ call Predef ; indirect jump to Func_27d98 (27d98 (9:7d98))
+.asm_3d54e
+ ld a, $1
+ ld [H_AUTOBGTRANSFERENABLED], a ; $ffba
+ jp Delay3
+
+DisabledText: ; 3d555 (f:5555)
+ db "disabled!@"
+
+TypeText: ; 3d55f (f:555f)
+ db "TYPE@"
+
+SelectEnemyMove: ; 3d564 (f:5564)
+ ld a, [W_ISLINKBATTLE]
+ sub $4
+ jr nz, .noLinkBattle
+ call SaveScreenTilesToBuffer1
+ call Func_3d605
+ call LoadScreenTilesFromBuffer1
+ ld a, [$cc3e]
+ cp $e
+ jp z, .asm_3d601
+ cp $d
+ jr z, .unableToMove
+ cp $4
+ ret nc
+ ld [$cce2], a
+ ld c, a
+ ld hl, W_ENEMYMONMOVES
+ ld b, $0
+ add hl, bc
+ ld a, [hl]
+ jr .done
+.noLinkBattle
+ ld a, [W_ENEMYBATTSTATUS2]
+ and $60 ; need to recharge or using rage
+ ret nz
+ ld hl, W_ENEMYBATTSTATUS1
+ ld a, [hl]
+ and $12 ; using multi-turn move or bide
+ ret nz
+ ld a, [W_ENEMYMONSTATUS]
+ and SLP | 1 << FRZ ; sleeping or frozen
+ ret nz
+ ld a, [W_ENEMYBATTSTATUS1]
+ and $21 ; using fly/dig or thrash/petal dance
+ ret nz
+ ld a, [W_PLAYERBATTSTATUS1]
+ bit 5, a ; caught in player's multi-turn move (e.g. wrap)
+ jr z, .notCaughtInWrap
+.unableToMove
+ ld a, $ff
+ jr .done
+.notCaughtInWrap
+ ld hl, W_ENEMYMONMOVES+1 ; 2nd enemy move
+ ld a, [hld]
+ and a
+ jr nz, .atLeastTwoMovesAvailable
+ ld a, [W_ENEMYDISABLEDMOVE]
+ and a
+ ld a, STRUGGLE ; struggle if the only move is disabled
+ jr nz, .done
+.atLeastTwoMovesAvailable
+ ld a, [W_ISINBATTLE]
+ dec a
+ jr z, .chooseRandomMove ; wild encounter
+ callab AIEnemyTrainerChooseMoves
+.chooseRandomMove
+ push hl
+ call GenRandomInBattle ; get random
+ ld b, $1
+ cp $3f ; select move 1 in [0,3e] (63/256 chance)
+ jr c, .moveChosen
+ inc hl
+ inc b
+ cp $7f ; select move 1 in [3f,7e] (64/256 chance)
+ jr c, .moveChosen
+ inc hl
+ inc b
+ cp $be ; select move 1 in [7f,bd] (63/256 chance)
+ jr c, .moveChosen
+ inc hl
+ inc b ; select move 4 in [be,ff] (66/256 chance)
+.moveChosen
+ ld a, b
+ dec a
+ ld [wEnemyMoveListIndex], a
+ ld a, [W_ENEMYDISABLEDMOVE]
+ swap a
+ and $f
+ cp b
+ ld a, [hl]
+ pop hl
+ jr z, .chooseRandomMove ; move disabled, try again
+ and a
+ jr z, .chooseRandomMove ; move non-existant, try again
+.done
+ ld [wEnemySelectedMove], a
+ ret
+.asm_3d601
+ ld a, $a5
+ jr .done
+
+Func_3d605: ; 3d605 (f:5605)
+ ld a, $ff
+ ld [$cc3e], a
+ ld a, [wPlayerMoveListIndex] ; $cc2e
+ cp $f
+ jr z, .asm_3d630
+ ld a, [$cd6a]
+ and a
+ jr nz, .asm_3d629
+ ld a, [wPlayerSelectedMove] ; $ccdc
+ cp $a5
+ ld b, $e
+ jr z, .asm_3d62f
+ dec b
+ inc a
+ jr z, .asm_3d62f
+ ld a, [wPlayerMoveListIndex] ; $cc2e
+ jr .asm_3d630
+.asm_3d629
+ ld a, [wWhichPokemon] ; $cf92
+ add $4
+ ld b, a
+.asm_3d62f
+ ld a, b
+.asm_3d630
+ ld [$cc42], a
+ callab PrintWaitingText
+.asm_3d63b
+ call Func_22c3
+ call DelayFrame
+ ld a, [$cc3e]
+ inc a
+ jr z, .asm_3d63b
+ ld b, $a
+.asm_3d649
+ call DelayFrame
+ call Func_22c3
+ dec b
+ jr nz, .asm_3d649
+ ld b, $a
+.asm_3d654
+ call DelayFrame
+ call Func_22ed
+ dec b
+ jr nz, .asm_3d654
+ ret
+
+Func_3d65e: ; 3d65e (f:565e)
+ xor a
+ ld [H_WHOSETURN], a ; $fff3
+ ld a, [wPlayerSelectedMove] ; $ccdc
+ inc a
+ jp z, Func_3d80a
+ xor a
+ ld [W_MOVEMISSED], a ; $d05f
+ ld [$cced], a
+ ld [$ccf4], a
+ ld a, $a
+ ld [$d05b], a
+ ld a, [$cd6a]
+ and a
+ jp nz, Func_3d80a
+ call PrintGhostText
+ jp z, Func_3d80a
+ call Func_3d854
+ jr nz, .asm_3d68a
+ jp [hl]
+.asm_3d68a
+ call GetCurrentMove
+ ld hl, W_PLAYERBATTSTATUS1 ; $d062
+ bit 4, [hl]
+ jr nz, asm_3d6a9
+ call Func_3dc88
+ jp z, Func_3d80a
+
+Func_3d69a: ; 3d69a (f:569a)
+ ld a, [W_PLAYERMOVEEFFECT] ; $cfd3
+ cp CHARGE_EFFECT
+ jp z, Func_3f132
+ cp FLY_EFFECT
+ jp z, Func_3f132
+ jr asm_3d6b0
+
+; in-battle stuff
+asm_3d6a9: ; 3d6a9 (f:56a9)
+ ld hl,W_PLAYERBATTSTATUS1
+ res 4,[hl]
+ res 6,[hl]
+asm_3d6b0: ; 3d6b0 (f:56b0)
+ call PrintMonName1Text
+ ld hl,DecrementPP
+ ld de,$CCDC ; pointer to the move just used
+ ld b,BANK(DecrementPP)
+ call Bankswitch
+ ld a,[W_PLAYERMOVEEFFECT] ; effect of the move just used
+ ld hl,EffectsArray1
+ ld de,1
+ call IsInArray
+ jp c,Func_3f132
+ ld a,[W_PLAYERMOVEEFFECT]
+ ld hl,EffectsArray5B
+ ld de,1
+ call IsInArray
+ call c,Func_3f132
+asm_3d6dc: ; 3d6dc (f:56dc)
+ ld a,[W_PLAYERMOVEEFFECT]
+ ld hl,EffectsArray2
+ ld de,1
+ call IsInArray
+ jp c,.asm_3d702
+ call CriticalHitTest
+ call HandleCounterMove
+ jr z,asm_3d705
+ call CalculateDamage
+ call MoreCalculateDamage
+ jp z,asm_3d74b
+ call AdjustDamageForMoveType
+ call Func_3e687
+.asm_3d702
+ call MoveHitTest
+asm_3d705
+ ld a,[W_MOVEMISSED]
+ and a
+ jr z,asm_3d714
+ ld a,[W_PLAYERMOVEEFFECT]
+ sub a,7
+ jr z,asm_3d71e
+ jr asm_3d74b ; 574B
+asm_3d714
+ ld a,[W_PLAYERMOVEEFFECT]
+ and a
+ ld a,4
+ jr z,asm_3d71e
+ ld a,5
+asm_3d71e
+ push af
+ ld a,[W_PLAYERBATTSTATUS2]
+ bit 4,a
+ ld hl,Func_79747
+ ld b,BANK(Func_79747)
+ call nz,Bankswitch
+ pop af
+ ld [$CC5B],a
+ ld a,[W_PLAYERMOVENUM]
+ call PlayMoveAnimation
+ call Func_3eed3
+ call Func_3cd60
+ ld a,[W_PLAYERBATTSTATUS2]
+ bit 4,a
+ ld hl,Func_79771
+ ld b,BANK(Func_79771)
+ call nz,Bankswitch
+ jr asm_3d766
+asm_3d74b
+ ld c,$1E
+ call DelayFrames
+ ld a,[W_PLAYERMOVEEFFECT]
+ cp a,FLY_EFFECT
+ jr z,.next5
+ cp a,CHARGE_EFFECT
+ jr z,.next5
+ jr asm_3d766
+.next5
+ xor a
+ ld [$CC5B],a
+ ld a,STATUS_AFFECTED_ANIM
+ call PlayMoveAnimation
+asm_3d766
+ ld a,[W_PLAYERMOVEEFFECT]
+ cp a,MIRROR_MOVE_EFFECT
+ jr nz,.next6 ; 577A
+ call MirrorMoveCopyMove
+ jp z,Func_3d80a
+ xor a
+ ld [$CCED],a
+ jp Func_3d69a
+.next6
+ cp a,METRONOME_EFFECT
+ jr nz,.next7 ; 5784
+ call MetronomePickMove
+ jp Func_3d69a
+.next7
+ ld a,[W_PLAYERMOVEEFFECT]
+ ld hl,EffectsArray3
+ ld de,1
+ call IsInArray
+ jp c,Func_3f132
+ ld a,[W_MOVEMISSED]
+ and a
+ jr z,.next8 ; 57A6
+ call PrintMoveFailureText
+ ld a,[W_PLAYERMOVEEFFECT]
+ cp a,EXPLODE_EFFECT
+ jr z,.next9 ; 57B9
+ jp Func_3d80a
+.next8
+ call ApplyAttackToEnemyPokemon
+ call Func_3dc5c
+ callab DisplayEffectiveness
+ ld a,1
+ ld [$CCF4],a
+.next9
+ ld a,[W_PLAYERMOVEEFFECT]
+ ld hl,EffectsArray4
+ ld de,1
+ call IsInArray
+ call c,Func_3f132
+ ld hl,$CFE6
+ ld a,[hli]
+ ld b,[hl]
+ or b
+ ret z
+ call HandleBuildingRage
+
+ ld hl,W_PLAYERBATTSTATUS1
+ bit 2,[hl]
+ jr z,.next10 ; 57EF
+ ld a,[$D06A]
+ dec a
+ ld [$D06A],a
+ jp nz,asm_3d714
+
+ res 2,[hl]
+ ld hl,MultiHitText
+ call PrintText
+ xor a
+ ld [W_NUMHITS],a ; reset
+.next10
+ ld a,[W_PLAYERMOVEEFFECT]
+ and a
+ jp z,Func_3d80a
+ ld hl,EffectsArray5
+ ld de,1
+ call IsInArray
+ call nc,Func_3f132
+ jp Func_3d80a
+
+MultiHitText: ; 3d805 (f:5805)
+ TX_FAR _MultiHitText
+ db "@"
+
+Func_3d80a: ; 3d80a (f:580a)
+ xor a
+ ld [$CD6A],a
+ ld b,1
+ ret
+
+PrintGhostText: ; 3d811 (f:5811)
+; print the ghost battle messages
+ call IsGhostBattle
+ ret nz
+ ld a,[H_WHOSETURN]
+ and a
+ jr nz,.Ghost
+ ld a,[W_PLAYERMONSTATUS] ; player’s turn
+ and a,SLP | (1 << FRZ)
+ ret nz
+ ld hl,ScaredText
+ call PrintText
+ xor a
+ ret
+.Ghost ; ghost’s turn
+ ld hl,GetOutText
+ call PrintText
+ xor a
+ ret
+
+ScaredText: ; 3d830 (f:5830)
+ TX_FAR _ScaredText
+ db "@"
+
+GetOutText: ; 3d835 (f:5835)
+ TX_FAR _GetOutText
+ db "@"
+
+IsGhostBattle: ; 3d83a (f:583a)
+ ld a,[W_ISINBATTLE]
+ dec a
+ ret nz
+ ld a,[W_CURMAP]
+ cp a,POKEMONTOWER_1
+ jr c,.next
+ cp a,LAVENDER_HOUSE_1
+ jr nc,.next
+ ld b,SILPH_SCOPE
+ call IsItemInBag ; $3493
+ ret z
+.next
+ ld a,1
+ and a
+ ret
+
+Func_3d854: ; 3d854 (f:5854)
+ ld hl,W_PLAYERMONSTATUS
+ ld a,[hl]
+ and a,SLP
+ jr z,.FrozenCheck ; to 5884
+
+ dec a
+ ld [W_PLAYERMONSTATUS],a ; decrement sleep count
+ and a
+ jr z,.WakeUp ; to 5874
+
+ xor a
+ ld [$CC5B],a
+ ld a,SLP_ANIM - 1
+ call PlayMoveAnimation
+ ld hl,FastAsleepText
+ call PrintText
+ jr .sleepDone
+.WakeUp
+ ld hl,WokeUpText
+ call PrintText
+.sleepDone
+ xor a
+ ld [$CCF1],a
+ ld hl,Func_3d80a
+ jp Func_3da37
+
+.FrozenCheck
+ bit FRZ,[hl] ; frozen?
+ jr z,.HeldInPlaceCheck ; to 5898
+ ld hl,IsFrozenText
+ call PrintText
+ xor a
+ ld [$CCF1],a
+ ld hl,Func_3d80a
+ jp Func_3da37
+
+.HeldInPlaceCheck
+ ld a,[W_ENEMYBATTSTATUS1]
+ bit 5,a
+ jp z,FlinchedCheck
+ ld hl,CantMoveText
+ call PrintText
+ ld hl,Func_3d80a
+ jp Func_3da37
+
+FlinchedCheck: ; 3d8ac (f:58ac)
+ ld hl,W_PLAYERBATTSTATUS1
+ bit 3,[hl]
+ jp z,HyperBeamCheck
+ res 3,[hl]
+ ld hl,FlinchedText
+ call PrintText
+ ld hl,Func_3d80a
+ jp Func_3da37
+
+HyperBeamCheck: ; 3d8c2 (f:58c2)
+ ld hl,W_PLAYERBATTSTATUS2
+ bit 5,[hl]
+ jr z,.next ; 58D7
+ res 5,[hl]
+ ld hl,MustRechargeText
+ call PrintText
+ ld hl,Func_3d80a ; $580a
+ jp Func_3da37
+.next
+ ld hl,$D06D
+ ld a,[hl]
+ and a
+ jr z,.next2 ; 58EE
+ dec a
+ ld [hl],a
+ and a,$F
+ jr nz,.next2
+ ld [hl],a
+ ld [$CCEE],a
+ ld hl,DisabledNoMoreText
+ call PrintText
+.next2
+ ld a,[W_PLAYERBATTSTATUS1]
+ add a
+ jr nc,.next3 ; 5929
+ ld hl,$D06B
+ dec [hl]
+ jr nz,.next4 ; 5907
+ ld hl,W_PLAYERBATTSTATUS1
+ res 7,[hl]
+ ld hl,ConfusedNoMoreText
+ call PrintText
+ jr .next3
+.next4
+ ld hl,IsConfusedText
+ call PrintText
+ xor a
+ ld [$CC5B],a
+ ld a,CONF_ANIM - 1
+ call PlayMoveAnimation
+ call GenRandomInBattle
+ cp a,$80
+ jr c,.next3
+ ld hl,W_PLAYERBATTSTATUS1
+ ld a,[hl]
+ and a,$80 ; confused
+ ld [hl],a
+ call PrintHurtItselfText
+ jr .next5 ; 5952
+.next3
+ ld a,[$CCEE]
+ and a
+ jr z,.ParalysisCheck ; 593E
+ ld hl,$CCDC
+ cp [hl]
+ jr nz,.ParalysisCheck
+ call PrintMoveIsDisabledText
+ ld hl,Func_3d80a ; $580a
+ jp Func_3da37
+.ParalysisCheck
+ ld hl,W_PLAYERMONSTATUS
+ bit PAR,[hl]
+ jr z,.next7 ; 5975
+ call GenRandomInBattle ; random number
+ cp a,$3F
+ jr nc,.next7
+ ld hl,FullyParalyzedText
+ call PrintText
+.next5
+ ld hl,W_PLAYERBATTSTATUS1
+ ld a,[hl]
+ and a,$CC
+ ld [hl],a
+ ld a,[W_PLAYERMOVEEFFECT]
+ cp a,FLY_EFFECT
+ jr z,.next8 ; 5966
+ cp a,CHARGE_EFFECT
+ jr z,.next8
+ jr .next9 ; 596F
+.next8
+ xor a
+ ld [$CC5B],a
+ ld a,STATUS_AFFECTED_ANIM
+ call PlayMoveAnimation
+.next9
+ ld hl,Func_3d80a ; $580a
+ jp Func_3da37
+.next7
+ ld hl,W_PLAYERBATTSTATUS1
+ bit 0,[hl]
+ jr z,.next10 ; 59D0
+ xor a
+ ld [W_PLAYERMOVENUM],a
+ ld hl,$D0D7
+ ld a,[hli]
+ ld b,a
+ ld c,[hl]
+ ld hl,$D075
+ ld a,[hl]
+ add c
+ ld [hld],a
+ ld a,[hl]
+ adc b
+ ld [hl],a
+ ld hl,$D06A
+ dec [hl]
+ jr z,.next11 ; 599B
+ ld hl,Func_3d80a ; $580a
+ jp Func_3da37
+.next11
+ ld hl,W_PLAYERBATTSTATUS1
+ res 0,[hl]
+ ld hl,UnleashedEnergyText
+ call PrintText
+ ld a,1
+ ld [$CFD4],a
+ ld hl,$D075
+ ld a,[hld]
+ add a
+ ld b,a
+ ld [$D0D8],a
+ ld a,[hl]
+ rl a
+ ld [$D0D7],a
+ or b
+ jr nz,.next12 ; 59C2
+ ld a,1
+ ld [W_MOVEMISSED],a
+.next12
+ xor a
+ ld [hli],a
+ ld [hl],a
+ ld a,BIDE
+ ld [W_PLAYERMOVENUM],a
+ ld hl,asm_3d705 ; $5705
+ jp Func_3da37
+.next10
+ bit 1,[hl]
+ jr z,.next13 ; 59FF
+ ld a,THRASH
+ ld [W_PLAYERMOVENUM],a
+ ld hl,ThrashingAboutText
+ call PrintText
+ ld hl,$D06A
+ dec [hl]
+ ld hl,asm_3d6dc ; $56dc
+ jp nz,Func_3da37
+ push hl
+ ld hl,W_PLAYERBATTSTATUS1
+ res 1,[hl]
+ set 7,[hl]
+ call GenRandomInBattle ; random number
+ and a,3
+ inc a
+ inc a
+ ld [$D06B],a
+ pop hl
+ jp Func_3da37
+.next13
+ bit 5,[hl]
+ jp z,Func_3da1a
+ ld hl,AttackContinuesText
+ call PrintText
+ ld a,[$D06A]
+ dec a
+ ld [$D06A],a
+ ld hl,asm_3d714 ; $5714
+ jp nz,Func_3da37
+ jp Func_3da37
+
+Func_3da1a: ; 3da1a (f:5a1a)
+ ld a, [W_PLAYERBATTSTATUS2] ; $d063
+ bit 6, a
+ jp z, Func_3da39
+ ld a, RAGE
+ ld [$d11e], a
+ call GetMoveName
+ call CopyStringToCF4B
+ xor a
+ ld [W_PLAYERMOVEEFFECT], a ; $cfd3
+ ld hl, asm_3d6b0 ; $56b0
+ jp Func_3da37
+
+Func_3da37: ; 3da37 (f:5a37)
+ xor a
+ ret
+
+Func_3da39: ; 3da39 (f:5a39)
+ ld a, $1
+ and a
+ ret
+
+FastAsleepText: ; 3da3d (f:5a3d)
+ TX_FAR _FastAsleepText
+ db "@"
+
+WokeUpText: ; 3da42 (f:5a42)
+ TX_FAR _WokeUpText
+ db "@"
+
+IsFrozenText: ; 3da47 (f:5a47)
+ TX_FAR _IsFrozenText
+ db "@"
+
+FullyParalyzedText: ; 3da4c (f:5a4c)
+ TX_FAR _FullyParalyzedText
+ db "@"
+
+FlinchedText: ; 3da51 (f:5a51)
+ TX_FAR _FlinchedText
+ db "@"
+
+MustRechargeText: ; 3da56 (f:5a56)
+ TX_FAR _MustRechargeText
+ db "@"
+
+DisabledNoMoreText: ; 3da5b (f:5a5b)
+ TX_FAR _DisabledNoMoreText
+ db "@"
+
+IsConfusedText: ; 3da60 (f:5a60)
+ TX_FAR _IsConfusedText
+ db "@"
+
+HurtItselfText: ; 3da65 (f:5a65)
+ TX_FAR _HurtItselfText
+ db "@"
+
+ConfusedNoMoreText: ; 3da6a (f:5a6a)
+ TX_FAR _ConfusedNoMoreText
+ db "@"
+
+SavingEnergyText: ; 3da6f (f:5a6f)
+ TX_FAR _SavingEnergyText
+ db "@"
+
+UnleashedEnergyText: ; 3da74 (f:5a74)
+ TX_FAR _UnleashedEnergyText
+ db "@"
+
+ThrashingAboutText: ; 3da79 (f:5a79)
+ TX_FAR _ThrashingAboutText
+ db "@"
+
+AttackContinuesText: ; 3da7e (f:5a7e)
+ TX_FAR _AttackContinuesText
+ db "@"
+
+CantMoveText: ; 3da83 (f:5a83)
+ TX_FAR _CantMoveText
+ db "@"
+
+PrintMoveIsDisabledText: ; 3da88 (f:5a88)
+ ld hl, wPlayerSelectedMove ; $ccdc
+ ld de, W_PLAYERBATTSTATUS1 ; $d062
+ ld a, [H_WHOSETURN] ; $fff3
+ and a
+ jr z, .asm_3da97
+ inc hl
+ ld de, W_ENEMYBATTSTATUS1 ; $d067
+.asm_3da97
+ ld a, [de]
+ res 4, a
+ ld [de], a
+ ld a, [hl]
+ ld [$d11e], a
+ call GetMoveName
+ ld hl, MoveIsDisabledText
+ jp PrintText
+
+MoveIsDisabledText: ; 3daa8 (f:5aa8)
+ TX_FAR _MoveIsDisabledText
+ db "@"
+
+PrintHurtItselfText: ; 3daad (f:5aad)
+ ld hl, HurtItselfText
+ call PrintText
+ ld hl, W_ENEMYMONDEFENSE ; $cff8
+ ld a, [hli]
+ push af
+ ld a, [hld]
+ push af
+ ld a, [W_PLAYERMONDEF]
+ ld [hli], a
+ ld a, [$d028]
+ ld [hl], a
+ ld hl, W_PLAYERMOVEEFFECT ; $cfd3
+ push hl
+ ld a, [hl]
+ push af
+ xor a
+ ld [hli], a
+ ld [$d05e], a
+ ld a, $28
+ ld [hli], a
+ xor a
+ ld [hl], a
+ call CalculateDamage
+ call MoreCalculateDamage
+ pop af
+ pop hl
+ ld [hl], a
+ ld hl, $cff9
+ pop af
+ ld [hld], a
+ pop af
+ ld [hl], a
+ xor a
+ ld [$cc5b], a
+ inc a
+ ld [H_WHOSETURN], a ; $fff3
+ call PlayMoveAnimation
+ call Func_3cd60
+ xor a
+ ld [H_WHOSETURN], a ; $fff3
+ jp ApplyDamageToPlayerPokemon
+
+PrintMonName1Text: ; 3daf5 (f:5af5)
+ ld hl, MonName1Text
+ jp PrintText
+
+MonName1Text: ; 3dafb (f:5afb)
+ TX_FAR _MonName1Text
+ db $08 ; asm
+ ld a, [H_WHOSETURN] ; $fff3
+ and a
+ ld a, [W_PLAYERMOVENUM] ; $cfd2
+ ld hl, $ccf1
+ jr z, .asm_3db11
+ ld a, [W_ENEMYMOVENUM] ; $cfcc
+ ld hl, $ccf2
+.asm_3db11
+ ld [hl], a
+ ld [$d11e], a
+ call Func_3db85
+ ld a, [$cced]
+ and a
+ ld hl, Used2Text
+ ret nz
+ ld a, [$d11e]
+ cp DOUBLESLAP
+ ld hl, Used2Text
+ ret c
+ ld hl, Used1Text
+ ret
+
+Used1Text: ; 3db2d (f:5b2d)
+ TX_FAR _Used1Text
+ db $08 ; asm
+ jr PrintInsteadText
+
+Used2Text: ; 3db34 (f:5b34)
+ TX_FAR _Used2Text
+ db $08 ; asm
+
+PrintInsteadText: ; 3db39 (f:5b39)
+ ld a, [$cced]
+ and a
+ jr z, PrintCF4BText
+ ld hl, InsteadText
+ ret
+
+InsteadText: ; 3db43 (f:5b43)
+ TX_FAR _InsteadText
+ db $08 ; asm
+
+PrintCF4BText: ; 3db48 (f:5b48)
+ ld hl, CF4BText
+ ret
+
+CF4BText: ; 3db4c (f:5b4c)
+ TX_FAR _CF4BText
+ db $08 ; asm
+ ld hl, ExclamationPointPointerTable
+ ld a, [$d11e]
+ add a
+ push bc
+ ld b, $0
+ ld c, a
+ add hl, bc
+ pop bc
+ ld a, [hli]
+ ld h, [hl]
+ ld l, a
+ ret
+
+ExclamationPointPointerTable: ; 3db62 (f:5b62)
+ dw ExclamationPoint1Text
+ dw ExclamationPoint2Text
+ dw ExclamationPoint3Text
+ dw ExclamationPoint4Text
+ dw ExclamationPoint5Text
+
+ExclamationPoint1Text: ; 3db6c (f:5b6c)
+ TX_FAR _ExclamationPoint1Text
+ db "@"
+
+ExclamationPoint2Text: ; 3db71 (f:5b71)
+ TX_FAR _ExclamationPoint2Text
+ db "@"
+
+ExclamationPoint3Text: ; 3db76 (f:5b76)
+ TX_FAR _ExclamationPoint3Text
+ db "@"
+
+ExclamationPoint4Text: ; 3db7b (f:5b7b)
+ TX_FAR _ExclamationPoint4Text
+ db "@"
+
+ExclamationPoint5Text: ; 3db80 (f:5b80)
+ TX_FAR _ExclamationPoint5Text
+ db "@"
+
+Func_3db85: ; 3db85 (f:5b85)
+ push bc
+ ld a, [$d11e] ; move number
+ ld c, a
+ ld b, $0
+ ld hl, UnknownMovesList_3dba3 ; $5ba3
+.asm_3db8f
+ ld a, [hli]
+ cp $ff
+ jr z, .asm_3db9d
+ cp c
+ jr z, .asm_3db9d
+ and a
+ jr nz, .asm_3db8f
+ inc b
+ jr .asm_3db8f
+.asm_3db9d
+ ld a, b
+ ld [$d11e], a
+ pop bc
+ ret
+
+UnknownMovesList_3dba3: ; 3dba3 (f:5ba3)
+ db SWORDS_DANCE, GROWTH
+ db $00
+ db RECOVER, BIDE, SELFDESTRUCT, AMNESIA
+ db $00
+ db MEDITATE, AGILITY, TELEPORT, MIMIC, DOUBLE_TEAM, BARRAGE
+ db $00
+ db POUND, SCRATCH, VICEGRIP, WING_ATTACK, FLY, BIND, SLAM, HORN_ATTACK, BODY_SLAM
+ db WRAP, THRASH, TAIL_WHIP, LEER, BITE, GROWL, ROAR, SING, PECK, COUNTER
+ db STRENGTH, ABSORB, STRING_SHOT, EARTHQUAKE, FISSURE, DIG, TOXIC, SCREECH, HARDEN
+ db MINIMIZE, WITHDRAW, DEFENSE_CURL, METRONOME, LICK, CLAMP, CONSTRICT, POISON_GAS
+ db LEECH_LIFE, BUBBLE, FLASH, SPLASH, ACID_ARMOR, FURY_SWIPES, REST, SHARPEN, SLASH, SUBSTITUTE
+ db $00
+ db $FF ; terminator
+
+PrintMoveFailureText: ; 3dbe2 (f:5be2)
+ ld de, W_PLAYERMOVEEFFECT ; $cfd3
+ ld a, [H_WHOSETURN] ; $fff3
+ and a
+ jr z, .asm_3dbed
+ ld de, W_ENEMYMOVEEFFECT ; $cfcd
+.asm_3dbed
+ ld hl, DoesntAffectMonText ; $5c57
+ ld a, [$d05b]
+ and $7f
+ jr z, .asm_3dc04
+ ld hl, AttackMissedText ; $5c42
+ ld a, [$d05e]
+ cp $ff
+ jr nz, .asm_3dc04
+ ld hl, UnaffectedText ; $5c4c
+.asm_3dc04
+ push de
+ call PrintText
+ xor a
+ ld [$d05e], a
+ pop de
+ ld a, [de]
+ cp JUMP_KICK_EFFECT
+ ret nz
+
+ ; if you get here, the mon used hi jump kick and missed
+ ld hl, W_DAMAGE ; $d0d7
+ ld a, [hli]
+ ld b, [hl]
+ srl a
+ rr b
+ srl a
+ rr b
+ srl a
+ rr b
+ ld [hl], b
+ dec hl
+ ld [hli], a
+ or b
+ jr nz, .asm_3dc2a
+ inc a
+ ld [hl], a
+.asm_3dc2a
+ ld hl, KeptGoingAndCrashedText ; $5c47
+ call PrintText
+ ld b, $4
+ ld a, $24
+ call Predef ; indirect jump to Func_48125 (48125 (12:4125))
+ ld a, [H_WHOSETURN] ; $fff3
+ and a
+ jr nz, .asm_3dc3f
+ jp ApplyDamageToPlayerPokemon
+.asm_3dc3f
+ jp ApplyDamageToEnemyPokemon
+
+AttackMissedText: ; 3dc42 (f:5c42)
+ TX_FAR _AttackMissedText
+ db "@"
+
+KeptGoingAndCrashedText: ; 3dc47 (f:5c47)
+ TX_FAR _KeptGoingAndCrashedText
+ db "@"
+
+UnaffectedText: ; 3dc4c (f:5c4c)
+ TX_FAR _UnaffectedText
+ db "@"
+
+PrintDoesntAffectText: ; 3dc51 (f:5c51)
+ ld hl, DoesntAffectMonText ; $5c57
+ jp PrintText
+
+DoesntAffectMonText: ; 3dc57 (f:5c57)
+ TX_FAR _DoesntAffectMonText
+ db "@"
+
+Func_3dc5c: ; 3dc5c (f:5c5c)
+ ld a, [$d05e]
+ and a
+ jr z, .asm_3dc75
+ dec a
+ add a
+ ld hl, CriticalOHKOTextPointers ; $5c7a
+ ld b, $0
+ ld c, a
+ add hl, bc
+ ld a, [hli]
+ ld h, [hl]
+ ld l, a
+ call PrintText
+ xor a
+ ld [$d05e], a
+.asm_3dc75
+ ld c, $14
+ jp DelayFrames
+
+CriticalOHKOTextPointers: ; 3dc7a (f:5c7a)
+ dw CriticalHitText
+ dw OHKOText
+
+CriticalHitText: ; 3dc7e (f:5c7e)
+ TX_FAR _CriticalHitText
+ db "@"
+
+OHKOText: ; 3dc83 (f:5c83)
+ TX_FAR _OHKOText
+ db "@"
+
+Func_3dc88: ; 3dc88 (f:5c88)
+ xor a
+ ld [$cced], a
+ ld a, [W_ISLINKBATTLE] ; $d12b
+ cp $4
+ jr nz, .asm_3dc97
+ ld a, $1
+ and a
+ ret
+.asm_3dc97
+ ld hl, W_PARTYMON1_OTID ; $d177
+ ld bc, $2c
+ ld a, [wPlayerMonNumber] ; $cc2f
+ call AddNTimes
+ ld a, [wPlayerID] ; $d359
+ cp [hl]
+ jr nz, .asm_3dcb1
+ inc hl
+ ld a, [wPlayerID + 1] ; $d35a
+ cp [hl]
+ jp z, Func_3ddb0
+.asm_3dcb1
+; what level might disobey?
+ ld hl, W_OBTAINEDBADGES
+ bit 7, [hl]
+ ld a, 101
+ jr nz, .asm_3dcce
+ bit 5, [hl]
+ ld a, 70
+ jr nz, .asm_3dcce
+ bit 3, [hl]
+ ld a, 50
+ jr nz, .asm_3dcce
+ bit 1, [hl]
+ ld a, 30
+ jr nz, .asm_3dcce
+ ld a, 10
+.asm_3dcce
+ ld b, a
+ ld c, a
+ ld a, [W_PLAYERMONLEVEL] ; $d022
+ ld d, a
+ add b
+ ld b, a
+ jr nc, .asm_3dcda
+ ld b, $ff
+.asm_3dcda
+ ld a, c
+ cp d
+ jp nc, Func_3ddb0
+.asm_3dcdf
+ call GenRandomInBattle
+ swap a
+ cp b
+ jr nc, .asm_3dcdf
+ cp c
+ jp c, Func_3ddb0
+.asm_3dceb
+ call GenRandomInBattle
+ cp b
+ jr nc, .asm_3dceb
+ cp c
+ jr c, .asm_3dd3f
+ ld a, d
+ sub c
+ ld b, a
+ call GenRandomInBattle
+ swap a
+ sub b
+ jr c, .asm_3dd0e
+ cp b
+ jr nc, .asm_3dd20
+ ld hl, WontObeyText
+ call PrintText
+ call PrintHurtItselfText
+ jp Func_3ddb4
+.asm_3dd0e
+ call GenRandomInBattle
+ add a
+ swap a
+ and $7
+ jr z, .asm_3dd0e
+ ld [W_PLAYERMONSTATUS], a ; $d018
+ ld hl, BeganToNapText
+ jr .asm_3dd3a
+.asm_3dd20
+ call GenRandomInBattle
+ and $3
+ ld hl, LoafingAroundText
+ and a
+ jr z, .asm_3dd3a
+ ld hl, WontObeyText
+ dec a
+ jr z, .asm_3dd3a
+ ld hl, TurnedAwayText
+ dec a
+ jr z, .asm_3dd3a
+ ld hl, IgnoredOrdersText
+.asm_3dd3a
+ call PrintText
+ jr Func_3ddb4
+.asm_3dd3f
+ ld a, [$d01d]
+ and a
+ jr z, .asm_3dd20
+ ld a, [$ccee]
+ and a
+ jr nz, .asm_3dd20
+ ld a, [wPlayerSelectedMove] ; $ccdc
+ cp $a5
+ jr z, .asm_3dd20
+ ld hl, W_PLAYERMONPP ; $d02d
+ push hl
+ ld a, [hli]
+ and $3f
+ ld b, a
+ ld a, [hli]
+ and $3f
+ add b
+ ld b, a
+ ld a, [hli]
+ and $3f
+ add b
+ ld b, a
+ ld a, [hl]
+ and $3f
+ add b
+ pop hl
+ push af
+ ld a, [wCurrentMenuItem] ; $cc26
+ ld c, a
+ ld b, $0
+ add hl, bc
+ ld a, [hl]
+ and $3f
+ ld b, a
+ pop af
+ cp b
+ jr z, .asm_3dd20
+ ld a, $1
+ ld [$cced], a
+ ld a, [wMaxMenuItem] ; $cc28
+ ld b, a
+ ld a, [wCurrentMenuItem] ; $cc26
+ ld c, a
+.asm_3dd86
+ call GenRandomInBattle
+ and $3
+ cp b
+ jr nc, .asm_3dd86
+ cp c
+ jr z, .asm_3dd86
+ ld [wCurrentMenuItem], a ; $cc26
+ ld hl, W_PLAYERMONPP ; $d02d
+ ld e, a
+ ld d, $0
+ add hl, de
+ ld a, [hl]
+ and a
+ jr z, .asm_3dd86
+ ld a, [wCurrentMenuItem] ; $cc26
+ ld c, a
+ ld b, $0
+ ld hl, W_PLAYERMONMOVES
+ add hl, bc
+ ld a, [hl]
+ ld [wPlayerSelectedMove], a ; $ccdc
+ call GetCurrentMove
+
+Func_3ddb0: ; 3ddb0 (f:5db0)
+ ld a, $1
+ and a
+ ret
+
+Func_3ddb4: ; 3ddb4 (f:5db4)
+ xor a
+ ret
+
+LoafingAroundText: ; 3ddb6 (f:5db6)
+ TX_FAR _LoafingAroundText
+ db "@"
+
+BeganToNapText: ; 3ddbb (f:5dbb)
+ TX_FAR _BeganToNapText
+ db "@"
+
+WontObeyText: ; 3ddc0 (f:5dc0)
+ TX_FAR _WontObeyText
+ db "@"
+
+TurnedAwayText: ; 3ddc5 (f:5dc5)
+ TX_FAR _TurnedAwayText
+ db "@"
+
+IgnoredOrdersText: ; 3ddca (f:5dca)
+ TX_FAR _IgnoredOrdersText
+ db "@"
+
+CalculateDamage: ; 3ddcf (f:5dcf)
+ xor a
+ ld hl, W_DAMAGE ;damage to eventually inflict, intitialise to zero
+ ldi [hl], a
+ ld [hl], a
+ ld hl, W_PLAYERMOVEPOWER
+ ld a, [hli] ;*read attack base power
+ and a
+ ld d, a ;*D = attack base, used later
+ ret z ;return if attack is zero
+ ld a, [hl] ;*test attacking type
+ cp a, $14 ;types >= $14 are all special
+ jr nc, .specialAttack
+.physicalAttack
+ ld hl, W_ENEMYMONDEFENSE ;opponent defense
+ ld a, [hli] ;*BC = opponent defense used later
+ ld b, a
+ ld c, [hl]
+ ld a, [W_ENEMYBATTSTATUS3] ;test for reflect
+ bit 2, a
+ jr z, .next
+.doubleDefense
+ sla c ;x2 defense if bit2 of D069 is set
+ rl b
+.next
+ ld hl, W_PLAYERMONATK ;attack pointer
+ ld a, [$d05e]
+ and a
+ jr z, .next3
+ ld c, 3
+ call Func_3df1c
+ ld a, [$ff97]
+ ld b, a
+ ld a, [$ff98]
+ ld c, a
+ push bc
+ ld hl, $d18f
+ ld a, [wPlayerMonNumber]
+ ld bc, $002c
+ call AddNTimes
+ pop bc
+ jr .next3
+.specialAttack
+ ld hl, W_ENEMYMONSPECIAL ;opponent special
+ ld a, [hli] ;*BC = opponent special defense used later
+ ld b, a
+ ld c, [hl]
+ ld a, [W_ENEMYBATTSTATUS3] ;test for lightscreen
+ bit 1, a
+ jr z, .next2
+.doubleSpecialDefense
+ sla c ;x2 special defense if bit1 of D069 set
+ rl b
+.next2
+ ld hl, W_PLAYERMONSPECIAL
+ ld a, [$d05e] ;XXX
+ and a
+ jr z, .next3 ;skip portion of code that pulls up inactive pokemon
+.loadOtherPoke
+ ld c, 5
+ call Func_3df1c
+ ld a, [$ff97]
+ ld b, a
+ ld a, [$ff98]
+ ld c, a
+ push bc
+ ld hl, $d195
+ ld a, [wPlayerMonNumber]
+ ld bc, $002c
+ call AddNTimes
+ pop bc
+.next3
+ ld a, [hli] ;HL: when this was taken
+ ld l, [hl]
+ ld h, a ;*HL = attacker attack
+ or b ;is either attack or defense high byte nonzero?
+ jr z, .next4
+ srl b ;[defense] BC /= 4 [this is just so it fits into a single byte, 10bits max]
+ rr c
+ srl b
+ rr c
+ srl h ;[attack] HL /= 4 [to apply equal scaling]
+ rr l
+ srl h
+ rr l
+ ld a, l
+ or h
+ jr nz, .next4 ;is HL result zero?
+ inc l ;minimum HL = 1
+.next4
+ ld b, l ;*B = attack [possibly scaled] [C contains defense]
+ ld a, [$d022] ;*E = level
+ ld e, a
+ ld a, [$d05e] ;critical hit?
+ and a
+ jr z, .next5
+ sla e ;double level if it was a critical hit
+.next5
+ ld a, 1 ;return Z = 0
+ and a
+ ret
+
+Func_3de75: ; 3de75 (f:5e75)
+ ld hl, W_DAMAGE ; $d0d7
+ xor a
+ ld [hli], a
+ ld [hl], a
+ ld hl, W_ENEMYMOVEPOWER ; $cfce
+ ld a, [hli]
+ ld d, a
+ and a
+ ret z
+ ld a, [hl]
+ cp $14
+ jr nc, .asm_3debc
+ ld hl, W_PLAYERMONDEF
+ ld a, [hli]
+ ld b, a
+ ld c, [hl]
+ ld a, [W_PLAYERBATTSTATUS3] ; $d064
+ bit 2, a
+ jr z, .asm_3de98
+ sla c
+ rl b
+.asm_3de98
+ ld hl, W_ENEMYMONATTACK
+ ld a, [$d05e]
+ and a
+ jr z, .asm_3deef
+ ld hl, W_PARTYMON1_DEFENSE ; $d191
+ ld a, [wPlayerMonNumber] ; $cc2f
+ ld bc, $2c
+ call AddNTimes
+ ld a, [hli]
+ ld b, a
+ ld c, [hl]
+ push bc
+ ld c, $2
+ call Func_3df1c
+ ld hl, $ff97
+ pop bc
+ jr .asm_3deef
+.asm_3debc
+ ld hl, W_PLAYERMONSPECIAL
+ ld a, [hli]
+ ld b, a
+ ld c, [hl]
+ ld a, [W_PLAYERBATTSTATUS3] ; $d064
+ bit 1, a
+ jr z, .asm_3decd
+ sla c
+ rl b
+.asm_3decd
+ ld hl, W_ENEMYMONSPECIAL ; $cffc
+ ld a, [$d05e]
+ and a
+ jr z, .asm_3deef
+ ld hl, W_PARTYMON1_SPECIAL ; $d195
+ ld a, [wPlayerMonNumber] ; $cc2f
+ ld bc, $2c
+ call AddNTimes
+ ld a, [hli]
+ ld b, a
+ ld c, [hl]
+ push bc
+ ld c, $5
+ call Func_3df1c
+ ld hl, $ff97
+ pop bc
+.asm_3deef
+ ld a, [hli]
+ ld l, [hl]
+ ld h, a
+ or b
+ jr z, .asm_3df0a
+ srl b
+ rr c
+ srl b
+ rr c
+ srl h
+ rr l
+ srl h
+ rr l
+ ld a, l
+ or h
+ jr nz, .asm_3df0a
+ inc l
+.asm_3df0a
+ ld b, l
+ ld a, [W_ENEMYMONLEVEL] ; $cff3
+ ld e, a
+ ld a, [$d05e]
+ and a
+ jr z, .asm_3df17
+ sla e
+.asm_3df17
+ ld a, $1
+ and a
+ and a
+ ret
+
+Func_3df1c: ; 3df1c (f:5f1c)
+ push de
+ push bc
+ ld a, [W_ISLINKBATTLE] ; $d12b
+ cp $4
+ jr nz, .asm_3df40
+ ld hl, $d8c6
+ dec c
+ sla c
+ ld b, $0
+ add hl, bc
+ ld a, [W_ENEMYMONNUMBER] ; $cfe8
+ ld bc, $2c
+ call AddNTimes
+ ld a, [hli]
+ ld [$ff97], a
+ ld a, [hl]
+ ld [$ff98], a
+ pop bc
+ pop de
+ ret
+.asm_3df40
+ ld a, [W_ENEMYMONLEVEL] ; $cff3
+ ld [W_CURENEMYLVL], a ; $d127
+ ld a, [$cfe5]
+ ld [$d0b5], a
+ call GetMonHeader
+ ld hl, $cff1
+ ld de, $cfaf
+ ld a, [hli]
+ ld [de], a
+ inc de
+ ld a, [hl]
+ ld [de], a
+ pop bc
+ ld b, $0
+ ld hl, $cfa4
+ call CalcStat
+ pop de
+ ret
+
+MoreCalculateDamage: ; 3df65 (f:5f65)
+; input:
+; b: attack
+; c: opponent defense
+; d: base power
+; e: level
+
+ ld a, [$fff3] ; whose turn?
+ and a
+ ld a, [W_PLAYERMOVEEFFECT]
+ jr z, .effect
+ ld a, [$cfcd]
+.effect
+
+; EXPLODE_EFFECT halves defense.
+ cp a, EXPLODE_EFFECT
+ jr nz, .ok
+ srl c
+ jr nz, .ok
+ inc c ; ...with a minimum value of 1 (used as a divisor later on)
+.ok
+
+; Multi-hit attacks may or may not have 0 bp.
+ cp a, TWO_TO_FIVE_ATTACKS_EFFECT
+ jr z, .skipbp
+ cp a, $1e
+ jr z, .skipbp
+
+; Calculate OHKO damage based on remaining HP.
+ cp a, OHKO_EFFECT
+ jp z, Func_3e016
+
+; Don't calculate damage for moves that don't do any.
+ ld a, d ; base power
+ and a
+ ret z
+.skipbp
+
+ xor a
+ ld hl, H_DIVIDEND
+ ldi [hl], a
+ ldi [hl], a
+ ld [hl], a
+
+; Multiply level by 2
+ ld a, e ; level
+ add a
+ jr nc, .nc
+ push af
+ ld a, 1
+ ld [hl], a
+ pop af
+.nc
+ inc hl
+ ldi [hl], a
+
+; Divide by 5
+ ld a, 5
+ ldd [hl], a
+ push bc
+ ld b, 4
+ call Divide
+ pop bc
+
+; Add 2
+ inc [hl]
+ inc [hl]
+
+ inc hl ; multiplier
+
+; Multiply by attack base power
+ ld [hl], d
+ call Multiply
+
+; Multiply by attack stat
+ ld [hl], b
+ call Multiply
+
+; Divide by defender's defense stat
+ ld [hl], c
+ ld b, 4
+ call Divide
+
+; Divide by 50
+ ld [hl], 50
+ ld b, 4
+ call Divide
+
+ ld hl, W_DAMAGE
+ ld b, [hl]
+ ld a, [H_QUOTIENT + 3]
+ add b
+ ld [H_QUOTIENT + 3], a
+ jr nc, .asm_3dfd0
+
+ ld a, [H_QUOTIENT + 2]
+ inc a
+ ld [H_QUOTIENT + 2], a
+ and a
+ jr z, .asm_3e004
+
+.asm_3dfd0
+ ld a, [H_QUOTIENT]
+ ld b, a
+ ld a, [H_QUOTIENT + 1]
+ or a
+ jr nz, .asm_3e004
+
+ ld a, [H_QUOTIENT + 2]
+ cp 998 / $100
+ jr c, .asm_3dfe8
+ cp 998 / $100 + 1
+ jr nc, .asm_3e004
+ ld a, [H_QUOTIENT + 3]
+ cp 998 % $100
+ jr nc, .asm_3e004
+
+.asm_3dfe8
+ inc hl
+ ld a, [H_QUOTIENT + 3]
+ ld b, [hl]
+ add b
+ ld [hld], a
+
+ ld a, [H_QUOTIENT + 2]
+ ld b, [hl]
+ adc b
+ ld [hl], a
+ jr c, .asm_3e004
+
+ ld a, [hl]
+ cp 998 / $100
+ jr c, .asm_3e00a
+ cp 998 / $100 + 1
+ jr nc, .asm_3e004
+ inc hl
+ ld a, [hld]
+ cp 998 % $100
+ jr c, .asm_3e00a
+
+.asm_3e004
+ ld a, 997 / $100
+ ld [hli], a
+ ld a, 997 % $100
+ ld [hld], a
+
+.asm_3e00a
+ inc hl
+ ld a, [hl]
+ add 2
+ ld [hld], a
+ jr nc, .done
+ inc [hl]
+.done
+
+ ld a, 1
+ and a
+ ret
+
+Func_3e016: ; 3e016 (f:6016)
+ call Func_3f132
+ ld a, [W_MOVEMISSED] ; $d05f
+ dec a
+ ret
+
+
+UnusedHighCriticalMoves: ; 3e01e (f:601e)
+ db KARATE_CHOP
+ db RAZOR_LEAF
+ db CRABHAMMER
+ db SLASH
+ db $FF
+; 3e023
+
+; determines if attack is a critical hit
+; azure heights claims "the fastest pokémon (who are,not coincidentally,
+; among the most popular) tend to CH about 20 to 25% of the time."
+CriticalHitTest: ; 3e023 (f:6023)
+ xor a
+ ld [$d05e], a
+ ld a, [H_WHOSETURN] ; $fff3
+ and a
+ ld a, [$cfe5]
+ jr nz, .asm_3e032
+ ld a, [W_PLAYERMONID]
+.asm_3e032
+ ld [$d0b5], a
+ call GetMonHeader
+ ld a, [W_MONHBASESPEED]
+ ld b, a
+ srl b ; (effective (base speed/2))
+ ld a, [H_WHOSETURN] ; $fff3
+ and a
+ ld hl, W_PLAYERMOVEPOWER ; $cfd4
+ ld de, W_PLAYERBATTSTATUS2 ; $d063
+ jr z, .calcCriticalHitProbability
+ ld hl, W_ENEMYMOVEPOWER ; $cfce
+ ld de, W_ENEMYBATTSTATUS2 ; $d068
+.calcCriticalHitProbability ; 0x3e04f
+ ld a, [hld] ; read base power from RAM
+ and a
+ ret z ; do nothing if zero
+ dec hl
+ ld c, [hl] ; read move id
+ ld a, [de]
+ bit 2, a ; test for focus energy
+ jr nz, .focusEnergyUsed ; bug: using focus energy causes a shift to the right instead of left,
+ ; resulting in 1/4 the usual crit chance
+ sla b ; (effective (base speed/2)*2)
+ jr nc, .noFocusEnergyUsed
+ ld b, $ff ; cap at 255/256
+ jr .noFocusEnergyUsed
+.focusEnergyUsed
+ srl b
+.noFocusEnergyUsed
+ ld hl, HighCriticalMoves ; table of high critical hit moves
+.Loop
+ ld a, [hli] ; read move from move table
+ cp c ; does it match the move about to be used?
+ jr z, .HighCritical ; if so, the move about to be used is a high critical hit ratio move
+ inc a ; move on to the next move, FF terminates loop
+ jr nz, .Loop ; check the next move in HighCriticalMoves
+ srl b ; /2 for regular move (effective (base speed / 2))
+ jr .SkipHighCritical ; continue as a normal move
+.HighCritical
+ sla b ; *2 for high critical hit moves
+ jr nc, .noCarry
+ ld b, $ff ; cap at 255/256
+.noCarry
+ sla b ; *4 for high critical move (effective (base speed/2)*8))
+ jr nc, .SkipHighCritical
+ ld b, $ff
+.SkipHighCritical
+ call GenRandomInBattle ; generates a random value, in "a"
+ rlc a
+ rlc a
+ rlc a
+ cp b ; check a against calculated crit rate
+ ret nc ; no critical hit if no borrow
+ ld a, $1
+ ld [$d05e], a ; set critical hit flag
+ ret
+
+; high critical hit moves
+HighCriticalMoves: ; 3e08e (f:608e)
+ db KARATE_CHOP
+ db RAZOR_LEAF
+ db CRABHAMMER
+ db SLASH
+ db $FF
+
+
+; function to determine if Counter hits and if so, how much damage it does
+HandleCounterMove: ; 3e093 (f:6093)
+ ld a,[H_WHOSETURN] ; whose turn
+ and a
+; player's turn
+ ld hl,wEnemySelectedMove
+ ld de,W_ENEMYMOVEPOWER
+ ld a,[wPlayerSelectedMove]
+ jr z,.next
+; enemy's turn
+ ld hl,wPlayerSelectedMove
+ ld de,W_PLAYERMOVEPOWER
+ ld a,[wEnemySelectedMove]
+.next
+ cp a,COUNTER
+ ret nz ; return if not using Counter
+ ld a,$01
+ ld [W_MOVEMISSED],a ; initialize the move missed variable to true (it is set to false below if the move hits)
+ ld a,[hl]
+ cp a,COUNTER
+ ret z ; if the target also used Counter, miss
+ ld a,[de]
+ and a
+ ret z ; if the move the target used has 0 power, miss
+; check if the move the target used was Normal or Fighting type
+ inc de
+ ld a,[de]
+ and a ; normal type
+ jr z,.counterableType
+ cp a,FIGHTING
+ jr z,.counterableType
+; if the move wasn't Normal or Fighting type, miss
+ xor a
+ ret
+.counterableType
+ ld hl,W_DAMAGE
+ ld a,[hli]
+ or [hl]
+ ret z ; Counter misses if the target did no damage to the Counter user
+; double the damage that the target did to the Counter user
+ ld a,[hl]
+ add a
+ ldd [hl],a
+ ld a,[hl]
+ adc a
+ ld [hl],a
+ jr nc,.noCarry
+; damage is capped at 0xFFFF
+ ld a,$ff
+ ld [hli],a
+ ld [hl],a
+.noCarry
+ xor a
+ ld [W_MOVEMISSED],a
+ call MoveHitTest ; do the normal move hit test in addition to Counter's special rules
+ xor a
+ ret
+
+ApplyAttackToEnemyPokemon: ; 3e0df (f:60df)
+ ld a,[W_PLAYERMOVEEFFECT]
+ cp a,OHKO_EFFECT
+ jr z,ApplyDamageToEnemyPokemon
+ cp a,SUPER_FANG_EFFECT
+ jr z,.superFangEffect
+ cp a,SPECIAL_DAMAGE_EFFECT
+ jr z,.specialDamage
+ ld a,[W_PLAYERMOVEPOWER]
+ and a
+ jp z,ApplyAttackToEnemyPokemonDone
+ jr ApplyDamageToEnemyPokemon
+.superFangEffect
+; set the damage to half the target's HP
+ ld hl,W_ENEMYMONCURHP
+ ld de,W_DAMAGE
+ ld a,[hli]
+ srl a
+ ld [de],a
+ inc de
+ ld b,a
+ ld a,[hl]
+ rr a
+ ld [de],a
+ or b
+ jr nz,ApplyDamageToEnemyPokemon
+; make sure Super Fang's damage is always at least 1
+ ld a,$01
+ ld [de],a
+ jr ApplyDamageToEnemyPokemon
+.specialDamage
+ ld hl,W_PLAYERMONLEVEL
+ ld a,[hl]
+ ld b,a
+ ld a,[W_PLAYERMOVENUM]
+ cp a,SEISMIC_TOSS
+ jr z,.storeDamage
+ cp a,NIGHT_SHADE
+ jr z,.storeDamage
+ ld b,SONICBOOM_DAMAGE
+ cp a,SONICBOOM
+ jr z,.storeDamage
+ ld b,DRAGON_RAGE_DAMAGE
+ cp a,DRAGON_RAGE
+ jr z,.storeDamage
+; Psywave
+ ld a,[hl]
+ ld b,a
+ srl a
+ add b
+ ld b,a ; b = level * 1.5
+; loop until a random number in the range [1, b) is found
+.loop
+ call GenRandomInBattle ; random number
+ and a
+ jr z,.loop
+ cp b
+ jr nc,.loop
+ ld b,a
+.storeDamage
+ ld hl,W_DAMAGE
+ xor a
+ ld [hli],a
+ ld a,b
+ ld [hl],a
+
+ApplyDamageToEnemyPokemon: ; 3e142 (f:6142)
+ ld hl,W_DAMAGE
+ ld a,[hli]
+ ld b,a
+ ld a,[hl]
+ or b
+ jr z,ApplyAttackToEnemyPokemonDone ; we're done if damage is 0
+ ld a,[W_ENEMYBATTSTATUS2]
+ bit 4,a ; does the enemy have a substitute?
+ jp nz,AttackSubstitute
+; subtract the damage from the pokemon's current HP
+; also, save the current HP at wHPBarOldHP
+ ld a,[hld]
+ ld b,a
+ ld a,[W_ENEMYMONCURHP + 1]
+ ld [wHPBarOldHP],a
+ sub b
+ ld [W_ENEMYMONCURHP + 1],a
+ ld a,[hl]
+ ld b,a
+ ld a,[W_ENEMYMONCURHP]
+ ld [wHPBarOldHP+1],a
+ sbc b
+ ld [W_ENEMYMONCURHP],a
+ jr nc,.animateHpBar
+; if more damage was done than the current HP, zero the HP and set the damage
+; equal to how much HP the pokemon had before the attack
+ ld a,[wHPBarOldHP+1]
+ ld [hli],a
+ ld a,[wHPBarOldHP]
+ ld [hl],a
+ xor a
+ ld hl,W_ENEMYMONCURHP
+ ld [hli],a
+ ld [hl],a
+.animateHpBar
+ ld hl,W_ENEMYMONMAXHP
+ ld a,[hli]
+ ld [wHPBarMaxHP+1],a
+ ld a,[hl]
+ ld [wHPBarMaxHP],a
+ ld hl,W_ENEMYMONCURHP
+ ld a,[hli]
+ ld [wHPBarNewHP+1],a
+ ld a,[hl]
+ ld [wHPBarNewHP],a
+ FuncCoord 2, 2 ; $c3ca
+ ld hl,Coord
+ xor a
+ ld [$cf94],a
+ ld a,$48
+ call Predef ; animate the HP bar shortening
+ApplyAttackToEnemyPokemonDone: ; 3e19d (f:619d)
+ jp Func_3cd5a ; redraw pokemon names and HP bars
+
+ApplyAttackToPlayerPokemon: ; 3e1a0 (f:61a0)
+ ld a,[W_ENEMYMOVEEFFECT]
+ cp a,OHKO_EFFECT
+ jr z,ApplyDamageToPlayerPokemon
+ cp a,SUPER_FANG_EFFECT
+ jr z,.superFangEffect
+ cp a,SPECIAL_DAMAGE_EFFECT
+ jr z,.specialDamage
+ ld a,[W_ENEMYMOVEPOWER]
+ and a
+ jp z,ApplyAttackToPlayerPokemonDone
+ jr ApplyDamageToPlayerPokemon
+.superFangEffect
+; set the damage to half the target's HP
+ ld hl,W_PLAYERMONCURHP
+ ld de,W_DAMAGE
+ ld a,[hli]
+ srl a
+ ld [de],a
+ inc de
+ ld b,a
+ ld a,[hl]
+ rr a
+ ld [de],a
+ or b
+ jr nz,ApplyDamageToPlayerPokemon
+; make sure Super Fang's damage is always at least 1
+ ld a,$01
+ ld [de],a
+ jr ApplyDamageToPlayerPokemon
+.specialDamage
+ ld hl,W_ENEMYMONLEVEL
+ ld a,[hl]
+ ld b,a
+ ld a,[W_ENEMYMOVENUM]
+ cp a,SEISMIC_TOSS
+ jr z,.storeDamage
+ cp a,NIGHT_SHADE
+ jr z,.storeDamage
+ ld b,SONICBOOM_DAMAGE
+ cp a,SONICBOOM
+ jr z,.storeDamage
+ ld b,DRAGON_RAGE_DAMAGE
+ cp a,DRAGON_RAGE
+ jr z,.storeDamage
+; Psywave
+ ld a,[hl]
+ ld b,a
+ srl a
+ add b
+ ld b,a ; b = attacker's level * 1.5
+; loop until a random number in the range [0, b) is found
+; this differs from the range when the player attacks, which is [1, b)
+; it's possible for the enemy to do 0 damage with Psywave, but the player always does at least 1 damage
+.loop
+ call GenRandomInBattle ; random number
+ cp b
+ jr nc,.loop
+ ld b,a
+.storeDamage
+ ld hl,W_DAMAGE
+ xor a
+ ld [hli],a
+ ld a,b
+ ld [hl],a
+
+ApplyDamageToPlayerPokemon: ; 3e200 (f:6200)
+ ld hl,W_DAMAGE
+ ld a,[hli]
+ ld b,a
+ ld a,[hl]
+ or b
+ jr z,ApplyAttackToPlayerPokemonDone ; we're done if damage is 0
+ ld a,[W_PLAYERBATTSTATUS2]
+ bit 4,a ; does the player have a substitute?
+ jp nz,AttackSubstitute
+; subtract the damage from the pokemon's current HP
+; also, save the current HP at wHPBarOldHP and the new HP at wHPBarNewHP
+ ld a,[hld]
+ ld b,a
+ ld a,[W_PLAYERMONCURHP + 1]
+ ld [wHPBarOldHP],a
+ sub b
+ ld [W_PLAYERMONCURHP + 1],a
+ ld [wHPBarNewHP],a
+ ld b,[hl]
+ ld a,[W_PLAYERMONCURHP]
+ ld [wHPBarOldHP+1],a
+ sbc b
+ ld [W_PLAYERMONCURHP],a
+ ld [wHPBarNewHP+1],a
+ jr nc,.animateHpBar
+; if more damage was done than the current HP, zero the HP and set the damage
+; equal to how much HP the pokemon had before the attack
+ ld a,[wHPBarOldHP+1]
+ ld [hli],a
+ ld a,[wHPBarOldHP]
+ ld [hl],a
+ xor a
+ ld hl,W_PLAYERMONCURHP
+ ld [hli],a
+ ld [hl],a
+ ld hl,wHPBarNewHP
+ ld [hli],a
+ ld [hl],a
+.animateHpBar
+ ld hl,W_PLAYERMONMAXHP
+ ld a,[hli]
+ ld [wHPBarMaxHP+1],a
+ ld a,[hl]
+ ld [wHPBarMaxHP],a
+ FuncCoord 10, 9 ; $c45e
+ ld hl,Coord
+ ld a,$01
+ ld [$cf94],a
+ ld a,$48
+ call Predef ; animate the HP bar shortening
+ApplyAttackToPlayerPokemonDone
+ jp Func_3cd5a ; redraw pokemon names and HP bars
+
+AttackSubstitute: ; 3e25e (f:625e)
+ ld hl,SubstituteTookDamageText
+ call PrintText
+; values for player turn
+ ld de,wEnemySubstituteHP
+ ld bc,W_ENEMYBATTSTATUS2
+ ld a,[H_WHOSETURN]
+ and a
+ jr z,.applyDamageToSubstitute
+; values for enemy turn
+ ld de,wPlayerSubstituteHP
+ ld bc,W_PLAYERBATTSTATUS2
+.applyDamageToSubstitute
+ ld hl,W_DAMAGE
+ ld a,[hli]
+ and a
+ jr nz,.substituteBroke ; damage > 0xFF always breaks substitutes
+; subtract damage from HP of substitute
+ ld a,[de]
+ sub [hl]
+ ld [de],a
+ ret nc
+.substituteBroke
+ ld h,b
+ ld l,c
+ res 4,[hl] ; unset the substitute bit
+ ld hl,SubstituteBrokeText
+ call PrintText
+; flip whose turn it is for the next function call
+ ld a,[H_WHOSETURN]
+ xor a,$01
+ ld [H_WHOSETURN],a
+ callab Func_79747 ; animate the substitute breaking
+; flip the turn back to the way it was
+ ld a,[H_WHOSETURN]
+ xor a,$01
+ ld [H_WHOSETURN],a
+ ld hl,W_PLAYERMOVEEFFECT ; value for player's turn
+ and a
+ jr z,.nullifyEffect
+ ld hl,W_ENEMYMOVEEFFECT ; value for enemy's turn
+.nullifyEffect
+ xor a
+ ld [hl],a ; zero the effect of the attacker's move
+ jp Func_3cd5a ; redraw pokemon names and HP bars
+
+SubstituteTookDamageText: ; 3e2ac (f:62ac)
+ TX_FAR _SubstituteTookDamageText
+ db "@"
+
+SubstituteBrokeText: ; 3e2b1 (f:62b1)
+ TX_FAR _SubstituteBrokeText
+ db "@"
+
+; this function raises the attack modifier of a pokemon using Rage when that pokemon is attacked
+HandleBuildingRage: ; 3e2b6 (f:62b6)
+; values for the player turn
+ ld hl,W_ENEMYBATTSTATUS2
+ ld de,wEnemyMonStatMods
+ ld bc,W_ENEMYMOVENUM
+ ld a,[H_WHOSETURN]
+ and a
+ jr z,.next
+; values for the enemy turn
+ ld hl,W_PLAYERBATTSTATUS2
+ ld de,wPlayerMonStatMods
+ ld bc,W_PLAYERMOVENUM
+.next
+ bit 6,[hl] ; is the pokemon being attacked under the effect of Rage?
+ ret z ; return if not
+ ld a,[de]
+ cp a,$0d ; maximum stat modifier value
+ ret z ; return if attack modifier is already maxed
+ ld a,[H_WHOSETURN]
+ xor a,$01 ; flip turn for the stat modifier raising function
+ ld [H_WHOSETURN],a
+; change the target pokemon's move to $00 and the effect to the one
+; that causes the attack modifier to go up one stage
+ ld h,b
+ ld l,c
+ ld [hl],$00 ; null move number
+ inc hl
+ ld [hl],ATTACK_UP1_EFFECT
+ push hl
+ ld hl,BuildingRageText
+ call PrintText
+ call StatModifierUpEffect ; stat modifier raising function
+ pop hl
+ xor a
+ ldd [hl],a ; null move effect
+ ld a,RAGE
+ ld [hl],a ; restore the target pokemon's move number to Rage
+ ld a,[H_WHOSETURN]
+ xor a,$01 ; flip turn back to the way it was
+ ld [H_WHOSETURN],a
+ ret
+
+BuildingRageText: ; 3e2f8 (f:62f8)
+ TX_FAR _BuildingRageText
+ db "@"
+
+; copy last move for Mirror Move
+; sets zero flag on failure and unsets zero flag on success
+MirrorMoveCopyMove: ; 3e2fd (f:62fd)
+ ld a,[H_WHOSETURN]
+ and a
+; values for player turn
+ ld a,[$ccf2]
+ ld hl,wPlayerSelectedMove
+ ld de,W_PLAYERMOVENUM
+ jr z,.next
+; values for enemy turn
+ ld a,[$ccf1]
+ ld de,W_ENEMYMOVENUM
+ ld hl,wEnemySelectedMove
+.next
+ ld [hl],a
+ cp a,MIRROR_MOVE ; did the target pokemon also use Mirror Move?
+ jr z,.mirrorMoveFailed
+ and a ; null move?
+ jr nz,ReloadMoveData
+.mirrorMoveFailed
+; Mirror Move fails on itself and null moves
+ ld hl,MirrorMoveFailedText
+ call PrintText
+ xor a
+ ret
+
+MirrorMoveFailedText: ; 3e324 (f:6324)
+ TX_FAR _MirrorMoveFailedText
+ db "@"
+
+; function used to reload move data for moves like Mirror Move and Metronome
+ReloadMoveData: ; 3e329 (f:6329)
+ ld [$d11e],a
+ dec a
+ ld hl,Moves
+ ld bc,$0006
+ call AddNTimes
+ ld a,BANK(Moves)
+ call FarCopyData ; copy the move's stats
+ call IncrementMovePP
+; the follow two function calls are used to reload the move name
+ call GetMoveName
+ call CopyStringToCF4B
+ ld a,$01
+ and a
+ ret
+
+; function that picks a random move for metronome
+MetronomePickMove: ; 3e348 (f:6348)
+ xor a
+ ld [$cc5b],a
+ ld a,METRONOME
+ call PlayMoveAnimation ; play Metronome's animation
+; values for player turn
+ ld de,W_PLAYERMOVENUM
+ ld hl,wPlayerSelectedMove
+ ld a,[H_WHOSETURN]
+ and a
+ jr z,.pickMoveLoop
+; values for enemy turn
+ ld de,W_ENEMYMOVENUM
+ ld hl,wEnemySelectedMove
+; loop to pick a random number in the range [1, $a5) to be the move used by Metronome
+.pickMoveLoop
+ call GenRandomInBattle ; random number
+ and a
+ jr z,.pickMoveLoop
+ cp a,NUM_MOVES + 1 ; max normal move number + 1 (this is Struggle's move number)
+ jr nc,.pickMoveLoop
+ cp a,METRONOME
+ jr z,.pickMoveLoop
+ ld [hl],a
+ jr ReloadMoveData
+
+; this function increments the current move's PP
+; it's used to prevent moves that run another move within the same turn
+; (like Mirror Move and Metronome) from losing 2 PP
+IncrementMovePP: ; 3e373 (f:6373)
+ ld a,[H_WHOSETURN]
+ and a
+; values for player turn
+ ld hl,W_PLAYERMONPP
+ ld de,W_PARTYMON1_MOVE1PP
+ ld a,[wPlayerMoveListIndex]
+ jr z,.next
+; values for enemy turn
+ ld hl,W_ENEMYMONPP
+ ld de,$d8c1 ; enemy party pokemon 1 PP
+ ld a,[wEnemyMoveListIndex]
+.next
+ ld b,$00
+ ld c,a
+ add hl,bc
+ inc [hl] ; increment PP in the currently battling pokemon memory location
+ ld h,d
+ ld l,e
+ add hl,bc
+ ld a,[H_WHOSETURN]
+ and a
+ ld a,[wPlayerMonNumber] ; value for player turn
+ jr z,.next2
+ ld a,[W_ENEMYMONNUMBER] ; value for enemy turn
+.next2
+ ld bc,$002c
+ call AddNTimes
+ inc [hl] ; increment PP in the party memory location
+ ret
+
+; function to adjust the base damage of an attack to account for type effectiveness
+AdjustDamageForMoveType: ; 3e3a5 (f:63a5)
+; values for player turn
+ ld hl,W_PLAYERMONTYPES
+ ld a,[hli]
+ ld b,a ; b = type 1 of attacker
+ ld c,[hl] ; c = type 2 of attacker
+ ld hl,W_ENEMYMONTYPES
+ ld a,[hli]
+ ld d,a ; d = type 1 of defender
+ ld e,[hl] ; e = type 2 of defender
+ ld a,[W_PLAYERMOVETYPE]
+ ld [$d11e],a
+ ld a,[H_WHOSETURN]
+ and a
+ jr z,.next
+; values for enemy turn
+ ld hl,W_ENEMYMONTYPES
+ ld a,[hli]
+ ld b,a ; b = type 1 of attacker
+ ld c,[hl] ; c = type 2 of attacker
+ ld hl,W_PLAYERMONTYPES
+ ld a,[hli]
+ ld d,a ; d = type 1 of defender
+ ld e,[hl] ; e = type 2 of defender
+ ld a,[W_ENEMYMOVETYPE]
+ ld [$d11e],a
+.next
+ ld a,[$d11e] ; move type
+ cp b ; does the move type match type 1 of the attacker?
+ jr z,.sameTypeAttackBonus
+ cp c ; does the move type match type 2 of the attacker?
+ jr z,.sameTypeAttackBonus
+ jr .skipSameTypeAttackBonus
+.sameTypeAttackBonus
+; if the move type matches one of the attacker's types
+ ld hl,W_DAMAGE + 1
+ ld a,[hld]
+ ld h,[hl]
+ ld l,a ; hl = damage
+ ld b,h
+ ld c,l ; bc = damage
+ srl b
+ rr c ; bc = floor(0.5 * damage)
+ add hl,bc ; hl = floor(1.5 * damage)
+; store damage
+ ld a,h
+ ld [W_DAMAGE],a
+ ld a,l
+ ld [W_DAMAGE + 1],a
+ ld hl,$d05b
+ set 7,[hl]
+.skipSameTypeAttackBonus
+ ld a,[$d11e]
+ ld b,a ; b = move type
+ ld hl,TypeEffects
+.loop
+ ld a,[hli] ; a = "attacking type" of the current type pair
+ cp a,$ff
+ jr z,.done
+ cp b ; does move type match "attacking type"?
+ jr nz,.nextTypePair
+ ld a,[hl] ; a = "defending type" of the current type pair
+ cp d ; does type 1 of defender match "defending type"?
+ jr z,.matchingPairFound
+ cp e ; does type 2 of defender match "defending type"?
+ jr z,.matchingPairFound
+ jr .nextTypePair
+.matchingPairFound
+; if the move type matches the "attacking type" and one of the defender's types matches the "defending type"
+ push hl
+ push bc
+ inc hl
+ ld a,[$d05b]
+ and a,$80
+ ld b,a
+ ld a,[hl] ; a = damage multiplier
+ ld [H_MULTIPLIER],a
+ add b
+ ld [$d05b],a
+ xor a
+ ld [H_MULTIPLICAND],a
+ ld hl,W_DAMAGE
+ ld a,[hli]
+ ld [H_MULTIPLICAND + 1],a
+ ld a,[hld]
+ ld [H_MULTIPLICAND + 2],a
+ call Multiply
+ ld a,10
+ ld [H_DIVISOR],a
+ ld b,$04
+ call Divide
+ ld a,[H_QUOTIENT + 2]
+ ld [hli],a
+ ld b,a
+ ld a,[H_QUOTIENT + 3]
+ ld [hl],a
+ or b ; is damage 0?
+ jr nz,.skipTypeImmunity
+.typeImmunity
+; if damage is 0, make the move miss
+ inc a
+ ld [W_MOVEMISSED],a
+.skipTypeImmunity
+ pop bc
+ pop hl
+.nextTypePair
+ inc hl
+ inc hl
+ jp .loop
+.done
+ ret
+
+; function to tell how effective the type of an enemy attack is on the player's current pokemon
+; this doesn't take into account the effects that dual types can have
+; (e.g. 4x weakness / resistance, weaknesses and resistances canceling)
+; the result is stored in [$D11E]
+; ($05 is not very effective, $10 is neutral, $14 is super effective)
+; as far is can tell, this is only used once in some AI code to help decide which move to use
+AIGetTypeEffectiveness: ; 3e449 (f:6449)
+ ld a,[W_ENEMYMOVETYPE]
+ ld d,a ; d = type of enemy move
+ ld hl,W_PLAYERMONTYPES
+ ld b,[hl] ; b = type 1 of player's pokemon
+ inc hl
+ ld c,[hl] ; c = type 2 of player's pokemon
+ ld a,$10
+ ld [$d11e],a ; initialize [$D11E] to neutral effectiveness
+ ld hl,TypeEffects
+.loop
+ ld a,[hli]
+ cp a,$ff
+ ret z
+ cp d ; match the type of the move
+ jr nz,.nextTypePair1
+ ld a,[hli]
+ cp b ; match with type 1 of pokemon
+ jr z,.done
+ cp c ; or match with type 2 of pokemon
+ jr z,.done
+ jr .nextTypePair2
+.nextTypePair1
+ inc hl
+.nextTypePair2
+ inc hl
+ jr .loop
+.done
+ ld a,[hl]
+ ld [$d11e],a ; store damage multiplier
+ ret
+
+INCLUDE "data/type_effects.asm"
+
+; some tests that need to pass for a move to hit
+MoveHitTest: ; 3e56b (f:656b)
+; player's turn
+ ld hl,W_ENEMYBATTSTATUS1
+ ld de,W_PLAYERMOVEEFFECT
+ ld bc,W_ENEMYMONSTATUS
+ ld a,[H_WHOSETURN]
+ and a
+ jr z,.dreamEaterCheck
+; enemy's turn
+ ld hl,W_PLAYERBATTSTATUS1
+ ld de,W_ENEMYMOVEEFFECT
+ ld bc,W_PLAYERMONSTATUS
+.dreamEaterCheck
+ ld a,[de]
+ cp a,DREAM_EATER_EFFECT
+ jr nz,.swiftCheck
+ ld a,[bc]
+ and a,$07 ; is the target pokemon sleeping?
+ jp z,.moveMissed
+.swiftCheck
+ ld a,[de]
+ cp a,SWIFT_EFFECT
+ ret z ; Swift never misses (interestingly, Azure Heights lists this is a myth, but it appears to be true)
+ call CheckTargetSubstitute ; substitute check (note that this overwrites a)
+ jr z,.checkForDigOrFlyStatus
+; this code is buggy. it's supposed to prevent HP draining moves from working on substitutes.
+; since $7b79 overwrites a with either $00 or $01, it never works.
+ cp a,DRAIN_HP_EFFECT ; $03
+ jp z,.moveMissed
+ cp a,DREAM_EATER_EFFECT ; $08
+ jp z,.moveMissed
+.checkForDigOrFlyStatus
+ bit 6,[hl]
+ jp nz,.moveMissed
+ ld a,[H_WHOSETURN]
+ and a
+ jr nz,.enemyTurn
+.playerTurn
+; this checks if the move effect is disallowed by mist
+ ld a,[W_PLAYERMOVEEFFECT]
+ cp a,ATTACK_DOWN1_EFFECT
+ jr c,.skipEnemyMistCheck
+ cp a,BIDE_EFFECT
+ jr c,.enemyMistCheck
+ cp a,$3a
+ jr c,.skipEnemyMistCheck
+ cp a,POISON_EFFECT
+ jr c,.enemyMistCheck
+ jr .skipEnemyMistCheck
+.enemyMistCheck
+; if move effect is from $12 to $19 inclusive or $3a to $41 inclusive
+; i.e. the following moves
+; GROWL, TAIL WHIP, LEER, STRING SHOT, SAND-ATTACK, SMOKESCREEN, KINESIS,
+; FLASH, CONVERSION, HAZE*, SCREECH, LIGHT SCREEN*, REFLECT*
+; the moves that are marked with an asterisk are not affected since this
+; function is not called when those moves are used
+; XXX are there are any others like those three?
+ ld a,[W_ENEMYBATTSTATUS2]
+ bit 1,a ; is mon protected by mist?
+ jp nz,.moveMissed
+.skipEnemyMistCheck
+ ld a,[W_PLAYERBATTSTATUS2]
+ bit 0,a ; is the player using X Accuracy?
+ ret nz ; if so, always hit regardless of accuracy/evasion
+ jr .calcHitChance
+.enemyTurn
+ ld a,[W_ENEMYMOVEEFFECT]
+ cp a,ATTACK_DOWN1_EFFECT
+ jr c,.skipPlayerMistCheck
+ cp a,BIDE_EFFECT
+ jr c,.playerMistCheck
+ cp a,$3a
+ jr c,.skipPlayerMistCheck
+ cp a,POISON_EFFECT
+ jr c,.playerMistCheck
+ jr .skipPlayerMistCheck
+.playerMistCheck
+; similar to enemy mist check
+ ld a,[W_PLAYERBATTSTATUS2]
+ bit 1,a ; is mon protected by mist?
+ jp nz,.moveMissed
+.skipPlayerMistCheck
+ ld a,[W_ENEMYBATTSTATUS2]
+ bit 0,a ; is the enemy using X Accuracy?
+ ret nz ; if so, always hit regardless of accuracy/evasion
+.calcHitChance
+ call CalcHitChance ; scale the move accuracy according to attacker's accuracy and target's evasion
+ ld a,[W_PLAYERMOVEACCURACY]
+ ld b,a
+ ld a,[H_WHOSETURN]
+ and a
+ jr z,.doAccuracyCheck
+ ld a,[W_ENEMYMOVEACCURACY]
+ ld b,a
+.doAccuracyCheck
+; if the random number generated is greater than or equal to the scaled accuracy, the move misses
+; note that this means that even the highest accuracy is still just a 255/256 chance, not 100%
+ call GenRandomInBattle ; random number
+ cp b
+ jr nc,.moveMissed
+ ret
+.moveMissed
+ xor a
+ ld hl,W_DAMAGE ; zero the damage
+ ld [hli],a
+ ld [hl],a
+ inc a
+ ld [W_MOVEMISSED],a
+ ld a,[H_WHOSETURN]
+ and a
+ jr z,.playerTurn2
+.enemyTurn2
+ ld hl,W_ENEMYBATTSTATUS1
+ res 5,[hl] ; end multi-turn attack e.g. wrap
+ ret
+.playerTurn2
+ ld hl,W_PLAYERBATTSTATUS1
+ res 5,[hl] ; end multi-turn attack e.g. wrap
+ ret
+
+; values for player turn
+CalcHitChance: ; 3e624 (f:6624)
+ ld hl,W_PLAYERMOVEACCURACY
+ ld a,[H_WHOSETURN]
+ and a
+ ld a,[wPlayerMonAccuracyMod]
+ ld b,a
+ ld a,[wEnemyMonEvasionMod]
+ ld c,a
+ jr z,.next
+; values for enemy turn
+ ld hl,W_ENEMYMOVEACCURACY
+ ld a,[wEnemyMonAccuracyMod]
+ ld b,a
+ ld a,[wPlayerMonEvasionMod]
+ ld c,a
+.next
+ ld a,$0e
+ sub c
+ ld c,a ; c = 14 - EVASIONMOD (this "reflects" the value over 7, so that an increase in the target's evasion decreases the hit chance instead of increasing the hit chance)
+; zero the high bytes of the multiplicand
+ xor a
+ ld [H_MULTIPLICAND],a
+ ld [H_MULTIPLICAND + 1],a
+ ld a,[hl]
+ ld [H_MULTIPLICAND + 2],a ; set multiplicand to move accuracy
+ push hl
+ ld d,$02 ; loop has two iterations
+; loop to do the calculations, the first iteration multiplies by the accuracy ratio and the second iteration multiplies by the evasion ratio
+.loop
+ push bc
+ ld hl, StatModifierRatios ; $76cb ; stat modifier ratios
+ dec b
+ sla b
+ ld c,b
+ ld b,$00
+ add hl,bc ; hl = address of stat modifier ratio
+ pop bc
+ ld a,[hli]
+ ld [H_MULTIPLIER],a ; set multiplier to the numerator of the ratio
+ call Multiply
+ ld a,[hl]
+ ld [H_DIVISOR],a ; set divisor to the the denominator of the ratio (the dividend is the product of the previous multiplication)
+ ld b,$04 ; number of bytes in the dividend
+ call Divide
+ ld a,[H_QUOTIENT + 3]
+ ld b,a
+ ld a,[H_QUOTIENT + 2]
+ or b
+ jp nz,.nextCalculation
+; make sure the result is always at least one
+ ld [H_QUOTIENT + 2],a
+ ld a,$01
+ ld [H_QUOTIENT + 3],a
+.nextCalculation
+ ld b,c
+ dec d
+ jr nz,.loop
+ ld a,[H_QUOTIENT + 2]
+ and a ; is the calculated hit chance over 0xFF?
+ ld a,[H_QUOTIENT + 3]
+ jr z,.storeAccuracy
+; if calculated hit chance over 0xFF
+ ld a,$ff ; set the hit chance to 0xFF
+.storeAccuracy
+ pop hl
+ ld [hl],a ; store the hit chance in the move accuracy variable
+ ret
+
+Func_3e687: ; 3e687 (f:6687)
+ ld hl, W_DAMAGE ; $d0d7
+ ld a, [hli]
+ and a
+ jr nz, .asm_3e692
+ ld a, [hl]
+ cp $2
+ ret c
+.asm_3e692
+ xor a
+ ld [H_NUMTOPRINT], a ; $ff96 (aliases: H_MULTIPLICAND)
+ dec hl
+ ld a, [hli]
+ ld [$ff97], a
+ ld a, [hl]
+ ld [$ff98], a
+.asm_3e69c
+ call GenRandomInBattle
+ rrca
+ cp $d9
+ jr c, .asm_3e69c
+ ld [H_REMAINDER], a ; $ff99 (aliases: H_DIVISOR, H_MULTIPLIER, H_POWEROFTEN)
+ call Multiply
+ ld a, $ff
+ ld [H_REMAINDER], a ; $ff99 (aliases: H_DIVISOR, H_MULTIPLIER, H_POWEROFTEN)
+ ld b, $4
+ call Divide
+ ld a, [$ff97]
+ ld hl, W_DAMAGE ; $d0d7
+ ld [hli], a
+ ld a, [$ff98]
+ ld [hl], a
+ ret
+
+Func_3e6bc: ; 3e6bc (f:66bc)
+ ld a, [wEnemySelectedMove] ; $ccdd
+ inc a
+ jp z, Func_3e88c
+ call PrintGhostText
+ jp z, Func_3e88c
+ ld a, [W_ISLINKBATTLE] ; $d12b
+ cp $4
+ jr nz, .asm_3e6dc
+ ld b, $1
+ ld a, [$cc3e]
+ cp $e
+ jr z, .asm_3e6dc
+ cp $4
+ ret nc
+.asm_3e6dc
+ ld hl, $ccd5
+ inc [hl]
+ xor a
+ ld [W_MOVEMISSED], a ; $d05f
+ ld [$ccf4], a
+ ld a, $a
+ ld [$d05b], a
+ call Func_3e88f
+ jr nz, .asm_3e6f2
+ jp [hl]
+.asm_3e6f2
+ ld hl, W_ENEMYBATTSTATUS1 ; $d067
+ bit 4, [hl]
+ jr nz, asm_3e70b
+ call GetCurrentMove
+
+Func_3e6fc: ; 3e6fc (f:66fc)
+ ld a, [W_ENEMYMOVEEFFECT] ; $cfcd
+ cp CHARGE_EFFECT
+ jp z, Func_3f132
+ cp FLY_EFFECT
+ jp z, Func_3f132
+ jr asm_3e72b
+asm_3e70b: ; 3e70b (f:670b)
+ ld hl, W_ENEMYBATTSTATUS1 ; $d067
+ res 4, [hl] ; no longer charging up for attack
+ res 6, [hl] ; no longer invulnerable to typcial attacks
+ ld a, [W_ENEMYMOVENUM] ; $cfcc
+ ld [$d0b5], a
+ ld a, $2c
+ ld [$d0b7], a
+ ld a, MOVE_NAME
+ ld [W_LISTTYPE], a
+ call GetName
+ ld de, $cd6d
+ call CopyStringToCF4B
+asm_3e72b: ; 3e72b (f:672b)
+ xor a
+ ld [$cced], a
+ call PrintMonName1Text
+ ld a, [W_ENEMYMOVEEFFECT] ; $cfcd
+ ld hl, EffectsArray1 ; $4000
+ ld de, $1
+ call IsInArray
+ jp c, Func_3f132
+ ld a, [W_ENEMYMOVEEFFECT] ; $cfcd
+ ld hl, EffectsArray5B ; $4049
+ ld de, $1
+ call IsInArray
+ call c, Func_3f132
+asm_3e750: ; 3e750 (f:6750)
+ call Func_3ec81
+ ld a, [W_ENEMYMOVEEFFECT] ; $cfcd
+ ld hl, EffectsArray2 ; $4011
+ ld de, $1
+ call IsInArray
+ jp c, Func_3e77f
+ call CriticalHitTest
+ call HandleCounterMove
+ jr z, asm_3e782
+ call Func_3ec81
+ call Func_3de75
+ call Func_3ec81
+ call MoreCalculateDamage
+ jp z, Func_3e7d1
+ call AdjustDamageForMoveType
+ call Func_3e687
+
+Func_3e77f: ; 3e77f (f:677f)
+ call MoveHitTest
+asm_3e782: ; 3e782 (f:6782)
+ ld a, [W_MOVEMISSED] ; $d05f
+ and a
+ jr z, .asm_3e791
+ ld a, [W_ENEMYMOVEEFFECT] ; $cfcd
+ cp EXPLODE_EFFECT
+ jr z, asm_3e7a0
+ jr Func_3e7d1
+.asm_3e791
+ call Func_3ec81
+
+Func_3e794: ; 3e794 (f:6794)
+ ld a, [W_ENEMYMOVEEFFECT] ; $cfcd
+ and a
+ ld a, $1
+ jr z, asm_3e7a4
+ ld a, $2
+ jr asm_3e7a4
+asm_3e7a0: ; 3e7a0 (f:67a0)
+ call Func_3ec81
+ xor a
+asm_3e7a4: ; 3e7a4 (f:67a4)
+ push af
+ ld a, [W_ENEMYBATTSTATUS2] ; $d068
+ bit 4, a ; does mon have a substitute?
+ ld hl, Func_79747
+ ld b, BANK(Func_79747)
+ call nz, Bankswitch
+ pop af
+ ld [$cc5b], a
+ ld a, [W_ENEMYMOVENUM] ; $cfcc
+ call PlayMoveAnimation
+ call Func_3eed3
+ call Func_3cdec
+ ld a, [W_ENEMYBATTSTATUS2] ; $d068
+ bit 4, a ; does mon have a substitute?
+ ld hl, Func_79771
+ ld b, BANK(Func_79771)
+ call nz, Bankswitch ; slide the substitute's sprite out
+ jr asm_3e7ef
+
+Func_3e7d1: ; 3e7d1 (f:67d1)
+ call Func_3ec81
+ ld c, $1e
+ call DelayFrames
+ ld a, [W_ENEMYMOVEEFFECT] ; $cfcd
+ cp FLY_EFFECT
+ jr z, .asm_3e7e6
+ cp CHARGE_EFFECT
+ jr z, .asm_3e7e6
+ jr asm_3e7ef
+.asm_3e7e6
+ xor a
+ ld [$cc5b], a
+ ld a,STATUS_AFFECTED_ANIM
+ call PlayMoveAnimation
+asm_3e7ef: ; 3e7ef (f:67ef)
+ ld a, [W_ENEMYMOVEEFFECT] ; $cfcd
+ cp MIRROR_MOVE_EFFECT
+ jr nz, .notMirrorMoveEffect
+ call MirrorMoveCopyMove
+ jp z, Func_3e88c
+ jp Func_3e6fc
+.notMirrorMoveEffect
+ cp METRONOME_EFFECT
+ jr nz, .notMetronomeEffect
+ call MetronomePickMove
+ jp Func_3e6fc
+.notMetronomeEffect
+ ld a, [W_ENEMYMOVEEFFECT] ; $cfcd
+ ld hl, EffectsArray3 ; $4014
+ ld de, $1
+ call IsInArray
+ jp c, Func_3f132
+ ld a, [W_MOVEMISSED] ; $d05f
+ and a
+ jr z, .asm_3e82b
+ call PrintMoveFailureText
+ ld a, [W_ENEMYMOVEEFFECT] ; $cfcd
+ cp EXPLODE_EFFECT
+ jr z, .asm_3e83e
+ jp Func_3e88c
+.asm_3e82b
+ call ApplyAttackToPlayerPokemon
+ call Func_3dc5c
+ callab DisplayEffectiveness
+ ld a, $1
+ ld [$ccf4], a
+.asm_3e83e
+ ld a, [W_ENEMYMOVEEFFECT] ; $cfcd
+ ld hl, EffectsArray4 ; $4030
+ ld de, $1
+ call IsInArray
+ call c, Func_3f132
+ ld hl, W_PLAYERMONCURHP ; $d015
+ ld a, [hli]
+ ld b, [hl]
+ or b
+ ret z
+ call HandleBuildingRage
+ ld hl, W_ENEMYBATTSTATUS1 ; $d067
+ bit 2, [hl] ; is mon hitting multiple times? (example: double kick)
+ jr z, .asm_3e873
+ push hl
+ ld hl, $d06f
+ dec [hl]
+ pop hl
+ jp nz, Func_3e794
+ res 2, [hl] ; mon is no longer hitting multiple times
+ ld hl, HitXTimesText ; $6887
+ call PrintText
+ xor a
+ ld [$cd05], a
+.asm_3e873
+ ld a, [W_ENEMYMOVEEFFECT] ; $cfcd
+ and a
+ jr z, Func_3e88c
+ ld hl, EffectsArray5 ; $403b
+ ld de, $1
+ call IsInArray
+ call nc, Func_3f132
+ jr Func_3e88c
+
+HitXTimesText: ; 3e887 (f:6887)
+ TX_FAR _HitXTimesText
+ db "@"
+
+Func_3e88c: ; 3e88c (f:688c)
+ ld b, $1
+ ret
+
+Func_3e88f: ; 3e88f (f:688f)
+ ld hl, W_ENEMYMONSTATUS ; $cfe9
+ ld a, [hl]
+ and $7
+ jr z, .asm_3e8bf
+ dec a
+ ld [W_ENEMYMONSTATUS], a ; $cfe9
+ and a
+ jr z, .asm_3e8af
+ ld hl, FastAsleepText
+ call PrintText
+ xor a
+ ld [$cc5b], a
+ ld a,SLP_ANIM
+ call PlayMoveAnimation
+ jr .asm_3e8b5
+.asm_3e8af
+ ld hl, WokeUpText
+ call PrintText
+.asm_3e8b5
+ xor a
+ ld [$ccf2], a
+ ld hl, Func_3e88c ; $688c
+ jp Func_3eab8
+.asm_3e8bf
+ bit 5, [hl]
+ jr z, .asm_3e8d3
+ ld hl, IsFrozenText
+ call PrintText
+ xor a
+ ld [$ccf2], a
+ ld hl, Func_3e88c ; $688c
+ jp Func_3eab8
+.asm_3e8d3
+ ld a, [W_PLAYERBATTSTATUS1] ; $d062
+ bit 5, a
+ jp z, Func_3e8e7
+ ld hl, CantMoveText
+ call PrintText
+ ld hl, Func_3e88c ; $688c
+ jp Func_3eab8
+
+Func_3e8e7: ; 3e8e7 (f:68e7)
+ ld hl, W_ENEMYBATTSTATUS1 ; $d067
+ bit 3, [hl]
+ jp z, Func_3e8fd
+ res 3, [hl]
+ ld hl, FlinchedText
+ call PrintText
+ ld hl, Func_3e88c ; $688c
+ jp Func_3eab8
+
+Func_3e8fd: ; 3e8fd (f:68fd)
+ ld hl, W_ENEMYBATTSTATUS2 ; $d068
+ bit 5, [hl]
+ jr z, .asm_3e912
+ res 5, [hl]
+ ld hl, MustRechargeText
+ call PrintText
+ ld hl, Func_3e88c ; $688c
+ jp Func_3eab8
+.asm_3e912
+ ld hl, W_ENEMYDISABLEDMOVE ; $d072
+ ld a, [hl]
+ and a
+ jr z, .asm_3e929
+ dec a
+ ld [hl], a
+ and $f
+ jr nz, .asm_3e929
+ ld [hl], a
+ ld [$ccef], a
+ ld hl, DisabledNoMoreText
+ call PrintText
+.asm_3e929
+ ld a, [W_ENEMYBATTSTATUS1] ; $d067
+ add a
+ jp nc, Func_3e9aa
+ ld hl, $d070
+ dec [hl]
+ jr nz, .asm_3e944
+ ld hl, W_ENEMYBATTSTATUS1 ; $d067
+ res 7, [hl]
+ ld hl, ConfusedNoMoreText
+ call PrintText
+ jp Func_3e9aa
+.asm_3e944
+ ld hl, IsConfusedText
+ call PrintText
+ xor a
+ ld [$cc5b], a
+ ld a,CONF_ANIM
+ call PlayMoveAnimation
+ call GenRandomInBattle
+ cp $80
+ jr c, Func_3e9aa
+ ld hl, W_ENEMYBATTSTATUS1 ; $d067
+ ld a, [hl]
+ and $80
+ ld [hl], a
+ ld hl, HurtItselfText
+ call PrintText
+ ld hl, W_PLAYERMONDEF
+ ld a, [hli]
+ push af
+ ld a, [hld]
+ push af
+ ld a, [W_ENEMYMONDEFENSE] ; $cff8
+ ld [hli], a
+ ld a, [$cff9]
+ ld [hl], a
+ ld hl, W_ENEMYMOVEEFFECT ; $cfcd
+ push hl
+ ld a, [hl]
+ push af
+ xor a
+ ld [hli], a
+ ld [$d05e], a
+ ld a, $28
+ ld [hli], a
+ xor a
+ ld [hl], a
+ call Func_3de75
+ call MoreCalculateDamage
+ pop af
+ pop hl
+ ld [hl], a
+ ld hl, $d028
+ pop af
+ ld [hld], a
+ pop af
+ ld [hl], a
+ xor a
+ ld [$cc5b], a
+ ld [H_WHOSETURN], a ; $fff3
+ ld a, POUND
+ call PlayMoveAnimation
+ ld a, $1
+ ld [H_WHOSETURN], a ; $fff3
+ call ApplyDamageToEnemyPokemon
+ jr asm_3e9d3
+
+Func_3e9aa: ; 3e9aa (f:69aa)
+ ld a, [$ccef]
+ and a
+ jr z, .asm_3e9bf
+ ld hl, wEnemySelectedMove ; $ccdd
+ cp [hl]
+ jr nz, .asm_3e9bf
+ call PrintMoveIsDisabledText
+ ld hl, Func_3e88c ; $688c
+ jp Func_3eab8
+.asm_3e9bf
+ ld hl, W_ENEMYMONSTATUS ; $cfe9
+ bit 6, [hl]
+ jr z, asm_3e9f6
+ call GenRandomInBattle
+ cp $3f
+ jr nc, asm_3e9f6
+ ld hl, FullyParalyzedText
+ call PrintText
+asm_3e9d3: ; 3e9d3 (f:69d3)
+ ld hl, W_ENEMYBATTSTATUS1 ; $d067
+ ld a, [hl]
+ and $cc
+ ld [hl], a
+ ld a, [W_ENEMYMOVEEFFECT] ; $cfcd
+ cp FLY_EFFECT
+ jr z, .asm_3e9e7
+ cp CHARGE_EFFECT
+ jr z, .asm_3e9e7
+ jr .asm_3e9f0
+.asm_3e9e7
+ xor a
+ ld [$cc5b], a
+ ld a, STATUS_AFFECTED_ANIM
+ call PlayMoveAnimation
+.asm_3e9f0
+ ld hl, Func_3e88c ; $688c
+ jp Func_3eab8
+asm_3e9f6: ; 3e9f6 (f:69f6)
+ ld hl, W_ENEMYBATTSTATUS1 ; $d067
+ bit 0, [hl] ; is mon using bide?
+ jr z, .asm_3ea54
+ xor a
+ ld [W_ENEMYMOVENUM], a ; $cfcc
+ ld hl, W_DAMAGE ; $d0d7
+ ld a, [hli]
+ ld b, a
+ ld c, [hl]
+ ld hl, $cd06
+ ld a, [hl]
+ add c
+ ld [hld], a
+ ld a, [hl]
+ adc b
+ ld [hl], a
+ ld hl, $d06f
+ dec [hl]
+ jr z, .asm_3ea1c
+ ld hl, Func_3e88c ; $688c
+ jp Func_3eab8
+.asm_3ea1c
+ ld hl, W_ENEMYBATTSTATUS1 ; $d067
+ res 0, [hl]
+ ld hl, UnleashedEnergyText
+ call PrintText
+ ld a, $1
+ ld [W_ENEMYMOVEPOWER], a ; $cfce
+ ld hl, $cd06
+ ld a, [hld]
+ add a
+ ld b, a
+ ld [$d0d8], a
+ ld a, [hl]
+ rl a
+ ld [W_DAMAGE], a ; $d0d7
+ or b
+ jr nz, .asm_3ea43
+ ld a, $1
+ ld [W_MOVEMISSED], a ; $d05f
+.asm_3ea43
+ xor a
+ ld [hli], a
+ ld [hl], a
+ ld a, BIDE
+ ld [W_ENEMYMOVENUM], a ; $cfcc
+ call Func_3ec81
+ ld hl, asm_3e782 ; $6782
+ jp Func_3eab8
+.asm_3ea54
+ bit 1, [hl] ; is mon using thrash or petal dance?
+ jr z, .asm_3ea83
+ ld a, THRASH
+ ld [W_ENEMYMOVENUM], a ; $cfcc
+ ld hl, ThrashingAboutText
+ call PrintText
+ ld hl, $d06f
+ dec [hl]
+ ld hl, asm_3e750 ; $6750
+ jp nz, Func_3eab8
+ push hl
+ ld hl, W_ENEMYBATTSTATUS1 ; $d067
+ res 1, [hl] ; mon is no longer using thrash or petal dance
+ set 7, [hl] ; mon is now confused
+ call GenRandomInBattle
+ and $3
+ inc a
+ inc a
+ ld [$d070], a
+ pop hl
+ jp Func_3eab8
+.asm_3ea83
+ bit 5, [hl] ; is mon using multi-turn move?
+ jp z, Func_3ea9b
+ ld hl, AttackContinuesText
+ call PrintText
+ ld hl, $d06f
+ dec [hl]
+ ld hl, Func_3e794 ; $6794
+ jp nz, Func_3eab8
+ jp Func_3eab8
+
+Func_3ea9b: ; 3ea9b (f:6a9b)
+ ld a, [W_ENEMYBATTSTATUS2] ; $d068
+ bit 6, a ; is mon using rage?
+ jp z, Func_3eaba
+ ld a, RAGE
+ ld [$d11e], a
+ call GetMoveName
+ call CopyStringToCF4B
+ xor a
+ ld [W_ENEMYMOVEEFFECT], a ; $cfcd
+ ld hl, asm_3e72b ; $672b
+ jp Func_3eab8
+
+Func_3eab8: ; 3eab8 (f:6ab8)
+ xor a
+ ret
+
+Func_3eaba: ; 3eaba (f:6aba)
+ ld a, $1
+ and a
+ ret
+
+GetCurrentMove: ; 3eabe (f:6abe)
+ ld a, [H_WHOSETURN] ; $fff3
+ and a
+ jp z, .player
+ ld de, W_ENEMYMOVENUM ; $cfcc
+ ld a, [wEnemySelectedMove] ; $ccdd
+ jr .selected
+.player
+ ld de, W_PLAYERMOVENUM ; $cfd2
+ ld a, [W_FLAGS_D733]
+ bit 0, a
+ ld a, [$ccd9]
+ jr nz, .selected
+ ld a, [wPlayerSelectedMove] ; $ccdc
+.selected
+ ld [$d0b5], a
+ dec a
+ ld hl, Moves ; $4000
+ ld bc, $6
+ call AddNTimes
+ ld a, BANK(Moves)
+ call FarCopyData
+ ld a, $2c
+ ld [$d0b7], a
+ ld a, $2
+ ld [W_LISTTYPE], a ; list type 2 = move name
+ call GetName
+ ld de, $cd6d
+ jp CopyStringToCF4B
+
+Func_3eb01: ; 3eb01 (f:6b01)
+ ld a, [W_ISLINKBATTLE] ; $d12b
+ cp $4
+ jp z, Func_3cc13
+ ld a, [W_ENEMYMONID]
+ ld [$cfe5], a
+ ld [$d0b5], a
+ call GetMonHeader
+ ld a, [W_ENEMYBATTSTATUS3] ; $d069
+ bit 3, a
+ ld hl, $cceb
+ ld a, [hli]
+ ld b, [hl]
+ jr nz, .asm_3eb33
+ ld a, [W_ISINBATTLE] ; $d057
+ cp $2
+ ld a, $98
+ ld b, $88
+ jr z, .asm_3eb33
+ call GenRandomInBattle
+ ld b, a
+ call GenRandomInBattle
+.asm_3eb33
+ ld hl, $cff1
+ ld [hli], a
+ ld [hl], b
+ ld de, W_ENEMYMONLEVEL ; $cff3
+ ld a, [W_CURENEMYLVL] ; $d127
+ ld [de], a
+ inc de
+ ld b, $0
+ ld hl, W_ENEMYMONCURHP ; $cfe6
+ push hl
+ call CalcStats
+ pop hl
+ ld a, [W_ISINBATTLE] ; $d057
+ cp $2
+ jr z, .asm_3eb65
+ ld a, [W_ENEMYBATTSTATUS3] ; $d069
+ bit 3, a
+ jr nz, .asm_3eb86
+ ld a, [W_ENEMYMONMAXHP] ; $cff4
+ ld [hli], a
+ ld a, [W_ENEMYMONMAXHP+1]
+ ld [hli], a
+ xor a
+ inc hl
+ ld [hl], a
+ jr .asm_3eb86
+.asm_3eb65
+ ld hl, W_ENEMYMON1HP ; $d8a5 (aliases: W_WATERMONS)
+ ld a, [wWhichPokemon] ; $cf92
+ ld bc, $2c
+ call AddNTimes
+ ld a, [hli]
+ ld [W_ENEMYMONCURHP], a ; $cfe6
+ ld a, [hli]
+ ld [$cfe7], a
+ ld a, [wWhichPokemon] ; $cf92
+ ld [W_ENEMYMONNUMBER], a ; $cfe8
+ inc hl
+ ld a, [hl]
+ ld [W_ENEMYMONSTATUS], a ; $cfe9
+ jr .asm_3eb86
+.asm_3eb86
+ ld hl, W_MONHTYPES
+ ld de, W_ENEMYMONTYPES ; $cfea
+ ld a, [hli] ; copy type 1
+ ld [de], a
+ inc de
+ ld a, [hli] ; copy type 2
+ ld [de], a
+ inc de
+ ld a, [hli] ; copy catch rate
+ ld [de], a
+ inc de
+ ld a, [W_ISINBATTLE] ; $d057
+ cp $2
+ jr nz, .asm_3ebb0
+ ld hl, $d8ac
+ ld a, [wWhichPokemon] ; $cf92
+ ld bc, $2c
+ call AddNTimes
+ ld bc, $4
+ call CopyData
+ jr .asm_3ebca
+.asm_3ebb0
+ ld hl, W_MONHMOVES
+ ld a, [hli]
+ ld [de], a
+ inc de
+ ld a, [hli]
+ ld [de], a
+ inc de
+ ld a, [hli]
+ ld [de], a
+ inc de
+ ld a, [hl]
+ ld [de], a
+ dec de
+ dec de
+ dec de
+ xor a
+ ld [$cee9], a
+ ld a, $3e
+ call Predef ; indirect jump to WriteMonMoves (3afb8 (e:6fb8))
+.asm_3ebca
+ ld hl, W_ENEMYMONMOVES
+ ld de, $cffd
+ ld a, $5e
+ call Predef ; indirect jump to LoadMovePPs (f473 (3:7473))
+ ld hl, W_MONHBASESTATS
+ ld de, $d002
+ ld b, $5
+.asm_3ebdd
+ ld a, [hli]
+ ld [de], a
+ inc de
+ dec b
+ jr nz, .asm_3ebdd
+ ld hl, W_MONHCATCHRATE
+ ld a, [hli]
+ ld [de], a
+ inc de
+ ld a, [hl] ; base exp
+ ld [de], a
+ ld a, [W_ENEMYMONID]
+ ld [$d11e], a
+ call GetMonName
+ ld hl, $cd6d
+ ld de, W_ENEMYMONNAME
+ ld bc, $b
+ call CopyData
+ ld a, [W_ENEMYMONID]
+ ld [$d11e], a
+ ld a, $3a
+ call Predef ; indirect jump to IndexToPokedex (41010 (10:5010))
+ ld a, [$d11e]
+ dec a
+ ld c, a
+ ld b, $1
+ ld hl, wPokedexSeen ; $d30a
+ ld a, $10
+ call Predef ; indirect jump to HandleBitArray (f666 (3:7666))
+ ld hl, W_ENEMYMONLEVEL ; $cff3
+ ld de, $cd23
+ ld bc, $b
+ call CopyData
+ ld a, $7
+ ld b, $8
+ ld hl, wEnemyMonStatMods ; $cd2e
+.asm_3ec2d
+ ld [hli], a
+ dec b
+ jr nz, .asm_3ec2d
+ ret
+
+Func_3ec32: ; 3ec32 (f:6c32)
+ ld a, [W_ISLINKBATTLE] ; $d12b
+ cp $4
+ jr nz, .asm_3ec4d
+ xor a
+ ld [wMenuJoypadPollCount], a ; $cc34
+ callab Func_372d6
+ ld a, $1
+ ld [$cfcb], a
+ call ClearScreen
+.asm_3ec4d
+ call DelayFrame
+ ld a, $30
+ call Predef ; indirect jump to Func_7096d (7096d (1c:496d))
+ callab Func_3ee58
+ ld a, $1
+ ld [H_AUTOBGTRANSFERENABLED], a ; $ffba
+ ld a, $ff
+ ld [$cfcb], a
+ call CleanLCD_OAM
+ call ClearScreen
+ xor a
+ ld [H_AUTOBGTRANSFERENABLED], a ; $ffba
+ ld [$ffb0], a
+ ld [rWY], a ; $ff4a
+ ld [$ffd7], a
+ ld hl, $d060
+ ld [hli], a
+ ld [hli], a
+ ld [hli], a
+ ld [hli], a
+ ld [hl], a
+ ld [W_PLAYERDISABLEDMOVE], a ; $d06d
+ ret
+
+Func_3ec81: ; 3ec81 (f:6c81)
+ push bc
+ ld a, [W_PLAYERMONLEVEL] ; $d022
+ ld b, a
+ ld a, [W_ENEMYMONLEVEL] ; $cff3
+ ld [W_PLAYERMONLEVEL], a ; $d022
+ ld a, b
+ ld [W_ENEMYMONLEVEL], a ; $cff3
+ pop bc
+ ret
+
+Func_3ec92: ; 3ec92 (f:6c92)
+ ld a, [W_BATTLETYPE] ; $d05a
+ dec a
+ ld de, RedPicBack ; $7e0a
+ jr nz, .asm_3ec9e
+ ld de, OldManPic ; $7e9a
+.asm_3ec9e
+ ld a, BANK(RedPicBack)
+ call UncompressSpriteFromDE
+ ld a, $3
+ call Predef ; indirect jump to ScaleSpriteByTwo (2fe40 (b:7e40))
+ ld hl, wOAMBuffer
+ xor a
+ ld [H_DOWNARROWBLINKCNT1], a ; $ff8b
+ ld b, $7
+ ld e, $a0
+.asm_3ecb2
+ ld c, $3
+ ld d, $38
+.asm_3ecb6
+ ld [hl], d
+ inc hl
+ ld [hl], e
+ ld a, $8
+ add d
+ ld d, a
+ inc hl
+ ld a, [H_DOWNARROWBLINKCNT1] ; $ff8b
+ ld [hli], a
+ inc a
+ ld [H_DOWNARROWBLINKCNT1], a ; $ff8b
+ inc hl
+ dec c
+ jr nz, .asm_3ecb6
+ ld a, [H_DOWNARROWBLINKCNT1] ; $ff8b
+ add $4
+ ld [H_DOWNARROWBLINKCNT1], a ; $ff8b
+ ld a, $8
+ add e
+ ld e, a
+ dec b
+ jr nz, .asm_3ecb2
+ ld de, $9310
+ call InterlaceMergeSpriteBuffers
+ ld a, $a
+ ld [$0], a
+ xor a
+ ld [$4000], a
+ ld hl, $8000
+ ld de, S_SPRITEBUFFER1
+ ld a, [H_LOADEDROMBANK]
+ ld b, a
+ ld c, $31
+ call CopyVideoData
+ xor a
+ ld [$0], a
+ ld a, $31
+ ld [$ffe1], a
+ FuncCoord 1, 5 ; $c405
+ ld hl, Coord
+ ld a, $1
+ jp Predef ; indirect jump to Func_3f0c6 (3f0c6 (f:70c6))
+
+Func_3ed02: ; 3ed02 (f:6d02)
+ callab Func_39680
+ ld hl, Func_396a7
+ ld b, BANK(Func_396a7)
+ jp Bankswitch
+
+ScrollTrainerPicAfterBattle: ; 3ed12 (f:6d12)
+ ld hl, _ScrollTrainerPicAfterBattle
+ ld b, BANK(_ScrollTrainerPicAfterBattle)
+ jp Bankswitch
+
+Func_3ed1a: ; 3ed1a (f:6d1a)
+ ld a, $1
+ jr asm_3ed1f
+
+Func_3ed1e: ; 3ed1e (f:6d1e)
+ xor a
+asm_3ed1f: ; 3ed1f (f:6d1f)
+ ld [H_WHOSETURN], a ; $fff3
+ call Func_3ed27
+ jp Func_3ed64
+
+Func_3ed27: ; 3ed27 (f:6d27)
+ ld a, [H_WHOSETURN] ; $fff3
+ and a
+ jr z, .asm_3ed48
+ ld a, [W_PLAYERMONSTATUS] ; $d018
+ and $40
+ ret z
+ ld hl, $d02a
+ ld a, [hld]
+ ld b, a
+ ld a, [hl]
+ srl a
+ rr b
+ srl a
+ rr b
+ ld [hli], a
+ or b
+ jr nz, .asm_3ed46
+ ld b, $1
+.asm_3ed46
+ ld [hl], b
+ ret
+.asm_3ed48
+ ld a, [W_ENEMYMONSTATUS] ; $cfe9
+ and $40
+ ret z
+ ld hl, $cffb
+ ld a, [hld]
+ ld b, a
+ ld a, [hl]
+ srl a
+ rr b
+ srl a
+ rr b
+ ld [hli], a
+ or b
+ jr nz, .asm_3ed62
+ ld b, $1
+.asm_3ed62
+ ld [hl], b
+ ret
+
+Func_3ed64: ; 3ed64 (f:6d64)
+ ld a, [H_WHOSETURN] ; $fff3
+ and a
+ jr z, .asm_3ed81
+ ld a, [W_PLAYERMONSTATUS] ; $d018
+ and $10
+ ret z
+ ld hl, $d026
+ ld a, [hld]
+ ld b, a
+ ld a, [hl]
+ srl a
+ rr b
+ ld [hli], a
+ or b
+ jr nz, .asm_3ed7f
+ ld b, $1
+.asm_3ed7f
+ ld [hl], b
+ ret
+.asm_3ed81
+ ld a, [W_ENEMYMONSTATUS] ; $cfe9
+ and $10
+ ret z
+ ld hl, $cff7
+ ld a, [hld]
+ ld b, a
+ ld a, [hl]
+ srl a
+ rr b
+ ld [hli], a
+ or b
+ jr nz, .asm_3ed97
+ ld b, $1
+.asm_3ed97
+ ld [hl], b
+ ret
+
+Func_3ed99: ; 3ed99 (f:6d99)
+ ld c, $0
+.asm_3ed9b
+ call Func_3eda5
+ inc c
+ ld a, c
+ cp $4
+ jr nz, .asm_3ed9b
+ ret
+
+Func_3eda5: ; 3eda5 (f:6da5)
+ push bc
+ push bc
+ ld a, [$d11e]
+ and a
+ ld a, c
+ ld hl, W_PLAYERMONATK
+ ld de, $cd12
+ ld bc, wPlayerMonAttackMod ; $cd1a
+ jr z, .asm_3edc0
+ ld hl, W_ENEMYMONATTACK
+ ld de, $cd26
+ ld bc, wEnemyMonStatMods ; $cd2e
+.asm_3edc0
+ add c
+ ld c, a
+ jr nc, .asm_3edc5
+ inc b
+.asm_3edc5
+ ld a, [bc]
+ pop bc
+ ld b, a
+ push bc
+ sla c
+ ld b, $0
+ add hl, bc
+ ld a, c
+ add e
+ ld e, a
+ jr nc, .asm_3edd4
+ inc d
+.asm_3edd4
+ pop bc
+ push hl
+ ld hl, StatModifierRatios ; $76cb
+ dec b
+ sla b
+ ld c, b
+ ld b, $0
+ add hl, bc
+ xor a
+ ld [H_NUMTOPRINT], a ; $ff96 (aliases: H_MULTIPLICAND)
+ ld a, [de]
+ ld [$ff97], a
+ inc de
+ ld a, [de]
+ ld [$ff98], a
+ ld a, [hli]
+ ld [H_REMAINDER], a ; $ff99 (aliases: H_DIVISOR, H_MULTIPLIER, H_POWEROFTEN)
+ call Multiply
+ ld a, [hl]
+ ld [H_REMAINDER], a ; $ff99 (aliases: H_DIVISOR, H_MULTIPLIER, H_POWEROFTEN)
+ ld b, $4
+ call Divide
+ pop hl
+ ld a, [$ff98]
+ sub $e7
+ ld a, [$ff97]
+ sbc $3
+ jp c, Func_3ee0c
+ ld a, $3
+ ld [$ff97], a
+ ld a, $e7
+ ld [$ff98], a
+
+Func_3ee0c: ; 3ee0c (f:6e0c)
+ ld a, [$ff97]
+ ld [hli], a
+ ld b, a
+ ld a, [$ff98]
+ ld [hl], a
+ or b
+ jr nz, .asm_3ee17
+ inc [hl]
+.asm_3ee17
+ pop bc
+ ret
+
+Func_3ee19: ; 3ee19 (f:6e19)
+ ld a, [W_ISLINKBATTLE]
+ cp $4
+ ret z
+ ld a, [W_OBTAINEDBADGES]
+ ld b, a
+ ld hl, W_PLAYERMONATK
+ ld c, $4
+.asm_3ee28
+ srl b
+ call c, Func_3ee35
+ inc hl
+ inc hl
+ srl b
+ dec c
+ jr nz, .asm_3ee28
+ ret
+
+Func_3ee35: ; 3ee35 (f:6e35)
+ ld a, [hli]
+ ld d, a
+ ld e, [hl]
+ srl d
+ rr e
+ srl d
+ rr e
+ srl d
+ rr e
+ ld a, [hl]
+ add e
+ ld [hld], a
+ ld a, [hl]
+ adc d
+ ld [hli], a
+ ld a, [hld]
+ sub $e7
+ ld a, [hl]
+ sbc $3
+ ret c
+ ld a, $3
+ ld [hli], a
+ ld a, $e7
+ ld [hld], a
+ ret
+
+Func_3ee58: ; 3ee58 (f:6e58)
+ call LoadHpBarAndStatusTilePatterns
+
+Func_3ee5b: ; 3ee5b (f:6e5b)
+ ld a, [rLCDC] ; $ff40
+ add a
+ jr c, .asm_3ee7c
+ ld hl, BattleHudTiles1 ; $6080
+ ld de, $96d0
+ ld bc, $18
+ ld a, BANK(BattleHudTiles1)
+ call FarCopyDataDouble
+ ld hl, BattleHudTiles2 ; $6098
+ ld de, $9730
+ ld bc, $30
+ ld a, BANK(BattleHudTiles2)
+ jp FarCopyDataDouble
+.asm_3ee7c
+ ld de, BattleHudTiles1 ; $6080
+ ld hl, $96d0
+ ld bc, (BANK(BattleHudTiles1) << 8) + $03
+ call CopyVideoDataDouble
+ ld de, BattleHudTiles2 ; $6098
+ ld hl, $9730
+ ld bc, (BANK(BattleHudTiles2) << 8) + $06
+ jp CopyVideoDataDouble
+
+Func_3ee94: ; 3ee94 (f:6e94)
+ ld hl, TerminatorText_3ee9a ; $6e9a
+ jp PrintText
+
+TerminatorText_3ee9a: ; 3ee9a (f:6e9a)
+ db "@"
+
+; generates a random number unless in link battle
+; stores random number in A
+GenRandomInBattle: ; 3ee9b (f:6e9b)
+ ld a, [W_ISLINKBATTLE]
+ cp $4
+ jp nz, GenRandom
+ push hl
+ push bc
+ ld a, [$ccde]
+ ld c, a
+ ld b, $0
+ ld hl, $d148
+ add hl, bc
+ inc a
+ ld [$ccde], a
+ cp $9
+ ld a, [hl]
+ pop bc
+ pop hl
+ ret c
+ push hl
+ push bc
+ push af
+ xor a
+ ld [$ccde], a
+ ld hl, $d148
+ ld b, $9
+.asm_3eec5
+ ld a, [hl]
+ ld c, a
+ add a
+ add a
+ add c
+ inc a
+ ld [hli], a
+ dec b
+ jr nz, .asm_3eec5 ; 0x3eecd $f6
+ pop af
+ pop bc
+ pop hl
+ ret
+
+Func_3eed3: ; 3eed3 (f:6ed3)
+ ld a, [H_WHOSETURN] ; $fff3
+ and a
+ ld hl, W_ENEMYMONTYPE1 ; $cfea (aliases: W_ENEMYMONTYPES)
+ ld de, W_ENEMYBATTSTATUS1 ; $d067
+ ld a, [W_PLAYERMOVENUM] ; $cfd2
+ jr z, .asm_3eeea
+ ld hl, W_PLAYERMONTYPE1 ; $d019 (aliases: W_PLAYERMONTYPES)
+ ld de, W_ENEMYBATTSTATUS1 ; $d067
+ ld a, [W_ENEMYMOVENUM] ; $cfcc
+.asm_3eeea
+ cp SELFDESTRUCT
+ jr z, .asm_3eef1
+ cp EXPLOSION
+ ret nz
+.asm_3eef1
+ ld a, [de]
+ bit 6, a ; fly/dig
+ ret nz
+ ld a, [hli]
+ cp GHOST
+ ret z
+ ld a, [hl]
+ cp GHOST
+ ret z
+ ld a, [W_MOVEMISSED] ; $d05f
+ and a
+ ret nz
+ ld a, MEGA_PUNCH
+ ld [$cc5b], a
+
+PlayMoveAnimation: ; 3ef07 (f:6f07)
+ ld [$D07C],a
+ call Delay3
+ PREDEF_JUMP MoveAnimationPredef ; predef 8
+
+InitBattle: ; 3ef12 (f:6f12)
+ ld a, [W_CUROPPONENT] ; $d059
+ and a
+ jr z, asm_3ef23
+
+InitOpponent: ; 3ef18 (f:6f18)
+ ld a, [W_CUROPPONENT] ; $d059
+ ld [$cf91], a
+ ld [W_ENEMYMONID], a
+ jr asm_3ef3d
+asm_3ef23: ; 3ef23 (f:6f23)
+ ld a, [$d732]
+ bit 1, a
+ jr z, .asm_3ef2f
+ ld a, [H_CURRENTPRESSEDBUTTONS]
+ bit 1, a
+ ret nz
+.asm_3ef2f
+ ld a, [$d13c]
+ and a
+ ret nz
+ callab Func_13870
+ ret nz
+asm_3ef3d: ; 3ef3d (f:6f3d)
+ ld a, [$d35d]
+ push af
+ ld hl, $d358
+ ld a, [hl]
+ push af
+ res 1, [hl]
+ callab Func_525af
+ ld a, [W_ENEMYMONID]
+ sub $c8
+ jp c, InitWildBattle
+ ld [W_TRAINERCLASS], a ; $d031
+ call GetTrainerInformation
+ callab ReadTrainer
+ call Func_3ec32
+ call _LoadTrainerPic
+ xor a
+ ld [W_ENEMYMONID], a
+ ld [$ffe1], a
+ dec a
+ ld [wAICount], a ; $ccdf
+ FuncCoord 12, 0 ; $c3ac
+ ld hl, Coord
+ ld a, $1
+ call Predef ; indirect jump to Func_3f0c6 (3f0c6 (f:70c6))
+ ld a, $ff
+ ld [W_ENEMYMONNUMBER], a ; $cfe8
+ ld a, $2
+ ld [W_ISINBATTLE], a ; $d057
+ jp Func_3efeb
+
+InitWildBattle: ; 3ef8b (f:6f8b)
+ ld a, $1
+ ld [W_ISINBATTLE], a ; $d057
+ call Func_3eb01
+ call Func_3ec32
+ ld a, [W_CUROPPONENT] ; $d059
+ cp MAROWAK
+ jr z, .isGhost
+ call IsGhostBattle
+ jr nz, .isNoGhost
+.isGhost
+ ld hl, W_MONHSPRITEDIM
+ ld a, $66
+ ld [hli], a ; write sprite dimensions
+ ld bc, GhostPic ; $66b5
+ ld a, c
+ ld [hli], a ; write front sprite pointer
+ ld [hl], b
+ ld hl, W_ENEMYMONNAME ; set name to "GHOST"
+ ld a, "G"
+ ld [hli], a
+ ld a, "H"
+ ld [hli], a
+ ld a, "O"
+ ld [hli], a
+ ld a, "S"
+ ld [hli], a
+ ld a, "T"
+ ld [hli], a
+ ld [hl], "@"
+ ld a, [$cf91]
+ push af
+ ld a, MON_GHOST
+ ld [$cf91], a
+ ld de, $9000
+ call LoadMonFrontSprite ; load ghost sprite
+ pop af
+ ld [$cf91], a
+ jr .spriteLoaded
+.isNoGhost
+ ld de, $9000
+ call LoadMonFrontSprite ; load mon sprite
+.spriteLoaded
+ xor a
+ ld [W_TRAINERCLASS], a ; $d031
+ ld [$ffe1], a
+ FuncCoord 12, 0 ; $c3ac
+ ld hl, Coord
+ ld a, $1
+ call Predef ; indirect jump to Func_3f0c6 (3f0c6 (f:70c6))
+
+Func_3efeb: ; 3efeb (f:6feb)
+ ld b, $0
+ call GoPAL_SET
+ call Func_3c04c
+ xor a
+ ld [H_AUTOBGTRANSFERENABLED], a ; $ffba
+ ld hl, TerminatorText_3f04a
+ call PrintText
+ call SaveScreenTilesToBuffer1
+ call ClearScreen
+ ld a, $98
+ ld [$ffbd], a
+ ld a, $1
+ ld [H_AUTOBGTRANSFERENABLED], a ; $ffba
+ call Delay3
+ ld a, $9c
+ ld [$ffbd], a
+ call LoadScreenTilesFromBuffer1
+ FuncCoord 9, 7 ; $c435
+ ld hl, Coord
+ ld bc, $50a
+ call ClearScreenArea
+ FuncCoord 1, 0 ; $c3a1
+ ld hl, Coord
+ ld bc, $40a
+ call ClearScreenArea
+ call CleanLCD_OAM
+ ld a, [W_ISINBATTLE] ; $d057
+ dec a
+ call z, Func_3cdec
+ call Func_3c11e
+ callab Func_137aa
+ pop af
+ ld [$d358], a
+ pop af
+ ld [$d35d], a
+ ld a, [$d0d4]
+ ld [$ffd7], a
+ scf
+ ret
+
+TerminatorText_3f04a: ; 3f04a (f:704a)
+ db "@"
+
+_LoadTrainerPic: ; 3f04b (f:704b)
+; $d033-$d034 contain pointer to pic
+ ld a, [$d033]
+ ld e, a
+ ld a, [$d034]
+ ld d, a ; de contains pointer to trainer pic
+ ld a, [W_ISLINKBATTLE] ; $d12b
+ and a
+ ld a, Bank(TrainerPics) ; this is where all the trainer pics are (not counting Red's)
+ jr z, .loadSprite
+ ld a, Bank(RedPicFront)
+.loadSprite
+ call UncompressSpriteFromDE
+ ld de, $9000
+ ld a, $77
+ ld c, a
+ jp LoadUncompressedSpriteData
+
+Func_3f069: ; 3f069 (f:7069)
+ xor a
+ ld [$c0f1], a
+ ld [$c0f2], a
+ jp PlaySound
+
+Func_3f073: ; 3f073 (f:7073)
+ ld a, [$cc4f]
+ ld h, a
+ ld a, [$cc50]
+ ld l, a
+ ld a, [$ffe1]
+ ld [H_DOWNARROWBLINKCNT1], a ; $ff8b
+ ld b, $4c
+ ld a, [W_ISINBATTLE] ; $d057
+ and a
+ jr z, .asm_3f0bc
+ add b
+ ld [hl], a
+ call Delay3
+ ld bc, $ffd7
+ add hl, bc
+ ld a, $1
+ ld [$cd6c], a
+ ld bc, $303
+ ld a, $5
+ call Predef ; indirect jump to Func_79aba (79aba (1e:5aba))
+ ld c, $4
+ call DelayFrames
+ ld bc, $ffd7
+ add hl, bc
+ xor a
+ ld [$cd6c], a
+ ld bc, $505
+ ld a, $5
+ call Predef ; indirect jump to Func_79aba (79aba (1e:5aba))
+ ld c, $5
+ call DelayFrames
+ ld bc, $ffd7
+ jr .asm_3f0bf
+.asm_3f0bc
+ ld bc, $ff85
+.asm_3f0bf
+ add hl, bc
+ ld a, [H_DOWNARROWBLINKCNT1] ; $ff8b
+ add $31
+ jr asm_3f0d0
+
+Func_3f0c6: ; 3f0c6 (f:70c6)
+ ld a, [$cc4f]
+ ld h, a
+ ld a, [$cc50]
+ ld l, a
+ ld a, [$ffe1]
+asm_3f0d0: ; 3f0d0 (f:70d0)
+ ld bc, $707
+ ld de, $14
+ push af
+ ld a, [W_SPRITEFLIPPED]
+ and a
+ jr nz, .asm_3f0ed
+ pop af
+.asm_3f0de
+ push bc
+ push hl
+.asm_3f0e0
+ ld [hl], a
+ add hl, de
+ inc a
+ dec c
+ jr nz, .asm_3f0e0
+ pop hl
+ inc hl
+ pop bc
+ dec b
+ jr nz, .asm_3f0de
+ ret
+.asm_3f0ed
+ push bc
+ ld b, $0
+ dec c
+ add hl, bc
+ pop bc
+ pop af
+.asm_3f0f4
+ push bc
+ push hl
+.asm_3f0f6
+ ld [hl], a
+ add hl, de
+ inc a
+ dec c
+ jr nz, .asm_3f0f6
+ pop hl
+ dec hl
+ pop bc
+ dec b
+ jr nz, .asm_3f0f4
+ ret
+
+; loads back sprite of mon to $8000
+; assumes the corresponding mon header is already loaded
+LoadMonBackSprite: ; 3f103 (f:7103)
+ ld a, [$cfd9]
+ ld [$cf91], a
+ FuncCoord 1, 5 ; $c405
+ ld hl, Coord
+ ld b, $7
+ ld c, $8
+ call ClearScreenArea
+ ld hl, W_MONHBACKSPRITE - W_MONHEADER
+ call UncompressMonSprite
+ ld a, $3
+ call Predef ; indirect jump to ScaleSpriteByTwo (2fe40 (b:7e40))
+ ld de, $9310
+ call InterlaceMergeSpriteBuffers ; combine the two buffers to a single 2bpp sprite
+ ld hl, $8000
+ ld de, $9310
+ ld c, (2*SPRITEBUFFERSIZE)/16 ; count of 16-byte chunks to be copied
+ ld a, [H_LOADEDROMBANK]
+ ld b, a
+ jp CopyVideoData
+
+Func_3f132: ; 3f132 (f:7132)
+ call JumpMoveEffect
+ ld b, $1
+ ret
+
+JumpMoveEffect: ; 3f138 (f:7138)
+ ld a, [$fff3] ;whose turn?
+ and a
+ ld a, [W_PLAYERMOVEEFFECT]
+ jr z, .next1
+ ld a, [W_ENEMYMOVEEFFECT]
+.next1
+ dec a ;subtract 1, there is no special effect for 00
+ add a ;x2, 16bit pointers
+ ld hl, MoveEffectPointerTable
+ ld b, 0
+ ld c, a
+ add hl, bc
+ ld a, [hli]
+ ld h, [hl]
+ ld l, a
+ jp [hl] ;jump to special effect handler
+
+MoveEffectPointerTable: ; 3f150 (f:7150)
+ dw SleepEffect ; unused effect
+ dw PoisonEffect ; POISON_SIDE_EFFECT1
+ dw DrainHPEffect ; DRAIN_HP_EFFECT
+ dw FreezeBurnParalyzeEffect ; BURN_SIDE_EFFECT1
+ dw FreezeBurnParalyzeEffect ; FREEZE_SIDE_EFFECT
+ dw FreezeBurnParalyzeEffect ; PARALYZE_SIDE_EFFECT1
+ dw ExplodeEffect ; EXPLODE_EFFECT
+ dw DrainHPEffect ; DREAM_EATER_EFFECT
+ dw $0000 ; MIRROR_MOVE_EFFECT
+ dw StatModifierUpEffect ; ATTACK_UP1_EFFECT
+ dw StatModifierUpEffect ; DEFENSE_UP1_EFFECT
+ dw StatModifierUpEffect ; SPEED_UP1_EFFECT
+ dw StatModifierUpEffect ; SPECIAL_UP1_EFFECT
+ dw StatModifierUpEffect ; ACCURACY_UP1_EFFECT
+ dw StatModifierUpEffect ; EVASION_UP1_EFFECT
+ dw PayDayEffect ; PAY_DAY_EFFECT
+ dw $0000 ; SWIFT_EFFECT
+ dw StatModifierDownEffect ; ATTACK_DOWN1_EFFECT
+ dw StatModifierDownEffect ; DEFENSE_DOWN1_EFFECT
+ dw StatModifierDownEffect ; SPEED_DOWN1_EFFECT
+ dw StatModifierDownEffect ; SPECIAL_DOWN1_EFFECT
+ dw StatModifierDownEffect ; ACCURACY_DOWN1_EFFECT
+ dw StatModifierDownEffect ; EVASION_DOWN1_EFFECT
+ dw ConversionEffect ; CONVERSION_EFFECT
+ dw HazeEffect ; HAZE_EFFECT
+ dw BideEffect ; BIDE_EFFECT
+ dw ThrashPetalDanceEffect ; THRASH_PETAL_DANCE_EFFECT
+ dw SwitchAndTeleportEffect ; SWITCH_AND_TELEPORT_EFFECT
+ dw TwoToFiveAttacksEffect ; TWO_TO_FIVE_ATTACKS_EFFECT
+ dw TwoToFiveAttacksEffect ; unused effect
+ dw FlichSideEffect ; FLINCH_SIDE_EFFECT1
+ dw SleepEffect ; SLEEP_EFFECT
+ dw PoisonEffect ; POISON_SIDE_EFFECT2
+ dw FreezeBurnParalyzeEffect ; BURN_SIDE_EFFECT2
+ dw FreezeBurnParalyzeEffect ; unused effect
+ dw FreezeBurnParalyzeEffect ; PARALYZE_SIDE_EFFECT2
+ dw FlichSideEffect ; FLINCH_SIDE_EFFECT2
+ dw OneHitKOEffect ; OHKO_EFFECT
+ dw ChargeEffect ; CHARGE_EFFECT
+ dw $0000 ; SUPER_FANG_EFFECT
+ dw $0000 ; SPECIAL_DAMAGE_EFFECT
+ dw TrappingEffect ; TRAPPING_EFFECT
+ dw ChargeEffect ; FLY_EFFECT
+ dw TwoToFiveAttacksEffect ; ATTACK_TWICE_EFFECT
+ dw $0000 ; JUMP_KICK_EFFECT
+ dw MistEffect ; MIST_EFFECT
+ dw FocusEnergyEffect ; FOCUS_ENERGY_EFFECT
+ dw RecoilEffect ; RECOIL_EFFECT
+ dw ConfusionEffect ; CONFUSION_EFFECT
+ dw StatModifierUpEffect ; ATTACK_UP2_EFFECT
+ dw StatModifierUpEffect ; DEFENSE_UP2_EFFECT
+ dw StatModifierUpEffect ; SPEED_UP2_EFFECT
+ dw StatModifierUpEffect ; SPECIAL_UP2_EFFECT
+ dw StatModifierUpEffect ; ACCURACY_UP2_EFFECT
+ dw StatModifierUpEffect ; EVASION_UP2_EFFECT
+ dw HealEffect ; HEAL_EFFECT
+ dw TransformEffect ; TRANSFORM_EFFECT
+ dw StatModifierDownEffect ; ATTACK_DOWN2_EFFECT
+ dw StatModifierDownEffect ; DEFENSE_DOWN2_EFFECT
+ dw StatModifierDownEffect ; SPEED_DOWN2_EFFECT
+ dw StatModifierDownEffect ; SPECIAL_DOWN2_EFFECT
+ dw StatModifierDownEffect ; ACCURACY_DOWN2_EFFECT
+ dw StatModifierDownEffect ; EVASION_DOWN2_EFFECT
+ dw ReflectLightScreenEffect ; LIGHT_SCREEN_EFFECT
+ dw ReflectLightScreenEffect ; REFLECT_EFFECT
+ dw PoisonEffect ; POISON_EFFECT
+ dw ParalyzeEffect ; PARALYZE_EFFECT
+ dw StatModifierDownEffect ; ATTACK_DOWN_SIDE_EFFECT
+ dw StatModifierDownEffect ; DEFENSE_DOWN_SIDE_EFFECT
+ dw StatModifierDownEffect ; SPEED_DOWN_SIDE_EFFECT
+ dw StatModifierDownEffect ; SPECIAL_DOWN_SIDE_EFFECT
+ dw StatModifierDownEffect ; unused effect
+ dw StatModifierDownEffect ; unused effect
+ dw StatModifierDownEffect ; unused effect
+ dw StatModifierDownEffect ; unused effect
+ dw ConfusionSideEffect ; CONFUSION_SIDE_EFFECT
+ dw TwoToFiveAttacksEffect ; TWINEEDLE_EFFECT
+ dw $0000 ; unused effect
+ dw SubstituteEffect ; SUBSTITUTE_EFFECT
+ dw HyperBeamEffect ; HYPER_BEAM_EFFECT
+ dw RageEffect ; RAGE_EFFECT
+ dw MimicEffect ; MIMIC_EFFECT
+ dw $0000 ; METRONOME_EFFECT
+ dw LeechSeedEffect ; LEECH_SEED_EFFECT
+ dw SplashEffect ; SPLASH_EFFECT
+ dw DisableEffect ; DISABLE_EFFECT
+
+SleepEffect: ; 3f1fc (f:71fc)
+ ld de, W_ENEMYMONSTATUS ; $cfe9
+ ld bc, W_ENEMYBATTSTATUS2 ; $d068
+ ld a, [H_WHOSETURN] ; $fff3
+ and a
+ jp z, .asm_3f20e
+ ld de, W_PLAYERMONSTATUS ; $d018
+ ld bc, W_PLAYERBATTSTATUS2 ; $d063
+
+.asm_3f20e
+ ld a, [bc]
+ bit 5, a ; does the mon need to recharge? (hyper beam)
+ res 5, a ; mon no longer needs to recharge
+ ld [bc], a
+ jr nz, .asm_3f231
+ ld a, [de]
+ ld b, a
+ and $7
+ jr z, .asm_3f222
+ ld hl, AlreadyAsleepText
+ jp PrintText
+.asm_3f222
+ ld a, b
+ and a
+ jr nz, .asm_3f242
+ push de
+ call MoveHitTest
+ pop de
+ ld a, [W_MOVEMISSED] ; $d05f
+ and a
+ jr nz, .asm_3f242
+.asm_3f231
+ call GenRandomInBattle
+ and $7
+ jr z, .asm_3f231
+ ld [de], a
+ call Func_3fb89
+ ld hl, FellAsleepText
+ jp PrintText
+.asm_3f242
+ jp PrintDidntAffectText
+
+FellAsleepText: ; 3f245 (f:7245)
+ TX_FAR _FellAsleepText
+ db "@"
+
+AlreadyAsleepText: ; 3f24a (f:724a)
+ TX_FAR _AlreadyAsleepText
+ db "@"
+
+PoisonEffect: ; 3f24f (f:724f)
+ ld hl, W_ENEMYMONSTATUS ; $cfe9
+ ld de, W_PLAYERMOVEEFFECT ; $cfd3
+ ld a, [H_WHOSETURN] ; $fff3
+ and a
+ jr z, .asm_3f260
+ ld hl, W_PLAYERMONSTATUS ; $d018
+ ld de, W_ENEMYMOVEEFFECT ; $cfcd
+.asm_3f260
+ call CheckTargetSubstitute
+ jr nz, .asm_3f2d3
+ ld a, [hli]
+ ld b, a
+ and a
+ jr nz, .asm_3f2d3
+ ld a, [hli]
+ cp $3
+ jr z, .asm_3f2d3
+ ld a, [hld]
+ cp $3
+ jr z, .asm_3f2d3
+ ld a, [de]
+ cp POISON_SIDE_EFFECT1
+ ld b, $34 ; ~20% chance of poisoning
+ jr z, .asm_3f290
+ cp POISON_SIDE_EFFECT2
+ ld b, $67 ; ~40% chance of poisoning
+ jr z, .asm_3f290
+ push hl
+ push de
+ call MoveHitTest
+ pop de
+ pop hl
+ ld a, [W_MOVEMISSED] ; $d05f
+ and a
+ jr nz, .asm_3f2d7
+ jr .asm_3f295
+.asm_3f290
+ call GenRandomInBattle
+ cp b
+ ret nc
+.asm_3f295
+ dec hl
+ set 3, [hl]
+ push de
+ dec de
+ ld a, [H_WHOSETURN] ; $fff3
+ and a
+ ld b, $c7
+ ld hl, W_PLAYERBATTSTATUS3 ; $d064
+ ld a, [de]
+ ld de, W_PLAYERTOXICCOUNTER ; $d06c
+ jr nz, .asm_3f2b0
+ ld b, $a9
+ ld hl, W_ENEMYBATTSTATUS3 ; $d069
+ ld de, W_ENEMYTOXICCOUNTER ; $d071
+.asm_3f2b0
+ cp $5c
+ jr nz, .asm_3f2bd
+ set 0, [hl]
+ xor a
+ ld [de], a
+ ld hl, BadlyPoisonedText
+ jr .asm_3f2c0
+.asm_3f2bd
+ ld hl, PoisonedText
+.asm_3f2c0
+ pop de
+ ld a, [de]
+ cp POISON_EFFECT
+ jr z, .asm_3f2cd
+ ld a, b
+ call Func_3fb96
+ jp PrintText
+.asm_3f2cd
+ call Func_3fb89
+ jp PrintText
+.asm_3f2d3
+ ld a, [de]
+ cp POISON_EFFECT
+ ret nz
+.asm_3f2d7
+ ld c, $32
+ call DelayFrames
+ jp PrintDidntAffectText
+
+PoisonedText: ; 3f2df (f:72df)
+ TX_FAR _PoisonedText
+ db "@"
+
+BadlyPoisonedText: ; 3f2e4 (f:72e4)
+ TX_FAR _BadlyPoisonedText
+ db "@"
+
+DrainHPEffect: ; 3f2e9 (f:72e9)
+ ld hl, DrainHPEffect_
+ ld b, BANK(DrainHPEffect_)
+ jp Bankswitch
+
+ExplodeEffect: ; 3f2f1 (f:72f1)
+ ld hl, W_PLAYERMONCURHP ; $d015
+ ld de, W_PLAYERBATTSTATUS2 ; $d063
+ ld a, [H_WHOSETURN] ; $fff3
+ and a
+ jr z, .asm_3f302
+ ld hl, W_ENEMYMONCURHP ; $cfe6
+ ld de, W_ENEMYBATTSTATUS2 ; $d068
+.asm_3f302
+ xor a
+ ld [hli], a ; set the mon's HP to 0
+ ld [hli], a
+ inc hl
+ ld [hl], a ; set mon's status to 0
+ ld a, [de]
+ res 7, a ; clear mon's leech seed status
+ ld [de], a
+ ret
+
+FreezeBurnParalyzeEffect: ; 3f30c (f:730c)
+ xor a
+ ld [$cc5b], a
+ call CheckTargetSubstitute ;test bit 4 of d063/d068 flags [target has substitute flag]
+ ret nz ;return if they have a substitute, can't effect them
+ ld a, [$fff3] ;whose turn?
+ and a
+ jp nz, opponentAttacker
+ ld a, [W_ENEMYMONSTATUS]
+ and a
+ jp nz, CheckDefrost
+ ;opponent has no existing status
+ ld a, [W_PLAYERMOVETYPE]
+ ld b, a
+ ld a, [W_ENEMYMONTYPE1]
+ cp b
+ ret z ;return if they match [can't freeze an ice type etc.]
+ ld a, [W_ENEMYMONTYPE2]
+ cp b
+ ret z ;return..
+ ld a, [W_PLAYERMOVEEFFECT]
+ cp a, 7 ;10% status effects are 04, 05, 06 so 07 will set carry for those
+ ld b, $1a ;[1A-1]/100 or [26-1]/256 = 9.8%~ chance
+ jr c, .next1 ;branch ahead if this is a 10% chance effect..
+ ld b, $4d ;..or use [4D-1]/100 or [76-1]/256 = 29.7%~ chance
+ sub a, $1e ;subtract $1E to map to equivalent 10% chance effects
+.next1
+ push af ;push effect...
+ call GenRandomInBattle ;get random 8bit value for probability test
+ cp b ;success?
+ pop bc ;...pop effect into C
+ ret nc ;do nothing if random value is >= 1A or 4D [no status applied]
+ ;the test passed
+ ld a, b ;what type of effect is this?
+ cp a, BURN_SIDE_EFFECT1
+ jr z, .burn
+ cp a, FREEZE_SIDE_EFFECT
+ jr z, .freeze
+ ld a, 1 << PAR
+ ld [W_ENEMYMONSTATUS], a
+ call Func_3ed27 ;quarter speed of affected monster
+ ld a, $a9
+ call Func_3fbb9 ;animation
+ jp PrintMayNotAttackText ;print paralysis text
+.burn
+ ld a, 1 << BRN
+ ld [W_ENEMYMONSTATUS], a
+ call Func_3ed64
+ ld a, $a9
+ call Func_3fbb9 ;animation
+ ld hl, BurnedText
+ jp PrintText
+.freeze
+ call Func_3f9cf ;resets bit 5 of the D063/D068 flags
+ ld a, 1 << FRZ
+ ld [W_ENEMYMONSTATUS], a
+ ld a, $a9
+ call Func_3fbb9 ;animation
+ ld hl, FrozenText
+ jp PrintText
+opponentAttacker: ; 3f382 (f:7382)
+ ld a, [W_PLAYERMONSTATUS] ;this appears to the same as above with addresses swapped for opponent
+ and a
+ jp nz, CheckDefrost
+ ld a, [W_ENEMYMOVETYPE]
+ ld b, a
+ ld a, [W_PLAYERMONTYPE1]
+ cp b
+ ret z
+ ld a, [W_PLAYERMONTYPE2]
+ cp b
+ ret z
+ ld a, [W_ENEMYMOVEEFFECT]
+ cp a, 7
+ ld b, $1a
+ jr c, .next1
+ ld b, $4d
+ sub a, $1e
+.next1
+ push af
+ call GenRandomInBattle
+ cp b
+ pop bc
+ ret nc
+ ld a, b
+ cp a, BURN_SIDE_EFFECT1
+ jr z, .burn
+ cp a, FREEZE_SIDE_EFFECT
+ jr z, .freeze
+ ld a, 1 << PAR
+ ld [W_PLAYERMONSTATUS], a
+ call Func_3ed27
+ jp PrintMayNotAttackText
+.burn
+ ld a, 1 << BRN
+ ld [W_PLAYERMONSTATUS], a
+ call Func_3ed64
+ ld hl, BurnedText
+ jp PrintText
+.freeze
+ ld a, 1 << FRZ
+ ld [W_PLAYERMONSTATUS], a
+ ld hl, FrozenText
+ jp PrintText
+
+BurnedText: ; 3f3d8 (f:73d8)
+ TX_FAR _BurnedText
+ db "@"
+
+FrozenText: ; 3f3dd (f:73dd)
+ TX_FAR _FrozenText
+ db "@"
+
+CheckDefrost: ; 3f3e2 (f:73e2)
+ and a, 1 << FRZ ;are they frozen?
+ ret z ;return if so
+ ;not frozen
+ ld a, [$fff3] ;whose turn?
+ and a
+ jr nz, .opponent
+ ;player [attacker]
+ ld a, [W_PLAYERMOVETYPE]
+ sub a, FIRE
+ ret nz ;return if it isn't fire
+ ;type is fire
+ ld [W_ENEMYMONSTATUS], a ;set opponent status to 00 ["defrost" a frozen monster]
+ ld hl, $d8a8 ;status of first opponent monster in their roster
+ ld a, [W_ENEMYMONNUMBER]
+ ld bc, $002c ;$2C bytes per roster entry
+ call AddNTimes
+ xor a
+ ld [hl], a ;clear status in roster
+ ld hl, FireDefrostedText
+ jr .common
+.opponent
+ ld a, [W_ENEMYMOVETYPE] ;same as above with addresses swapped
+ sub a, FIRE
+ ret nz
+ ld [W_PLAYERMONSTATUS], a
+ ld hl, $d16f
+ ld a, [wPlayerMonNumber]
+ ld bc, $002c
+ call AddNTimes
+ xor a
+ ld [hl], a
+ ld hl, FireDefrostedText
+.common
+ jp PrintText
+
+FireDefrostedText: ; 3f423 (f:7423)
+ TX_FAR _FireDefrostedText
+ db "@"
+
+StatModifierUpEffect: ; 3f428 (f:7428)
+ ld hl, wPlayerMonStatMods ; $cd1a
+ ld de, W_PLAYERMOVEEFFECT ; $cfd3
+ ld a, [H_WHOSETURN] ; $fff3
+ and a
+ jr z, .asm_3f439
+ ld hl, wEnemyMonStatMods ; $cd2e
+ ld de, W_ENEMYMOVEEFFECT ; $cfcd
+.asm_3f439
+ ld a, [de]
+ sub $a
+ cp $8
+ jr c, .asm_3f442
+ sub $28
+.asm_3f442
+ ld c, a
+ ld b, $0
+ add hl, bc
+ ld b, [hl]
+ inc b
+ ld a, $d
+ cp b
+ jp c, Func_3f522
+ ld a, [de]
+ cp $12
+ jr c, .asm_3f45a
+ inc b
+ ld a, $d
+ cp b
+ jr nc, .asm_3f45a
+ ld b, a
+.asm_3f45a
+ ld [hl], b
+ ld a, c
+ cp $4
+ jr nc, asm_3f4ca
+ push hl
+ ld hl, $d026
+ ld de, $cd12
+ ld a, [H_WHOSETURN] ; $fff3
+ and a
+ jr z, .asm_3f472
+ ld hl, $cff7
+ ld de, $cd26
+.asm_3f472
+ push bc
+ sla c
+ ld b, $0
+ add hl, bc
+ ld a, c
+ add e
+ ld e, a
+ jr nc, .asm_3f47e
+ inc d
+.asm_3f47e
+ pop bc
+ ld a, [hld]
+ sub $e7
+ jr nz, .asm_3f48a
+ ld a, [hl]
+ sbc $3
+ jp z, Func_3f520
+.asm_3f48a
+ push hl
+ push bc
+ ld hl, StatModifierRatios ; $76cb
+ dec b
+ sla b
+ ld c, b
+ ld b, $0
+ add hl, bc
+ pop bc
+ xor a
+ ld [H_NUMTOPRINT], a ; $ff96 (aliases: H_MULTIPLICAND)
+ ld a, [de]
+ ld [$ff97], a
+ inc de
+ ld a, [de]
+ ld [$ff98], a
+ ld a, [hli]
+ ld [H_REMAINDER], a ; $ff99 (aliases: H_DIVISOR, H_MULTIPLIER, H_POWEROFTEN)
+ call Multiply
+ ld a, [hl]
+ ld [H_REMAINDER], a ; $ff99 (aliases: H_DIVISOR, H_MULTIPLIER, H_POWEROFTEN)
+ ld b, $4
+ call Divide
+ pop hl
+ ld a, [$ff98]
+ sub $e7
+ ld a, [$ff97]
+ sbc $3
+ jp c, Func_3f4c3
+ ld a, 999 / $100
+ ld [$ff97], a
+ ld a, 999 % $100
+ ld [$ff98], a
+
+Func_3f4c3: ; 3f4c3 (f:74c3)
+ ld a, [$ff97]
+ ld [hli], a
+ ld a, [$ff98]
+ ld [hl], a
+ pop hl
+asm_3f4ca: ; 3f4ca (f:74ca)
+ ld b, c
+ inc b
+ call Func_3f688
+ ld hl, W_PLAYERBATTSTATUS2 ; $d063
+ ld de, W_PLAYERMOVENUM ; $cfd2
+ ld bc, $ccf7
+ ld a, [H_WHOSETURN] ; $fff3
+ and a
+ jr z, .asm_3f4e6
+ ld hl, W_ENEMYBATTSTATUS2 ; $d068
+ ld de, W_ENEMYMOVENUM ; $cfcc
+ ld bc, $ccf3
+.asm_3f4e6
+ ld a, [de]
+ cp MINIMIZE
+ jr nz, .asm_3f4f9
+ bit 4, [hl]
+ push af
+ push bc
+ ld hl, Func_79747
+ ld b, BANK(Func_79747)
+ push de
+ call nz, Bankswitch
+ pop de
+.asm_3f4f9
+ call Func_3fba8
+ ld a, [de]
+ cp MINIMIZE
+ jr nz, .asm_3f50e
+ pop bc
+ ld a, $1
+ ld [bc], a
+ ld hl, Func_79771
+ ld b, BANK(Func_79771)
+ pop af
+ call nz, Bankswitch
+.asm_3f50e
+ ld a, [H_WHOSETURN] ; $fff3
+ and a
+ call z, Func_3ee19
+ ld hl, MonsStatsRoseText
+ call PrintText
+ call Func_3ed27
+ jp Func_3ed64
+
+Func_3f520: ; 3f520 (f:7520)
+ pop hl
+ dec [hl]
+
+Func_3f522: ; 3f522 (f:7522)
+ ld hl, NothingHappenedText
+ jp PrintText
+
+MonsStatsRoseText: ; 3f528 (f:7528)
+ TX_FAR _MonsStatsRoseText
+ db $08 ; asm
+ ld hl, GreatlyRoseText
+ ld a, [H_WHOSETURN] ; $fff3
+ and a
+ ld a, [W_PLAYERMOVEEFFECT] ; $cfd3
+ jr z, .asm_3f53b
+ ld a, [W_ENEMYMOVEEFFECT] ; $cfcd
+.asm_3f53b
+ cp ATTACK_DOWN1_EFFECT
+ ret nc
+ ld hl, RoseText
+ ret
+
+GreatlyRoseText: ; 3f542 (f:7542)
+ db $0a
+ TX_FAR _GreatlyRoseText
+
+RoseText: ; 3f547 (f:7547)
+ TX_FAR _RoseText
+ db "@"
+
+StatModifierDownEffect: ; 3f54c (f:754c)
+ ld hl, wEnemyMonStatMods ; $cd2e
+ ld de, W_PLAYERMOVEEFFECT ; $cfd3
+ ld bc, W_ENEMYBATTSTATUS1 ; $d067
+ ld a, [H_WHOSETURN] ; $fff3
+ and a
+ jr z, .asm_3f572
+ ld hl, wPlayerMonStatMods ; $cd1a
+ ld de, W_ENEMYMOVEEFFECT ; $cfcd
+ ld bc, W_PLAYERBATTSTATUS1 ; $d062
+ ld a, [W_ISLINKBATTLE] ; $d12b
+ cp $4
+ jr z, .asm_3f572
+ call GenRandomInBattle
+ cp $40
+ jp c, Func_3f65a
+.asm_3f572
+ call CheckTargetSubstitute
+ jp nz, Func_3f65a
+ ld a, [de]
+ cp ATTACK_DOWN_SIDE_EFFECT
+ jr c, .asm_3f58a
+ call GenRandomInBattle
+ cp SPLASH_EFFECT
+ jp nc, Func_3f650
+ ld a, [de]
+ sub ATTACK_DOWN_SIDE_EFFECT
+ jr .asm_3f5a9
+.asm_3f58a
+ push hl
+ push de
+ push bc
+ call MoveHitTest
+ pop bc
+ pop de
+ pop hl
+ ld a, [W_MOVEMISSED] ; $d05f
+ and a
+ jp nz, Func_3f65a
+ ld a, [bc]
+ bit 6, a
+ jp nz, Func_3f65a
+ ld a, [de]
+ sub $12
+ cp $8
+ jr c, .asm_3f5a9
+ sub $28
+.asm_3f5a9
+ ld c, a
+ ld b, $0
+ add hl, bc
+ ld b, [hl]
+ dec b
+ jp z, Func_3f650
+ ld a, [de]
+ cp $24
+ jr c, .asm_3f5bf
+ cp $44
+ jr nc, .asm_3f5bf
+ dec b
+ jr nz, .asm_3f5bf
+ inc b
+.asm_3f5bf
+ ld [hl], b
+ ld a, c
+ cp $4
+ jr nc, asm_3f62c
+ push hl
+ push de
+ ld hl, $cff7
+ ld de, $cd26
+ ld a, [H_WHOSETURN] ; $fff3
+ and a
+ jr z, .asm_3f5d8
+ ld hl, $d026
+ ld de, $cd12
+.asm_3f5d8
+ push bc
+ sla c
+ ld b, $0
+ add hl, bc
+ ld a, c
+ add e
+ ld e, a
+ jr nc, .asm_3f5e4
+ inc d
+.asm_3f5e4
+ pop bc
+ ld a, [hld]
+ sub $1
+ jr nz, .asm_3f5ef
+ ld a, [hl]
+ and a
+ jp z, Func_3f64d
+.asm_3f5ef
+ push hl
+ push bc
+ ld hl, StatModifierRatios ; $76cb
+ dec b
+ sla b
+ ld c, b
+ ld b, $0
+ add hl, bc
+ pop bc
+ xor a
+ ld [H_NUMTOPRINT], a ; $ff96 (aliases: H_MULTIPLICAND)
+ ld a, [de]
+ ld [$ff97], a
+ inc de
+ ld a, [de]
+ ld [$ff98], a
+ ld a, [hli]
+ ld [H_REMAINDER], a ; $ff99 (aliases: H_DIVISOR, H_MULTIPLIER, H_POWEROFTEN)
+ call Multiply
+ ld a, [hl]
+ ld [H_REMAINDER], a ; $ff99 (aliases: H_DIVISOR, H_MULTIPLIER, H_POWEROFTEN)
+ ld b, $4
+ call Divide
+ pop hl
+ ld a, [$ff98]
+ ld b, a
+ ld a, [$ff97]
+ or b
+ jp nz, Func_3f624
+ ld [$ff97], a
+ ld a, $1
+ ld [$ff98], a
+
+Func_3f624: ; 3f624 (f:7624)
+ ld a, [$ff97]
+ ld [hli], a
+ ld a, [$ff98]
+ ld [hl], a
+ pop de
+ pop hl
+asm_3f62c: ; 3f62c (f:762c)
+ ld b, c
+ inc b
+ push de
+ call Func_3f688
+ pop de
+ ld a, [de]
+ cp $44
+ jr nc, .asm_3f63b
+ call Func_3fb89
+.asm_3f63b
+ ld a, [H_WHOSETURN] ; $fff3
+ and a
+ call nz, Func_3ee19
+ ld hl, MonsStatsFellText
+ call PrintText
+ call Func_3ed27
+ jp Func_3ed64
+
+Func_3f64d: ; 3f64d (f:764d)
+ pop de
+ pop hl
+ inc [hl]
+
+Func_3f650: ; 3f650 (f:7650)
+ ld a, [de]
+ cp ATTACK_DOWN_SIDE_EFFECT
+ ret nc
+ ld hl, NothingHappenedText
+ jp PrintText
+
+Func_3f65a: ; 3f65a (f:765a)
+ ld a, [de]
+ cp $44
+ ret nc
+ jp Func_3fb4e
+
+MonsStatsFellText: ; 3f661 (f:7661)
+ TX_FAR _MonsStatsFellText
+ db $08 ; asm
+ ld hl, FellText
+ ld a, [H_WHOSETURN] ; $fff3
+ and a
+ ld a, [W_PLAYERMOVEEFFECT] ; $cfd3
+ jr z, .asm_3f674
+ ld a, [W_ENEMYMOVEEFFECT] ; $cfcd
+.asm_3f674
+ cp $1a
+ ret c
+ cp $44
+ ret nc
+ ld hl, GreatlyFellText
+ ret
+
+GreatlyFellText: ; 3f67e (f:767e)
+ db $0a
+ TX_FAR _GreatlyFellText
+
+FellText: ; 3f683 (f:7683)
+ TX_FAR _FellText
+ db "@"
+
+Func_3f688: ; 3f688 (f:7688)
+ ld hl, StatsTextStrings
+ ld c, $50
+.asm_3f68d
+ dec b
+ jr z, .asm_3f696
+.asm_3f690
+ ld a, [hli]
+ cp c
+ jr z, .asm_3f68d
+ jr .asm_3f690
+.asm_3f696
+ ld de, $cf4b
+ ld bc, $a
+ jp CopyData
+
+StatsTextStrings: ; 3f69f (f:769f)
+ db "ATTACK@"
+ db "DEFENSE@"
+ db "SPEED@"
+ db "SPECIAL@"
+ db "ACCURACY@"
+ db "EVADE@"
+
+StatModifierRatios: ; 3f6cb (f:76cb)
+; first byte is numerator, second byte is denominator
+ db 25, 100 ; 0.25
+ db 28, 100 ; 0.28
+ db 33, 100 ; 0.33
+ db 40, 100 ; 0.40
+ db 50, 100 ; 0.50
+ db 66, 100 ; 0.66
+ db 1, 1 ; 1.00
+ db 15, 10 ; 1.50
+ db 2, 1 ; 2.00
+ db 25, 10 ; 2.50
+ db 3, 1 ; 3.00
+ db 35, 10 ; 3.50
+ db 4, 1 ; 4.00
+
+BideEffect: ; 3f6e5 (f:76e5)
+ ld hl, W_PLAYERBATTSTATUS1
+ ld de, W_NUMHITS
+ ld bc, $d06a
+ ld a, [H_WHOSETURN]
+ and a
+ jr z, .asm_3f6fc
+ ld hl, W_ENEMYBATTSTATUS1
+ ld de, $cd05
+ ld bc, $d06f
+.asm_3f6fc
+ set 0, [hl] ; mon is now using bide
+ xor a
+ ld [de], a
+ inc de
+ ld [de], a
+ ld [W_PLAYERMOVEEFFECT], a
+ ld [W_ENEMYMOVEEFFECT], a
+ call GenRandomInBattle
+ and $1
+ inc a
+ inc a
+ ld [bc], a
+ ld a, [H_WHOSETURN]
+ add $ae
+ jp Func_3fb96
+
+ThrashPetalDanceEffect: ; 3f717 (f:7717)
+ ld hl, W_PLAYERBATTSTATUS1 ; $d062
+ ld de, $d06a
+ ld a, [H_WHOSETURN] ; $fff3
+ and a
+ jr z, .asm_3f728
+ ld hl, W_ENEMYBATTSTATUS1 ; $d067
+ ld de, $d06f
+.asm_3f728
+ set 1, [hl] ; mon is now using thrash/petal dance
+ call GenRandomInBattle
+ and $1
+ inc a
+ inc a
+ ld [de], a
+ ld a, [H_WHOSETURN] ; $fff3
+ add $b0
+ jp Func_3fb96
+
+SwitchAndTeleportEffect: ; 3f739 (f:7739)
+ ld a, [H_WHOSETURN] ; $fff3
+ and a
+ jr nz, .asm_3f791
+ ld a, [W_ISINBATTLE] ; $d057
+ dec a
+ jr nz, .asm_3f77e
+ ld a, [W_CURENEMYLVL] ; $d127
+ ld b, a
+ ld a, [W_PLAYERMONLEVEL] ; $d022
+ cp b
+ jr nc, .asm_3f76e
+ add b
+ ld c, a
+ inc c
+.asm_3f751
+ call GenRandomInBattle
+ cp c
+ jr nc, .asm_3f751
+ srl b
+ srl b
+ cp b
+ jr nc, .asm_3f76e
+ ld c, $32
+ call DelayFrames
+ ld a, [W_PLAYERMOVENUM] ; $cfd2
+ cp TELEPORT
+ jp nz, PrintDidntAffectText
+ jp PrintButItFailedText_
+.asm_3f76e
+ call ReadPlayerMonCurHPAndStatus
+ xor a
+ ld [$cc5b], a
+ inc a
+ ld [$d078], a
+ ld a, [W_PLAYERMOVENUM] ; $cfd2
+ jr .asm_3f7e4
+.asm_3f77e
+ ld c, $32
+ call DelayFrames
+ ld hl, IsUnaffectedText
+ ld a, [W_PLAYERMOVENUM] ; $cfd2
+ cp TELEPORT
+ jp nz, PrintText
+ jp PrintButItFailedText_
+.asm_3f791
+ ld a, [W_ISINBATTLE] ; $d057
+ dec a
+ jr nz, .asm_3f7d1
+ ld a, [W_PLAYERMONLEVEL] ; $d022
+ ld b, a
+ ld a, [W_CURENEMYLVL] ; $d127
+ cp b
+ jr nc, .asm_3f7c1
+ add b
+ ld c, a
+ inc c
+.asm_3f7a4
+ call GenRandomInBattle
+ cp c
+ jr nc, .asm_3f7a4
+ srl b
+ srl b
+ cp b
+ jr nc, .asm_3f7c1
+ ld c, $32
+ call DelayFrames
+ ld a, [W_ENEMYMOVENUM] ; $cfcc
+ cp TELEPORT
+ jp nz, PrintDidntAffectText
+ jp PrintButItFailedText_
+.asm_3f7c1
+ call ReadPlayerMonCurHPAndStatus
+ xor a
+ ld [$cc5b], a
+ inc a
+ ld [$d078], a
+ ld a, [W_ENEMYMOVENUM] ; $cfcc
+ jr .asm_3f7e4
+.asm_3f7d1
+ ld c, $32
+ call DelayFrames
+ ld hl, IsUnaffectedText
+ ld a, [W_ENEMYMOVENUM] ; $cfcc
+ cp TELEPORT
+ jp nz, PrintText
+ jp Func_3fb4e
+.asm_3f7e4
+ push af
+ call Func_3fbb9
+ ld c, $14
+ call DelayFrames
+ pop af
+ ld hl, RanFromBattleText ; $7802
+ cp TELEPORT
+ jr z, .asm_3f7ff
+ ld hl, RanAwayScaredText ; $7807
+ cp ROAR
+ jr z, .asm_3f7ff
+ ld hl, WasBlownAwayText ; $780c
+.asm_3f7ff
+ jp PrintText
+
+RanFromBattleText: ; 3f802 (f:7802)
+ TX_FAR _RanFromBattleText
+ db "@"
+
+RanAwayScaredText: ; 3f807 (f:7807)
+ TX_FAR _RanAwayScaredText
+ db "@"
+
+WasBlownAwayText: ; 3f80c (f:780c)
+ TX_FAR _WasBlownAwayText
+ db "@"
+
+TwoToFiveAttacksEffect: ; 3f811 (f:7811)
+ ld hl, W_PLAYERBATTSTATUS1 ; $d062
+ ld de, $d06a
+ ld bc, W_NUMHITS ; $d074
+ ld a, [H_WHOSETURN] ; $fff3
+ and a
+ jr z, .asm_3f828
+ ld hl, W_ENEMYBATTSTATUS1 ; $d067
+ ld de, $d06f
+ ld bc, $cd05
+.asm_3f828
+ bit 2, [hl] ; is mon attacking multiple times?
+ ret nz
+ set 2, [hl] ; mon is now attacking multiple times
+ ld hl, W_PLAYERMOVEEFFECT ; $cfd3
+ ld a, [H_WHOSETURN] ; $fff3
+ and a
+ jr z, .asm_3f838
+ ld hl, W_ENEMYMOVEEFFECT ; $cfcd
+.asm_3f838
+ ld a, [hl]
+ cp TWINEEDLE_EFFECT
+ jr z, .asm_3f856
+ cp ATTACK_TWICE_EFFECT
+ ld a, $2
+ jr z, .asm_3f853
+ call GenRandomInBattle
+ and $3
+ cp $2
+ jr c, .asm_3f851
+ call GenRandomInBattle
+ and $3
+.asm_3f851
+ inc a
+ inc a
+.asm_3f853
+ ld [de], a
+ ld [bc], a
+ ret
+.asm_3f856
+ ld a, $2
+ ld [hl], a
+ jr .asm_3f853
+
+FlichSideEffect: ; 3f85b (f:785b)
+ call CheckTargetSubstitute
+ ret nz
+ ld hl, W_ENEMYBATTSTATUS1 ; $d067
+ ld de, W_PLAYERMOVEEFFECT ; $cfd3
+ ld a, [H_WHOSETURN] ; $fff3
+ and a
+ jr z, .asm_3f870
+ ld hl, W_PLAYERBATTSTATUS1 ; $d062
+ ld de, W_ENEMYMOVEEFFECT ; $cfcd
+.asm_3f870
+ ld a, [de]
+ cp FLINCH_SIDE_EFFECT1
+ ld b, $1a ; ~10% chance of flinch
+ jr z, .asm_3f879
+ ld b, $4d ; ~30% chance of flinch
+.asm_3f879
+ call GenRandomInBattle
+ cp b
+ ret nc
+ set 3, [hl] ; set mon's status to flinching
+ call Func_3f9cf
+ ret
+
+OneHitKOEffect: ; 3f884 (f:7884)
+ ld hl, OneHitKOEffect_
+ ld b, BANK(OneHitKOEffect_)
+ jp Bankswitch
+
+ChargeEffect: ; 3f88c (f:788c)
+ ld hl, W_PLAYERBATTSTATUS1 ; $d062
+ ld de, W_PLAYERMOVEEFFECT ; $cfd3
+ ld a, [H_WHOSETURN] ; $fff3
+ and a
+ ld b, $ae
+ jr z, .asm_3f8a1
+ ld hl, W_ENEMYBATTSTATUS1 ; $d067
+ ld de, W_ENEMYMOVEEFFECT ; $cfcd
+ ld b, $af
+.asm_3f8a1
+ set 4, [hl]
+ ld a, [de]
+ dec de ; de contains enemy or player MOVENUM
+ cp FLY_EFFECT
+ jr nz, .asm_3f8ad
+ set 6, [hl] ; mon is now invulnerable to typical attacks (fly/dig)
+ ld b, $64
+.asm_3f8ad
+ ld a, [de]
+ cp DIG
+ jr nz, .asm_3f8b6
+ set 6, [hl] ; mon is now invulnerable to typical attacks (fly/dig)
+ ld b, $c0
+.asm_3f8b6
+ xor a
+ ld [$cc5b], a
+ ld a, b
+ call Func_3fbb9
+ ld a, [de]
+ ld [wWhichTrade], a ; $cd3d
+ ld hl, ChargeMoveEffectText ; $78c8
+ jp PrintText
+
+ChargeMoveEffectText: ; 3f8c8 (f:78c8)
+ TX_FAR _ChargeMoveEffectText
+ db $08 ; asm
+ ld a, [wWhichTrade] ; $cd3d
+ cp RAZOR_WIND
+ ld hl, MadeWhirlwindText ; $78f9
+ jr z, .asm_3f8f8
+ cp SOLARBEAM
+ ld hl, TookInSunlightText ; $78fe
+ jr z, .asm_3f8f8
+ cp SKULL_BASH
+ ld hl, LoweredItsHeadText ; $7903
+ jr z, .asm_3f8f8
+ cp SKY_ATTACK
+ ld hl, SkyAttackGlowingText ; $7908
+ jr z, .asm_3f8f8
+ cp FLY
+ ld hl, FlewUpHighText ; $790d
+ jr z, .asm_3f8f8
+ cp DIG
+ ld hl, DugAHoleText ; $7912
+.asm_3f8f8
+ ret
+
+MadeWhirlwindText: ; 3f8f9 (f:78f9)
+ TX_FAR _MadeWhirlwindText
+ db "@"
+
+TookInSunlightText: ; 3f8fe (f:78fe)
+ TX_FAR _TookInSunlightText
+ db "@"
+
+LoweredItsHeadText: ; 3f903 (f:7903)
+ TX_FAR _LoweredItsHeadText
+ db "@"
+
+SkyAttackGlowingText: ; 3f908 (f:7908)
+ TX_FAR _SkyAttackGlowingText
+ db "@"
+
+FlewUpHighText: ; 3f90d (f:790d)
+ TX_FAR _FlewUpHighText
+ db "@"
+
+DugAHoleText: ; 3f912 (f:7912)
+ TX_FAR _DugAHoleText
+ db "@"
+
+TrappingEffect: ; 3f917 (f:7917)
+ ld hl, W_PLAYERBATTSTATUS1 ; $d062
+ ld de, $d06a
+ ld a, [H_WHOSETURN] ; $fff3
+ and a
+ jr z, .asm_3f928
+ ld hl, W_ENEMYBATTSTATUS1 ; $d067
+ ld de, $d06f
+.asm_3f928
+ bit 5, [hl]
+ ret nz
+ call Func_3f9cf
+ set 5, [hl]
+ call GenRandomInBattle
+ and $3
+ cp $2
+ jr c, .asm_3f93e
+ call GenRandomInBattle
+ and $3
+.asm_3f93e
+ inc a
+ ld [de], a
+ ret
+
+MistEffect: ; 3f941 (f:7941)
+ ld hl, MistEffect_
+ ld b, BANK(MistEffect_)
+ jp Bankswitch
+
+FocusEnergyEffect: ; 3f949 (f:7949)
+ ld hl, FocusEnergyEffect_
+ ld b, BANK(FocusEnergyEffect_)
+ jp Bankswitch
+
+RecoilEffect: ; 3f951 (f:7951)
+ ld hl, RecoilEffect_
+ ld b, BANK(RecoilEffect_)
+ jp Bankswitch
+
+ConfusionSideEffect: ; 3f959 (f:7959)
+ call GenRandomInBattle
+ cp $19
+ ret nc
+ jr Func_3f96f
+
+ConfusionEffect: ; 3f961 (f:7961)
+ call CheckTargetSubstitute
+ jr nz, Func_3f9a6
+ call MoveHitTest
+ ld a, [W_MOVEMISSED] ; $d05f
+ and a
+ jr nz, Func_3f9a6
+
+Func_3f96f: ; 3f96f (f:796f)
+ ld a, [H_WHOSETURN] ; $fff3
+ and a
+ ld hl, W_ENEMYBATTSTATUS1 ; $d067
+ ld bc, $d070
+ ld a, [W_PLAYERMOVEEFFECT] ; $cfd3
+ jr z, .asm_3f986
+ ld hl, W_PLAYERBATTSTATUS1 ; $d062
+ ld bc, $d06b
+ ld a, [W_ENEMYMOVEEFFECT] ; $cfcd
+.asm_3f986
+ bit 7, [hl] ; is mon confused?
+ jr nz, Func_3f9a6
+ set 7, [hl] ; mon is now confused
+ push af
+ call GenRandomInBattle
+ and $3
+ inc a
+ inc a
+ ld [bc], a
+ pop af
+ cp CONFUSION_SIDE_EFFECT
+ call nz, Func_3fb89
+ ld hl, BecameConfusedText ; $79a1
+ jp PrintText
+
+BecameConfusedText: ; 3f9a1 (f:79a1)
+ TX_FAR _BecameConfusedText
+ db "@"
+
+Func_3f9a6: ; 3f9a6 (f:79a6)
+ cp CONFUSION_SIDE_EFFECT
+ ret z
+ ld c, $32
+ call DelayFrames
+ jp Func_3fb4e
+
+ParalyzeEffect: ; 3f9b1 (f:79b1)
+ ld hl, ParalyzeEffect_
+ ld b, BANK(ParalyzeEffect_)
+ jp Bankswitch
+
+SubstituteEffect: ; 3f9b9 (f:79b9)
+ ld hl, SubstituteEffectHandler
+ ld b, BANK(SubstituteEffectHandler)
+ jp Bankswitch
+
+HyperBeamEffect: ; 3f9c1 (f:79c1)
+ ld hl, W_PLAYERBATTSTATUS2 ; $d063
+ ld a, [H_WHOSETURN] ; $fff3
+ and a
+ jr z, .asm_3f9cc
+ ld hl, W_ENEMYBATTSTATUS2 ; $d068
+.asm_3f9cc
+ set 5, [hl] ; mon now needs to recharge
+ ret
+
+Func_3f9cf: ; 3f9cf (f:79cf)
+ push hl
+ ld hl, W_ENEMYBATTSTATUS2 ; $d068
+ ld a, [H_WHOSETURN] ; $fff3
+ and a
+ jr z, .asm_3f9db
+ ld hl, W_PLAYERBATTSTATUS2 ; $d063
+.asm_3f9db
+ res 5, [hl] ; mon no longer needs to recharge
+ pop hl
+ ret
+
+RageEffect: ; 3f9df (f:79df)
+ ld hl, W_PLAYERBATTSTATUS2
+ ld a, [H_WHOSETURN]
+ and a
+ jr z, .player
+ ld hl, W_ENEMYBATTSTATUS2
+.player
+ set 6, [hl] ; mon is now in "rage" mode
+ ret
+
+MimicEffect: ; 3f9ed (f:79ed)
+ ld c, $32
+ call DelayFrames
+ call MoveHitTest
+ ld a, [W_MOVEMISSED]
+ and a
+ jr nz, .asm_3fa74
+ ld a, [H_WHOSETURN]
+ and a
+ ld hl, W_PLAYERMONMOVES
+ ld a, [W_PLAYERBATTSTATUS1]
+ jr nz, .asm_3fa13
+ ld a, [W_ISLINKBATTLE]
+ cp $4
+ jr nz, .asm_3fa3a
+ ld hl, W_ENEMYMONMOVES
+ ld a, [W_ENEMYBATTSTATUS1]
+.asm_3fa13
+ bit 6, a
+ jr nz, .asm_3fa74
+.asm_3fa17
+ push hl
+ call GenRandomInBattle
+ and $3
+ ld c, a
+ ld b, $0
+ add hl, bc
+ ld a, [hl]
+ pop hl
+ and a
+ jr z, .asm_3fa17
+ ld d, a
+ ld a, [H_WHOSETURN]
+ and a
+ ld hl, W_PLAYERMONMOVES
+ ld a, [wPlayerMoveListIndex]
+ jr z, .asm_3fa5f
+ ld hl, W_ENEMYMONMOVES
+ ld a, [wEnemyMoveListIndex]
+ jr .asm_3fa5f
+.asm_3fa3a
+ ld a, [W_ENEMYBATTSTATUS1]
+ bit 6, a
+ jr nz, .asm_3fa74
+ ld a, [wCurrentMenuItem]
+ push af
+ ld a, $1
+ ld [wMoveMenuType], a
+ call MoveSelectionMenu
+ call LoadScreenTilesFromBuffer1
+ ld hl, W_ENEMYMONMOVES
+ ld a, [wCurrentMenuItem]
+ ld c, a
+ ld b, $0
+ add hl, bc
+ ld d, [hl]
+ pop af
+ ld hl, W_PLAYERMONMOVES
+.asm_3fa5f
+ ld c, a
+ ld b, $0
+ add hl, bc
+ ld a, d
+ ld [hl], a
+ ld [$d11e], a
+ call GetMoveName
+ call Func_3fba8
+ ld hl, MimicLearnedMoveText
+ jp PrintText
+.asm_3fa74
+ jp PrintButItFailedText_
+
+MimicLearnedMoveText: ; 3fa77 (f:7a77)
+ TX_FAR _MimicLearnedMoveText
+ db "@"
+
+LeechSeedEffect: ; 3fa7c (f:7a7c)
+ ld hl, LeechSeedEffect_
+ ld b, BANK(LeechSeedEffect_)
+ jp Bankswitch
+
+SplashEffect: ; 3fa84 (f:7a84)
+ call Func_3fba8
+ jp PrintNoEffectText
+
+DisableEffect: ; 3fa8a (f:7a8a)
+ call MoveHitTest
+ ld a, [W_MOVEMISSED] ; $d05f
+ and a
+ jr nz, .asm_3fb06
+ ld de, W_ENEMYDISABLEDMOVE ; $d072
+ ld hl, W_ENEMYMONMOVES
+ ld a, [H_WHOSETURN] ; $fff3
+ and a
+ jr z, .asm_3faa4
+ ld de, W_PLAYERDISABLEDMOVE ; $d06d
+ ld hl, W_PLAYERMONMOVES
+.asm_3faa4
+ ld a, [de]
+ and a
+ jr nz, .asm_3fb06
+.asm_3faa8
+ push hl
+ call GenRandomInBattle
+ and $3
+ ld c, a
+ ld b, $0
+ add hl, bc
+ ld a, [hl]
+ pop hl
+ and a
+ jr z, .asm_3faa8
+ ld [$d11e], a
+ push hl
+ ld a, [H_WHOSETURN] ; $fff3
+ and a
+ ld hl, W_PLAYERMONPP ; $d02d
+ jr nz, .asm_3facf
+ ld a, [W_ISLINKBATTLE] ; $d12b
+ cp $4
+ pop hl
+ jr nz, .asm_3fae1
+ push hl
+ ld hl, W_ENEMYMONPP ; $cffe
+.asm_3facf
+ push hl
+ ld a, [hli]
+ or [hl]
+ inc hl
+ or [hl]
+ inc hl
+ or [hl]
+ and $3f
+ pop hl
+ jr z, .asm_3fb05
+ add hl, bc
+ ld a, [hl]
+ pop hl
+ and a
+ jr z, .asm_3faa8
+.asm_3fae1
+ call GenRandomInBattle
+ and $7
+ inc a
+ inc c
+ swap c
+ add c
+ ld [de], a
+ call Func_3fb89
+ ld hl, $ccee
+ ld a, [H_WHOSETURN] ; $fff3
+ and a
+ jr nz, .asm_3faf8
+ inc hl
+.asm_3faf8
+ ld a, [$d11e]
+ ld [hl], a
+ call GetMoveName
+ ld hl, MoveWasDisabledText ; $7b09
+ jp PrintText
+.asm_3fb05
+ pop hl
+.asm_3fb06
+ jp PrintButItFailedText_
+
+MoveWasDisabledText: ; 3fb09 (f:7b09)
+ TX_FAR _MoveWasDisabledText
+ db "@"
+
+PayDayEffect: ; 3fb0e (f:7b0e)
+ ld hl, PayDayEffect_
+ ld b, BANK(PayDayEffect_)
+ jp Bankswitch
+
+ConversionEffect: ; 3fb16 (f:7b16)
+ ld hl, ConversionEffect_
+ ld b, BANK(ConversionEffect_)
+ jp Bankswitch
+
+HazeEffect: ; 3fb1e (f:7b1e)
+ ld hl, HazeEffect_
+ ld b, BANK(HazeEffect_)
+ jp Bankswitch
+
+HealEffect: ; 3fb26 (f:7b26)
+ ld hl, HealEffect_
+ ld b, BANK(HealEffect_)
+ jp Bankswitch
+
+TransformEffect: ; 3fb2e (f:7b2e)
+ ld hl, TransformEffect_
+ ld b, BANK(TransformEffect_)
+ jp Bankswitch
+
+ReflectLightScreenEffect: ; 3fb36 (f:7b36)
+ ld hl, ReflectLightScreenEffect_
+ ld b, BANK(ReflectLightScreenEffect_)
+ jp Bankswitch
+
+NothingHappenedText: ; 3fb3e (f:7b3e)
+ TX_FAR _NothingHappenedText
+ db "@"
+
+PrintNoEffectText: ; 3fb43 (f:7b43)
+ ld hl, NoEffectText
+ jp PrintText
+
+NoEffectText: ; 3fb49 (f:7b49)
+ TX_FAR _NoEffectText
+ db "@"
+
+Func_3fb4e: ; 3fb4e (f:7b4e)
+ ld a, [$ccf4]
+ and a
+ ret nz
+
+PrintButItFailedText_: ; 3fb53 (f:7b53)
+ ld hl, ButItFailedText
+ jp PrintText
+
+ButItFailedText: ; 3fb59 (f:7b59)
+ TX_FAR _ButItFailedText
+ db "@"
+
+PrintDidntAffectText: ; 3fb5e (f:7b5e)
+ ld hl, DidntAffectText
+ jp PrintText
+
+DidntAffectText: ; 3fb64 (f:7b64)
+ TX_FAR _DidntAffectText
+ db "@"
+
+IsUnaffectedText: ; 3fb69 (f:7b69)
+ TX_FAR _IsUnaffectedText
+ db "@"
+
+PrintMayNotAttackText: ; 3fb6e (f:7b6e)
+ ld hl, ParalyzedMayNotAttackText ; $7b74
+ jp PrintText
+
+ParalyzedMayNotAttackText: ; 3fb74 (f:7b74)
+ TX_FAR _ParalyzedMayNotAttackText
+ db "@"
+
+CheckTargetSubstitute: ; 3fb79 (f:7b79)
+ push hl
+ ld hl, $d068
+ ld a, [$fff3] ;whose turn?
+ and a
+ jr z, .next1
+ ld hl, $d063
+.next1
+ bit 4, [hl] ;test bit 4 in d063/d068 flags
+ pop hl
+ ret
+
+Func_3fb89: ; 3fb89 (f:7b89)
+ ld a, [H_WHOSETURN] ; $fff3
+ and a
+ ld a, [W_PLAYERMOVENUM] ; $cfd2
+ jr z, .asm_3fb94
+ ld a, [W_ENEMYMOVENUM] ; $cfcc
+.asm_3fb94
+ and a
+ ret z
+
+Func_3fb96: ; 3fb96 (f:7b96)
+ ld [W_ANIMATIONID], a ; $d07c
+ ld a, [H_WHOSETURN] ; $fff3
+ and a
+ ld a, $6
+ jr z, .asm_3fba2
+ ld a, $3
+.asm_3fba2
+ ld [$cc5b], a
+ jp Func_3fbbc
+
+Func_3fba8: ; 3fba8 (f:7ba8)
+ xor a
+ ld [$cc5b], a
+ ld a, [H_WHOSETURN] ; $fff3
+ and a
+ ld a, [W_PLAYERMOVENUM] ; $cfd2
+ jr z, .asm_3fbb7
+ ld a, [W_ENEMYMOVENUM] ; $cfcc
+.asm_3fbb7
+ and a
+ ret z
+
+Func_3fbb9: ; 3fbb9 (f:7bb9)
+ ld [W_ANIMATIONID], a ; $d07c
+
+Func_3fbbc: ; 3fbbc (f:7bbc)
+ push hl
+ push de
+ push bc
+ ld a, $8
+ call Predef ; indirect jump to MoveAnimation (78d5e (1e:4d5e))
+ pop bc
+ pop de
+ pop hl
+ ret
diff --git a/engine/battle/d.asm b/engine/battle/d.asm
new file mode 100755
index 00000000..a6ad21ea
--- /dev/null
+++ b/engine/battle/d.asm
@@ -0,0 +1,25 @@
+Func_372d6: ; 372d6 (d:72d6)
+ call LoadTextBoxTilePatterns
+ FuncCoord 3, 4 ; $c3f3
+ ld hl, Coord
+ ld b, $7
+ ld c, $c
+ call TextBoxBorder
+ FuncCoord 4, 5 ; $c408
+ ld hl, Coord
+ ld de, W_PLAYERNAME ; $d158
+ call PlaceString
+ FuncCoord 4, 10 ; $c46c
+ ld hl, Coord
+ ld de, W_GRASSRATE ; $d887
+ call PlaceString
+ FuncCoord 9, 8 ; $c449
+ ld hl, Coord
+ ld a, $69
+ ld [hli], a
+ ld [hl], $6a
+ xor a
+ ld [$cfcb], a
+ callab SetupPlayerAndEnemyPokeballs
+ ld c, $96
+ jp DelayFrames
diff --git a/engine/battle/e.asm b/engine/battle/e.asm
new file mode 100755
index 00000000..ada3071e
--- /dev/null
+++ b/engine/battle/e.asm
@@ -0,0 +1,1563 @@
+Func_39680: ; 39680 (e:5680)
+ ld a, [H_WHOSETURN] ; $fff3
+ and a
+ ld a, [$d060]
+ ld hl, $d026
+ jr z, .asm_39691
+ ld a, [$d065]
+ ld hl, $cff7
+.asm_39691
+ ld c, $4
+ ld b, a
+.asm_39694
+ srl b
+ call c, Func_3969f
+ inc hl
+ inc hl
+ dec c
+ ret z
+ jr .asm_39694
+
+Func_3969f: ; 3969f (e:569f)
+ ld a, [hl]
+ add a
+ ld [hld], a
+ ld a, [hl]
+ rl a
+ ld [hli], a
+ ret
+
+Func_396a7: ; 396a7 (e:56a7)
+ ld a, [H_WHOSETURN] ; $fff3
+ and a
+ ld a, [$d061]
+ ld hl, W_PLAYERMONATK
+ jr z, .asm_396b8
+ ld a, [$d066]
+ ld hl, W_ENEMYMONATTACK
+.asm_396b8
+ ld c, $4
+ ld b, a
+.asm_396bb
+ srl b
+ call c, Func_396c6
+ inc hl
+ inc hl
+ dec c
+ ret z
+ jr .asm_396bb
+
+Func_396c6: ; 396c6 (e:56c6)
+ ld a, [hl]
+ srl a
+ ld [hli], a
+ rr [hl]
+ or [hl]
+ jr nz, .asm_396d1
+ ld [hl], $1
+.asm_396d1
+ dec hl
+ ret
+
+_ScrollTrainerPicAfterBattle: ; 396d3 (e:56d3)
+; Load the enemy trainer's pic and scrolls it into
+; the screen from the right.
+ xor a
+ ld [W_ENEMYMONID], a
+ ld b, $1
+ call GoPAL_SET
+ callab _LoadTrainerPic
+ FuncCoord 19, 0 ; $c3b3
+ ld hl, Coord
+ ld c, $0
+.asm_396e9
+ inc c
+ ld a, c
+ cp $7
+ ret z
+ ld d, $0
+ push bc
+ push hl
+.asm_396f2
+ call Func_39707
+ inc hl
+ ld a, $7
+ add d
+ ld d, a
+ dec c
+ jr nz, .asm_396f2
+ ld c, $4
+ call DelayFrames
+ pop hl
+ pop bc
+ dec hl
+ jr .asm_396e9
+
+Func_39707: ; 39707 (e:5707)
+ push hl
+ push de
+ push bc
+ ld e, $7
+.asm_3970c
+ ld [hl], d
+ ld bc, $14
+ add hl, bc
+ inc d
+ dec e
+ jr nz, .asm_3970c
+ pop bc
+ pop de
+ pop hl
+ ret
+
+; creates a set of moves that may be used and returns its address in hl
+; unused slots are filled with 0, all used slots may be chosen with equal probability
+AIEnemyTrainerChooseMoves: ; 39719 (e:5719)
+ ld a, $a
+ ld hl, $cee9 ; init temporary move selection array. Only the moves with the lowest numbers are chosen in the end
+ ld [hli], a ; move 1
+ ld [hli], a ; move 2
+ ld [hli], a ; move 3
+ ld [hl], a ; move 4
+ ld a, [W_ENEMYDISABLEDMOVE] ; forbid disabled move (if any)
+ swap a
+ and $f
+ jr z, .noMoveDisabled
+ ld hl, $cee9
+ dec a
+ ld c, a
+ ld b, $0
+ add hl, bc ; advance pointer to forbidden move
+ ld [hl], $50 ; forbid (highly discourage) disabled move
+.noMoveDisabled
+ ld hl, TrainerClassMoveChoiceModifications ; 589B
+ ld a, [W_TRAINERCLASS]
+ ld b, a
+.loopTrainerClasses
+ dec b
+ jr z, .readTrainerClassData
+.loopTrainerClassData
+ ld a, [hli]
+ and a
+ jr nz, .loopTrainerClassData
+ jr .loopTrainerClasses
+.readTrainerClassData
+ ld a, [hl]
+ and a
+ jp z, .useOriginalMoveSet
+ push hl
+.nextMoveChoiceModification
+ pop hl
+ ld a, [hli]
+ and a
+ jr z, .loopFindMinimumEntries
+ push hl
+ ld hl, AIMoveChoiceModificationFunctionPointers ; $57a3
+ dec a
+ add a
+ ld c, a
+ ld b, $0
+ add hl, bc ; skip to pointer
+ ld a, [hli] ; read pointer into hl
+ ld h, [hl]
+ ld l, a
+ ld de, .nextMoveChoiceModification ; set return address
+ push de
+ jp [hl] ; execute modification function
+.loopFindMinimumEntries ; all entries will be decremented sequentially until one of them is zero
+ ld hl, $cee9 ; temp move selection array
+ ld de, W_ENEMYMONMOVES ; enemy moves
+ ld c, $4
+.loopDecrementEntries
+ ld a, [de]
+ inc de
+ and a
+ jr z, .loopFindMinimumEntries
+ dec [hl]
+ jr z, .minimumEntriesFound
+ inc hl
+ dec c
+ jr z, .loopFindMinimumEntries
+ jr .loopDecrementEntries
+.minimumEntriesFound
+ ld a, c
+.loopUndoPartialIteration ; undo last (partial) loop iteration
+ inc [hl]
+ dec hl
+ inc a
+ cp $5
+ jr nz, .loopUndoPartialIteration
+ ld hl, $cee9 ; temp move selection array
+ ld de, W_ENEMYMONMOVES ; enemy moves
+ ld c, $4
+.filterMinimalEntries ; all minimal entries now have value 1. All other slots will be disabled (move set to 0)
+ ld a, [de]
+ and a
+ jr nz, .moveExisting ; 0x3978a $1
+ ld [hl], a
+.moveExisting
+ ld a, [hl]
+ dec a
+ jr z, .slotWithMinimalValue
+ xor a
+ ld [hli], a ; disable move slot
+ jr .next
+.slotWithMinimalValue
+ ld a, [de]
+ ld [hli], a ; enable move slot
+.next
+ inc de
+ dec c
+ jr nz, .filterMinimalEntries
+ ld hl, $cee9 ; use created temporary array as move set
+ ret
+.useOriginalMoveSet
+ ld hl, W_ENEMYMONMOVES ; use original move set
+ ret
+
+AIMoveChoiceModificationFunctionPointers: ; 397a3 (e:57a3)
+ dw AIMoveChoiceModification1
+ dw AIMoveChoiceModification2
+ dw AIMoveChoiceModification3
+ dw AIMoveChoiceModification4 ; unused, does nothing
+
+; discourages moves that cause no damage but only a status ailment if player's mon already has one
+AIMoveChoiceModification1: ; 397ab (e:57ab)
+ ld a, [W_PLAYERMONSTATUS]
+ and a
+ ret z ; return if no status ailment on player's mon
+ ld hl, $cee8 ; temp move selection array (-1 byte offest)
+ ld de, W_ENEMYMONMOVES ; enemy moves
+ ld b, $5
+.nextMove
+ dec b
+ ret z ; processed all 4 moves
+ inc hl
+ ld a, [de]
+ and a
+ ret z ; no more moves in move set
+ inc de
+ call ReadMove
+ ld a, [W_ENEMYMOVEPOWER]
+ and a
+ jr nz, .nextMove
+ ld a, [W_ENEMYMOVEEFFECT]
+ push hl
+ push de
+ push bc
+ ld hl, StatusAilmentMoveEffects
+ ld de, $0001
+ call IsInArray
+ pop bc
+ pop de
+ pop hl
+ jr nc, .nextMove
+ ld a, [hl]
+ add $5 ; discourage move
+ ld [hl], a
+ jr .nextMove
+
+StatusAilmentMoveEffects ; 57e2
+ db $01 ; some sleep effect?
+ db SLEEP_EFFECT
+ db POISON_EFFECT
+ db PARALYZE_EFFECT
+ db $FF
+
+; slightly encourage moves with specific effects
+AIMoveChoiceModification2: ; 397e7 (e:57e7)
+ ld a, [$ccd5]
+ cp $1
+ ret nz
+ ld hl, $cee8 ; temp move selection array (-1 byte offest)
+ ld de, W_ENEMYMONMOVES ; enemy moves
+ ld b, $5
+.nextMove
+ dec b
+ ret z ; processed all 4 moves
+ inc hl
+ ld a, [de]
+ and a
+ ret z ; no more moves in move set
+ inc de
+ call ReadMove
+ ld a, [W_ENEMYMOVEEFFECT]
+ cp ATTACK_UP1_EFFECT
+ jr c, .nextMove
+ cp BIDE_EFFECT
+ jr c, .preferMove
+ cp ATTACK_UP2_EFFECT
+ jr c, .nextMove
+ cp POISON_EFFECT
+ jr c, .preferMove
+ jr .nextMove
+.preferMove
+ dec [hl] ; slighly encourage this move
+ jr .nextMove
+
+; encourages moves that are effective against the player's mon
+AIMoveChoiceModification3: ; 39817 (e:5817)
+ ld hl, $cee8 ; temp move selection array (-1 byte offest)
+ ld de, W_ENEMYMONMOVES ; enemy moves
+ ld b, $5
+.nextMove
+ dec b
+ ret z ; processed all 4 moves
+ inc hl
+ ld a, [de]
+ and a
+ ret z ; no more moves in move set
+ inc de
+ call ReadMove
+ push hl
+ push bc
+ push de
+ callab AIGetTypeEffectiveness
+ pop de
+ pop bc
+ pop hl
+ ld a, [$d11e]
+ cp $10
+ jr z, .nextMove
+ jr c, .notEffectiveMove
+ dec [hl] ; slighly encourage this move
+ jr .nextMove
+.notEffectiveMove ; discourages non-effective moves if better moves are available
+ push hl
+ push de
+ push bc
+ ld a, [W_ENEMYMOVETYPE]
+ ld d, a
+ ld hl, W_ENEMYMONMOVES ; enemy moves
+ ld b, $5
+ ld c, $0
+.loopMoves
+ dec b
+ jr z, .done
+ ld a, [hli]
+ and a
+ jr z, .done
+ call ReadMove
+ ld a, [W_ENEMYMOVEEFFECT]
+ cp SUPER_FANG_EFFECT
+ jr z, .betterMoveFound ; Super Fang is considered to be a better move
+ cp SPECIAL_DAMAGE_EFFECT
+ jr z, .betterMoveFound ; any special damage moves are considered to be better moves
+ cp FLY_EFFECT
+ jr z, .betterMoveFound ; Fly is considered to be a better move
+ ld a, [W_ENEMYMOVETYPE]
+ cp d
+ jr z, .loopMoves
+ ld a, [W_ENEMYMOVEPOWER]
+ and a
+ jr nz, .betterMoveFound ; damaging moves of a different type are considered to be better moves
+ jr .loopMoves
+.betterMoveFound
+ ld c, a
+.done
+ ld a, c
+ pop bc
+ pop de
+ pop hl
+ and a
+ jr z, .nextMove
+ inc [hl] ; slighly discourage this move
+ jr .nextMove
+AIMoveChoiceModification4: ; 39883 (e:5883)
+ ret
+
+ReadMove: ; 39884 (e:5884)
+ push hl
+ push de
+ push bc
+ dec a
+ ld hl,Moves
+ ld bc,6
+ call AddNTimes
+ ld de,$CFCC
+ call CopyData
+ pop bc
+ pop de
+ pop hl
+ ret
+
+; move choice modification methods that are applied for each trainer class
+; 0 is sentinel value
+TrainerClassMoveChoiceModifications: ; 3989b (e:589b)
+ db 0 ; YOUNGSTER
+ db 1,0 ; BUG CATCHER
+ db 1,0 ; LASS
+ db 1,3,0 ; SAILOR
+ db 1,0 ; JR__TRAINER_M
+ db 1,0 ; JR__TRAINER_F
+ db 1,2,3,0; POKEMANIAC
+ db 1,2,0 ; SUPER_NERD
+ db 1,0 ; HIKER
+ db 1,0 ; BIKER
+ db 1,3,0 ; BURGLAR
+ db 1,0 ; ENGINEER
+ db 1,2,0 ; JUGGLER_X
+ db 1,3,0 ; FISHER
+ db 1,3,0 ; SWIMMER
+ db 0 ; CUE_BALL
+ db 1,0 ; GAMBLER
+ db 1,3,0 ; BEAUTY
+ db 1,2,0 ; PSYCHIC_TR
+ db 1,3,0 ; ROCKER
+ db 1,0 ; JUGGLER
+ db 1,0 ; TAMER
+ db 1,0 ; BIRD_KEEPER
+ db 1,0 ; BLACKBELT
+ db 1,0 ; SONY1
+ db 1,3,0 ; PROF_OAK
+ db 1,2,0 ; CHIEF
+ db 1,2,0 ; SCIENTIST
+ db 1,3,0 ; GIOVANNI
+ db 1,0 ; ROCKET
+ db 1,3,0 ; COOLTRAINER_M
+ db 1,3,0 ; COOLTRAINER_F
+ db 1,0 ; BRUNO
+ db 1,0 ; BROCK
+ db 1,3,0 ; MISTY
+ db 1,3,0 ; LT__SURGE
+ db 1,3,0 ; ERIKA
+ db 1,3,0 ; KOGA
+ db 1,3,0 ; BLAINE
+ db 1,3,0 ; SABRINA
+ db 1,2,0 ; GENTLEMAN
+ db 1,3,0 ; SONY2
+ db 1,3,0 ; SONY3
+ db 1,2,3,0; LORELEI
+ db 1,0 ; CHANNELER
+ db 1,0 ; AGATHA
+ db 1,3,0 ; LANCE
+
+TrainerPicAndMoneyPointers: ; 39914 (e:5914)
+; trainer pic pointers and base money.
+; money received after battle = base money × level of highest-level enemy mon
+ dw YoungsterPic
+ db 0,$15,0
+
+ dw BugCatcherPic
+ db 0,$10,0
+
+ dw LassPic
+ db 0,$15,0
+
+ dw SailorPic
+ db 0,$30,0
+
+ dw JrTrainerMPic
+ db 0,$20,0
+
+ dw JrTrainerFPic
+ db 0,$20,0
+
+ dw PokemaniacPic
+ db 0,$50,0
+
+ dw SuperNerdPic
+ db 0,$25,0
+
+ dw HikerPic
+ db 0,$35,0
+
+ dw BikerPic
+ db 0,$20,0
+
+ dw BurglarPic
+ db 0,$90,0
+
+ dw EngineerPic
+ db 0,$50,0
+
+ dw JugglerPic
+ db 0,$35,0
+
+ dw FisherPic
+ db 0,$35,0
+
+ dw SwimmerPic
+ db 0,$05,0
+
+ dw CueBallPic
+ db 0,$25,0
+
+ dw GamblerPic
+ db 0,$70,0
+
+ dw BeautyPic
+ db 0,$70,0
+
+ dw PsychicPic
+ db 0,$10,0
+
+ dw RockerPic
+ db 0,$25,0
+
+ dw JugglerPic
+ db 0,$35,0
+
+ dw TamerPic
+ db 0,$40,0
+
+ dw BirdKeeperPic
+ db 0,$25,0
+
+ dw BlackbeltPic
+ db 0,$25,0
+
+ dw Rival1Pic
+ db 0,$35,0
+
+ dw ProfOakPic
+ db 0,$99,0
+
+ dw ChiefPic
+ db 0,$30,0
+
+ dw ScientistPic
+ db 0,$50,0
+
+ dw GiovanniPic
+ db 0,$99,0
+
+ dw RocketPic
+ db 0,$30,0
+
+ dw CooltrainerMPic
+ db 0,$35,0
+
+ dw CooltrainerFPic
+ db 0,$35,0
+
+ dw BrunoPic
+ db 0,$99,0
+
+ dw BrockPic
+ db 0,$99,0
+
+ dw MistyPic
+ db 0,$99,0
+
+ dw LtSurgePic
+ db 0,$99,0
+
+ dw ErikaPic
+ db 0,$99,0
+
+ dw KogaPic
+ db 0,$99,0
+
+ dw BlainePic
+ db 0,$99,0
+
+ dw SabrinaPic
+ db 0,$99,0
+
+ dw GentlemanPic
+ db 0,$70,0
+
+ dw Rival2Pic
+ db 0,$65,0
+
+ dw Rival3Pic
+ db 0,$99,0
+
+ dw LoreleiPic
+ db 0,$99,0
+
+ dw ChannelerPic
+ db 0,$30,0
+
+ dw AgathaPic
+ db 0,$99,0
+
+ dw LancePic
+ db 0,$99,0
+
+INCLUDE "text/trainer_names.asm"
+
+Func_39b87: ; 39b87 (e:5b87)
+ ld hl, $d0dc
+ ld de, $d0e1
+ ld b, $0
+.asm_39b8f
+ ld a, [hli]
+ and a
+ jr z, .asm_39bc1
+ push hl
+ ld [$d0b5], a
+ ld a, $2c
+ ld [$d0b7], a
+ ld a, MOVE_NAME
+ ld [W_LISTTYPE], a
+ call GetName
+ ld hl, $cd6d
+.asm_39ba7
+ ld a, [hli]
+ cp $50
+ jr z, .asm_39bb0
+ ld [de], a
+ inc de
+ jr .asm_39ba7
+.asm_39bb0
+ ld a, b
+ ld [$cd6c], a
+ inc b
+ ld a, $4e
+ ld [de], a
+ inc de
+ pop hl
+ ld a, b
+ cp $4
+ jr z, .asm_39bd1
+ jr .asm_39b8f
+.asm_39bc1
+ ld a, "-"
+ ld [de], a
+ inc de
+ inc b
+ ld a, b
+ cp $4
+ jr z, .asm_39bd1
+ ld a, $4e
+ ld [de], a
+ inc de
+ jr .asm_39bc1
+.asm_39bd1
+ ld a, "@"
+ ld [de], a
+ ret
+
+Func_39bd5: ; 39bd5 (e:5bd5)
+ ld a, [$d11b]
+ cp $1
+ jr nz, .asm_39be6
+ ld hl, wEnemyPartyCount ; $d89c
+ ld de, W_ENEMYMON1OT ; $d9ac OT names of other player
+ ld a, $6
+ jr .asm_39c18
+.asm_39be6
+ cp $4
+ jr nz, .calcAttackStat4
+ ld hl, W_NUMINPARTY ; $d163
+ ld de, W_PARTYMON1OT ; $d273
+ ld a, $5
+ jr .asm_39c18
+.calcAttackStat4
+ cp $5
+ jr nz, .asm_39c02
+ ld hl, $cf7b
+ ld de, MonsterNames ; $421e
+ ld a, $1
+ jr .asm_39c18
+.asm_39c02
+ cp $2
+ jr nz, .asm_39c10
+ ld hl, wNumBagItems ; $d31d
+ ld de, ItemNames ; $472b
+ ld a, $4
+ jr .asm_39c18
+.asm_39c10
+ ld hl, $cf7b
+ ld de, ItemNames ; $472b
+ ld a, ITEM_NAME
+.asm_39c18
+ ld [W_LISTTYPE], a
+ ld a, l
+ ld [$cf8b], a
+ ld a, h
+ ld [$cf8c], a
+ ld a, e
+ ld [$cf8d], a
+ ld a, d
+ ld [$cf8e], a
+ ld bc, ItemPrices ; $4608
+ ld a, c
+ ld [$cf8f], a
+ ld a, b
+ ld [$cf90], a
+ ret
+
+Func_39c37: ; 39c37 (e:5c37)
+ ld hl, W_PARTYMON1 ; $d164
+ ld a, [$cc49]
+ and a
+ jr z, .asm_39c4b
+ dec a
+ jr z, .asm_39c48
+ ld hl, $da81
+ jr .asm_39c4b
+.asm_39c48
+ ld hl, $d89d
+.asm_39c4b
+ ld d, $0
+ add hl, de
+ ld a, [hl]
+ ld [$cf91], a
+ ret
+
+ReadTrainer: ; 39c53 (e:5c53)
+
+; don't change any moves in a link battle
+ ld a,[W_ISLINKBATTLE]
+ and a
+ ret nz
+
+; set [wEnemyPartyCount] to 0, [$D89D] to FF
+; XXX first is total enemy pokemon?
+; XXX second is species of first pokemon?
+ ld hl,wEnemyPartyCount
+ xor a
+ ld [hli],a
+ dec a
+ ld [hl],a
+
+; get the pointer to trainer data for this class
+ ld a,[W_CUROPPONENT]
+ sub $C9 ; convert value from pokemon to trainer
+ add a,a
+ ld hl,TrainerDataPointers
+ ld c,a
+ ld b,0
+ add hl,bc ; hl points to trainer class
+ ld a,[hli]
+ ld h,[hl]
+ ld l,a
+ ld a,[W_TRAINERNO]
+ ld b,a
+; At this point b contains the trainer number,
+; and hl points to the trainer class.
+; Our next task is to iterate through the trainers,
+; decrementing b each time, until we get to the right one.
+.outer
+ dec b
+ jr z,.IterateTrainer
+.inner
+ ld a,[hli]
+ and a
+ jr nz,.inner
+ jr .outer
+
+; if the first byte of trainer data is FF,
+; - each pokemon has a specific level
+; (as opposed to the whole team being of the same level)
+; - if [W_LONEATTACKNO] != 0, one pokemon on the team has a special move
+; else the first byte is the level of every pokemon on the team
+.IterateTrainer
+ ld a,[hli]
+ cp $FF ; is the trainer special?
+ jr z,.SpecialTrainer ; if so, check for special moves
+ ld [W_CURENEMYLVL],a
+.LoopTrainerData
+ ld a,[hli]
+ and a ; have we reached the end of the trainer data?
+ jr z,.FinishUp
+ ld [$CF91],a ; write species somewhere (XXX why?)
+ ld a,1
+ ld [$CC49],a
+ push hl
+ call AddPokemonToParty
+ pop hl
+ jr .LoopTrainerData
+.SpecialTrainer
+; if this code is being run:
+; - each pokemon has a specific level
+; (as opposed to the whole team being of the same level)
+; - if [W_LONEATTACKNO] != 0, one pokemon on the team has a special move
+ ld a,[hli]
+ and a ; have we reached the end of the trainer data?
+ jr z,.AddLoneMove
+ ld [W_CURENEMYLVL],a
+ ld a,[hli]
+ ld [$CF91],a
+ ld a,1
+ ld [$CC49],a
+ push hl
+ call AddPokemonToParty
+ pop hl
+ jr .SpecialTrainer
+.AddLoneMove
+; does the trainer have a single monster with a different move
+ ld a,[W_LONEATTACKNO] ; Brock is 01, Misty is 02, Erika is 04, etc
+ and a
+ jr z,.AddTeamMove
+ dec a
+ add a,a
+ ld c,a
+ ld b,0
+ ld hl,LoneMoves
+ add hl,bc
+ ld a,[hli]
+ ld d,[hl]
+ ld hl,W_ENEMYMON1MOVE3
+ ld bc,W_ENEMYMON2MOVE3 - W_ENEMYMON1MOVE3
+ call AddNTimes
+ ld [hl],d
+ jr .FinishUp
+.AddTeamMove
+; check if our trainer's team has special moves
+
+; get trainer class number
+ ld a,[W_CUROPPONENT]
+ sub $C8
+ ld b,a
+ ld hl,TeamMoves
+
+; iterate through entries in TeamMoves, checking each for our trainer class
+.IterateTeamMoves
+ ld a,[hli]
+ cp b
+ jr z,.GiveTeamMoves ; is there a match?
+ inc hl ; if not, go to the next entry
+ inc a
+ jr nz,.IterateTeamMoves
+
+ ; no matches found. is this trainer champion rival?
+ ld a,b
+ cp SONY3
+ jr z,.ChampionRival
+ jr .FinishUp ; nope
+.GiveTeamMoves
+ ld a,[hl]
+ ld [$D95E],a
+ jr .FinishUp
+.ChampionRival ; give moves to his team
+
+; pidgeot
+ ld a,SKY_ATTACK
+ ld [W_ENEMYMON1MOVE3],a
+
+; starter
+ ld a,[W_RIVALSTARTER]
+ cp STARTER3
+ ld b,MEGA_DRAIN
+ jr z,.GiveStarterMove
+ cp STARTER1
+ ld b,FIRE_BLAST
+ jr z,.GiveStarterMove
+ ld b,BLIZZARD ; must be squirtle
+.GiveStarterMove
+ ld a,b
+ ld [W_ENEMYMON6MOVE3],a
+.FinishUp ; XXX this needs documenting
+ xor a ; clear D079-D07B
+ ld de,$D079
+ ld [de],a
+ inc de
+ ld [de],a
+ inc de
+ ld [de],a
+ ld a,[W_CURENEMYLVL]
+ ld b,a
+.LastLoop
+ ld hl,$D047
+ ld c,2
+ push bc
+ ld a,$B
+ call Predef
+ pop bc
+ inc de
+ inc de
+ dec b
+ jr nz,.LastLoop
+ ret
+
+INCLUDE "data/trainer_moves.asm"
+
+INCLUDE "data/trainer_parties.asm"
+
+TrainerAI: ; 3a52e (e:652e)
+;XXX called at 34964, 3c342, 3c398
+ and a
+ ld a,[W_ISINBATTLE]
+ dec a
+ ret z ; if not a trainer, we're done here
+ ld a,[W_ISLINKBATTLE]
+ cp 4
+ ret z
+ ld a,[W_TRAINERCLASS] ; what trainer class is this?
+ dec a
+ ld c,a
+ ld b,0
+ ld hl,TrainerAIPointers
+ add hl,bc
+ add hl,bc
+ add hl,bc
+ ld a,[wAICount]
+ and a
+ ret z ; if no AI uses left, we're done here
+ inc hl
+ inc a
+ jr nz,.getpointer
+ dec hl
+ ld a,[hli]
+ ld [wAICount],a
+.getpointer
+ ld a,[hli]
+ ld h,[hl]
+ ld l,a
+ call GenRandom
+ jp [hl]
+
+TrainerAIPointers: ; 3a55c (e:655c)
+; one entry per trainer class
+; first byte, number of times (per Pokémon) it can occur
+; next two bytes, pointer to AI subroutine for trainer class
+ dbw 3,GenericAI
+ dbw 3,GenericAI
+ dbw 3,GenericAI
+ dbw 3,GenericAI
+ dbw 3,GenericAI
+ dbw 3,GenericAI
+ dbw 3,GenericAI
+ dbw 3,GenericAI
+ dbw 3,GenericAI
+ dbw 3,GenericAI
+ dbw 3,GenericAI
+ dbw 3,GenericAI
+ dbw 3,JugglerAI ; juggler_x
+ dbw 3,GenericAI
+ dbw 3,GenericAI
+ dbw 3,GenericAI
+ dbw 3,GenericAI
+ dbw 3,GenericAI
+ dbw 3,GenericAI
+ dbw 3,GenericAI
+ dbw 3,JugglerAI ; juggler
+ dbw 3,GenericAI
+ dbw 3,GenericAI
+ dbw 2,BlackbeltAI ; blackbelt
+ dbw 3,GenericAI
+ dbw 3,GenericAI
+ dbw 1,GenericAI ; chief
+ dbw 3,GenericAI
+ dbw 1,GiovanniAI ; giovanni
+ dbw 3,GenericAI
+ dbw 2,CooltrainerMAI ; cooltrainerm
+ dbw 1,CooltrainerFAI ; cooltrainerf
+ dbw 2,BrunoAI ; bruno
+ dbw 5,BrockAI ; brock
+ dbw 1,MistyAI ; misty
+ dbw 1,LtSurgeAI ; surge
+ dbw 1,ErikaAI ; erika
+ dbw 2,KogaAI ; koga
+ dbw 2,BlaineAI ; blaine
+ dbw 1,SabrinaAI ; sabrina
+ dbw 3,GenericAI
+ dbw 1,Sony2AI ; sony2
+ dbw 1,Sony3AI ; sony3
+ dbw 2,LoreleiAI ; lorelei
+ dbw 3,GenericAI
+ dbw 2,AgathaAI ; agatha
+ dbw 1,LanceAI ; lance
+
+JugglerAI: ; 3a5e9 (e:65e9)
+ cp $40
+ ret nc
+ jp Func_3a72a
+
+BlackbeltAI: ; 3a5ef (e:65ef)
+ cp $20
+ ret nc
+ jp AIUseXAttack
+
+GiovanniAI: ; 3a5f5 (e:65f5)
+ cp $40
+ ret nc
+ jp AIUseGuardSpec
+
+CooltrainerMAI: ; 3a5fb (e:65fb)
+ cp $40
+ ret nc
+ jp AIUseXAttack
+
+CooltrainerFAI: ; 3a601 (e:6601)
+ cp $40
+ ld a,$A
+ call Func_3a7cf
+ jp c,AIUseHyperPotion
+ ld a,5
+ call Func_3a7cf
+ ret nc
+ jp Func_3a72a
+
+BrockAI: ; 3a614 (e:6614)
+; if his active monster has a status condition, use a full heal
+ ld a,[W_ENEMYMONSTATUS]
+ and a
+ ret z
+ jp AIUseFullHeal
+
+MistyAI: ; 3a61c (e:661c)
+ cp $40
+ ret nc
+ jp AIUseXDefend
+
+LtSurgeAI: ; 3a622 (e:6622)
+ cp $40
+ ret nc
+ jp AIUseXSpeed
+
+ErikaAI: ; 3a628 (e:6628)
+ cp $80
+ ret nc
+ ld a,$A
+ call Func_3a7cf
+ ret nc
+ jp AIUseSuperPotion
+
+KogaAI: ; 3a634 (e:6634)
+ cp $40
+ ret nc
+ jp AIUseXAttack
+
+BlaineAI: ; 3a63a (e:663a)
+ cp $40
+ ret nc
+ jp AIUseSuperPotion
+
+SabrinaAI: ; 3a640 (e:6640)
+ cp $40
+ ret nc
+ ld a,$A
+ call Func_3a7cf
+ ret nc
+ jp AIUseHyperPotion
+
+Sony2AI: ; 3a64c (e:664c)
+ cp $20
+ ret nc
+ ld a,5
+ call Func_3a7cf
+ ret nc
+ jp AIUsePotion
+
+Sony3AI: ; 3a658 (e:6658)
+ cp $20
+ ret nc
+ ld a,5
+ call Func_3a7cf
+ ret nc
+ jp AIUseFullRestore
+
+LoreleiAI: ; 3a664 (e:6664)
+ cp $80
+ ret nc
+ ld a,5
+ call Func_3a7cf
+ ret nc
+ jp AIUseSuperPotion
+
+BrunoAI: ; 3a670 (e:6670)
+ cp $40
+ ret nc
+ jp AIUseXDefend
+
+AgathaAI: ; 3a676 (e:6676)
+ cp $14
+ jp c,Func_3a72a
+ cp $80
+ ret nc
+ ld a,4
+ call Func_3a7cf
+ ret nc
+ jp AIUseSuperPotion
+
+LanceAI: ; 3a687 (e:6687)
+ cp $80
+ ret nc
+ ld a,5
+ call Func_3a7cf
+ ret nc
+ jp AIUseHyperPotion
+
+GenericAI: ; 3a693 (e:6693)
+ and a ; clear carry
+ ret
+
+; end of individual trainer AI routines
+
+DecrementAICount: ; 3a695 (e:6695)
+ ld hl,wAICount
+ dec [hl]
+ scf
+ ret
+
+Func_3a69b: ; 3a69b (e:669b)
+ ld a,(SFX_08_3e - SFX_Headers_08) / 3
+ jp PlaySoundWaitForCurrent
+
+AIUseFullRestore: ; 3a6a0 (e:66a0)
+ call AICureStatus
+ ld a,FULL_RESTORE
+ ld [$CF05],a
+ ld de,wHPBarOldHP
+ ld hl,$CFE7
+ ld a,[hld]
+ ld [de],a
+ inc de
+ ld a,[hl]
+ ld [de],a
+ inc de
+ ld hl,$CFF5
+ ld a,[hld]
+ ld [de],a
+ inc de
+ ld [wHPBarMaxHP],a
+ ld [$CFE7],a
+ ld a,[hl]
+ ld [de],a
+ ld [wHPBarMaxHP+1],a
+ ld [W_ENEMYMONCURHP],a
+ jr Func_3a718
+
+AIUsePotion: ; 3a6ca (e:66ca)
+; enemy trainer heals his monster with a potion
+ ld a,POTION
+ ld b,20
+ jr AIRecoverHP
+
+AIUseSuperPotion: ; 3a6d0 (e:66d0)
+; enemy trainer heals his monster with a super potion
+ ld a,SUPER_POTION
+ ld b,50
+ jr AIRecoverHP
+
+AIUseHyperPotion: ; 3a6d6 (e:66d6)
+; enemy trainer heals his monster with a hyper potion
+ ld a,HYPER_POTION
+ ld b,200
+ ; fallthrough
+
+AIRecoverHP: ; 3a6da (e:66da)
+; heal b HP and print "trainer used $(a) on pokemon!"
+ ld [$CF05],a
+ ld hl,$CFE7
+ ld a,[hl]
+ ld [wHPBarOldHP],a
+ add b
+ ld [hld],a
+ ld [wHPBarNewHP],a
+ ld a,[hl]
+ ld [wHPBarOldHP+1],a
+ ld [wHPBarNewHP+1],a
+ jr nc,.next
+ inc a
+ ld [hl],a
+ ld [wHPBarNewHP+1],a
+.next
+ inc hl
+ ld a,[hld]
+ ld b,a
+ ld de,$CFF5
+ ld a,[de]
+ dec de
+ ld [wHPBarMaxHP],a
+ sub b
+ ld a,[hli]
+ ld b,a
+ ld a,[de]
+ ld [wHPBarMaxHP+1],a
+ sbc b
+ jr nc,Func_3a718
+ inc de
+ ld a,[de]
+ dec de
+ ld [hld],a
+ ld [wHPBarNewHP],a
+ ld a,[de]
+ ld [hl],a
+ ld [wHPBarNewHP+1],a
+ ; fallthrough
+
+Func_3a718: ; 3a718 (e:6718)
+ call AIPrintItemUse_
+ FuncCoord 2, 2 ; $c3ca
+ ld hl,Coord
+ xor a
+ ld [$CF94],a
+ ld a,$48
+ call Predef
+ jp DecrementAICount
+
+Func_3a72a: ; 3a72a (e:672a)
+ ld a,[wEnemyPartyCount]
+ ld c,a
+ ld hl,W_ENEMYMON1HP
+
+ ld d,0 ; keep count of unfainted monsters
+
+ ; count how many monsters haven't fainted yet
+.loop
+ ld a,[hli]
+ ld b,a
+ ld a,[hld]
+ or b
+ jr z,.Fainted ; has monster fainted?
+ inc d
+.Fainted
+ push bc
+ ld bc,$2C
+ add hl,bc
+ pop bc
+ dec c
+ jr nz,.loop
+
+ ld a,d ; how many available monsters are there?
+ cp 2 ; don't bother if only 1 or 2
+ jp nc,Func_3a74b
+ and a
+ ret
+
+Func_3a74b: ; 3a74b (e:674b)
+
+; prepare to withdraw the active monster: copy hp, number, and status to roster
+
+ ld a,[W_ENEMYMONNUMBER]
+ ld hl,W_ENEMYMON1HP
+ ld bc,$2C
+ call AddNTimes
+ ld d,h
+ ld e,l
+ ld hl,W_ENEMYMONCURHP
+ ld bc,4
+ call CopyData
+
+ ld hl, AIBattleWithdrawText
+ call PrintText
+
+ ld a,1
+ ld [$D11D],a
+ callab EnemySendOut
+ xor a
+ ld [$D11D],a
+
+ ld a,[W_ISLINKBATTLE]
+ cp 4
+ ret z
+ scf
+ ret
+
+AIBattleWithdrawText: ; 3a781 (e:6781)
+ TX_FAR _AIBattleWithdrawText
+ db "@"
+
+AIUseFullHeal: ; 3a786 (e:6786)
+ call Func_3a69b
+ call AICureStatus
+ ld a,FULL_HEAL
+ jp AIPrintItemUse
+
+AICureStatus: ; 3a791 (e:6791)
+; cures the status of enemy's active pokemon
+ ld a,[W_ENEMYMONNUMBER]
+ ld hl,$D8A8
+ ld bc,$2C
+ call AddNTimes
+ xor a
+ ld [hl],a ; clear status in enemy team roster
+ ld [W_ENEMYMONSTATUS],a ; clear status of active enemy
+ ld hl,$D069
+ res 0,[hl]
+ ret
+
+AIUseXAccuracy: ; 0x3a7a8 unused
+ call Func_3a69b
+ ld hl,$D068
+ set 0,[hl]
+ ld a,X_ACCURACY
+ jp AIPrintItemUse
+
+AIUseGuardSpec: ; 3a7b5 (e:67b5)
+ call Func_3a69b
+ ld hl,$D068
+ set 1,[hl]
+ ld a,GUARD_SPEC_
+ jp AIPrintItemUse
+
+AIUseDireHit: ; 0x3a7c2 unused
+ call Func_3a69b
+ ld hl,$D068
+ set 2,[hl]
+ ld a,DIRE_HIT
+ jp AIPrintItemUse
+
+Func_3a7cf: ; 3a7cf (e:67cf)
+ ld [H_DIVISOR],a
+ ld hl,$CFF4
+ ld a,[hli]
+ ld [H_DIVIDEND],a
+ ld a,[hl]
+ ld [H_DIVIDEND + 1],a
+ ld b,2
+ call Divide
+ ld a,[H_QUOTIENT + 3]
+ ld c,a
+ ld a,[H_QUOTIENT + 2]
+ ld b,a
+ ld hl,$CFE7
+ ld a,[hld]
+ ld e,a
+ ld a,[hl]
+ ld d,a
+ ld a,d
+ sub b
+ ret nz
+ ld a,e
+ sub c
+ ret
+
+AIUseXAttack: ; 3a7f2 (e:67f2)
+ ld b,$A
+ ld a,X_ATTACK
+ jr AIIncreaseStat
+
+AIUseXDefend: ; 3a7f8 (e:67f8)
+ ld b,$B
+ ld a,X_DEFEND
+ jr AIIncreaseStat
+
+AIUseXSpeed: ; 3a7fe (e:67fe)
+ ld b,$C
+ ld a,X_SPEED
+ jr AIIncreaseStat
+
+AIUseXSpecial: ; 3a804 (e:6804)
+ ld b,$D
+ ld a,X_SPECIAL
+ ; fallthrough
+
+AIIncreaseStat: ; 3a808 (e:6808)
+ ld [$CF05],a
+ push bc
+ call AIPrintItemUse_
+ pop bc
+ ld hl,$CFCD
+ ld a,[hld]
+ push af
+ ld a,[hl]
+ push af
+ push hl
+ ld a,$AF
+ ld [hli],a
+ ld [hl],b
+ callab StatModifierUpEffect
+ pop hl
+ pop af
+ ld [hli],a
+ pop af
+ ld [hl],a
+ jp DecrementAICount
+
+AIPrintItemUse: ; 3a82c (e:682c)
+ ld [$CF05],a
+ call AIPrintItemUse_
+ jp DecrementAICount
+
+AIPrintItemUse_: ; 3a835 (e:6835)
+; print "x used [$CF05] on z!"
+ ld a,[$CF05]
+ ld [$D11E],a
+ call GetItemName
+ ld hl, AIBattleUseItemText
+ jp PrintText
+
+AIBattleUseItemText: ; 3a844 (e:6844)
+ TX_FAR _AIBattleUseItemText
+ db "@"
+
+DrawAllPokeballs: ; 3a849 (e:6849)
+ call LoadPartyPokeballGfx
+ call SetupOwnPartyPokeballs
+ ld a, [W_ISINBATTLE] ; $d057
+ dec a
+ ret z ; return if wild pokémon
+ jp SetupEnemyPartyPokeballs
+
+DrawEnemyPokeballs: ; 0x3a857
+ call LoadPartyPokeballGfx
+ jp SetupEnemyPartyPokeballs
+
+LoadPartyPokeballGfx: ; 3a85d (e:685d)
+ ld de, PokeballTileGraphics ; $697e
+ ld hl, $8310
+ ld bc, (BANK(PokeballTileGraphics) << 8) + $04
+ jp CopyVideoData
+
+SetupOwnPartyPokeballs: ; 3a869 (e:6869)
+ call PlacePlayerHUDTiles
+ ld hl, W_PARTYMON1DATA
+ ld de, W_NUMINPARTY ; $d163
+ call SetupPokeballs
+ ld a, $60
+ ld hl, W_BASECOORDX ; $d081
+ ld [hli], a
+ ld [hl], a
+ ld a, $8
+ ld [$cd3e], a
+ ld hl, wOAMBuffer
+ jp Func_3a8e1
+
+SetupEnemyPartyPokeballs: ; 3a887 (e:6887)
+ call PlaceEnemyHUDTiles
+ ld hl, wEnemyMons
+ ld de, wEnemyPartyCount ; $d89c
+ call SetupPokeballs
+ ld hl, W_BASECOORDX ; $d081
+ ld a, $48
+ ld [hli], a
+ ld [hl], $20
+ ld a, $f8
+ ld [$cd3e], a
+ ld hl, $c318
+ jp Func_3a8e1
+
+SetupPokeballs: ; 0x3a8a6
+ ld a, [de]
+ push af
+ ld de, wBuffer
+ ld c, $6 ; max num of partymons
+ ld a, $34 ; empty pokeball
+.emptyloop
+ ld [de], a
+ inc de
+ dec c
+ jr nz, .emptyloop ; 0x3a8b2 $fb
+ pop af
+ ld de, wBuffer
+.monloop
+ push af
+ call PickPokeball
+ inc de
+ pop af
+ dec a
+ jr nz, .monloop
+ ret
+
+PickPokeball: ; 3a8c2 (e:68c2)
+ inc hl
+ ld a, [hli]
+ and a
+ jr nz, .alive
+ ld a, [hl]
+ and a
+ ld b, $33 ; crossed ball (fainted)
+ jr z, .done_fainted
+.alive
+ inc hl
+ inc hl
+ ld a, [hl] ; status
+ and a
+ ld b, $32 ; black ball (status)
+ jr nz, .done
+ dec b ; regular ball
+ jr .done
+.done_fainted
+ inc hl
+ inc hl
+.done
+ ld a, b
+ ld [de], a
+ ld bc, $0028 ; rest of mon struct
+ add hl, bc
+ ret
+
+Func_3a8e1: ; 3a8e1 (e:68e1)
+ ld de, $cee9
+ ld c, $6
+.asm_3a8e6
+ ld a, [W_BASECOORDY] ; $d082
+ ld [hli], a
+ ld a, [W_BASECOORDX] ; $d081
+ ld [hli], a
+ ld a, [de]
+ ld [hli], a
+ xor a
+ ld [hli], a
+ ld a, [W_BASECOORDX] ; $d081
+ ld b, a
+ ld a, [$cd3e]
+ add b
+ ld [W_BASECOORDX], a ; $d081
+ inc de
+ dec c
+ jr nz, .asm_3a8e6
+ ret
+
+PlacePlayerHUDTiles: ; 3a902 (e:6902)
+ ld hl, PlayerBattleHUDGraphicsTiles ; $6916
+ ld de, $cd3f
+ ld bc, $3
+ call CopyData
+ FuncCoord 18, 10 ; $c47a
+ ld hl, Coord
+ ld de, rIE ; $ffff
+ jr PlaceHUDTiles
+
+PlayerBattleHUDGraphicsTiles: ; 3a916 (e:6916)
+; The tile numbers for specific parts of the battle display for the player's pokemon
+ db $73 ; unused ($73 is hardcoded into the routine that uses these bytes)
+ db $77 ; lower-right corner tile of the HUD
+ db $6F ; lower-left triangle tile of the HUD
+
+PlaceEnemyHUDTiles: ; 3a919 (e:6919)
+ ld hl, EnemyBattleHUDGraphicsTiles ; $692d
+ ld de, $cd3f
+ ld bc, $3
+ call CopyData
+ FuncCoord 1, 2 ; $c3c9
+ ld hl, Coord
+ ld de, $1
+ jr PlaceHUDTiles
+
+EnemyBattleHUDGraphicsTiles: ; 3a92d (e:692d)
+; The tile numbers for specific parts of the battle display for the enemy
+ db $73 ; unused ($73 is hardcoded in the routine that uses these bytes)
+ db $74 ; lower-left corner tile of the HUD
+ db $78 ; lower-right triangle tile of the HUD
+
+PlaceHUDTiles: ; 3a930 (e:6930)
+ ld [hl], $73
+ ld bc, $14
+ add hl, bc
+ ld a, [$cd40]
+ ld [hl], a
+ ld a, $8
+.asm_3a93c
+ add hl, de
+ ld [hl], $76
+ dec a
+ jr nz, .asm_3a93c
+ add hl, de
+ ld a, [$cd41]
+ ld [hl], a
+ ret
+
+SetupPlayerAndEnemyPokeballs: ; 3a948 (e:6948)
+ call LoadPartyPokeballGfx
+ ld hl, W_PARTYMON1_NUM ; $d16b (aliases: W_PARTYMON1DATA)
+ ld de, W_NUMINPARTY ; $d163
+ call SetupPokeballs
+ ld hl, W_BASECOORDX ; $d081
+ ld a, $50
+ ld [hli], a
+ ld [hl], $40
+ ld a, $8
+ ld [$cd3e], a
+ ld hl, wOAMBuffer
+ call Func_3a8e1
+ ld hl, wEnemyMons ; $d8a4
+ ld de, wEnemyPartyCount ; $d89c
+ call SetupPokeballs
+ ld hl, W_BASECOORDX ; $d081
+ ld a, $50
+ ld [hli], a
+ ld [hl], $68
+ ld hl, $c318
+ jp Func_3a8e1
+
+; four tiles: pokeball, black pokeball (status ailment), crossed out pokeball (faited) and pokeball slot (no mon)
+PokeballTileGraphics:: ; 3a97e (e:697e)
+ INCBIN "gfx/pokeball.2bpp" \ No newline at end of file
diff --git a/engine/battle/e_2.asm b/engine/battle/e_2.asm
new file mode 100755
index 00000000..e6d6eddc
--- /dev/null
+++ b/engine/battle/e_2.asm
@@ -0,0 +1,305 @@
+HealEffect_: ; 3b9ec (e:79ec)
+ ld a, [H_WHOSETURN] ; $fff3
+ and a
+ ld de, W_PLAYERMONCURHP ; $d015
+ ld hl, W_PLAYERMONMAXHP ; $d023
+ ld a, [W_PLAYERMOVENUM] ; $cfd2
+ jr z, .asm_3ba03
+ ld de, W_ENEMYMONCURHP ; $cfe6
+ ld hl, W_ENEMYMONMAXHP ; $cff4
+ ld a, [W_ENEMYMOVENUM] ; $cfcc
+.asm_3ba03
+ ld b, a
+ ld a, [de]
+ cp [hl]
+ inc de
+ inc hl
+ ld a, [de]
+ sbc [hl]
+ jp z, Func_3ba97
+ ld a, b
+ cp REST
+ jr nz, .asm_3ba37
+ push hl
+ push de
+ push af
+ ld c, $32
+ call DelayFrames
+ ld hl, W_PLAYERMONSTATUS ; $d018
+ ld a, [H_WHOSETURN] ; $fff3
+ and a
+ jr z, .asm_3ba25
+ ld hl, W_ENEMYMONSTATUS ; $cfe9
+.asm_3ba25
+ ld a, [hl]
+ and a
+ ld [hl], 2 ; Number of turns from Rest
+ ld hl, StartedSleepingEffect ; $7aa2
+ jr z, .asm_3ba31
+ ld hl, FellAsleepBecameHealthyText ; $7aa7
+.asm_3ba31
+ call PrintText
+ pop af
+ pop de
+ pop hl
+.asm_3ba37
+ ld a, [hld]
+ ld [wHPBarMaxHP], a
+ ld c, a
+ ld a, [hl]
+ ld [wHPBarMaxHP+1], a
+ ld b, a
+ jr z, .asm_3ba47
+ srl b
+ rr c
+.asm_3ba47
+ ld a, [de]
+ ld [wHPBarOldHP], a
+ add c
+ ld [de], a
+ ld [wHPBarNewHP], a
+ dec de
+ ld a, [de]
+ ld [wHPBarOldHP+1], a
+ adc b
+ ld [de], a
+ ld [wHPBarNewHP+1], a
+ inc hl
+ inc de
+ ld a, [de]
+ dec de
+ sub [hl]
+ dec hl
+ ld a, [de]
+ sbc [hl]
+ jr c, .asm_3ba6f
+ ld a, [hli]
+ ld [de], a
+ ld [wHPBarNewHP+1], a
+ inc de
+ ld a, [hl]
+ ld [de], a
+ ld [wHPBarNewHP], a
+.asm_3ba6f
+ ld hl, Func_3fba8 ; $7ba8
+ call BankswitchEtoF
+ ld a, [H_WHOSETURN] ; $fff3
+ and a
+ FuncCoord 10, 9 ; $c45e
+ ld hl, Coord
+ ld a, $1
+ jr z, .asm_3ba83
+ FuncCoord 2, 2 ; $c3ca
+ ld hl, Coord
+ xor a
+.asm_3ba83
+ ld [wListMenuID], a ; $cf94
+ ld a, $48
+ call Predef ; indirect jump to UpdateHPBar (fa1d (3:7a1d))
+ ld hl, Func_3cd5a ; $4d5a
+ call BankswitchEtoF
+ ld hl, RegainedHealthText ; $7aac
+ jp PrintText
+
+Func_3ba97: ; 3ba97 (e:7a97)
+ ld c, $32
+ call DelayFrames
+ ld hl, PrintButItFailedText_
+ jp BankswitchEtoF
+
+StartedSleepingEffect: ; 3baa2 (e:7aa2)
+ TX_FAR _StartedSleepingEffect
+ db "@"
+
+FellAsleepBecameHealthyText: ; 3baa7 (e:7aa7)
+ TX_FAR _FellAsleepBecameHealthyText
+ db "@"
+
+RegainedHealthText: ; 3baac (e:7aac)
+ TX_FAR _RegainedHealthText
+ db "@"
+
+TransformEffect_: ; 3bab1 (e:7ab1)
+ ld hl, W_PLAYERMONID
+ ld de, $cfe5
+ ld bc, W_ENEMYBATTSTATUS3 ; $d069
+ ld a, [W_ENEMYBATTSTATUS1] ; $d067
+ ld a, [H_WHOSETURN] ; $fff3
+ and a
+ jr nz, .asm_3bad1
+ ld hl, $cfe5
+ ld de, W_PLAYERMONID
+ ld bc, W_PLAYERBATTSTATUS3 ; $d064
+ ld [wPlayerMoveListIndex], a ; $cc2e
+ ld a, [W_PLAYERBATTSTATUS1] ; $d062
+.asm_3bad1
+ bit 6, a ; is mon invulnerable to typical attacks? (fly/dig)
+ jp nz, Func_3bb8c
+ push hl
+ push de
+ push bc
+ ld hl, W_PLAYERBATTSTATUS2 ; $d063
+ ld a, [H_WHOSETURN] ; $fff3
+ and a
+ jr z, .asm_3bae4
+ ld hl, W_ENEMYBATTSTATUS2 ; $d068
+.asm_3bae4
+ bit 4, [hl]
+ push af
+ ld hl, Func_79747
+ ld b, BANK(Func_79747)
+ call nz, Bankswitch
+ ld a, [W_OPTIONS] ; $d355
+ add a
+ ld hl, Func_3fba8 ; $7ba8
+ ld b, BANK(Func_3fba8)
+ jr nc, .asm_3baff
+ ld hl, AnimationTransformMon
+ ld b, BANK(AnimationTransformMon)
+.asm_3baff
+ call Bankswitch
+ ld hl, Func_79771
+ ld b, BANK(Func_79771)
+ pop af
+ call nz, Bankswitch
+ pop bc
+ ld a, [bc]
+ set 3, a
+ ld [bc], a
+ pop de
+ pop hl
+ push hl
+ ld a, [hl]
+ ld [de], a
+ ld bc, $5
+ add hl, bc
+ inc de
+ inc de
+ inc de
+ inc de
+ inc de
+ inc bc
+ inc bc
+ call CopyData
+ ld a, [H_WHOSETURN] ; $fff3
+ and a
+ jr z, .asm_3bb32
+ ld a, [de]
+ ld [$cceb], a
+ inc de
+ ld a, [de]
+ ld [$ccec], a
+ dec de
+.asm_3bb32
+ ld a, [hli]
+ ld [de], a
+ inc de
+ ld a, [hli]
+ ld [de], a
+ inc de
+ inc hl
+ inc hl
+ inc hl
+ inc de
+ inc de
+ inc de
+ ld bc, $8
+ call CopyData
+ ld bc, $ffef
+ add hl, bc
+ ld b, $4
+.asm_3bb4a
+ ld a, [hli]
+ and a
+ jr z, .asm_3bb57
+ ld a, $5
+ ld [de], a
+ inc de
+ dec b
+ jr nz, .asm_3bb4a
+ jr .asm_3bb5d
+.asm_3bb57
+ xor a
+ ld [de], a
+ inc de
+ dec b
+ jr nz, .asm_3bb57
+.asm_3bb5d
+ pop hl
+ ld a, [hl]
+ ld [$d11e], a
+ call GetMonName
+ ld hl, $cd26
+ ld de, $cd12
+ call Func_3bb7d
+ ld hl, wEnemyMonStatMods ; $cd2e
+ ld de, wPlayerMonStatMods ; $cd1a
+ call Func_3bb7d
+ ld hl, TransformedText ; $7b92
+ jp PrintText
+
+Func_3bb7d: ; 3bb7d (e:7b7d)
+ ld a, [H_WHOSETURN] ; $fff3
+ and a
+ jr z, .asm_3bb86
+ push hl
+ ld h, d
+ ld l, e
+ pop de
+.asm_3bb86
+ ld bc, $8
+ jp CopyData
+
+Func_3bb8c: ; 3bb8c (e:7b8c)
+ ld hl, PrintButItFailedText_ ; $7b53
+ jp BankswitchEtoF
+
+TransformedText: ; 3bb92 (e:7b92)
+ TX_FAR _TransformedText
+ db "@"
+
+ReflectLightScreenEffect_: ; 3bb97 (e:7b97)
+ ld hl, W_PLAYERBATTSTATUS3 ; $d064
+ ld de, W_PLAYERMOVEEFFECT ; $cfd3
+ ld a, [H_WHOSETURN] ; $fff3
+ and a
+ jr z, .asm_3bba8
+ ld hl, W_ENEMYBATTSTATUS3 ; $d069
+ ld de, W_ENEMYMOVEEFFECT ; $cfcd
+.asm_3bba8
+ ld a, [de]
+ cp LIGHT_SCREEN_EFFECT
+ jr nz, .reflect
+ bit 1, [hl] ; is mon already protected by light screen?
+ jr nz, .moveFailed
+ set 1, [hl] ; mon is now protected by light screen
+ ld hl, LightScreenProtectedText ; $7bd7
+ jr .asm_3bbc1
+.reflect
+ bit 2, [hl] ; is mon already protected by reflect?
+ jr nz, .moveFailed
+ set 2, [hl] ; mon is now protected by reflect
+ ld hl, ReflectGainedArmorText ; $7bdc
+.asm_3bbc1
+ push hl
+ ld hl, Func_3fba8 ; $7ba8
+ call BankswitchEtoF
+ pop hl
+ jp PrintText
+.moveFailed
+ ld c, $32
+ call DelayFrames
+ ld hl, PrintButItFailedText_ ; $7b53
+ jp BankswitchEtoF
+
+LightScreenProtectedText: ; 3bbd7 (e:7bd7)
+ TX_FAR _LightScreenProtectedText
+ db "@"
+
+ReflectGainedArmorText: ; 3bbdc (e:7bdc)
+ TX_FAR _ReflectGainedArmorText
+ db "@"
+
+BankswitchEtoF: ; 3bbe1 (e:7be1)
+ ld b, BANK(BattleCore)
+ jp Bankswitch
diff --git a/engine/battle/safari_zone.asm b/engine/battle/safari_zone.asm
new file mode 100755
index 00000000..426e391e
--- /dev/null
+++ b/engine/battle/safari_zone.asm
@@ -0,0 +1,36 @@
+PrintSafariZoneBattleText: ; 4277 (1:4277)
+ ld hl, $cce9
+ ld a, [hl]
+ and a
+ jr z, .asm_4284
+ dec [hl]
+ ld hl, SafariZoneEatingText
+ jr .asm_429f
+.asm_4284
+ dec hl
+ ld a, [hl]
+ and a
+ ret z
+ dec [hl]
+ ld hl, SafariZoneAngryText
+ jr nz, .asm_429f
+ push hl
+ ld a, [$cfe5]
+ ld [$d0b5], a
+ call GetMonHeader
+ ld a, [W_MONHCATCHRATE]
+ ld [$d007], a
+ pop hl
+.asm_429f
+ push hl
+ call LoadScreenTilesFromBuffer1
+ pop hl
+ jp PrintText
+
+SafariZoneEatingText: ; 42a7 (1:42a7)
+ TX_FAR _SafariZoneEatingText
+ db "@"
+
+SafariZoneAngryText: ; 42ac (1:42ac)
+ TX_FAR _SafariZoneAngryText
+ db "@"