summaryrefslogtreecommitdiff
path: root/engine/battle/core.asm
diff options
context:
space:
mode:
Diffstat (limited to 'engine/battle/core.asm')
-rwxr-xr-xengine/battle/core.asm8547
1 files changed, 8547 insertions, 0 deletions
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