summaryrefslogtreecommitdiff
path: root/engine
diff options
context:
space:
mode:
Diffstat (limited to 'engine')
-rwxr-xr-xengine/HoF_room_pc.asm2
-rwxr-xr-xengine/battle/1.asm4
-rwxr-xr-xengine/battle/14.asm14
-rwxr-xr-xengine/battle/15.asm233
-rwxr-xr-xengine/battle/16.asm40
-rwxr-xr-xengine/battle/1c.asm4
-rwxr-xr-xengine/battle/4_2.asm65
-rwxr-xr-xengine/battle/5.asm4
-rwxr-xr-xengine/battle/animations.asm44
-rwxr-xr-xengine/battle/b_2.asm8
-rwxr-xr-xengine/battle/c.asm4
-rwxr-xr-xengine/battle/core.asm3761
-rwxr-xr-xengine/battle/core.asm.orig8639
-rwxr-xr-xengine/battle/d.asm12
-rwxr-xr-xengine/battle/e.asm4
-rwxr-xr-xengine/battle/e_2.asm6
-rwxr-xr-xengine/battle/safari_zone.asm4
-rwxr-xr-xengine/cable_club.asm8
-rwxr-xr-xengine/evolution.asm2
-rwxr-xr-xengine/evolve_trade.asm4
-rwxr-xr-xengine/evos_moves.asm230
-rwxr-xr-xengine/experience.asm22
-rwxr-xr-xengine/give_pokemon.asm4
-rwxr-xr-xengine/hall_of_fame.asm14
-rwxr-xr-xengine/hidden_object_functions14.asm2
-rwxr-xr-xengine/hidden_object_functions17.asm6
-rwxr-xr-xengine/hidden_object_functions18.asm4
-rwxr-xr-xengine/hidden_object_functions3.asm31
-rwxr-xr-xengine/hidden_object_functions7.asm16
-rwxr-xr-xengine/in_game_trades.asm6
-rwxr-xr-xengine/intro.asm2
-rwxr-xr-xengine/items/items.asm96
-rw-r--r--engine/menu/bills_pc.asm2
-rwxr-xr-xengine/menu/diploma.asm4
-rwxr-xr-xengine/menu/league_pc.asm12
-rwxr-xr-xengine/menu/main_menu.asm27
-rwxr-xr-xengine/menu/naming_screen.asm16
-rwxr-xr-xengine/menu/party_menu.asm2
-rwxr-xr-xengine/menu/pc.asm2
-rwxr-xr-xengine/menu/players_pc.asm2
-rwxr-xr-xengine/menu/pokedex.asm10
-rwxr-xr-xengine/menu/pokedex.asm.orig647
-rwxr-xr-xengine/menu/start_menu.asm4
-rwxr-xr-xengine/menu/start_sub_menus.asm62
-rwxr-xr-xengine/menu/status_screen.asm12
-rwxr-xr-xengine/mon_party_sprites.asm2
-rwxr-xr-xengine/oak_speech.asm20
-rwxr-xr-xengine/overworld/cable_club_npc.asm6
-rwxr-xr-xengine/overworld/card_key.asm70
-rwxr-xr-xengine/overworld/cut.asm58
-rwxr-xr-xengine/overworld/cut2.asm14
-rwxr-xr-xengine/overworld/doors.asm15
-rwxr-xr-xengine/overworld/elevator.asm4
-rwxr-xr-xengine/overworld/emotion_bubbles.asm6
-rwxr-xr-xengine/overworld/healing_machine.asm2
-rwxr-xr-xengine/overworld/hidden_items.asm4
-rwxr-xr-xengine/overworld/hidden_objects.asm114
-rw-r--r--engine/overworld/item.asm2
-rwxr-xr-xengine/overworld/ledges.asm58
-rw-r--r--engine/overworld/movement.asm39
-rwxr-xr-xengine/overworld/npc_movement.asm169
-rw-r--r--engine/overworld/oam.asm4
-rwxr-xr-xengine/overworld/pewter_guys.asm12
-rwxr-xr-xengine/overworld/player_animations.asm348
-rwxr-xr-xengine/overworld/pokemart.asm8
-rwxr-xr-xengine/overworld/ssanne.asm54
-rwxr-xr-xengine/overworld/trainers.asm70
-rwxr-xr-xengine/palettes.asm4
-rwxr-xr-xengine/play_time.asm26
-rwxr-xr-xengine/predefs.asm36
-rwxr-xr-xengine/predefs12.asm13
-rwxr-xr-xengine/predefs7.asm2
-rwxr-xr-xengine/save.asm192
-rwxr-xr-xengine/slot_machine.asm10
-rwxr-xr-xengine/titlescreen.asm18
-rwxr-xr-xengine/town_map.asm49
-rwxr-xr-xengine/town_map.asm.orig605
-rwxr-xr-xengine/trade.asm12
-rwxr-xr-xengine/turn_sprite.asm18
79 files changed, 13136 insertions, 3025 deletions
diff --git a/engine/HoF_room_pc.asm b/engine/HoF_room_pc.asm
index 16a3c3f9..4eec7377 100755
--- a/engine/HoF_room_pc.asm
+++ b/engine/HoF_room_pc.asm
@@ -92,7 +92,7 @@ DisplayCreditsMon: ; 740cb (1d:40cb)
dec c
jr nz,.next2
xor a
- ld [$FFB0],a
+ ld [hVBlankWY],a
ld a,$C0
ld [$FF47],a
ret
diff --git a/engine/battle/1.asm b/engine/battle/1.asm
index 04546313..fdf2841d 100755
--- a/engine/battle/1.asm
+++ b/engine/battle/1.asm
@@ -75,8 +75,8 @@ Func_7861: ; 7861 (1:7861)
.asm_78aa
ld [wListMenuID], a ; wListMenuID
predef UpdateHPBar2
- predef Func_3cd60
- predef Func_3cdec
+ predef DrawPlayerHUDAndHPBar
+ predef DrawEnemyHUDAndHPBar
callab ReadPlayerMonCurHPAndStatus
ld hl, SuckedHealthText ; $78dc
ld a, [H_WHOSETURN] ; $fff3
diff --git a/engine/battle/14.asm b/engine/battle/14.asm
index 01d115a6..18aaa5e1 100755
--- a/engine/battle/14.asm
+++ b/engine/battle/14.asm
@@ -1,21 +1,21 @@
Func_525af: ; 525af (14:65af)
- ld a, [$ffd7]
+ ld a, [hTilesetType]
ld [wd0d4], a
xor a
ld [wcd6a], a
- ld [wcf0b], a
+ ld [wBattleResult], a
ld hl, wcc2b
ld [hli], a
ld [hli], a
ld [hli], a
ld [hl], a
ld [wListScrollOffset], a ; wcc36
- ld [wd05e], a
+ ld [wCriticalHitOrOHKO], a
ld [wBattleMonSpecies], a
- ld [wPartyAliveFlags], a
+ ld [wPartyGainExpFlags], a
ld [wPlayerMonNumber], a ; wPlayerMonNumber
- ld [wd078], a
- ld [wd35d], a
+ ld [wEscapedFromBattle], a
+ ld [wMapPalOffset], a
ld hl, wcf1d
ld [hli], a
ld [hl], a
@@ -73,7 +73,7 @@ ParalyzeEffect_: ; 52601 (14:6601)
and a
jr nz, .asm_52659
set 6, [hl]
- callab Func_3ed27
+ callab QuarterSpeedDueToParalysis
ld c, $1e
call DelayFrames
callab Func_3fba8
diff --git a/engine/battle/15.asm b/engine/battle/15.asm
index 69d8ff3f..2fb3b108 100755
--- a/engine/battle/15.asm
+++ b/engine/battle/15.asm
@@ -1,63 +1,63 @@
GainExperience: ; 5524f (15:524f)
ld a, [W_ISLINKBATTLE]
cp $4
- ret z
- call Func_5546c
- ld hl, wPartyMons
+ ret z ; return if link battle
+ call DivideExpDataByNumMonsGainingExp
+ ld hl, wPartyMon1
xor a
ld [wWhichPokemon], a
-
-Func_5525f: ; 5525f (15:525f)
+.partyMonLoop ; loop over each mon and add gained exp
inc hl
ld a, [hli]
- or [hl]
- jp z, Func_55436
+ or [hl] ; is mon's HP 0?
+ jp z, .nextMon ; if so, go to next mon
push hl
- ld hl, wPartyAliveFlags
+ ld hl, wPartyGainExpFlags
ld a, [wWhichPokemon]
ld c, a
ld b, $2
predef FlagActionPredef
ld a, c
- and a
+ and a ; is mon's gain exp flag set?
pop hl
- jp z, Func_55436
- ld de, $10
+ jp z, .nextMon ; if mon's gain exp flag not set, go to next mon
+ ld de, (wPartyMon1HPExp + 1) - (wPartyMon1HP + 1)
add hl, de
ld d, h
ld e, l
- ld hl, wd002
+ ld hl, wEnemyMonBaseStats
ld c, $5
-.asm_55285
+.gainStatExpLoop
ld a, [hli]
- ld b, a
- ld a, [de]
- add b
+ ld b, a ; enemy mon base stat
+ ld a, [de] ; stat exp
+ add b ; add enemy mon base state to stat exp
ld [de], a
- jr nc, .asm_5529a
+ jr nc, .nextBaseStat
+; if there was a carry, increment the upper byte
dec de
ld a, [de]
inc a
- jr z, .asm_55295
+ jr z, .maxStatExp ; jump if the value overflowed
ld [de], a
inc de
- jr .asm_5529a
-.asm_55295
+ jr .nextBaseStat
+.maxStatExp ; if the upper byte also overflowed, then we have hit the max stat exp
ld a, $ff
ld [de], a
inc de
ld [de], a
-.asm_5529a
+.nextBaseStat
dec c
jr z, .asm_552a1
inc de
inc de
- jr .asm_55285
+ jr .gainStatExpLoop
.asm_552a1
xor a
ld [H_MULTIPLICAND], a
ld [H_MULTIPLICAND + 1], a
- ld a, [wd008]
+ ld a, [wEnemyMonBaseExp]
ld [H_MULTIPLICAND + 2], a
ld a, [wEnemyMonLevel]
ld [H_MULTIPLIER], a
@@ -66,44 +66,46 @@ Func_5525f: ; 5525f (15:525f)
ld [H_DIVISOR], a
ld b, 4
call Divide
- ld hl, $fff2
+ ld hl, -((wPartyMon1HPExp + 1) - wPartyMon1OTID + 4 * 2)
add hl, de
- ld b, [hl]
+ ld b, [hl] ; party mon OTID
inc hl
ld a, [wPlayerID]
cp b
- jr nz, .asm_552d1
+ jr nz, .tradedMon
ld b, [hl]
ld a, [wPlayerID + 1]
cp b
ld a, $0
- jr z, .asm_552d6
-.asm_552d1
- call Func_5549f
+ jr z, .next
+.tradedMon
+ call BoostExp ; traded mon exp boost
ld a, $1
-.asm_552d6
+.next
ld [wcf4d], a
ld a, [W_ISINBATTLE]
- dec a
- call nz, Func_5549f
+ dec a ; is it a trainer battle?
+ call nz, BoostExp ; if so, boost exp
inc hl
inc hl
inc hl
+; add the gained exp to the party mon's exp
ld b, [hl]
- ld a, [$ff98]
+ ld a, [H_QUOTIENT + 3]
ld [wcf4c], a
add b
ld [hld], a
ld b, [hl]
- ld a, [$ff97]
+ ld a, [H_QUOTIENT + 2]
ld [wcf4b], a
adc b
ld [hl], a
- jr nc, .asm_552f8
+ jr nc, .noCarry
dec hl
inc [hl]
inc hl
-.asm_552f8
+.noCarry
+; calculate exp for the mon at max level, and cap the exp at that value
inc hl
push hl
ld a, [wWhichPokemon]
@@ -111,11 +113,12 @@ Func_5525f: ; 5525f (15:525f)
ld b, 0
ld hl, wPartySpecies
add hl, bc
- ld a, [hl]
+ ld a, [hl] ; species
ld [wd0b5], a
call GetMonHeader
ld d, MAX_LEVEL
- callab CalcExperience
+ callab CalcExperience ; get max exp
+; compare max exp with current exp
ld a, [$ff96]
ld b, a
ld a, [$ff97]
@@ -129,7 +132,8 @@ Func_5525f: ; 5525f (15:525f)
sbc c
ld a, [hl]
sbc b
- jr c, .asm_5532e
+ jr c, .next2
+; the mon's exp is greater than the max exp, so overwrite it with the max exp
ld a, b
ld [hli], a
ld a, c
@@ -137,103 +141,108 @@ Func_5525f: ; 5525f (15:525f)
ld a, d
ld [hld], a
dec hl
-.asm_5532e
+.next2
push hl
ld a, [wWhichPokemon]
ld hl, wPartyMonNicks
call GetPartyMonName
ld hl, GainedText
call PrintText
- xor a
+ xor a ; party mon data
ld [wcc49], a
call LoadMonData
pop hl
- ld bc, $13
+ ld bc, wPartyMon1Level - wPartyMon1Exp
add hl, bc
push hl
- callba Func_58f43
+ callba CalcLevelFromExperience
pop hl
- ld a, [hl]
+ ld a, [hl] ; current level
cp d
- jp z, Func_55436
+ jp z, .nextMon ; if level didn't change, go to next mon
ld a, [W_CURENEMYLVL]
push af
push hl
ld a, d
ld [W_CURENEMYLVL], a
ld [hl], a
- ld bc, $ffdf
+ ld bc, wPartyMon1Species - wPartyMon1Level
add hl, bc
- ld a, [hl]
+ ld a, [hl] ; species
ld [wd0b5], a
ld [wd11e], a
call GetMonHeader
- ld bc, $23
+ ld bc, (wPartyMon1MaxHP + 1) - wPartyMon1Species
add hl, bc
push hl
ld a, [hld]
ld c, a
ld b, [hl]
- push bc
+ push bc ; push max HP (from before levelling up)
ld d, h
ld e, l
- ld bc, $ffee
+ ld bc, (wPartyMon1HPExp - 1) - wPartyMon1MaxHP
add hl, bc
- ld b, $1
+ ld b, $1 ; consider stat exp when calculating stats
call CalcStats
- pop bc
+ pop bc ; pop max HP (from before levelling up)
pop hl
ld a, [hld]
sub c
ld c, a
ld a, [hl]
sbc b
- ld b, a
- ld de, $ffe0
+ ld b, a ; bc = difference between old max HP and new max HP after levelling
+ ld de, (wPartyMon1HP + 1) - wPartyMon1MaxHP
add hl, de
- ld a, [hl]
+; add to the current HP the amount of max HP gained when levelling
+ ld a, [hl] ; wPartyMon1HP + 1
add c
ld [hld], a
- ld a, [hl]
+ ld a, [hl] ; wPartyMon1HP + 1
adc b
- ld [hl], a
+ ld [hl], a ; wPartyMon1HP
ld a, [wPlayerMonNumber]
ld b, a
ld a, [wWhichPokemon]
- cp b
- jr nz, .asm_553f7
+ cp b ; is the current mon in battle?
+ jr nz, .printGrewLevelText
+; current mon is in battle
ld de, wBattleMonHP
+; copy party mon HP to battle mon HP
ld a, [hli]
ld [de], a
inc de
ld a, [hl]
ld [de], a
- ld bc, $1f
+; copy other stats from party mon to battle mon
+ ld bc, wPartyMon1Level - (wPartyMon1HP + 1)
add hl, bc
push hl
- ld de, wBattleMonLevel ; wBattleMonLevel
- ld bc, $b
+ ld de, wBattleMonLevel
+ ld bc, $b ; size of stats
call CopyData
pop hl
- ld a, [W_PLAYERBATTSTATUS3] ; W_PLAYERBATTSTATUS3
- bit 3, a
- jr nz, .asm_553c8
+ ld a, [W_PLAYERBATTSTATUS3]
+ bit 3, a ; is the mon transformed?
+ jr nz, .recalcStatChanges
+; the mon is transformed, so copy transformed data
ld de, wcd0f
ld bc, $b
call CopyData
-.asm_553c8
+.recalcStatChanges
xor a
ld [wd11e], a
- callab Func_3ed99
- callab Func_3ed1a
- callab Func_3ee19
- callab Func_3cd60
- callab Func_3ee94
+ callab CalculateModifiedStats
+ callab ApplyBurnAndParalysisPenaltiesToPlayer
+ callab ApplyBadgeStatBoosts
+ callab DrawPlayerHUDAndHPBar
+ callab PrintEmptyString
call SaveScreenTilesToBuffer1
-.asm_553f7
+.printGrewLevelText
ld hl, GrewLevelText
call PrintText
- xor a
+ xor a ; party mon data
ld [wcc49], a
call LoadMonData
ld d, $1
@@ -244,88 +253,90 @@ Func_5525f: ; 5525f (15:525f)
ld [wcc49], a
ld a, [wd0b5]
ld [wd11e], a
- predef Func_3af5b
+ predef LearnMoveFromLevelUp
ld hl, wccd3
- ld a, [wWhichPokemon] ; wWhichPokemon
+ ld a, [wWhichPokemon]
ld c, a
ld b, $1
predef FlagActionPredef
pop hl
pop af
- ld [W_CURENEMYLVL], a ; W_CURENEMYLVL
+ ld [W_CURENEMYLVL], a
-Func_55436: ; 55436 (15:5436)
- ld a, [wPartyCount] ; wPartyCount
+.nextMon
+ ld a, [wPartyCount]
ld b, a
- ld a, [wWhichPokemon] ; wWhichPokemon
+ ld a, [wWhichPokemon]
inc a
cp b
- jr z, .asm_55450
- ld [wWhichPokemon], a ; wWhichPokemon
- ld bc, $2c
- ld hl, wPartyMon1Species ; wPartyMon1Species (aliases: wPartyMon1)
+ jr z, .done
+ ld [wWhichPokemon], a
+ ld bc, wPartyMon2 - wPartyMon1
+ ld hl, wPartyMon1
call AddNTimes
- jp Func_5525f
-.asm_55450
- ld hl, wPartyAliveFlags
+ jp .partyMonLoop
+.done
+ ld hl, wPartyGainExpFlags
xor a
- ld [hl], a
- ld a, [wPlayerMonNumber] ; wPlayerMonNumber
+ ld [hl], a ; clear gain exp flags
+ ld a, [wPlayerMonNumber]
ld c, a
ld b, $1
push bc
- predef FlagActionPredef
- ld hl, wccf5
+ predef FlagActionPredef ; set the gain exp flag for the mon that is currently out
+ ld hl, wPartyFoughtCurrentEnemyFlags
xor a
ld [hl], a
pop bc
- predef_jump FlagActionPredef
+ predef_jump FlagActionPredef ; set the fought current enemy flag for the mon that is currently out
-Func_5546c: ; 5546c (15:546c)
- ld a, [wPartyAliveFlags]
+; divide enemy base stats, catch rate, and base exp by the number of mons gaining exp
+DivideExpDataByNumMonsGainingExp: ; 5546c (15:546c)
+ ld a, [wPartyGainExpFlags]
ld b, a
xor a
ld c, $8
ld d, $0
-.asm_55475
+.countSetBitsLoop ; loop to count set bits in wPartyGainExpFlags
xor a
srl b
adc d
ld d, a
dec c
- jr nz, .asm_55475
+ jr nz, .countSetBitsLoop
cp $2
- ret c
- ld [wd11e], a
- ld hl, wd002
+ ret c ; return if only one mon is gaining exp
+ ld [wd11e], a ; store number of mons gaining exp
+ ld hl, wEnemyMonBaseStats
ld c, $7
-.asm_55488
+.divideLoop
xor a
- ld [H_DIVIDEND], a ; $ff95 (aliases: H_PRODUCT, H_PASTLEADINGZEROES, H_QUOTIENT)
+ ld [H_DIVIDEND], a
ld a, [hl]
- ld [H_NUMTOPRINT], a ; $ff96 (aliases: H_MULTIPLICAND)
+ ld [H_DIVIDEND + 1], a
ld a, [wd11e]
- ld [H_REMAINDER], a ; $ff99 (aliases: H_DIVISOR, H_MULTIPLIER, H_POWEROFTEN)
+ ld [H_DIVISOR], a
ld b, $2
- call Divide
- ld a, [$ff98]
+ call Divide ; divide value by number of mons gaining exp
+ ld a, [H_QUOTIENT + 3]
ld [hli], a
dec c
- jr nz, .asm_55488
+ jr nz, .divideLoop
ret
-Func_5549f: ; 5549f (15:549f)
- ld a, [$ff97]
+; multiplies exp by 1.5
+BoostExp: ; 5549f (15:549f)
+ ld a, [H_QUOTIENT + 2]
ld b, a
- ld a, [$ff98]
+ ld a, [H_QUOTIENT + 3]
ld c, a
srl b
rr c
add c
- ld [$ff98], a
- ld a, [$ff97]
+ ld [H_QUOTIENT + 3], a
+ ld a, [H_QUOTIENT + 2]
adc b
- ld [$ff97], a
+ ld [H_QUOTIENT + 2], a
ret
GainedText: ; 554b2 (15:54b2)
diff --git a/engine/battle/16.asm b/engine/battle/16.asm
index 1500d003..d1cecbbe 100755
--- a/engine/battle/16.asm
+++ b/engine/battle/16.asm
@@ -38,7 +38,7 @@ PrintBeginningBattleText: ; 58d99 (16:4d99)
ld a, b
and a
jr z, .noSilphScope
- callab Func_3eb01
+ callab LoadEnemyMonData
jr .notPokemonTower
.noSilphScope
ld hl, EnemyAppearedText
@@ -54,7 +54,7 @@ PrintBeginningBattleText: ; 58d99 (16:4d99)
call PrintText
ld hl, UnveiledGhostText
call PrintText
- callab Func_3eb01
+ callab LoadEnemyMonData
callab Func_708ca
ld hl, WildMonAppearedText
call PrintText
@@ -94,25 +94,25 @@ GhostCantBeIDdText: ; 58e54 (16:4e54)
TX_FAR _GhostCantBeIDdText
db "@"
-SendOutMon: ; 58e59 (16:4e59)
- ld hl, wEnemyMonHP ; wEnemyMonHP
+PrintSendOutMonMessage: ; 58e59 (16:4e59)
+ ld hl, wEnemyMonHP
ld a, [hli]
or [hl]
ld hl, GoText
jr z, .printText
xor a
- ld [H_NUMTOPRINT], a ; $ff96 (aliases: H_MULTIPLICAND)
- ld hl, wEnemyMonHP ; wEnemyMonHP
+ ld [H_MULTIPLICAND], a
+ ld hl, wEnemyMonHP
ld a, [hli]
ld [wcce3], a
- ld [$ff97], a
+ ld [H_MULTIPLICAND + 1], a
ld a, [hl]
ld [wcce4], a
- ld [$ff98], a
- ld a, $19
- ld [H_REMAINDER], a ; $ff99 (aliases: H_DIVISOR, H_MULTIPLIER, H_POWEROFTEN)
+ ld [H_MULTIPLICAND + 2], a
+ ld a, 25
+ ld [H_MULTIPLIER], a
call Multiply
- ld hl, wEnemyMonMaxHP ; wEnemyMonMaxHP
+ ld hl, wEnemyMonMaxHP
ld a, [hli]
ld b, [hl]
srl a
@@ -121,19 +121,19 @@ SendOutMon: ; 58e59 (16:4e59)
rr b
ld a, b
ld b, $4
- ld [H_REMAINDER], a ; $ff99 (aliases: H_DIVISOR, H_MULTIPLIER, H_POWEROFTEN)
+ ld [H_DIVISOR], a ; enemy mon max HP divided by 4
call Divide
- ld a, [$ff98]
- ld hl, GoText
- cp $46
+ ld a, [H_QUOTIENT + 3] ; a = (enemy mon current HP * 25) / (enemy max HP / 4); this approximates the current percentage of max HP
+ ld hl, GoText ; 70% or greater
+ cp 70
jr nc, .printText
- ld hl, DoItText
- cp $28
+ ld hl, DoItText ; 40% - 69%
+ cp 40
jr nc, .printText
- ld hl, GetmText
- cp $a
+ ld hl, GetmText ; 10% - 39%
+ cp 10
jr nc, .printText
- ld hl, EnemysWeakText
+ ld hl, EnemysWeakText ; 0% - 9%
.printText
jp PrintText
diff --git a/engine/battle/1c.asm b/engine/battle/1c.asm
index b3b24007..1c69c00f 100755
--- a/engine/battle/1c.asm
+++ b/engine/battle/1c.asm
@@ -87,9 +87,9 @@ BattleTransition: ; 7096d (1c:496d)
ld [H_AUTOBGTRANSFERENABLED], a
call Delay3
xor a
- ld [$ffb0], a
+ ld [hVBlankWY], a
dec a
- ld [wcfcb], a
+ ld [wUpdateSpritesEnabled], a
call DelayFrame
ld hl, wSpriteStateData1 + 2
ld a, [H_DOWNARROWBLINKCNT2]
diff --git a/engine/battle/4_2.asm b/engine/battle/4_2.asm
index b53ea6e4..aaada492 100755
--- a/engine/battle/4_2.asm
+++ b/engine/battle/4_2.asm
@@ -1,76 +1,77 @@
-Func_137aa: ; 137aa (4:77aa)
- ld a, [W_ISLINKBATTLE] ; W_ISLINKBATTLE
+EndOfBattle: ; 137aa (4:77aa)
+ ld a, [W_ISLINKBATTLE]
cp $4
- jr nz, .asm_137eb
+ jr nz, .notLinkBattle
+; link battle
ld a, [wEnemyMonPartyPos]
ld hl, wEnemyMon1Status
ld bc, wEnemyMon2 - wEnemyMon1
call AddNTimes
- ld a, [wEnemyMonStatus] ; wcfe9
+ ld a, [wEnemyMonStatus]
ld [hl], a
call ClearScreen
- callab Func_372d6
- ld a, [wcf0b]
+ callab DisplayLinkBattleVersusTextBox
+ ld a, [wBattleResult]
cp $1
ld de, YouWinText
- jr c, .asm_137de
+ jr c, .placeWinOrLoseString
ld de, YouLoseText
- jr z, .asm_137de
+ jr z, .placeWinOrLoseString
ld de, DrawText
-.asm_137de
+.placeWinOrLoseString
hlCoord 6, 8
call PlaceString
ld c, $c8
call DelayFrames
- jr .asm_1380a
-.asm_137eb
- ld a, [wcf0b]
+ jr .evolution
+.notLinkBattle
+ ld a, [wBattleResult]
and a
- jr nz, .asm_13813
- ld hl, wcce5
+ jr nz, .resetVariables
+ ld hl, wTotalPayDayMoney
ld a, [hli]
or [hl]
inc hl
or [hl]
- jr z, .asm_1380a
- ld de, wPlayerMoney + 2 ; wd349
+ jr z, .evolution ; if pay day money is 0, jump
+ ld de, wPlayerMoney + 2
ld c, $3
predef AddBCDPredef
ld hl, PickUpPayDayMoneyText
call PrintText
-.asm_1380a
+.evolution
xor a
ld [wccd4], a
- predef Func_3ad1c
-.asm_13813
+ predef EvolutionAfterBattle
+.resetVariables
xor a
ld [wd083], a
ld [wc02a], a
- ld [W_ISINBATTLE], a ; W_ISINBATTLE
- ld [W_BATTLETYPE], a ; wd05a
- ld [W_MOVEMISSED], a ; W_MOVEMISSED
- ld [W_CUROPPONENT], a ; wd059
+ ld [W_ISINBATTLE], a
+ ld [W_BATTLETYPE], a
+ ld [W_MOVEMISSED], a
+ ld [W_CUROPPONENT], a
ld [wd11f], a
- ld [wd120], a
- ld [wd078], a
+ ld [wNumRunAttempts], a
+ ld [wEscapedFromBattle], a
ld hl, wcc2b
ld [hli], a
ld [hli], a
ld [hli], a
ld [hl], a
- ld [wListScrollOffset], a ; wcc36
+ ld [wListScrollOffset], a
ld hl, wd060
ld b, $18
-.asm_1383e
+.loop
ld [hli], a
dec b
- jr nz, .asm_1383e
+ jr nz, .loop
ld hl, wd72c
set 0, [hl]
call WaitForSoundToFinish
call GBPalWhiteOut
ld a, $ff
- ld [wd42f], a
+ ld [wDestinationWarpID], a
ret
YouWinText: ; 13853 (4:7853)
@@ -87,13 +88,13 @@ PickUpPayDayMoneyText: ; 1386b (4:786b)
db "@"
Func_13870: ; 13870 (4:7870)
- ld a, [wcc57]
+ ld a, [wNPCMovementScriptPointerTableNum]
and a
ret nz
ld a, [wd736]
and a
ret nz
- callab Func_c49d
+ callab IsPlayerStandingOnDoorTileOrWarpTile
jr nc, .asm_13888
.asm_13884
ld a, $1
@@ -307,7 +308,7 @@ HazeEffect_: ; 139da (4:79da)
ld hl, wcd12
ld de, wBattleMonAttack
call Func_13a4a
- ld hl, wcd26
+ ld hl, wEnemyMonUnmodifiedAttack
ld de, wEnemyMonAttack
call Func_13a4a
ld hl, wEnemyMonStatus
diff --git a/engine/battle/5.asm b/engine/battle/5.asm
index 6c7a642e..82518052 100755
--- a/engine/battle/5.asm
+++ b/engine/battle/5.asm
@@ -53,8 +53,8 @@ SubstituteEffectHandler: ; 17dad (5:7dad)
call Bankswitch ;jump to routine depending on animation setting
ld hl, SubstituteText
call PrintText
- ld hl, Func_3cd5a
- ld b, BANK(Func_3cd5a)
+ ld hl, DrawHUDsAndHPBars
+ ld b, BANK(DrawHUDsAndHPBars)
jp Bankswitch
.alreadyHasSubstitute
ld hl, HasSubstituteText
diff --git a/engine/battle/animations.asm b/engine/battle/animations.asm
index a8ed3865..58d4e60a 100755
--- a/engine/battle/animations.asm
+++ b/engine/battle/animations.asm
@@ -517,7 +517,7 @@ Func_78e01: ; 78e01 (1e:4e01)
ret
Func_78e23: ; 78e23 (1e:4e23)
- ld a, [wcf1b]
+ ld a, [wOnSGB]
and a
ld a, $e4
jr z, .asm_78e47
@@ -1091,7 +1091,7 @@ CallWithTurnFlipped: ; 79155 (1e:5155)
AnimationFlashScreenLong: ; 79165 (1e:5165)
ld a,3 ; cycle through the palettes 3 times
ld [wd08a],a
- ld a,[wcf1b] ; running on SGB?
+ ld a,[wOnSGB] ; running on SGB?
and a
ld hl,FlashScreenLongMonochrome
jr z,.loop
@@ -1211,7 +1211,7 @@ Func_791f9: ; 791f9 (1e:51f9)
ld bc, $4040
Func_791fc: ; 791fc (1e:51fc)
- ld a, [wcf1b]
+ ld a, [wOnSGB]
and a
ld a, b
jr z, .asm_79204
@@ -1411,50 +1411,50 @@ Func_79329: ; 79329 (1e:5329)
ld [hli], a
ret
-Func_79337: ; 79337 (1e:5337)
+AdjustOAMBlockXPos: ; 79337 (1e:5337)
ld l, e
ld h, d
-Func_79339: ; 79339 (1e:5339)
+AdjustOAMBlockXPos2: ; 79339 (1e:5339)
ld de, $4
-.asm_7933c
+.loop
ld a, [wd08a]
ld b, a
ld a, [hl]
add b
cp $a8
- jr c, .asm_7934a
+ jr c, .skipPuttingEntryOffScreen
dec hl
ld a, $a0
ld [hli], a
-.asm_7934a
+.skipPuttingEntryOffScreen
ld [hl], a
add hl, de
dec c
- jr nz, .asm_7933c
+ jr nz, .loop
ret
-Func_79350: ; 79350 (1e:5350)
+AdjustOAMBlockYPos: ; 79350 (1e:5350)
ld l, e
ld h, d
-Func_79352: ; 79352 (1e:5352)
+AdjustOAMBlockYPos2: ; 79352 (1e:5352)
ld de, $4
-.asm_79355
+.loop
ld a, [wd08a]
ld b, a
ld a, [hl]
add b
cp $70
- jr c, .asm_79363
+ jr c, .skipSettingPreviousEntrysAttribute
dec hl
- ld a, $a0
+ ld a, $a0 ; bug, sets previous OAM entry's attribute
ld [hli], a
-.asm_79363
+.skipSettingPreviousEntrysAttribute
ld [hl], a
add hl, de
dec c
- jr nz, .asm_79355
+ jr nz, .loop
ret
AnimationBlinkEnemyMon: ; 79369 (1e:5369)
@@ -1962,7 +1962,7 @@ AnimationWavyScreen: ; 79666 (1e:5666)
xor a
ld [H_AUTOBGTRANSFERENABLED], a
ld a, $90
- ld [$ffb0], a
+ ld [hVBlankWY], a
ld d, $80
ld e, $8f
ld c, $ff
@@ -1984,7 +1984,7 @@ AnimationWavyScreen: ; 79666 (1e:5666)
dec c
jr nz, .asm_7967f
xor a
- ld [$ffb0], a
+ ld [hVBlankWY], a
call SaveScreenTilesToBuffer2
call ClearScreen
ld a, $1
@@ -2744,11 +2744,11 @@ AnimationShakeEnemyHUD: ; 79d77 (1e:5d77)
ld hl, vBGMap0
call Func_79e0d
ld a, $90
- ld [$ffb0], a
+ ld [hVBlankWY], a
ld hl, vBGMap0 + $320
call Func_79e0d
ld a, $38
- ld [$ffb0], a
+ ld [hVBlankWY], a
call Func_792fd
ld hl, vBGMap0
call Func_79e0d
@@ -2759,11 +2759,11 @@ AnimationShakeEnemyHUD: ; 79d77 (1e:5d77)
call AnimationShowMonPic
call ClearSprites
ld a, $90
- ld [$ffb0], a
+ ld [hVBlankWY], a
ld hl, vBGMap1
call Func_79e0d
xor a
- ld [$ffb0], a
+ ld [hVBlankWY], a
call SaveScreenTilesToBuffer1
ld hl, vBGMap0
call Func_79e0d
diff --git a/engine/battle/b_2.asm b/engine/battle/b_2.asm
index e343f1aa..4ff8b66b 100755
--- a/engine/battle/b_2.asm
+++ b/engine/battle/b_2.asm
@@ -88,10 +88,10 @@ PayDayEffect_ ; 2feb8 (b:7eb8)
xor a
ld hl, wcd6d
ld [hli], a
- ld a, [$fff3]
+ ld a, [H_WHOSETURN]
and a
ld a, [wBattleMonLevel]
- jr z, .asm_2fec8 ; 0x2fec3 $3
+ jr z, .asm_2fec8
ld a, [wEnemyMonLevel]
.asm_2fec8
add a
@@ -118,10 +118,10 @@ PayDayEffect_ ; 2feb8 (b:7eb8)
ld a, [$ff99]
add b
ld [hl], a
- ld de, wcce7
+ ld de, wTotalPayDayMoney + 2
ld c, $3
predef AddBCDPredef
- ld hl, CoinsScatteredText ; $7f04
+ ld hl, CoinsScatteredText
jp PrintText
CoinsScatteredText: ; 2ff04 (b:7f04)
diff --git a/engine/battle/c.asm b/engine/battle/c.asm
index c1347d24..e31b1fce 100755
--- a/engine/battle/c.asm
+++ b/engine/battle/c.asm
@@ -26,7 +26,7 @@ OneHitKOEffect_: ; 33f57 (c:7f57)
ld [hli], a
ld [hl], a ; set the damage output to zero
dec a
- ld [wd05e], a
+ ld [wCriticalHitOrOHKO], a
ld hl, wBattleMonSpeed + 1
ld de, wEnemyMonSpeed + 1
ld a, [H_WHOSETURN] ; $fff3
@@ -50,7 +50,7 @@ OneHitKOEffect_: ; 33f57 (c:7f57)
ld [hli], a
ld [hl], a
ld a, $2
- ld [wd05e], a
+ ld [wCriticalHitOrOHKO], a
ret
.asm_33f8a
ld a, $1
diff --git a/engine/battle/core.asm b/engine/battle/core.asm
index 4baa7a76..c2616ff7 100755
--- a/engine/battle/core.asm
+++ b/engine/battle/core.asm
@@ -91,9 +91,9 @@ EffectsArray5B: ; 3c049 (f:4049)
db TRAPPING_EFFECT
db -1
-Func_3c04c: ; 3c04c (f:404c)
- call Func_3ec92
- ld a, $1
+SlidePlayerAndEnemySilhouettesOnScreen: ; 3c04c (f:404c)
+ call LoadPlayerBackPic
+ ld a, $1 ; the usual text box at the bottom of the screen
ld [wd125], a
call DisplayTextBoxID
hlCoord 1, 5
@@ -101,82 +101,83 @@ Func_3c04c: ; 3c04c (f:404c)
call ClearScreenArea
call DisableLCD
call LoadFontTilePatterns
- call Func_3ee58
+ call LoadHudAndHpBarAndStatusTilePatterns
ld hl, vBGMap0
ld bc, $400
-.asm_3c06f
+.clearBackgroundLoop
ld a, $7f
ld [hli], a
dec bc
ld a, b
or c
- jr nz, .asm_3c06f
+ jr nz, .clearBackgroundLoop
+; copy the work RAM tile map to VRAM
ld hl, wTileMap
ld de, vBGMap0
- ld b, $12
-.asm_3c07f
- ld c, $14
-.asm_3c081
+ ld b, 18 ; number of rows
+.copyRowLoop
+ ld c, 20 ; number of columns
+.copyColumnLoop
ld a, [hli]
ld [de], a
inc e
dec c
- jr nz, .asm_3c081
- ld a, $c
- add e
+ jr nz, .copyColumnLoop
+ ld a, 12 ; number of off screen tiles to the right of screen in VRAM
+ add e ; skip the off screen tiles
ld e, a
- jr nc, .asm_3c08e
+ jr nc, .noCarry
inc d
-.asm_3c08e
+.noCarry
dec b
- jr nz, .asm_3c07f
+ jr nz, .copyRowLoop
call EnableLCD
ld a, $90
- ld [$ffb0], a
- ld [rWY], a ; $ff4a
+ ld [hVBlankWY], a
+ ld [rWY], a
xor a
- ld [$ffd7], a
- ld [$ffaf], a
+ ld [hTilesetType], a
+ ld [hVBlankSCY], a
dec a
- ld [wcfcb], a
+ ld [wUpdateSpritesEnabled], a
call Delay3
xor a
- ld [H_AUTOBGTRANSFERENABLED], a ; $ffba
+ ld [H_AUTOBGTRANSFERENABLED], a
ld b, $70
ld c, $90
ld a, c
- ld [$ffae], a
+ ld [hVBlankSCX], a
call DelayFrame
- ld a, $e4
- ld [rBGP], a ; $ff47
- ld [rOBP0], a ; $ff48
- ld [rOBP1], a ; $ff49
-.asm_3c0bb
+ ld a, %11100100 ; inverted palette for silhouette effect
+ ld [rBGP], a
+ ld [rOBP0], a
+ ld [rOBP1], a
+.slideSilhouettesLoop ; slide silhouettes of the player's pic and the enemy's pic onto the screen
ld h, b
ld l, $40
- call Func_3c110
+ call SetScrollXForSlidingPlayerBodyLeft ; begin background scrolling on line $40
inc b
inc b
ld h, $0
ld l, $60
- call Func_3c110
- call Func_3c0ff
+ call SetScrollXForSlidingPlayerBodyLeft ; end background scrolling on line $60
+ call SlidePlayerHeadLeft
ld a, c
- ld [$ffae], a
+ ld [hVBlankSCX], a
dec c
dec c
- jr nz, .asm_3c0bb
+ jr nz, .slideSilhouettesLoop
ld a, $1
- ld [H_AUTOBGTRANSFERENABLED], a ; $ffba
+ ld [H_AUTOBGTRANSFERENABLED], a
ld a, $31
ld [$ffe1], a
hlCoord 1, 5
predef Func_3f0c6
xor a
- ld [$ffb0], a
- ld [rWY], a ; $ff4a
+ ld [hVBlankWY], a
+ ld [rWY], a
inc a
- ld [H_AUTOBGTRANSFERENABLED], a ; $ffba
+ ld [H_AUTOBGTRANSFERENABLED], a
call Delay3
ld b, $1
call GoPAL_SET
@@ -185,160 +186,174 @@ Func_3c04c: ; 3c04c (f:404c)
ld b, BANK(PrintBeginningBattleText)
jp Bankswitch
-Func_3c0ff: ; 3c0ff (f:40ff)
+; when a battle is starting, silhouettes of the player's pic and the enemy's pic are slid onto the screen
+; the lower of the player's pic (his body) is part of the background, but his head is a sprite
+; the reason for this is that it shares Y coordinates with the lower part of the enemy pic, so background scrolling wouldn't work for both pics
+; instead, the enemy pic is part of the background and uses the scroll register, while the player's head is a sprite and is slid by changing its X coordinates in a loop
+SlidePlayerHeadLeft: ; 3c0ff (f:40ff)
push bc
ld hl, wOAMBuffer + $01
- ld c, $15
- ld de, $4
-.asm_3c108
- dec [hl]
- dec [hl]
- add hl, de
+ ld c, $15 ; number of OAM entries
+ ld de, $4 ; size of OAM entry
+.loop
+ dec [hl] ; decrement X
+ dec [hl] ; decrement X
+ add hl, de ; next OAM entry
dec c
- jr nz, .asm_3c108
+ jr nz, .loop
pop bc
ret
-Func_3c110: ; 3c110 (f:4110)
- ld a, [$ff44]
+SetScrollXForSlidingPlayerBodyLeft: ; 3c110 (f:4110)
+ ld a, [rLY]
cp l
- jr nz, Func_3c110
+ jr nz, SetScrollXForSlidingPlayerBodyLeft
ld a, h
- ld [rSCX], a ; $ff43
-.asm_3c118
- ld a, [$ff44]
+ ld [rSCX], a
+.loop
+ ld a, [rLY]
cp h
- jr z, .asm_3c118
+ jr z, .loop
ret
-Func_3c11e: ; 3c11e (f:411e)
+StartBattle: ; 3c11e (f:411e)
xor a
- ld [wPartyAliveFlags], a
- ld [wccf5], a
+ ld [wPartyGainExpFlags], a
+ ld [wPartyFoughtCurrentEnemyFlags], a
ld [wcd6a], a
inc a
ld [wd11d], a
- ld hl, wEnemyMon1HP ; wd8a5
- ld bc, $2b
+ ld hl, wEnemyMon1HP
+ ld bc, wEnemyMon2 - wEnemyMon1 - 1
ld d, $3
-.asm_3c134
+.findFirstAliveEnemyMonLoop
inc d
ld a, [hli]
or [hl]
- jr nz, .asm_3c13c
+ jr nz, .foundFirstAliveEnemyMon
add hl, bc
- jr .asm_3c134
-.asm_3c13c
+ jr .findFirstAliveEnemyMonLoop
+.foundFirstAliveEnemyMon
ld a, d
ld [wcc3e], a
- ld a, [W_ISINBATTLE] ; W_ISINBATTLE
- dec a
- call nz, Func_3c92a
- ld c, $28
+ ld a, [W_ISINBATTLE]
+ dec a ; is it a trainer battle?
+ call nz, EnemySendOutFirstMon ; if it is a trainer battle, send out enemy mon
+ ld c, 40
call DelayFrames
call SaveScreenTilesToBuffer1
-.asm_3c14f
+.checkAnyPartyAlive
call AnyPartyAlive
ld a, d
and a
- jp z, HandlePlayerBlackOut
+ jp z, HandlePlayerBlackOut ; jump if no mon is alive
call LoadScreenTilesFromBuffer1
- ld a, [W_BATTLETYPE] ; wd05a
- and a
- jp z, Func_3c1ad
-.asm_3c161
- call InitBattleMenu
- ret c
+ ld a, [W_BATTLETYPE]
+ and a ; is it a normal battle?
+ jp z, .playerSendOutFirstMon ; if so, send out player mon
+; safari zone battle
+.displaySafariZoneBattleMenu
+ call DisplayBattleMenu
+ ret c ; return if the player ran from battle
ld a, [wcd6a]
+ and a ; was the item used successfully?
+ jr z, .displaySafariZoneBattleMenu ; if not, display the menu again; XXX does this ever jump?
+ ld a, [W_NUMSAFARIBALLS]
and a
- jr z, .asm_3c161
- ld a, [W_NUMSAFARIBALLS] ; W_NUMSAFARIBALLS
- and a
- jr nz, .asm_3c17a
+ jr nz, .notOutOfSafariBalls
call LoadScreenTilesFromBuffer1
- ld hl, OutOfSafariBallsText
+ ld hl, .outOfSafariBallsText
jp PrintText
-.asm_3c17a
+.notOutOfSafariBalls
callab PrintSafariZoneBattleText
ld a, [wEnemyMonSpeed + 1]
add a
- ld b, a
- jp c, asm_3c202
- ld a, [wcce9]
- and a
- jr z, .asm_3c194
+ ld b, a ; init b (which is later compared with random value) to (enemy speed % 256) * 2
+ jp c, EnemyRan ; if (enemy speed % 256) > 127, the enemy runs
+ ld a, [wSafariBaitFactor]
+ and a ; is bait factor 0?
+ jr z, .checkEscapeFactor
+; bait factor is not 0
+; divide b by 4 (making the mon less likely to run)
srl b
srl b
-.asm_3c194
- ld a, [wcce8]
- and a
- jr z, .asm_3c1a0
+.checkEscapeFactor
+ ld a, [wSafariEscapeFactor]
+ and a ; is escape factor 0?
+ jr z, .compareWithRandomValue
+; escape factor is not 0
+; multiply b by 2 (making the mon more likely to run)
sla b
- jr nc, .asm_3c1a0
+ jr nc, .compareWithRandomValue
+; cap b at 255
ld b, $ff
-.asm_3c1a0
+.compareWithRandomValue
call Random
cp b
- jr nc, .asm_3c14f
- jr asm_3c202
+ jr nc, .checkAnyPartyAlive
+ jr EnemyRan ; if b was greater than the random value, the enemy runs
-OutOfSafariBallsText: ; 3c1a8 (f:41a8)
+.outOfSafariBallsText
TX_FAR _OutOfSafariBallsText
db "@"
-Func_3c1ad: ; 3c1ad (f:41ad)
+.playerSendOutFirstMon
xor a
- ld [wWhichPokemon], a ; wWhichPokemon
-.asm_3c1b1
- call Func_3ca97
- jr nz, .asm_3c1bc
- ld hl, wWhichPokemon ; wWhichPokemon
+ ld [wWhichPokemon], a
+.findFirstAliveMonLoop
+ call HasMonFainted
+ jr nz, .foundFirstAliveMon
+; fainted, go to the next one
+ ld hl, wWhichPokemon
inc [hl]
- jr .asm_3c1b1
-.asm_3c1bc
- ld a, [wWhichPokemon] ; wWhichPokemon
- ld [wPlayerMonNumber], a ; wPlayerMonNumber
+ jr .findFirstAliveMonLoop
+.foundFirstAliveMon
+ ld a, [wWhichPokemon]
+ ld [wPlayerMonNumber], a
inc a
- ld hl, wPartyCount ; wPartyCount
+ ld hl, wPartySpecies - 1
ld c, a
- ld b, $0
+ ld b, 0
add hl, bc
- ld a, [hl]
+ ld a, [hl] ; species
ld [wcf91], a
ld [wBattleMonSpecies2], a
call LoadScreenTilesFromBuffer1
hlCoord 1, 5
ld a, $9
- call Func_3c8df
+ call SlideTrainerPicOffScreen
call SaveScreenTilesToBuffer1
- ld a, [wWhichPokemon] ; wWhichPokemon
+ ld a, [wWhichPokemon]
ld c, a
ld b, $1
push bc
- ld hl, wPartyAliveFlags
+ ld hl, wPartyGainExpFlags
predef FlagActionPredef
- ld hl, wccf5
+ ld hl, wPartyFoughtCurrentEnemyFlags
pop bc
predef FlagActionPredef
- call Func_3cba6
+ call LoadBattleMonFromParty
call LoadScreenTilesFromBuffer1
- call Func_3cc91
+ call SendOutMon
jr MainInBattleLoop
-asm_3c202: ; 3c202 (f:4202)
+
+; wild mon or link battle enemy ran from battle
+EnemyRan: ; 3c202 (f:4202)
call LoadScreenTilesFromBuffer1
- ld a, [W_ISLINKBATTLE] ; W_ISLINKBATTLE
+ ld a, [W_ISLINKBATTLE]
cp $4
ld hl, WildRanText
- jr nz, .asm_3c216
+ jr nz, .printText
+; link battle
xor a
- ld [wcf0b], a
+ ld [wBattleResult], a
ld hl, EnemyRanText
-.asm_3c216
+.printText
call PrintText
ld a, (SFX_08_44 - SFX_Headers_08) / 3
call PlaySoundWaitForCurrent
xor a
- ld [H_WHOSETURN], a ; $fff3
+ ld [H_WHOSETURN], a
ld hl, AnimationSlideEnemyMonOut
ld b, BANK(AnimationSlideEnemyMonOut)
jp Bankswitch
@@ -355,116 +370,121 @@ MainInBattleLoop: ; 3c233 (f:4233)
call ReadPlayerMonCurHPAndStatus
ld hl, wBattleMonHP
ld a, [hli]
- or [hl]
- jp z, HandlePlayerMonFainted ; test if current player mon is fainted
+ or [hl] ; is battle mon HP 0?
+ jp z, HandlePlayerMonFainted ; if battle mon HP is 0, jump
ld hl, wEnemyMonHP
ld a, [hli]
- or [hl]
- jp z, HandleEnemyMonFainted
+ or [hl] ; is enemy mon HP 0?
+ jp z, HandleEnemyMonFainted ; if enemy mon HP is 0, jump
call SaveScreenTilesToBuffer1
xor a
ld [wd11d], a
ld a, [W_PLAYERBATTSTATUS2]
- and $60
- jr nz, .asm_3c2a6 ; 0x3c252 $52
+ and %01100000 ; check if the player is using Rage or needs to recharge
+ jr nz, .selectEnemyMove
+; the player is not using Rage and doesn't need to recharge
ld hl, W_ENEMYBATTSTATUS1
- res 3, [hl]
+ res 3, [hl] ; reset flinch bit
ld hl, W_PLAYERBATTSTATUS1
- res 3, [hl]
+ res 3, [hl] ; reset flinch bit
ld a, [hl]
- and $12
- jr nz, .asm_3c2a6 ; 0x3c261 $43
- call InitBattleMenu ; show battle menu
- ret c
- ld a, [wd078]
- and a
- ret nz
+ and %00010010 ; check if the player is thrashing about or charging for an attack
+ jr nz, .selectEnemyMove ; if so, jump
+; the player is neither thrashing about nor charging for an attack
+ call DisplayBattleMenu ; show battle menu
+ ret c ; return if player ran from battle
+ ld a, [wEscapedFromBattle]
+ and a
+ ret nz ; return if pokedoll was used to escape from battle
ld a, [wBattleMonStatus]
- and $27
- jr nz, .asm_3c2a6 ; 0x3c271 $33
+ and (1 << FRZ) | SLP ; is mon frozen or asleep?
+ jr nz, .selectEnemyMove ; if so, jump
ld a, [W_PLAYERBATTSTATUS1]
- and $21
- jr nz, .asm_3c2a6 ; 0x3c278 $2c
+ and %00100001 ; check player is using Bide or using a multi-turn attack like wrap
+ jr nz, .selectEnemyMove ; if so, jump
ld a, [W_ENEMYBATTSTATUS1]
- bit 5, a
- jr z, .asm_3c288 ; 0x3c27f $7
+ bit 5, a ; check if enemy is using a multi-turn attack like wrap
+ jr z, .selectPlayerMove ; if not, jump
+; enemy is using a mult-turn attack like wrap, so player is trapped and cannot select a move
ld a, $ff
ld [wPlayerSelectedMove], a
- jr .asm_3c2a6 ; 0x3c286 $1e
-.asm_3c288
+ jr .selectEnemyMove
+.selectPlayerMove
ld a, [wcd6a]
and a
- jr nz, .asm_3c2a6 ; 0x3c28c $18
+ jr nz, .selectEnemyMove
ld [wMoveMenuType], a
inc a
ld [W_ANIMATIONID], a
xor a
- ld [wcc35], a
+ ld [wMenuItemToSwap], a
call MoveSelectionMenu
push af
call LoadScreenTilesFromBuffer1
- call Func_3cd5a
+ call DrawHUDsAndHPBars
pop af
- jr nz, MainInBattleLoop
-.asm_3c2a6
+ jr nz, MainInBattleLoop ; if the player didn't select a move, jump
+.selectEnemyMove
call SelectEnemyMove
ld a, [W_ISLINKBATTLE]
cp $4
jr nz, .noLinkBattle
+; link battle
ld a, [wcc3e]
cp $f
- jp z, asm_3c202
+ jp z, EnemyRan
cp $e
jr z, .noLinkBattle
cp $d
jr z, .noLinkBattle
sub $4
jr c, .noLinkBattle
+; the link battle enemy has switched mons
ld a, [W_PLAYERBATTSTATUS1]
- bit 5, a
- jr z, .asm_3c2dd ; 0x3c2c9 $12
+ bit 5, a ; check if using multi-turn move like Wrap
+ jr z, .asm_3c2dd
ld a, [wPlayerMoveListIndex]
ld hl, wBattleMonMoves
ld c, a
- ld b, $0
+ ld b, 0
add hl, bc
ld a, [hl]
- cp $76
- jr nz, .asm_3c2dd ; 0x3c2d8 $3
+ cp METRONOME
+ jr nz, .asm_3c2dd
ld [wPlayerSelectedMove], a
.asm_3c2dd
- callab Func_3a74b
+ callab SwitchEnemyMon
.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
+ jr z, .compareSpeed ; if both used Quick Attack
+ jp .playerMovesFirst ; if player used Quick Attack and enemy didn't
.playerDidNotUseQuickAttack
ld a, [wEnemySelectedMove]
cp QUICK_ATTACK
- jr z, .enemyMovesFirst
+ jr z, .enemyMovesFirst ; if enemy used Quick Attack and player didn't
ld a, [wPlayerSelectedMove]
cp COUNTER
jr nz, .playerDidNotUseCounter
ld a, [wEnemySelectedMove]
cp COUNTER
- jr z, .compareSpeed ; both used Counter
- jr .enemyMovesFirst ; player used Counter
+ jr z, .compareSpeed ; if both used Counter
+ jr .enemyMovesFirst ; if player used Counter and enemy didn't
.playerDidNotUseCounter
ld a, [wEnemySelectedMove]
cp COUNTER
- jr z, .playerMovesFirst
+ jr z, .playerMovesFirst ; if enemy used Counter and player didn't
.compareSpeed
ld de, wBattleMonSpeed ; player speed value
ld hl, wEnemyMonSpeed ; enemy speed value
ld c, $2
call StringCmp ; compare speed values
jr z, .speedEqual
- jr nc, .playerMovesFirst
- jr .enemyMovesFirst
+ jr nc, .playerMovesFirst ; if player is faster
+ jr .enemyMovesFirst ; if enemy is faster
.speedEqual
ld a, [$ffaa]
cp $2
@@ -483,66 +503,66 @@ MainInBattleLoop: ; 3c233 (f:4233)
ld [H_WHOSETURN], a
callab TrainerAI
jr c, .AIActionUsedEnemyFirst
- call Func_3e6bc ; execute enemy move
- ld a, [wd078]
- and a
- ret nz
+ call ExecuteEnemyMove
+ ld a, [wEscapedFromBattle]
+ and a ; was Teleport, Road, or Whirlwind used to escape from battle?
+ ret nz ; if so, return
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, [wd078]
- and a
- ret nz
+ call DrawHUDsAndHPBars
+ call ExecutePlayerMove
+ ld a, [wEscapedFromBattle]
+ and a ; was Teleport, Road, or Whirlwind used to escape from battle?
+ ret nz ; if so, return
ld a, b
and a
jp z, HandleEnemyMonFainted
call HandlePoisonBurnLeechSeed
jp z, HandlePlayerMonFainted
- call Func_3cd5a
- call Func_3c50f
+ call DrawHUDsAndHPBars
+ call CheckNumAttacksLeft
jp MainInBattleLoop
.playerMovesFirst
- call Func_3d65e ; execute player move
- ld a, [wd078]
- and a
- ret nz
+ call ExecutePlayerMove
+ ld a, [wEscapedFromBattle]
+ and a ; was Teleport, Road, or Whirlwind used to escape from battle?
+ ret nz ; if so, return
ld a, b
and a
jp z, HandleEnemyMonFainted
call HandlePoisonBurnLeechSeed
jp z, HandlePlayerMonFainted
- call Func_3cd5a
+ call DrawHUDsAndHPBars
ld a, $1
ld [H_WHOSETURN], a
callab TrainerAI
jr c, .AIActionUsedPlayerFirst
- call Func_3e6bc ; execute enemy move
- ld a, [wd078]
- and a
- ret nz
+ call ExecuteEnemyMove
+ ld a, [wEscapedFromBattle]
+ and a ; was Teleport, Road, or Whirlwind used to escape from battle?
+ ret nz ; if so, return
ld a, b
and a
jp z, HandlePlayerMonFainted
.AIActionUsedPlayerFirst
call HandlePoisonBurnLeechSeed
jp z, HandleEnemyMonFainted
- call Func_3cd5a
- call Func_3c50f
+ call DrawHUDsAndHPBars
+ call CheckNumAttacksLeft
jp MainInBattleLoop
HandlePoisonBurnLeechSeed: ; 3c3bd (f:43bd)
- ld hl, wBattleMonHP ; wd015
- ld de, wBattleMonStatus ; wBattleMonStatus
- ld a, [H_WHOSETURN] ; $fff3
+ ld hl, wBattleMonHP
+ ld de, wBattleMonStatus
+ ld a, [H_WHOSETURN]
and a
jr z, .playersTurn
- ld hl, wEnemyMonHP ; wEnemyMonHP
- ld de, wEnemyMonStatus ; wcfe9
+ ld hl, wEnemyMonHP
+ ld de, wEnemyMonStatus
.playersTurn
ld a, [de]
and (1 << BRN) | (1 << PSN)
@@ -562,26 +582,26 @@ HandlePoisonBurnLeechSeed: ; 3c3bd (f:43bd)
pop hl
call HandlePoisonBurnLeechSeed_DecreaseOwnHP
.notBurnedOrPoisoned
- ld de, W_PLAYERBATTSTATUS2 ; W_PLAYERBATTSTATUS2
- ld a, [H_WHOSETURN] ; $fff3
+ ld de, W_PLAYERBATTSTATUS2
+ ld a, [H_WHOSETURN]
and a
jr z, .playersTurn2
- ld de, W_ENEMYBATTSTATUS2 ; W_ENEMYBATTSTATUS2
+ ld de, W_ENEMYBATTSTATUS2
.playersTurn2
ld a, [de]
add a
jr nc, .notLeechSeeded
push hl
- ld a, [H_WHOSETURN] ; $fff3
+ ld a, [H_WHOSETURN]
push af
xor $1
- ld [H_WHOSETURN], a ; $fff3
+ ld [H_WHOSETURN], a
xor a
ld [wcc5b], a
ld a,ABSORB
call PlayMoveAnimation ; play leech seed animation (from opposing mon)
pop af
- ld [H_WHOSETURN], a ; $fff3
+ ld [H_WHOSETURN], a
pop hl
call HandlePoisonBurnLeechSeed_DecreaseOwnHP
call HandlePoisonBurnLeechSeed_IncreaseEnemyHP
@@ -593,7 +613,7 @@ HandlePoisonBurnLeechSeed: ; 3c3bd (f:43bd)
ld a, [hli]
or [hl]
ret nz ; test if fainted
- call Func_3cd5a
+ call DrawHUDsAndHPBars
ld c, $14
call DelayFrames
xor a
@@ -637,13 +657,13 @@ HandlePoisonBurnLeechSeed_DecreaseOwnHP: ; 3c43d (f:443d)
jr nz, .nonZeroDamage
inc c ; damage is at least 1
.nonZeroDamage
- ld hl, W_PLAYERBATTSTATUS3 ; W_PLAYERBATTSTATUS3
- ld de, W_PLAYERTOXICCOUNTER ; wd06c
- ld a, [H_WHOSETURN] ; $fff3
+ ld hl, W_PLAYERBATTSTATUS3
+ ld de, W_PLAYERTOXICCOUNTER
+ ld a, [H_WHOSETURN]
and a
jr z, .playersTurn
- ld hl, W_ENEMYBATTSTATUS3 ; W_ENEMYBATTSTATUS3
- ld de, W_ENEMYTOXICCOUNTER ; wd071
+ ld hl, W_ENEMYBATTSTATUS3
+ ld de, W_ENEMYTOXICCOUNTER
.playersTurn
bit 0, [hl]
jr z, .noToxic
@@ -684,11 +704,11 @@ HandlePoisonBurnLeechSeed_DecreaseOwnHP: ; 3c43d (f:443d)
; adds bc to enemy HP
HandlePoisonBurnLeechSeed_IncreaseEnemyHP: ; 3c4a3 (f:44a3)
push hl
- ld hl, wEnemyMonMaxHP ; wEnemyMonMaxHP
- ld a, [H_WHOSETURN] ; $fff3
+ ld hl, wEnemyMonMaxHP
+ ld a, [H_WHOSETURN]
and a
jr z, .playersTurn
- ld hl, wBattleMonMaxHP ; wd023
+ ld hl, wBattleMonMaxHP
.playersTurn
ld a, [hli]
ld [wHPBarMaxHP+1], a
@@ -722,19 +742,19 @@ HandlePoisonBurnLeechSeed_IncreaseEnemyHP: ; 3c4a3 (f:44a3)
ld [hl], a
ld [wHPBarNewHP], a
.noOverfullHeal
- ld a, [H_WHOSETURN] ; $fff3
+ ld a, [H_WHOSETURN]
xor $1
- ld [H_WHOSETURN], a ; $fff3
+ ld [H_WHOSETURN], a
call UpdateCurMonHPBar
- ld a, [H_WHOSETURN] ; $fff3
+ ld a, [H_WHOSETURN]
xor $1
- ld [H_WHOSETURN], a ; $fff3
+ ld [H_WHOSETURN], a
pop hl
ret
UpdateCurMonHPBar: ; 3c4f6 (f:44f6)
hlCoord 10, 9 ; tile pointer to player HP bar
- ld a, [H_WHOSETURN] ; $fff3
+ ld a, [H_WHOSETURN]
and a
ld a, $1
jr z, .playersTurn
@@ -742,23 +762,25 @@ UpdateCurMonHPBar: ; 3c4f6 (f:44f6)
xor a
.playersTurn
push bc
- ld [wListMenuID], a ; wListMenuID
+ ld [wListMenuID], a
predef UpdateHPBar2
pop bc
ret
-Func_3c50f: ; 3c50f (f:450f)
- ld a, [wd06a]
+CheckNumAttacksLeft: ; 3c50f (f:450f)
+ ld a, [wPlayerNumAttacksLeft]
and a
- jr nz, .asm_3c51a
- ld hl, W_PLAYERBATTSTATUS1 ; W_PLAYERBATTSTATUS1
- res 5, [hl]
-.asm_3c51a
- ld a, [wd06f]
+ jr nz, .checkEnemy
+; player has 0 attacks left
+ ld hl, W_PLAYERBATTSTATUS1
+ res 5, [hl] ; player not using multi-turn attack like wrap any more
+.checkEnemy
+ ld a, [wEnemyNumAttacksLeft]
and a
ret nz
- ld hl, W_ENEMYBATTSTATUS1 ; W_ENEMYBATTSTATUS1
- res 5, [hl]
+; enemy has 0 attacks left
+ ld hl, W_ENEMYBATTSTATUS1
+ res 5, [hl] ; enemy not using multi-turn attack like wrap any more
ret
HandleEnemyMonFainted: ; 3c525 (f:4525)
@@ -768,56 +790,56 @@ HandleEnemyMonFainted: ; 3c525 (f:4525)
call AnyPartyAlive
ld a, d
and a
- jp z, HandlePlayerBlackOut
- ld hl, wBattleMonHP ; wd015
+ jp z, HandlePlayerBlackOut ; if no party mons are alive, the player blacks out
+ ld hl, wBattleMonHP
ld a, [hli]
- or [hl]
- call nz, Func_3cd60
- ld a, [W_ISINBATTLE] ; W_ISINBATTLE
+ or [hl] ; is battle mon HP zero?
+ call nz, DrawPlayerHUDAndHPBar ; if battle mon HP is not zero, draw player HD and HP bar
+ ld a, [W_ISINBATTLE]
dec a
- ret z
+ ret z ; return if it's a wild battle
call AnyEnemyPokemonAliveCheck
jp z, TrainerBattleVictory
- ld hl, wBattleMonHP ; wd015
+ ld hl, wBattleMonHP
ld a, [hli]
- or [hl]
- jr nz, .asm_3c555
- call Func_3c79b
+ or [hl] ; does battle mon have 0 HP?
+ jr nz, .skipReplacingBattleMon ; if not, skip replacing battle mon
+ call DoUseNextMonDialogue ; this call is useless in a trainer battle. it shouldn't be here
ret c
- call Func_3c7d8
-.asm_3c555
+ call ChooseNextMon
+.skipReplacingBattleMon
ld a, $1
ld [wcd6a], a
- call Func_3c664
- jp z, asm_3c202
+ call ReplaceFaintedEnemyMon
+ jp z, EnemyRan
xor a
ld [wcd6a], a
jp MainInBattleLoop
FaintEnemyPokemon ; 0x3c567
call ReadPlayerMonCurHPAndStatus
- ld a, [W_ISINBATTLE] ; W_ISINBATTLE
+ ld a, [W_ISINBATTLE]
dec a
jr z, .wild
ld a, [wEnemyMonPartyPos]
ld hl, wEnemyMon1HP
- ld bc, $2c ; mon struct len
+ ld bc, wEnemyMon2 - wEnemyMon1
call AddNTimes
xor a
ld [hli], a
ld [hl], a
.wild
- ld hl, W_PLAYERBATTSTATUS1 ; W_PLAYERBATTSTATUS1
+ ld hl, W_PLAYERBATTSTATUS1
res 2, [hl]
xor a
- ld [W_NUMHITS], a ; wd074
+ ld [W_NUMHITS], a
ld hl, wd065 ; enemy statuses
ld [hli], a
ld [hli], a
ld [hli], a
ld [hli], a
ld [hl], a
- ld [W_ENEMYDISABLEDMOVE], a ; W_ENEMYDISABLEDMOVE
+ ld [W_ENEMYDISABLEDMOVE], a
ld [wccef], a
ld [wccf3], a
ld hl, wccf1
@@ -825,11 +847,11 @@ FaintEnemyPokemon ; 0x3c567
ld [hl], a
hlCoord 12, 5
deCoord 12, 6
- call Func_3c893
+ call SlideDownFaintedMonPic
ld hl, wTileMap
ld bc, $40b
call ClearScreenArea
- ld a, [W_ISINBATTLE] ; W_ISINBATTLE
+ ld a, [W_ISINBATTLE]
dec a
jr z, .wild_win
xor a
@@ -850,14 +872,14 @@ FaintEnemyPokemon ; 0x3c567
ld a, MUSIC_DEFEATED_WILD_MON
call PlayBattleVictoryMusic
.sfxplayed
- ld hl, wBattleMonHP ; wd015
+ ld hl, wBattleMonHP
ld a, [hli]
or [hl]
jr nz, .playermonnotfaint
ld a, [wccf0]
and a
jr nz, .playermonnotfaint
- call Func_3c741
+ call RemoveFaintedPlayerMon
.playermonnotfaint
call AnyPartyAlive
ld a, d
@@ -865,38 +887,50 @@ FaintEnemyPokemon ; 0x3c567
ret z
ld hl, EnemyMonFaintedText
call PrintText
- call Func_3ee94
+ call PrintEmptyString
call SaveScreenTilesToBuffer1
xor a
- ld [wcf0b], a
+ ld [wBattleResult], a
ld b, EXP__ALL
call IsItemInBag
push af
- jr z, .no_exp_all
- ld hl, wd002
+ jr z, .giveExpToMonsThatFought ; if no exp all, then jump
+
+; the player has exp all
+; first, we halve the values that determine exp gain
+; the enemy mon base stats are added to stat exp, so they are halved
+; the base exp (which determines normal exp) is also halved
+ ld hl, wEnemyMonBaseStats
ld b, $7
-.exp_all_loop
+.halveExpDataLoop
srl [hl]
inc hl
dec b
- jr nz, .exp_all_loop
-.no_exp_all
+ jr nz, .halveExpDataLoop
+
+; give exp (divided evenly) to the mons that actually fought in battle against the enemy mon that has fainted
+; if exp all is in the bag, this will be only be half of the stat exp and normal exp, due to the above loop
+.giveExpToMonsThatFought
xor a
ld [wcc5b], a
callab GainExperience
pop af
- ret z
+ ret z ; return if no exp all
+
+; the player has exp all
+; now, set the gain exp flag for every party member
+; half of the total stat exp and normal exp will divided evenly amongst every party member
ld a, $1
ld [wcc5b], a
- ld a, [wPartyCount] ; wPartyCount
- ld b, $0
-.asm_3c62c
+ ld a, [wPartyCount]
+ ld b, 0
+.gainExpFlagsLoop
scf
rl b
dec a
- jr nz, .asm_3c62c
+ jr nz, .gainExpFlagsLoop
ld a, b
- ld [wPartyAliveFlags], a
+ ld [wPartyGainExpFlags], a
ld hl, GainExperience
ld b, BANK(GainExperience)
jp Bankswitch
@@ -914,10 +948,10 @@ Func_3c643: ; 3c643 (f:4643)
ret
AnyEnemyPokemonAliveCheck: ; 3c64f (f:464f)
- ld a, [wEnemyPartyCount] ; wEnemyPartyCount
+ ld a, [wEnemyPartyCount]
ld b, a
xor a
- ld hl, wEnemyMon1HP ; wd8a5
+ ld hl, wEnemyMon1HP
ld de, $2c
.asm_3c65a
or [hl]
@@ -930,15 +964,17 @@ AnyEnemyPokemonAliveCheck: ; 3c64f (f:464f)
and a
ret
-Func_3c664: ; 3c664 (f:4664)
+; stores whether enemy ran in Z flag
+ReplaceFaintedEnemyMon: ; 3c664 (f:4664)
ld hl, wcf1e
ld e, $30
call GetBattleHealthBarColor
callab DrawEnemyPokeballs
- ld a, [W_ISLINKBATTLE] ; W_ISLINKBATTLE
+ ld a, [W_ISLINKBATTLE]
cp $4
jr nz, .asm_3c687
- call Func_3d605
+; link battle
+ call LinkBattleExchangeData
ld a, [wcc3e]
cp $f
ret z
@@ -946,43 +982,43 @@ Func_3c664: ; 3c664 (f:4664)
.asm_3c687
call EnemySendOut
xor a
- ld [W_ENEMYMOVENUM], a ; W_ENEMYMOVENUM
+ ld [W_ENEMYMOVENUM], a
ld [wcd6a], a
ld [wccd5], a
- inc a
+ inc a ; reset Z flag
ret
TrainerBattleVictory: ; 3c696 (f:4696)
call Func_3c643
ld b, MUSIC_DEFEATED_GYM_LEADER
- ld a, [W_GYMLEADERNO] ; W_GYMLEADERNO
+ ld a, [W_GYMLEADERNO]
and a
jr nz, .gymleader
ld b, MUSIC_DEFEATED_TRAINER
.gymleader
- ld a, [W_TRAINERCLASS] ; wd031
+ ld a, [W_TRAINERCLASS]
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] ; W_ISLINKBATTLE
+ ld a, [W_ISLINKBATTLE]
cp $4
ld a, b
call nz, PlayBattleVictoryMusic
ld hl, TrainerDefeatedText
call PrintText
- ld a, [W_ISLINKBATTLE] ; W_ISLINKBATTLE
+ ld a, [W_ISLINKBATTLE]
cp $4
ret z
call ScrollTrainerPicAfterBattle
ld c, $28
call DelayFrames
- call Func_3381
+ call PrintEndBattleText
ld hl, MoneyForWinningText
call PrintText
- ld de, wPlayerMoney + 2 ; wd349
+ ld de, wPlayerMoney + 2
ld hl, wd07b
ld c, $3
predef_jump AddBCDPredef
@@ -1008,41 +1044,44 @@ PlayBattleVictoryMusic: ; 3c6ee (f:46ee)
HandlePlayerMonFainted: ; 3c700 (f:4700)
ld a, $1
ld [wccf0], a
- call Func_3c741
+ call RemoveFaintedPlayerMon
call AnyPartyAlive ; test if any more mons are alive
ld a, d
and a
jp z, HandlePlayerBlackOut
- ld hl, wEnemyMonHP ; wEnemyMonHP
+ ld hl, wEnemyMonHP
ld a, [hli]
- or [hl]
- jr nz, .enemyMonNotFainted
+ or [hl] ; is enemy mon's HP 0?
+ jr nz, .doUseNextMonDialogue ; if not, jump
+; the enemy mon has 0 HP
call FaintEnemyPokemon
- ld a, [W_ISINBATTLE] ; W_ISINBATTLE
+ ld a, [W_ISINBATTLE]
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
+.doUseNextMonDialogue
+ call DoUseNextMonDialogue
+ ret c ; return if the player ran from battle
+ call ChooseNextMon
+ jp nz, MainInBattleLoop ; if the enemy mon has more than 0 HP, go back to battle loop
+; the enemy mon has 0 HP
ld a, $1
ld [wcd6a], a
- call Func_3c664
- jp z, asm_3c202
+ call ReplaceFaintedEnemyMon
+ jp z, EnemyRan ; if enemy ran from battle rather than sending out another mon, jump
xor a
ld [wcd6a], a
jp MainInBattleLoop
-Func_3c741: ; 3c741 (f:4741)
- ld a, [wPlayerMonNumber] ; wPlayerMonNumber
+; resets flags, slides mon's pic down, plays cry, and prints fainted message
+RemoveFaintedPlayerMon: ; 3c741 (f:4741)
+ ld a, [wPlayerMonNumber]
ld c, a
- ld hl, wPartyAliveFlags ; clear fainted mon's alive flag
+ ld hl, wPartyGainExpFlags
ld b, $0
- predef FlagActionPredef
- ld hl, W_ENEMYBATTSTATUS1 ; W_ENEMYBATTSTATUS1
+ predef FlagActionPredef ; clear gain exp flag for fainted mon
+ ld hl, W_ENEMYBATTSTATUS1
res 2, [hl] ; reset "attacking multiple times" flag
ld a, [wd083]
bit 7, a ; skip sound flag (red bar (?))
@@ -1054,16 +1093,16 @@ Func_3c741: ; 3c741 (f:4741)
ld hl, wcd05
ld [hli], a
ld [hl], a
- ld [wBattleMonStatus], a ; wBattleMonStatus
+ ld [wBattleMonStatus], a
call ReadPlayerMonCurHPAndStatus
hlCoord 9, 7
ld bc, $50b
call ClearScreenArea
hlCoord 1, 10
deCoord 1, 11
- call Func_3c893
+ call SlideDownFaintedMonPic
ld a, $1
- ld [wcf0b], a
+ ld [wBattleResult], a
ld a, [wccf0]
and a
ret z
@@ -1076,78 +1115,82 @@ PlayerMonFaintedText: ; 3c796 (f:4796)
TX_FAR _PlayerMonFaintedText
db "@"
-Func_3c79b: ; 3c79b (f:479b)
- call Func_3ee94
+; asks if you want to use next mon
+; stores whether you ran in C flag
+DoUseNextMonDialogue: ; 3c79b (f:479b)
+ call PrintEmptyString
call SaveScreenTilesToBuffer1
- ld a, [W_ISINBATTLE] ; W_ISINBATTLE
+ ld a, [W_ISINBATTLE]
and a
dec a
- ret nz
+ ret nz ; return if it's a trainer battle
ld hl, UseNextMonText
call PrintText
-.asm_3c7ad
+.displayYesNoBox
hlCoord 13, 9
ld bc, $a0e
- ld a, $14
+ ld a, $14 ; yes/no text box
ld [wd125], a
call DisplayTextBoxID
ld a, [wd12e]
- cp $2
- jr z, .asm_3c7c4
- and a
+ cp $2 ; did the player choose NO?
+ jr z, .tryRunning ; if the player chose NO, try running
+ and a ; reset carry
ret
-.asm_3c7c4
- ld a, [wCurrentMenuItem] ; wCurrentMenuItem
+.tryRunning
+ ld a, [wCurrentMenuItem]
and a
- jr z, .asm_3c7ad
+ jr z, .displayYesNoBox ; xxx when does this happen?
ld hl, wPartyMon1Speed
ld de, wEnemyMonSpeed
- jp Func_3cab9
+ jp TryRunningFromBattle
UseNextMonText: ; 3c7d3 (f:47d3)
TX_FAR _UseNextMonText
db "@"
-Func_3c7d8: ; 3c7d8 (f:47d8)
+; choose next player mon to send out
+; stores whether enemy mon has no HP left in Z flag
+ChooseNextMon: ; 3c7d8 (f:47d8)
ld a, $2
ld [wd07d], a
call DisplayPartyMenu
-.asm_3c7e0
- jr nc, .asm_3c7e7
-.asm_3c7e2
+.checkIfMonChosen
+ jr nc, .monChosen
+.goBackToPartyMenu
call GoBackToPartyMenu
- jr .asm_3c7e0
-.asm_3c7e7
- call Func_3ca97
- jr z, .asm_3c7e2
- ld a, [W_ISLINKBATTLE] ; W_ISLINKBATTLE
+ jr .checkIfMonChosen
+.monChosen
+ call HasMonFainted
+ jr z, .goBackToPartyMenu ; if mon fainted, you have to choose another
+ ld a, [W_ISLINKBATTLE]
cp $4
jr nz, .asm_3c7fa
inc a
ld [wcd6a], a
- call Func_3d605
+ call LinkBattleExchangeData
.asm_3c7fa
xor a
ld [wcd6a], a
call ClearSprites
- ld a, [wWhichPokemon] ; wWhichPokemon
- ld [wPlayerMonNumber], a ; wPlayerMonNumber
+ ld a, [wWhichPokemon]
+ ld [wPlayerMonNumber], a
ld c, a
- ld hl, wPartyAliveFlags
+ ld hl, wPartyGainExpFlags
ld b, $1
push bc
predef FlagActionPredef
pop bc
- ld hl, wccf5
+ ld hl, wPartyFoughtCurrentEnemyFlags
predef FlagActionPredef
- call Func_3cba6
+ call LoadBattleMonFromParty
call GBPalWhiteOut
- call Func_3ee5b
+ call LoadHudTilePatterns
call LoadScreenTilesFromBuffer1
call GoPAL_SET_CF1C
call GBPalNormal
- call Func_3cc91
- ld hl, wEnemyMonHP ; wEnemyMonHP
+ call SendOutMon
+ ld hl, wEnemyMonHP
ld a, [hli]
or [hl]
ret
@@ -1155,10 +1198,10 @@ Func_3c7d8: ; 3c7d8 (f:47d8)
; 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] ; W_ISLINKBATTLE
+ ld a, [W_ISLINKBATTLE]
cp $4
jr z, .notSony1Battle
- ld a, [W_CUROPPONENT] ; wd059
+ ld a, [W_CUROPPONENT]
cp $c8 + SONY1
jr nz, .notSony1Battle
ld hl, wTileMap ; sony 1 battle
@@ -1176,7 +1219,7 @@ HandlePlayerBlackOut: ; 3c837 (f:4837)
ld b, $0
call GoPAL_SET
ld hl, PlayerBlackedOutText2
- ld a, [W_ISLINKBATTLE] ; W_ISLINKBATTLE
+ ld a, [W_ISLINKBATTLE]
cp $4
jr nz, .noLinkBattle
ld hl, LinkBattleLostText
@@ -1201,18 +1244,20 @@ LinkBattleLostText: ; 3c88e (f:488e)
TX_FAR _LinkBattleLostText
db "@"
-Func_3c893: ; 3c893 (f:4893)
+; slides pic of fainted mon downwards until it disappears
+; bug: when this is called, [H_AUTOBGTRANSFERENABLED] is non-zero, so there is screen tearing
+SlideDownFaintedMonPic: ; 3c893 (f:4893)
ld a, [wd730]
push af
set 6, a
ld [wd730], a
- ld b, $7
-.asm_3c89e
+ ld b, 7 ; number of times to slide
+.slideStepLoop ; each iteration, the mon is slid down one row
push bc
push de
push hl
- ld b, $6
-.asm_3c8a3
+ ld b, 6 ; number of rows
+.rowLoop
push bc
push hl
push de
@@ -1220,7 +1265,7 @@ Func_3c893: ; 3c893 (f:4893)
call CopyData
pop de
pop hl
- ld bc, $ffec
+ ld bc, -20
add hl, bc
push hl
ld h, d
@@ -1231,18 +1276,18 @@ Func_3c893: ; 3c893 (f:4893)
pop hl
pop bc
dec b
- jr nz, .asm_3c8a3
- ld bc, $14
+ jr nz, .rowLoop
+ ld bc, 20
add hl, bc
ld de, SevenSpacesText
call PlaceString
- ld c, $2
+ ld c, 2
call DelayFrames
pop hl
pop de
pop bc
dec b
- jr nz, .asm_3c89e
+ jr nz, .slideStepLoop
pop af
ld [wd730], a
ret
@@ -1250,48 +1295,53 @@ Func_3c893: ; 3c893 (f:4893)
SevenSpacesText: ; 3c8d7 (f:48d7)
db " @"
-Func_3c8df: ; 3c8df (f:48df)
- ld [H_DOWNARROWBLINKCNT1], a ; $ff8b
+; slides the player or enemy trainer off screen
+; a is the number of tiles to slide it horizontally (always 9 for the player trainer or 8 for the enemy trainer)
+; if a is 8, the slide is to the right, else it is to the left
+; bug: when this is called, [H_AUTOBGTRANSFERENABLED] is non-zero, so there is screen tearing
+SlideTrainerPicOffScreen: ; 3c8df (f:48df)
+ ld [$FF8B], a
ld c, a
-.asm_3c8e2
+.slideStepLoop ; each iteration, the trainer pic is slid one tile left/right
push bc
push hl
- ld b, $7
-.asm_3c8e6
+ ld b, 7 ; number of rows
+.rowLoop
push hl
- ld a, [H_DOWNARROWBLINKCNT1] ; $ff8b
+ ld a, [$FF8B]
ld c, a
-.asm_3c8ea
- ld a, [H_DOWNARROWBLINKCNT1] ; $ff8b
- cp $8
- jr z, .asm_3c8f5
+.columnLoop
+ ld a, [$FF8B]
+ cp 8
+ jr z, .slideRight
+.slideLeft ; slide player sprite off screen
ld a, [hld]
ld [hli], a
inc hl
- jr .asm_3c8f8
-.asm_3c8f5
+ jr .nextColumn
+.slideRight ; slide enemy trainer sprite off screen
ld a, [hli]
ld [hld], a
dec hl
-.asm_3c8f8
+.nextColumn
dec c
- jr nz, .asm_3c8ea
+ jr nz, .columnLoop
pop hl
- ld de, $14
+ ld de, 20
add hl, de
dec b
- jr nz, .asm_3c8e6
- ld c, $2
+ jr nz, .rowLoop
+ ld c, 2
call DelayFrames
pop hl
pop bc
dec c
- jr nz, .asm_3c8e2
+ jr nz, .slideStepLoop
ret
-; XXX this needs cleaning up. it's what runs when a juggler switches pokemon
+; send out a trainer's mon
EnemySendOut: ; 3c90e (f:490e)
- ld hl,wPartyAliveFlags
+ ld hl,wPartyGainExpFlags
xor a
ld [hl],a
ld a,[wPlayerMonNumber]
@@ -1299,12 +1349,14 @@ EnemySendOut: ; 3c90e (f:490e)
ld b,1
push bc
predef FlagActionPredef
- ld hl,wccf5
+ ld hl,wPartyFoughtCurrentEnemyFlags
xor a
ld [hl],a
pop bc
predef FlagActionPredef
-Func_3c92a: ; 3c92a (f:492a)
+
+; don't change wPartyGainExpFlags or wPartyFoughtCurrentEnemyFlags
+EnemySendOutFirstMon: ; 3c92a (f:492a)
xor a
ld hl,wd065
ld [hli],a
@@ -1324,8 +1376,8 @@ Func_3c92a: ; 3c92a (f:492a)
res 5,[hl]
hlCoord 18, 0
ld a,8
- call Func_3c8df
- call Func_3ee94
+ call SlideTrainerPicOffScreen
+ call PrintEmptyString
call SaveScreenTilesToBuffer1
ld a,[W_ISLINKBATTLE]
cp 4
@@ -1370,7 +1422,7 @@ Func_3c92a: ; 3c92a (f:492a)
ld a,[hl]
ld [wEnemyMonSpecies2],a
ld [wcf91],a
- call Func_3eb01
+ call LoadEnemyMonData
ld hl,wEnemyMonHP
ld a,[hli]
ld [wcce3],a
@@ -1417,13 +1469,13 @@ Func_3c92a: ; 3c92a (f:492a)
call GoBackToPartyMenu
jr .next9
.next6
- call Func_3ca97
+ call HasMonFainted
jr z,.next8
xor a
ld [wCurrentMenuItem],a
.next7
call GBPalWhiteOut
- call Func_3ee5b
+ call LoadHudTilePatterns
call LoadScreenTilesFromBuffer1
.next4
call ClearSprites
@@ -1447,15 +1499,15 @@ Func_3c92a: ; 3c92a (f:492a)
predef Func_3f073
ld a,[wEnemyMonSpecies2]
call PlayCry
- call Func_3cdec
+ call DrawEnemyHUDAndHPBar
ld a,[wCurrentMenuItem]
and a
ret nz
xor a
- ld [wPartyAliveFlags],a
- ld [wccf5],a
+ ld [wPartyGainExpFlags],a
+ ld [wPartyFoughtCurrentEnemyFlags],a
call SaveScreenTilesToBuffer1
- jp Func_3d1ba
+ jp SwitchPlayerMon
TrainerAboutToUseText: ; 3ca79 (f:4a79)
TX_FAR _TrainerAboutToUseText
@@ -1468,10 +1520,10 @@ TrainerSentOutText: ; 3ca7e (f:4a7e)
; 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
AnyPartyAlive: ; 3ca83 (f:4a83)
- ld a, [wPartyCount] ; wPartyCount
+ ld a, [wPartyCount]
ld e, a
xor a
- ld hl, wPartyMon1HP ; wd16c
+ ld hl, wPartyMon1HP
ld bc, wPartyMon2 - wPartyMon1 - 1
.partyMonsLoop
or [hl]
@@ -1483,20 +1535,22 @@ AnyPartyAlive: ; 3ca83 (f:4a83)
ld d, a
ret
-Func_3ca97: ; 3ca97 (f:4a97)
- ld a, [wWhichPokemon] ; wWhichPokemon
- ld hl, wPartyMon1HP ; wd16c
- ld bc, $2c
+; tests if player mon has fainted
+; stores whether mon has fainted in Z flag
+HasMonFainted: ; 3ca97 (f:4a97)
+ ld a, [wWhichPokemon]
+ ld hl, wPartyMon1HP
+ ld bc, wPartyMon2 - wPartyMon1
call AddNTimes
ld a, [hli]
or [hl]
ret nz
ld a, [wd11d]
and a
- jr nz, .asm_3cab2
+ jr nz, .done
ld hl, NoWillText
call PrintText
-.asm_3cab2
+.done
xor a
ret
@@ -1504,116 +1558,122 @@ NoWillText: ; 3cab4 (f:4ab4)
TX_FAR _NoWillText
db "@"
-Func_3cab9: ; 3cab9 (f:4ab9)
+; try to run from battle (hl = player speed, de = enemy speed)
+; stores whether the attempt was successful in carry flag
+TryRunningFromBattle: ; 3cab9 (f:4ab9)
call IsGhostBattle
- jp z, .asm_3cb5c
- ld a, [W_BATTLETYPE] ; wd05a
+ jp z, .canEscape ; jump if it's a ghost battle
+ ld a, [W_BATTLETYPE]
cp $2
- jp z, .asm_3cb5c
- ld a, [W_ISLINKBATTLE] ; W_ISLINKBATTLE
+ jp z, .canEscape ; jump if it's a safari battle
+ ld a, [W_ISLINKBATTLE]
cp $4
- jp z, .asm_3cb5c
- ld a, [W_ISINBATTLE] ; W_ISINBATTLE
+ jp z, .canEscape
+ ld a, [W_ISINBATTLE]
dec a
- jr nz, .asm_3cb4c
- ld a, [wd120]
+ jr nz, .trainerBattle ; jump if it's a trainer battle
+ ld a, [wNumRunAttempts]
inc a
- ld [wd120], a
+ ld [wNumRunAttempts], a
ld a, [hli]
- ld [$ff97], a
+ ld [H_MULTIPLICAND + 1], a
ld a, [hl]
- ld [$ff98], a
+ ld [H_MULTIPLICAND + 2], a
ld a, [de]
ld [$ff8d], a
inc de
ld a, [de]
ld [$ff8e], a
call LoadScreenTilesFromBuffer1
- ld de, $ff97
+ ld de, H_MULTIPLICAND + 1
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)
+ jr nc, .canEscape ; jump if player speed greater than enemy speed
+ xor a
+ ld [H_MULTIPLICAND], a
+ ld a, 32
+ ld [H_MULTIPLIER], a
+ call Multiply ; multiply player speed by 32
+ ld a, [H_PRODUCT + 2]
+ ld [H_DIVIDEND], a
+ ld a, [H_PRODUCT + 3]
+ ld [H_DIVIDEND + 1], a
ld a, [$ff8d]
ld b, a
ld a, [$ff8e]
+; divide enemy speed by 4
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)
+ jr z, .canEscape ; jump if enemy speed divided by 4, mod 256 is 0
+ ld [H_DIVISOR], a ; ((enemy speed / 4) % 256)
ld b, $2
- call Divide
- ld a, [$ff97]
- and a
- jr nz, .asm_3cb5c
- ld a, [wd120]
+ call Divide ; divide (player speed * 32) by ((enemy speed / 4) % 256)
+ ld a, [H_QUOTIENT + 2]
+ and a ; is the quotient greater than 256?
+ jr nz, .canEscape ; if so, the player can escape
+ ld a, [wNumRunAttempts]
ld c, a
-.asm_3cb2b
+; add 30 to the quotient for each run attempt
+.loop
dec c
- jr z, .asm_3cb39
- ld b, $1e
- ld a, [$ff98]
+ jr z, .compareWithRandomValue
+ ld b, 30
+ ld a, [H_QUOTIENT + 3]
add b
- ld [$ff98], a
- jr c, .asm_3cb5c
- jr .asm_3cb2b
-.asm_3cb39
+ ld [H_QUOTIENT + 3], a
+ jr c, .canEscape
+ jr .loop
+.compareWithRandomValue
call BattleRandom
ld b, a
- ld a, [$ff98]
+ ld a, [H_QUOTIENT + 3]
cp b
- jr nc, .asm_3cb5c
+ jr nc, .canEscape ; if the random value was less than or equal to the quotient plus 30 times the number of attempts, the player can escape
+; can't escape
ld a, $1
ld [wcd6a], a
ld hl, CantEscapeText
- jr .asm_3cb4f
-.asm_3cb4c
+ jr .printCantEscapeOrNoRunningText
+.trainerBattle
ld hl, NoRunningText
-.asm_3cb4f
+.printCantEscapeOrNoRunningText
call PrintText
ld a, $1
ld [wd11f], a
call SaveScreenTilesToBuffer1
- and a
+ and a ; reset carry
ret
-.asm_3cb5c
- ld a, [W_ISLINKBATTLE] ; W_ISLINKBATTLE
+.canEscape
+ ld a, [W_ISLINKBATTLE]
cp $4
ld a, $2
- jr nz, .asm_3cb81
+ jr nz, .playSound
+; link battle
call SaveScreenTilesToBuffer1
xor a
ld [wcd6a], a
ld a, $f
- ld [wPlayerMoveListIndex], a ; wPlayerMoveListIndex
- call Func_3d605
+ ld [wPlayerMoveListIndex], a
+ call LinkBattleExchangeData
call LoadScreenTilesFromBuffer1
ld a, [wcc3e]
cp $f
ld a, $2
- jr z, .asm_3cb81
+ jr z, .playSound
dec a
-.asm_3cb81
- ld [wcf0b], a
+.playSound
+ ld [wBattleResult], a
ld a, (SFX_08_44 - SFX_Headers_08) / 3
call PlaySoundWaitForCurrent
ld hl, GotAwayText
call PrintText
call WaitForSoundToFinish
call SaveScreenTilesToBuffer1
- scf
+ scf ; set carry
ret
CantEscapeText: ; 3cb97 (f:4b97)
@@ -1628,10 +1688,11 @@ GotAwayText: ; 3cba1 (f:4ba1)
TX_FAR _GotAwayText
db "@"
-Func_3cba6: ; 3cba6 (f:4ba6)
- ld a, [wWhichPokemon] ; wWhichPokemon
+; copies from party data to battle mon data when sending out a new player mon
+LoadBattleMonFromParty: ; 3cba6 (f:4ba6)
+ ld a, [wWhichPokemon]
ld bc, $2c
- ld hl, wPartyMon1Species ; wPartyMon1Species (aliases: wPartyMon1)
+ ld hl, wPartyMon1Species
call AddNTimes
ld de, wBattleMonSpecies
ld bc, $c
@@ -1641,40 +1702,41 @@ Func_3cba6: ; 3cba6 (f:4ba6)
ld de, wBattleMonDVs
ld bc, $2
call CopyData
- ld de, wBattleMonPP ; wBattleMonPP
+ ld de, wBattleMonPP
ld bc, $4
call CopyData
- ld de, wBattleMonLevel ; wBattleMonLevel
+ ld de, wBattleMonLevel
ld bc, $b
call CopyData
ld a, [wBattleMonSpecies2]
ld [wd0b5], a
call GetMonHeader
- ld hl, wPartyMonNicks ; wPartyMonNicks
- ld a, [wPlayerMonNumber] ; wPlayerMonNumber
+ ld hl, wPartyMonNicks
+ ld a, [wPlayerMonNumber]
call SkipFixedLengthTextEntries
ld de, wBattleMonNick
ld bc, $b
call CopyData
- ld hl, wBattleMonLevel ; wBattleMonLevel
- ld de, wcd0f
+ ld hl, wBattleMonLevel
+ ld de, wPlayerMonUnmodifiedLevel ; block of memory used for unmodified stats
ld bc, $b
call CopyData
- call Func_3ed1a
- call Func_3ee19
- ld a, $7
+ call ApplyBurnAndParalysisPenaltiesToPlayer
+ call ApplyBadgeStatBoosts
+ ld a, $7 ; default stat modifier
ld b, $8
- ld hl, wPlayerMonAttackMod ; wcd1a
-.asm_3cc0e
+ ld hl, wPlayerMonAttackMod
+.statModLoop
ld [hli], a
dec b
- jr nz, .asm_3cc0e
+ jr nz, .statModLoop
ret
-Func_3cc13: ; 3cc13 (f:4c13)
- ld a, [wWhichPokemon] ; wWhichPokemon
+; copies from enemy party data to current enemy mon data when sending out a new enemy mon
+LoadEnemyMonFromParty: ; 3cc13 (f:4c13)
+ ld a, [wWhichPokemon]
ld bc, $2c
- ld hl, wEnemyMons ; wEnemyMon1Species
+ ld hl, wEnemyMons
call AddNTimes
ld de, wEnemyMonSpecies
ld bc, $c
@@ -1684,56 +1746,55 @@ Func_3cc13: ; 3cc13 (f:4c13)
ld de, wEnemyMonDVs
ld bc, $2
call CopyData
- ld de, wEnemyMonPP ; wcffe
+ ld de, wEnemyMonPP
ld bc, $4
call CopyData
- ld de, wEnemyMonLevel ; wEnemyMonLevel
+ ld de, wEnemyMonLevel
ld bc, $b
call CopyData
ld a, [wEnemyMonSpecies]
ld [wd0b5], a
call GetMonHeader
ld hl, wEnemyMonNicks
- ld a, [wWhichPokemon] ; wWhichPokemon
+ ld a, [wWhichPokemon]
call SkipFixedLengthTextEntries
ld de, wEnemyMonNick
ld bc, $b
call CopyData
- ld hl, wEnemyMonLevel ; wEnemyMonLevel
- ld de, wcd23
+ ld hl, wEnemyMonLevel
+ ld de, wEnemyMonUnmodifiedLevel ; block of memory used for unmodified stats
ld bc, $b
call CopyData
- call Func_3ed1e
+ call ApplyBurnAndParalysisPenaltiesToEnemy
ld hl, W_MONHBASESTATS
- ld de, wd002
+ ld de, wEnemyMonBaseStats
ld b, $5
-.asm_3cc79
+.copyBaseStatsLoop
ld a, [hli]
ld [de], a
inc de
dec b
- jr nz, .asm_3cc79
- ld a, $7
+ jr nz, .copyBaseStatsLoop
+ ld a, $7 ; default stat modifier
ld b, $8
- ld hl, wEnemyMonStatMods ; wcd2e
-.asm_3cc86
+ ld hl, wEnemyMonStatMods
+.statModLoop
ld [hli], a
dec b
- jr nz, .asm_3cc86
- ld a, [wWhichPokemon] ; wWhichPokemon
+ jr nz, .statModLoop
+ ld a, [wWhichPokemon]
ld [wEnemyMonPartyPos], a
ret
-Func_3cc91: ; 3cc91 (f:4c91)
- callab SendOutMon
- ld hl, wEnemyMonHP ; wEnemyMonHP
+SendOutMon: ; 3cc91 (f:4c91)
+ callab PrintSendOutMonMessage
+ ld hl, wEnemyMonHP
ld a, [hli]
- or [hl]
- jp z, Func_3cca4
- call Func_3cdec
-
-Func_3cca4: ; 3cca4 (f:4ca4)
- call Func_3cd60
+ or [hl] ; is enemy mon HP zero?
+ jp z, .skipDrawingEnemyHUDAndHPBar; if HP is zero, skip drawing the HUD and HP bar
+ call DrawEnemyHUDAndHPBar
+.skipDrawingEnemyHUDAndHPBar
+ call DrawPlayerHUDAndHPBar
predef LoadMonBackPic
xor a
ld [$ffe1], a
@@ -1742,7 +1803,7 @@ Func_3cca4: ; 3cca4 (f:4ca4)
ld [hl], a
ld [wcc5b], a
ld [wd05b], a
- ld [W_PLAYERMOVENUM], a ; wcfd2
+ ld [W_PLAYERMOVENUM], a
ld hl, wccf1
ld [hli], a
ld [hl], a
@@ -1752,25 +1813,26 @@ Func_3cca4: ; 3cca4 (f:4ca4)
ld [hli], a
ld [hli], a
ld [hl], a
- ld [W_PLAYERDISABLEDMOVE], a ; W_PLAYERDISABLEDMOVE
+ ld [W_PLAYERDISABLEDMOVE], a
ld [wccee], a
ld [wccf7], a
ld b, $1
call GoPAL_SET
- ld hl, W_ENEMYBATTSTATUS1 ; W_ENEMYBATTSTATUS1
+ ld hl, W_ENEMYBATTSTATUS1
res 5, [hl]
ld a, $1
- ld [H_WHOSETURN], a ; $fff3
+ ld [H_WHOSETURN], a
ld a, POOF_ANIM
call PlayMoveAnimation
hlCoord 4, 11
predef Func_3f073
ld a, [wcf91]
call PlayCry
- call Func_3ee94
+ call PrintEmptyString
jp SaveScreenTilesToBuffer1
-Func_3ccfa: ; 3ccfa (f:4cfa)
+; show 2 stages of the player getting smaller before disappearing
+AnimateRetreatingPlayerMon: ; 3ccfa (f:4cfa)
hlCoord 1, 5
ld bc, $707
call ClearScreenArea
@@ -1778,47 +1840,46 @@ Func_3ccfa: ; 3ccfa (f:4cfa)
ld bc, $505
xor a
ld [wcd6c], a
- ld [H_DOWNARROWBLINKCNT1], a ; $ff8b
+ ld [H_DOWNARROWBLINKCNT1], a
predef Func_79aba
ld c, $4
call DelayFrames
- call Func_3cd3a
+ call .clearScreenArea
hlCoord 4, 9
ld bc, $303
ld a, $1
ld [wcd6c], a
xor a
- ld [H_DOWNARROWBLINKCNT1], a ; $ff8b
+ ld [H_DOWNARROWBLINKCNT1], a
predef Func_79aba
call Delay3
- call Func_3cd3a
+ call .clearScreenArea
ld a, $4c
Coorda 5, 11
-
-Func_3cd3a: ; 3cd3a (f:4d3a)
+.clearScreenArea
hlCoord 1, 5
ld bc, $707
jp ClearScreenArea
; reads player's current mon's HP into wBattleMonHP
ReadPlayerMonCurHPAndStatus: ; 3cd43 (f:4d43)
- ld a, [wPlayerMonNumber] ; wPlayerMonNumber
- ld hl, wPartyMon1HP ; wd16c
+ ld a, [wPlayerMonNumber]
+ ld hl, wPartyMon1HP
ld bc, wPartyMon2 - wPartyMon1
call AddNTimes
ld d, h
ld e, l
- ld hl, wBattleMonHP ; wd015
+ ld hl, wBattleMonHP
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
+DrawHUDsAndHPBars: ; 3cd5a (f:4d5a)
+ call DrawPlayerHUDAndHPBar
+ jp DrawEnemyHUDAndHPBar
-Func_3cd60: ; 3cd60 (f:4d60)
+DrawPlayerHUDAndHPBar: ; 3cd60 (f:4d60)
xor a
- ld [H_AUTOBGTRANSFERENABLED], a ; $ffba
+ ld [H_AUTOBGTRANSFERENABLED], a
hlCoord 9, 7
ld bc, $50b
call ClearScreenArea
@@ -1827,13 +1888,13 @@ Func_3cd60: ; 3cd60 (f:4d60)
ld [hl], $73
ld de, wBattleMonNick
hlCoord 10, 7
- call Func_3ce9c
+ call CenterMonName
call PlaceString
ld hl, wBattleMonSpecies
ld de, wcf98
ld bc, $c
call CopyData
- ld hl, wBattleMonLevel ; wBattleMonLevel
+ ld hl, wBattleMonLevel
ld de, wcfb9
ld bc, $b
call CopyData
@@ -1851,10 +1912,10 @@ Func_3cd60: ; 3cd60 (f:4d60)
hlCoord 10, 9
predef DrawHP
ld a, $1
- ld [H_AUTOBGTRANSFERENABLED], a ; $ffba
+ ld [H_AUTOBGTRANSFERENABLED], a
ld hl, wcf1d
call GetBattleHealthBarColor
- ld hl, wBattleMonHP ; wd015
+ ld hl, wBattleMonHP
ld a, [hli]
or [hl]
jr z, .asm_3cdd9
@@ -1877,90 +1938,94 @@ Func_3cd60: ; 3cd60 (f:4d60)
set 7, [hl]
ret
-Func_3cdec: ; 3cdec (f:4dec)
+DrawEnemyHUDAndHPBar: ; 3cdec (f:4dec)
xor a
- ld [H_AUTOBGTRANSFERENABLED], a ; $ffba
+ ld [H_AUTOBGTRANSFERENABLED], a
ld hl, wTileMap
ld bc, $40c
call ClearScreenArea
callab PlaceEnemyHUDTiles
ld de, wEnemyMonNick
hlCoord 1, 0
- call Func_3ce9c
+ call CenterMonName
call PlaceString
hlCoord 4, 1
push hl
inc hl
- ld de, wEnemyMonStatus ; wcfe9
+ ld de, wEnemyMonStatus
call PrintStatusConditionNotFainted
pop hl
- jr nz, .asm_3ce23
- ld a, [wEnemyMonLevel] ; wEnemyMonLevel
+ jr nz, .skipPrintLevel ; if the mon has a status condition, skip printing the level
+ ld a, [wEnemyMonLevel]
ld [wcfb9], a
call PrintLevel
-.asm_3ce23
- ld hl, wEnemyMonHP ; wEnemyMonHP
+.skipPrintLevel
+ ld hl, wEnemyMonHP
ld a, [hli]
- ld [$ff97], a
+ ld [H_MULTIPLICAND + 1], a
ld a, [hld]
- ld [$ff98], a
- or [hl]
- jr nz, .asm_3ce36
+ ld [H_MULTIPLICAND + 2], a
+ or [hl] ; is current HP zero?
+ jr nz, .hpNonzero
+; current HP is 0
+; set variables for DrawHPBar
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, wEnemyMonMaxHP ; wEnemyMonMaxHP
+ jp .drawHPBar
+.hpNonzero
+ xor a
+ ld [H_MULTIPLICAND], a
+ ld a, 48
+ ld [H_MULTIPLIER], a
+ call Multiply ; multiply current HP by 48
+ ld hl, wEnemyMonMaxHP
ld a, [hli]
ld b, a
ld a, [hl]
- ld [H_REMAINDER], a ; $ff99 (aliases: H_DIVISOR, H_MULTIPLIER, H_POWEROFTEN)
+ ld [H_DIVISOR], a
ld a, b
- and a
- jr z, .asm_3ce6a
- ld a, [H_REMAINDER] ; $ff99 (aliases: H_DIVISOR, H_MULTIPLIER, H_POWEROFTEN)
+ and a ; is max HP > 255?
+ jr z, .doDivide
+; if max HP > 255, scale both (current HP * 48) and max HP by dividing by 4 so that max HP fits in one byte
+; (it needs to be one byte so it can be used as the divisor for the Divide function)
+ ld a, [H_DIVISOR]
srl b
rr a
srl b
rr a
- ld [H_REMAINDER], a ; $ff99 (aliases: H_DIVISOR, H_MULTIPLIER, H_POWEROFTEN)
- ld a, [$ff97]
+ ld [H_DIVISOR], a
+ ld a, [H_PRODUCT + 2]
ld b, a
srl b
- ld a, [$ff98]
+ ld a, [H_PRODUCT + 3]
rr a
srl b
rr a
- ld [$ff98], a
+ ld [H_PRODUCT + 3], 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 [H_PRODUCT + 2], a
+.doDivide
+ ld a, [H_PRODUCT + 2]
+ ld [H_DIVIDEND], a
+ ld a, [H_PRODUCT + 3]
+ ld [H_DIVIDEND + 1], a
ld a, $2
ld b, a
- call Divide
- ld a, [$ff98]
+ call Divide ; divide (current HP * 48) by max HP
+ ld a, [H_QUOTIENT + 3]
+; set variables for DrawHPBar
ld e, a
ld a, $6
ld d, a
ld c, a
-
-Func_3ce7f: ; 3ce7f (f:4e7f)
+.drawHPBar
xor a
- ld [wListMenuID], a ; wListMenuID
+ ld [wListMenuID], a
hlCoord 2, 2
call DrawHPBar
ld a, $1
- ld [H_AUTOBGTRANSFERENABLED], a ; $ffba
+ ld [H_AUTOBGTRANSFERENABLED], a
ld hl, wcf1e
GetBattleHealthBarColor: ; 3ce90 (f:4e90)
@@ -1972,37 +2037,40 @@ GetBattleHealthBarColor: ; 3ce90 (f:4e90)
ld b, $1
jp GoPAL_SET
-Func_3ce9c: ; 3ce9c (f:4e9c)
+; center's mon's name on the battle screen
+; if the name is 1 or 2 letters long, it is printed 2 spaces more to the right than usual (i.e. for names longer than 4 letters)
+; if the name is 3 or 4 letters long, it is printed 1 space more to the right than usual (i.e. for names longer than 4 letters)
+CenterMonName: ; 3ce9c (f:4e9c)
push de
inc hl
inc hl
ld b, $2
-.asm_3cea1
+.loop
inc de
ld a, [de]
cp $50
- jr z, .asm_3ceb1
+ jr z, .done
inc de
ld a, [de]
cp $50
- jr z, .asm_3ceb1
+ jr z, .done
dec hl
dec b
- jr nz, .asm_3cea1
-.asm_3ceb1
+ jr nz, .loop
+.done
pop de
ret
-InitBattleMenu: ; 3ceb3 (f:4eb3)
+DisplayBattleMenu: ; 3ceb3 (f:4eb3)
call LoadScreenTilesFromBuffer1 ; restore saved screen
- ld a, [W_BATTLETYPE] ; wd05a
+ ld a, [W_BATTLETYPE]
and a
jr nz, .nonstandardbattle
- call Func_3cd5a ; redraw names and HP bars?
- call Func_3ee94
+ call DrawHUDsAndHPBars
+ call PrintEmptyString
call SaveScreenTilesToBuffer1
.nonstandardbattle
- ld a, [W_BATTLETYPE] ; wd05a
+ ld a, [W_BATTLETYPE]
cp $2 ; safari
ld a, $b ; safari menu id
jr nz, .menuselected
@@ -2010,20 +2078,20 @@ InitBattleMenu: ; 3ceb3 (f:4eb3)
.menuselected
ld [wd125], a
call DisplayTextBoxID
- ld a, [W_BATTLETYPE] ; wd05a
+ ld a, [W_BATTLETYPE]
dec a
- jp nz, RegularBattleMenu ; regular battle
- ; the following happens for the old man tutorial
- ld hl, wPlayerName ; wd158
- ld de, W_GRASSRATE ; W_GRASSRATE
+ jp nz, .handleBattleMenuInput ; handle menu input if it's not the old man tutorial
+; the following happens for the old man tutorial
+ ld hl, wPlayerName
+ ld de, W_GRASSRATE
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, wPlayerName ; wd158
+ ld hl, .oldManName
+ ld de, wPlayerName
ld bc, $b
call CopyData
; the following simulates the keystrokes by drawing menus on screen
@@ -2037,178 +2105,198 @@ InitBattleMenu: ; 3ceb3 (f:4eb3)
ld c, $32
call DelayFrames
ld [hl], $ec
- ld a, $2
- jp Func_3cfe8
-
-OldManName: ; 3cf12 (f:4f12)
+ ld a, $2 ; select the "ITEM" menu
+ jp .upperLeftMenuItemWasNotSelected
+.oldManName
db "OLD MAN@"
-
-RegularBattleMenu: ; 3cf1a (f:4f1a)
+.handleBattleMenuInput
ld a, [wcc2d]
- ld [wCurrentMenuItem], a ; wCurrentMenuItem
- ld [wLastMenuItem], a ; wLastMenuItem
- sub $2
- jr c, .leftcolumn
- ld [wCurrentMenuItem], a ; wCurrentMenuItem
- ld [wLastMenuItem], a ; wLastMenuItem
- jr .rightcolumn
-.leftcolumn
- ld a, [W_BATTLETYPE] ; wd05a
+ ld [wCurrentMenuItem], a
+ ld [wLastMenuItem], a
+ sub 2 ; check if the cursor is in the left column
+ jr c, .leftColumn
+; cursor is in the right column
+ ld [wCurrentMenuItem], a
+ ld [wLastMenuItem], a
+ jr .rightColumn
+.leftColumn ; put cursor in left column of menu
+ ld a, [W_BATTLETYPE]
cp $2
ld a, " "
- jr z, .safaribattle
- Coorda 15, 14
- Coorda 15, 16
- ld b, $9
- jr .notsafari
-.safaribattle
+ jr z, .safariLeftColumn
+; put cursor in left column for normal battle menu (i.e. when it's not a Safari battle)
+ Coorda 15, 14 ; clear upper cursor position in right column
+ Coorda 15, 16 ; clear lower cursor position in right column
+ ld b, $9 ; top menu item X
+ jr .leftColumn_WaitForInput
+.safariLeftColumn
Coorda 13, 14
Coorda 13, 16
hlCoord 7, 14
- ld de, W_NUMSAFARIBALLS ; W_NUMSAFARIBALLS
+ ld de, W_NUMSAFARIBALLS
ld bc, $102
call PrintNumber
- ld b, $1
-.notsafari
- ld hl, wTopMenuItemY ; wTopMenuItemY
+ ld b, $1 ; top menu item X
+.leftColumn_WaitForInput
+ ld hl, wTopMenuItemY
ld a, $e
- ld [hli], a
+ ld [hli], a ; wTopMenuItemY
ld a, b
- ld [hli], a
+ ld [hli], a ; wTopMenuItemX
inc hl
inc hl
ld a, $1
- ld [hli], a
- ld [hl], $11
+ ld [hli], a ; wMaxMenuItem
+ ld [hl], D_RIGHT | A_BUTTON ; wMenuWatchedKeys
call HandleMenuInput
- bit 4, a
- jr nz, .rightcolumn
- jr .selection
-.rightcolumn
- ld a, [W_BATTLETYPE] ; wd05a
+ bit 4, a ; check if right was pressed
+ jr nz, .rightColumn
+ jr .AButtonPressed ; the A button was pressed
+.rightColumn ; put cursor in right column of menu
+ ld a, [W_BATTLETYPE]
cp $2
ld a, " "
- jr z, .safarirightcolumn
- Coorda 9, 14
- Coorda 9, 16
- ld b, $f
- jr .notsafarirightcolumn
-.safarirightcolumn
- Coorda 1, 14
- Coorda 1, 16
+ jr z, .safariRightColumn
+; put cursor in right column for normal battle menu (i.e. when it's not a Safari battle)
+ Coorda 9, 14 ; clear upper cursor position in left column
+ Coorda 9, 16 ; clear lower cursor position in left column
+ ld b, $f ; top menu item X
+ jr .rightColumn_WaitForInput
+.safariRightColumn
+ Coorda 1, 14 ; clear upper cursor position in left column
+ Coorda 1, 16 ; clear lower cursor position in left column
hlCoord 7, 14
- ld de, W_NUMSAFARIBALLS ; W_NUMSAFARIBALLS
+ ld de, W_NUMSAFARIBALLS
ld bc, $102
call PrintNumber
- ld b, $d
-.notsafarirightcolumn
- ld hl, wTopMenuItemY ; wTopMenuItemY
+ ld b, $d ; top menu item X
+.rightColumn_WaitForInput
+ ld hl, wTopMenuItemY
ld a, $e
- ld [hli], a
+ ld [hli], a ; wTopMenuItemY
ld a, b
- ld [hli], a
+ ld [hli], a ; wTopMenuItemX
inc hl
inc hl
ld a, $1
- ld [hli], a
- ld a, $21
- ld [hli], a
+ ld [hli], a ; wMaxMenuItem
+ ld a, D_LEFT | A_BUTTON
+ ld [hli], a ; wMenuWatchedKeys
call HandleMenuInput
- bit 5, a
- jr nz, .leftcolumn
- ld a, [wCurrentMenuItem] ; wCurrentMenuItem
+ bit 5, a ; check if left was pressed
+ jr nz, .leftColumn ; if left was pressed, jump
+ ld a, [wCurrentMenuItem]
add $2 ; if we're in the right column, the actual id is +2
- ld [wCurrentMenuItem], a ; wCurrentMenuItem
-.selection
+ ld [wCurrentMenuItem], a
+.AButtonPressed
call PlaceUnfilledArrowMenuCursor
- ld a, [W_BATTLETYPE] ; wd05a
- cp $2
- ld a, [wCurrentMenuItem] ; wCurrentMenuItem
+ ld a, [W_BATTLETYPE]
+ cp $2 ; is it a Safari battle?
+ ld a, [wCurrentMenuItem]
ld [wcc2d], 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] ; wd05a
+ jr z, .handleMenuSelection
+; not Safari battle
+; swap the IDs of the item menu and party menu (this is probably because they swapped the positions of these menu items in first generation English versions)
+ cp $1 ; was the item menu selected?
+ jr nz, .notItemMenu
+; item menu was selected
+ inc a ; increment a to 2
+ jr .handleMenuSelection
+.notItemMenu
+ cp $2 ; was the party menu selected?
+ jr nz, .handleMenuSelection
+; party menu selected
+ dec a ; decrement a to 1
+.handleMenuSelection
+ and a
+ jr nz, .upperLeftMenuItemWasNotSelected
+; the upper left menu item was selected
+ ld a, [W_BATTLETYPE]
cp $2
- jr z, .safari1
+ jr z, .throwSafariBallWasSelected
+; the "FIGHT" menu was selected
xor a
- ld [wd120], a
- jp LoadScreenTilesFromBuffer1 ; restore saved screen and return??
-.safari1 ; safari first option??
+ ld [wNumRunAttempts], a
+ jp LoadScreenTilesFromBuffer1 ; restore saved screen and return
+.throwSafariBallWasSelected
ld a, SAFARI_BALL
ld [wcf91], a
- jr asm_3d05f
+ jr UseBagItem
-Func_3cfe8: ; 3cfe8 (f:4fe8)
+.upperLeftMenuItemWasNotSelected ; a menu item other than the upper left item was selected
cp $2
- jp nz, Func_3d0ca
- ld a, [W_ISLINKBATTLE] ; W_ISLINKBATTLE
+ jp nz, PartyMenuOrRockOrRun
+
+; either the bag (normal battle) or bait (safari battle) was selected
+ ld a, [W_ISLINKBATTLE]
cp $4
- jr nz, .asm_3cffd
+ jr nz, .notLinkBattle
+
+; can't use items in link battles
ld hl, ItemsCantBeUsedHereText
call PrintText
- jp InitBattleMenu
-.asm_3cffd ; bag?
- call SaveScreenTilesToBuffer2 ; copy bg?
- ld a, [W_BATTLETYPE] ; wd05a
- cp $2
- jr nz, asm_3d00e
+ jp DisplayBattleMenu
+
+.notLinkBattle
+ call SaveScreenTilesToBuffer2
+ ld a, [W_BATTLETYPE]
+ cp $2 ; is it a safari battle?
+ jr nz, BagWasSelected
+
+; bait was selected
ld a, SAFARI_BAIT
ld [wcf91], a
- jr asm_3d05f
-asm_3d00e: ; 3d00e (f:500e)
+ jr UseBagItem
+
+BagWasSelected:
call LoadScreenTilesFromBuffer1
- ld a, [W_BATTLETYPE] ; wd05a
- and a
- jr nz, .asm_3d01a
- call Func_3cd5a
-.asm_3d01a
- ld a, [W_BATTLETYPE] ; wd05a
- dec a
- jr nz, Func_3d031
+ ld a, [W_BATTLETYPE]
+ and a ; is it a normal battle?
+ jr nz, .next
+
+; normal battle
+ call DrawHUDsAndHPBars
+.next
+ ld a, [W_BATTLETYPE]
+ dec a ; is it the old man tutorial?
+ jr nz, DisplayPlayerBag ; no, it is a normal battle
ld hl, OldManItemList
ld a, l
ld [wcf8b], a
ld a, h
ld [wcf8c], a
- jr Func_3d03c
+ jr DisplayBagMenu
-OldManItemList: ; 3d02d (f:502d)
+OldManItemList:
db 1 ; # items
db POKE_BALL, 50
db -1
-Func_3d031
- ld hl, wNumBagItems ; wNumBagItems
+DisplayPlayerBag:
+ ; get the pointer to player's bag when in a normal battle
+ ld hl, wNumBagItems
ld a, l
ld [wcf8b], a
ld a, h
ld [wcf8c], a
-Func_3d03c
+
+DisplayBagMenu:
xor a
ld [wcf93], a
- ld a, $3
- ld [wListMenuID], a ; wListMenuID
+ ld a, ITEMLISTMENU
+ ld [wListMenuID], a
ld a, [wcc2c]
- ld [wCurrentMenuItem], a ; wCurrentMenuItem
+ ld [wCurrentMenuItem], a
call DisplayListMenuID
- ld a, [wCurrentMenuItem] ; wCurrentMenuItem
+ ld a, [wCurrentMenuItem]
ld [wcc2c], a
ld a, $0
ld [wcc37], a
- ld [wcc35], a
- jp c, InitBattleMenu
-asm_3d05f: ; 3d05f (f:505f)
+ ld [wMenuItemToSwap], a
+ jp c, DisplayBattleMenu ; go back to battle menu if an item was not selected
+
+UseBagItem:
+ ; either use an item from the bag or use a safari zone item
ld a, [wcf91]
ld [wd11e], a
call GetItemName
@@ -2216,80 +2304,87 @@ asm_3d05f: ; 3d05f (f:505f)
xor a
ld [wd152], a
call UseItem
- call Func_3ee5b
+ call LoadHudTilePatterns
call ClearSprites
xor a
- ld [wCurrentMenuItem], a ; wCurrentMenuItem
- ld a, [W_BATTLETYPE] ; wd05a
- cp $2
- jr z, .asm_3d09c
+ ld [wCurrentMenuItem], a
+ ld a, [W_BATTLETYPE]
+ cp $2 ; is it a safari battle?
+ jr z, .checkIfMonCaptured
+
ld a, [wcd6a]
- and a
- jp z, asm_3d00e
- ld a, [W_PLAYERBATTSTATUS1] ; W_PLAYERBATTSTATUS1
- bit 5, a
- jr z, .asm_3d09c
- ld hl, wd06a
+ and a ; was the item used successfully?
+ jp z, BagWasSelected ; if not, go back to the bag menu
+
+ ld a, [W_PLAYERBATTSTATUS1]
+ bit 5, a ; is the player using a multi-turn move like wrap?
+ jr z, .checkIfMonCaptured
+ ld hl, wPlayerNumAttacksLeft
dec [hl]
- jr nz, .asm_3d09c
- ld hl, W_PLAYERBATTSTATUS1 ; W_PLAYERBATTSTATUS1
- res 5, [hl]
-.asm_3d09c
+ jr nz, .checkIfMonCaptured
+ ld hl, W_PLAYERBATTSTATUS1
+ res 5, [hl] ; not using multi-turn move any more
+
+.checkIfMonCaptured
ld a, [wd11c]
- and a
- jr nz, .asm_3d0b7
- ld a, [W_BATTLETYPE] ; wd05a
- cp $2
- jr z, .asm_3d0b2
+ and a ; was the enemy mon captured with a ball?
+ jr nz, .returnAfterCapturingMon
+
+ ld a, [W_BATTLETYPE]
+ cp $2 ; is it a safari battle?
+ jr z, .returnAfterUsingItem_NoCapture
+; not a safari battle
call LoadScreenTilesFromBuffer1
- call Func_3cd5a ; redraw name and hp bar?
+ call DrawHUDsAndHPBars
call Delay3
-.asm_3d0b2
+.returnAfterUsingItem_NoCapture
+
call GBPalNormal
- and a
+ and a ; reset carry
ret
-.asm_3d0b7
+
+.returnAfterCapturingMon
call GBPalNormal
xor a
ld [wd11c], a
ld a, $2
- ld [wcf0b], a
- scf
+ ld [wBattleResult], a
+ scf ; set carry
ret
-ItemsCantBeUsedHereText: ; 3d0c5 (f:50c5)
+ItemsCantBeUsedHereText:
TX_FAR _ItemsCantBeUsedHereText
db "@"
-Func_3d0ca: ; 3d0ca (f:50ca)
- dec a
- jp nz, Func_3d1fa
+PartyMenuOrRockOrRun:
+ dec a ; was Run selected?
+ jp nz, BattleMenu_RunWasSelected
+; party menu or rock was selected
call SaveScreenTilesToBuffer2
- ld a, [W_BATTLETYPE] ; wd05a
- cp $2
- jr nz, Func_3d0e0
+ ld a, [W_BATTLETYPE]
+ cp $2 ; is it a safari battle?
+ jr nz, .partyMenuWasSelected
+; safari battle
ld a, SAFARI_ROCK
ld [wcf91], a
- jp asm_3d05f
-
-Func_3d0e0: ; 3d0e0 (f:50e0)
+ jp UseBagItem
+.partyMenuWasSelected
call LoadScreenTilesFromBuffer1
xor a
ld [wd07d], a
- ld [wcc35], a
+ ld [wMenuItemToSwap], a
call DisplayPartyMenu
-asm_3d0ed: ; 3d0ed (f:50ed)
- jp nc, Func_3d119
-asm_3d0f0: ; 3d0f0 (f:50f0)
+.checkIfPartyMonWasSelected
+ jp nc, .partyMonWasSelected ; if a party mon was selected, jump, else we quit the party menu
+.quitPartyMenu
call ClearSprites
call GBPalWhiteOut
- call Func_3ee5b
+ call LoadHudTilePatterns
call LoadScreenTilesFromBuffer2
call GoPAL_SET_CF1C
call GBPalNormal
- jp InitBattleMenu
-
-Func_3d105: ; 3d105 (f:5105)
+ jp DisplayBattleMenu
+.partyMonDeselected
hlCoord 11, 11
ld bc, $81
ld a, $7f
@@ -2297,101 +2392,108 @@ Func_3d105: ; 3d105 (f:5105)
xor a
ld [wd07d], a
call GoBackToPartyMenu
- jr asm_3d0ed
-
-Func_3d119: ; 3d119 (f:5119)
- ld a, $c
+ jr .checkIfPartyMonWasSelected
+.partyMonWasSelected
+ ld a, $c ; switch/stats/cancel menu
ld [wd125], a
call DisplayTextBoxID
- ld hl, wTopMenuItemY ; wTopMenuItemY
+ ld hl, wTopMenuItemY
ld a, $c
- ld [hli], a
- ld [hli], a
+ ld [hli], a ; wTopMenuItemY
+ ld [hli], a ; wTopMenuItemX
xor a
- ld [hli], a
+ ld [hli], a ; wCurrentMenuItem
inc hl
ld a, $2
- ld [hli], a
- ld a, $3
- ld [hli], a
+ ld [hli], a ; wMaxMenuItem
+ ld a, B_BUTTON | A_BUTTON
+ ld [hli], a ; wMenuWatchedKeys
xor a
- ld [hl], a
+ ld [hl], a ; wLastMenuItem
call HandleMenuInput
- bit 1, a
- jr nz, Func_3d105
+ bit 1, a ; was A pressed?
+ jr nz, .partyMonDeselected ; if B was pressed, jump
+; A was pressed
call PlaceUnfilledArrowMenuCursor
- ld a, [wCurrentMenuItem] ; wCurrentMenuItem
- cp $2
- jr z, asm_3d0f0
- and a
- jr z, .asm_3d18a
+ ld a, [wCurrentMenuItem]
+ cp $2 ; was Cancel selected?
+ jr z, .quitPartyMenu ; if so, quit the party menu entirely
+ and a ; was Switch selected?
+ jr z, .switchMon ; if so, jump
+; Stats was selected
xor a
ld [wcc49], a
- ld hl, wPartyMon1Species ; wPartyMon1Species (aliases: wPartyMon1)
+ ld hl, wPartyMon1
call ClearSprites
+; display the two status screens
predef StatusScreen
predef StatusScreen2
- ld a, [W_ENEMYBATTSTATUS2] ; W_ENEMYBATTSTATUS2
- bit 4, a
+; now we need to reload the enemy mon pic
+ ld a, [W_ENEMYBATTSTATUS2]
+ bit 4, a ; does the enemy mon have a substitute?
ld hl, AnimationSubstitute
- jr nz, .asm_3d182
+ jr nz, .doEnemyMonAnimation
+; enemy mon doesn't have substitute
ld a, [wccf3]
- and a
+ and a ; has the enemy mon used Minimise?
ld hl, AnimationMinimizeMon
- jr nz, .asm_3d182
+ jr nz, .doEnemyMonAnimation
+; enemy mon is not minimised
ld a, [wEnemyMonSpecies]
ld [wcf91], a
ld [wd0b5], a
call GetMonHeader
ld de, vFrontPic
call LoadMonFrontSprite
- jr .asm_3d187
-.asm_3d182
+ jr .enemyMonPicReloaded
+.doEnemyMonAnimation
ld b, BANK(AnimationSubstitute) ; BANK(AnimationMinimizeMon)
call Bankswitch
-.asm_3d187
- jp Func_3d0e0
-.asm_3d18a
- ld a, [wPlayerMonNumber] ; wPlayerMonNumber
+.enemyMonPicReloaded ; enemy mon pic has been reloaded, so return to the party menu
+ jp .partyMenuWasSelected
+.switchMon
+ ld a, [wPlayerMonNumber]
ld d, a
- ld a, [wWhichPokemon] ; wWhichPokemon
- cp d
- jr nz, .asm_3d19d
+ ld a, [wWhichPokemon]
+ cp d ; check if the mon to switch to is already out
+ jr nz, .notAlreadyOut
+; mon is already out
ld hl, AlreadyOutText
call PrintText
- jp Func_3d105
-.asm_3d19d
- call Func_3ca97
- jp z, Func_3d105
+ jp .partyMonDeselected
+.notAlreadyOut
+ call HasMonFainted
+ jp z, .partyMonDeselected ; can't switch to fainted mon
ld a, $1
ld [wcd6a], a
call GBPalWhiteOut
call ClearSprites
- call Func_3ee5b
+ call LoadHudTilePatterns
call LoadScreenTilesFromBuffer1
call GoPAL_SET_CF1C
call GBPalNormal
+; fall through to SwitchPlayerMon
-Func_3d1ba: ; 3d1ba (f:51ba)
+SwitchPlayerMon: ; 3d1ba (f:51ba)
callab RetreatMon
ld c, $32
call DelayFrames
- call Func_3ccfa
- ld a, [wWhichPokemon] ; wWhichPokemon
- ld [wPlayerMonNumber], a ; wPlayerMonNumber
+ call AnimateRetreatingPlayerMon
+ ld a, [wWhichPokemon]
+ ld [wPlayerMonNumber], a
ld c, a
ld b, $1
push bc
- ld hl, wPartyAliveFlags
+ ld hl, wPartyGainExpFlags
predef FlagActionPredef
pop bc
- ld hl, wccf5
+ ld hl, wPartyFoughtCurrentEnemyFlags
predef FlagActionPredef
- call Func_3cba6
- call Func_3cc91
+ call LoadBattleMonFromParty
+ call SendOutMon
call SaveScreenTilesToBuffer1
ld a, $2
- ld [wCurrentMenuItem], a ; wCurrentMenuItem
+ ld [wCurrentMenuItem], a
and a
ret
@@ -2399,20 +2501,20 @@ AlreadyOutText: ; 3d1f5 (f:51f5)
TX_FAR _AlreadyOutText
db "@"
-Func_3d1fa: ; 3d1fa (f:51fa)
+BattleMenu_RunWasSelected: ; 3d1fa (f:51fa)
call LoadScreenTilesFromBuffer1
ld a, $3
- ld [wCurrentMenuItem], a ; wCurrentMenuItem
+ ld [wCurrentMenuItem], a
ld hl, wBattleMonSpeed
ld de, wEnemyMonSpeed
- call Func_3cab9
+ call TryRunningFromBattle
ld a, $0
ld [wd11f], a
ret c
ld a, [wcd6a]
and a
ret nz
- jp InitBattleMenu
+ jp DisplayBattleMenu
MoveSelectionMenu: ; 3d219 (f:5219)
ld a, [wMoveMenuType]
@@ -2473,8 +2575,8 @@ MoveSelectionMenu: ; 3d219 (f:5219)
ld a, $7
jr .menuset
.relearnmenu
- ld a, [wWhichPokemon] ; wWhichPokemon
- ld hl, wPartyMon1Moves ; wPartyMon1Moves
+ ld a, [wWhichPokemon]
+ ld hl, wPartyMon1Moves
ld bc, $2c
call AddNTimes
call .loadmoves
@@ -2487,24 +2589,24 @@ MoveSelectionMenu: ; 3d219 (f:5219)
ld b, $5
ld a, $7
.menuset
- ld hl, wTopMenuItemY ; wTopMenuItemY
+ ld hl, wTopMenuItemY
ld [hli], a
ld a, b
- ld [hli], a ; wTopMenuItemX
+ ld [hli], a
ld a, [wMoveMenuType]
cp $1
jr z, .selectedmoveknown
ld a, $1
jr nc, .selectedmoveknown
- ld a, [wPlayerMoveListIndex] ; wPlayerMoveListIndex
+ ld a, [wPlayerMoveListIndex]
inc a
.selectedmoveknown
- ld [hli], a ; wCurrentMenuItem
+ ld [hli], a
inc hl ; wTileBehindCursor untouched
ld a, [wcd6c]
inc a
inc a
- ld [hli], a ; wMaxMenuItem
+ ld [hli], a
ld a, [wMoveMenuType]
dec a
ld b, $c1 ; can't use B
@@ -2512,7 +2614,7 @@ MoveSelectionMenu: ; 3d219 (f:5219)
dec a
ld b, $c3
jr z, .matchedkeyspicked
- ld a, [W_ISLINKBATTLE] ; W_ISLINKBATTLE
+ ld a, [W_ISLINKBATTLE]
cp $4
jr z, .matchedkeyspicked
ld a, [W_FLAGS_D733]
@@ -2522,14 +2624,14 @@ MoveSelectionMenu: ; 3d219 (f:5219)
ld b, $ff
.matchedkeyspicked
ld a, b
- ld [hli], a ; wMenuWatchedKeys
+ ld [hli], a
ld a, [wMoveMenuType]
cp $1
jr z, .movelistindex1
- ld a, [wPlayerMoveListIndex] ; wPlayerMoveListIndex
+ ld a, [wPlayerMoveListIndex]
inc a
.movelistindex1
- ld [hl], a ; wLastMenuItem
+ ld [hl], a
Func_3d2fe: ; 3d2fe (f:52fe)
ld a, [wMoveMenuType]
@@ -2538,7 +2640,7 @@ Func_3d2fe: ; 3d2fe (f:52fe)
dec a
jr nz, .select
hlCoord 1, 14
- ld de, WhichTechniqueString ; $53b8
+ ld de, WhichTechniqueString
call PlaceString
jr .select
.battleselect
@@ -2546,7 +2648,7 @@ Func_3d2fe: ; 3d2fe (f:52fe)
bit 0, a
jr nz, .select
call Func_3d4b6
- ld a, [wcc35]
+ ld a, [wMenuItemToSwap]
and a
jr z, .select
hlCoord 5, 13
@@ -2565,14 +2667,14 @@ Func_3d2fe: ; 3d2fe (f:52fe)
bit 7, a
jp nz, Func_3d3dd ; down
bit 2, a
- jp nz, Func_3d435 ; select
+ jp nz, SwapMovesInMenu ; select
bit 1, a ; B, but was it reset above?
push af
xor a
- ld [wcc35], a
- ld a, [wCurrentMenuItem] ; wCurrentMenuItem
+ ld [wMenuItemToSwap], a
+ ld a, [wCurrentMenuItem]
dec a
- ld [wCurrentMenuItem], a ; wCurrentMenuItem
+ ld [wCurrentMenuItem], a
ld b, a
ld a, [wMoveMenuType]
dec a ; if not mimic
@@ -2582,38 +2684,38 @@ Func_3d2fe: ; 3d2fe (f:52fe)
.nob
dec a
ld a, b
- ld [wPlayerMoveListIndex], a ; wPlayerMoveListIndex
+ ld [wPlayerMoveListIndex], a
jr nz, .moveselected
pop af
ret
.moveselected
pop af
ret nz
- ld hl, wBattleMonPP ; wBattleMonPP
- ld a, [wCurrentMenuItem] ; wCurrentMenuItem
+ ld hl, wBattleMonPP
+ ld a, [wCurrentMenuItem]
ld c, a
ld b, $0
add hl, bc
ld a, [hl]
and $3f
jr z, .nopp
- ld a, [W_PLAYERDISABLEDMOVE] ; W_PLAYERDISABLEDMOVE
+ ld a, [W_PLAYERDISABLEDMOVE]
swap a
and $f
dec a
cp c
jr z, .disabled
- ld a, [W_PLAYERBATTSTATUS3] ; W_PLAYERBATTSTATUS3
+ ld a, [W_PLAYERBATTSTATUS3]
bit 3, a ; transformed
jr nz, .dummy ; game freak derp
.dummy
- ld a, [wCurrentMenuItem] ; wCurrentMenuItem
+ ld a, [wCurrentMenuItem]
ld hl, wBattleMonMoves
ld c, a
ld b, $0
add hl, bc
ld a, [hl]
- ld [wPlayerSelectedMove], a ; wPlayerSelectedMove
+ ld [wPlayerSelectedMove], a
xor a
ret
.disabled
@@ -2638,17 +2740,17 @@ WhichTechniqueString: ; 3d3b8 (f:53b8)
db "WHICH TECHNIQUE?@"
Func_3d3c9: ; 3d3c9 (f:53c9)
- ld a, [wCurrentMenuItem] ; wCurrentMenuItem
+ ld a, [wCurrentMenuItem]
and a
jp nz, Func_3d2fe
call EraseMenuCursor
ld a, [wcd6c]
inc a
- ld [wCurrentMenuItem], a ; wCurrentMenuItem
+ ld [wCurrentMenuItem], a
jp Func_3d2fe
Func_3d3dd: ; 3d3dd (f:53dd)
- ld a, [wCurrentMenuItem] ; wCurrentMenuItem
+ ld a, [wCurrentMenuItem]
ld b, a
ld a, [wcd6c]
inc a
@@ -2657,15 +2759,15 @@ Func_3d3dd: ; 3d3dd (f:53dd)
jp nz, Func_3d2fe
call EraseMenuCursor
ld a, $1
- ld [wCurrentMenuItem], a ; wCurrentMenuItem
+ ld [wCurrentMenuItem], a
jp Func_3d2fe
Func_3d3f5: ; 3d3f5 (f:53f5)
- ld a, $a5
- ld [wPlayerSelectedMove], a ; wPlayerSelectedMove
- ld a, [W_PLAYERDISABLEDMOVE] ; W_PLAYERDISABLEDMOVE
+ ld a, STRUGGLE
+ ld [wPlayerSelectedMove], a
+ ld a, [W_PLAYERDISABLEDMOVE]
and a
- ld hl, wBattleMonPP ; wBattleMonPP
+ ld hl, wBattleMonPP
jr nz, .asm_3d40e
ld a, [hli]
or [hl]
@@ -2706,70 +2808,70 @@ NoMovesLeftText: ; 3d430 (f:5430)
TX_FAR _NoMovesLeftText
db "@"
-Func_3d435: ; 3d435 (f:5435)
- ld a, [wcc35]
+SwapMovesInMenu: ; 3d435 (f:5435)
+ ld a, [wMenuItemToSwap]
and a
- jr z, asm_3d4ad
+ jr z, .noMenuItemSelected
ld hl, wBattleMonMoves
- call Func_3d493
- ld hl, wBattleMonPP ; wBattleMonPP
- call Func_3d493
- ld hl, W_PLAYERDISABLEDMOVE ; W_PLAYERDISABLEDMOVE
+ call .swapBytes ; swap moves
+ ld hl, wBattleMonPP
+ call .swapBytes ; swap move PP
+; update the index of the disabled move if necessary
+ ld hl, W_PLAYERDISABLEDMOVE
ld a, [hl]
swap a
and $f
ld b, a
- ld a, [wCurrentMenuItem] ; wCurrentMenuItem
+ ld a, [wCurrentMenuItem]
cp b
- jr nz, .asm_3d463
+ jr nz, .next
ld a, [hl]
and $f
ld b, a
- ld a, [wcc35]
+ ld a, [wMenuItemToSwap]
swap a
add b
ld [hl], a
- jr .asm_3d474
-.asm_3d463
- ld a, [wcc35]
+ jr .swapMovesInPartyMon
+.next
+ ld a, [wMenuItemToSwap]
cp b
- jr nz, .asm_3d474
+ jr nz, .swapMovesInPartyMon
ld a, [hl]
and $f
ld b, a
- ld a, [wCurrentMenuItem] ; wCurrentMenuItem
+ ld a, [wCurrentMenuItem]
swap a
add b
ld [hl], a
-.asm_3d474
- ld hl, wPartyMon1Moves ; wPartyMon1Moves
- ld a, [wPlayerMonNumber] ; wPlayerMonNumber
- ld bc, $2c
+.swapMovesInPartyMon
+ ld hl, wPartyMon1Moves
+ ld a, [wPlayerMonNumber]
+ ld bc, wPartyMon2 - wPartyMon1
call AddNTimes
push hl
- call Func_3d493
+ call .swapBytes ; swap moves
pop hl
ld bc, $15
add hl, bc
- call Func_3d493
+ call .swapBytes ; swap move PP
xor a
- ld [wcc35], a
+ ld [wMenuItemToSwap], a ; deselect the item
jp MoveSelectionMenu
-
-Func_3d493: ; 3d493 (f:5493)
+.swapBytes
push hl
- ld a, [wcc35]
+ ld a, [wMenuItemToSwap]
dec a
ld c, a
- ld b, $0
+ ld b, 0
add hl, bc
ld d, h
ld e, l
pop hl
- ld a, [wCurrentMenuItem] ; wCurrentMenuItem
+ ld a, [wCurrentMenuItem]
dec a
ld c, a
- ld b, $0
+ ld b, 0
add hl, bc
ld a, [de]
ld b, [hl]
@@ -2777,25 +2879,25 @@ Func_3d493: ; 3d493 (f:5493)
ld a, b
ld [de], a
ret
-asm_3d4ad: ; 3d4ad (f:54ad)
- ld a, [wCurrentMenuItem] ; wCurrentMenuItem
- ld [wcc35], a
+.noMenuItemSelected
+ ld a, [wCurrentMenuItem]
+ ld [wMenuItemToSwap], a ; select the current menu item for swapping
jp MoveSelectionMenu
Func_3d4b6: ; 3d4b6 (f:54b6)
xor a
- ld [H_AUTOBGTRANSFERENABLED], a ; $ffba
+ ld [H_AUTOBGTRANSFERENABLED], a
hlCoord 0, 8
ld b, $3
ld c, $9
call TextBoxBorder
- ld a, [W_PLAYERDISABLEDMOVE] ; W_PLAYERDISABLEDMOVE
+ ld a, [W_PLAYERDISABLEDMOVE]
and a
jr z, .asm_3d4df
swap a
and $f
ld b, a
- ld a, [wCurrentMenuItem] ; wCurrentMenuItem
+ ld a, [wCurrentMenuItem]
cp b
jr nz, .asm_3d4df
hlCoord 1, 10
@@ -2803,27 +2905,27 @@ Func_3d4b6: ; 3d4b6 (f:54b6)
call PlaceString
jr .asm_3d54e
.asm_3d4df
- ld hl, wCurrentMenuItem ; wCurrentMenuItem
+ ld hl, wCurrentMenuItem
dec [hl]
xor a
- ld [H_WHOSETURN], a ; $fff3
+ ld [H_WHOSETURN], a
ld hl, wBattleMonMoves
- ld a, [wCurrentMenuItem] ; wCurrentMenuItem
+ ld a, [wCurrentMenuItem]
ld c, a
ld b, $0
add hl, bc
ld a, [hl]
- ld [wPlayerSelectedMove], a ; wPlayerSelectedMove
- ld a, [wPlayerMonNumber] ; wPlayerMonNumber
- ld [wWhichPokemon], a ; wWhichPokemon
+ ld [wPlayerSelectedMove], a
+ ld a, [wPlayerMonNumber]
+ ld [wWhichPokemon], a
ld a, $4
ld [wcc49], a
callab GetMaxPP
- ld hl, wCurrentMenuItem ; wCurrentMenuItem
+ ld hl, wCurrentMenuItem
ld c, [hl]
inc [hl]
ld b, $0
- ld hl, wBattleMonPP ; wBattleMonPP
+ ld hl, wBattleMonPP
add hl, bc
ld a, [hl]
and $3f
@@ -2848,7 +2950,7 @@ Func_3d4b6: ; 3d4b6 (f:54b6)
predef Func_27d98
.asm_3d54e
ld a, $1
- ld [H_AUTOBGTRANSFERENABLED], a ; $ffba
+ ld [H_AUTOBGTRANSFERENABLED], a
jp Delay3
DisabledText: ; 3d555 (f:5555)
@@ -2861,8 +2963,9 @@ SelectEnemyMove: ; 3d564 (f:5564)
ld a, [W_ISLINKBATTLE]
sub $4
jr nz, .noLinkBattle
+; link battle
call SaveScreenTilesToBuffer1
- call Func_3d605
+ call LinkBattleExchangeData
call LoadScreenTilesFromBuffer1
ld a, [wcc3e]
cp $e
@@ -2945,29 +3048,30 @@ SelectEnemyMove: ; 3d564 (f:5564)
ld [wEnemySelectedMove], a
ret
.asm_3d601
- ld a, $a5
+ ld a, STRUGGLE
jr .done
-Func_3d605: ; 3d605 (f:5605)
+; this appears to exchange data with the other gameboy during link battles
+LinkBattleExchangeData: ; 3d605 (f:5605)
ld a, $ff
ld [wcc3e], a
- ld a, [wPlayerMoveListIndex] ; wPlayerMoveListIndex
- cp $f
+ ld a, [wPlayerMoveListIndex]
+ cp $f ; is the player running from battle?
jr z, .asm_3d630
ld a, [wcd6a]
and a
jr nz, .asm_3d629
- ld a, [wPlayerSelectedMove] ; wPlayerSelectedMove
- cp $a5
+ ld a, [wPlayerSelectedMove]
+ cp STRUGGLE
ld b, $e
jr z, .asm_3d62f
dec b
inc a
jr z, .asm_3d62f
- ld a, [wPlayerMoveListIndex] ; wPlayerMoveListIndex
+ ld a, [wPlayerMoveListIndex]
jr .asm_3d630
.asm_3d629
- ld a, [wWhichPokemon] ; wWhichPokemon
+ ld a, [wWhichPokemon]
add $4
ld b, a
.asm_3d62f
@@ -2995,14 +3099,14 @@ Func_3d605: ; 3d605 (f:5605)
jr nz, .asm_3d654
ret
-Func_3d65e: ; 3d65e (f:565e)
+ExecutePlayerMove: ; 3d65e (f:565e)
xor a
- ld [H_WHOSETURN], a ; $fff3
- ld a, [wPlayerSelectedMove] ; wPlayerSelectedMove
+ ld [H_WHOSETURN], a
+ ld a, [wPlayerSelectedMove]
inc a
jp z, Func_3d80a
xor a
- ld [W_MOVEMISSED], a ; W_MOVEMISSED
+ ld [W_MOVEMISSED], a
ld [wcced], a
ld [wccf4], a
ld a, $a
@@ -3012,23 +3116,23 @@ Func_3d65e: ; 3d65e (f:565e)
jp nz, Func_3d80a
call PrintGhostText
jp z, Func_3d80a
- call Func_3d854
+ call CheckPlayerStatusConditions
jr nz, .asm_3d68a
jp [hl]
.asm_3d68a
call GetCurrentMove
- ld hl, W_PLAYERBATTSTATUS1 ; W_PLAYERBATTSTATUS1
+ ld hl, W_PLAYERBATTSTATUS1
bit 4, [hl]
jr nz, asm_3d6a9
- call Func_3dc88
+ call CheckForDisobedience
jp z, Func_3d80a
Func_3d69a: ; 3d69a (f:569a)
- ld a, [W_PLAYERMOVEEFFECT] ; wcfd3
+ ld a, [W_PLAYERMOVEEFFECT]
cp CHARGE_EFFECT
- jp z, Func_3f132
+ jp z, JumpMoveEffect
cp FLY_EFFECT
- jp z, Func_3f132
+ jp z, JumpMoveEffect
jr asm_3d6b0
; in-battle stuff
@@ -3046,12 +3150,12 @@ asm_3d6b0: ; 3d6b0 (f:56b0)
ld hl,EffectsArray1
ld de,1
call IsInArray
- jp c,Func_3f132
+ jp c,JumpMoveEffect
ld a,[W_PLAYERMOVEEFFECT]
ld hl,EffectsArray5B
ld de,1
call IsInArray
- call c,Func_3f132
+ call c,JumpMoveEffect
asm_3d6dc: ; 3d6dc (f:56dc)
ld a,[W_PLAYERMOVEEFFECT]
ld hl,EffectsArray2
@@ -3061,11 +3165,11 @@ asm_3d6dc: ; 3d6dc (f:56dc)
call CriticalHitTest
call HandleCounterMove
jr z,asm_3d705
+ call GetDamageVarsForPlayerAttack
call CalculateDamage
- call MoreCalculateDamage
jp z,asm_3d74b
call AdjustDamageForMoveType
- call Func_3e687
+ call RandomizeDamage
.asm_3d702
call MoveHitTest
asm_3d705
@@ -3075,7 +3179,7 @@ asm_3d705
ld a,[W_PLAYERMOVEEFFECT]
sub a,7
jr z,asm_3d71e
- jr asm_3d74b ; 574B
+ jr asm_3d74b
asm_3d714
ld a,[W_PLAYERMOVEEFFECT]
and a
@@ -3094,7 +3198,7 @@ asm_3d71e
ld a,[W_PLAYERMOVENUM]
call PlayMoveAnimation
call Func_3eed3
- call Func_3cd60
+ call DrawPlayerHUDAndHPBar
ld a,[W_PLAYERBATTSTATUS2]
bit 4,a
ld hl,Func_79771
@@ -3118,7 +3222,7 @@ asm_3d74b
asm_3d766
ld a,[W_PLAYERMOVEEFFECT]
cp a,MIRROR_MOVE_EFFECT
- jr nz,.next6 ; 577A
+ jr nz,.next6
call MirrorMoveCopyMove
jp z,Func_3d80a
xor a
@@ -3126,7 +3230,7 @@ asm_3d766
jp Func_3d69a
.next6
cp a,METRONOME_EFFECT
- jr nz,.next7 ; 5784
+ jr nz,.next7
call MetronomePickMove
jp Func_3d69a
.next7
@@ -3134,18 +3238,18 @@ asm_3d766
ld hl,EffectsArray3
ld de,1
call IsInArray
- jp c,Func_3f132
+ jp c,JumpMoveEffect
ld a,[W_MOVEMISSED]
and a
- jr z,.next8 ; 57A6
+ jr z,.next8
call PrintMoveFailureText
ld a,[W_PLAYERMOVEEFFECT]
cp a,EXPLODE_EFFECT
- jr z,.next9 ; 57B9
+ jr z,.next9
jp Func_3d80a
.next8
call ApplyAttackToEnemyPokemon
- call Func_3dc5c
+ call PrintCriticalOHKOText
callab DisplayEffectiveness
ld a,1
ld [wccf4],a
@@ -3154,7 +3258,7 @@ asm_3d766
ld hl,EffectsArray4
ld de,1
call IsInArray
- call c,Func_3f132
+ call c,JumpMoveEffect
ld hl,wEnemyMonHP
ld a,[hli]
ld b,[hl]
@@ -3164,10 +3268,10 @@ asm_3d766
ld hl,W_PLAYERBATTSTATUS1
bit 2,[hl]
- jr z,.next10 ; 57EF
- ld a,[wd06a]
+ jr z,.next10
+ ld a,[wPlayerNumAttacksLeft]
dec a
- ld [wd06a],a
+ ld [wPlayerNumAttacksLeft],a
jp nz,asm_3d714
res 2,[hl]
@@ -3182,7 +3286,7 @@ asm_3d766
ld hl,EffectsArray5
ld de,1
call IsInArray
- call nc,Func_3f132
+ call nc,JumpMoveEffect
jp Func_3d80a
MultiHitText: ; 3d805 (f:5805)
@@ -3233,24 +3337,27 @@ IsGhostBattle: ; 3d83a (f:583a)
cp a,LAVENDER_HOUSE_1
jr nc,.next
ld b,SILPH_SCOPE
- call IsItemInBag ; $3493
+ call IsItemInBag
ret z
.next
ld a,1
and a
ret
-Func_3d854: ; 3d854 (f:5854)
+; checks for various status conditions affecting the player mon
+; stores whether the mon cannot use a move this turn in Z flag
+CheckPlayerStatusConditions: ; 3d854 (f:5854)
ld hl,wBattleMonStatus
ld a,[hl]
- and a,SLP
- jr z,.FrozenCheck ; to 5884
+ and a,SLP ; sleep mask
+ jr z,.FrozenCheck
+; sleeping
dec a
- ld [wBattleMonStatus],a ; decrement sleep count
+ ld [wBattleMonStatus],a ; decrement number of turns left
and a
- jr z,.WakeUp ; to 5874
-
+ jr z,.WakeUp ; if the number of turns hit 0, wake up
+; fast asleep
xor a
ld [wcc5b],a
ld a,SLP_ANIM - 1
@@ -3265,72 +3372,74 @@ Func_3d854: ; 3d854 (f:5854)
xor a
ld [wccf1],a
ld hl,Func_3d80a
- jp Func_3da37
+ jp .CannotUseMove
.FrozenCheck
bit FRZ,[hl] ; frozen?
- jr z,.HeldInPlaceCheck ; to 5898
+ jr z,.HeldInPlaceCheck
ld hl,IsFrozenText
call PrintText
xor a
ld [wccf1],a
ld hl,Func_3d80a
- jp Func_3da37
+ jp .CannotUseMove
.HeldInPlaceCheck
ld a,[W_ENEMYBATTSTATUS1]
bit 5,a
- jp z,FlinchedCheck
+ jp z,.FlinchedCheck
ld hl,CantMoveText
call PrintText
ld hl,Func_3d80a
- jp Func_3da37
+ jp .CannotUseMove
-FlinchedCheck: ; 3d8ac (f:58ac)
+.FlinchedCheck
ld hl,W_PLAYERBATTSTATUS1
bit 3,[hl]
- jp z,HyperBeamCheck
+ jp z,.HyperBeamCheck
res 3,[hl]
ld hl,FlinchedText
call PrintText
ld hl,Func_3d80a
- jp Func_3da37
+ jp .CannotUseMove
-HyperBeamCheck: ; 3d8c2 (f:58c2)
+.HyperBeamCheck
ld hl,W_PLAYERBATTSTATUS2
bit 5,[hl]
- jr z,.next ; 58D7
+ jr z,.AnyMoveDisabledCheck
res 5,[hl]
ld hl,MustRechargeText
call PrintText
- ld hl,Func_3d80a ; $580a
- jp Func_3da37
-.next
+ ld hl,Func_3d80a
+ jp .CannotUseMove
+
+.AnyMoveDisabledCheck
ld hl,W_PLAYERDISABLEDMOVE
ld a,[hl]
and a
- jr z,.next2 ; 58EE
+ jr z,.ConfusedCheck
dec a
ld [hl],a
and a,$F
- jr nz,.next2
+ jr nz,.ConfusedCheck
ld [hl],a
ld [wccee],a
ld hl,DisabledNoMoreText
call PrintText
-.next2
+
+.ConfusedCheck
ld a,[W_PLAYERBATTSTATUS1]
add a
- jr nc,.next3 ; 5929
+ jr nc,.TriedToUseDisabledMoveCheck
ld hl,wd06b
dec [hl]
- jr nz,.next4 ; 5907
+ jr nz,.IsConfused
ld hl,W_PLAYERBATTSTATUS1
res 7,[hl]
ld hl,ConfusedNoMoreText
call PrintText
- jr .next3
-.next4
+ jr .TriedToUseDisabledMoveCheck
+.IsConfused
ld hl,IsConfusedText
call PrintText
xor a
@@ -3339,55 +3448,60 @@ HyperBeamCheck: ; 3d8c2 (f:58c2)
call PlayMoveAnimation
call BattleRandom
cp a,$80
- jr c,.next3
+ jr c,.TriedToUseDisabledMoveCheck
ld hl,W_PLAYERBATTSTATUS1
ld a,[hl]
and a,$80 ; confused
ld [hl],a
call PrintHurtItselfText
- jr .next5 ; 5952
-.next3
+ jr .MonHurtItselfOrFullyParalysed
+
+.TriedToUseDisabledMoveCheck
ld a,[wccee]
and a
- jr z,.ParalysisCheck ; 593E
+ jr z,.ParalysisCheck
ld hl,wPlayerSelectedMove
cp [hl]
jr nz,.ParalysisCheck
call PrintMoveIsDisabledText
- ld hl,Func_3d80a ; $580a
- jp Func_3da37
+ ld hl,Func_3d80a
+ jp .CannotUseMove
+
.ParalysisCheck
ld hl,wBattleMonStatus
bit PAR,[hl]
- jr z,.next7 ; 5975
+ jr z,.BideCheck
call BattleRandom
cp a,$3F
- jr nc,.next7
+ jr nc,.BideCheck
ld hl,FullyParalyzedText
call PrintText
-.next5
+
+.MonHurtItselfOrFullyParalysed
ld hl,W_PLAYERBATTSTATUS1
ld a,[hl]
- and a,$CC
+ and a,$CC ; clear bide, thrashing, charging up, and multi-turn moves such as warp
ld [hl],a
ld a,[W_PLAYERMOVEEFFECT]
cp a,FLY_EFFECT
- jr z,.next8 ; 5966
+ jr z,.FlyOrChargeEffect
cp a,CHARGE_EFFECT
- jr z,.next8
- jr .next9 ; 596F
-.next8
+ jr z,.FlyOrChargeEffect
+ jr .NotFlyOrChargeEffect
+
+.FlyOrChargeEffect
xor a
ld [wcc5b],a
ld a,STATUS_AFFECTED_ANIM
call PlayMoveAnimation
-.next9
- ld hl,Func_3d80a ; $580a
- jp Func_3da37
-.next7
+.NotFlyOrChargeEffect
+ ld hl,Func_3d80a
+ jp .CannotUseMove
+
+.BideCheck
ld hl,W_PLAYERBATTSTATUS1
- bit 0,[hl]
- jr z,.next10 ; 59D0
+ bit 0,[hl] ; is mon using bide?
+ jr z,.ThrashingAboutCheck
xor a
ld [W_PLAYERMOVENUM],a
ld hl,W_DAMAGE
@@ -3401,14 +3515,14 @@ HyperBeamCheck: ; 3d8c2 (f:58c2)
ld a,[hl]
adc b
ld [hl],a
- ld hl,wd06a
+ ld hl,wPlayerNumAttacksLeft
dec [hl]
- jr z,.next11 ; 599B
- ld hl,Func_3d80a ; $580a
- jp Func_3da37
-.next11
+ jr z,.UnleashEnergy
+ ld hl,Func_3d80a
+ jp .CannotUseMove
+.UnleashEnergy
ld hl,W_PLAYERBATTSTATUS1
- res 0,[hl]
+ res 0,[hl] ; not using bide any more
ld hl,UnleashedEnergyText
call PrintText
ld a,1
@@ -3422,28 +3536,29 @@ HyperBeamCheck: ; 3d8c2 (f:58c2)
rl a
ld [W_DAMAGE],a
or b
- jr nz,.next12 ; 59C2
+ jr nz,.next
ld a,1
ld [W_MOVEMISSED],a
-.next12
+.next
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 hl,asm_3d705
+ jp .CannotUseMove
+
+.ThrashingAboutCheck
+ bit 1,[hl] ; is mon using thrash or petal dance?
+ jr z,.MultiturnMoveCheck
ld a,THRASH
ld [W_PLAYERMOVENUM],a
ld hl,ThrashingAboutText
call PrintText
- ld hl,wd06a
+ ld hl,wPlayerNumAttacksLeft
dec [hl]
- ld hl,asm_3d6dc ; $56dc
- jp nz,Func_3da37
+ ld hl,asm_3d6dc
+ jp nz,.CannotUseMove
push hl
ld hl,W_PLAYERBATTSTATUS1
res 1,[hl]
@@ -3454,37 +3569,38 @@ HyperBeamCheck: ; 3d8c2 (f:58c2)
inc a
ld [wd06b],a
pop hl
- jp Func_3da37
-.next13
- bit 5,[hl]
- jp z,Func_3da1a
+ jp .CannotUseMove
+
+.MultiturnMoveCheck
+ bit 5,[hl] ; is mon using multi-turn move?
+ jp z,.RageCheck
ld hl,AttackContinuesText
call PrintText
- ld a,[wd06a]
+ ld a,[wPlayerNumAttacksLeft]
dec a
- ld [wd06a],a
- ld hl,asm_3d714 ; $5714
- jp nz,Func_3da37
- jp Func_3da37
+ ld [wPlayerNumAttacksLeft],a
+ ld hl,asm_3d714
+ jp nz,.CannotUseMove
+ jp .CannotUseMove
-Func_3da1a: ; 3da1a (f:5a1a)
- ld a, [W_PLAYERBATTSTATUS2] ; W_PLAYERBATTSTATUS2
- bit 6, a
- jp z, Func_3da39
+.RageCheck
+ ld a, [W_PLAYERBATTSTATUS2]
+ bit 6, a ; is mon using rage?
+ jp z, .CanUseMove
ld a, RAGE
ld [wd11e], a
call GetMoveName
call CopyStringToCF4B
xor a
- ld [W_PLAYERMOVEEFFECT], a ; wcfd3
- ld hl, asm_3d6b0 ; $56b0
- jp Func_3da37
+ ld [W_PLAYERMOVEEFFECT], a
+ ld hl, asm_3d6b0
+ jp .CannotUseMove
-Func_3da37: ; 3da37 (f:5a37)
+.CannotUseMove
xor a
ret
-Func_3da39: ; 3da39 (f:5a39)
+.CanUseMove
ld a, $1
and a
ret
@@ -3550,13 +3666,13 @@ CantMoveText: ; 3da83 (f:5a83)
db "@"
PrintMoveIsDisabledText: ; 3da88 (f:5a88)
- ld hl, wPlayerSelectedMove ; wPlayerSelectedMove
- ld de, W_PLAYERBATTSTATUS1 ; W_PLAYERBATTSTATUS1
- ld a, [H_WHOSETURN] ; $fff3
+ ld hl, wPlayerSelectedMove
+ ld de, W_PLAYERBATTSTATUS1
+ ld a, [H_WHOSETURN]
and a
jr z, .asm_3da97
inc hl
- ld de, W_ENEMYBATTSTATUS1 ; W_ENEMYBATTSTATUS1
+ ld de, W_ENEMYBATTSTATUS1
.asm_3da97
ld a, [de]
res 4, a
@@ -3574,7 +3690,7 @@ MoveIsDisabledText: ; 3daa8 (f:5aa8)
PrintHurtItselfText: ; 3daad (f:5aad)
ld hl, HurtItselfText
call PrintText
- ld hl, wEnemyMonDefense ; wcff8
+ ld hl, wEnemyMonDefense
ld a, [hli]
push af
ld a, [hld]
@@ -3583,19 +3699,19 @@ PrintHurtItselfText: ; 3daad (f:5aad)
ld [hli], a
ld a, [wBattleMonDefense + 1]
ld [hl], a
- ld hl, W_PLAYERMOVEEFFECT ; wcfd3
+ ld hl, W_PLAYERMOVEEFFECT
push hl
ld a, [hl]
push af
xor a
ld [hli], a
- ld [wd05e], a
+ ld [wCriticalHitOrOHKO], a
ld a, $28
ld [hli], a
xor a
ld [hl], a
+ call GetDamageVarsForPlayerAttack
call CalculateDamage
- call MoreCalculateDamage
pop af
pop hl
ld [hl], a
@@ -3607,11 +3723,11 @@ PrintHurtItselfText: ; 3daad (f:5aad)
xor a
ld [wcc5b], a
inc a
- ld [H_WHOSETURN], a ; $fff3
+ ld [H_WHOSETURN], a
call PlayMoveAnimation
- call Func_3cd60
+ call DrawPlayerHUDAndHPBar
xor a
- ld [H_WHOSETURN], a ; $fff3
+ ld [H_WHOSETURN], a
jp ApplyDamageToPlayerPokemon
PrintMonName1Text: ; 3daf5 (f:5af5)
@@ -3621,12 +3737,12 @@ PrintMonName1Text: ; 3daf5 (f:5af5)
MonName1Text: ; 3dafb (f:5afb)
TX_FAR _MonName1Text
db $08 ; asm
- ld a, [H_WHOSETURN] ; $fff3
+ ld a, [H_WHOSETURN]
and a
- ld a, [W_PLAYERMOVENUM] ; wcfd2
+ ld a, [W_PLAYERMOVENUM]
ld hl, wccf1
jr z, .asm_3db11
- ld a, [W_ENEMYMOVENUM] ; W_ENEMYMOVENUM
+ ld a, [W_ENEMYMOVENUM]
ld hl, wccf2
.asm_3db11
ld [hl], a
@@ -3715,7 +3831,7 @@ Func_3db85: ; 3db85 (f:5b85)
ld a, [wd11e] ; move number
ld c, a
ld b, $0
- ld hl, UnknownMovesList_3dba3 ; $5ba3
+ ld hl, UnknownMovesList_3dba3
.asm_3db8f
ld a, [hli]
cp $ff
@@ -3748,33 +3864,33 @@ UnknownMovesList_3dba3: ; 3dba3 (f:5ba3)
db $FF ; terminator
PrintMoveFailureText: ; 3dbe2 (f:5be2)
- ld de, W_PLAYERMOVEEFFECT ; wcfd3
- ld a, [H_WHOSETURN] ; $fff3
+ ld de, W_PLAYERMOVEEFFECT
+ ld a, [H_WHOSETURN]
and a
- jr z, .asm_3dbed
- ld de, W_ENEMYMOVEEFFECT ; W_ENEMYMOVEEFFECT
-.asm_3dbed
- ld hl, DoesntAffectMonText ; $5c57
+ jr z, .playersTurn
+ ld de, W_ENEMYMOVEEFFECT
+.playersTurn
+ ld hl, DoesntAffectMonText
ld a, [wd05b]
and $7f
jr z, .asm_3dc04
- ld hl, AttackMissedText ; $5c42
- ld a, [wd05e]
+ ld hl, AttackMissedText
+ ld a, [wCriticalHitOrOHKO]
cp $ff
jr nz, .asm_3dc04
- ld hl, UnaffectedText ; $5c4c
+ ld hl, UnaffectedText
.asm_3dc04
push de
call PrintText
xor a
- ld [wd05e], a
+ ld [wCriticalHitOrOHKO], 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 ; W_DAMAGE
+ ld hl, W_DAMAGE
ld a, [hli]
ld b, [hl]
srl a
@@ -3791,11 +3907,11 @@ PrintMoveFailureText: ; 3dbe2 (f:5be2)
inc a
ld [hl], a
.asm_3dc2a
- ld hl, KeptGoingAndCrashedText ; $5c47
+ ld hl, KeptGoingAndCrashedText
call PrintText
ld b, $4
predef Func_48125
- ld a, [H_WHOSETURN] ; $fff3
+ ld a, [H_WHOSETURN]
and a
jr nz, .asm_3dc3f
jp ApplyDamageToPlayerPokemon
@@ -3815,20 +3931,21 @@ UnaffectedText: ; 3dc4c (f:5c4c)
db "@"
PrintDoesntAffectText: ; 3dc51 (f:5c51)
- ld hl, DoesntAffectMonText ; $5c57
+ ld hl, DoesntAffectMonText
jp PrintText
DoesntAffectMonText: ; 3dc57 (f:5c57)
TX_FAR _DoesntAffectMonText
db "@"
-Func_3dc5c: ; 3dc5c (f:5c5c)
- ld a, [wd05e]
+; if there was a critical hit or an OHKO was successful, print the corresponding text
+PrintCriticalOHKOText: ; 3dc5c (f:5c5c)
+ ld a, [wCriticalHitOrOHKO]
and a
- jr z, .asm_3dc75
+ jr z, .done ; do nothing if there was no critical hit or successful OHKO
dec a
add a
- ld hl, CriticalOHKOTextPointers ; $5c7a
+ ld hl, CriticalOHKOTextPointers
ld b, $0
ld c, a
add hl, bc
@@ -3837,8 +3954,8 @@ Func_3dc5c: ; 3dc5c (f:5c5c)
ld l, a
call PrintText
xor a
- ld [wd05e], a
-.asm_3dc75
+ ld [wCriticalHitOrOHKO], a
+.done
ld c, $14
jp DelayFrames
@@ -3854,118 +3971,123 @@ OHKOText: ; 3dc83 (f:5c83)
TX_FAR _OHKOText
db "@"
-Func_3dc88: ; 3dc88 (f:5c88)
+; checks if a traded mon will disobey due to lack of badges
+; stores whether the mon will use a move in Z flag
+CheckForDisobedience: ; 3dc88 (f:5c88)
xor a
ld [wcced], a
- ld a, [W_ISLINKBATTLE] ; W_ISLINKBATTLE
+ ld a, [W_ISLINKBATTLE]
cp $4
- jr nz, .asm_3dc97
+ jr nz, .checkIfMonIsTraded
ld a, $1
and a
ret
-.asm_3dc97
- ld hl, wPartyMon1OTID ; wPartyMon1OTID
- ld bc, $2c
- ld a, [wPlayerMonNumber] ; wPlayerMonNumber
+; compare the mon's original trainer ID with the player's ID to see if it was traded
+.checkIfMonIsTraded
+ ld hl, wPartyMon1OTID
+ ld bc, wPartyMon2 - wPartyMon1
+ ld a, [wPlayerMonNumber]
call AddNTimes
- ld a, [wPlayerID] ; wPlayerID
+ ld a, [wPlayerID]
cp [hl]
- jr nz, .asm_3dcb1
+ jr nz, .monIsTraded
inc hl
- ld a, [wPlayerID + 1] ; wd35a
+ ld a, [wPlayerID + 1]
cp [hl]
- jp z, Func_3ddb0
-.asm_3dcb1
+ jp z, .canUseMove
+; it was traded
+.monIsTraded
; what level might disobey?
ld hl, W_OBTAINEDBADGES
bit 7, [hl]
ld a, 101
- jr nz, .asm_3dcce
+ jr nz, .next
bit 5, [hl]
ld a, 70
- jr nz, .asm_3dcce
+ jr nz, .next
bit 3, [hl]
ld a, 50
- jr nz, .asm_3dcce
+ jr nz, .next
bit 1, [hl]
ld a, 30
- jr nz, .asm_3dcce
+ jr nz, .next
ld a, 10
-.asm_3dcce
+.next
ld b, a
ld c, a
- ld a, [wBattleMonLevel] ; wBattleMonLevel
+ ld a, [wBattleMonLevel]
ld d, a
add b
ld b, a
- jr nc, .asm_3dcda
- ld b, $ff
-.asm_3dcda
+ jr nc, .noCarry
+ ld b, $ff ; cap b at $ff
+.noCarry
ld a, c
cp d
- jp nc, Func_3ddb0
-.asm_3dcdf
+ jp nc, .canUseMove
+.loop1
call BattleRandom
swap a
cp b
- jr nc, .asm_3dcdf
+ jr nc, .loop1
cp c
- jp c, Func_3ddb0
-.asm_3dceb
+ jp c, .canUseMove
+.loop2
call BattleRandom
cp b
- jr nc, .asm_3dceb
+ jr nc, .loop2
cp c
- jr c, .asm_3dd3f
+ jr c, .useRandomMove
ld a, d
sub c
ld b, a
call BattleRandom
swap a
sub b
- jr c, .asm_3dd0e
+ jr c, .monNaps
cp b
- jr nc, .asm_3dd20
+ jr nc, .monDoesNothing
ld hl, WontObeyText
call PrintText
call PrintHurtItselfText
- jp Func_3ddb4
-.asm_3dd0e
+ jp .cannotUseMove
+.monNaps
call BattleRandom
add a
swap a
- and $7
- jr z, .asm_3dd0e
- ld [wBattleMonStatus], a ; wBattleMonStatus
+ and SLP ; sleep mask
+ jr z, .monNaps ; keep trying until we get at least 1 turn of sleep
+ ld [wBattleMonStatus], a
ld hl, BeganToNapText
- jr .asm_3dd3a
-.asm_3dd20
+ jr .printText
+.monDoesNothing
call BattleRandom
and $3
ld hl, LoafingAroundText
and a
- jr z, .asm_3dd3a
+ jr z, .printText
ld hl, WontObeyText
dec a
- jr z, .asm_3dd3a
+ jr z, .printText
ld hl, TurnedAwayText
dec a
- jr z, .asm_3dd3a
+ jr z, .printText
ld hl, IgnoredOrdersText
-.asm_3dd3a
+.printText
call PrintText
- jr Func_3ddb4
-.asm_3dd3f
+ jr .cannotUseMove
+.useRandomMove
ld a, [wBattleMonMoves + 1]
- and a
- jr z, .asm_3dd20
+ and a ; is the second move slot empty?
+ jr z, .monDoesNothing ; mon will not use move if it only knows one move
ld a, [wccee]
and a
- jr nz, .asm_3dd20
- ld a, [wPlayerSelectedMove] ; wPlayerSelectedMove
- cp $a5
- jr z, .asm_3dd20
- ld hl, wBattleMonPP ; wBattleMonPP
+ jr nz, .monDoesNothing
+ ld a, [wPlayerSelectedMove]
+ cp STRUGGLE
+ jr z, .monDoesNothing ; mon will not use move if struggling
+; check if only one move has remaining PP
+ ld hl, wBattleMonPP
push hl
ld a, [hli]
and $3f
@@ -3983,7 +4105,7 @@ Func_3dc88: ; 3dc88 (f:5c88)
add b
pop hl
push af
- ld a, [wCurrentMenuItem] ; wCurrentMenuItem
+ ld a, [wCurrentMenuItem]
ld c, a
ld b, $0
add hl, bc
@@ -3992,44 +4114,42 @@ Func_3dc88: ; 3dc88 (f:5c88)
ld b, a
pop af
cp b
- jr z, .asm_3dd20
+ jr z, .monDoesNothing ; mon will not use move if only one move has remaining PP
ld a, $1
ld [wcced], a
- ld a, [wMaxMenuItem] ; wMaxMenuItem
+ ld a, [wMaxMenuItem]
ld b, a
- ld a, [wCurrentMenuItem] ; wCurrentMenuItem
+ ld a, [wCurrentMenuItem]
ld c, a
-.asm_3dd86
+.chooseMove
call BattleRandom
and $3
cp b
- jr nc, .asm_3dd86
+ jr nc, .chooseMove ; if the random number is greater than the move count, choose another
cp c
- jr z, .asm_3dd86
- ld [wCurrentMenuItem], a ; wCurrentMenuItem
- ld hl, wBattleMonPP ; wBattleMonPP
+ jr z, .chooseMove ; if the random number matches the move the player selected, choose another
+ ld [wCurrentMenuItem], a
+ ld hl, wBattleMonPP
ld e, a
ld d, $0
add hl, de
ld a, [hl]
- and a
- jr z, .asm_3dd86
- ld a, [wCurrentMenuItem] ; wCurrentMenuItem
+ and a ; does the move have any PP left?
+ jr z, .chooseMove ; if the move has no PP left, choose another
+ ld a, [wCurrentMenuItem]
ld c, a
ld b, $0
ld hl, wBattleMonMoves
add hl, bc
ld a, [hl]
- ld [wPlayerSelectedMove], a ; wPlayerSelectedMove
+ ld [wPlayerSelectedMove], a
call GetCurrentMove
-
-Func_3ddb0: ; 3ddb0 (f:5db0)
+.canUseMove
ld a, $1
- and a
+ and a; clear Z flag
ret
-
-Func_3ddb4: ; 3ddb4 (f:5db4)
- xor a
+.cannotUseMove
+ xor a ; set Z flag
ret
LoafingAroundText: ; 3ddb6 (f:5db6)
@@ -4052,37 +4172,39 @@ IgnoredOrdersText: ; 3ddca (f:5dca)
TX_FAR _IgnoredOrdersText
db "@"
-CalculateDamage: ; 3ddcf (f:5dcf)
+; sets b, c, d, and e for the CalculateDamage routine in the case of an attack by the player mon
+GetDamageVarsForPlayerAttack: ; 3ddcf (f:5dcf)
xor a
- ld hl, W_DAMAGE ;damage to eventually inflict, intitialise to zero
+ ld hl, W_DAMAGE ; damage to eventually inflict, initialise to zero
ldi [hl], a
ld [hl], a
ld hl, W_PLAYERMOVEPOWER
- ld a, [hli] ;*read attack base power
+ ld a, [hli]
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
+ ld d, a ; d = move power
+ ret z ; return if move power is zero
+ ld a, [hl] ; a = [W_PLAYERMOVETYPE]
+ cp FIRE ; types >= FIRE are all special
jr nc, .specialAttack
.physicalAttack
- ld hl, wEnemyMonDefense ;opponent defense
- ld a, [hli] ;*BC = opponent defense used later
+ ld hl, wEnemyMonDefense
+ ld a, [hli]
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
+ ld c, [hl] ; bc = enemy defense
+ ld a, [W_ENEMYBATTSTATUS3]
+ bit 2, a ; check for Reflect
+ jr z, .physicalAttackCritCheck
+; if the enemy has used Reflect, double the enemy's defense
+ sla c
rl b
-.next
- ld hl, wBattleMonAttack ;attack pointer
- ld a, [wd05e]
- and a
- jr z, .next3
- ld c, 3
- call Func_3df1c
+.physicalAttackCritCheck
+ ld hl, wBattleMonAttack
+ ld a, [wCriticalHitOrOHKO]
+ and a ; check for critical hit
+ jr z, .scaleStats
+; in the case of a critical hit, reset the player's attack and the enemy's defense to their base values
+ ld c, 3 ; defense stat
+ call GetEnemyMonStat
ld a, [$ff97]
ld b, a
ld a, [$ff98]
@@ -4093,26 +4215,26 @@ CalculateDamage: ; 3ddcf (f:5dcf)
ld bc, wPartyMon2 - wPartyMon1
call AddNTimes
pop bc
- jr .next3
+ jr .scaleStats
.specialAttack
- ld hl, wEnemyMonSpecial ;opponent special
- ld a, [hli] ;*BC = opponent special defense used later
+ ld hl, wEnemyMonSpecial
+ ld a, [hli]
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
+ ld c, [hl] ; bc = enemy special
+ ld a, [W_ENEMYBATTSTATUS3]
+ bit 1, a ; check for Light Screen
+ jr z, .specialAttackCritCheck
+; if the enemy has used Light Screen, double the enemy's special
+ sla c
rl b
-.next2
+.specialAttackCritCheck
ld hl, wBattleMonSpecial
- ld a, [wd05e] ;XXX
- and a
- jr z, .next3 ;skip portion of code that pulls up inactive pokemon
-.loadOtherPoke
- ld c, 5
- call Func_3df1c
+ ld a, [wCriticalHitOrOHKO]
+ and a ; check for critical hit
+ jr z, .scaleStats
+; in the case of a critical hit, reset the player's and enemy's specials to their base values
+ ld c, 5 ; special stat
+ call GetEnemyMonStat
ld a, [$ff97]
ld b, a
ld a, [$ff98]
@@ -4123,140 +4245,158 @@ CalculateDamage: ; 3ddcf (f:5dcf)
ld bc, wPartyMon2 - wPartyMon1
call AddNTimes
pop bc
-.next3
- ld a, [hli] ;HL: when this was taken
+; if either the offensive or defensive stat is too large to store in a byte, scale both stats by dividing them by 4
+; this allows values with up to 10 bits (values up to 1023) to be handled
+; anything larger will wrap around
+.scaleStats
+ ld a, [hli]
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]
+ ld h, a ; hl = player's offensive stat
+ or b ; is either high byte nonzero?
+ jr z, .next ; if not, we don't need to scale
+ ; bc /= 4 (scale enemy's defensive stat)
+ srl b
rr c
srl b
rr c
- srl h ;[attack] HL /= 4 [to apply equal scaling]
+ ; hl /= 4 (scale player's offensive stat)
+ srl h
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, [wBattleMonLevel] ;*E = level
- ld e, a
- ld a, [wd05e] ;critical hit?
- and a
- jr z, .next5
- sla e ;double level if it was a critical hit
-.next5
- ld a, 1 ;return Z = 0
+ or h ; is the player's offensive stat 0?
+ jr nz, .next
+ inc l ; if the player's offensive stat is 0, bump it up to 1
+.next
+ ld b, l ; b = player's offensive stat (possibly scaled) (c already contains enemy's defensive stat (possibly scaled))
+ ld a, [wBattleMonLevel]
+ ld e, a ; e = level
+ ld a, [wCriticalHitOrOHKO]
+ and a ; check for critical hit
+ jr z, .done
+ sla e ; double level if it was a critical hit
+.done
+ ld a, 1
and a
ret
-Func_3de75: ; 3de75 (f:5e75)
- ld hl, W_DAMAGE ; W_DAMAGE
+; sets b, c, d, and e for the CalculateDamage routine in the case of an attack by the enemy mon
+GetDamageVarsForEnemyAttack: ; 3de75 (f:5e75)
+ ld hl, W_DAMAGE ; damage to eventually inflict, initialise to zero
xor a
ld [hli], a
ld [hl], a
- ld hl, W_ENEMYMOVEPOWER ; wcfce
+ ld hl, W_ENEMYMOVEPOWER
ld a, [hli]
- ld d, a
+ ld d, a ; d = move power
and a
- ret z
- ld a, [hl]
- cp $14
- jr nc, .asm_3debc
+ ret z ; return if move power is zero
+ ld a, [hl] ; a = [W_ENEMYMOVETYPE]
+ cp FIRE ; types >= FIRE are all special
+ jr nc, .specialAttack
+.physicalAttack
ld hl, wBattleMonDefense
ld a, [hli]
ld b, a
- ld c, [hl]
- ld a, [W_PLAYERBATTSTATUS3] ; W_PLAYERBATTSTATUS3
- bit 2, a
- jr z, .asm_3de98
+ ld c, [hl] ; bc = player defense
+ ld a, [W_PLAYERBATTSTATUS3]
+ bit 2, a ; check for Reflect
+ jr z, .physicalAttackCritCheck
+; if the player has used Reflect, double the player's defense
sla c
rl b
-.asm_3de98
+.physicalAttackCritCheck
ld hl, wEnemyMonAttack
- ld a, [wd05e]
- and a
- jr z, .asm_3deef
+ ld a, [wCriticalHitOrOHKO]
+ and a ; check for critical hit
+ jr z, .scaleStats
+; in the case of a critical hit, reset the player's defense and the enemy's attack to their base values
ld hl, wPartyMon1Defense
- ld a, [wPlayerMonNumber] ; wPlayerMonNumber
- ld bc, $2c
+ ld a, [wPlayerMonNumber]
+ ld bc, wPartyMon2 - wPartyMon1
call AddNTimes
ld a, [hli]
ld b, a
ld c, [hl]
push bc
- ld c, $2
- call Func_3df1c
+ ld c, 2 ; attack stat
+ call GetEnemyMonStat
ld hl, $ff97
pop bc
- jr .asm_3deef
-.asm_3debc
+ jr .scaleStats
+.specialAttack
ld hl, wBattleMonSpecial
ld a, [hli]
ld b, a
ld c, [hl]
- ld a, [W_PLAYERBATTSTATUS3] ; W_PLAYERBATTSTATUS3
- bit 1, a
- jr z, .asm_3decd
+ ld a, [W_PLAYERBATTSTATUS3]
+ bit 1, a ; check for Light Screen
+ jr z, .specialAttackCritCheck
+; if the player has used Light Screen, double the player's special
sla c
rl b
-.asm_3decd
- ld hl, wEnemyMonSpecial ; wcffc
- ld a, [wd05e]
- and a
- jr z, .asm_3deef
- ld hl, wPartyMon1Special ; wPartyMon1Special
- ld a, [wPlayerMonNumber] ; wPlayerMonNumber
- ld bc, $2c
+.specialAttackCritCheck
+ ld hl, wEnemyMonSpecial
+ ld a, [wCriticalHitOrOHKO]
+ and a ; check for critical hit
+ jr z, .scaleStats
+; in the case of a critical hit, reset the player's and enemy's specials to their base values
+ ld hl, wPartyMon1Special
+ ld a, [wPlayerMonNumber]
+ ld bc, wPartyMon2 - wPartyMon1
call AddNTimes
ld a, [hli]
ld b, a
ld c, [hl]
push bc
- ld c, $5
- call Func_3df1c
+ ld c, 5 ; special stat
+ call GetEnemyMonStat
ld hl, $ff97
pop bc
-.asm_3deef
+; if either the offensive or defensive stat is too large to store in a byte, scale both stats by dividing them by 4
+; this allows values with up to 10 bits (values up to 1023) to be handled
+; anything larger will wrap around
+.scaleStats
ld a, [hli]
ld l, [hl]
- ld h, a
- or b
- jr z, .asm_3df0a
+ ld h, a ; hl = enemy's offensive stat
+ or b ; is either high byte nonzero?
+ jr z, .next ; if not, we don't need to scale
+; bc /= 4 (scale player's defensive stat)
srl b
rr c
srl b
rr c
+; hl /= 4 (scale enemy's offensive stat)
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, [wEnemyMonLevel] ; wEnemyMonLevel
+ or h ; is the enemy's offensive stat 0?
+ jr nz, .next
+ inc l ; if the enemy's offensive stat is 0, bump it up to 1
+.next
+ ld b, l ; b = enemy's offensive stat (possibly scaled) (c already contains player's defensive stat (possibly scaled))
+ ld a, [wEnemyMonLevel]
ld e, a
- ld a, [wd05e]
- and a
- jr z, .asm_3df17
- sla e
-.asm_3df17
+ ld a, [wCriticalHitOrOHKO]
+ and a ; check for critical hit
+ jr z, .done
+ sla e ; double level if it was a critical hit
+.done
ld a, $1
and a
and a
ret
-Func_3df1c: ; 3df1c (f:5f1c)
+; get stat c of enemy mon
+; c: stat to get (HP=1,Attack=2,Defense=3,Speed=4,Special=5)
+GetEnemyMonStat: ; 3df1c (f:5f1c)
push de
push bc
- ld a, [W_ISLINKBATTLE] ; W_ISLINKBATTLE
+ ld a, [W_ISLINKBATTLE]
cp $4
jr nz, .asm_3df40
ld hl, wEnemyMon1Stats
@@ -4275,8 +4415,8 @@ Func_3df1c: ; 3df1c (f:5f1c)
pop de
ret
.asm_3df40
- ld a, [wEnemyMonLevel] ; wEnemyMonLevel
- ld [W_CURENEMYLVL], a ; W_CURENEMYLVL
+ ld a, [wEnemyMonLevel]
+ ld [W_CURENEMYLVL], a
ld a, [wEnemyMonSpecies]
ld [wd0b5], a
call GetMonHeader
@@ -4294,7 +4434,7 @@ Func_3df1c: ; 3df1c (f:5f1c)
pop de
ret
-MoreCalculateDamage: ; 3df65 (f:5f65)
+CalculateDamage: ; 3df65 (f:5f65)
; input:
; b: attack
; c: opponent defense
@@ -4454,8 +4594,8 @@ MoreCalculateDamage: ; 3df65 (f:5f65)
ret
Func_3e016: ; 3e016 (f:6016)
- call Func_3f132
- ld a, [W_MOVEMISSED] ; W_MOVEMISSED
+ call JumpMoveEffect
+ ld a, [W_MOVEMISSED]
dec a
ret
@@ -4473,8 +4613,8 @@ UnusedHighCriticalMoves: ; 3e01e (f:601e)
; among the most popular) tend to CH about 20 to 25% of the time."
CriticalHitTest: ; 3e023 (f:6023)
xor a
- ld [wd05e], a
- ld a, [H_WHOSETURN] ; $fff3
+ ld [wCriticalHitOrOHKO], a
+ ld a, [H_WHOSETURN]
and a
ld a, [wEnemyMonSpecies]
jr nz, .asm_3e032
@@ -4485,13 +4625,13 @@ CriticalHitTest: ; 3e023 (f:6023)
ld a, [W_MONHBASESPEED]
ld b, a
srl b ; (effective (base speed/2))
- ld a, [H_WHOSETURN] ; $fff3
+ ld a, [H_WHOSETURN]
and a
- ld hl, W_PLAYERMOVEPOWER ; W_PLAYERMOVEPOWER
- ld de, W_PLAYERBATTSTATUS2 ; W_PLAYERBATTSTATUS2
+ ld hl, W_PLAYERMOVEPOWER
+ ld de, W_PLAYERBATTSTATUS2
jr z, .calcCriticalHitProbability
- ld hl, W_ENEMYMOVEPOWER ; wcfce
- ld de, W_ENEMYBATTSTATUS2 ; W_ENEMYBATTSTATUS2
+ ld hl, W_ENEMYMOVEPOWER
+ ld de, W_ENEMYBATTSTATUS2
.calcCriticalHitProbability ; 0x3e04f
ld a, [hld] ; read base power from RAM
and a
@@ -4534,7 +4674,7 @@ CriticalHitTest: ; 3e023 (f:6023)
cp b ; check a against calculated crit rate
ret nc ; no critical hit if no borrow
ld a, $1
- ld [wd05e], a ; set critical hit flag
+ ld [wCriticalHitOrOHKO], a ; set critical hit flag
ret
; high critical hit moves
@@ -4721,7 +4861,7 @@ ApplyDamageToEnemyPokemon: ; 3e142 (f:6142)
ld [wListMenuID],a
predef UpdateHPBar2 ; animate the HP bar shortening
ApplyAttackToEnemyPokemonDone: ; 3e19d (f:619d)
- jp Func_3cd5a ; redraw pokemon names and HP bars
+ jp DrawHUDsAndHPBars
ApplyAttackToPlayerPokemon: ; 3e1a0 (f:61a0)
ld a,[W_ENEMYMOVEEFFECT]
@@ -4839,7 +4979,7 @@ ApplyDamageToPlayerPokemon: ; 3e200 (f:6200)
ld [wListMenuID],a
predef UpdateHPBar2 ; animate the HP bar shortening
ApplyAttackToPlayerPokemonDone
- jp Func_3cd5a ; redraw pokemon names and HP bars
+ jp DrawHUDsAndHPBars
AttackSubstitute: ; 3e25e (f:625e)
ld hl,SubstituteTookDamageText
@@ -4885,7 +5025,7 @@ AttackSubstitute: ; 3e25e (f:625e)
.nullifyEffect
xor a
ld [hl],a ; zero the effect of the attacker's move
- jp Func_3cd5a ; redraw pokemon names and HP bars
+ jp DrawHUDsAndHPBars
SubstituteTookDamageText: ; 3e2ac (f:62ac)
TX_FAR _SubstituteTookDamageText
@@ -5232,9 +5372,9 @@ MoveHitTest: ; 3e56b (f:656b)
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
+ cp a,DRAIN_HP_EFFECT
jp z,.moveMissed
- cp a,DREAM_EATER_EFFECT ; $08
+ cp a,DREAM_EATER_EFFECT
jp z,.moveMissed
.checkForDigOrFlyStatus
bit 6,[hl]
@@ -5394,47 +5534,50 @@ CalcHitChance: ; 3e624 (f:6624)
ld [hl],a ; store the hit chance in the move accuracy variable
ret
-Func_3e687: ; 3e687 (f:6687)
- ld hl, W_DAMAGE ; W_DAMAGE
+; multiplies damage by a random percentage from ~85% to 100%
+RandomizeDamage: ; 3e687 (f:6687)
+ ld hl, W_DAMAGE
ld a, [hli]
and a
- jr nz, .asm_3e692
+ jr nz, .DamageGreaterThanOne
ld a, [hl]
- cp $2
+ cp 2
ret c
-.asm_3e692
+.DamageGreaterThanOne
xor a
- ld [H_NUMTOPRINT], a ; $ff96 (aliases: H_MULTIPLICAND)
+ ld [H_MULTIPLICAND], a
dec hl
ld a, [hli]
- ld [$ff97], a
+ ld [H_MULTIPLICAND + 1], a
ld a, [hl]
- ld [$ff98], a
-.asm_3e69c
+ ld [H_MULTIPLICAND + 2], a
+; loop until a random number greater than or equal to 217 is generated
+.loop
call BattleRandom
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)
+ cp 217
+ jr c, .loop
+ ld [H_MULTIPLIER], a
+ call Multiply ; multiply damage by the random number, which is in the range [217, 255]
+ ld a, 255
+ ld [H_DIVISOR], a
ld b, $4
- call Divide
- ld a, [$ff97]
- ld hl, W_DAMAGE ; W_DAMAGE
+ call Divide ; divide the result by 255
+; store the modified damage
+ ld a, [H_QUOTIENT + 2]
+ ld hl, W_DAMAGE
ld [hli], a
- ld a, [$ff98]
+ ld a, [H_QUOTIENT + 3]
ld [hl], a
ret
-Func_3e6bc: ; 3e6bc (f:66bc)
- ld a, [wEnemySelectedMove] ; wccdd
+ExecuteEnemyMove: ; 3e6bc (f:66bc)
+ ld a, [wEnemySelectedMove]
inc a
jp z, Func_3e88c
call PrintGhostText
jp z, Func_3e88c
- ld a, [W_ISLINKBATTLE] ; W_ISLINKBATTLE
+ ld a, [W_ISLINKBATTLE]
cp $4
jr nz, .asm_3e6dc
ld b, $1
@@ -5447,31 +5590,31 @@ Func_3e6bc: ; 3e6bc (f:66bc)
ld hl, wccd5
inc [hl]
xor a
- ld [W_MOVEMISSED], a ; W_MOVEMISSED
+ ld [W_MOVEMISSED], a
ld [wccf4], a
ld a, $a
ld [wd05b], a
- call Func_3e88f
- jr nz, .asm_3e6f2
+ call CheckEnemyStatusConditions
+ jr nz, .canUseMove
jp [hl]
-.asm_3e6f2
- ld hl, W_ENEMYBATTSTATUS1 ; W_ENEMYBATTSTATUS1
- bit 4, [hl]
- jr nz, asm_3e70b
+.canUseMove
+ ld hl, W_ENEMYBATTSTATUS1
+ bit 4, [hl] ; is the enemy charging up for attack?
+ jr nz, asm_3e70b ; if so, jump
call GetCurrentMove
Func_3e6fc: ; 3e6fc (f:66fc)
- ld a, [W_ENEMYMOVEEFFECT] ; W_ENEMYMOVEEFFECT
+ ld a, [W_ENEMYMOVEEFFECT]
cp CHARGE_EFFECT
- jp z, Func_3f132
+ jp z, JumpMoveEffect
cp FLY_EFFECT
- jp z, Func_3f132
+ jp z, JumpMoveEffect
jr asm_3e72b
asm_3e70b: ; 3e70b (f:670b)
- ld hl, W_ENEMYBATTSTATUS1 ; W_ENEMYBATTSTATUS1
+ ld hl, W_ENEMYBATTSTATUS1
res 4, [hl] ; no longer charging up for attack
- res 6, [hl] ; no longer invulnerable to typcial attacks
- ld a, [W_ENEMYMOVENUM] ; W_ENEMYMOVENUM
+ res 6, [hl] ; no longer invulnerable to typical attacks
+ ld a, [W_ENEMYMOVENUM]
ld [wd0b5], a
ld a, BANK(MoveNames)
ld [wPredefBank], a
@@ -5484,71 +5627,71 @@ asm_3e72b: ; 3e72b (f:672b)
xor a
ld [wcced], a
call PrintMonName1Text
- ld a, [W_ENEMYMOVEEFFECT] ; W_ENEMYMOVEEFFECT
- ld hl, EffectsArray1 ; $4000
+ ld a, [W_ENEMYMOVEEFFECT]
+ ld hl, EffectsArray1
ld de, $1
call IsInArray
- jp c, Func_3f132
- ld a, [W_ENEMYMOVEEFFECT] ; W_ENEMYMOVEEFFECT
- ld hl, EffectsArray5B ; $4049
+ jp c, JumpMoveEffect
+ ld a, [W_ENEMYMOVEEFFECT]
+ ld hl, EffectsArray5B
ld de, $1
call IsInArray
- call c, Func_3f132
+ call c, JumpMoveEffect
asm_3e750: ; 3e750 (f:6750)
- call Func_3ec81
- ld a, [W_ENEMYMOVEEFFECT] ; W_ENEMYMOVEEFFECT
- ld hl, EffectsArray2 ; $4011
+ call SwapPlayerAndEnemyLevels
+ ld a, [W_ENEMYMOVEEFFECT]
+ ld hl, EffectsArray2
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
+ call SwapPlayerAndEnemyLevels
+ call GetDamageVarsForEnemyAttack
+ call SwapPlayerAndEnemyLevels
+ call CalculateDamage
jp z, Func_3e7d1
call AdjustDamageForMoveType
- call Func_3e687
+ call RandomizeDamage
Func_3e77f: ; 3e77f (f:677f)
call MoveHitTest
asm_3e782: ; 3e782 (f:6782)
- ld a, [W_MOVEMISSED] ; W_MOVEMISSED
+ ld a, [W_MOVEMISSED]
and a
jr z, .asm_3e791
- ld a, [W_ENEMYMOVEEFFECT] ; W_ENEMYMOVEEFFECT
+ ld a, [W_ENEMYMOVEEFFECT]
cp EXPLODE_EFFECT
jr z, asm_3e7a0
jr Func_3e7d1
.asm_3e791
- call Func_3ec81
+ call SwapPlayerAndEnemyLevels
Func_3e794: ; 3e794 (f:6794)
- ld a, [W_ENEMYMOVEEFFECT] ; W_ENEMYMOVEEFFECT
+ ld a, [W_ENEMYMOVEEFFECT]
and a
ld a, $1
jr z, asm_3e7a4
ld a, $2
jr asm_3e7a4
asm_3e7a0: ; 3e7a0 (f:67a0)
- call Func_3ec81
+ call SwapPlayerAndEnemyLevels
xor a
asm_3e7a4: ; 3e7a4 (f:67a4)
push af
- ld a, [W_ENEMYBATTSTATUS2] ; W_ENEMYBATTSTATUS2
+ ld a, [W_ENEMYBATTSTATUS2]
bit 4, a ; does mon have a substitute?
ld hl, Func_79747
ld b, BANK(Func_79747)
call nz, Bankswitch
pop af
ld [wcc5b], a
- ld a, [W_ENEMYMOVENUM] ; W_ENEMYMOVENUM
+ ld a, [W_ENEMYMOVENUM]
call PlayMoveAnimation
call Func_3eed3
- call Func_3cdec
- ld a, [W_ENEMYBATTSTATUS2] ; W_ENEMYBATTSTATUS2
+ call DrawEnemyHUDAndHPBar
+ ld a, [W_ENEMYBATTSTATUS2]
bit 4, a ; does mon have a substitute?
ld hl, Func_79771
ld b, BANK(Func_79771)
@@ -5556,10 +5699,10 @@ asm_3e7a4: ; 3e7a4 (f:67a4)
jr asm_3e7ef
Func_3e7d1: ; 3e7d1 (f:67d1)
- call Func_3ec81
+ call SwapPlayerAndEnemyLevels
ld c, $1e
call DelayFrames
- ld a, [W_ENEMYMOVEEFFECT] ; W_ENEMYMOVEEFFECT
+ ld a, [W_ENEMYMOVEEFFECT]
cp FLY_EFFECT
jr z, .asm_3e7e6
cp CHARGE_EFFECT
@@ -5571,7 +5714,7 @@ Func_3e7d1: ; 3e7d1 (f:67d1)
ld a,STATUS_AFFECTED_ANIM
call PlayMoveAnimation
asm_3e7ef: ; 3e7ef (f:67ef)
- ld a, [W_ENEMYMOVEEFFECT] ; W_ENEMYMOVEEFFECT
+ ld a, [W_ENEMYMOVEEFFECT]
cp MIRROR_MOVE_EFFECT
jr nz, .notMirrorMoveEffect
call MirrorMoveCopyMove
@@ -5583,58 +5726,58 @@ asm_3e7ef: ; 3e7ef (f:67ef)
call MetronomePickMove
jp Func_3e6fc
.notMetronomeEffect
- ld a, [W_ENEMYMOVEEFFECT] ; W_ENEMYMOVEEFFECT
- ld hl, EffectsArray3 ; $4014
+ ld a, [W_ENEMYMOVEEFFECT]
+ ld hl, EffectsArray3
ld de, $1
call IsInArray
- jp c, Func_3f132
- ld a, [W_MOVEMISSED] ; W_MOVEMISSED
+ jp c, JumpMoveEffect
+ ld a, [W_MOVEMISSED]
and a
jr z, .asm_3e82b
call PrintMoveFailureText
- ld a, [W_ENEMYMOVEEFFECT] ; W_ENEMYMOVEEFFECT
+ ld a, [W_ENEMYMOVEEFFECT]
cp EXPLODE_EFFECT
jr z, .asm_3e83e
jp Func_3e88c
.asm_3e82b
call ApplyAttackToPlayerPokemon
- call Func_3dc5c
+ call PrintCriticalOHKOText
callab DisplayEffectiveness
- ld a, $1
+ ld a, 1
ld [wccf4], a
.asm_3e83e
- ld a, [W_ENEMYMOVEEFFECT] ; W_ENEMYMOVEEFFECT
- ld hl, EffectsArray4 ; $4030
+ ld a, [W_ENEMYMOVEEFFECT]
+ ld hl, EffectsArray4
ld de, $1
call IsInArray
- call c, Func_3f132
- ld hl, wBattleMonHP ; wd015
+ call c, JumpMoveEffect
+ ld hl, wBattleMonHP
ld a, [hli]
ld b, [hl]
or b
ret z
call HandleBuildingRage
- ld hl, W_ENEMYBATTSTATUS1 ; W_ENEMYBATTSTATUS1
+ ld hl, W_ENEMYBATTSTATUS1
bit 2, [hl] ; is mon hitting multiple times? (example: double kick)
jr z, .asm_3e873
push hl
- ld hl, wd06f
+ ld hl, wEnemyNumAttacksLeft
dec [hl]
pop hl
jp nz, Func_3e794
res 2, [hl] ; mon is no longer hitting multiple times
- ld hl, HitXTimesText ; $6887
+ ld hl, HitXTimesText
call PrintText
xor a
ld [wcd05], a
.asm_3e873
- ld a, [W_ENEMYMOVEEFFECT] ; W_ENEMYMOVEEFFECT
+ ld a, [W_ENEMYMOVEEFFECT]
and a
jr z, Func_3e88c
- ld hl, EffectsArray5 ; $403b
+ ld hl, EffectsArray5
ld de, $1
call IsInArray
- call nc, Func_3f132
+ call nc, JumpMoveEffect
jr Func_3e88c
HitXTimesText: ; 3e887 (f:6887)
@@ -5645,93 +5788,93 @@ Func_3e88c: ; 3e88c (f:688c)
ld b, $1
ret
-Func_3e88f: ; 3e88f (f:688f)
- ld hl, wEnemyMonStatus ; wcfe9
+; checks for various status conditions affecting the enemy mon
+; stores whether the mon cannot use a move this turn in Z flag
+CheckEnemyStatusConditions: ; 3e88f (f:688f)
+ ld hl, wEnemyMonStatus
ld a, [hl]
- and $7
- jr z, .asm_3e8bf
- dec a
- ld [wEnemyMonStatus], a ; wcfe9
+ and SLP ; sleep mask
+ jr z, .checkIfFrozen
+ dec a ; decrement number of turns left
+ ld [wEnemyMonStatus], a
and a
- jr z, .asm_3e8af
+ jr z, .wokeUp ; if the number of turns hit 0, wake up
ld hl, FastAsleepText
call PrintText
xor a
ld [wcc5b], a
ld a,SLP_ANIM
call PlayMoveAnimation
- jr .asm_3e8b5
-.asm_3e8af
+ jr .next1
+.wokeUp
ld hl, WokeUpText
call PrintText
-.asm_3e8b5
+.next1
xor a
ld [wccf2], a
- ld hl, Func_3e88c ; $688c
- jp Func_3eab8
-.asm_3e8bf
- bit 5, [hl]
- jr z, .asm_3e8d3
+ ld hl, Func_3e88c
+ jp .cannotUseMove
+.checkIfFrozen
+ bit FRZ, [hl]
+ jr z, .checkIfTrapped
ld hl, IsFrozenText
call PrintText
xor a
ld [wccf2], a
- ld hl, Func_3e88c ; $688c
- jp Func_3eab8
-.asm_3e8d3
- ld a, [W_PLAYERBATTSTATUS1] ; W_PLAYERBATTSTATUS1
- bit 5, a
- jp z, Func_3e8e7
+ ld hl, Func_3e88c
+ jp .cannotUseMove
+.checkIfTrapped
+ ld a, [W_PLAYERBATTSTATUS1]
+ bit 5, a ; is the player using a multi-turn attack like warp
+ jp z, .checkIfFlinched
ld hl, CantMoveText
call PrintText
- ld hl, Func_3e88c ; $688c
- jp Func_3eab8
-
-Func_3e8e7: ; 3e8e7 (f:68e7)
- ld hl, W_ENEMYBATTSTATUS1 ; W_ENEMYBATTSTATUS1
- bit 3, [hl]
- jp z, Func_3e8fd
+ ld hl, Func_3e88c
+ jp .cannotUseMove
+.checkIfFlinched
+ ld hl, W_ENEMYBATTSTATUS1
+ bit 3, [hl] ; check if enemy mon flinched
+ jp z, .checkIfMustRecharge
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 ; W_ENEMYBATTSTATUS2
- bit 5, [hl]
- jr z, .asm_3e912
+ ld hl, Func_3e88c
+ jp .cannotUseMove
+.checkIfMustRecharge
+ ld hl, W_ENEMYBATTSTATUS2
+ bit 5, [hl] ; check if enemy mon has to recharge after using a move
+ jr z, .checkIfAnyMoveDisabled
res 5, [hl]
ld hl, MustRechargeText
call PrintText
- ld hl, Func_3e88c ; $688c
- jp Func_3eab8
-.asm_3e912
- ld hl, W_ENEMYDISABLEDMOVE ; W_ENEMYDISABLEDMOVE
+ ld hl, Func_3e88c
+ jp .cannotUseMove
+.checkIfAnyMoveDisabled
+ ld hl, W_ENEMYDISABLEDMOVE
ld a, [hl]
and a
- jr z, .asm_3e929
+ jr z, .checkIfConfused
dec a
ld [hl], a
and $f
- jr nz, .asm_3e929
+ jr nz, .checkIfConfused
ld [hl], a
ld [wccef], a
ld hl, DisabledNoMoreText
call PrintText
-.asm_3e929
- ld a, [W_ENEMYBATTSTATUS1] ; W_ENEMYBATTSTATUS1
- add a
- jp nc, Func_3e9aa
+.checkIfConfused
+ ld a, [W_ENEMYBATTSTATUS1]
+ add a ; check if enemy mon is confused
+ jp nc, .checkIfTriedToUseDisabledMove
ld hl, wd070
dec [hl]
- jr nz, .asm_3e944
- ld hl, W_ENEMYBATTSTATUS1 ; W_ENEMYBATTSTATUS1
+ jr nz, .isConfused
+ ld hl, W_ENEMYBATTSTATUS1
res 7, [hl]
ld hl, ConfusedNoMoreText
call PrintText
- jp Func_3e9aa
-.asm_3e944
+ jp .checkIfTriedToUseDisabledMove
+.isConfused
ld hl, IsConfusedText
call PrintText
xor a
@@ -5740,8 +5883,8 @@ Func_3e8fd: ; 3e8fd (f:68fd)
call PlayMoveAnimation
call BattleRandom
cp $80
- jr c, Func_3e9aa
- ld hl, W_ENEMYBATTSTATUS1 ; W_ENEMYBATTSTATUS1
+ jr c, .checkIfTriedToUseDisabledMove
+ ld hl, W_ENEMYBATTSTATUS1
ld a, [hl]
and $80
ld [hl], a
@@ -5752,23 +5895,23 @@ Func_3e8fd: ; 3e8fd (f:68fd)
push af
ld a, [hld]
push af
- ld a, [wEnemyMonDefense] ; wcff8
+ ld a, [wEnemyMonDefense]
ld [hli], a
ld a, [wEnemyMonDefense + 1]
ld [hl], a
- ld hl, W_ENEMYMOVEEFFECT ; W_ENEMYMOVEEFFECT
+ ld hl, W_ENEMYMOVEEFFECT
push hl
ld a, [hl]
push af
xor a
ld [hli], a
- ld [wd05e], a
+ ld [wCriticalHitOrOHKO], a
ld a, $28
ld [hli], a
xor a
ld [hl], a
- call Func_3de75
- call MoreCalculateDamage
+ call GetDamageVarsForEnemyAttack
+ call CalculateDamage
pop af
pop hl
ld [hl], a
@@ -5779,59 +5922,58 @@ Func_3e8fd: ; 3e8fd (f:68fd)
ld [hl], a
xor a
ld [wcc5b], a
- ld [H_WHOSETURN], a ; $fff3
+ ld [H_WHOSETURN], a
ld a, POUND
call PlayMoveAnimation
ld a, $1
- ld [H_WHOSETURN], a ; $fff3
+ ld [H_WHOSETURN], a
call ApplyDamageToEnemyPokemon
- jr asm_3e9d3
-
-Func_3e9aa: ; 3e9aa (f:69aa)
+ jr .monHurtItselfOrFullyParalysed
+.checkIfTriedToUseDisabledMove
ld a, [wccef]
and a
- jr z, .asm_3e9bf
- ld hl, wEnemySelectedMove ; wccdd
+ jr z, .checkIfParalysed
+ ld hl, wEnemySelectedMove
cp [hl]
- jr nz, .asm_3e9bf
+ jr nz, .checkIfParalysed
call PrintMoveIsDisabledText
- ld hl, Func_3e88c ; $688c
- jp Func_3eab8
-.asm_3e9bf
- ld hl, wEnemyMonStatus ; wcfe9
- bit 6, [hl]
- jr z, asm_3e9f6
+ ld hl, Func_3e88c
+ jp .cannotUseMove
+.checkIfParalysed
+ ld hl, wEnemyMonStatus
+ bit PAR, [hl]
+ jr z, .checkIfUsingBide
call BattleRandom
cp $3f
- jr nc, asm_3e9f6
+ jr nc, .checkIfUsingBide
ld hl, FullyParalyzedText
call PrintText
-asm_3e9d3: ; 3e9d3 (f:69d3)
- ld hl, W_ENEMYBATTSTATUS1 ; W_ENEMYBATTSTATUS1
+.monHurtItselfOrFullyParalysed
+ ld hl, W_ENEMYBATTSTATUS1
ld a, [hl]
- and $cc
+ and $cc ; clear bide, thrashing, charging up, and multi-turn moves such as warp
ld [hl], a
- ld a, [W_ENEMYMOVEEFFECT] ; W_ENEMYMOVEEFFECT
+ ld a, [W_ENEMYMOVEEFFECT]
cp FLY_EFFECT
- jr z, .asm_3e9e7
+ jr z, .flyOrChargeEffect
cp CHARGE_EFFECT
- jr z, .asm_3e9e7
- jr .asm_3e9f0
-.asm_3e9e7
+ jr z, .flyOrChargeEffect
+ jr .notFlyOrChargeEffect
+.flyOrChargeEffect
xor a
ld [wcc5b], 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 ; W_ENEMYBATTSTATUS1
+.notFlyOrChargeEffect
+ ld hl, Func_3e88c
+ jp .cannotUseMove
+.checkIfUsingBide
+ ld hl, W_ENEMYBATTSTATUS1
bit 0, [hl] ; is mon using bide?
- jr z, .asm_3ea54
+ jr z, .checkIfThrashingAbout
xor a
- ld [W_ENEMYMOVENUM], a ; W_ENEMYMOVENUM
- ld hl, W_DAMAGE ; W_DAMAGE
+ ld [W_ENEMYMOVENUM], a
+ ld hl, W_DAMAGE
ld a, [hli]
ld b, a
ld c, [hl]
@@ -5842,18 +5984,18 @@ asm_3e9f6: ; 3e9f6 (f:69f6)
ld a, [hl]
adc b
ld [hl], a
- ld hl, wd06f
+ ld hl, wEnemyNumAttacksLeft
dec [hl]
- jr z, .asm_3ea1c
- ld hl, Func_3e88c ; $688c
- jp Func_3eab8
-.asm_3ea1c
- ld hl, W_ENEMYBATTSTATUS1 ; W_ENEMYBATTSTATUS1
- res 0, [hl]
+ jr z, .unleashEnergy
+ ld hl, Func_3e88c
+ jp .cannotUseMove
+.unleashEnergy
+ ld hl, W_ENEMYBATTSTATUS1
+ res 0, [hl] ; not using bide any more
ld hl, UnleashedEnergyText
call PrintText
ld a, $1
- ld [W_ENEMYMOVEPOWER], a ; wcfce
+ ld [W_ENEMYMOVEPOWER], a
ld hl, wcd06
ld a, [hld]
add a
@@ -5861,33 +6003,33 @@ asm_3e9f6: ; 3e9f6 (f:69f6)
ld [wd0d8], a
ld a, [hl]
rl a
- ld [W_DAMAGE], a ; W_DAMAGE
+ ld [W_DAMAGE], a
or b
- jr nz, .asm_3ea43
+ jr nz, .next2
ld a, $1
- ld [W_MOVEMISSED], a ; W_MOVEMISSED
-.asm_3ea43
+ ld [W_MOVEMISSED], a
+.next2
xor a
ld [hli], a
ld [hl], a
ld a, BIDE
- ld [W_ENEMYMOVENUM], a ; W_ENEMYMOVENUM
- call Func_3ec81
- ld hl, asm_3e782 ; $6782
- jp Func_3eab8
-.asm_3ea54
+ ld [W_ENEMYMOVENUM], a
+ call SwapPlayerAndEnemyLevels
+ ld hl, asm_3e782
+ jp .cannotUseMove
+.checkIfThrashingAbout
bit 1, [hl] ; is mon using thrash or petal dance?
- jr z, .asm_3ea83
+ jr z, .checkIfUsingMultiturnMove
ld a, THRASH
- ld [W_ENEMYMOVENUM], a ; W_ENEMYMOVENUM
+ ld [W_ENEMYMOVENUM], a
ld hl, ThrashingAboutText
call PrintText
- ld hl, wd06f
+ ld hl, wEnemyNumAttacksLeft
dec [hl]
- ld hl, asm_3e750 ; $6750
- jp nz, Func_3eab8
+ ld hl, asm_3e750
+ jp nz, .cannotUseMove
push hl
- ld hl, W_ENEMYBATTSTATUS1 ; W_ENEMYBATTSTATUS1
+ ld hl, W_ENEMYBATTSTATUS1
res 1, [hl] ; mon is no longer using thrash or petal dance
set 7, [hl] ; mon is now confused
call BattleRandom
@@ -5896,58 +6038,55 @@ asm_3e9f6: ; 3e9f6 (f:69f6)
inc a
ld [wd070], a
pop hl
- jp Func_3eab8
-.asm_3ea83
+ jp .cannotUseMove
+.checkIfUsingMultiturnMove
bit 5, [hl] ; is mon using multi-turn move?
- jp z, Func_3ea9b
+ jp z, .checkIfUsingRage
ld hl, AttackContinuesText
call PrintText
- ld hl, wd06f
+ ld hl, wEnemyNumAttacksLeft
dec [hl]
- ld hl, Func_3e794 ; $6794
- jp nz, Func_3eab8
- jp Func_3eab8
-
-Func_3ea9b: ; 3ea9b (f:6a9b)
- ld a, [W_ENEMYBATTSTATUS2] ; W_ENEMYBATTSTATUS2
+ ld hl, Func_3e794
+ jp nz, .cannotUseMove
+ jp .cannotUseMove
+.checkIfUsingRage
+ ld a, [W_ENEMYBATTSTATUS2]
bit 6, a ; is mon using rage?
- jp z, Func_3eaba
+ jp z, .canUseMove
ld a, RAGE
ld [wd11e], a
call GetMoveName
call CopyStringToCF4B
xor a
- ld [W_ENEMYMOVEEFFECT], a ; W_ENEMYMOVEEFFECT
- ld hl, asm_3e72b ; $672b
- jp Func_3eab8
-
-Func_3eab8: ; 3eab8 (f:6ab8)
- xor a
+ ld [W_ENEMYMOVEEFFECT], a
+ ld hl, asm_3e72b
+ jp .cannotUseMove
+.cannotUseMove
+ xor a ; set Z flag
ret
-
-Func_3eaba: ; 3eaba (f:6aba)
+.canUseMove
ld a, $1
- and a
+ and a ; clear Z flag
ret
GetCurrentMove: ; 3eabe (f:6abe)
- ld a, [H_WHOSETURN] ; $fff3
+ ld a, [H_WHOSETURN]
and a
jp z, .player
- ld de, W_ENEMYMOVENUM ; W_ENEMYMOVENUM
- ld a, [wEnemySelectedMove] ; wccdd
+ ld de, W_ENEMYMOVENUM
+ ld a, [wEnemySelectedMove]
jr .selected
.player
- ld de, W_PLAYERMOVENUM ; wcfd2
+ ld de, W_PLAYERMOVENUM
ld a, [W_FLAGS_D733]
bit 0, a
ld a, [wccd9]
jr nz, .selected
- ld a, [wPlayerSelectedMove] ; wPlayerSelectedMove
+ ld a, [wPlayerSelectedMove]
.selected
ld [wd0b5], a
dec a
- ld hl, Moves ; $4000
+ ld hl, Moves
ld bc, $6
call AddNTimes
ld a, BANK(Moves)
@@ -5961,73 +6100,77 @@ GetCurrentMove: ; 3eabe (f:6abe)
ld de, wcd6d
jp CopyStringToCF4B
-Func_3eb01: ; 3eb01 (f:6b01)
- ld a, [W_ISLINKBATTLE] ; W_ISLINKBATTLE
+LoadEnemyMonData: ; 3eb01 (f:6b01)
+ ld a, [W_ISLINKBATTLE]
cp $4
- jp z, Func_3cc13
+ jp z, LoadEnemyMonFromParty
ld a, [wEnemyMonSpecies2]
ld [wEnemyMonSpecies], a
ld [wd0b5], a
call GetMonHeader
- ld a, [W_ENEMYBATTSTATUS3] ; W_ENEMYBATTSTATUS3
- bit 3, a
- ld hl, wcceb
+ ld a, [W_ENEMYBATTSTATUS3]
+ bit 3, a ; is enemy mon transformed?
+ ld hl, wcceb ; copied DVs from when it used Transform
ld a, [hli]
ld b, [hl]
- jr nz, .asm_3eb33
- ld a, [W_ISINBATTLE] ; W_ISINBATTLE
- cp $2
+ jr nz, .storeDVs
+ ld a, [W_ISINBATTLE]
+ cp $2 ; is it a trainer battle?
+; fixed DVs for trainer mon
ld a, $98
ld b, $88
- jr z, .asm_3eb33
+ jr z, .storeDVs
+; random DVs for wild mon
call BattleRandom
ld b, a
call BattleRandom
-.asm_3eb33
+.storeDVs
ld hl, wEnemyMonDVs
ld [hli], a
ld [hl], b
- ld de, wEnemyMonLevel ; wEnemyMonLevel
- ld a, [W_CURENEMYLVL] ; W_CURENEMYLVL
+ ld de, wEnemyMonLevel
+ ld a, [W_CURENEMYLVL]
ld [de], a
inc de
ld b, $0
- ld hl, wEnemyMonHP ; wEnemyMonHP
+ ld hl, wEnemyMonHP
push hl
call CalcStats
pop hl
- ld a, [W_ISINBATTLE] ; W_ISINBATTLE
- cp $2
- jr z, .asm_3eb65
- ld a, [W_ENEMYBATTSTATUS3] ; W_ENEMYBATTSTATUS3
- bit 3, a
- jr nz, .asm_3eb86
- ld a, [wEnemyMonMaxHP] ; wEnemyMonMaxHP
+ ld a, [W_ISINBATTLE]
+ cp $2 ; is it a trainer battle?
+ jr z, .copyHPAndStatusFromPartyData
+ ld a, [W_ENEMYBATTSTATUS3]
+ bit 3, a ; is enemy mon transformed?
+ jr nz, .copyTypes ; if transformed, jump
+; if it's a wild mon and not transformed, init the current HP to max HP and the status to 0
+ ld a, [wEnemyMonMaxHP]
ld [hli], a
ld a, [wEnemyMonMaxHP+1]
ld [hli], a
xor a
inc hl
- ld [hl], a
- jr .asm_3eb86
-.asm_3eb65
- ld hl, wEnemyMon1HP ; wd8a5 (aliases: W_WATERMONS)
- ld a, [wWhichPokemon] ; wWhichPokemon
+ ld [hl], a ; init status to 0
+ jr .copyTypes
+; if it's a trainer mon, copy the HP and status from the enemy party data
+.copyHPAndStatusFromPartyData
+ ld hl, wEnemyMon1HP
+ ld a, [wWhichPokemon]
ld bc, wEnemyMon2 - wEnemyMon1
call AddNTimes
ld a, [hli]
- ld [wEnemyMonHP], a ; wEnemyMonHP
+ ld [wEnemyMonHP], a
ld a, [hli]
ld [wEnemyMonHP + 1], a
- ld a, [wWhichPokemon] ; wWhichPokemon
+ ld a, [wWhichPokemon]
ld [wEnemyMonPartyPos], a
inc hl
ld a, [hl]
- ld [wEnemyMonStatus], a ; wcfe9
- jr .asm_3eb86
-.asm_3eb86
+ ld [wEnemyMonStatus], a
+ jr .copyTypes
+.copyTypes
ld hl, W_MONHTYPES
- ld de, wEnemyMonType ; wcfea
+ ld de, wEnemyMonType
ld a, [hli] ; copy type 1
ld [de], a
inc de
@@ -6037,17 +6180,19 @@ Func_3eb01: ; 3eb01 (f:6b01)
ld a, [hli] ; copy catch rate
ld [de], a
inc de
- ld a, [W_ISINBATTLE] ; W_ISINBATTLE
- cp $2
- jr nz, .asm_3ebb0
+ ld a, [W_ISINBATTLE]
+ cp $2 ; is it a trainer battle?
+ jr nz, .copyStandardMoves
+; if it's a trainer battle, copy moves from enemy party data
ld hl, wEnemyMon1Moves
- ld a, [wWhichPokemon] ; wWhichPokemon
+ ld a, [wWhichPokemon]
ld bc, wEnemyMon2 - wEnemyMon1
call AddNTimes
ld bc, NUM_MOVES
call CopyData
- jr .asm_3ebca
-.asm_3ebb0
+ jr .loadMovePPs
+.copyStandardMoves
+; for a wild mon, first copy default moves from the mon header
ld hl, W_MONHMOVES
ld a, [hli]
ld [de], a
@@ -6065,20 +6210,20 @@ Func_3eb01: ; 3eb01 (f:6b01)
dec de
xor a
ld [wHPBarMaxHP], a
- predef WriteMonMoves
-.asm_3ebca
+ predef WriteMonMoves ; get moves based on current level
+.loadMovePPs
ld hl, wEnemyMonMoves
ld de, wEnemyMonSpecial + 1
predef LoadMovePPs
ld hl, W_MONHBASESTATS
- ld de, wd002
+ ld de, wEnemyMonBaseStats
ld b, $5
-.asm_3ebdd
+.copyBaseStatsLoop
ld a, [hli]
ld [de], a
inc de
dec b
- jr nz, .asm_3ebdd
+ jr nz, .copyBaseStatsLoop
ld hl, W_MONHCATCHRATE
ld a, [hli]
ld [de], a
@@ -6099,107 +6244,113 @@ Func_3eb01: ; 3eb01 (f:6b01)
dec a
ld c, a
ld b, $1
- ld hl, wPokedexSeen ; wd30a
- predef FlagActionPredef
- ld hl, wEnemyMonLevel ; wEnemyMonLevel
- ld de, wcd23
+ ld hl, wPokedexSeen
+ predef FlagActionPredef ; mark this mon as seen in the pokedex
+ ld hl, wEnemyMonLevel
+ ld de, wEnemyMonUnmodifiedLevel
ld bc, $b
call CopyData
- ld a, $7
- ld b, $8
- ld hl, wEnemyMonStatMods ; wcd2e
-.asm_3ec2d
+ ld a, $7 ; default stat mod
+ ld b, $8 ; number of stat mods
+ ld hl, wEnemyMonStatMods
+.statModLoop
ld [hli], a
dec b
- jr nz, .asm_3ec2d
+ jr nz, .statModLoop
ret
-Func_3ec32: ; 3ec32 (f:6c32)
- ld a, [W_ISLINKBATTLE] ; W_ISLINKBATTLE
+; calls BattleTransition to show the battle transition animation and initializes some battle variables
+DoBattleTransitionAndInitBattleVariables: ; 3ec32 (f:6c32)
+ ld a, [W_ISLINKBATTLE]
cp $4
- jr nz, .asm_3ec4d
+ jr nz, .next
+; link battle
xor a
- ld [wMenuJoypadPollCount], a ; wMenuJoypadPollCount
- callab Func_372d6
+ ld [wMenuJoypadPollCount], a
+ callab DisplayLinkBattleVersusTextBox
ld a, $1
- ld [wcfcb], a
+ ld [wUpdateSpritesEnabled], a
call ClearScreen
-.asm_3ec4d
+.next
call DelayFrame
predef BattleTransition
- callab Func_3ee58
+ callab LoadHudAndHpBarAndStatusTilePatterns
ld a, $1
- ld [H_AUTOBGTRANSFERENABLED], a ; $ffba
+ ld [H_AUTOBGTRANSFERENABLED], a
ld a, $ff
- ld [wcfcb], a
+ ld [wUpdateSpritesEnabled], a
call ClearSprites
call ClearScreen
xor a
- ld [H_AUTOBGTRANSFERENABLED], a ; $ffba
- ld [$ffb0], a
- ld [rWY], a ; $ff4a
- ld [$ffd7], a
+ ld [H_AUTOBGTRANSFERENABLED], a
+ ld [hVBlankWY], a
+ ld [rWY], a
+ ld [hTilesetType], a
ld hl, wd060
ld [hli], a
ld [hli], a
ld [hli], a
ld [hli], a
ld [hl], a
- ld [W_PLAYERDISABLEDMOVE], a ; W_PLAYERDISABLEDMOVE
+ ld [W_PLAYERDISABLEDMOVE], a
ret
-Func_3ec81: ; 3ec81 (f:6c81)
+; swaps the level values of the BattleMon and EnemyMon structs
+SwapPlayerAndEnemyLevels: ; 3ec81 (f:6c81)
push bc
- ld a, [wBattleMonLevel] ; wBattleMonLevel
+ ld a, [wBattleMonLevel]
ld b, a
- ld a, [wEnemyMonLevel] ; wEnemyMonLevel
- ld [wBattleMonLevel], a ; wBattleMonLevel
+ ld a, [wEnemyMonLevel]
+ ld [wBattleMonLevel], a
ld a, b
- ld [wEnemyMonLevel], a ; wEnemyMonLevel
+ ld [wEnemyMonLevel], a
pop bc
ret
-Func_3ec92: ; 3ec92 (f:6c92)
- ld a, [W_BATTLETYPE] ; wd05a
- dec a
- ld de, RedPicBack ; $7e0a
- jr nz, .asm_3ec9e
- ld de, OldManPic ; $7e9a
-.asm_3ec9e
+; loads either red back pic or old man back pic
+; also writes OAM data and loads tile patterns for the Red or Old Man back sprite's head
+; (for use when scrolling the player sprite and enemy's silhouettes on screen)
+LoadPlayerBackPic: ; 3ec92 (f:6c92)
+ ld a, [W_BATTLETYPE]
+ dec a ; is it the old man tutorial?
+ ld de, RedPicBack
+ jr nz, .next
+ ld de, OldManPic
+.next
ld a, BANK(RedPicBack)
call UncompressSpriteFromDE
predef ScaleSpriteByTwo
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
+ ld [$FF8B], a ; initial tile number
+ ld b, $7 ; 7 columns
+ ld e, $a0 ; X for the left-most column
+.loop ; each loop iteration writes 3 OAM entries in a vertical column
+ ld c, $3 ; 3 tiles per column
+ ld d, $38 ; Y for the top of each column
+.innerLoop ; each loop iteration writes 1 OAM entry in the column
+ ld [hl], d ; OAM Y
inc hl
- ld [hl], e
- ld a, $8
- add d
+ ld [hl], e ; OAM X
+ ld a, $8 ; height of tile
+ add d ; increase Y by height of tile
ld d, a
inc hl
- ld a, [H_DOWNARROWBLINKCNT1] ; $ff8b
- ld [hli], a
- inc a
- ld [H_DOWNARROWBLINKCNT1], a ; $ff8b
+ ld a, [$FF8B]
+ ld [hli], a ; OAM tile number
+ inc a ; increment tile number
+ ld [$FF8B], a
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
+ jr nz, .innerLoop
+ ld a, [$FF8B]
+ add $4 ; increase tile number by 4
+ ld [$FF8B], a
+ ld a, $8 ; width of tile
+ add e ; increase X by width of tile
ld e, a
dec b
- jr nz, .asm_3ecb2
+ jr nz, .loop
ld de, vBackPic
call InterlaceMergeSpriteBuffers
ld a, $a
@@ -6230,24 +6381,26 @@ ScrollTrainerPicAfterBattle: ; 3ed12 (f:6d12)
ld b, BANK(_ScrollTrainerPicAfterBattle)
jp Bankswitch
-Func_3ed1a: ; 3ed1a (f:6d1a)
+ApplyBurnAndParalysisPenaltiesToPlayer: ; 3ed1a (f:6d1a)
ld a, $1
- jr asm_3ed1f
+ jr ApplyBurnAndParalysisPenalties
-Func_3ed1e: ; 3ed1e (f:6d1e)
+ApplyBurnAndParalysisPenaltiesToEnemy: ; 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
+ApplyBurnAndParalysisPenalties: ; 3ed1f (f:6d1f)
+ ld [H_WHOSETURN], a
+ call QuarterSpeedDueToParalysis
+ jp HalveAttackDueToBurn
+
+QuarterSpeedDueToParalysis: ; 3ed27 (f:6d27)
+ ld a, [H_WHOSETURN]
and a
- jr z, .asm_3ed48
- ld a, [wBattleMonStatus] ; wBattleMonStatus
- and $40
- ret z
+ jr z, .playerTurn
+.enemyTurn ; quarter the player's speed
+ ld a, [wBattleMonStatus]
+ and 1 << PAR
+ ret z ; return if player not paralysed
ld hl, wBattleMonSpeed + 1
ld a, [hld]
ld b, a
@@ -6258,15 +6411,15 @@ Func_3ed27: ; 3ed27 (f:6d27)
rr b
ld [hli], a
or b
- jr nz, .asm_3ed46
- ld b, $1
-.asm_3ed46
+ jr nz, .storePlayerSpeed
+ ld b, 1 ; give the player a minimum of at least one speed point
+.storePlayerSpeed
ld [hl], b
ret
-.asm_3ed48
- ld a, [wEnemyMonStatus] ; wcfe9
- and $40
- ret z
+.playerTurn ; quarter the enemy's speed
+ ld a, [wEnemyMonStatus]
+ and 1 << PAR
+ ret z ; return if enemy not paralysed
ld hl, wEnemyMonSpeed + 1
ld a, [hld]
ld b, a
@@ -6277,19 +6430,20 @@ Func_3ed27: ; 3ed27 (f:6d27)
rr b
ld [hli], a
or b
- jr nz, .asm_3ed62
- ld b, $1
-.asm_3ed62
+ jr nz, .storeEnemySpeed
+ ld b, 1 ; give the enemy a minimum of at least one speed point
+.storeEnemySpeed
ld [hl], b
ret
-Func_3ed64: ; 3ed64 (f:6d64)
- ld a, [H_WHOSETURN] ; $fff3
+HalveAttackDueToBurn: ; 3ed64 (f:6d64)
+ ld a, [H_WHOSETURN]
and a
- jr z, .asm_3ed81
- ld a, [wBattleMonStatus] ; wBattleMonStatus
- and $10
- ret z
+ jr z, .playerTurn
+.enemyTurn ; halve the player's attack
+ ld a, [wBattleMonStatus]
+ and 1 << BRN
+ ret z ; return if player not burnt
ld hl, wBattleMonAttack + 1
ld a, [hld]
ld b, a
@@ -6298,15 +6452,15 @@ Func_3ed64: ; 3ed64 (f:6d64)
rr b
ld [hli], a
or b
- jr nz, .asm_3ed7f
- ld b, $1
-.asm_3ed7f
+ jr nz, .storePlayerAttack
+ ld b, 1 ; give the player a minimum of at least one attack point
+.storePlayerAttack
ld [hl], b
ret
-.asm_3ed81
- ld a, [wEnemyMonStatus] ; wcfe9
- and $10
- ret z
+.playerTurn ; halve the enemy's attack
+ ld a, [wEnemyMonStatus]
+ and 1 << BRN
+ ret z ; return if enemy not burnt
ld hl, wEnemyMonAttack + 1
ld a, [hld]
ld b, a
@@ -6315,119 +6469,128 @@ Func_3ed64: ; 3ed64 (f:6d64)
rr b
ld [hli], a
or b
- jr nz, .asm_3ed97
- ld b, $1
-.asm_3ed97
+ jr nz, .storeEnemyAttack
+ ld b, 1 ; give the enemy a minimum of at least one attack point
+.storeEnemyAttack
ld [hl], b
ret
-Func_3ed99: ; 3ed99 (f:6d99)
- ld c, $0
-.asm_3ed9b
- call Func_3eda5
+CalculateModifiedStats: ; 3ed99 (f:6d99)
+ ld c, 0
+.loop
+ call CalculateModifiedStat
inc c
ld a, c
- cp $4
- jr nz, .asm_3ed9b
+ cp 4
+ jr nz, .loop
ret
-Func_3eda5: ; 3eda5 (f:6da5)
+; calculate modified stat for stat c (0 = attack, 1 = defense, 2 = speed, 3 = special)
+CalculateModifiedStat: ; 3eda5 (f:6da5)
push bc
push bc
ld a, [wd11e]
and a
ld a, c
ld hl, wBattleMonAttack
- ld de, wcd12
- ld bc, wPlayerMonAttackMod ; wcd1a
- jr z, .asm_3edc0
+ ld de, wPlayerMonUnmodifiedAttack
+ ld bc, wPlayerMonAttackMod
+ jr z, .next
ld hl, wEnemyMonAttack
- ld de, wcd26
- ld bc, wEnemyMonStatMods ; wcd2e
-.asm_3edc0
+ ld de, wEnemyMonUnmodifiedAttack
+ ld bc, wEnemyMonStatMods
+.next
add c
ld c, a
- jr nc, .asm_3edc5
+ jr nc, .noCarry1
inc b
-.asm_3edc5
+.noCarry1
ld a, [bc]
pop bc
ld b, a
push bc
sla c
- ld b, $0
+ ld b, 0
add hl, bc
ld a, c
add e
ld e, a
- jr nc, .asm_3edd4
+ jr nc, .noCarry2
inc d
-.asm_3edd4
+.noCarry2
pop bc
push hl
- ld hl, StatModifierRatios ; $76cb
+ ld hl, StatModifierRatios
dec b
sla b
ld c, b
- ld b, $0
+ ld b, 0
add hl, bc
xor a
- ld [H_NUMTOPRINT], a ; $ff96 (aliases: H_MULTIPLICAND)
+ ld [H_MULTIPLICAND], a
ld a, [de]
- ld [$ff97], a
+ ld [H_MULTIPLICAND + 1], a
inc de
ld a, [de]
- ld [$ff98], a
+ ld [H_MULTIPLICAND + 2], a
ld a, [hli]
- ld [H_REMAINDER], a ; $ff99 (aliases: H_DIVISOR, H_MULTIPLIER, H_POWEROFTEN)
+ ld [H_MULTIPLIER], a
call Multiply
ld a, [hl]
- ld [H_REMAINDER], a ; $ff99 (aliases: H_DIVISOR, H_MULTIPLIER, H_POWEROFTEN)
+ ld [H_DIVISOR], a
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 a, [H_DIVIDEND + 3]
+ sub 999 % $100
+ ld a, [H_DIVIDEND + 2]
+ sbc 999 / $100
+ jp c, .storeNewStatValue
+; cap the stat at 999
+ ld a, 999 / $100
+ ld [H_DIVIDEND + 2], a
+ ld a, 999 % $100
+ ld [H_DIVIDEND + 3], a
+.storeNewStatValue
+ ld a, [H_DIVIDEND + 2]
ld [hli], a
ld b, a
- ld a, [$ff98]
+ ld a, [H_DIVIDEND + 3]
ld [hl], a
or b
- jr nz, .asm_3ee17
- inc [hl]
-.asm_3ee17
+ jr nz, .done
+ inc [hl] ; if the stat is 0, bump it up to 1
+.done
pop bc
ret
-Func_3ee19: ; 3ee19 (f:6e19)
+ApplyBadgeStatBoosts: ; 3ee19 (f:6e19)
ld a, [W_ISLINKBATTLE]
cp $4
- ret z
+ ret z ; return if link battle
ld a, [W_OBTAINEDBADGES]
ld b, a
ld hl, wBattleMonAttack
ld c, $4
-.asm_3ee28
+; the boost is applied for badges whose bit position is even
+; the order of boosts matches the order they are laid out in RAM
+; Boulder (bit 0) - attack
+; Thunder (bit 2) - defense
+; Soul (bit 4) - speed
+; Volcano (bit 6) - special
+.loop
srl b
- call c, Func_3ee35
+ call c, .applyBoostToStat
inc hl
inc hl
srl b
dec c
- jr nz, .asm_3ee28
+ jr nz, .loop
ret
-Func_3ee35: ; 3ee35 (f:6e35)
+; multiply stat at hl by 1.125
+; cap stat at 999
+.applyBoostToStat
ld a, [hli]
ld d, a
ld e, [hl]
@@ -6444,48 +6607,48 @@ Func_3ee35: ; 3ee35 (f:6e35)
adc d
ld [hli], a
ld a, [hld]
- sub $e7
+ sub 999 % $100
ld a, [hl]
- sbc $3
+ sbc 999 / $100
ret c
- ld a, $3
+ ld a, 999 / $100
ld [hli], a
- ld a, $e7
+ ld a, 999 % $100
ld [hld], a
ret
-Func_3ee58: ; 3ee58 (f:6e58)
+LoadHudAndHpBarAndStatusTilePatterns: ; 3ee58 (f:6e58)
call LoadHpBarAndStatusTilePatterns
-Func_3ee5b: ; 3ee5b (f:6e5b)
- ld a, [rLCDC] ; $ff40
- add a
- jr c, .asm_3ee7c
- ld hl, BattleHudTiles1 ; $6080
+LoadHudTilePatterns: ; 3ee5b (f:6e5b)
+ ld a, [rLCDC]
+ add a ; is LCD disabled?
+ jr c, .lcdEnabled
+.lcdDisabled
+ ld hl, BattleHudTiles1
ld de, vChars2 + $6d0
ld bc, $18
ld a, BANK(BattleHudTiles1)
call FarCopyDataDouble
- ld hl, BattleHudTiles2 ; $6098
+ ld hl, BattleHudTiles2
ld de, vChars2 + $730
ld bc, $30
ld a, BANK(BattleHudTiles2)
jp FarCopyDataDouble
-.asm_3ee7c
- ld de, BattleHudTiles1 ; $6080
+.lcdEnabled
+ ld de, BattleHudTiles1
ld hl, vChars2 + $6d0
ld bc, (BANK(BattleHudTiles1) << 8) + $03
call CopyVideoDataDouble
- ld de, BattleHudTiles2 ; $6098
+ ld de, BattleHudTiles2
ld hl, vChars2 + $730
ld bc, (BANK(BattleHudTiles2) << 8) + $06
jp CopyVideoDataDouble
-Func_3ee94: ; 3ee94 (f:6e94)
- ld hl, TerminatorText_3ee9a ; $6e9a
+PrintEmptyString: ; 3ee94 (f:6e94)
+ ld hl, .emptyString
jp PrintText
-
-TerminatorText_3ee9a: ; 3ee9a (f:6e9a)
+.emptyString
db "@"
@@ -6538,15 +6701,15 @@ BattleRandom:
Func_3eed3: ; 3eed3 (f:6ed3)
- ld a, [H_WHOSETURN] ; $fff3
+ ld a, [H_WHOSETURN]
and a
ld hl, wEnemyMonType1 ; wcfea (aliases: wEnemyMonType)
- ld de, W_ENEMYBATTSTATUS1 ; W_ENEMYBATTSTATUS1
- ld a, [W_PLAYERMOVENUM] ; wcfd2
+ ld de, W_ENEMYBATTSTATUS1
+ ld a, [W_PLAYERMOVENUM]
jr z, .asm_3eeea
ld hl, wBattleMonType1 ; wd019 (aliases: wBattleMonType)
- ld de, W_ENEMYBATTSTATUS1 ; W_ENEMYBATTSTATUS1
- ld a, [W_ENEMYMOVENUM] ; W_ENEMYMOVENUM
+ ld de, W_ENEMYBATTSTATUS1
+ ld a, [W_ENEMYMOVENUM]
.asm_3eeea
cp SELFDESTRUCT
jr z, .asm_3eef1
@@ -6562,7 +6725,7 @@ Func_3eed3: ; 3eed3 (f:6ed3)
ld a, [hl]
cp GHOST
ret z
- ld a, [W_MOVEMISSED] ; W_MOVEMISSED
+ ld a, [W_MOVEMISSED]
and a
ret nz
ld a, MEGA_PUNCH
@@ -6574,12 +6737,12 @@ PlayMoveAnimation: ; 3ef07 (f:6f07)
predef_jump MoveAnimation
InitBattle: ; 3ef12 (f:6f12)
- ld a, [W_CUROPPONENT] ; wd059
+ ld a, [W_CUROPPONENT]
and a
jr z, asm_3ef23
InitOpponent: ; 3ef18 (f:6f18)
- ld a, [W_CUROPPONENT] ; wd059
+ ld a, [W_CUROPPONENT]
ld [wcf91], a
ld [wEnemyMonSpecies2], a
jr asm_3ef3d
@@ -6588,16 +6751,16 @@ asm_3ef23: ; 3ef23 (f:6f23)
bit 1, a
jr z, .asm_3ef2f
ld a, [hJoyHeld]
- bit 1, a
+ bit 1, a ; B button pressed?
ret nz
.asm_3ef2f
- ld a, [wd13c]
+ ld a, [wNumberOfNoRandomBattleStepsLeft]
and a
ret nz
callab Func_13870
ret nz
asm_3ef3d: ; 3ef3d (f:6f3d)
- ld a, [wd35d]
+ ld a, [wMapPalOffset]
push af
ld hl, wd358
ld a, [hl]
@@ -6607,30 +6770,30 @@ asm_3ef3d: ; 3ef3d (f:6f3d)
ld a, [wEnemyMonSpecies2]
sub $c8
jp c, InitWildBattle
- ld [W_TRAINERCLASS], a ; wd031
+ ld [W_TRAINERCLASS], a
call GetTrainerInformation
callab ReadTrainer
- call Func_3ec32
+ call DoBattleTransitionAndInitBattleVariables
call _LoadTrainerPic
xor a
ld [wEnemyMonSpecies2], a
ld [$ffe1], a
dec a
- ld [wAICount], a ; wccdf
+ ld [wAICount], a
hlCoord 12, 0
predef Func_3f0c6
ld a, $ff
ld [wEnemyMonPartyPos], a
ld a, $2
- ld [W_ISINBATTLE], a ; W_ISINBATTLE
- jp Func_3efeb
+ ld [W_ISINBATTLE], a
+ jp InitBattle_Common
InitWildBattle: ; 3ef8b (f:6f8b)
ld a, $1
- ld [W_ISINBATTLE], a ; W_ISINBATTLE
- call Func_3eb01
- call Func_3ec32
- ld a, [W_CUROPPONENT] ; wd059
+ ld [W_ISINBATTLE], a
+ call LoadEnemyMonData
+ call DoBattleTransitionAndInitBattleVariables
+ ld a, [W_CUROPPONENT]
cp MAROWAK
jr z, .isGhost
call IsGhostBattle
@@ -6639,7 +6802,7 @@ InitWildBattle: ; 3ef8b (f:6f8b)
ld hl, W_MONHSPRITEDIM
ld a, $66
ld [hli], a ; write sprite dimensions
- ld bc, GhostPic ; $66b5
+ ld bc, GhostPic
ld a, c
ld [hli], a ; write front sprite pointer
ld [hl], b
@@ -6669,25 +6832,26 @@ InitWildBattle: ; 3ef8b (f:6f8b)
call LoadMonFrontSprite ; load mon sprite
.spriteLoaded
xor a
- ld [W_TRAINERCLASS], a ; wd031
+ ld [W_TRAINERCLASS], a
ld [$ffe1], a
hlCoord 12, 0
predef Func_3f0c6
-Func_3efeb: ; 3efeb (f:6feb)
+; common code that executes after init battle code specific to trainer or wild battles
+InitBattle_Common: ; 3efeb (f:6feb)
ld b, $0
call GoPAL_SET
- call Func_3c04c
+ call SlidePlayerAndEnemySilhouettesOnScreen
xor a
- ld [H_AUTOBGTRANSFERENABLED], a ; $ffba
- ld hl, TerminatorText_3f04a
+ ld [H_AUTOBGTRANSFERENABLED], a
+ ld hl, .emptyString
call PrintText
call SaveScreenTilesToBuffer1
call ClearScreen
ld a, $98
ld [$ffbd], a
ld a, $1
- ld [H_AUTOBGTRANSFERENABLED], a ; $ffba
+ ld [H_AUTOBGTRANSFERENABLED], a
call Delay3
ld a, $9c
ld [$ffbd], a
@@ -6699,21 +6863,20 @@ Func_3efeb: ; 3efeb (f:6feb)
ld bc, $40a
call ClearScreenArea
call ClearSprites
- ld a, [W_ISINBATTLE] ; W_ISINBATTLE
- dec a
- call z, Func_3cdec
- call Func_3c11e
- callab Func_137aa
+ ld a, [W_ISINBATTLE]
+ dec a ; is it a wild battle?
+ call z, DrawEnemyHUDAndHPBar ; draw enemy HUD and HP bar if it's a wild battle
+ call StartBattle
+ callab EndOfBattle
pop af
ld [wd358], a
pop af
- ld [wd35d], a
+ ld [wMapPalOffset], a
ld a, [wd0d4]
- ld [$ffd7], a
+ ld [hTilesetType], a
scf
ret
-
-TerminatorText_3f04a: ; 3f04a (f:704a)
+.emptyString
db "@"
_LoadTrainerPic: ; 3f04b (f:704b)
@@ -6722,7 +6885,7 @@ _LoadTrainerPic: ; 3f04b (f:704b)
ld e, a
ld a, [wd034]
ld d, a ; de contains pointer to trainer pic
- ld a, [W_ISLINKBATTLE] ; W_ISLINKBATTLE
+ ld a, [W_ISLINKBATTLE]
and a
ld a, Bank(TrainerPics) ; this is where all the trainer pics are (not counting Red's)
jr z, .loadSprite
@@ -6746,15 +6909,15 @@ Func_3f073: ; 3f073 (f:7073)
ld a, [wPredefRegisters + 1]
ld l, a
ld a, [$ffe1]
- ld [H_DOWNARROWBLINKCNT1], a ; $ff8b
+ ld [H_DOWNARROWBLINKCNT1], a
ld b, $4c
- ld a, [W_ISINBATTLE] ; W_ISINBATTLE
+ ld a, [W_ISINBATTLE]
and a
jr z, .asm_3f0bc
add b
ld [hl], a
call Delay3
- ld bc, $ffd7
+ ld bc, -41
add hl, bc
ld a, $1
ld [wcd6c], a
@@ -6762,7 +6925,7 @@ Func_3f073: ; 3f073 (f:7073)
predef Func_79aba
ld c, $4
call DelayFrames
- ld bc, $ffd7
+ ld bc, -41
add hl, bc
xor a
ld [wcd6c], a
@@ -6770,13 +6933,13 @@ Func_3f073: ; 3f073 (f:7073)
predef Func_79aba
ld c, $5
call DelayFrames
- ld bc, $ffd7
+ ld bc, -41
jr .asm_3f0bf
.asm_3f0bc
- ld bc, $ff85
+ ld bc, -123
.asm_3f0bf
add hl, bc
- ld a, [H_DOWNARROWBLINKCNT1] ; $ff8b
+ ld a, [H_DOWNARROWBLINKCNT1]
add $31
jr asm_3f0d0
@@ -6853,12 +7016,12 @@ LoadMonBackPic:
ld b, a
jp CopyVideoData
-Func_3f132: ; 3f132 (f:7132)
- call JumpMoveEffect
+JumpMoveEffect: ; 3f132 (f:7132)
+ call _JumpMoveEffect
ld b, $1
ret
-JumpMoveEffect: ; 3f138 (f:7138)
+_JumpMoveEffect: ; 3f138 (f:7138)
ld a, [$fff3] ;whose turn?
and a
ld a, [W_PLAYERMOVEEFFECT]
@@ -6965,13 +7128,13 @@ MoveEffectPointerTable: ; 3f150 (f:7150)
dw DisableEffect ; DISABLE_EFFECT
SleepEffect: ; 3f1fc (f:71fc)
- ld de, wEnemyMonStatus ; wcfe9
- ld bc, W_ENEMYBATTSTATUS2 ; W_ENEMYBATTSTATUS2
- ld a, [H_WHOSETURN] ; $fff3
+ ld de, wEnemyMonStatus
+ ld bc, W_ENEMYBATTSTATUS2
+ ld a, [H_WHOSETURN]
and a
jp z, .asm_3f20e
- ld de, wBattleMonStatus ; wBattleMonStatus
- ld bc, W_PLAYERBATTSTATUS2 ; W_PLAYERBATTSTATUS2
+ ld de, wBattleMonStatus
+ ld bc, W_PLAYERBATTSTATUS2
.asm_3f20e
ld a, [bc]
@@ -6992,7 +7155,7 @@ SleepEffect: ; 3f1fc (f:71fc)
push de
call MoveHitTest
pop de
- ld a, [W_MOVEMISSED] ; W_MOVEMISSED
+ ld a, [W_MOVEMISSED]
and a
jr nz, .asm_3f242
.asm_3f231
@@ -7015,13 +7178,13 @@ AlreadyAsleepText: ; 3f24a (f:724a)
db "@"
PoisonEffect: ; 3f24f (f:724f)
- ld hl, wEnemyMonStatus ; wcfe9
- ld de, W_PLAYERMOVEEFFECT ; wcfd3
- ld a, [H_WHOSETURN] ; $fff3
+ ld hl, wEnemyMonStatus
+ ld de, W_PLAYERMOVEEFFECT
+ ld a, [H_WHOSETURN]
and a
jr z, .asm_3f260
- ld hl, wBattleMonStatus ; wBattleMonStatus
- ld de, W_ENEMYMOVEEFFECT ; W_ENEMYMOVEEFFECT
+ ld hl, wBattleMonStatus
+ ld de, W_ENEMYMOVEEFFECT
.asm_3f260
call CheckTargetSubstitute
jr nz, .asm_3f2d3
@@ -7047,7 +7210,7 @@ PoisonEffect: ; 3f24f (f:724f)
call MoveHitTest
pop de
pop hl
- ld a, [W_MOVEMISSED] ; W_MOVEMISSED
+ ld a, [W_MOVEMISSED]
and a
jr nz, .asm_3f2d7
jr .asm_3f295
@@ -7060,16 +7223,16 @@ PoisonEffect: ; 3f24f (f:724f)
set 3, [hl]
push de
dec de
- ld a, [H_WHOSETURN] ; $fff3
+ ld a, [H_WHOSETURN]
and a
ld b, ANIM_C7
- ld hl, W_PLAYERBATTSTATUS3 ; W_PLAYERBATTSTATUS3
+ ld hl, W_PLAYERBATTSTATUS3
ld a, [de]
- ld de, W_PLAYERTOXICCOUNTER ; wd06c
+ ld de, W_PLAYERTOXICCOUNTER
jr nz, .asm_3f2b0
ld b, ANIM_A9
- ld hl, W_ENEMYBATTSTATUS3 ; W_ENEMYBATTSTATUS3
- ld de, W_ENEMYTOXICCOUNTER ; wd071
+ ld hl, W_ENEMYBATTSTATUS3
+ ld de, W_ENEMYTOXICCOUNTER
.asm_3f2b0
cp TOXIC
jr nz, .asm_3f2bd
@@ -7114,13 +7277,13 @@ DrainHPEffect: ; 3f2e9 (f:72e9)
jp Bankswitch
ExplodeEffect: ; 3f2f1 (f:72f1)
- ld hl, wBattleMonHP ; wd015
- ld de, W_PLAYERBATTSTATUS2 ; W_PLAYERBATTSTATUS2
- ld a, [H_WHOSETURN] ; $fff3
+ ld hl, wBattleMonHP
+ ld de, W_PLAYERBATTSTATUS2
+ ld a, [H_WHOSETURN]
and a
jr z, .asm_3f302
- ld hl, wEnemyMonHP ; wEnemyMonHP
- ld de, W_ENEMYBATTSTATUS2 ; W_ENEMYBATTSTATUS2
+ ld hl, wEnemyMonHP
+ ld de, W_ENEMYBATTSTATUS2
.asm_3f302
xor a
ld [hli], a ; set the mon's HP to 0
@@ -7172,14 +7335,14 @@ FreezeBurnParalyzeEffect: ; 3f30c (f:730c)
jr z, .freeze
ld a, 1 << PAR
ld [wEnemyMonStatus], a
- call Func_3ed27 ;quarter speed of affected monster
+ call QuarterSpeedDueToParalysis ;quarter speed of affected monster
ld a, ANIM_A9
call Func_3fbb9 ;animation
jp PrintMayNotAttackText ;print paralysis text
.burn
ld a, 1 << BRN
ld [wEnemyMonStatus], a
- call Func_3ed64
+ call HalveAttackDueToBurn
ld a, ANIM_A9
call Func_3fbb9 ;animation
ld hl, BurnedText
@@ -7223,12 +7386,12 @@ opponentAttacker: ; 3f382 (f:7382)
jr z, .freeze
ld a, 1 << PAR
ld [wBattleMonStatus], a
- call Func_3ed27
+ call QuarterSpeedDueToParalysis
jp PrintMayNotAttackText
.burn
ld a, 1 << BRN
ld [wBattleMonStatus], a
- call Func_3ed64
+ call HalveAttackDueToBurn
ld hl, BurnedText
jp PrintText
.freeze
@@ -7286,13 +7449,13 @@ FireDefrostedText: ; 3f423 (f:7423)
db "@"
StatModifierUpEffect: ; 3f428 (f:7428)
- ld hl, wPlayerMonStatMods ; wcd1a
- ld de, W_PLAYERMOVEEFFECT ; wcfd3
- ld a, [H_WHOSETURN] ; $fff3
+ ld hl, wPlayerMonStatMods
+ ld de, W_PLAYERMOVEEFFECT
+ ld a, [H_WHOSETURN]
and a
jr z, .asm_3f439
- ld hl, wEnemyMonStatMods ; wcd2e
- ld de, W_ENEMYMOVEEFFECT ; W_ENEMYMOVEEFFECT
+ ld hl, wEnemyMonStatMods
+ ld de, W_ENEMYMOVEEFFECT
.asm_3f439
ld a, [de]
sub $a
@@ -7324,11 +7487,11 @@ StatModifierUpEffect: ; 3f428 (f:7428)
push hl
ld hl, wBattleMonAttack + 1
ld de, wcd12
- ld a, [H_WHOSETURN] ; $fff3
+ ld a, [H_WHOSETURN]
and a
jr z, .asm_3f472
ld hl, wEnemyMonAttack + 1
- ld de, wcd26
+ ld de, wEnemyMonUnmodifiedAttack
.asm_3f472
push bc
sla c
@@ -7350,7 +7513,7 @@ StatModifierUpEffect: ; 3f428 (f:7428)
.asm_3f48a
push hl
push bc
- ld hl, StatModifierRatios ; $76cb
+ ld hl, StatModifierRatios
dec b
sla b
ld c, b
@@ -7392,14 +7555,14 @@ asm_3f4ca: ; 3f4ca (f:74ca)
ld b, c
inc b
call Func_3f688
- ld hl, W_PLAYERBATTSTATUS2 ; W_PLAYERBATTSTATUS2
- ld de, W_PLAYERMOVENUM ; wcfd2
+ ld hl, W_PLAYERBATTSTATUS2
+ ld de, W_PLAYERMOVENUM
ld bc, wccf7
- ld a, [H_WHOSETURN] ; $fff3
+ ld a, [H_WHOSETURN]
and a
jr z, .asm_3f4e6
- ld hl, W_ENEMYBATTSTATUS2 ; W_ENEMYBATTSTATUS2
- ld de, W_ENEMYMOVENUM ; W_ENEMYMOVENUM
+ ld hl, W_ENEMYBATTSTATUS2
+ ld de, W_ENEMYMOVENUM
ld bc, wccf3
.asm_3f4e6
ld a, [de]
@@ -7426,13 +7589,13 @@ asm_3f4ca: ; 3f4ca (f:74ca)
pop af
call nz, Bankswitch
.asm_3f50e
- ld a, [H_WHOSETURN] ; $fff3
+ ld a, [H_WHOSETURN]
and a
- call z, Func_3ee19
+ call z, ApplyBadgeStatBoosts
ld hl, MonsStatsRoseText
call PrintText
- call Func_3ed27
- jp Func_3ed64
+ call QuarterSpeedDueToParalysis
+ jp HalveAttackDueToBurn
Func_3f520: ; 3f520 (f:7520)
pop hl
@@ -7446,11 +7609,11 @@ MonsStatsRoseText: ; 3f528 (f:7528)
TX_FAR _MonsStatsRoseText
db $08 ; asm
ld hl, GreatlyRoseText
- ld a, [H_WHOSETURN] ; $fff3
+ ld a, [H_WHOSETURN]
and a
- ld a, [W_PLAYERMOVEEFFECT] ; wcfd3
+ ld a, [W_PLAYERMOVEEFFECT]
jr z, .asm_3f53b
- ld a, [W_ENEMYMOVEEFFECT] ; W_ENEMYMOVEEFFECT
+ ld a, [W_ENEMYMOVEEFFECT]
.asm_3f53b
cp ATTACK_DOWN1_EFFECT
ret nc
@@ -7466,16 +7629,16 @@ RoseText: ; 3f547 (f:7547)
db "@"
StatModifierDownEffect: ; 3f54c (f:754c)
- ld hl, wEnemyMonStatMods ; wcd2e
- ld de, W_PLAYERMOVEEFFECT ; wcfd3
- ld bc, W_ENEMYBATTSTATUS1 ; W_ENEMYBATTSTATUS1
- ld a, [H_WHOSETURN] ; $fff3
+ ld hl, wEnemyMonStatMods
+ ld de, W_PLAYERMOVEEFFECT
+ ld bc, W_ENEMYBATTSTATUS1
+ ld a, [H_WHOSETURN]
and a
jr z, .asm_3f572
- ld hl, wPlayerMonStatMods ; wcd1a
- ld de, W_ENEMYMOVEEFFECT ; W_ENEMYMOVEEFFECT
- ld bc, W_PLAYERBATTSTATUS1 ; W_PLAYERBATTSTATUS1
- ld a, [W_ISLINKBATTLE] ; W_ISLINKBATTLE
+ ld hl, wPlayerMonStatMods
+ ld de, W_ENEMYMOVEEFFECT
+ ld bc, W_PLAYERBATTSTATUS1
+ ld a, [W_ISLINKBATTLE]
cp $4
jr z, .asm_3f572
call BattleRandom
@@ -7501,7 +7664,7 @@ StatModifierDownEffect: ; 3f54c (f:754c)
pop bc
pop de
pop hl
- ld a, [W_MOVEMISSED] ; W_MOVEMISSED
+ ld a, [W_MOVEMISSED]
and a
jp nz, Func_3f65a
ld a, [bc]
@@ -7535,8 +7698,8 @@ StatModifierDownEffect: ; 3f54c (f:754c)
push hl
push de
ld hl, wEnemyMonAttack + 1
- ld de, wcd26
- ld a, [H_WHOSETURN] ; $fff3
+ ld de, wEnemyMonUnmodifiedAttack
+ ld a, [H_WHOSETURN]
and a
jr z, .asm_3f5d8
ld hl, wBattleMonAttack + 1
@@ -7562,7 +7725,7 @@ StatModifierDownEffect: ; 3f54c (f:754c)
.asm_3f5ef
push hl
push bc
- ld hl, StatModifierRatios ; $76cb
+ ld hl, StatModifierRatios
dec b
sla b
ld c, b
@@ -7611,13 +7774,13 @@ asm_3f62c: ; 3f62c (f:762c)
jr nc, .asm_3f63b
call Func_3fb89
.asm_3f63b
- ld a, [H_WHOSETURN] ; $fff3
+ ld a, [H_WHOSETURN]
and a
- call nz, Func_3ee19
+ call nz, ApplyBadgeStatBoosts
ld hl, MonsStatsFellText
call PrintText
- call Func_3ed27
- jp Func_3ed64
+ call QuarterSpeedDueToParalysis
+ jp HalveAttackDueToBurn
Func_3f64d: ; 3f64d (f:764d)
pop de
@@ -7641,11 +7804,11 @@ MonsStatsFellText: ; 3f661 (f:7661)
TX_FAR _MonsStatsFellText
db $08 ; asm
ld hl, FellText
- ld a, [H_WHOSETURN] ; $fff3
+ ld a, [H_WHOSETURN]
and a
- ld a, [W_PLAYERMOVEEFFECT] ; wcfd3
+ ld a, [W_PLAYERMOVEEFFECT]
jr z, .asm_3f674
- ld a, [W_ENEMYMOVEEFFECT] ; W_ENEMYMOVEEFFECT
+ ld a, [W_ENEMYMOVEEFFECT]
.asm_3f674
cp $1a
ret c
@@ -7705,13 +7868,13 @@ StatModifierRatios: ; 3f6cb (f:76cb)
BideEffect: ; 3f6e5 (f:76e5)
ld hl, W_PLAYERBATTSTATUS1
ld de, W_NUMHITS
- ld bc, wd06a
+ ld bc, wPlayerNumAttacksLeft
ld a, [H_WHOSETURN]
and a
jr z, .asm_3f6fc
ld hl, W_ENEMYBATTSTATUS1
ld de, wcd05
- ld bc, wd06f
+ ld bc, wEnemyNumAttacksLeft
.asm_3f6fc
set 0, [hl] ; mon is now using bide
xor a
@@ -7730,13 +7893,13 @@ BideEffect: ; 3f6e5 (f:76e5)
jp Func_3fb96
ThrashPetalDanceEffect: ; 3f717 (f:7717)
- ld hl, W_PLAYERBATTSTATUS1 ; W_PLAYERBATTSTATUS1
- ld de, wd06a
- ld a, [H_WHOSETURN] ; $fff3
+ ld hl, W_PLAYERBATTSTATUS1
+ ld de, wPlayerNumAttacksLeft
+ ld a, [H_WHOSETURN]
and a
jr z, .asm_3f728
- ld hl, W_ENEMYBATTSTATUS1 ; W_ENEMYBATTSTATUS1
- ld de, wd06f
+ ld hl, W_ENEMYBATTSTATUS1
+ ld de, wEnemyNumAttacksLeft
.asm_3f728
set 1, [hl] ; mon is now using thrash/petal dance
call BattleRandom
@@ -7744,20 +7907,20 @@ ThrashPetalDanceEffect: ; 3f717 (f:7717)
inc a
inc a
ld [de], a
- ld a, [H_WHOSETURN] ; $fff3
+ ld a, [H_WHOSETURN]
add ANIM_B0
jp Func_3fb96
SwitchAndTeleportEffect: ; 3f739 (f:7739)
- ld a, [H_WHOSETURN] ; $fff3
+ ld a, [H_WHOSETURN]
and a
jr nz, .asm_3f791
- ld a, [W_ISINBATTLE] ; W_ISINBATTLE
+ ld a, [W_ISINBATTLE]
dec a
jr nz, .asm_3f77e
- ld a, [W_CURENEMYLVL] ; W_CURENEMYLVL
+ ld a, [W_CURENEMYLVL]
ld b, a
- ld a, [wBattleMonLevel] ; wBattleMonLevel
+ ld a, [wBattleMonLevel]
cp b
jr nc, .asm_3f76e
add b
@@ -7773,7 +7936,7 @@ SwitchAndTeleportEffect: ; 3f739 (f:7739)
jr nc, .asm_3f76e
ld c, $32
call DelayFrames
- ld a, [W_PLAYERMOVENUM] ; wcfd2
+ ld a, [W_PLAYERMOVENUM]
cp TELEPORT
jp nz, PrintDidntAffectText
jp PrintButItFailedText_
@@ -7782,24 +7945,24 @@ SwitchAndTeleportEffect: ; 3f739 (f:7739)
xor a
ld [wcc5b], a
inc a
- ld [wd078], a
- ld a, [W_PLAYERMOVENUM] ; wcfd2
+ ld [wEscapedFromBattle], a
+ ld a, [W_PLAYERMOVENUM]
jr .asm_3f7e4
.asm_3f77e
ld c, $32
call DelayFrames
ld hl, IsUnaffectedText
- ld a, [W_PLAYERMOVENUM] ; wcfd2
+ ld a, [W_PLAYERMOVENUM]
cp TELEPORT
jp nz, PrintText
jp PrintButItFailedText_
.asm_3f791
- ld a, [W_ISINBATTLE] ; W_ISINBATTLE
+ ld a, [W_ISINBATTLE]
dec a
jr nz, .asm_3f7d1
- ld a, [wBattleMonLevel] ; wBattleMonLevel
+ ld a, [wBattleMonLevel]
ld b, a
- ld a, [W_CURENEMYLVL] ; W_CURENEMYLVL
+ ld a, [W_CURENEMYLVL]
cp b
jr nc, .asm_3f7c1
add b
@@ -7815,7 +7978,7 @@ SwitchAndTeleportEffect: ; 3f739 (f:7739)
jr nc, .asm_3f7c1
ld c, $32
call DelayFrames
- ld a, [W_ENEMYMOVENUM] ; W_ENEMYMOVENUM
+ ld a, [W_ENEMYMOVENUM]
cp TELEPORT
jp nz, PrintDidntAffectText
jp PrintButItFailedText_
@@ -7824,14 +7987,14 @@ SwitchAndTeleportEffect: ; 3f739 (f:7739)
xor a
ld [wcc5b], a
inc a
- ld [wd078], a
- ld a, [W_ENEMYMOVENUM] ; W_ENEMYMOVENUM
+ ld [wEscapedFromBattle], a
+ ld a, [W_ENEMYMOVENUM]
jr .asm_3f7e4
.asm_3f7d1
ld c, $32
call DelayFrames
ld hl, IsUnaffectedText
- ld a, [W_ENEMYMOVENUM] ; W_ENEMYMOVENUM
+ ld a, [W_ENEMYMOVENUM]
cp TELEPORT
jp nz, PrintText
jp Func_3fb4e
@@ -7841,13 +8004,13 @@ SwitchAndTeleportEffect: ; 3f739 (f:7739)
ld c, $14
call DelayFrames
pop af
- ld hl, RanFromBattleText ; $7802
+ ld hl, RanFromBattleText
cp TELEPORT
jr z, .asm_3f7ff
- ld hl, RanAwayScaredText ; $7807
+ ld hl, RanAwayScaredText
cp ROAR
jr z, .asm_3f7ff
- ld hl, WasBlownAwayText ; $780c
+ ld hl, WasBlownAwayText
.asm_3f7ff
jp PrintText
@@ -7864,24 +8027,24 @@ WasBlownAwayText: ; 3f80c (f:780c)
db "@"
TwoToFiveAttacksEffect: ; 3f811 (f:7811)
- ld hl, W_PLAYERBATTSTATUS1 ; W_PLAYERBATTSTATUS1
- ld de, wd06a
- ld bc, W_NUMHITS ; wd074
- ld a, [H_WHOSETURN] ; $fff3
+ ld hl, W_PLAYERBATTSTATUS1
+ ld de, wPlayerNumAttacksLeft
+ ld bc, W_NUMHITS
+ ld a, [H_WHOSETURN]
and a
jr z, .asm_3f828
- ld hl, W_ENEMYBATTSTATUS1 ; W_ENEMYBATTSTATUS1
- ld de, wd06f
+ ld hl, W_ENEMYBATTSTATUS1
+ ld de, wEnemyNumAttacksLeft
ld bc, wcd05
.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 ; wcfd3
- ld a, [H_WHOSETURN] ; $fff3
+ ld hl, W_PLAYERMOVEEFFECT
+ ld a, [H_WHOSETURN]
and a
jr z, .asm_3f838
- ld hl, W_ENEMYMOVEEFFECT ; W_ENEMYMOVEEFFECT
+ ld hl, W_ENEMYMOVEEFFECT
.asm_3f838
ld a, [hl]
cp TWINEEDLE_EFFECT
@@ -7910,13 +8073,13 @@ TwoToFiveAttacksEffect: ; 3f811 (f:7811)
FlichSideEffect: ; 3f85b (f:785b)
call CheckTargetSubstitute
ret nz
- ld hl, W_ENEMYBATTSTATUS1 ; W_ENEMYBATTSTATUS1
- ld de, W_PLAYERMOVEEFFECT ; wcfd3
- ld a, [H_WHOSETURN] ; $fff3
+ ld hl, W_ENEMYBATTSTATUS1
+ ld de, W_PLAYERMOVEEFFECT
+ ld a, [H_WHOSETURN]
and a
jr z, .asm_3f870
- ld hl, W_PLAYERBATTSTATUS1 ; W_PLAYERBATTSTATUS1
- ld de, W_ENEMYMOVEEFFECT ; W_ENEMYMOVEEFFECT
+ ld hl, W_PLAYERBATTSTATUS1
+ ld de, W_ENEMYMOVEEFFECT
.asm_3f870
ld a, [de]
cp FLINCH_SIDE_EFFECT1
@@ -7937,14 +8100,14 @@ OneHitKOEffect: ; 3f884 (f:7884)
jp Bankswitch
ChargeEffect: ; 3f88c (f:788c)
- ld hl, W_PLAYERBATTSTATUS1 ; W_PLAYERBATTSTATUS1
- ld de, W_PLAYERMOVEEFFECT ; wcfd3
- ld a, [H_WHOSETURN] ; $fff3
+ ld hl, W_PLAYERBATTSTATUS1
+ ld de, W_PLAYERMOVEEFFECT
+ ld a, [H_WHOSETURN]
and a
ld b, XSTATITEM_ANIM
jr z, .asm_3f8a1
- ld hl, W_ENEMYBATTSTATUS1 ; W_ENEMYBATTSTATUS1
- ld de, W_ENEMYMOVEEFFECT ; W_ENEMYMOVEEFFECT
+ ld hl, W_ENEMYBATTSTATUS1
+ ld de, W_ENEMYMOVEEFFECT
ld b, ANIM_AF
.asm_3f8a1
set 4, [hl]
@@ -7966,31 +8129,31 @@ ChargeEffect: ; 3f88c (f:788c)
ld a, b
call Func_3fbb9
ld a, [de]
- ld [wWhichTrade], a ; wWhichTrade
- ld hl, ChargeMoveEffectText ; $78c8
+ ld [wWhichTrade], a
+ ld hl, ChargeMoveEffectText
jp PrintText
ChargeMoveEffectText: ; 3f8c8 (f:78c8)
TX_FAR _ChargeMoveEffectText
db $08 ; asm
- ld a, [wWhichTrade] ; wWhichTrade
+ ld a, [wWhichTrade]
cp RAZOR_WIND
- ld hl, MadeWhirlwindText ; $78f9
+ ld hl, MadeWhirlwindText
jr z, .asm_3f8f8
cp SOLARBEAM
- ld hl, TookInSunlightText ; $78fe
+ ld hl, TookInSunlightText
jr z, .asm_3f8f8
cp SKULL_BASH
- ld hl, LoweredItsHeadText ; $7903
+ ld hl, LoweredItsHeadText
jr z, .asm_3f8f8
cp SKY_ATTACK
- ld hl, SkyAttackGlowingText ; $7908
+ ld hl, SkyAttackGlowingText
jr z, .asm_3f8f8
cp FLY
- ld hl, FlewUpHighText ; $790d
+ ld hl, FlewUpHighText
jr z, .asm_3f8f8
cp DIG
- ld hl, DugAHoleText ; $7912
+ ld hl, DugAHoleText
.asm_3f8f8
ret
@@ -8019,13 +8182,13 @@ DugAHoleText: ; 3f912 (f:7912)
db "@"
TrappingEffect: ; 3f917 (f:7917)
- ld hl, W_PLAYERBATTSTATUS1 ; W_PLAYERBATTSTATUS1
- ld de, wd06a
- ld a, [H_WHOSETURN] ; $fff3
+ ld hl, W_PLAYERBATTSTATUS1
+ ld de, wPlayerNumAttacksLeft
+ ld a, [H_WHOSETURN]
and a
jr z, .asm_3f928
- ld hl, W_ENEMYBATTSTATUS1 ; W_ENEMYBATTSTATUS1
- ld de, wd06f
+ ld hl, W_ENEMYBATTSTATUS1
+ ld de, wEnemyNumAttacksLeft
.asm_3f928
bit 5, [hl]
ret nz
@@ -8067,20 +8230,20 @@ ConfusionEffect: ; 3f961 (f:7961)
call CheckTargetSubstitute
jr nz, Func_3f9a6
call MoveHitTest
- ld a, [W_MOVEMISSED] ; W_MOVEMISSED
+ ld a, [W_MOVEMISSED]
and a
jr nz, Func_3f9a6
Func_3f96f: ; 3f96f (f:796f)
- ld a, [H_WHOSETURN] ; $fff3
+ ld a, [H_WHOSETURN]
and a
- ld hl, W_ENEMYBATTSTATUS1 ; W_ENEMYBATTSTATUS1
+ ld hl, W_ENEMYBATTSTATUS1
ld bc, wd070
- ld a, [W_PLAYERMOVEEFFECT] ; wcfd3
+ ld a, [W_PLAYERMOVEEFFECT]
jr z, .asm_3f986
- ld hl, W_PLAYERBATTSTATUS1 ; W_PLAYERBATTSTATUS1
+ ld hl, W_PLAYERBATTSTATUS1
ld bc, wd06b
- ld a, [W_ENEMYMOVEEFFECT] ; W_ENEMYMOVEEFFECT
+ ld a, [W_ENEMYMOVEEFFECT]
.asm_3f986
bit 7, [hl] ; is mon confused?
jr nz, Func_3f9a6
@@ -8094,7 +8257,7 @@ Func_3f96f: ; 3f96f (f:796f)
pop af
cp CONFUSION_SIDE_EFFECT
call nz, Func_3fb89
- ld hl, BecameConfusedText ; $79a1
+ ld hl, BecameConfusedText
jp PrintText
BecameConfusedText: ; 3f9a1 (f:79a1)
@@ -8119,22 +8282,22 @@ SubstituteEffect: ; 3f9b9 (f:79b9)
jp Bankswitch
HyperBeamEffect: ; 3f9c1 (f:79c1)
- ld hl, W_PLAYERBATTSTATUS2 ; W_PLAYERBATTSTATUS2
- ld a, [H_WHOSETURN] ; $fff3
+ ld hl, W_PLAYERBATTSTATUS2
+ ld a, [H_WHOSETURN]
and a
jr z, .asm_3f9cc
- ld hl, W_ENEMYBATTSTATUS2 ; W_ENEMYBATTSTATUS2
+ ld hl, W_ENEMYBATTSTATUS2
.asm_3f9cc
set 5, [hl] ; mon now needs to recharge
ret
Func_3f9cf: ; 3f9cf (f:79cf)
push hl
- ld hl, W_ENEMYBATTSTATUS2 ; W_ENEMYBATTSTATUS2
- ld a, [H_WHOSETURN] ; $fff3
+ ld hl, W_ENEMYBATTSTATUS2
+ ld a, [H_WHOSETURN]
and a
jr z, .asm_3f9db
- ld hl, W_PLAYERBATTSTATUS2 ; W_PLAYERBATTSTATUS2
+ ld hl, W_PLAYERBATTSTATUS2
.asm_3f9db
res 5, [hl] ; mon no longer needs to recharge
pop hl
@@ -8237,15 +8400,15 @@ SplashEffect: ; 3fa84 (f:7a84)
DisableEffect: ; 3fa8a (f:7a8a)
call MoveHitTest
- ld a, [W_MOVEMISSED] ; W_MOVEMISSED
+ ld a, [W_MOVEMISSED]
and a
jr nz, .asm_3fb06
- ld de, W_ENEMYDISABLEDMOVE ; W_ENEMYDISABLEDMOVE
+ ld de, W_ENEMYDISABLEDMOVE
ld hl, wEnemyMonMoves
- ld a, [H_WHOSETURN] ; $fff3
+ ld a, [H_WHOSETURN]
and a
jr z, .asm_3faa4
- ld de, W_PLAYERDISABLEDMOVE ; W_PLAYERDISABLEDMOVE
+ ld de, W_PLAYERDISABLEDMOVE
ld hl, wBattleMonMoves
.asm_3faa4
ld a, [de]
@@ -8264,16 +8427,16 @@ DisableEffect: ; 3fa8a (f:7a8a)
jr z, .asm_3faa8
ld [wd11e], a
push hl
- ld a, [H_WHOSETURN] ; $fff3
+ ld a, [H_WHOSETURN]
and a
- ld hl, wBattleMonPP ; wBattleMonPP
+ ld hl, wBattleMonPP
jr nz, .asm_3facf
- ld a, [W_ISLINKBATTLE] ; W_ISLINKBATTLE
+ ld a, [W_ISLINKBATTLE]
cp $4
pop hl
jr nz, .asm_3fae1
push hl
- ld hl, wEnemyMonPP ; wcffe
+ ld hl, wEnemyMonPP
.asm_3facf
push hl
ld a, [hli]
@@ -8300,7 +8463,7 @@ DisableEffect: ; 3fa8a (f:7a8a)
ld [de], a
call Func_3fb89
ld hl, wccee
- ld a, [H_WHOSETURN] ; $fff3
+ ld a, [H_WHOSETURN]
and a
jr nz, .asm_3faf8
inc hl
@@ -8308,7 +8471,7 @@ DisableEffect: ; 3fa8a (f:7a8a)
ld a, [wd11e]
ld [hl], a
call GetMoveName
- ld hl, MoveWasDisabledText ; $7b09
+ ld hl, MoveWasDisabledText
jp PrintText
.asm_3fb05
pop hl
@@ -8387,7 +8550,7 @@ IsUnaffectedText: ; 3fb69 (f:7b69)
db "@"
PrintMayNotAttackText: ; 3fb6e (f:7b6e)
- ld hl, ParalyzedMayNotAttackText ; $7b74
+ ld hl, ParalyzedMayNotAttackText
jp PrintText
ParalyzedMayNotAttackText: ; 3fb74 (f:7b74)
@@ -8407,18 +8570,18 @@ CheckTargetSubstitute: ; 3fb79 (f:7b79)
ret
Func_3fb89: ; 3fb89 (f:7b89)
- ld a, [H_WHOSETURN] ; $fff3
+ ld a, [H_WHOSETURN]
and a
- ld a, [W_PLAYERMOVENUM] ; wcfd2
+ ld a, [W_PLAYERMOVENUM]
jr z, .asm_3fb94
- ld a, [W_ENEMYMOVENUM] ; W_ENEMYMOVENUM
+ ld a, [W_ENEMYMOVENUM]
.asm_3fb94
and a
ret z
Func_3fb96: ; 3fb96 (f:7b96)
- ld [W_ANIMATIONID], a ; W_ANIMATIONID
- ld a, [H_WHOSETURN] ; $fff3
+ ld [W_ANIMATIONID], a
+ ld a, [H_WHOSETURN]
and a
ld a, $6
jr z, .asm_3fba2
@@ -8430,17 +8593,17 @@ Func_3fb96: ; 3fb96 (f:7b96)
Func_3fba8: ; 3fba8 (f:7ba8)
xor a
ld [wcc5b], a
- ld a, [H_WHOSETURN] ; $fff3
+ ld a, [H_WHOSETURN]
and a
- ld a, [W_PLAYERMOVENUM] ; wcfd2
+ ld a, [W_PLAYERMOVENUM]
jr z, .asm_3fbb7
- ld a, [W_ENEMYMOVENUM] ; W_ENEMYMOVENUM
+ ld a, [W_ENEMYMOVENUM]
.asm_3fbb7
and a
ret z
Func_3fbb9: ; 3fbb9 (f:7bb9)
- ld [W_ANIMATIONID], a ; W_ANIMATIONID
+ ld [W_ANIMATIONID], a
Func_3fbbc: ; 3fbbc (f:7bbc)
push hl
diff --git a/engine/battle/core.asm.orig b/engine/battle/core.asm.orig
new file mode 100755
index 00000000..b8314a82
--- /dev/null
+++ b/engine/battle/core.asm.orig
@@ -0,0 +1,8639 @@
+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
+
+SlidePlayerAndEnemySilhouettesOnScreen: ; 3c04c (f:404c)
+ call LoadPlayerBackPic
+ ld a, $1 ; the usual text box at the bottom of the screen
+ ld [wd125], a
+ call DisplayTextBoxID
+ hlCoord 1, 5
+ ld bc, $307
+ call ClearScreenArea
+ call DisableLCD
+ call LoadFontTilePatterns
+ call LoadHudAndHpBarAndStatusTilePatterns
+ ld hl, vBGMap0
+ ld bc, $400
+.clearBackgroundLoop
+ ld a, $7f
+ ld [hli], a
+ dec bc
+ ld a, b
+ or c
+ jr nz, .clearBackgroundLoop
+; copy the work RAM tile map to VRAM
+ ld hl, wTileMap
+ ld de, vBGMap0
+ ld b, 18 ; number of rows
+.copyRowLoop
+ ld c, 20 ; number of columns
+.copyColumnLoop
+ ld a, [hli]
+ ld [de], a
+ inc e
+ dec c
+ jr nz, .copyColumnLoop
+ ld a, 12 ; number of off screen tiles to the right of screen in VRAM
+ add e ; skip the off screen tiles
+ ld e, a
+ jr nc, .noCarry
+ inc d
+.noCarry
+ dec b
+ jr nz, .copyRowLoop
+ call EnableLCD
+ ld a, $90
+ ld [hVBlankWY], a
+ ld [rWY], a
+ xor a
+ ld [hTilesetType], a
+ ld [hVBlankSCY], a
+ dec a
+ ld [wUpdateSpritesEnabled], a
+ call Delay3
+ xor a
+ ld [H_AUTOBGTRANSFERENABLED], a
+ ld b, $70
+ ld c, $90
+ ld a, c
+ ld [hVBlankSCX], a
+ call DelayFrame
+ ld a, %11100100 ; inverted palette for silhouette effect
+ ld [rBGP], a
+ ld [rOBP0], a
+ ld [rOBP1], a
+.slideSilhouettesLoop ; slide silhouettes of the player's pic and the enemy's pic onto the screen
+ ld h, b
+ ld l, $40
+ call SetScrollXForSlidingPlayerBodyLeft ; begin background scrolling on line $40
+ inc b
+ inc b
+ ld h, $0
+ ld l, $60
+ call SetScrollXForSlidingPlayerBodyLeft ; end background scrolling on line $60
+ call SlidePlayerHeadLeft
+ ld a, c
+ ld [hVBlankSCX], a
+ dec c
+ dec c
+ jr nz, .slideSilhouettesLoop
+ ld a, $1
+ ld [H_AUTOBGTRANSFERENABLED], a
+ ld a, $31
+ ld [$ffe1], a
+ hlCoord 1, 5
+ predef Func_3f0c6
+ xor a
+ ld [hVBlankWY], a
+ ld [rWY], a
+ inc a
+ ld [H_AUTOBGTRANSFERENABLED], a
+ call Delay3
+ ld b, $1
+ call GoPAL_SET
+ call HideSprites
+ ld hl, PrintBeginningBattleText
+ ld b, BANK(PrintBeginningBattleText)
+ jp Bankswitch
+
+; when a battle is starting, silhouettes of the player's pic and the enemy's pic are slid onto the screen
+; the lower of the player's pic (his body) is part of the background, but his head is a sprite
+; the reason for this is that it shares Y coordinates with the lower part of the enemy pic, so background scrolling wouldn't work for both pics
+; instead, the enemy pic is part of the background and uses the scroll register, while the player's head is a sprite and is slid by changing its X coordinates in a loop
+SlidePlayerHeadLeft: ; 3c0ff (f:40ff)
+ push bc
+ ld hl, wOAMBuffer + $01
+ ld c, $15 ; number of OAM entries
+ ld de, $4 ; size of OAM entry
+.loop
+ dec [hl] ; decrement X
+ dec [hl] ; decrement X
+ add hl, de ; next OAM entry
+ dec c
+ jr nz, .loop
+ pop bc
+ ret
+
+SetScrollXForSlidingPlayerBodyLeft: ; 3c110 (f:4110)
+ ld a, [rLY]
+ cp l
+ jr nz, SetScrollXForSlidingPlayerBodyLeft
+ ld a, h
+ ld [rSCX], a
+.loop
+ ld a, [rLY]
+ cp h
+ jr z, .loop
+ ret
+
+StartBattle: ; 3c11e (f:411e)
+ xor a
+ ld [wPartyGainExpFlags], a
+ ld [wPartyFoughtCurrentEnemyFlags], a
+ ld [wcd6a], a
+ inc a
+ ld [wd11d], a
+ ld hl, wEnemyMon1HP
+ ld bc, wEnemyMon2 - wEnemyMon1 - 1
+ ld d, $3
+.findFirstAliveEnemyMonLoop
+ inc d
+ ld a, [hli]
+ or [hl]
+ jr nz, .foundFirstAliveEnemyMon
+ add hl, bc
+ jr .findFirstAliveEnemyMonLoop
+.foundFirstAliveEnemyMon
+ ld a, d
+ ld [wcc3e], a
+ ld a, [W_ISINBATTLE]
+ dec a ; is it a trainer battle?
+ call nz, EnemySendOutFirstMon ; if it is a trainer battle, send out enemy mon
+ ld c, 40
+ call DelayFrames
+ call SaveScreenTilesToBuffer1
+.checkAnyPartyAlive
+ call AnyPartyAlive
+ ld a, d
+ and a
+ jp z, HandlePlayerBlackOut ; jump if no mon is alive
+ call LoadScreenTilesFromBuffer1
+ ld a, [W_BATTLETYPE]
+ and a ; is it a normal battle?
+ jp z, .playerSendOutFirstMon ; if so, send out player mon
+; safari zone battle
+.displaySafariZoneBattleMenu
+ call DisplayBattleMenu
+ ret c ; return if the player ran from battle
+ ld a, [wcd6a]
+ and a ; was the item used successfully?
+ jr z, .displaySafariZoneBattleMenu ; if not, display the menu again; XXX does this ever jump?
+ ld a, [W_NUMSAFARIBALLS]
+ and a
+ jr nz, .notOutOfSafariBalls
+ call LoadScreenTilesFromBuffer1
+ ld hl, .outOfSafariBallsText
+ jp PrintText
+.notOutOfSafariBalls
+ callab PrintSafariZoneBattleText
+ ld a, [wEnemyMonSpeed + 1]
+ add a
+ ld b, a ; init b (which is later compared with random value) to (enemy speed % 256) * 2
+ jp c, EnemyRan ; if (enemy speed % 256) > 127, the enemy runs
+ ld a, [wSafariBaitFactor]
+ and a ; is bait factor 0?
+ jr z, .checkEscapeFactor
+; bait factor is not 0
+; divide b by 4 (making the mon less likely to run)
+ srl b
+ srl b
+.checkEscapeFactor
+ ld a, [wSafariEscapeFactor]
+ and a ; is escape factor 0?
+ jr z, .compareWithRandomValue
+; escape factor is not 0
+; multiply b by 2 (making the mon more likely to run)
+ sla b
+ jr nc, .compareWithRandomValue
+; cap b at 255
+ ld b, $ff
+.compareWithRandomValue
+ call Random
+ cp b
+ jr nc, .checkAnyPartyAlive
+ jr EnemyRan ; if b was greater than the random value, the enemy runs
+
+.outOfSafariBallsText
+ TX_FAR _OutOfSafariBallsText
+ db "@"
+
+.playerSendOutFirstMon
+ xor a
+ ld [wWhichPokemon], a
+.findFirstAliveMonLoop
+ call HasMonFainted
+ jr nz, .foundFirstAliveMon
+; fainted, go to the next one
+ ld hl, wWhichPokemon
+ inc [hl]
+ jr .findFirstAliveMonLoop
+.foundFirstAliveMon
+ ld a, [wWhichPokemon]
+ ld [wPlayerMonNumber], a
+ inc a
+ ld hl, wPartySpecies - 1
+ ld c, a
+ ld b, 0
+ add hl, bc
+ ld a, [hl] ; species
+ ld [wcf91], a
+ ld [wBattleMonSpecies2], a
+ call LoadScreenTilesFromBuffer1
+ hlCoord 1, 5
+ ld a, $9
+ call SlideTrainerPicOffScreen
+ call SaveScreenTilesToBuffer1
+ ld a, [wWhichPokemon]
+ ld c, a
+ ld b, $1
+ push bc
+ ld hl, wPartyGainExpFlags
+ predef FlagActionPredef
+ ld hl, wPartyFoughtCurrentEnemyFlags
+ pop bc
+ predef FlagActionPredef
+ call LoadBattleMonFromParty
+ call LoadScreenTilesFromBuffer1
+ call SendOutMon
+ jr MainInBattleLoop
+
+; wild mon or link battle enemy ran from battle
+EnemyRan: ; 3c202 (f:4202)
+ call LoadScreenTilesFromBuffer1
+ ld a, [W_ISLINKBATTLE]
+ cp $4
+ ld hl, WildRanText
+ jr nz, .printText
+; link battle
+ xor a
+ ld [wBattleResult], a
+ ld hl, EnemyRanText
+.printText
+ call PrintText
+ ld a, (SFX_08_44 - SFX_Headers_08) / 3
+ call PlaySoundWaitForCurrent
+ xor a
+ ld [H_WHOSETURN], a
+ 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, wBattleMonHP
+ ld a, [hli]
+ or [hl] ; is battle mon HP 0?
+ jp z, HandlePlayerMonFainted ; if battle mon HP is 0, jump
+ ld hl, wEnemyMonHP
+ ld a, [hli]
+ or [hl] ; is enemy mon HP 0?
+ jp z, HandleEnemyMonFainted ; if enemy mon HP is 0, jump
+ call SaveScreenTilesToBuffer1
+ xor a
+ ld [wd11d], a
+ ld a, [W_PLAYERBATTSTATUS2]
+ and %01100000 ; check if the player is using Rage or needs to recharge
+ jr nz, .selectEnemyMove
+; the player is not using Rage and doesn't need to recharge
+ ld hl, W_ENEMYBATTSTATUS1
+ res 3, [hl] ; reset flinch bit
+ ld hl, W_PLAYERBATTSTATUS1
+ res 3, [hl] ; reset flinch bit
+ ld a, [hl]
+ and %00010010 ; check if the player is thrashing about or charging for an attack
+ jr nz, .selectEnemyMove ; if so, jump
+; the player is neither thrashing about nor charging for an attack
+ call DisplayBattleMenu ; show battle menu
+ ret c ; return if player ran from battle
+ ld a, [wEscapedFromBattle]
+ and a
+ ret nz ; return if pokedoll was used to escape from battle
+ ld a, [wBattleMonStatus]
+ and (1 << FRZ) | SLP ; is mon frozen or asleep?
+ jr nz, .selectEnemyMove ; if so, jump
+ ld a, [W_PLAYERBATTSTATUS1]
+ and %00100001 ; check player is using Bide or using a multi-turn attack like wrap
+ jr nz, .selectEnemyMove ; if so, jump
+ ld a, [W_ENEMYBATTSTATUS1]
+ bit 5, a ; check if enemy is using a multi-turn attack like wrap
+ jr z, .selectPlayerMove ; if not, jump
+; enemy is using a mult-turn attack like wrap, so player is trapped and cannot select a move
+ ld a, $ff
+ ld [wPlayerSelectedMove], a
+ jr .selectEnemyMove
+.selectPlayerMove
+ ld a, [wcd6a]
+ and a
+ jr nz, .selectEnemyMove
+ ld [wMoveMenuType], a
+ inc a
+ ld [W_ANIMATIONID], a
+ xor a
+ ld [wMenuItemToSwap], a
+ call MoveSelectionMenu
+ push af
+ call LoadScreenTilesFromBuffer1
+ call DrawHUDsAndHPBars
+ pop af
+ jr nz, MainInBattleLoop ; if the player didn't select a move, jump
+.selectEnemyMove
+ call SelectEnemyMove
+ ld a, [W_ISLINKBATTLE]
+ cp $4
+ jr nz, .noLinkBattle
+; link battle
+ ld a, [wcc3e]
+ cp $f
+ jp z, EnemyRan
+ cp $e
+ jr z, .noLinkBattle
+ cp $d
+ jr z, .noLinkBattle
+ sub $4
+ jr c, .noLinkBattle
+; the link battle enemy has switched mons
+ ld a, [W_PLAYERBATTSTATUS1]
+ bit 5, a ; check if using multi-turn move like Wrap
+ jr z, .asm_3c2dd
+ ld a, [wPlayerMoveListIndex]
+ ld hl, wBattleMonMoves
+ ld c, a
+ ld b, 0
+ add hl, bc
+ ld a, [hl]
+ cp METRONOME
+ jr nz, .asm_3c2dd
+ ld [wPlayerSelectedMove], a
+.asm_3c2dd
+ callab SwitchEnemyMon
+.noLinkBattle
+ ld a, [wPlayerSelectedMove]
+ cp QUICK_ATTACK
+ jr nz, .playerDidNotUseQuickAttack
+ ld a, [wEnemySelectedMove]
+ cp QUICK_ATTACK
+ jr z, .compareSpeed ; if both used Quick Attack
+ jp .playerMovesFirst ; if player used Quick Attack and enemy didn't
+.playerDidNotUseQuickAttack
+ ld a, [wEnemySelectedMove]
+ cp QUICK_ATTACK
+ jr z, .enemyMovesFirst ; if enemy used Quick Attack and player didn't
+ ld a, [wPlayerSelectedMove]
+ cp COUNTER
+ jr nz, .playerDidNotUseCounter
+ ld a, [wEnemySelectedMove]
+ cp COUNTER
+ jr z, .compareSpeed ; if both used Counter
+ jr .enemyMovesFirst ; if player used Counter and enemy didn't
+.playerDidNotUseCounter
+ ld a, [wEnemySelectedMove]
+ cp COUNTER
+ jr z, .playerMovesFirst ; if enemy used Counter and player didn't
+.compareSpeed
+ ld de, wBattleMonSpeed ; player speed value
+ ld hl, wEnemyMonSpeed ; enemy speed value
+ ld c, $2
+ call StringCmp ; compare speed values
+ jr z, .speedEqual
+ jr nc, .playerMovesFirst ; if player is faster
+ jr .enemyMovesFirst ; if enemy is faster
+.speedEqual
+ ld a, [$ffaa]
+ cp $2
+ jr z, .invertOutcome
+ call BattleRandom
+ cp $80
+ jr c, .playerMovesFirst
+ jr .enemyMovesFirst
+.invertOutcome
+ call BattleRandom
+ cp $80
+ jr c, .enemyMovesFirst
+ jr .playerMovesFirst
+.enemyMovesFirst
+ ld a, $1
+ ld [H_WHOSETURN], a
+ callab TrainerAI
+ jr c, .AIActionUsedEnemyFirst
+ call ExecuteEnemyMove
+ ld a, [wEscapedFromBattle]
+ and a ; was Teleport, Road, or Whirlwind used to escape from battle?
+ ret nz ; if so, return
+ ld a, b
+ and a
+ jp z, HandlePlayerMonFainted
+.AIActionUsedEnemyFirst
+ call HandlePoisonBurnLeechSeed
+ jp z, HandleEnemyMonFainted
+ call DrawHUDsAndHPBars
+ call ExecutePlayerMove
+ ld a, [wEscapedFromBattle]
+ and a ; was Teleport, Road, or Whirlwind used to escape from battle?
+ ret nz ; if so, return
+ ld a, b
+ and a
+ jp z, HandleEnemyMonFainted
+ call HandlePoisonBurnLeechSeed
+ jp z, HandlePlayerMonFainted
+ call DrawHUDsAndHPBars
+ call CheckNumAttacksLeft
+ jp MainInBattleLoop
+.playerMovesFirst
+ call ExecutePlayerMove
+ ld a, [wEscapedFromBattle]
+ and a ; was Teleport, Road, or Whirlwind used to escape from battle?
+ ret nz ; if so, return
+ ld a, b
+ and a
+ jp z, HandleEnemyMonFainted
+ call HandlePoisonBurnLeechSeed
+ jp z, HandlePlayerMonFainted
+ call DrawHUDsAndHPBars
+ ld a, $1
+ ld [H_WHOSETURN], a
+ callab TrainerAI
+ jr c, .AIActionUsedPlayerFirst
+ call ExecuteEnemyMove
+ ld a, [wEscapedFromBattle]
+ and a ; was Teleport, Road, or Whirlwind used to escape from battle?
+ ret nz ; if so, return
+ ld a, b
+ and a
+ jp z, HandlePlayerMonFainted
+.AIActionUsedPlayerFirst
+ call HandlePoisonBurnLeechSeed
+ jp z, HandleEnemyMonFainted
+ call DrawHUDsAndHPBars
+ call CheckNumAttacksLeft
+ jp MainInBattleLoop
+
+HandlePoisonBurnLeechSeed: ; 3c3bd (f:43bd)
+ ld hl, wBattleMonHP
+ ld de, wBattleMonStatus
+ ld a, [H_WHOSETURN]
+ and a
+ jr z, .playersTurn
+ ld hl, wEnemyMonHP
+ ld de, wEnemyMonStatus
+.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 [wcc5b], a
+ ld a,BURN_PSN_ANIM
+ call PlayMoveAnimation ; play burn/poison animation
+ pop hl
+ call HandlePoisonBurnLeechSeed_DecreaseOwnHP
+.notBurnedOrPoisoned
+ ld de, W_PLAYERBATTSTATUS2
+ ld a, [H_WHOSETURN]
+ and a
+ jr z, .playersTurn2
+ ld de, W_ENEMYBATTSTATUS2
+.playersTurn2
+ ld a, [de]
+ add a
+ jr nc, .notLeechSeeded
+ push hl
+ ld a, [H_WHOSETURN]
+ push af
+ xor $1
+ ld [H_WHOSETURN], a
+ xor a
+ ld [wcc5b], a
+ ld a,ABSORB
+ call PlayMoveAnimation ; play leech seed animation (from opposing mon)
+ pop af
+ ld [H_WHOSETURN], a
+ 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 DrawHUDsAndHPBars
+ 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
+ ld de, W_PLAYERTOXICCOUNTER
+ ld a, [H_WHOSETURN]
+ and a
+ jr z, .playersTurn
+ ld hl, W_ENEMYBATTSTATUS3
+ ld de, W_ENEMYTOXICCOUNTER
+.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, wEnemyMonMaxHP
+ ld a, [H_WHOSETURN]
+ and a
+ jr z, .playersTurn
+ ld hl, wBattleMonMaxHP
+.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]
+ xor $1
+ ld [H_WHOSETURN], a
+ call UpdateCurMonHPBar
+ ld a, [H_WHOSETURN]
+ xor $1
+ ld [H_WHOSETURN], a
+ pop hl
+ ret
+
+UpdateCurMonHPBar: ; 3c4f6 (f:44f6)
+ hlCoord 10, 9 ; tile pointer to player HP bar
+ ld a, [H_WHOSETURN]
+ and a
+ ld a, $1
+ jr z, .playersTurn
+ hlCoord 2, 2 ; tile pointer to enemy HP bar
+ xor a
+.playersTurn
+ push bc
+ ld [wListMenuID], a
+ predef UpdateHPBar2
+ pop bc
+ ret
+
+CheckNumAttacksLeft: ; 3c50f (f:450f)
+ ld a, [wPlayerNumAttacksLeft]
+ and a
+ jr nz, .checkEnemy
+; player has 0 attacks left
+ ld hl, W_PLAYERBATTSTATUS1
+ res 5, [hl] ; player not using multi-turn attack like wrap any more
+.checkEnemy
+ ld a, [wEnemyNumAttacksLeft]
+ and a
+ ret nz
+; enemy has 0 attacks left
+ ld hl, W_ENEMYBATTSTATUS1
+ res 5, [hl] ; enemy not using multi-turn attack like wrap any more
+ ret
+
+HandleEnemyMonFainted: ; 3c525 (f:4525)
+ xor a
+ ld [wccf0], a
+ call FaintEnemyPokemon
+ call AnyPartyAlive
+ ld a, d
+ and a
+ jp z, HandlePlayerBlackOut ; if no party mons are alive, the player blacks out
+ ld hl, wBattleMonHP
+ ld a, [hli]
+ or [hl] ; is battle mon HP zero?
+ call nz, DrawPlayerHUDAndHPBar ; if battle mon HP is not zero, draw player HD and HP bar
+ ld a, [W_ISINBATTLE]
+ dec a
+ ret z ; return if it's a wild battle
+ call AnyEnemyPokemonAliveCheck
+ jp z, TrainerBattleVictory
+ ld hl, wBattleMonHP
+ ld a, [hli]
+ or [hl] ; does battle mon have 0 HP?
+ jr nz, .skipReplacingBattleMon ; if not, skip replacing battle mon
+ call DoUseNextMonDialogue ; this call is useless in a trainer battle. it shouldn't be here
+ ret c
+ call ChooseNextMon
+.skipReplacingBattleMon
+ ld a, $1
+ ld [wcd6a], a
+ call ReplaceFaintedEnemyMon
+ jp z, EnemyRan
+ xor a
+ ld [wcd6a], a
+ jp MainInBattleLoop
+
+FaintEnemyPokemon ; 0x3c567
+ call ReadPlayerMonCurHPAndStatus
+ ld a, [W_ISINBATTLE]
+ dec a
+ jr z, .wild
+ ld a, [wEnemyMonPartyPos]
+ ld hl, wEnemyMon1HP
+ ld bc, wEnemyMon2 - wEnemyMon1
+ call AddNTimes
+ xor a
+ ld [hli], a
+ ld [hl], a
+.wild
+ ld hl, W_PLAYERBATTSTATUS1
+ res 2, [hl]
+ xor a
+ ld [W_NUMHITS], a
+ ld hl, wd065 ; enemy statuses
+ ld [hli], a
+ ld [hli], a
+ ld [hli], a
+ ld [hli], a
+ ld [hl], a
+ ld [W_ENEMYDISABLEDMOVE], a
+ ld [wccef], a
+ ld [wccf3], a
+ ld hl, wccf1
+ ld [hli], a
+ ld [hl], a
+ hlCoord 12, 5
+ deCoord 12, 6
+ call SlideDownFaintedMonPic
+ ld hl, wTileMap
+ ld bc, $40b
+ call ClearScreenArea
+ ld a, [W_ISINBATTLE]
+ dec a
+ jr z, .wild_win
+ xor a
+ ld [wc0f1], a
+ ld [wc0f2], a
+ ld a, (SFX_08_48 - SFX_Headers_08) / 3 ; SFX_FALL?
+ call PlaySoundWaitForCurrent
+.sfxwait
+ ld a, [wc02a]
+ 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, wBattleMonHP
+ ld a, [hli]
+ or [hl]
+ jr nz, .playermonnotfaint
+ ld a, [wccf0]
+ and a
+ jr nz, .playermonnotfaint
+ call RemoveFaintedPlayerMon
+.playermonnotfaint
+ call AnyPartyAlive
+ ld a, d
+ and a
+ ret z
+ ld hl, EnemyMonFaintedText
+ call PrintText
+ call PrintEmptyString
+ call SaveScreenTilesToBuffer1
+ xor a
+ ld [wBattleResult], a
+ ld b, EXP__ALL
+ call IsItemInBag
+ push af
+ jr z, .giveExpToMonsThatFought ; if no exp all, then jump
+
+; the player has exp all
+; first, we halve the values that determine exp gain
+; the enemy mon base stats are added to stat exp, so they are halved
+; the base exp (which determines normal exp) is also halved
+ ld hl, wEnemyMonBaseStats
+ ld b, $7
+.halveExpDataLoop
+ srl [hl]
+ inc hl
+ dec b
+ jr nz, .halveExpDataLoop
+
+; give exp (divided evenly) to the mons that actually fought in battle against the enemy mon that has fainted
+; if exp all is in the bag, this will be only be half of the stat exp and normal exp, due to the above loop
+.giveExpToMonsThatFought
+ xor a
+ ld [wcc5b], a
+ callab GainExperience
+ pop af
+ ret z ; return if no exp all
+
+; the player has exp all
+; now, set the gain exp flag for every party member
+; half of the total stat exp and normal exp will divided evenly amongst every party member
+ ld a, $1
+ ld [wcc5b], a
+ ld a, [wPartyCount]
+ ld b, 0
+.gainExpFlagsLoop
+ scf
+ rl b
+ dec a
+ jr nz, .gainExpFlagsLoop
+ ld a, b
+ ld [wPartyGainExpFlags], a
+ ld hl, GainExperience
+ ld b, BANK(GainExperience)
+ jp Bankswitch
+
+EnemyMonFaintedText: ; 0x3c63e
+ TX_FAR _EnemyMonFaintedText
+ db "@"
+
+Func_3c643: ; 3c643 (f:4643)
+ xor a
+ ld [wd083], a
+ ld [wc02a], a
+ inc a
+ ld [wccf6], a
+ ret
+
+AnyEnemyPokemonAliveCheck: ; 3c64f (f:464f)
+ ld a, [wEnemyPartyCount]
+ ld b, a
+ xor a
+ ld hl, wEnemyMon1HP
+ 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
+
+; stores whether enemy ran in Z flag
+ReplaceFaintedEnemyMon: ; 3c664 (f:4664)
+ ld hl, wcf1e
+ ld e, $30
+ call GetBattleHealthBarColor
+ callab DrawEnemyPokeballs
+ ld a, [W_ISLINKBATTLE]
+ cp $4
+ jr nz, .asm_3c687
+; link battle
+ call LinkBattleExchangeData
+ ld a, [wcc3e]
+ cp $f
+ ret z
+ call LoadScreenTilesFromBuffer1
+.asm_3c687
+ call EnemySendOut
+ xor a
+ ld [W_ENEMYMOVENUM], a
+ ld [wcd6a], a
+ ld [wccd5], a
+ inc a ; reset Z flag
+ ret
+
+TrainerBattleVictory: ; 3c696 (f:4696)
+ call Func_3c643
+ ld b, MUSIC_DEFEATED_GYM_LEADER
+ ld a, [W_GYMLEADERNO]
+ and a
+ jr nz, .gymleader
+ ld b, MUSIC_DEFEATED_TRAINER
+.gymleader
+ ld a, [W_TRAINERCLASS]
+ 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]
+ cp $4
+ ld a, b
+ call nz, PlayBattleVictoryMusic
+ ld hl, TrainerDefeatedText
+ call PrintText
+ ld a, [W_ISLINKBATTLE]
+ cp $4
+ ret z
+ call ScrollTrainerPicAfterBattle
+ ld c, $28
+ call DelayFrames
+ call PrintEndBattleText
+ ld hl, MoneyForWinningText
+ call PrintText
+ ld de, wPlayerMoney + 2
+ ld hl, wd07b
+ ld c, $3
+ predef_jump AddBCDPredef
+
+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 [wc0ee], a
+ call PlaySoundWaitForCurrent
+ ld c, BANK(Music_DefeatedTrainer)
+ pop af
+ call PlayMusic
+ jp Delay3
+
+HandlePlayerMonFainted: ; 3c700 (f:4700)
+ ld a, $1
+ ld [wccf0], a
+ call RemoveFaintedPlayerMon
+ call AnyPartyAlive ; test if any more mons are alive
+ ld a, d
+ and a
+ jp z, HandlePlayerBlackOut
+ ld hl, wEnemyMonHP
+ ld a, [hli]
+ or [hl] ; is enemy mon's HP 0?
+ jr nz, .doUseNextMonDialogue ; if not, jump
+; the enemy mon has 0 HP
+ call FaintEnemyPokemon
+ ld a, [W_ISINBATTLE]
+ dec a
+ ret z ; if wild encounter, battle is over
+ call AnyEnemyPokemonAliveCheck
+ jp z, TrainerBattleVictory
+.doUseNextMonDialogue
+ call DoUseNextMonDialogue
+ ret c ; return if the player ran from battle
+ call ChooseNextMon
+ jp nz, MainInBattleLoop ; if the enemy mon has more than 0 HP, go back to battle loop
+; the enemy mon has 0 HP
+ ld a, $1
+ ld [wcd6a], a
+ call ReplaceFaintedEnemyMon
+ jp z, EnemyRan ; if enemy ran from battle rather than sending out another mon, jump
+ xor a
+ ld [wcd6a], a
+ jp MainInBattleLoop
+
+; resets flags, slides mon's pic down, plays cry, and prints fainted message
+RemoveFaintedPlayerMon: ; 3c741 (f:4741)
+ ld a, [wPlayerMonNumber]
+ ld c, a
+ ld hl, wPartyGainExpFlags
+ ld b, $0
+ predef FlagActionPredef ; clear gain exp flag for fainted mon
+ ld hl, W_ENEMYBATTSTATUS1
+ res 2, [hl] ; reset "attacking multiple times" flag
+ ld a, [wd083]
+ bit 7, a ; skip sound flag (red bar (?))
+ jr z, .skipWaitForSound
+ ld a, $ff
+ ld [wd083], a
+ call WaitForSoundToFinish
+.skipWaitForSound
+ ld hl, wcd05
+ ld [hli], a
+ ld [hl], a
+ ld [wBattleMonStatus], a
+ call ReadPlayerMonCurHPAndStatus
+ hlCoord 9, 7
+ ld bc, $50b
+ call ClearScreenArea
+ hlCoord 1, 10
+ deCoord 1, 11
+ call SlideDownFaintedMonPic
+ ld a, $1
+ ld [wBattleResult], a
+ ld a, [wccf0]
+ and a
+ ret z
+ ld a, [wBattleMonSpecies]
+ call PlayCry
+ ld hl, PlayerMonFaintedText
+ jp PrintText
+
+PlayerMonFaintedText: ; 3c796 (f:4796)
+ TX_FAR _PlayerMonFaintedText
+ db "@"
+
+; asks if you want to use next mon
+; stores whether you ran in C flag
+DoUseNextMonDialogue: ; 3c79b (f:479b)
+ call PrintEmptyString
+ call SaveScreenTilesToBuffer1
+ ld a, [W_ISINBATTLE]
+ and a
+ dec a
+ ret nz ; return if it's a trainer battle
+ ld hl, UseNextMonText
+ call PrintText
+.displayYesNoBox
+ hlCoord 13, 9
+ ld bc, $a0e
+ ld a, $14 ; yes/no text box
+ ld [wd125], a
+ call DisplayTextBoxID
+ ld a, [wd12e]
+ cp $2 ; did the player choose NO?
+ jr z, .tryRunning ; if the player chose NO, try running
+ and a ; reset carry
+ ret
+.tryRunning
+ ld a, [wCurrentMenuItem]
+ and a
+ jr z, .displayYesNoBox ; xxx when does this happen?
+ ld hl, wPartyMon1Speed
+ ld de, wEnemyMonSpeed
+ jp TryRunningFromBattle
+
+UseNextMonText: ; 3c7d3 (f:47d3)
+ TX_FAR _UseNextMonText
+ db "@"
+
+; choose next player mon to send out
+; stores whether enemy mon has no HP left in Z flag
+ChooseNextMon: ; 3c7d8 (f:47d8)
+ ld a, $2
+ ld [wd07d], a
+ call DisplayPartyMenu
+.checkIfMonChosen
+ jr nc, .monChosen
+.goBackToPartyMenu
+ call GoBackToPartyMenu
+ jr .checkIfMonChosen
+.monChosen
+ call HasMonFainted
+ jr z, .goBackToPartyMenu ; if mon fainted, you have to choose another
+ ld a, [W_ISLINKBATTLE]
+ cp $4
+ jr nz, .asm_3c7fa
+ inc a
+ ld [wcd6a], a
+ call LinkBattleExchangeData
+.asm_3c7fa
+ xor a
+ ld [wcd6a], a
+ call ClearSprites
+ ld a, [wWhichPokemon]
+ ld [wPlayerMonNumber], a
+ ld c, a
+ ld hl, wPartyGainExpFlags
+ ld b, $1
+ push bc
+ predef FlagActionPredef
+ pop bc
+ ld hl, wPartyFoughtCurrentEnemyFlags
+ predef FlagActionPredef
+ call LoadBattleMonFromParty
+ call GBPalWhiteOut
+ call LoadHudTilePatterns
+ call LoadScreenTilesFromBuffer1
+ call GoPAL_SET_CF1C
+ call GBPalNormal
+ call SendOutMon
+ ld hl, wEnemyMonHP
+ 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]
+ cp $4
+ jr z, .notSony1Battle
+ ld a, [W_CUROPPONENT]
+ 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]
+ cp $4
+ jr nz, .noLinkBattle
+ ld hl, LinkBattleLostText
+.noLinkBattle
+ call PrintText
+ ld a, [wd732]
+ res 5, a
+ ld [wd732], 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 "@"
+
+; slides pic of fainted mon downwards until it disappears
+; bug: when this is called, [H_AUTOBGTRANSFERENABLED] is non-zero, so there is screen tearing
+SlideDownFaintedMonPic: ; 3c893 (f:4893)
+ ld a, [wd730]
+ push af
+ set 6, a
+ ld [wd730], a
+ ld b, 7 ; number of times to slide
+.slideStepLoop ; each iteration, the mon is slid down one row
+ push bc
+ push de
+ push hl
+ ld b, 6 ; number of rows
+.rowLoop
+ push bc
+ push hl
+ push de
+ ld bc, $7
+ call CopyData
+ pop de
+ pop hl
+ ld bc, -20
+ 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, .rowLoop
+ ld bc, 20
+ add hl, bc
+ ld de, SevenSpacesText
+ call PlaceString
+ ld c, 2
+ call DelayFrames
+ pop hl
+ pop de
+ pop bc
+ dec b
+ jr nz, .slideStepLoop
+ pop af
+ ld [wd730], a
+ ret
+
+SevenSpacesText: ; 3c8d7 (f:48d7)
+ db " @"
+
+; slides the player or enemy trainer off screen
+; a is the number of tiles to slide it horizontally (always 9 for the player trainer or 8 for the enemy trainer)
+; if a is 8, the slide is to the right, else it is to the left
+; bug: when this is called, [H_AUTOBGTRANSFERENABLED] is non-zero, so there is screen tearing
+SlideTrainerPicOffScreen: ; 3c8df (f:48df)
+ ld [$FF8B], a
+ ld c, a
+.slideStepLoop ; each iteration, the trainer pic is slid one tile left/right
+ push bc
+ push hl
+ ld b, 7 ; number of rows
+.rowLoop
+ push hl
+ ld a, [$FF8B]
+ ld c, a
+.columnLoop
+ ld a, [$FF8B]
+ cp 8
+ jr z, .slideRight
+.slideLeft ; slide player sprite off screen
+ ld a, [hld]
+ ld [hli], a
+ inc hl
+ jr .nextColumn
+.slideRight ; slide enemy trainer sprite off screen
+ ld a, [hli]
+ ld [hld], a
+ dec hl
+.nextColumn
+ dec c
+ jr nz, .columnLoop
+ pop hl
+ ld de, 20
+ add hl, de
+ dec b
+ jr nz, .rowLoop
+ ld c, 2
+ call DelayFrames
+ pop hl
+ pop bc
+ dec c
+ jr nz, .slideStepLoop
+ ret
+
+; send out a trainer's mon
+EnemySendOut: ; 3c90e (f:490e)
+ ld hl,wPartyGainExpFlags
+ xor a
+ ld [hl],a
+ ld a,[wPlayerMonNumber]
+ ld c,a
+ ld b,1
+ push bc
+ predef FlagActionPredef
+ ld hl,wPartyFoughtCurrentEnemyFlags
+ xor a
+ ld [hl],a
+ pop bc
+ predef FlagActionPredef
+
+; don't change wPartyGainExpFlags or wPartyFoughtCurrentEnemyFlags
+EnemySendOutFirstMon: ; 3c92a (f:492a)
+ xor a
+ ld hl,wd065
+ ld [hli],a
+ ld [hli],a
+ ld [hli],a
+ ld [hli],a
+ ld [hl],a
+ ld [W_ENEMYDISABLEDMOVE],a
+ ld [wccef],a
+ ld [wccf3],a
+ ld hl,wccf1
+ ld [hli],a
+ ld [hl],a
+ dec a
+ ld [wAICount],a
+ ld hl,W_PLAYERBATTSTATUS1
+ res 5,[hl]
+ hlCoord 18, 0
+ ld a,8
+ call SlideTrainerPicOffScreen
+ call PrintEmptyString
+ call SaveScreenTilesToBuffer1
+ ld a,[W_ISLINKBATTLE]
+ cp 4
+ jr nz,.next
+ ld a,[wcc3e]
+ sub 4
+ ld [wWhichPokemon],a
+ jr .next3
+.next
+ ld b,$FF
+.next2
+ inc b
+ ld a,[wEnemyMonPartyPos]
+ cp b
+ jr z,.next2
+ ld hl,wEnemyMon1
+ ld a,b
+ ld [wWhichPokemon],a
+ push bc
+ ld bc,wEnemyMon2 - wEnemyMon1
+ 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,wEnemyMon1Level
+ ld bc,wEnemyMon2 - wEnemyMon1
+ call AddNTimes
+ ld a,[hl]
+ ld [W_CURENEMYLVL],a
+ ld a,[wWhichPokemon]
+ inc a
+ ld hl,wEnemyPartyCount
+ ld c,a
+ ld b,0
+ add hl,bc
+ ld a,[hl]
+ ld [wEnemyMonSpecies2],a
+ ld [wcf91],a
+ call LoadEnemyMonData
+ ld hl,wEnemyMonHP
+ ld a,[hli]
+ ld [wcce3],a
+ ld a,[hl]
+ ld [wcce4],a
+ ld a,1
+ ld [wCurrentMenuItem],a
+ ld a,[wd11d]
+ dec a
+ jr z,.next4
+ ld a,[wPartyCount]
+ dec a
+ jr z,.next4
+ ld a,[W_ISLINKBATTLE]
+ cp 4
+ jr z,.next4
+ ld a,[W_OPTIONS]
+ bit 6,a
+ jr nz,.next4
+ ld hl, TrainerAboutToUseText
+ call PrintText
+ hlCoord 0, 7
+ ld bc,$0801
+ ld a,$14
+ ld [wd125],a
+ call DisplayTextBoxID
+ ld a,[wCurrentMenuItem]
+ and a
+ jr nz,.next4
+ ld a,2
+ ld [wd07d],a
+ call DisplayPartyMenu
+.next9
+ ld a,1
+ ld [wCurrentMenuItem],a
+ jr c,.next7
+ ld hl,wPlayerMonNumber
+ ld a,[wWhichPokemon]
+ cp [hl]
+ jr nz,.next6
+ ld hl,AlreadyOutText
+ call PrintText
+.next8
+ call GoBackToPartyMenu
+ jr .next9
+.next6
+ call HasMonFainted
+ jr z,.next8
+ xor a
+ ld [wCurrentMenuItem],a
+.next7
+ call GBPalWhiteOut
+ call LoadHudTilePatterns
+ call LoadScreenTilesFromBuffer1
+.next4
+ call ClearSprites
+ ld hl,wTileMap
+ ld bc,$040B
+ call ClearScreenArea
+ ld b,1
+ call GoPAL_SET
+ call GBPalNormal
+ ld hl,TrainerSentOutText
+ call PrintText
+ ld a,[wEnemyMonSpecies2]
+ ld [wcf91],a
+ ld [wd0b5],a
+ call GetMonHeader
+ ld de,vFrontPic
+ call LoadMonFrontSprite
+ ld a,$CF
+ ld [$FFE1],a
+ hlCoord 15, 6
+ predef Func_3f073
+ ld a,[wEnemyMonSpecies2]
+ call PlayCry
+ call DrawEnemyHUDAndHPBar
+ ld a,[wCurrentMenuItem]
+ and a
+ ret nz
+ xor a
+ ld [wPartyGainExpFlags],a
+ ld [wPartyFoughtCurrentEnemyFlags],a
+ call SaveScreenTilesToBuffer1
+ jp SwitchPlayerMon
+
+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
+AnyPartyAlive: ; 3ca83 (f:4a83)
+ ld a, [wPartyCount]
+ ld e, a
+ xor a
+ ld hl, wPartyMon1HP
+ ld bc, wPartyMon2 - wPartyMon1 - 1
+.partyMonsLoop
+ or [hl]
+ inc hl
+ or [hl]
+ add hl, bc
+ dec e
+ jr nz, .partyMonsLoop
+ ld d, a
+ ret
+
+; tests if player mon has fainted
+; stores whether mon has fainted in Z flag
+HasMonFainted: ; 3ca97 (f:4a97)
+ ld a, [wWhichPokemon]
+ ld hl, wPartyMon1HP
+ ld bc, wPartyMon2 - wPartyMon1
+ call AddNTimes
+ ld a, [hli]
+ or [hl]
+ ret nz
+ ld a, [wd11d]
+ and a
+ jr nz, .done
+ ld hl, NoWillText
+ call PrintText
+.done
+ xor a
+ ret
+
+NoWillText: ; 3cab4 (f:4ab4)
+ TX_FAR _NoWillText
+ db "@"
+
+; try to run from battle (hl = player speed, de = enemy speed)
+; stores whether the attempt was successful in carry flag
+TryRunningFromBattle: ; 3cab9 (f:4ab9)
+ call IsGhostBattle
+ jp z, .canEscape ; jump if it's a ghost battle
+ ld a, [W_BATTLETYPE]
+ cp $2
+ jp z, .canEscape ; jump if it's a safari battle
+ ld a, [W_ISLINKBATTLE]
+ cp $4
+ jp z, .canEscape
+ ld a, [W_ISINBATTLE]
+ dec a
+ jr nz, .trainerBattle ; jump if it's a trainer battle
+ ld a, [wNumRunAttempts]
+ inc a
+ ld [wNumRunAttempts], a
+ ld a, [hli]
+ ld [H_MULTIPLICAND + 1], a
+ ld a, [hl]
+ ld [H_MULTIPLICAND + 2], a
+ ld a, [de]
+ ld [$ff8d], a
+ inc de
+ ld a, [de]
+ ld [$ff8e], a
+ call LoadScreenTilesFromBuffer1
+ ld de, H_MULTIPLICAND + 1
+ ld hl, $ff8d
+ ld c, $2
+ call StringCmp
+ jr nc, .canEscape ; jump if player speed greater than enemy speed
+ xor a
+ ld [H_MULTIPLICAND], a
+ ld a, 32
+ ld [H_MULTIPLIER], a
+ call Multiply ; multiply player speed by 32
+ ld a, [H_PRODUCT + 2]
+ ld [H_DIVIDEND], a
+ ld a, [H_PRODUCT + 3]
+ ld [H_DIVIDEND + 1], a
+ ld a, [$ff8d]
+ ld b, a
+ ld a, [$ff8e]
+; divide enemy speed by 4
+ srl b
+ rr a
+ srl b
+ rr a
+ and a
+ jr z, .canEscape ; jump if enemy speed divided by 4, mod 256 is 0
+ ld [H_DIVISOR], a ; ((enemy speed / 4) % 256)
+ ld b, $2
+ call Divide ; divide (player speed * 32) by ((enemy speed / 4) % 256)
+ ld a, [H_QUOTIENT + 2]
+ and a ; is the quotient greater than 256?
+ jr nz, .canEscape ; if so, the player can escape
+ ld a, [wNumRunAttempts]
+ ld c, a
+; add 30 to the quotient for each run attempt
+.loop
+ dec c
+ jr z, .compareWithRandomValue
+ ld b, 30
+ ld a, [H_QUOTIENT + 3]
+ add b
+ ld [H_QUOTIENT + 3], a
+ jr c, .canEscape
+ jr .loop
+.compareWithRandomValue
+ call BattleRandom
+ ld b, a
+ ld a, [H_QUOTIENT + 3]
+ cp b
+ jr nc, .canEscape ; if the random value was less than or equal to the quotient plus 30 times the number of attempts, the player can escape
+; can't escape
+ ld a, $1
+ ld [wcd6a], a
+ ld hl, CantEscapeText
+ jr .printCantEscapeOrNoRunningText
+.trainerBattle
+ ld hl, NoRunningText
+.printCantEscapeOrNoRunningText
+ call PrintText
+ ld a, $1
+ ld [wd11f], a
+ call SaveScreenTilesToBuffer1
+ and a ; reset carry
+ ret
+.canEscape
+ ld a, [W_ISLINKBATTLE]
+ cp $4
+ ld a, $2
+ jr nz, .playSound
+; link battle
+ call SaveScreenTilesToBuffer1
+ xor a
+ ld [wcd6a], a
+ ld a, $f
+ ld [wPlayerMoveListIndex], a
+ call LinkBattleExchangeData
+ call LoadScreenTilesFromBuffer1
+ ld a, [wcc3e]
+ cp $f
+ ld a, $2
+ jr z, .playSound
+ dec a
+.playSound
+ ld [wBattleResult], a
+ ld a, (SFX_08_44 - SFX_Headers_08) / 3
+ call PlaySoundWaitForCurrent
+ ld hl, GotAwayText
+ call PrintText
+ call WaitForSoundToFinish
+ call SaveScreenTilesToBuffer1
+ scf ; set carry
+ 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 "@"
+
+; copies from party data to battle mon data when sending out a new player mon
+LoadBattleMonFromParty: ; 3cba6 (f:4ba6)
+ ld a, [wWhichPokemon]
+ ld bc, $2c
+ ld hl, wPartyMon1Species
+ call AddNTimes
+ ld de, wBattleMonSpecies
+ ld bc, $c
+ call CopyData
+ ld bc, $f
+ add hl, bc
+ ld de, wBattleMonDVs
+ ld bc, $2
+ call CopyData
+ ld de, wBattleMonPP
+ ld bc, $4
+ call CopyData
+ ld de, wBattleMonLevel
+ ld bc, $b
+ call CopyData
+ ld a, [wBattleMonSpecies2]
+ ld [wd0b5], a
+ call GetMonHeader
+ ld hl, wPartyMonNicks
+ ld a, [wPlayerMonNumber]
+ call SkipFixedLengthTextEntries
+ ld de, wBattleMonNick
+ ld bc, $b
+ call CopyData
+ ld hl, wBattleMonLevel
+ ld de, wPlayerMonUnmodifiedLevel ; block of memory used for unmodified stats
+ ld bc, $b
+ call CopyData
+ call ApplyBurnAndParalysisPenaltiesToPlayer
+ call ApplyBadgeStatBoosts
+ ld a, $7 ; default stat modifier
+ ld b, $8
+ ld hl, wPlayerMonAttackMod
+.statModLoop
+ ld [hli], a
+ dec b
+ jr nz, .statModLoop
+ ret
+
+; copies from enemy party data to current enemy mon data when sending out a new enemy mon
+LoadEnemyMonFromParty: ; 3cc13 (f:4c13)
+ ld a, [wWhichPokemon]
+ ld bc, $2c
+ ld hl, wEnemyMons
+ call AddNTimes
+ ld de, wEnemyMonSpecies
+ ld bc, $c
+ call CopyData
+ ld bc, $f
+ add hl, bc
+ ld de, wEnemyMonDVs
+ ld bc, $2
+ call CopyData
+ ld de, wEnemyMonPP
+ ld bc, $4
+ call CopyData
+ ld de, wEnemyMonLevel
+ ld bc, $b
+ call CopyData
+ ld a, [wEnemyMonSpecies]
+ ld [wd0b5], a
+ call GetMonHeader
+ ld hl, wEnemyMonNicks
+ ld a, [wWhichPokemon]
+ call SkipFixedLengthTextEntries
+ ld de, wEnemyMonNick
+ ld bc, $b
+ call CopyData
+ ld hl, wEnemyMonLevel
+ ld de, wEnemyMonUnmodifiedLevel ; block of memory used for unmodified stats
+ ld bc, $b
+ call CopyData
+ call ApplyBurnAndParalysisPenaltiesToEnemy
+ ld hl, W_MONHBASESTATS
+ ld de, wEnemyMonBaseStats
+ ld b, $5
+.copyBaseStatsLoop
+ ld a, [hli]
+ ld [de], a
+ inc de
+ dec b
+ jr nz, .copyBaseStatsLoop
+ ld a, $7 ; default stat modifier
+ ld b, $8
+ ld hl, wEnemyMonStatMods
+.statModLoop
+ ld [hli], a
+ dec b
+ jr nz, .statModLoop
+ ld a, [wWhichPokemon]
+ ld [wEnemyMonPartyPos], a
+ ret
+
+SendOutMon: ; 3cc91 (f:4c91)
+ callab PrintSendOutMonMessage
+ ld hl, wEnemyMonHP
+ ld a, [hli]
+ or [hl] ; is enemy mon HP zero?
+ jp z, .skipDrawingEnemyHUDAndHPBar; if HP is zero, skip drawing the HUD and HP bar
+ call DrawEnemyHUDAndHPBar
+.skipDrawingEnemyHUDAndHPBar
+ call DrawPlayerHUDAndHPBar
+ predef LoadMonBackPic
+ xor a
+ ld [$ffe1], a
+ ld hl, wcc2d
+ ld [hli], a
+ ld [hl], a
+ ld [wcc5b], a
+ ld [wd05b], a
+ ld [W_PLAYERMOVENUM], a
+ ld hl, wccf1
+ ld [hli], a
+ ld [hl], a
+ ld hl, wd060
+ ld [hli], a
+ ld [hli], a
+ ld [hli], a
+ ld [hli], a
+ ld [hl], a
+ ld [W_PLAYERDISABLEDMOVE], a
+ ld [wccee], a
+ ld [wccf7], a
+ ld b, $1
+ call GoPAL_SET
+ ld hl, W_ENEMYBATTSTATUS1
+ res 5, [hl]
+ ld a, $1
+ ld [H_WHOSETURN], a
+ ld a, POOF_ANIM
+ call PlayMoveAnimation
+ hlCoord 4, 11
+ predef Func_3f073
+ ld a, [wcf91]
+ call PlayCry
+ call PrintEmptyString
+ jp SaveScreenTilesToBuffer1
+
+; show 2 stages of the player getting smaller before disappearing
+AnimateRetreatingPlayerMon: ; 3ccfa (f:4cfa)
+ hlCoord 1, 5
+ ld bc, $707
+ call ClearScreenArea
+ hlCoord 3, 7
+ ld bc, $505
+ xor a
+ ld [wcd6c], a
+ ld [H_DOWNARROWBLINKCNT1], a
+ predef Func_79aba
+ ld c, $4
+ call DelayFrames
+ call .clearScreenArea
+ hlCoord 4, 9
+ ld bc, $303
+ ld a, $1
+ ld [wcd6c], a
+ xor a
+ ld [H_DOWNARROWBLINKCNT1], a
+ predef Func_79aba
+ call Delay3
+ call .clearScreenArea
+ ld a, $4c
+ Coorda 5, 11
+.clearScreenArea
+ hlCoord 1, 5
+ ld bc, $707
+ jp ClearScreenArea
+
+; reads player's current mon's HP into wBattleMonHP
+ReadPlayerMonCurHPAndStatus: ; 3cd43 (f:4d43)
+ ld a, [wPlayerMonNumber]
+ ld hl, wPartyMon1HP
+ ld bc, wPartyMon2 - wPartyMon1
+ call AddNTimes
+ ld d, h
+ ld e, l
+ ld hl, wBattleMonHP
+ ld bc, $4 ; 2 bytes HP, 1 byte unknown (unused?), 1 byte status
+ jp CopyData
+
+DrawHUDsAndHPBars: ; 3cd5a (f:4d5a)
+ call DrawPlayerHUDAndHPBar
+ jp DrawEnemyHUDAndHPBar
+
+DrawPlayerHUDAndHPBar: ; 3cd60 (f:4d60)
+ xor a
+ ld [H_AUTOBGTRANSFERENABLED], a
+ hlCoord 9, 7
+ ld bc, $50b
+ call ClearScreenArea
+ callab PlacePlayerHUDTiles
+ hlCoord 18, 9
+ ld [hl], $73
+ ld de, wBattleMonNick
+ hlCoord 10, 7
+ call CenterMonName
+ call PlaceString
+ ld hl, wBattleMonSpecies
+ ld de, wcf98
+ ld bc, $c
+ call CopyData
+ ld hl, wBattleMonLevel
+ ld de, wcfb9
+ ld bc, $b
+ call CopyData
+ hlCoord 14, 8
+ push hl
+ inc hl
+ ld de, wcf9c
+ call PrintStatusConditionNotFainted
+ pop hl
+ jr nz, .asm_3cdae
+ call PrintLevel
+.asm_3cdae
+ ld a, [wcf98]
+ ld [wcf91], a
+ hlCoord 10, 9
+ predef DrawHP
+ ld a, $1
+ ld [H_AUTOBGTRANSFERENABLED], a
+ ld hl, wcf1d
+ call GetBattleHealthBarColor
+ ld hl, wBattleMonHP
+ ld a, [hli]
+ or [hl]
+ jr z, .asm_3cdd9
+ ld a, [wccf6]
+ and a
+ ret nz
+ ld a, [wcf1d]
+ cp $2
+ jr z, .asm_3cde6
+.asm_3cdd9
+ ld hl, wd083
+ bit 7, [hl]
+ ld [hl], $0
+ ret z
+ xor a
+ ld [wc02a], a
+ ret
+.asm_3cde6
+ ld hl, wd083
+ set 7, [hl]
+ ret
+
+DrawEnemyHUDAndHPBar: ; 3cdec (f:4dec)
+ xor a
+ ld [H_AUTOBGTRANSFERENABLED], a
+ ld hl, wTileMap
+ ld bc, $40c
+ call ClearScreenArea
+ callab PlaceEnemyHUDTiles
+ ld de, wEnemyMonNick
+ hlCoord 1, 0
+ call CenterMonName
+ call PlaceString
+ hlCoord 4, 1
+ push hl
+ inc hl
+ ld de, wEnemyMonStatus
+ call PrintStatusConditionNotFainted
+ pop hl
+ jr nz, .skipPrintLevel ; if the mon has a status condition, skip printing the level
+ ld a, [wEnemyMonLevel]
+ ld [wcfb9], a
+ call PrintLevel
+.skipPrintLevel
+ ld hl, wEnemyMonHP
+ ld a, [hli]
+ ld [H_MULTIPLICAND + 1], a
+ ld a, [hld]
+ ld [H_MULTIPLICAND + 2], a
+ or [hl] ; is current HP zero?
+ jr nz, .hpNonzero
+; current HP is 0
+; set variables for DrawHPBar
+ ld c, a
+ ld e, a
+ ld d, $6
+ jp .drawHPBar
+.hpNonzero
+ xor a
+ ld [H_MULTIPLICAND], a
+ ld a, 48
+ ld [H_MULTIPLIER], a
+ call Multiply ; multiply current HP by 48
+ ld hl, wEnemyMonMaxHP
+ ld a, [hli]
+ ld b, a
+ ld a, [hl]
+ ld [H_DIVISOR], a
+ ld a, b
+ and a ; is max HP > 255?
+ jr z, .doDivide
+; if max HP > 255, scale both (current HP * 48) and max HP by dividing by 4 so that max HP fits in one byte
+; (it needs to be one byte so it can be used as the divisor for the Divide function)
+ ld a, [H_DIVISOR]
+ srl b
+ rr a
+ srl b
+ rr a
+ ld [H_DIVISOR], a
+ ld a, [H_PRODUCT + 2]
+ ld b, a
+ srl b
+ ld a, [H_PRODUCT + 3]
+ rr a
+ srl b
+ rr a
+ ld [H_PRODUCT + 3], a
+ ld a, b
+ ld [H_PRODUCT + 2], a
+.doDivide
+ ld a, [H_PRODUCT + 2]
+ ld [H_DIVIDEND], a
+ ld a, [H_PRODUCT + 3]
+ ld [H_DIVIDEND + 1], a
+ ld a, $2
+ ld b, a
+ call Divide ; divide (current HP * 48) by max HP
+ ld a, [H_QUOTIENT + 3]
+; set variables for DrawHPBar
+ ld e, a
+ ld a, $6
+ ld d, a
+ ld c, a
+.drawHPBar
+ xor a
+ ld [wListMenuID], a
+ hlCoord 2, 2
+ call DrawHPBar
+ ld a, $1
+ ld [H_AUTOBGTRANSFERENABLED], a
+ ld hl, wcf1e
+
+GetBattleHealthBarColor: ; 3ce90 (f:4e90)
+ ld b, [hl]
+ call GetHealthBarColor
+ ld a, [hl]
+ cp b
+ ret z
+ ld b, $1
+ jp GoPAL_SET
+
+; center's mon's name on the battle screen
+; if the name is 1 or 2 letters long, it is printed 2 spaces more to the right than usual (i.e. for names longer than 4 letters)
+; if the name is 3 or 4 letters long, it is printed 1 space more to the right than usual (i.e. for names longer than 4 letters)
+CenterMonName: ; 3ce9c (f:4e9c)
+ push de
+ inc hl
+ inc hl
+ ld b, $2
+.loop
+ inc de
+ ld a, [de]
+ cp $50
+ jr z, .done
+ inc de
+ ld a, [de]
+ cp $50
+ jr z, .done
+ dec hl
+ dec b
+ jr nz, .loop
+.done
+ pop de
+ ret
+
+DisplayBattleMenu: ; 3ceb3 (f:4eb3)
+ call LoadScreenTilesFromBuffer1 ; restore saved screen
+ ld a, [W_BATTLETYPE]
+ and a
+ jr nz, .nonstandardbattle
+ call DrawHUDsAndHPBars
+ call PrintEmptyString
+ call SaveScreenTilesToBuffer1
+.nonstandardbattle
+ ld a, [W_BATTLETYPE]
+ cp $2 ; safari
+ ld a, $b ; safari menu id
+ jr nz, .menuselected
+ ld a, $1b ; regular menu id
+.menuselected
+ ld [wd125], a
+ call DisplayTextBoxID
+ ld a, [W_BATTLETYPE]
+ dec a
+ jp nz, .handleBattleMenuInput ; handle menu input if it's not the old man tutorial
+; the following happens for the old man tutorial
+ ld hl, wPlayerName
+ ld de, W_GRASSRATE
+ 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
+ ld de, wPlayerName
+ ld bc, $b
+ call CopyData
+ ; the following simulates the keystrokes by drawing menus on screen
+ hlCoord 9, 14
+ ld [hl], "▶"
+ ld c, $50
+ call DelayFrames
+ ld [hl], $7f
+ hlCoord 9, 16
+ ld [hl], "▶"
+ ld c, $32
+ call DelayFrames
+ ld [hl], $ec
+ ld a, $2 ; select the "ITEM" menu
+ jp .upperLeftMenuItemWasNotSelected
+.oldManName
+ db "OLD MAN@"
+.handleBattleMenuInput
+ ld a, [wcc2d]
+ ld [wCurrentMenuItem], a
+ ld [wLastMenuItem], a
+ sub 2 ; check if the cursor is in the left column
+ jr c, .leftColumn
+; cursor is in the right column
+ ld [wCurrentMenuItem], a
+ ld [wLastMenuItem], a
+ jr .rightColumn
+.leftColumn ; put cursor in left column of menu
+ ld a, [W_BATTLETYPE]
+ cp $2
+ ld a, " "
+ jr z, .safariLeftColumn
+; put cursor in left column for normal battle menu (i.e. when it's not a Safari battle)
+ Coorda 15, 14 ; clear upper cursor position in right column
+ Coorda 15, 16 ; clear lower cursor position in right column
+ ld b, $9 ; top menu item X
+ jr .leftColumn_WaitForInput
+.safariLeftColumn
+ Coorda 13, 14
+ Coorda 13, 16
+ hlCoord 7, 14
+ ld de, W_NUMSAFARIBALLS
+ ld bc, $102
+ call PrintNumber
+ ld b, $1 ; top menu item X
+.leftColumn_WaitForInput
+ ld hl, wTopMenuItemY
+ ld a, $e
+ ld [hli], a ; wTopMenuItemY
+ ld a, b
+ ld [hli], a ; wTopMenuItemX
+ inc hl
+ inc hl
+ ld a, $1
+ ld [hli], a ; wMaxMenuItem
+ ld [hl], D_RIGHT | A_BUTTON ; wMenuWatchedKeys
+ call HandleMenuInput
+ bit 4, a ; check if right was pressed
+ jr nz, .rightColumn
+ jr .AButtonPressed ; the A button was pressed
+.rightColumn ; put cursor in right column of menu
+ ld a, [W_BATTLETYPE]
+ cp $2
+ ld a, " "
+ jr z, .safariRightColumn
+; put cursor in right column for normal battle menu (i.e. when it's not a Safari battle)
+ Coorda 9, 14 ; clear upper cursor position in left column
+ Coorda 9, 16 ; clear lower cursor position in left column
+ ld b, $f ; top menu item X
+ jr .rightColumn_WaitForInput
+.safariRightColumn
+ Coorda 1, 14 ; clear upper cursor position in left column
+ Coorda 1, 16 ; clear lower cursor position in left column
+ hlCoord 7, 14
+ ld de, W_NUMSAFARIBALLS
+ ld bc, $102
+ call PrintNumber
+ ld b, $d ; top menu item X
+.rightColumn_WaitForInput
+ ld hl, wTopMenuItemY
+ ld a, $e
+ ld [hli], a ; wTopMenuItemY
+ ld a, b
+ ld [hli], a ; wTopMenuItemX
+ inc hl
+ inc hl
+ ld a, $1
+ ld [hli], a ; wMaxMenuItem
+ ld a, D_LEFT | A_BUTTON
+ ld [hli], a ; wMenuWatchedKeys
+ call HandleMenuInput
+ bit 5, a ; check if left was pressed
+ jr nz, .leftColumn ; if left was pressed, jump
+ ld a, [wCurrentMenuItem]
+ add $2 ; if we're in the right column, the actual id is +2
+ ld [wCurrentMenuItem], a
+.AButtonPressed
+ call PlaceUnfilledArrowMenuCursor
+ ld a, [W_BATTLETYPE]
+ cp $2 ; is it a Safari battle?
+ ld a, [wCurrentMenuItem]
+ ld [wcc2d], a
+ jr z, .handleMenuSelection
+; not Safari battle
+; swap the IDs of the item menu and party menu (this is probably because they swapped the positions of these menu items in first generation English versions)
+ cp $1 ; was the item menu selected?
+ jr nz, .notItemMenu
+; item menu was selected
+ inc a ; increment a to 2
+ jr .handleMenuSelection
+.notItemMenu
+ cp $2 ; was the party menu selected?
+ jr nz, .handleMenuSelection
+; party menu selected
+ dec a ; decrement a to 1
+.handleMenuSelection
+ and a
+ jr nz, .upperLeftMenuItemWasNotSelected
+; the upper left menu item was selected
+ ld a, [W_BATTLETYPE]
+ cp $2
+ jr z, .throwSafariBallWasSelected
+; the "FIGHT" menu was selected
+ xor a
+ ld [wNumRunAttempts], a
+ jp LoadScreenTilesFromBuffer1 ; restore saved screen and return
+.throwSafariBallWasSelected
+ ld a, SAFARI_BALL
+ ld [wcf91], a
+ jr .useItem
+.upperLeftMenuItemWasNotSelected ; a menu item other than the upper left item was selected
+ cp $2
+ jp nz, .partyMenuOrRockOrRunWasSelected
+; either the bag (normal battle) or bait (safari battle) was selected
+ ld a, [W_ISLINKBATTLE]
+ cp $4
+ jr nz, .notLinkBattle
+; can't use items in link battles
+ ld hl, .itemsCantBeUsedHereText
+ call PrintText
+ jp DisplayBattleMenu
+.notLinkBattle
+ call SaveScreenTilesToBuffer2
+ ld a, [W_BATTLETYPE]
+ cp $2 ; is it a safari battle?
+ jr nz, .bagWasSelected
+; bait was selected
+ ld a, SAFARI_BAIT
+ ld [wcf91], a
+ jr .useItem
+.bagWasSelected
+ call LoadScreenTilesFromBuffer1
+ ld a, [W_BATTLETYPE]
+ and a ; is it a normal battle?
+ jr nz, .next
+; normal battle
+ call DrawHUDsAndHPBars
+.next
+ ld a, [W_BATTLETYPE]
+ dec a ; is it the old man tutorial?
+ jr nz, .getPlayerBagPointer ; no, it is a normal battle
+ ld hl, .oldManItemList
+ ld a, l
+ ld [wcf8b], a
+ ld a, h
+ ld [wcf8c], a
+<<<<<<< HEAD
+ jr Func_3d03c
+
+OldManItemList: ; 3d02d (f:502d)
+ db 1 ; # items
+ db POKE_BALL, 50
+ db -1
+
+Func_3d031
+ ld hl, wNumBagItems ; wNumBagItems
+=======
+ jr .displayBagMenu
+.oldManItemList
+ db $01, POKE_BALL, 50, $ff
+.getPlayerBagPointer ; get the pointer to player's bag when in a normal battle
+ ld hl, wNumBagItems
+>>>>>>> yama/master
+ ld a, l
+ ld [wcf8b], a
+ ld a, h
+ ld [wcf8c], a
+.displayBagMenu
+ xor a
+ ld [wcf93], a
+ ld a, ITEMLISTMENU
+ ld [wListMenuID], a
+ ld a, [wcc2c]
+ ld [wCurrentMenuItem], a
+ call DisplayListMenuID
+ ld a, [wCurrentMenuItem]
+ ld [wcc2c], a
+ ld a, $0
+ ld [wcc37], a
+ ld [wMenuItemToSwap], a
+ jp c, DisplayBattleMenu ; go back to battle menu if an item was not selected
+.useItem ; either use an item from the bag or use a safari zone item
+ ld a, [wcf91]
+ ld [wd11e], a
+ call GetItemName
+ call CopyStringToCF4B ; copy name
+ xor a
+ ld [wd152], a
+ call UseItem
+ call LoadHudTilePatterns
+ call ClearSprites
+ xor a
+ ld [wCurrentMenuItem], a
+ ld a, [W_BATTLETYPE]
+ cp $2 ; is it a safari battle?
+ jr z, .checkIfMonCaptured
+ ld a, [wcd6a]
+ and a ; was the item used successfully?
+ jp z, .bagWasSelected ; if not, go back to the bag menu
+ ld a, [W_PLAYERBATTSTATUS1]
+ bit 5, a ; is the player using a multi-turn move like wrap?
+ jr z, .checkIfMonCaptured
+ ld hl, wPlayerNumAttacksLeft
+ dec [hl]
+ jr nz, .checkIfMonCaptured
+ ld hl, W_PLAYERBATTSTATUS1
+ res 5, [hl] ; not using multi-turn move any more
+.checkIfMonCaptured
+ ld a, [wd11c]
+ and a ; was the enemy mon captured with a ball?
+ jr nz, .returnAfterCapturingMon
+ ld a, [W_BATTLETYPE]
+ cp $2 ; is it a safari battle?
+ jr z, .returnAfterUsingItem_NoCapture
+; not a safari battle
+ call LoadScreenTilesFromBuffer1
+ call DrawHUDsAndHPBars
+ call Delay3
+.returnAfterUsingItem_NoCapture
+ call GBPalNormal
+ and a ; reset carry
+ ret
+.returnAfterCapturingMon
+ call GBPalNormal
+ xor a
+ ld [wd11c], a
+ ld a, $2
+ ld [wBattleResult], a
+ scf ; set carry
+ ret
+
+.itemsCantBeUsedHereText
+ TX_FAR _ItemsCantBeUsedHereText
+ db "@"
+
+.partyMenuOrRockOrRunWasSelected
+ dec a ; was Run selected?
+ jp nz, BattleMenu_RunWasSelected
+; party menu or rock was selected
+ call SaveScreenTilesToBuffer2
+ ld a, [W_BATTLETYPE]
+ cp $2 ; is it a safari battle?
+ jr nz, .partyMenuWasSelected
+; safari battle
+ ld a, SAFARI_ROCK
+ ld [wcf91], a
+ jp .useItem
+.partyMenuWasSelected
+ call LoadScreenTilesFromBuffer1
+ xor a
+ ld [wd07d], a
+ ld [wMenuItemToSwap], a
+ call DisplayPartyMenu
+.checkIfPartyMonWasSelected
+ jp nc, .partyMonWasSelected ; if a party mon was selected, jump, else we quit the party menu
+.quitPartyMenu
+ call ClearSprites
+ call GBPalWhiteOut
+ call LoadHudTilePatterns
+ call LoadScreenTilesFromBuffer2
+ call GoPAL_SET_CF1C
+ call GBPalNormal
+ jp DisplayBattleMenu
+.partyMonDeselected
+ hlCoord 11, 11
+ ld bc, $81
+ ld a, $7f
+ call FillMemory
+ xor a
+ ld [wd07d], a
+ call GoBackToPartyMenu
+ jr .checkIfPartyMonWasSelected
+.partyMonWasSelected
+ ld a, $c ; switch/stats/cancel menu
+ ld [wd125], a
+ call DisplayTextBoxID
+ ld hl, wTopMenuItemY
+ ld a, $c
+ ld [hli], a ; wTopMenuItemY
+ ld [hli], a ; wTopMenuItemX
+ xor a
+ ld [hli], a ; wCurrentMenuItem
+ inc hl
+ ld a, $2
+ ld [hli], a ; wMaxMenuItem
+ ld a, B_BUTTON | A_BUTTON
+ ld [hli], a ; wMenuWatchedKeys
+ xor a
+ ld [hl], a ; wLastMenuItem
+ call HandleMenuInput
+ bit 1, a ; was A pressed?
+ jr nz, .partyMonDeselected ; if B was pressed, jump
+; A was pressed
+ call PlaceUnfilledArrowMenuCursor
+ ld a, [wCurrentMenuItem]
+ cp $2 ; was Cancel selected?
+ jr z, .quitPartyMenu ; if so, quit the party menu entirely
+ and a ; was Switch selected?
+ jr z, .switchMon ; if so, jump
+; Stats was selected
+ xor a
+ ld [wcc49], a
+ ld hl, wPartyMon1
+ call ClearSprites
+; display the two status screens
+ predef StatusScreen
+ predef StatusScreen2
+; now we need to reload the enemy mon pic
+ ld a, [W_ENEMYBATTSTATUS2]
+ bit 4, a ; does the enemy mon have a substitute?
+ ld hl, AnimationSubstitute
+ jr nz, .doEnemyMonAnimation
+; enemy mon doesn't have substitute
+ ld a, [wccf3]
+ and a ; has the enemy mon used Minimise?
+ ld hl, AnimationMinimizeMon
+ jr nz, .doEnemyMonAnimation
+; enemy mon is not minimised
+ ld a, [wEnemyMonSpecies]
+ ld [wcf91], a
+ ld [wd0b5], a
+ call GetMonHeader
+ ld de, vFrontPic
+ call LoadMonFrontSprite
+ jr .enemyMonPicReloaded
+.doEnemyMonAnimation
+ ld b, BANK(AnimationSubstitute) ; BANK(AnimationMinimizeMon)
+ call Bankswitch
+.enemyMonPicReloaded ; enemy mon pic has been reloaded, so return to the party menu
+ jp .partyMenuWasSelected
+.switchMon
+ ld a, [wPlayerMonNumber]
+ ld d, a
+ ld a, [wWhichPokemon]
+ cp d ; check if the mon to switch to is already out
+ jr nz, .notAlreadyOut
+; mon is already out
+ ld hl, AlreadyOutText
+ call PrintText
+ jp .partyMonDeselected
+.notAlreadyOut
+ call HasMonFainted
+ jp z, .partyMonDeselected ; can't switch to fainted mon
+ ld a, $1
+ ld [wcd6a], a
+ call GBPalWhiteOut
+ call ClearSprites
+ call LoadHudTilePatterns
+ call LoadScreenTilesFromBuffer1
+ call GoPAL_SET_CF1C
+ call GBPalNormal
+; fall through to SwitchPlayerMon
+
+SwitchPlayerMon: ; 3d1ba (f:51ba)
+ callab RetreatMon
+ ld c, $32
+ call DelayFrames
+ call AnimateRetreatingPlayerMon
+ ld a, [wWhichPokemon]
+ ld [wPlayerMonNumber], a
+ ld c, a
+ ld b, $1
+ push bc
+ ld hl, wPartyGainExpFlags
+ predef FlagActionPredef
+ pop bc
+ ld hl, wPartyFoughtCurrentEnemyFlags
+ predef FlagActionPredef
+ call LoadBattleMonFromParty
+ call SendOutMon
+ call SaveScreenTilesToBuffer1
+ ld a, $2
+ ld [wCurrentMenuItem], a
+ and a
+ ret
+
+AlreadyOutText: ; 3d1f5 (f:51f5)
+ TX_FAR _AlreadyOutText
+ db "@"
+
+BattleMenu_RunWasSelected: ; 3d1fa (f:51fa)
+ call LoadScreenTilesFromBuffer1
+ ld a, $3
+ ld [wCurrentMenuItem], a
+ ld hl, wBattleMonSpeed
+ ld de, wEnemyMonSpeed
+ call TryRunningFromBattle
+ ld a, $0
+ ld [wd11f], a
+ ret c
+ ld a, [wcd6a]
+ and a
+ ret nz
+ jp DisplayBattleMenu
+
+MoveSelectionMenu: ; 3d219 (f:5219)
+ ld a, [wMoveMenuType]
+ dec a
+ jr z, .mimicmenu
+ dec a
+ jr z, .relearnmenu
+ jr .regularmenu
+
+.loadmoves
+ ld de, wd0dc
+ ld bc, $4
+ call CopyData
+ callab Func_39b87
+ ret
+
+.writemoves
+ ld de, wd0e1
+ 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, wBattleMonMoves
+ call .loadmoves
+ hlCoord 4, 12
+ ld b, $4
+ ld c, $e
+ di
+ call TextBoxBorder
+ hlCoord 4, 12
+ ld [hl], $7a
+ hlCoord 10, 12
+ ld [hl], $7e
+ ei
+ hlCoord 6, 13
+ call .writemoves
+ ld b, $5
+ ld a, $c
+ jr .menuset
+.mimicmenu
+ ld hl, wEnemyMonMoves
+ call .loadmoves
+ hlCoord 0, 7
+ ld b, $4
+ ld c, $e
+ call TextBoxBorder
+ hlCoord 2, 8
+ call .writemoves
+ ld b, $1
+ ld a, $7
+ jr .menuset
+.relearnmenu
+ ld a, [wWhichPokemon]
+ ld hl, wPartyMon1Moves
+ ld bc, $2c
+ call AddNTimes
+ call .loadmoves
+ hlCoord 4, 7
+ ld b, $4
+ ld c, $e
+ call TextBoxBorder
+ hlCoord 6, 8
+ call .writemoves
+ ld b, $5
+ ld a, $7
+.menuset
+ ld hl, wTopMenuItemY
+ ld [hli], a
+ ld a, b
+ ld [hli], a
+ ld a, [wMoveMenuType]
+ cp $1
+ jr z, .selectedmoveknown
+ ld a, $1
+ jr nc, .selectedmoveknown
+ ld a, [wPlayerMoveListIndex]
+ inc a
+.selectedmoveknown
+ ld [hli], a
+ inc hl ; wTileBehindCursor untouched
+ ld a, [wcd6c]
+ inc a
+ inc a
+ ld [hli], a
+ 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]
+ 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
+ ld a, [wMoveMenuType]
+ cp $1
+ jr z, .movelistindex1
+ ld a, [wPlayerMoveListIndex]
+ inc a
+.movelistindex1
+ ld [hl], a
+
+Func_3d2fe: ; 3d2fe (f:52fe)
+ ld a, [wMoveMenuType]
+ and a
+ jr z, .battleselect
+ dec a
+ jr nz, .select
+ hlCoord 1, 14
+ ld de, WhichTechniqueString
+ call PlaceString
+ jr .select
+.battleselect
+ ld a, [W_FLAGS_D733]
+ bit 0, a
+ jr nz, .select
+ call Func_3d4b6
+ ld a, [wMenuItemToSwap]
+ and a
+ jr z, .select
+ hlCoord 5, 13
+ 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, SwapMovesInMenu ; select
+ bit 1, a ; B, but was it reset above?
+ push af
+ xor a
+ ld [wMenuItemToSwap], a
+ ld a, [wCurrentMenuItem]
+ dec a
+ ld [wCurrentMenuItem], a
+ 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
+ jr nz, .moveselected
+ pop af
+ ret
+.moveselected
+ pop af
+ ret nz
+ ld hl, wBattleMonPP
+ ld a, [wCurrentMenuItem]
+ ld c, a
+ ld b, $0
+ add hl, bc
+ ld a, [hl]
+ and $3f
+ jr z, .nopp
+ ld a, [W_PLAYERDISABLEDMOVE]
+ swap a
+ and $f
+ dec a
+ cp c
+ jr z, .disabled
+ ld a, [W_PLAYERBATTSTATUS3]
+ bit 3, a ; transformed
+ jr nz, .dummy ; game freak derp
+.dummy
+ ld a, [wCurrentMenuItem]
+ ld hl, wBattleMonMoves
+ ld c, a
+ ld b, $0
+ add hl, bc
+ ld a, [hl]
+ ld [wPlayerSelectedMove], a
+ 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]
+ and a
+ jp nz, Func_3d2fe
+ call EraseMenuCursor
+ ld a, [wcd6c]
+ inc a
+ ld [wCurrentMenuItem], a
+ jp Func_3d2fe
+
+Func_3d3dd: ; 3d3dd (f:53dd)
+ ld a, [wCurrentMenuItem]
+ ld b, a
+ ld a, [wcd6c]
+ inc a
+ inc a
+ cp b
+ jp nz, Func_3d2fe
+ call EraseMenuCursor
+ ld a, $1
+ ld [wCurrentMenuItem], a
+ jp Func_3d2fe
+
+Func_3d3f5: ; 3d3f5 (f:53f5)
+ ld a, STRUGGLE
+ ld [wPlayerSelectedMove], a
+ ld a, [W_PLAYERDISABLEDMOVE]
+ and a
+ ld hl, wBattleMonPP
+ 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 "@"
+
+SwapMovesInMenu: ; 3d435 (f:5435)
+ ld a, [wMenuItemToSwap]
+ and a
+ jr z, .noMenuItemSelected
+ ld hl, wBattleMonMoves
+ call .swapBytes ; swap moves
+ ld hl, wBattleMonPP
+ call .swapBytes ; swap move PP
+; update the index of the disabled move if necessary
+ ld hl, W_PLAYERDISABLEDMOVE
+ ld a, [hl]
+ swap a
+ and $f
+ ld b, a
+ ld a, [wCurrentMenuItem]
+ cp b
+ jr nz, .next
+ ld a, [hl]
+ and $f
+ ld b, a
+ ld a, [wMenuItemToSwap]
+ swap a
+ add b
+ ld [hl], a
+ jr .swapMovesInPartyMon
+.next
+ ld a, [wMenuItemToSwap]
+ cp b
+ jr nz, .swapMovesInPartyMon
+ ld a, [hl]
+ and $f
+ ld b, a
+ ld a, [wCurrentMenuItem]
+ swap a
+ add b
+ ld [hl], a
+.swapMovesInPartyMon
+ ld hl, wPartyMon1Moves
+ ld a, [wPlayerMonNumber]
+ ld bc, wPartyMon2 - wPartyMon1
+ call AddNTimes
+ push hl
+ call .swapBytes ; swap moves
+ pop hl
+ ld bc, $15
+ add hl, bc
+ call .swapBytes ; swap move PP
+ xor a
+ ld [wMenuItemToSwap], a ; deselect the item
+ jp MoveSelectionMenu
+.swapBytes
+ push hl
+ ld a, [wMenuItemToSwap]
+ dec a
+ ld c, a
+ ld b, 0
+ add hl, bc
+ ld d, h
+ ld e, l
+ pop hl
+ ld a, [wCurrentMenuItem]
+ 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
+.noMenuItemSelected
+ ld a, [wCurrentMenuItem]
+ ld [wMenuItemToSwap], a ; select the current menu item for swapping
+ jp MoveSelectionMenu
+
+Func_3d4b6: ; 3d4b6 (f:54b6)
+ xor a
+ ld [H_AUTOBGTRANSFERENABLED], a
+ hlCoord 0, 8
+ ld b, $3
+ ld c, $9
+ call TextBoxBorder
+ ld a, [W_PLAYERDISABLEDMOVE]
+ and a
+ jr z, .asm_3d4df
+ swap a
+ and $f
+ ld b, a
+ ld a, [wCurrentMenuItem]
+ cp b
+ jr nz, .asm_3d4df
+ hlCoord 1, 10
+ ld de, DisabledText
+ call PlaceString
+ jr .asm_3d54e
+.asm_3d4df
+ ld hl, wCurrentMenuItem
+ dec [hl]
+ xor a
+ ld [H_WHOSETURN], a
+ ld hl, wBattleMonMoves
+ ld a, [wCurrentMenuItem]
+ ld c, a
+ ld b, $0
+ add hl, bc
+ ld a, [hl]
+ ld [wPlayerSelectedMove], a
+ ld a, [wPlayerMonNumber]
+ ld [wWhichPokemon], a
+ ld a, $4
+ ld [wcc49], a
+ callab GetMaxPP
+ ld hl, wCurrentMenuItem
+ ld c, [hl]
+ inc [hl]
+ ld b, $0
+ ld hl, wBattleMonPP
+ add hl, bc
+ ld a, [hl]
+ and $3f
+ ld [wcd6d], a
+ hlCoord 1, 9
+ ld de, TypeText
+ call PlaceString
+ hlCoord 7, 11
+ ld [hl], "/"
+ hlCoord 5, 9
+ ld [hl], "/"
+ hlCoord 5, 11
+ ld de, wcd6d
+ ld bc, $102
+ call PrintNumber
+ hlCoord 8, 11
+ ld de, wd11e
+ ld bc, $102
+ call PrintNumber
+ call GetCurrentMove
+ hlCoord 2, 10
+ predef Func_27d98
+.asm_3d54e
+ ld a, $1
+ ld [H_AUTOBGTRANSFERENABLED], a
+ 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
+; link battle
+ call SaveScreenTilesToBuffer1
+ call LinkBattleExchangeData
+ call LoadScreenTilesFromBuffer1
+ ld a, [wcc3e]
+ cp $e
+ jp z, .asm_3d601
+ cp $d
+ jr z, .unableToMove
+ cp $4
+ ret nc
+ ld [wEnemyMoveListIndex], a
+ ld c, a
+ ld hl, wEnemyMonMoves
+ 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, [wEnemyMonStatus]
+ 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, wEnemyMonMoves+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 BattleRandom
+ 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, STRUGGLE
+ jr .done
+
+; this appears to exchange data with the other gameboy during link battles
+LinkBattleExchangeData: ; 3d605 (f:5605)
+ ld a, $ff
+ ld [wcc3e], a
+ ld a, [wPlayerMoveListIndex]
+ cp $f ; is the player running from battle?
+ jr z, .asm_3d630
+ ld a, [wcd6a]
+ and a
+ jr nz, .asm_3d629
+ ld a, [wPlayerSelectedMove]
+ cp STRUGGLE
+ ld b, $e
+ jr z, .asm_3d62f
+ dec b
+ inc a
+ jr z, .asm_3d62f
+ ld a, [wPlayerMoveListIndex]
+ jr .asm_3d630
+.asm_3d629
+ ld a, [wWhichPokemon]
+ add $4
+ ld b, a
+.asm_3d62f
+ ld a, b
+.asm_3d630
+ ld [wcc42], a
+ callab PrintWaitingText
+.asm_3d63b
+ call Func_22c3
+ call DelayFrame
+ ld a, [wcc3e]
+ 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
+
+ExecutePlayerMove: ; 3d65e (f:565e)
+ xor a
+ ld [H_WHOSETURN], a
+ ld a, [wPlayerSelectedMove]
+ inc a
+ jp z, Func_3d80a
+ xor a
+ ld [W_MOVEMISSED], a
+ ld [wcced], a
+ ld [wccf4], a
+ ld a, $a
+ ld [wd05b], a
+ ld a, [wcd6a]
+ and a
+ jp nz, Func_3d80a
+ call PrintGhostText
+ jp z, Func_3d80a
+ call CheckPlayerStatusConditions
+ jr nz, .asm_3d68a
+ jp [hl]
+.asm_3d68a
+ call GetCurrentMove
+ ld hl, W_PLAYERBATTSTATUS1
+ bit 4, [hl]
+ jr nz, asm_3d6a9
+ call CheckForDisobedience
+ jp z, Func_3d80a
+
+Func_3d69a: ; 3d69a (f:569a)
+ ld a, [W_PLAYERMOVEEFFECT]
+ cp CHARGE_EFFECT
+ jp z, JumpMoveEffect
+ cp FLY_EFFECT
+ jp z, JumpMoveEffect
+ 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,wPlayerSelectedMove ; 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,JumpMoveEffect
+ ld a,[W_PLAYERMOVEEFFECT]
+ ld hl,EffectsArray5B
+ ld de,1
+ call IsInArray
+ call c,JumpMoveEffect
+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 GetDamageVarsForPlayerAttack
+ call CalculateDamage
+ jp z,asm_3d74b
+ call AdjustDamageForMoveType
+ call RandomizeDamage
+.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
+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 [wcc5b],a
+ ld a,[W_PLAYERMOVENUM]
+ call PlayMoveAnimation
+ call Func_3eed3
+ call DrawPlayerHUDAndHPBar
+ 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 [wcc5b],a
+ ld a,STATUS_AFFECTED_ANIM
+ call PlayMoveAnimation
+asm_3d766
+ ld a,[W_PLAYERMOVEEFFECT]
+ cp a,MIRROR_MOVE_EFFECT
+ jr nz,.next6
+ call MirrorMoveCopyMove
+ jp z,Func_3d80a
+ xor a
+ ld [wcced],a
+ jp Func_3d69a
+.next6
+ cp a,METRONOME_EFFECT
+ jr nz,.next7
+ call MetronomePickMove
+ jp Func_3d69a
+.next7
+ ld a,[W_PLAYERMOVEEFFECT]
+ ld hl,EffectsArray3
+ ld de,1
+ call IsInArray
+ jp c,JumpMoveEffect
+ ld a,[W_MOVEMISSED]
+ and a
+ jr z,.next8
+ call PrintMoveFailureText
+ ld a,[W_PLAYERMOVEEFFECT]
+ cp a,EXPLODE_EFFECT
+ jr z,.next9
+ jp Func_3d80a
+.next8
+ call ApplyAttackToEnemyPokemon
+ call PrintCriticalOHKOText
+ callab DisplayEffectiveness
+ ld a,1
+ ld [wccf4],a
+.next9
+ ld a,[W_PLAYERMOVEEFFECT]
+ ld hl,EffectsArray4
+ ld de,1
+ call IsInArray
+ call c,JumpMoveEffect
+ ld hl,wEnemyMonHP
+ ld a,[hli]
+ ld b,[hl]
+ or b
+ ret z
+ call HandleBuildingRage
+
+ ld hl,W_PLAYERBATTSTATUS1
+ bit 2,[hl]
+ jr z,.next10
+ ld a,[wPlayerNumAttacksLeft]
+ dec a
+ ld [wPlayerNumAttacksLeft],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,JumpMoveEffect
+ jp Func_3d80a
+
+MultiHitText: ; 3d805 (f:5805)
+ TX_FAR _MultiHitText
+ db "@"
+
+Func_3d80a: ; 3d80a (f:580a)
+ xor a
+ ld [wcd6a],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,[wBattleMonStatus] ; 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
+ ret z
+.next
+ ld a,1
+ and a
+ ret
+
+; checks for various status conditions affecting the player mon
+; stores whether the mon cannot use a move this turn in Z flag
+CheckPlayerStatusConditions: ; 3d854 (f:5854)
+ ld hl,wBattleMonStatus
+ ld a,[hl]
+ and a,SLP ; sleep mask
+ jr z,.FrozenCheck
+
+; sleeping
+ dec a
+ ld [wBattleMonStatus],a ; decrement number of turns left
+ and a
+ jr z,.WakeUp ; if the number of turns hit 0, wake up
+; fast asleep
+ xor a
+ ld [wcc5b],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 [wccf1],a
+ ld hl,Func_3d80a
+ jp .CannotUseMove
+
+.FrozenCheck
+ bit FRZ,[hl] ; frozen?
+ jr z,.HeldInPlaceCheck
+ ld hl,IsFrozenText
+ call PrintText
+ xor a
+ ld [wccf1],a
+ ld hl,Func_3d80a
+ jp .CannotUseMove
+
+.HeldInPlaceCheck
+ ld a,[W_ENEMYBATTSTATUS1]
+ bit 5,a
+ jp z,.FlinchedCheck
+ ld hl,CantMoveText
+ call PrintText
+ ld hl,Func_3d80a
+ jp .CannotUseMove
+
+.FlinchedCheck
+ ld hl,W_PLAYERBATTSTATUS1
+ bit 3,[hl]
+ jp z,.HyperBeamCheck
+ res 3,[hl]
+ ld hl,FlinchedText
+ call PrintText
+ ld hl,Func_3d80a
+ jp .CannotUseMove
+
+.HyperBeamCheck
+ ld hl,W_PLAYERBATTSTATUS2
+ bit 5,[hl]
+ jr z,.AnyMoveDisabledCheck
+ res 5,[hl]
+ ld hl,MustRechargeText
+ call PrintText
+ ld hl,Func_3d80a
+ jp .CannotUseMove
+
+.AnyMoveDisabledCheck
+ ld hl,W_PLAYERDISABLEDMOVE
+ ld a,[hl]
+ and a
+ jr z,.ConfusedCheck
+ dec a
+ ld [hl],a
+ and a,$F
+ jr nz,.ConfusedCheck
+ ld [hl],a
+ ld [wccee],a
+ ld hl,DisabledNoMoreText
+ call PrintText
+
+.ConfusedCheck
+ ld a,[W_PLAYERBATTSTATUS1]
+ add a
+ jr nc,.TriedToUseDisabledMoveCheck
+ ld hl,wd06b
+ dec [hl]
+ jr nz,.IsConfused
+ ld hl,W_PLAYERBATTSTATUS1
+ res 7,[hl]
+ ld hl,ConfusedNoMoreText
+ call PrintText
+ jr .TriedToUseDisabledMoveCheck
+.IsConfused
+ ld hl,IsConfusedText
+ call PrintText
+ xor a
+ ld [wcc5b],a
+ ld a,CONF_ANIM - 1
+ call PlayMoveAnimation
+ call BattleRandom
+ cp a,$80
+ jr c,.TriedToUseDisabledMoveCheck
+ ld hl,W_PLAYERBATTSTATUS1
+ ld a,[hl]
+ and a,$80 ; confused
+ ld [hl],a
+ call PrintHurtItselfText
+ jr .MonHurtItselfOrFullyParalysed
+
+.TriedToUseDisabledMoveCheck
+ ld a,[wccee]
+ and a
+ jr z,.ParalysisCheck
+ ld hl,wPlayerSelectedMove
+ cp [hl]
+ jr nz,.ParalysisCheck
+ call PrintMoveIsDisabledText
+ ld hl,Func_3d80a
+ jp .CannotUseMove
+
+.ParalysisCheck
+ ld hl,wBattleMonStatus
+ bit PAR,[hl]
+ jr z,.BideCheck
+ call BattleRandom
+ cp a,$3F
+ jr nc,.BideCheck
+ ld hl,FullyParalyzedText
+ call PrintText
+
+.MonHurtItselfOrFullyParalysed
+ ld hl,W_PLAYERBATTSTATUS1
+ ld a,[hl]
+ and a,$CC ; clear bide, thrashing, charging up, and multi-turn moves such as warp
+ ld [hl],a
+ ld a,[W_PLAYERMOVEEFFECT]
+ cp a,FLY_EFFECT
+ jr z,.FlyOrChargeEffect
+ cp a,CHARGE_EFFECT
+ jr z,.FlyOrChargeEffect
+ jr .NotFlyOrChargeEffect
+
+.FlyOrChargeEffect
+ xor a
+ ld [wcc5b],a
+ ld a,STATUS_AFFECTED_ANIM
+ call PlayMoveAnimation
+.NotFlyOrChargeEffect
+ ld hl,Func_3d80a
+ jp .CannotUseMove
+
+.BideCheck
+ ld hl,W_PLAYERBATTSTATUS1
+ bit 0,[hl] ; is mon using bide?
+ jr z,.ThrashingAboutCheck
+ xor a
+ ld [W_PLAYERMOVENUM],a
+ ld hl,W_DAMAGE
+ ld a,[hli]
+ ld b,a
+ ld c,[hl]
+ ld hl,wd075
+ ld a,[hl]
+ add c
+ ld [hld],a
+ ld a,[hl]
+ adc b
+ ld [hl],a
+ ld hl,wPlayerNumAttacksLeft
+ dec [hl]
+ jr z,.UnleashEnergy
+ ld hl,Func_3d80a
+ jp .CannotUseMove
+.UnleashEnergy
+ ld hl,W_PLAYERBATTSTATUS1
+ res 0,[hl] ; not using bide any more
+ ld hl,UnleashedEnergyText
+ call PrintText
+ ld a,1
+ ld [W_PLAYERMOVEPOWER],a
+ ld hl,wd075
+ ld a,[hld]
+ add a
+ ld b,a
+ ld [wd0d8],a
+ ld a,[hl]
+ rl a
+ ld [W_DAMAGE],a
+ or b
+ jr nz,.next
+ ld a,1
+ ld [W_MOVEMISSED],a
+.next
+ xor a
+ ld [hli],a
+ ld [hl],a
+ ld a,BIDE
+ ld [W_PLAYERMOVENUM],a
+ ld hl,asm_3d705
+ jp .CannotUseMove
+
+.ThrashingAboutCheck
+ bit 1,[hl] ; is mon using thrash or petal dance?
+ jr z,.MultiturnMoveCheck
+ ld a,THRASH
+ ld [W_PLAYERMOVENUM],a
+ ld hl,ThrashingAboutText
+ call PrintText
+ ld hl,wPlayerNumAttacksLeft
+ dec [hl]
+ ld hl,asm_3d6dc
+ jp nz,.CannotUseMove
+ push hl
+ ld hl,W_PLAYERBATTSTATUS1
+ res 1,[hl]
+ set 7,[hl]
+ call BattleRandom
+ and a,3
+ inc a
+ inc a
+ ld [wd06b],a
+ pop hl
+ jp .CannotUseMove
+
+.MultiturnMoveCheck
+ bit 5,[hl] ; is mon using multi-turn move?
+ jp z,.RageCheck
+ ld hl,AttackContinuesText
+ call PrintText
+ ld a,[wPlayerNumAttacksLeft]
+ dec a
+ ld [wPlayerNumAttacksLeft],a
+ ld hl,asm_3d714
+ jp nz,.CannotUseMove
+ jp .CannotUseMove
+
+.RageCheck
+ ld a, [W_PLAYERBATTSTATUS2]
+ bit 6, a ; is mon using rage?
+ jp z, .CanUseMove
+ ld a, RAGE
+ ld [wd11e], a
+ call GetMoveName
+ call CopyStringToCF4B
+ xor a
+ ld [W_PLAYERMOVEEFFECT], a
+ ld hl, asm_3d6b0
+ jp .CannotUseMove
+
+.CannotUseMove
+ xor a
+ ret
+
+.CanUseMove
+ 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
+ ld de, W_PLAYERBATTSTATUS1
+ ld a, [H_WHOSETURN]
+ and a
+ jr z, .asm_3da97
+ inc hl
+ ld de, W_ENEMYBATTSTATUS1
+.asm_3da97
+ ld a, [de]
+ res 4, a
+ ld [de], a
+ ld a, [hl]
+ ld [wd11e], 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, wEnemyMonDefense
+ ld a, [hli]
+ push af
+ ld a, [hld]
+ push af
+ ld a, [wBattleMonDefense]
+ ld [hli], a
+ ld a, [wBattleMonDefense + 1]
+ ld [hl], a
+ ld hl, W_PLAYERMOVEEFFECT
+ push hl
+ ld a, [hl]
+ push af
+ xor a
+ ld [hli], a
+ ld [wCriticalHitOrOHKO], a
+ ld a, $28
+ ld [hli], a
+ xor a
+ ld [hl], a
+ call GetDamageVarsForPlayerAttack
+ call CalculateDamage
+ pop af
+ pop hl
+ ld [hl], a
+ ld hl, wEnemyMonDefense + 1
+ pop af
+ ld [hld], a
+ pop af
+ ld [hl], a
+ xor a
+ ld [wcc5b], a
+ inc a
+ ld [H_WHOSETURN], a
+ call PlayMoveAnimation
+ call DrawPlayerHUDAndHPBar
+ xor a
+ ld [H_WHOSETURN], a
+ 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]
+ and a
+ ld a, [W_PLAYERMOVENUM]
+ ld hl, wccf1
+ jr z, .asm_3db11
+ ld a, [W_ENEMYMOVENUM]
+ ld hl, wccf2
+.asm_3db11
+ ld [hl], a
+ ld [wd11e], a
+ call Func_3db85
+ ld a, [wcced]
+ and a
+ ld hl, Used2Text
+ ret nz
+ ld a, [wd11e]
+ 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, [wcced]
+ 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, [wd11e]
+ 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, [wd11e] ; move number
+ ld c, a
+ ld b, $0
+ ld hl, UnknownMovesList_3dba3
+.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 [wd11e], 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
+ ld a, [H_WHOSETURN]
+ and a
+ jr z, .playersTurn
+ ld de, W_ENEMYMOVEEFFECT
+.playersTurn
+ ld hl, DoesntAffectMonText
+ ld a, [wd05b]
+ and $7f
+ jr z, .asm_3dc04
+ ld hl, AttackMissedText
+ ld a, [wCriticalHitOrOHKO]
+ cp $ff
+ jr nz, .asm_3dc04
+ ld hl, UnaffectedText
+.asm_3dc04
+ push de
+ call PrintText
+ xor a
+ ld [wCriticalHitOrOHKO], 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
+ 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
+ call PrintText
+ ld b, $4
+ predef Func_48125
+ ld a, [H_WHOSETURN]
+ 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
+ jp PrintText
+
+DoesntAffectMonText: ; 3dc57 (f:5c57)
+ TX_FAR _DoesntAffectMonText
+ db "@"
+
+; if there was a critical hit or an OHKO was successful, print the corresponding text
+PrintCriticalOHKOText: ; 3dc5c (f:5c5c)
+ ld a, [wCriticalHitOrOHKO]
+ and a
+ jr z, .done ; do nothing if there was no critical hit or successful OHKO
+ dec a
+ add a
+ ld hl, CriticalOHKOTextPointers
+ ld b, $0
+ ld c, a
+ add hl, bc
+ ld a, [hli]
+ ld h, [hl]
+ ld l, a
+ call PrintText
+ xor a
+ ld [wCriticalHitOrOHKO], a
+.done
+ 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 "@"
+
+; checks if a traded mon will disobey due to lack of badges
+; stores whether the mon will use a move in Z flag
+CheckForDisobedience: ; 3dc88 (f:5c88)
+ xor a
+ ld [wcced], a
+ ld a, [W_ISLINKBATTLE]
+ cp $4
+ jr nz, .checkIfMonIsTraded
+ ld a, $1
+ and a
+ ret
+; compare the mon's original trainer ID with the player's ID to see if it was traded
+.checkIfMonIsTraded
+ ld hl, wPartyMon1OTID
+ ld bc, wPartyMon2 - wPartyMon1
+ ld a, [wPlayerMonNumber]
+ call AddNTimes
+ ld a, [wPlayerID]
+ cp [hl]
+ jr nz, .monIsTraded
+ inc hl
+ ld a, [wPlayerID + 1]
+ cp [hl]
+ jp z, .canUseMove
+; it was traded
+.monIsTraded
+; what level might disobey?
+ ld hl, W_OBTAINEDBADGES
+ bit 7, [hl]
+ ld a, 101
+ jr nz, .next
+ bit 5, [hl]
+ ld a, 70
+ jr nz, .next
+ bit 3, [hl]
+ ld a, 50
+ jr nz, .next
+ bit 1, [hl]
+ ld a, 30
+ jr nz, .next
+ ld a, 10
+.next
+ ld b, a
+ ld c, a
+ ld a, [wBattleMonLevel]
+ ld d, a
+ add b
+ ld b, a
+ jr nc, .noCarry
+ ld b, $ff ; cap b at $ff
+.noCarry
+ ld a, c
+ cp d
+ jp nc, .canUseMove
+.loop1
+ call BattleRandom
+ swap a
+ cp b
+ jr nc, .loop1
+ cp c
+ jp c, .canUseMove
+.loop2
+ call BattleRandom
+ cp b
+ jr nc, .loop2
+ cp c
+ jr c, .useRandomMove
+ ld a, d
+ sub c
+ ld b, a
+ call BattleRandom
+ swap a
+ sub b
+ jr c, .monNaps
+ cp b
+ jr nc, .monDoesNothing
+ ld hl, WontObeyText
+ call PrintText
+ call PrintHurtItselfText
+ jp .cannotUseMove
+.monNaps
+ call BattleRandom
+ add a
+ swap a
+ and SLP ; sleep mask
+ jr z, .monNaps ; keep trying until we get at least 1 turn of sleep
+ ld [wBattleMonStatus], a
+ ld hl, BeganToNapText
+ jr .printText
+.monDoesNothing
+ call BattleRandom
+ and $3
+ ld hl, LoafingAroundText
+ and a
+ jr z, .printText
+ ld hl, WontObeyText
+ dec a
+ jr z, .printText
+ ld hl, TurnedAwayText
+ dec a
+ jr z, .printText
+ ld hl, IgnoredOrdersText
+.printText
+ call PrintText
+ jr .cannotUseMove
+.useRandomMove
+ ld a, [wBattleMonMoves + 1]
+ and a ; is the second move slot empty?
+ jr z, .monDoesNothing ; mon will not use move if it only knows one move
+ ld a, [wccee]
+ and a
+ jr nz, .monDoesNothing
+ ld a, [wPlayerSelectedMove]
+ cp STRUGGLE
+ jr z, .monDoesNothing ; mon will not use move if struggling
+; check if only one move has remaining PP
+ ld hl, wBattleMonPP
+ 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]
+ ld c, a
+ ld b, $0
+ add hl, bc
+ ld a, [hl]
+ and $3f
+ ld b, a
+ pop af
+ cp b
+ jr z, .monDoesNothing ; mon will not use move if only one move has remaining PP
+ ld a, $1
+ ld [wcced], a
+ ld a, [wMaxMenuItem]
+ ld b, a
+ ld a, [wCurrentMenuItem]
+ ld c, a
+.chooseMove
+ call BattleRandom
+ and $3
+ cp b
+ jr nc, .chooseMove ; if the random number is greater than the move count, choose another
+ cp c
+ jr z, .chooseMove ; if the random number matches the move the player selected, choose another
+ ld [wCurrentMenuItem], a
+ ld hl, wBattleMonPP
+ ld e, a
+ ld d, $0
+ add hl, de
+ ld a, [hl]
+ and a ; does the move have any PP left?
+ jr z, .chooseMove ; if the move has no PP left, choose another
+ ld a, [wCurrentMenuItem]
+ ld c, a
+ ld b, $0
+ ld hl, wBattleMonMoves
+ add hl, bc
+ ld a, [hl]
+ ld [wPlayerSelectedMove], a
+ call GetCurrentMove
+.canUseMove
+ ld a, $1
+ and a; clear Z flag
+ ret
+.cannotUseMove
+ xor a ; set Z flag
+ 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 "@"
+
+; sets b, c, d, and e for the CalculateDamage routine in the case of an attack by the player mon
+GetDamageVarsForPlayerAttack: ; 3ddcf (f:5dcf)
+ xor a
+ ld hl, W_DAMAGE ; damage to eventually inflict, initialise to zero
+ ldi [hl], a
+ ld [hl], a
+ ld hl, W_PLAYERMOVEPOWER
+ ld a, [hli]
+ and a
+ ld d, a ; d = move power
+ ret z ; return if move power is zero
+ ld a, [hl] ; a = [W_PLAYERMOVETYPE]
+ cp FIRE ; types >= FIRE are all special
+ jr nc, .specialAttack
+.physicalAttack
+ ld hl, wEnemyMonDefense
+ ld a, [hli]
+ ld b, a
+ ld c, [hl] ; bc = enemy defense
+ ld a, [W_ENEMYBATTSTATUS3]
+ bit 2, a ; check for Reflect
+ jr z, .physicalAttackCritCheck
+; if the enemy has used Reflect, double the enemy's defense
+ sla c
+ rl b
+.physicalAttackCritCheck
+ ld hl, wBattleMonAttack
+ ld a, [wCriticalHitOrOHKO]
+ and a ; check for critical hit
+ jr z, .scaleStats
+; in the case of a critical hit, reset the player's attack and the enemy's defense to their base values
+ ld c, 3 ; defense stat
+ call GetEnemyMonStat
+ ld a, [$ff97]
+ ld b, a
+ ld a, [$ff98]
+ ld c, a
+ push bc
+ ld hl, wPartyMon1Attack
+ ld a, [wPlayerMonNumber]
+ ld bc, wPartyMon2 - wPartyMon1
+ call AddNTimes
+ pop bc
+ jr .scaleStats
+.specialAttack
+ ld hl, wEnemyMonSpecial
+ ld a, [hli]
+ ld b, a
+ ld c, [hl] ; bc = enemy special
+ ld a, [W_ENEMYBATTSTATUS3]
+ bit 1, a ; check for Light Screen
+ jr z, .specialAttackCritCheck
+; if the enemy has used Light Screen, double the enemy's special
+ sla c
+ rl b
+.specialAttackCritCheck
+ ld hl, wBattleMonSpecial
+ ld a, [wCriticalHitOrOHKO]
+ and a ; check for critical hit
+ jr z, .scaleStats
+; in the case of a critical hit, reset the player's and enemy's specials to their base values
+ ld c, 5 ; special stat
+ call GetEnemyMonStat
+ ld a, [$ff97]
+ ld b, a
+ ld a, [$ff98]
+ ld c, a
+ push bc
+ ld hl, wPartyMon1Special
+ ld a, [wPlayerMonNumber]
+ ld bc, wPartyMon2 - wPartyMon1
+ call AddNTimes
+ pop bc
+; if either the offensive or defensive stat is too large to store in a byte, scale both stats by dividing them by 4
+; this allows values with up to 10 bits (values up to 1023) to be handled
+; anything larger will wrap around
+.scaleStats
+ ld a, [hli]
+ ld l, [hl]
+ ld h, a ; hl = player's offensive stat
+ or b ; is either high byte nonzero?
+ jr z, .next ; if not, we don't need to scale
+ ; bc /= 4 (scale enemy's defensive stat)
+ srl b
+ rr c
+ srl b
+ rr c
+ ; hl /= 4 (scale player's offensive stat)
+ srl h
+ rr l
+ srl h
+ rr l
+ ld a, l
+ or h ; is the player's offensive stat 0?
+ jr nz, .next
+ inc l ; if the player's offensive stat is 0, bump it up to 1
+.next
+ ld b, l ; b = player's offensive stat (possibly scaled) (c already contains enemy's defensive stat (possibly scaled))
+ ld a, [wBattleMonLevel]
+ ld e, a ; e = level
+ ld a, [wCriticalHitOrOHKO]
+ and a ; check for critical hit
+ jr z, .done
+ sla e ; double level if it was a critical hit
+.done
+ ld a, 1
+ and a
+ ret
+
+; sets b, c, d, and e for the CalculateDamage routine in the case of an attack by the enemy mon
+GetDamageVarsForEnemyAttack: ; 3de75 (f:5e75)
+ ld hl, W_DAMAGE ; damage to eventually inflict, initialise to zero
+ xor a
+ ld [hli], a
+ ld [hl], a
+ ld hl, W_ENEMYMOVEPOWER
+ ld a, [hli]
+ ld d, a ; d = move power
+ and a
+ ret z ; return if move power is zero
+ ld a, [hl] ; a = [W_ENEMYMOVETYPE]
+ cp FIRE ; types >= FIRE are all special
+ jr nc, .specialAttack
+.physicalAttack
+ ld hl, wBattleMonDefense
+ ld a, [hli]
+ ld b, a
+ ld c, [hl] ; bc = player defense
+ ld a, [W_PLAYERBATTSTATUS3]
+ bit 2, a ; check for Reflect
+ jr z, .physicalAttackCritCheck
+; if the player has used Reflect, double the player's defense
+ sla c
+ rl b
+.physicalAttackCritCheck
+ ld hl, wEnemyMonAttack
+ ld a, [wCriticalHitOrOHKO]
+ and a ; check for critical hit
+ jr z, .scaleStats
+; in the case of a critical hit, reset the player's defense and the enemy's attack to their base values
+ ld hl, wPartyMon1Defense
+ ld a, [wPlayerMonNumber]
+ ld bc, wPartyMon2 - wPartyMon1
+ call AddNTimes
+ ld a, [hli]
+ ld b, a
+ ld c, [hl]
+ push bc
+ ld c, 2 ; attack stat
+ call GetEnemyMonStat
+ ld hl, $ff97
+ pop bc
+ jr .scaleStats
+.specialAttack
+ ld hl, wBattleMonSpecial
+ ld a, [hli]
+ ld b, a
+ ld c, [hl]
+ ld a, [W_PLAYERBATTSTATUS3]
+ bit 1, a ; check for Light Screen
+ jr z, .specialAttackCritCheck
+; if the player has used Light Screen, double the player's special
+ sla c
+ rl b
+.specialAttackCritCheck
+ ld hl, wEnemyMonSpecial
+ ld a, [wCriticalHitOrOHKO]
+ and a ; check for critical hit
+ jr z, .scaleStats
+; in the case of a critical hit, reset the player's and enemy's specials to their base values
+ ld hl, wPartyMon1Special
+ ld a, [wPlayerMonNumber]
+ ld bc, wPartyMon2 - wPartyMon1
+ call AddNTimes
+ ld a, [hli]
+ ld b, a
+ ld c, [hl]
+ push bc
+ ld c, 5 ; special stat
+ call GetEnemyMonStat
+ ld hl, $ff97
+ pop bc
+; if either the offensive or defensive stat is too large to store in a byte, scale both stats by dividing them by 4
+; this allows values with up to 10 bits (values up to 1023) to be handled
+; anything larger will wrap around
+.scaleStats
+ ld a, [hli]
+ ld l, [hl]
+ ld h, a ; hl = enemy's offensive stat
+ or b ; is either high byte nonzero?
+ jr z, .next ; if not, we don't need to scale
+; bc /= 4 (scale player's defensive stat)
+ srl b
+ rr c
+ srl b
+ rr c
+; hl /= 4 (scale enemy's offensive stat)
+ srl h
+ rr l
+ srl h
+ rr l
+ ld a, l
+ or h ; is the enemy's offensive stat 0?
+ jr nz, .next
+ inc l ; if the enemy's offensive stat is 0, bump it up to 1
+.next
+ ld b, l ; b = enemy's offensive stat (possibly scaled) (c already contains player's defensive stat (possibly scaled))
+ ld a, [wEnemyMonLevel]
+ ld e, a
+ ld a, [wCriticalHitOrOHKO]
+ and a ; check for critical hit
+ jr z, .done
+ sla e ; double level if it was a critical hit
+.done
+ ld a, $1
+ and a
+ and a
+ ret
+
+; get stat c of enemy mon
+; c: stat to get (HP=1,Attack=2,Defense=3,Speed=4,Special=5)
+GetEnemyMonStat: ; 3df1c (f:5f1c)
+ push de
+ push bc
+ ld a, [W_ISLINKBATTLE]
+ cp $4
+ jr nz, .asm_3df40
+ ld hl, wEnemyMon1Stats
+ dec c
+ sla c
+ ld b, $0
+ add hl, bc
+ ld a, [wEnemyMonPartyPos]
+ ld bc, wEnemyMon2 - wEnemyMon1
+ call AddNTimes
+ ld a, [hli]
+ ld [$ff97], a
+ ld a, [hl]
+ ld [$ff98], a
+ pop bc
+ pop de
+ ret
+.asm_3df40
+ ld a, [wEnemyMonLevel]
+ ld [W_CURENEMYLVL], a
+ ld a, [wEnemyMonSpecies]
+ ld [wd0b5], a
+ call GetMonHeader
+ ld hl, wEnemyMonDVs
+ ld de, wcfaf
+ ld a, [hli]
+ ld [de], a
+ inc de
+ ld a, [hl]
+ ld [de], a
+ pop bc
+ ld b, $0
+ ld hl, wcfa4
+ call CalcStat
+ pop de
+ ret
+
+CalculateDamage: ; 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, [W_ENEMYMOVEEFFECT]
+.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 JumpMoveEffect
+ ld a, [W_MOVEMISSED]
+ 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 [wCriticalHitOrOHKO], a
+ ld a, [H_WHOSETURN]
+ and a
+ ld a, [wEnemyMonSpecies]
+ jr nz, .asm_3e032
+ ld a, [wBattleMonSpecies]
+.asm_3e032
+ ld [wd0b5], a
+ call GetMonHeader
+ ld a, [W_MONHBASESPEED]
+ ld b, a
+ srl b ; (effective (base speed/2))
+ ld a, [H_WHOSETURN]
+ and a
+ ld hl, W_PLAYERMOVEPOWER
+ ld de, W_PLAYERBATTSTATUS2
+ jr z, .calcCriticalHitProbability
+ ld hl, W_ENEMYMOVEPOWER
+ ld de, W_ENEMYBATTSTATUS2
+.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 BattleRandom ; 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 [wCriticalHitOrOHKO], 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,wEnemyMonHP
+ 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,wBattleMonLevel
+ 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 BattleRandom
+ 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,[wEnemyMonHP + 1]
+ ld [wHPBarOldHP],a
+ sub b
+ ld [wEnemyMonHP + 1],a
+ ld a,[hl]
+ ld b,a
+ ld a,[wEnemyMonHP]
+ ld [wHPBarOldHP+1],a
+ sbc b
+ ld [wEnemyMonHP],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,wEnemyMonHP
+ ld [hli],a
+ ld [hl],a
+.animateHpBar
+ ld hl,wEnemyMonMaxHP
+ ld a,[hli]
+ ld [wHPBarMaxHP+1],a
+ ld a,[hl]
+ ld [wHPBarMaxHP],a
+ ld hl,wEnemyMonHP
+ ld a,[hli]
+ ld [wHPBarNewHP+1],a
+ ld a,[hl]
+ ld [wHPBarNewHP],a
+ hlCoord 2, 2
+ xor a
+ ld [wListMenuID],a
+ predef UpdateHPBar2 ; animate the HP bar shortening
+ApplyAttackToEnemyPokemonDone: ; 3e19d (f:619d)
+ jp DrawHUDsAndHPBars
+
+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,wBattleMonHP
+ 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,wEnemyMonLevel
+ 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 BattleRandom
+ 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,[wBattleMonHP + 1]
+ ld [wHPBarOldHP],a
+ sub b
+ ld [wBattleMonHP + 1],a
+ ld [wHPBarNewHP],a
+ ld b,[hl]
+ ld a,[wBattleMonHP]
+ ld [wHPBarOldHP+1],a
+ sbc b
+ ld [wBattleMonHP],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,wBattleMonHP
+ ld [hli],a
+ ld [hl],a
+ ld hl,wHPBarNewHP
+ ld [hli],a
+ ld [hl],a
+.animateHpBar
+ ld hl,wBattleMonMaxHP
+ ld a,[hli]
+ ld [wHPBarMaxHP+1],a
+ ld a,[hl]
+ ld [wHPBarMaxHP],a
+ hlCoord 10, 9
+ ld a,$01
+ ld [wListMenuID],a
+ predef UpdateHPBar2 ; animate the HP bar shortening
+ApplyAttackToPlayerPokemonDone
+ jp DrawHUDsAndHPBars
+
+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 DrawHUDsAndHPBars
+
+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,[wccf2]
+ ld hl,wPlayerSelectedMove
+ ld de,W_PLAYERMOVENUM
+ jr z,.next
+; values for enemy turn
+ ld a,[wccf1]
+ 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 [wd11e],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 [wcc5b],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 BattleRandom
+ and a
+ jr z,.pickMoveLoop
+ cp a,NUM_ATTACKS + 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,wBattleMonPP
+ ld de,wPartyMon1PP
+ ld a,[wPlayerMoveListIndex]
+ jr z,.next
+; values for enemy turn
+ ld hl,wEnemyMonPP
+ ld de,wEnemyMon1PP
+ 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,[wEnemyMonPartyPos] ; value for enemy turn
+.next2
+ ld bc,wEnemyMon2 - wEnemyMon1
+ 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,wBattleMonType
+ ld a,[hli]
+ ld b,a ; b = type 1 of attacker
+ ld c,[hl] ; c = type 2 of attacker
+ ld hl,wEnemyMonType
+ ld a,[hli]
+ ld d,a ; d = type 1 of defender
+ ld e,[hl] ; e = type 2 of defender
+ ld a,[W_PLAYERMOVETYPE]
+ ld [wd11e],a
+ ld a,[H_WHOSETURN]
+ and a
+ jr z,.next
+; values for enemy turn
+ ld hl,wEnemyMonType
+ ld a,[hli]
+ ld b,a ; b = type 1 of attacker
+ ld c,[hl] ; c = type 2 of attacker
+ ld hl,wBattleMonType
+ ld a,[hli]
+ ld d,a ; d = type 1 of defender
+ ld e,[hl] ; e = type 2 of defender
+ ld a,[W_ENEMYMOVETYPE]
+ ld [wd11e],a
+.next
+ ld a,[wd11e] ; 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,wd05b
+ set 7,[hl]
+.skipSameTypeAttackBonus
+ ld a,[wd11e]
+ 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,[wd05b]
+ and a,$80
+ ld b,a
+ ld a,[hl] ; a = damage multiplier
+ ld [H_MULTIPLIER],a
+ add b
+ ld [wd05b],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 [wd11e]
+; ($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,wBattleMonType
+ 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 [wd11e],a ; initialize [wd11e] 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 [wd11e],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,wEnemyMonStatus
+ ld a,[H_WHOSETURN]
+ and a
+ jr z,.dreamEaterCheck
+; enemy's turn
+ ld hl,W_PLAYERBATTSTATUS1
+ ld de,W_ENEMYMOVEEFFECT
+ ld bc,wBattleMonStatus
+.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
+ jp z,.moveMissed
+ cp a,DREAM_EATER_EFFECT
+ 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 BattleRandom
+ 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
+
+; multiplies damage by a random percentage from ~85% to 100%
+RandomizeDamage: ; 3e687 (f:6687)
+ ld hl, W_DAMAGE
+ ld a, [hli]
+ and a
+ jr nz, .DamageGreaterThanOne
+ ld a, [hl]
+ cp 2
+ ret c
+.DamageGreaterThanOne
+ xor a
+ ld [H_MULTIPLICAND], a
+ dec hl
+ ld a, [hli]
+ ld [H_MULTIPLICAND + 1], a
+ ld a, [hl]
+ ld [H_MULTIPLICAND + 2], a
+; loop until a random number greater than or equal to 217 is generated
+.loop
+ call BattleRandom
+ rrca
+ cp 217
+ jr c, .loop
+ ld [H_MULTIPLIER], a
+ call Multiply ; multiply damage by the random number, which is in the range [217, 255]
+ ld a, 255
+ ld [H_DIVISOR], a
+ ld b, $4
+ call Divide ; divide the result by 255
+; store the modified damage
+ ld a, [H_QUOTIENT + 2]
+ ld hl, W_DAMAGE
+ ld [hli], a
+ ld a, [H_QUOTIENT + 3]
+ ld [hl], a
+ ret
+
+ExecuteEnemyMove: ; 3e6bc (f:66bc)
+ ld a, [wEnemySelectedMove]
+ inc a
+ jp z, Func_3e88c
+ call PrintGhostText
+ jp z, Func_3e88c
+ ld a, [W_ISLINKBATTLE]
+ cp $4
+ jr nz, .asm_3e6dc
+ ld b, $1
+ ld a, [wcc3e]
+ cp $e
+ jr z, .asm_3e6dc
+ cp $4
+ ret nc
+.asm_3e6dc
+ ld hl, wccd5
+ inc [hl]
+ xor a
+ ld [W_MOVEMISSED], a
+ ld [wccf4], a
+ ld a, $a
+ ld [wd05b], a
+ call CheckEnemyStatusConditions
+ jr nz, .canUseMove
+ jp [hl]
+.canUseMove
+ ld hl, W_ENEMYBATTSTATUS1
+ bit 4, [hl] ; is the enemy charging up for attack?
+ jr nz, asm_3e70b ; if so, jump
+ call GetCurrentMove
+
+Func_3e6fc: ; 3e6fc (f:66fc)
+ ld a, [W_ENEMYMOVEEFFECT]
+ cp CHARGE_EFFECT
+ jp z, JumpMoveEffect
+ cp FLY_EFFECT
+ jp z, JumpMoveEffect
+ jr asm_3e72b
+asm_3e70b: ; 3e70b (f:670b)
+ ld hl, W_ENEMYBATTSTATUS1
+ res 4, [hl] ; no longer charging up for attack
+ res 6, [hl] ; no longer invulnerable to typical attacks
+ ld a, [W_ENEMYMOVENUM]
+ ld [wd0b5], a
+ ld a, BANK(MoveNames)
+ ld [wPredefBank], a
+ ld a, MOVE_NAME
+ ld [W_LISTTYPE], a
+ call GetName
+ ld de, wcd6d
+ call CopyStringToCF4B
+asm_3e72b: ; 3e72b (f:672b)
+ xor a
+ ld [wcced], a
+ call PrintMonName1Text
+ ld a, [W_ENEMYMOVEEFFECT]
+ ld hl, EffectsArray1
+ ld de, $1
+ call IsInArray
+ jp c, JumpMoveEffect
+ ld a, [W_ENEMYMOVEEFFECT]
+ ld hl, EffectsArray5B
+ ld de, $1
+ call IsInArray
+ call c, JumpMoveEffect
+asm_3e750: ; 3e750 (f:6750)
+ call SwapPlayerAndEnemyLevels
+ ld a, [W_ENEMYMOVEEFFECT]
+ ld hl, EffectsArray2
+ ld de, $1
+ call IsInArray
+ jp c, Func_3e77f
+ call CriticalHitTest
+ call HandleCounterMove
+ jr z, asm_3e782
+ call SwapPlayerAndEnemyLevels
+ call GetDamageVarsForEnemyAttack
+ call SwapPlayerAndEnemyLevels
+ call CalculateDamage
+ jp z, Func_3e7d1
+ call AdjustDamageForMoveType
+ call RandomizeDamage
+
+Func_3e77f: ; 3e77f (f:677f)
+ call MoveHitTest
+asm_3e782: ; 3e782 (f:6782)
+ ld a, [W_MOVEMISSED]
+ and a
+ jr z, .asm_3e791
+ ld a, [W_ENEMYMOVEEFFECT]
+ cp EXPLODE_EFFECT
+ jr z, asm_3e7a0
+ jr Func_3e7d1
+.asm_3e791
+ call SwapPlayerAndEnemyLevels
+
+Func_3e794: ; 3e794 (f:6794)
+ ld a, [W_ENEMYMOVEEFFECT]
+ and a
+ ld a, $1
+ jr z, asm_3e7a4
+ ld a, $2
+ jr asm_3e7a4
+asm_3e7a0: ; 3e7a0 (f:67a0)
+ call SwapPlayerAndEnemyLevels
+ xor a
+asm_3e7a4: ; 3e7a4 (f:67a4)
+ push af
+ ld a, [W_ENEMYBATTSTATUS2]
+ bit 4, a ; does mon have a substitute?
+ ld hl, Func_79747
+ ld b, BANK(Func_79747)
+ call nz, Bankswitch
+ pop af
+ ld [wcc5b], a
+ ld a, [W_ENEMYMOVENUM]
+ call PlayMoveAnimation
+ call Func_3eed3
+ call DrawEnemyHUDAndHPBar
+ ld a, [W_ENEMYBATTSTATUS2]
+ 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 SwapPlayerAndEnemyLevels
+ ld c, $1e
+ call DelayFrames
+ ld a, [W_ENEMYMOVEEFFECT]
+ cp FLY_EFFECT
+ jr z, .asm_3e7e6
+ cp CHARGE_EFFECT
+ jr z, .asm_3e7e6
+ jr asm_3e7ef
+.asm_3e7e6
+ xor a
+ ld [wcc5b], a
+ ld a,STATUS_AFFECTED_ANIM
+ call PlayMoveAnimation
+asm_3e7ef: ; 3e7ef (f:67ef)
+ ld a, [W_ENEMYMOVEEFFECT]
+ 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]
+ ld hl, EffectsArray3
+ ld de, $1
+ call IsInArray
+ jp c, JumpMoveEffect
+ ld a, [W_MOVEMISSED]
+ and a
+ jr z, .asm_3e82b
+ call PrintMoveFailureText
+ ld a, [W_ENEMYMOVEEFFECT]
+ cp EXPLODE_EFFECT
+ jr z, .asm_3e83e
+ jp Func_3e88c
+.asm_3e82b
+ call ApplyAttackToPlayerPokemon
+ call PrintCriticalOHKOText
+ callab DisplayEffectiveness
+ ld a, 1
+ ld [wccf4], a
+.asm_3e83e
+ ld a, [W_ENEMYMOVEEFFECT]
+ ld hl, EffectsArray4
+ ld de, $1
+ call IsInArray
+ call c, JumpMoveEffect
+ ld hl, wBattleMonHP
+ ld a, [hli]
+ ld b, [hl]
+ or b
+ ret z
+ call HandleBuildingRage
+ ld hl, W_ENEMYBATTSTATUS1
+ bit 2, [hl] ; is mon hitting multiple times? (example: double kick)
+ jr z, .asm_3e873
+ push hl
+ ld hl, wEnemyNumAttacksLeft
+ dec [hl]
+ pop hl
+ jp nz, Func_3e794
+ res 2, [hl] ; mon is no longer hitting multiple times
+ ld hl, HitXTimesText
+ call PrintText
+ xor a
+ ld [wcd05], a
+.asm_3e873
+ ld a, [W_ENEMYMOVEEFFECT]
+ and a
+ jr z, Func_3e88c
+ ld hl, EffectsArray5
+ ld de, $1
+ call IsInArray
+ call nc, JumpMoveEffect
+ jr Func_3e88c
+
+HitXTimesText: ; 3e887 (f:6887)
+ TX_FAR _HitXTimesText
+ db "@"
+
+Func_3e88c: ; 3e88c (f:688c)
+ ld b, $1
+ ret
+
+; checks for various status conditions affecting the enemy mon
+; stores whether the mon cannot use a move this turn in Z flag
+CheckEnemyStatusConditions: ; 3e88f (f:688f)
+ ld hl, wEnemyMonStatus
+ ld a, [hl]
+ and SLP ; sleep mask
+ jr z, .checkIfFrozen
+ dec a ; decrement number of turns left
+ ld [wEnemyMonStatus], a
+ and a
+ jr z, .wokeUp ; if the number of turns hit 0, wake up
+ ld hl, FastAsleepText
+ call PrintText
+ xor a
+ ld [wcc5b], a
+ ld a,SLP_ANIM
+ call PlayMoveAnimation
+ jr .next1
+.wokeUp
+ ld hl, WokeUpText
+ call PrintText
+.next1
+ xor a
+ ld [wccf2], a
+ ld hl, Func_3e88c
+ jp .cannotUseMove
+.checkIfFrozen
+ bit FRZ, [hl]
+ jr z, .checkIfTrapped
+ ld hl, IsFrozenText
+ call PrintText
+ xor a
+ ld [wccf2], a
+ ld hl, Func_3e88c
+ jp .cannotUseMove
+.checkIfTrapped
+ ld a, [W_PLAYERBATTSTATUS1]
+ bit 5, a ; is the player using a multi-turn attack like warp
+ jp z, .checkIfFlinched
+ ld hl, CantMoveText
+ call PrintText
+ ld hl, Func_3e88c
+ jp .cannotUseMove
+.checkIfFlinched
+ ld hl, W_ENEMYBATTSTATUS1
+ bit 3, [hl] ; check if enemy mon flinched
+ jp z, .checkIfMustRecharge
+ res 3, [hl]
+ ld hl, FlinchedText
+ call PrintText
+ ld hl, Func_3e88c
+ jp .cannotUseMove
+.checkIfMustRecharge
+ ld hl, W_ENEMYBATTSTATUS2
+ bit 5, [hl] ; check if enemy mon has to recharge after using a move
+ jr z, .checkIfAnyMoveDisabled
+ res 5, [hl]
+ ld hl, MustRechargeText
+ call PrintText
+ ld hl, Func_3e88c
+ jp .cannotUseMove
+.checkIfAnyMoveDisabled
+ ld hl, W_ENEMYDISABLEDMOVE
+ ld a, [hl]
+ and a
+ jr z, .checkIfConfused
+ dec a
+ ld [hl], a
+ and $f
+ jr nz, .checkIfConfused
+ ld [hl], a
+ ld [wccef], a
+ ld hl, DisabledNoMoreText
+ call PrintText
+.checkIfConfused
+ ld a, [W_ENEMYBATTSTATUS1]
+ add a ; check if enemy mon is confused
+ jp nc, .checkIfTriedToUseDisabledMove
+ ld hl, wd070
+ dec [hl]
+ jr nz, .isConfused
+ ld hl, W_ENEMYBATTSTATUS1
+ res 7, [hl]
+ ld hl, ConfusedNoMoreText
+ call PrintText
+ jp .checkIfTriedToUseDisabledMove
+.isConfused
+ ld hl, IsConfusedText
+ call PrintText
+ xor a
+ ld [wcc5b], a
+ ld a,CONF_ANIM
+ call PlayMoveAnimation
+ call BattleRandom
+ cp $80
+ jr c, .checkIfTriedToUseDisabledMove
+ ld hl, W_ENEMYBATTSTATUS1
+ ld a, [hl]
+ and $80
+ ld [hl], a
+ ld hl, HurtItselfText
+ call PrintText
+ ld hl, wBattleMonDefense
+ ld a, [hli]
+ push af
+ ld a, [hld]
+ push af
+ ld a, [wEnemyMonDefense]
+ ld [hli], a
+ ld a, [wEnemyMonDefense + 1]
+ ld [hl], a
+ ld hl, W_ENEMYMOVEEFFECT
+ push hl
+ ld a, [hl]
+ push af
+ xor a
+ ld [hli], a
+ ld [wCriticalHitOrOHKO], a
+ ld a, $28
+ ld [hli], a
+ xor a
+ ld [hl], a
+ call GetDamageVarsForEnemyAttack
+ call CalculateDamage
+ pop af
+ pop hl
+ ld [hl], a
+ ld hl, wBattleMonDefense + 1
+ pop af
+ ld [hld], a
+ pop af
+ ld [hl], a
+ xor a
+ ld [wcc5b], a
+ ld [H_WHOSETURN], a
+ ld a, POUND
+ call PlayMoveAnimation
+ ld a, $1
+ ld [H_WHOSETURN], a
+ call ApplyDamageToEnemyPokemon
+ jr .monHurtItselfOrFullyParalysed
+.checkIfTriedToUseDisabledMove
+ ld a, [wccef]
+ and a
+ jr z, .checkIfParalysed
+ ld hl, wEnemySelectedMove
+ cp [hl]
+ jr nz, .checkIfParalysed
+ call PrintMoveIsDisabledText
+ ld hl, Func_3e88c
+ jp .cannotUseMove
+.checkIfParalysed
+ ld hl, wEnemyMonStatus
+ bit PAR, [hl]
+ jr z, .checkIfUsingBide
+ call BattleRandom
+ cp $3f
+ jr nc, .checkIfUsingBide
+ ld hl, FullyParalyzedText
+ call PrintText
+.monHurtItselfOrFullyParalysed
+ ld hl, W_ENEMYBATTSTATUS1
+ ld a, [hl]
+ and $cc ; clear bide, thrashing, charging up, and multi-turn moves such as warp
+ ld [hl], a
+ ld a, [W_ENEMYMOVEEFFECT]
+ cp FLY_EFFECT
+ jr z, .flyOrChargeEffect
+ cp CHARGE_EFFECT
+ jr z, .flyOrChargeEffect
+ jr .notFlyOrChargeEffect
+.flyOrChargeEffect
+ xor a
+ ld [wcc5b], a
+ ld a, STATUS_AFFECTED_ANIM
+ call PlayMoveAnimation
+.notFlyOrChargeEffect
+ ld hl, Func_3e88c
+ jp .cannotUseMove
+.checkIfUsingBide
+ ld hl, W_ENEMYBATTSTATUS1
+ bit 0, [hl] ; is mon using bide?
+ jr z, .checkIfThrashingAbout
+ xor a
+ ld [W_ENEMYMOVENUM], a
+ ld hl, W_DAMAGE
+ ld a, [hli]
+ ld b, a
+ ld c, [hl]
+ ld hl, wcd06
+ ld a, [hl]
+ add c
+ ld [hld], a
+ ld a, [hl]
+ adc b
+ ld [hl], a
+ ld hl, wEnemyNumAttacksLeft
+ dec [hl]
+ jr z, .unleashEnergy
+ ld hl, Func_3e88c
+ jp .cannotUseMove
+.unleashEnergy
+ ld hl, W_ENEMYBATTSTATUS1
+ res 0, [hl] ; not using bide any more
+ ld hl, UnleashedEnergyText
+ call PrintText
+ ld a, $1
+ ld [W_ENEMYMOVEPOWER], a
+ ld hl, wcd06
+ ld a, [hld]
+ add a
+ ld b, a
+ ld [wd0d8], a
+ ld a, [hl]
+ rl a
+ ld [W_DAMAGE], a
+ or b
+ jr nz, .next2
+ ld a, $1
+ ld [W_MOVEMISSED], a
+.next2
+ xor a
+ ld [hli], a
+ ld [hl], a
+ ld a, BIDE
+ ld [W_ENEMYMOVENUM], a
+ call SwapPlayerAndEnemyLevels
+ ld hl, asm_3e782
+ jp .cannotUseMove
+.checkIfThrashingAbout
+ bit 1, [hl] ; is mon using thrash or petal dance?
+ jr z, .checkIfUsingMultiturnMove
+ ld a, THRASH
+ ld [W_ENEMYMOVENUM], a
+ ld hl, ThrashingAboutText
+ call PrintText
+ ld hl, wEnemyNumAttacksLeft
+ dec [hl]
+ ld hl, asm_3e750
+ jp nz, .cannotUseMove
+ push hl
+ ld hl, W_ENEMYBATTSTATUS1
+ res 1, [hl] ; mon is no longer using thrash or petal dance
+ set 7, [hl] ; mon is now confused
+ call BattleRandom
+ and $3
+ inc a
+ inc a
+ ld [wd070], a
+ pop hl
+ jp .cannotUseMove
+.checkIfUsingMultiturnMove
+ bit 5, [hl] ; is mon using multi-turn move?
+ jp z, .checkIfUsingRage
+ ld hl, AttackContinuesText
+ call PrintText
+ ld hl, wEnemyNumAttacksLeft
+ dec [hl]
+ ld hl, Func_3e794
+ jp nz, .cannotUseMove
+ jp .cannotUseMove
+.checkIfUsingRage
+ ld a, [W_ENEMYBATTSTATUS2]
+ bit 6, a ; is mon using rage?
+ jp z, .canUseMove
+ ld a, RAGE
+ ld [wd11e], a
+ call GetMoveName
+ call CopyStringToCF4B
+ xor a
+ ld [W_ENEMYMOVEEFFECT], a
+ ld hl, asm_3e72b
+ jp .cannotUseMove
+.cannotUseMove
+ xor a ; set Z flag
+ ret
+.canUseMove
+ ld a, $1
+ and a ; clear Z flag
+ ret
+
+GetCurrentMove: ; 3eabe (f:6abe)
+ ld a, [H_WHOSETURN]
+ and a
+ jp z, .player
+ ld de, W_ENEMYMOVENUM
+ ld a, [wEnemySelectedMove]
+ jr .selected
+.player
+ ld de, W_PLAYERMOVENUM
+ ld a, [W_FLAGS_D733]
+ bit 0, a
+ ld a, [wccd9]
+ jr nz, .selected
+ ld a, [wPlayerSelectedMove]
+.selected
+ ld [wd0b5], a
+ dec a
+ ld hl, Moves
+ ld bc, $6
+ call AddNTimes
+ ld a, BANK(Moves)
+ call FarCopyData
+
+ ld a, BANK(MoveNames)
+ ld [wPredefBank], a
+ ld a, MOVE_NAME
+ ld [W_LISTTYPE], a
+ call GetName
+ ld de, wcd6d
+ jp CopyStringToCF4B
+
+LoadEnemyMonData: ; 3eb01 (f:6b01)
+ ld a, [W_ISLINKBATTLE]
+ cp $4
+ jp z, LoadEnemyMonFromParty
+ ld a, [wEnemyMonSpecies2]
+ ld [wEnemyMonSpecies], a
+ ld [wd0b5], a
+ call GetMonHeader
+ ld a, [W_ENEMYBATTSTATUS3]
+ bit 3, a ; is enemy mon transformed?
+ ld hl, wcceb ; copied DVs from when it used Transform
+ ld a, [hli]
+ ld b, [hl]
+ jr nz, .storeDVs
+ ld a, [W_ISINBATTLE]
+ cp $2 ; is it a trainer battle?
+; fixed DVs for trainer mon
+ ld a, $98
+ ld b, $88
+ jr z, .storeDVs
+; random DVs for wild mon
+ call BattleRandom
+ ld b, a
+ call BattleRandom
+.storeDVs
+ ld hl, wEnemyMonDVs
+ ld [hli], a
+ ld [hl], b
+ ld de, wEnemyMonLevel
+ ld a, [W_CURENEMYLVL]
+ ld [de], a
+ inc de
+ ld b, $0
+ ld hl, wEnemyMonHP
+ push hl
+ call CalcStats
+ pop hl
+ ld a, [W_ISINBATTLE]
+ cp $2 ; is it a trainer battle?
+ jr z, .copyHPAndStatusFromPartyData
+ ld a, [W_ENEMYBATTSTATUS3]
+ bit 3, a ; is enemy mon transformed?
+ jr nz, .copyTypes ; if transformed, jump
+; if it's a wild mon and not transformed, init the current HP to max HP and the status to 0
+ ld a, [wEnemyMonMaxHP]
+ ld [hli], a
+ ld a, [wEnemyMonMaxHP+1]
+ ld [hli], a
+ xor a
+ inc hl
+ ld [hl], a ; init status to 0
+ jr .copyTypes
+; if it's a trainer mon, copy the HP and status from the enemy party data
+.copyHPAndStatusFromPartyData
+ ld hl, wEnemyMon1HP
+ ld a, [wWhichPokemon]
+ ld bc, wEnemyMon2 - wEnemyMon1
+ call AddNTimes
+ ld a, [hli]
+ ld [wEnemyMonHP], a
+ ld a, [hli]
+ ld [wEnemyMonHP + 1], a
+ ld a, [wWhichPokemon]
+ ld [wEnemyMonPartyPos], a
+ inc hl
+ ld a, [hl]
+ ld [wEnemyMonStatus], a
+ jr .copyTypes
+.copyTypes
+ ld hl, W_MONHTYPES
+ ld de, wEnemyMonType
+ 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]
+ cp $2 ; is it a trainer battle?
+ jr nz, .copyStandardMoves
+; if it's a trainer battle, copy moves from enemy party data
+ ld hl, wEnemyMon1Moves
+ ld a, [wWhichPokemon]
+ ld bc, wEnemyMon2 - wEnemyMon1
+ call AddNTimes
+ ld bc, NUM_MOVES
+ call CopyData
+ jr .loadMovePPs
+.copyStandardMoves
+; for a wild mon, first copy default moves from the mon header
+ 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 [wHPBarMaxHP], a
+ predef WriteMonMoves ; get moves based on current level
+.loadMovePPs
+ ld hl, wEnemyMonMoves
+ ld de, wEnemyMonSpecial + 1
+ predef LoadMovePPs
+ ld hl, W_MONHBASESTATS
+ ld de, wEnemyMonBaseStats
+ ld b, $5
+.copyBaseStatsLoop
+ ld a, [hli]
+ ld [de], a
+ inc de
+ dec b
+ jr nz, .copyBaseStatsLoop
+ ld hl, W_MONHCATCHRATE
+ ld a, [hli]
+ ld [de], a
+ inc de
+ ld a, [hl] ; base exp
+ ld [de], a
+ ld a, [wEnemyMonSpecies2]
+ ld [wd11e], a
+ call GetMonName
+ ld hl, wcd6d
+ ld de, wEnemyMonNick
+ ld bc, $b
+ call CopyData
+ ld a, [wEnemyMonSpecies2]
+ ld [wd11e], a
+ predef IndexToPokedex
+ ld a, [wd11e]
+ dec a
+ ld c, a
+ ld b, $1
+ ld hl, wPokedexSeen
+ predef FlagActionPredef ; mark this mon as seen in the pokedex
+ ld hl, wEnemyMonLevel
+ ld de, wEnemyMonUnmodifiedLevel
+ ld bc, $b
+ call CopyData
+ ld a, $7 ; default stat mod
+ ld b, $8 ; number of stat mods
+ ld hl, wEnemyMonStatMods
+.statModLoop
+ ld [hli], a
+ dec b
+ jr nz, .statModLoop
+ ret
+
+; calls BattleTransition to show the battle transition animation and initializes some battle variables
+DoBattleTransitionAndInitBattleVariables: ; 3ec32 (f:6c32)
+ ld a, [W_ISLINKBATTLE]
+ cp $4
+ jr nz, .next
+; link battle
+ xor a
+ ld [wMenuJoypadPollCount], a
+ callab DisplayLinkBattleVersusTextBox
+ ld a, $1
+ ld [wUpdateSpritesEnabled], a
+ call ClearScreen
+.next
+ call DelayFrame
+ predef BattleTransition
+ callab LoadHudAndHpBarAndStatusTilePatterns
+ ld a, $1
+ ld [H_AUTOBGTRANSFERENABLED], a
+ ld a, $ff
+ ld [wUpdateSpritesEnabled], a
+ call ClearSprites
+ call ClearScreen
+ xor a
+ ld [H_AUTOBGTRANSFERENABLED], a
+ ld [hVBlankWY], a
+ ld [rWY], a
+ ld [hTilesetType], a
+ ld hl, wd060
+ ld [hli], a
+ ld [hli], a
+ ld [hli], a
+ ld [hli], a
+ ld [hl], a
+ ld [W_PLAYERDISABLEDMOVE], a
+ ret
+
+; swaps the level values of the BattleMon and EnemyMon structs
+SwapPlayerAndEnemyLevels: ; 3ec81 (f:6c81)
+ push bc
+ ld a, [wBattleMonLevel]
+ ld b, a
+ ld a, [wEnemyMonLevel]
+ ld [wBattleMonLevel], a
+ ld a, b
+ ld [wEnemyMonLevel], a
+ pop bc
+ ret
+
+; loads either red back pic or old man back pic
+; also writes OAM data and loads tile patterns for the Red or Old Man back sprite's head
+; (for use when scrolling the player sprite and enemy's silhouettes on screen)
+LoadPlayerBackPic: ; 3ec92 (f:6c92)
+ ld a, [W_BATTLETYPE]
+ dec a ; is it the old man tutorial?
+ ld de, RedPicBack
+ jr nz, .next
+ ld de, OldManPic
+.next
+ ld a, BANK(RedPicBack)
+ call UncompressSpriteFromDE
+ predef ScaleSpriteByTwo
+ ld hl, wOAMBuffer
+ xor a
+ ld [$FF8B], a ; initial tile number
+ ld b, $7 ; 7 columns
+ ld e, $a0 ; X for the left-most column
+.loop ; each loop iteration writes 3 OAM entries in a vertical column
+ ld c, $3 ; 3 tiles per column
+ ld d, $38 ; Y for the top of each column
+.innerLoop ; each loop iteration writes 1 OAM entry in the column
+ ld [hl], d ; OAM Y
+ inc hl
+ ld [hl], e ; OAM X
+ ld a, $8 ; height of tile
+ add d ; increase Y by height of tile
+ ld d, a
+ inc hl
+ ld a, [$FF8B]
+ ld [hli], a ; OAM tile number
+ inc a ; increment tile number
+ ld [$FF8B], a
+ inc hl
+ dec c
+ jr nz, .innerLoop
+ ld a, [$FF8B]
+ add $4 ; increase tile number by 4
+ ld [$FF8B], a
+ ld a, $8 ; width of tile
+ add e ; increase X by width of tile
+ ld e, a
+ dec b
+ jr nz, .loop
+ ld de, vBackPic
+ call InterlaceMergeSpriteBuffers
+ ld a, $a
+ ld [$0], a
+ xor a
+ ld [$4000], a
+ ld hl, vSprites
+ ld de, S_SPRITEBUFFER1
+ ld a, [H_LOADEDROMBANK]
+ ld b, a
+ ld c, 7 * 7
+ call CopyVideoData
+ xor a
+ ld [$0], a
+ ld a, $31
+ ld [$ffe1], a
+ hlCoord 1, 5
+ predef_jump Func_3f0c6
+
+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
+
+ApplyBurnAndParalysisPenaltiesToPlayer: ; 3ed1a (f:6d1a)
+ ld a, $1
+ jr ApplyBurnAndParalysisPenalties
+
+ApplyBurnAndParalysisPenaltiesToEnemy: ; 3ed1e (f:6d1e)
+ xor a
+
+ApplyBurnAndParalysisPenalties: ; 3ed1f (f:6d1f)
+ ld [H_WHOSETURN], a
+ call QuarterSpeedDueToParalysis
+ jp HalveAttackDueToBurn
+
+QuarterSpeedDueToParalysis: ; 3ed27 (f:6d27)
+ ld a, [H_WHOSETURN]
+ and a
+ jr z, .playerTurn
+.enemyTurn ; quarter the player's speed
+ ld a, [wBattleMonStatus]
+ and 1 << PAR
+ ret z ; return if player not paralysed
+ ld hl, wBattleMonSpeed + 1
+ ld a, [hld]
+ ld b, a
+ ld a, [hl]
+ srl a
+ rr b
+ srl a
+ rr b
+ ld [hli], a
+ or b
+ jr nz, .storePlayerSpeed
+ ld b, 1 ; give the player a minimum of at least one speed point
+.storePlayerSpeed
+ ld [hl], b
+ ret
+.playerTurn ; quarter the enemy's speed
+ ld a, [wEnemyMonStatus]
+ and 1 << PAR
+ ret z ; return if enemy not paralysed
+ ld hl, wEnemyMonSpeed + 1
+ ld a, [hld]
+ ld b, a
+ ld a, [hl]
+ srl a
+ rr b
+ srl a
+ rr b
+ ld [hli], a
+ or b
+ jr nz, .storeEnemySpeed
+ ld b, 1 ; give the enemy a minimum of at least one speed point
+.storeEnemySpeed
+ ld [hl], b
+ ret
+
+HalveAttackDueToBurn: ; 3ed64 (f:6d64)
+ ld a, [H_WHOSETURN]
+ and a
+ jr z, .playerTurn
+.enemyTurn ; halve the player's attack
+ ld a, [wBattleMonStatus]
+ and 1 << BRN
+ ret z ; return if player not burnt
+ ld hl, wBattleMonAttack + 1
+ ld a, [hld]
+ ld b, a
+ ld a, [hl]
+ srl a
+ rr b
+ ld [hli], a
+ or b
+ jr nz, .storePlayerAttack
+ ld b, 1 ; give the player a minimum of at least one attack point
+.storePlayerAttack
+ ld [hl], b
+ ret
+.playerTurn ; halve the enemy's attack
+ ld a, [wEnemyMonStatus]
+ and 1 << BRN
+ ret z ; return if enemy not burnt
+ ld hl, wEnemyMonAttack + 1
+ ld a, [hld]
+ ld b, a
+ ld a, [hl]
+ srl a
+ rr b
+ ld [hli], a
+ or b
+ jr nz, .storeEnemyAttack
+ ld b, 1 ; give the enemy a minimum of at least one attack point
+.storeEnemyAttack
+ ld [hl], b
+ ret
+
+CalculateModifiedStats: ; 3ed99 (f:6d99)
+ ld c, 0
+.loop
+ call CalculateModifiedStat
+ inc c
+ ld a, c
+ cp 4
+ jr nz, .loop
+ ret
+
+; calculate modified stat for stat c (0 = attack, 1 = defense, 2 = speed, 3 = special)
+CalculateModifiedStat: ; 3eda5 (f:6da5)
+ push bc
+ push bc
+ ld a, [wd11e]
+ and a
+ ld a, c
+ ld hl, wBattleMonAttack
+ ld de, wPlayerMonUnmodifiedAttack
+ ld bc, wPlayerMonAttackMod
+ jr z, .next
+ ld hl, wEnemyMonAttack
+ ld de, wEnemyMonUnmodifiedAttack
+ ld bc, wEnemyMonStatMods
+.next
+ add c
+ ld c, a
+ jr nc, .noCarry1
+ inc b
+.noCarry1
+ 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, .noCarry2
+ inc d
+.noCarry2
+ pop bc
+ push hl
+ ld hl, StatModifierRatios
+ dec b
+ sla b
+ ld c, b
+ ld b, 0
+ add hl, bc
+ xor a
+ ld [H_MULTIPLICAND], a
+ ld a, [de]
+ ld [H_MULTIPLICAND + 1], a
+ inc de
+ ld a, [de]
+ ld [H_MULTIPLICAND + 2], a
+ ld a, [hli]
+ ld [H_MULTIPLIER], a
+ call Multiply
+ ld a, [hl]
+ ld [H_DIVISOR], a
+ ld b, $4
+ call Divide
+ pop hl
+ ld a, [H_DIVIDEND + 3]
+ sub 999 % $100
+ ld a, [H_DIVIDEND + 2]
+ sbc 999 / $100
+ jp c, .storeNewStatValue
+; cap the stat at 999
+ ld a, 999 / $100
+ ld [H_DIVIDEND + 2], a
+ ld a, 999 % $100
+ ld [H_DIVIDEND + 3], a
+.storeNewStatValue
+ ld a, [H_DIVIDEND + 2]
+ ld [hli], a
+ ld b, a
+ ld a, [H_DIVIDEND + 3]
+ ld [hl], a
+ or b
+ jr nz, .done
+ inc [hl] ; if the stat is 0, bump it up to 1
+.done
+ pop bc
+ ret
+
+ApplyBadgeStatBoosts: ; 3ee19 (f:6e19)
+ ld a, [W_ISLINKBATTLE]
+ cp $4
+ ret z ; return if link battle
+ ld a, [W_OBTAINEDBADGES]
+ ld b, a
+ ld hl, wBattleMonAttack
+ ld c, $4
+; the boost is applied for badges whose bit position is even
+; the order of boosts matches the order they are laid out in RAM
+; Boulder (bit 0) - attack
+; Thunder (bit 2) - defense
+; Soul (bit 4) - speed
+; Volcano (bit 6) - special
+.loop
+ srl b
+ call c, .applyBoostToStat
+ inc hl
+ inc hl
+ srl b
+ dec c
+ jr nz, .loop
+ ret
+
+; multiply stat at hl by 1.125
+; cap stat at 999
+.applyBoostToStat
+ 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 999 % $100
+ ld a, [hl]
+ sbc 999 / $100
+ ret c
+ ld a, 999 / $100
+ ld [hli], a
+ ld a, 999 % $100
+ ld [hld], a
+ ret
+
+LoadHudAndHpBarAndStatusTilePatterns: ; 3ee58 (f:6e58)
+ call LoadHpBarAndStatusTilePatterns
+
+LoadHudTilePatterns: ; 3ee5b (f:6e5b)
+ ld a, [rLCDC]
+ add a ; is LCD disabled?
+ jr c, .lcdEnabled
+.lcdDisabled
+ ld hl, BattleHudTiles1
+ ld de, vChars2 + $6d0
+ ld bc, $18
+ ld a, BANK(BattleHudTiles1)
+ call FarCopyDataDouble
+ ld hl, BattleHudTiles2
+ ld de, vChars2 + $730
+ ld bc, $30
+ ld a, BANK(BattleHudTiles2)
+ jp FarCopyDataDouble
+.lcdEnabled
+ ld de, BattleHudTiles1
+ ld hl, vChars2 + $6d0
+ ld bc, (BANK(BattleHudTiles1) << 8) + $03
+ call CopyVideoDataDouble
+ ld de, BattleHudTiles2
+ ld hl, vChars2 + $730
+ ld bc, (BANK(BattleHudTiles2) << 8) + $06
+ jp CopyVideoDataDouble
+
+PrintEmptyString: ; 3ee94 (f:6e94)
+ ld hl, .emptyString
+ jp PrintText
+.emptyString
+ db "@"
+
+
+BattleRandom:
+; Link battles use a shared PRNG.
+
+ ld a, [W_ISLINKBATTLE]
+ cp $4
+ jp nz, Random
+
+ push hl
+ push bc
+ ld a, [wccde]
+ ld c, a
+ ld b, 0
+ ld hl, wd148
+ add hl, bc
+ inc a
+ ld [wccde], a
+ cp 9
+ ld a, [hl]
+ pop bc
+ pop hl
+ ret c
+
+ push hl
+ push bc
+ push af
+
+ xor a
+ ld [wccde], a
+
+ ld hl, wd148
+ ld b, 9
+.loop
+ ld a, [hl]
+ ld c, a
+ add a
+ add a
+ add c
+ inc a
+ ld [hli], a
+ dec b
+ jr nz, .loop
+
+ pop af
+ pop bc
+ pop hl
+ ret
+
+
+Func_3eed3: ; 3eed3 (f:6ed3)
+ ld a, [H_WHOSETURN]
+ and a
+ ld hl, wEnemyMonType1 ; wcfea (aliases: wEnemyMonType)
+ ld de, W_ENEMYBATTSTATUS1
+ ld a, [W_PLAYERMOVENUM]
+ jr z, .asm_3eeea
+ ld hl, wBattleMonType1 ; wd019 (aliases: wBattleMonType)
+ ld de, W_ENEMYBATTSTATUS1
+ ld a, [W_ENEMYMOVENUM]
+.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]
+ and a
+ ret nz
+ ld a, MEGA_PUNCH
+ ld [wcc5b], a
+
+PlayMoveAnimation: ; 3ef07 (f:6f07)
+ ld [W_ANIMATIONID],a
+ call Delay3
+ predef_jump MoveAnimation
+
+InitBattle: ; 3ef12 (f:6f12)
+ ld a, [W_CUROPPONENT]
+ and a
+ jr z, asm_3ef23
+
+InitOpponent: ; 3ef18 (f:6f18)
+ ld a, [W_CUROPPONENT]
+ ld [wcf91], a
+ ld [wEnemyMonSpecies2], a
+ jr asm_3ef3d
+asm_3ef23: ; 3ef23 (f:6f23)
+ ld a, [wd732]
+ bit 1, a
+ jr z, .asm_3ef2f
+ ld a, [hJoyHeld]
+ bit 1, a ; B button pressed?
+ ret nz
+.asm_3ef2f
+ ld a, [wNumberOfNoRandomBattleStepsLeft]
+ and a
+ ret nz
+ callab Func_13870
+ ret nz
+asm_3ef3d: ; 3ef3d (f:6f3d)
+ ld a, [wMapPalOffset]
+ push af
+ ld hl, wd358
+ ld a, [hl]
+ push af
+ res 1, [hl]
+ callab Func_525af
+ ld a, [wEnemyMonSpecies2]
+ sub $c8
+ jp c, InitWildBattle
+ ld [W_TRAINERCLASS], a
+ call GetTrainerInformation
+ callab ReadTrainer
+ call DoBattleTransitionAndInitBattleVariables
+ call _LoadTrainerPic
+ xor a
+ ld [wEnemyMonSpecies2], a
+ ld [$ffe1], a
+ dec a
+ ld [wAICount], a
+ hlCoord 12, 0
+ predef Func_3f0c6
+ ld a, $ff
+ ld [wEnemyMonPartyPos], a
+ ld a, $2
+ ld [W_ISINBATTLE], a
+ jp InitBattle_Common
+
+InitWildBattle: ; 3ef8b (f:6f8b)
+ ld a, $1
+ ld [W_ISINBATTLE], a
+ call LoadEnemyMonData
+ call DoBattleTransitionAndInitBattleVariables
+ ld a, [W_CUROPPONENT]
+ 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
+ ld a, c
+ ld [hli], a ; write front sprite pointer
+ ld [hl], b
+ ld hl, wEnemyMonNick ; 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, [wcf91]
+ push af
+ ld a, MON_GHOST
+ ld [wcf91], a
+ ld de, vFrontPic
+ call LoadMonFrontSprite ; load ghost sprite
+ pop af
+ ld [wcf91], a
+ jr .spriteLoaded
+.isNoGhost
+ ld de, vFrontPic
+ call LoadMonFrontSprite ; load mon sprite
+.spriteLoaded
+ xor a
+ ld [W_TRAINERCLASS], a
+ ld [$ffe1], a
+ hlCoord 12, 0
+ predef Func_3f0c6
+
+; common code that executes after init battle code specific to trainer or wild battles
+InitBattle_Common: ; 3efeb (f:6feb)
+ ld b, $0
+ call GoPAL_SET
+ call SlidePlayerAndEnemySilhouettesOnScreen
+ xor a
+ ld [H_AUTOBGTRANSFERENABLED], a
+ ld hl, .emptyString
+ call PrintText
+ call SaveScreenTilesToBuffer1
+ call ClearScreen
+ ld a, $98
+ ld [$ffbd], a
+ ld a, $1
+ ld [H_AUTOBGTRANSFERENABLED], a
+ call Delay3
+ ld a, $9c
+ ld [$ffbd], a
+ call LoadScreenTilesFromBuffer1
+ hlCoord 9, 7
+ ld bc, $50a
+ call ClearScreenArea
+ hlCoord 1, 0
+ ld bc, $40a
+ call ClearScreenArea
+ call ClearSprites
+ ld a, [W_ISINBATTLE]
+ dec a ; is it a wild battle?
+ call z, DrawEnemyHUDAndHPBar ; draw enemy HUD and HP bar if it's a wild battle
+ call StartBattle
+ callab EndOfBattle
+ pop af
+ ld [wd358], a
+ pop af
+ ld [wMapPalOffset], a
+ ld a, [wd0d4]
+ ld [hTilesetType], a
+ scf
+ ret
+.emptyString
+ db "@"
+
+_LoadTrainerPic: ; 3f04b (f:704b)
+; wd033-wd034 contain pointer to pic
+ ld a, [wd033]
+ ld e, a
+ ld a, [wd034]
+ ld d, a ; de contains pointer to trainer pic
+ ld a, [W_ISLINKBATTLE]
+ 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, vFrontPic
+ ld a, $77
+ ld c, a
+ jp LoadUncompressedSpriteData
+
+Func_3f069: ; 3f069 (f:7069)
+ xor a
+ ld [wc0f1], a
+ ld [wc0f2], a
+ jp PlaySound
+
+Func_3f073: ; 3f073 (f:7073)
+ ld a, [wPredefRegisters]
+ ld h, a
+ ld a, [wPredefRegisters + 1]
+ ld l, a
+ ld a, [$ffe1]
+ ld [H_DOWNARROWBLINKCNT1], a
+ ld b, $4c
+ ld a, [W_ISINBATTLE]
+ and a
+ jr z, .asm_3f0bc
+ add b
+ ld [hl], a
+ call Delay3
+ ld bc, -41
+ add hl, bc
+ ld a, $1
+ ld [wcd6c], a
+ ld bc, $303
+ predef Func_79aba
+ ld c, $4
+ call DelayFrames
+ ld bc, -41
+ add hl, bc
+ xor a
+ ld [wcd6c], a
+ ld bc, $505
+ predef Func_79aba
+ ld c, $5
+ call DelayFrames
+ ld bc, -41
+ jr .asm_3f0bf
+.asm_3f0bc
+ ld bc, -123
+.asm_3f0bf
+ add hl, bc
+ ld a, [H_DOWNARROWBLINKCNT1]
+ add $31
+ jr asm_3f0d0
+
+Func_3f0c6: ; 3f0c6 (f:70c6)
+ ld a, [wPredefRegisters]
+ ld h, a
+ ld a, [wPredefRegisters + 1]
+ 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
+
+LoadMonBackPic:
+; Assumes the monster's attributes have
+; been loaded with GetMonHeader.
+ ld a, [wBattleMonSpecies2]
+ ld [wcf91], a
+ hlCoord 1, 5
+ ld b, $7
+ ld c, $8
+ call ClearScreenArea
+ ld hl, W_MONHBACKSPRITE - W_MONHEADER
+ call UncompressMonSprite
+ predef ScaleSpriteByTwo
+ ld de, vBackPic
+ call InterlaceMergeSpriteBuffers ; combine the two buffers to a single 2bpp sprite
+ ld hl, vSprites
+ ld de, vBackPic
+ ld c, (2*SPRITEBUFFERSIZE)/16 ; count of 16-byte chunks to be copied
+ ld a, [H_LOADEDROMBANK]
+ ld b, a
+ jp CopyVideoData
+
+JumpMoveEffect: ; 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, wEnemyMonStatus
+ ld bc, W_ENEMYBATTSTATUS2
+ ld a, [H_WHOSETURN]
+ and a
+ jp z, .asm_3f20e
+ ld de, wBattleMonStatus
+ ld bc, W_PLAYERBATTSTATUS2
+
+.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]
+ and a
+ jr nz, .asm_3f242
+.asm_3f231
+ call BattleRandom
+ 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, wEnemyMonStatus
+ ld de, W_PLAYERMOVEEFFECT
+ ld a, [H_WHOSETURN]
+ and a
+ jr z, .asm_3f260
+ ld hl, wBattleMonStatus
+ ld de, W_ENEMYMOVEEFFECT
+.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]
+ and a
+ jr nz, .asm_3f2d7
+ jr .asm_3f295
+.asm_3f290
+ call BattleRandom
+ cp b
+ ret nc
+.asm_3f295
+ dec hl
+ set 3, [hl]
+ push de
+ dec de
+ ld a, [H_WHOSETURN]
+ and a
+<<<<<<< HEAD
+ ld b, ANIM_C7
+ ld hl, W_PLAYERBATTSTATUS3 ; W_PLAYERBATTSTATUS3
+=======
+ ld b, $c7
+ ld hl, W_PLAYERBATTSTATUS3
+>>>>>>> yama/master
+ ld a, [de]
+ ld de, W_PLAYERTOXICCOUNTER
+ jr nz, .asm_3f2b0
+<<<<<<< HEAD
+ ld b, ANIM_A9
+ ld hl, W_ENEMYBATTSTATUS3 ; W_ENEMYBATTSTATUS3
+ ld de, W_ENEMYTOXICCOUNTER ; wd071
+=======
+ ld b, $a9
+ ld hl, W_ENEMYBATTSTATUS3
+ ld de, W_ENEMYTOXICCOUNTER
+>>>>>>> yama/master
+.asm_3f2b0
+ cp TOXIC
+ 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, wBattleMonHP
+ ld de, W_PLAYERBATTSTATUS2
+ ld a, [H_WHOSETURN]
+ and a
+ jr z, .asm_3f302
+ ld hl, wEnemyMonHP
+ ld de, W_ENEMYBATTSTATUS2
+.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 [wcc5b], 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, [wEnemyMonStatus]
+ and a
+ jp nz, CheckDefrost
+ ;opponent has no existing status
+ ld a, [W_PLAYERMOVETYPE]
+ ld b, a
+ ld a, [wEnemyMonType1]
+ cp b
+ ret z ;return if they match [can't freeze an ice type etc.]
+ ld a, [wEnemyMonType2]
+ 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 BattleRandom ;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 [wEnemyMonStatus], a
+<<<<<<< HEAD
+ call Func_3ed27 ;quarter speed of affected monster
+ ld a, ANIM_A9
+=======
+ call QuarterSpeedDueToParalysis ;quarter speed of affected monster
+ ld a, $a9
+>>>>>>> yama/master
+ call Func_3fbb9 ;animation
+ jp PrintMayNotAttackText ;print paralysis text
+.burn
+ ld a, 1 << BRN
+ ld [wEnemyMonStatus], a
+<<<<<<< HEAD
+ call Func_3ed64
+ ld a, ANIM_A9
+=======
+ call HalveAttackDueToBurn
+ ld a, $a9
+>>>>>>> yama/master
+ 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 [wEnemyMonStatus], a
+ ld a, ANIM_A9
+ call Func_3fbb9 ;animation
+ ld hl, FrozenText
+ jp PrintText
+opponentAttacker: ; 3f382 (f:7382)
+ ld a, [wBattleMonStatus] ;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, [wBattleMonType1]
+ cp b
+ ret z
+ ld a, [wBattleMonType2]
+ 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 BattleRandom
+ 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 [wBattleMonStatus], a
+ call QuarterSpeedDueToParalysis
+ jp PrintMayNotAttackText
+.burn
+ ld a, 1 << BRN
+ ld [wBattleMonStatus], a
+ call HalveAttackDueToBurn
+ ld hl, BurnedText
+ jp PrintText
+.freeze
+ ld a, 1 << FRZ
+ ld [wBattleMonStatus], 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 [wEnemyMonStatus], a ;set opponent status to 00 ["defrost" a frozen monster]
+ ld hl, wEnemyMon1Status
+ ld a, [wEnemyMonPartyPos]
+ ld bc, wEnemyMon2 - wEnemyMon1
+ 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 [wBattleMonStatus], a
+ ld hl, wPartyMon1Status
+ ld a, [wPlayerMonNumber]
+ ld bc, wPartyMon2 - wPartyMon1
+ 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
+ ld de, W_PLAYERMOVEEFFECT
+ ld a, [H_WHOSETURN]
+ and a
+ jr z, .asm_3f439
+ ld hl, wEnemyMonStatMods
+ ld de, W_ENEMYMOVEEFFECT
+.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, wBattleMonAttack + 1
+ ld de, wcd12
+ ld a, [H_WHOSETURN]
+ and a
+ jr z, .asm_3f472
+ ld hl, wEnemyMonAttack + 1
+ ld de, wEnemyMonUnmodifiedAttack
+.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
+ 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
+ ld de, W_PLAYERMOVENUM
+ ld bc, wccf7
+ ld a, [H_WHOSETURN]
+ and a
+ jr z, .asm_3f4e6
+ ld hl, W_ENEMYBATTSTATUS2
+ ld de, W_ENEMYMOVENUM
+ ld bc, wccf3
+.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]
+ and a
+ call z, ApplyBadgeStatBoosts
+ ld hl, MonsStatsRoseText
+ call PrintText
+ call QuarterSpeedDueToParalysis
+ jp HalveAttackDueToBurn
+
+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]
+ and a
+ ld a, [W_PLAYERMOVEEFFECT]
+ jr z, .asm_3f53b
+ ld a, [W_ENEMYMOVEEFFECT]
+.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
+ ld de, W_PLAYERMOVEEFFECT
+ ld bc, W_ENEMYBATTSTATUS1
+ ld a, [H_WHOSETURN]
+ and a
+ jr z, .asm_3f572
+ ld hl, wPlayerMonStatMods
+ ld de, W_ENEMYMOVEEFFECT
+ ld bc, W_PLAYERBATTSTATUS1
+ ld a, [W_ISLINKBATTLE]
+ cp $4
+ jr z, .asm_3f572
+ call BattleRandom
+ 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 BattleRandom
+ 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]
+ 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, wEnemyMonAttack + 1
+ ld de, wEnemyMonUnmodifiedAttack
+ ld a, [H_WHOSETURN]
+ and a
+ jr z, .asm_3f5d8
+ ld hl, wBattleMonAttack + 1
+ ld de, wcd12
+.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
+ 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]
+ and a
+ call nz, ApplyBadgeStatBoosts
+ ld hl, MonsStatsFellText
+ call PrintText
+ call QuarterSpeedDueToParalysis
+ jp HalveAttackDueToBurn
+
+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]
+ and a
+ ld a, [W_PLAYERMOVEEFFECT]
+ jr z, .asm_3f674
+ ld a, [W_ENEMYMOVEEFFECT]
+.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, wcf4b
+ 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, wPlayerNumAttacksLeft
+ ld a, [H_WHOSETURN]
+ and a
+ jr z, .asm_3f6fc
+ ld hl, W_ENEMYBATTSTATUS1
+ ld de, wcd05
+ ld bc, wEnemyNumAttacksLeft
+.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 BattleRandom
+ and $1
+ inc a
+ inc a
+ ld [bc], a
+ ld a, [H_WHOSETURN]
+ add XSTATITEM_ANIM
+ jp Func_3fb96
+
+ThrashPetalDanceEffect: ; 3f717 (f:7717)
+ ld hl, W_PLAYERBATTSTATUS1
+ ld de, wPlayerNumAttacksLeft
+ ld a, [H_WHOSETURN]
+ and a
+ jr z, .asm_3f728
+ ld hl, W_ENEMYBATTSTATUS1
+ ld de, wEnemyNumAttacksLeft
+.asm_3f728
+ set 1, [hl] ; mon is now using thrash/petal dance
+ call BattleRandom
+ and $1
+ inc a
+ inc a
+ ld [de], a
+<<<<<<< HEAD
+ ld a, [H_WHOSETURN] ; $fff3
+ add ANIM_B0
+=======
+ ld a, [H_WHOSETURN]
+ add $b0
+>>>>>>> yama/master
+ jp Func_3fb96
+
+SwitchAndTeleportEffect: ; 3f739 (f:7739)
+ ld a, [H_WHOSETURN]
+ and a
+ jr nz, .asm_3f791
+ ld a, [W_ISINBATTLE]
+ dec a
+ jr nz, .asm_3f77e
+ ld a, [W_CURENEMYLVL]
+ ld b, a
+ ld a, [wBattleMonLevel]
+ cp b
+ jr nc, .asm_3f76e
+ add b
+ ld c, a
+ inc c
+.asm_3f751
+ call BattleRandom
+ 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]
+ cp TELEPORT
+ jp nz, PrintDidntAffectText
+ jp PrintButItFailedText_
+.asm_3f76e
+ call ReadPlayerMonCurHPAndStatus
+ xor a
+ ld [wcc5b], a
+ inc a
+ ld [wEscapedFromBattle], a
+ ld a, [W_PLAYERMOVENUM]
+ jr .asm_3f7e4
+.asm_3f77e
+ ld c, $32
+ call DelayFrames
+ ld hl, IsUnaffectedText
+ ld a, [W_PLAYERMOVENUM]
+ cp TELEPORT
+ jp nz, PrintText
+ jp PrintButItFailedText_
+.asm_3f791
+ ld a, [W_ISINBATTLE]
+ dec a
+ jr nz, .asm_3f7d1
+ ld a, [wBattleMonLevel]
+ ld b, a
+ ld a, [W_CURENEMYLVL]
+ cp b
+ jr nc, .asm_3f7c1
+ add b
+ ld c, a
+ inc c
+.asm_3f7a4
+ call BattleRandom
+ 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]
+ cp TELEPORT
+ jp nz, PrintDidntAffectText
+ jp PrintButItFailedText_
+.asm_3f7c1
+ call ReadPlayerMonCurHPAndStatus
+ xor a
+ ld [wcc5b], a
+ inc a
+ ld [wEscapedFromBattle], a
+ ld a, [W_ENEMYMOVENUM]
+ jr .asm_3f7e4
+.asm_3f7d1
+ ld c, $32
+ call DelayFrames
+ ld hl, IsUnaffectedText
+ ld a, [W_ENEMYMOVENUM]
+ 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
+ cp TELEPORT
+ jr z, .asm_3f7ff
+ ld hl, RanAwayScaredText
+ cp ROAR
+ jr z, .asm_3f7ff
+ ld hl, WasBlownAwayText
+.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
+ ld de, wPlayerNumAttacksLeft
+ ld bc, W_NUMHITS
+ ld a, [H_WHOSETURN]
+ and a
+ jr z, .asm_3f828
+ ld hl, W_ENEMYBATTSTATUS1
+ ld de, wEnemyNumAttacksLeft
+ ld bc, wcd05
+.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
+ ld a, [H_WHOSETURN]
+ and a
+ jr z, .asm_3f838
+ ld hl, W_ENEMYMOVEEFFECT
+.asm_3f838
+ ld a, [hl]
+ cp TWINEEDLE_EFFECT
+ jr z, .asm_3f856
+ cp ATTACK_TWICE_EFFECT
+ ld a, $2
+ jr z, .asm_3f853
+ call BattleRandom
+ and $3
+ cp $2
+ jr c, .asm_3f851
+ call BattleRandom
+ 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
+ ld de, W_PLAYERMOVEEFFECT
+ ld a, [H_WHOSETURN]
+ and a
+ jr z, .asm_3f870
+ ld hl, W_PLAYERBATTSTATUS1
+ ld de, W_ENEMYMOVEEFFECT
+.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 BattleRandom
+ 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
+ ld de, W_PLAYERMOVEEFFECT
+ ld a, [H_WHOSETURN]
+ and a
+ ld b, XSTATITEM_ANIM
+ jr z, .asm_3f8a1
+<<<<<<< HEAD
+ ld hl, W_ENEMYBATTSTATUS1 ; W_ENEMYBATTSTATUS1
+ ld de, W_ENEMYMOVEEFFECT ; W_ENEMYMOVEEFFECT
+ ld b, ANIM_AF
+=======
+ ld hl, W_ENEMYBATTSTATUS1
+ ld de, W_ENEMYMOVEEFFECT
+ ld b, $af
+>>>>>>> yama/master
+.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, TELEPORT
+.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, ANIM_C0
+.asm_3f8b6
+ xor a
+ ld [wcc5b], a
+ ld a, b
+ call Func_3fbb9
+ ld a, [de]
+ ld [wWhichTrade], a
+ ld hl, ChargeMoveEffectText
+ jp PrintText
+
+ChargeMoveEffectText: ; 3f8c8 (f:78c8)
+ TX_FAR _ChargeMoveEffectText
+ db $08 ; asm
+ ld a, [wWhichTrade]
+ cp RAZOR_WIND
+ ld hl, MadeWhirlwindText
+ jr z, .asm_3f8f8
+ cp SOLARBEAM
+ ld hl, TookInSunlightText
+ jr z, .asm_3f8f8
+ cp SKULL_BASH
+ ld hl, LoweredItsHeadText
+ jr z, .asm_3f8f8
+ cp SKY_ATTACK
+ ld hl, SkyAttackGlowingText
+ jr z, .asm_3f8f8
+ cp FLY
+ ld hl, FlewUpHighText
+ jr z, .asm_3f8f8
+ cp DIG
+ ld hl, DugAHoleText
+.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
+ ld de, wPlayerNumAttacksLeft
+ ld a, [H_WHOSETURN]
+ and a
+ jr z, .asm_3f928
+ ld hl, W_ENEMYBATTSTATUS1
+ ld de, wEnemyNumAttacksLeft
+.asm_3f928
+ bit 5, [hl]
+ ret nz
+ call Func_3f9cf
+ set 5, [hl]
+ call BattleRandom
+ and $3
+ cp $2
+ jr c, .asm_3f93e
+ call BattleRandom
+ 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 BattleRandom
+ cp $19
+ ret nc
+ jr Func_3f96f
+
+ConfusionEffect: ; 3f961 (f:7961)
+ call CheckTargetSubstitute
+ jr nz, Func_3f9a6
+ call MoveHitTest
+ ld a, [W_MOVEMISSED]
+ and a
+ jr nz, Func_3f9a6
+
+Func_3f96f: ; 3f96f (f:796f)
+ ld a, [H_WHOSETURN]
+ and a
+ ld hl, W_ENEMYBATTSTATUS1
+ ld bc, wd070
+ ld a, [W_PLAYERMOVEEFFECT]
+ jr z, .asm_3f986
+ ld hl, W_PLAYERBATTSTATUS1
+ ld bc, wd06b
+ ld a, [W_ENEMYMOVEEFFECT]
+.asm_3f986
+ bit 7, [hl] ; is mon confused?
+ jr nz, Func_3f9a6
+ set 7, [hl] ; mon is now confused
+ push af
+ call BattleRandom
+ and $3
+ inc a
+ inc a
+ ld [bc], a
+ pop af
+ cp CONFUSION_SIDE_EFFECT
+ call nz, Func_3fb89
+ ld hl, BecameConfusedText
+ 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
+ ld a, [H_WHOSETURN]
+ and a
+ jr z, .asm_3f9cc
+ ld hl, W_ENEMYBATTSTATUS2
+.asm_3f9cc
+ set 5, [hl] ; mon now needs to recharge
+ ret
+
+Func_3f9cf: ; 3f9cf (f:79cf)
+ push hl
+ ld hl, W_ENEMYBATTSTATUS2
+ ld a, [H_WHOSETURN]
+ and a
+ jr z, .asm_3f9db
+ ld hl, W_PLAYERBATTSTATUS2
+.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, wBattleMonMoves
+ ld a, [W_PLAYERBATTSTATUS1]
+ jr nz, .asm_3fa13
+ ld a, [W_ISLINKBATTLE]
+ cp $4
+ jr nz, .asm_3fa3a
+ ld hl, wEnemyMonMoves
+ ld a, [W_ENEMYBATTSTATUS1]
+.asm_3fa13
+ bit 6, a
+ jr nz, .asm_3fa74
+.asm_3fa17
+ push hl
+ call BattleRandom
+ 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, wBattleMonMoves
+ ld a, [wPlayerMoveListIndex]
+ jr z, .asm_3fa5f
+ ld hl, wEnemyMonMoves
+ 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, wEnemyMonMoves
+ ld a, [wCurrentMenuItem]
+ ld c, a
+ ld b, $0
+ add hl, bc
+ ld d, [hl]
+ pop af
+ ld hl, wBattleMonMoves
+.asm_3fa5f
+ ld c, a
+ ld b, $0
+ add hl, bc
+ ld a, d
+ ld [hl], a
+ ld [wd11e], 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]
+ and a
+ jr nz, .asm_3fb06
+ ld de, W_ENEMYDISABLEDMOVE
+ ld hl, wEnemyMonMoves
+ ld a, [H_WHOSETURN]
+ and a
+ jr z, .asm_3faa4
+ ld de, W_PLAYERDISABLEDMOVE
+ ld hl, wBattleMonMoves
+.asm_3faa4
+ ld a, [de]
+ and a
+ jr nz, .asm_3fb06
+.asm_3faa8
+ push hl
+ call BattleRandom
+ and $3
+ ld c, a
+ ld b, $0
+ add hl, bc
+ ld a, [hl]
+ pop hl
+ and a
+ jr z, .asm_3faa8
+ ld [wd11e], a
+ push hl
+ ld a, [H_WHOSETURN]
+ and a
+ ld hl, wBattleMonPP
+ jr nz, .asm_3facf
+ ld a, [W_ISLINKBATTLE]
+ cp $4
+ pop hl
+ jr nz, .asm_3fae1
+ push hl
+ ld hl, wEnemyMonPP
+.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 BattleRandom
+ and $7
+ inc a
+ inc c
+ swap c
+ add c
+ ld [de], a
+ call Func_3fb89
+ ld hl, wccee
+ ld a, [H_WHOSETURN]
+ and a
+ jr nz, .asm_3faf8
+ inc hl
+.asm_3faf8
+ ld a, [wd11e]
+ ld [hl], a
+ call GetMoveName
+ ld hl, MoveWasDisabledText
+ 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, [wccf4]
+ 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
+ jp PrintText
+
+ParalyzedMayNotAttackText: ; 3fb74 (f:7b74)
+ TX_FAR _ParalyzedMayNotAttackText
+ db "@"
+
+CheckTargetSubstitute: ; 3fb79 (f:7b79)
+ push hl
+ ld hl, W_ENEMYBATTSTATUS2
+ ld a, [$fff3] ;whose turn?
+ and a
+ jr z, .next1
+ ld hl, W_PLAYERBATTSTATUS2
+.next1
+ bit 4, [hl] ;test bit 4 in d063/d068 flags
+ pop hl
+ ret
+
+Func_3fb89: ; 3fb89 (f:7b89)
+ ld a, [H_WHOSETURN]
+ and a
+ ld a, [W_PLAYERMOVENUM]
+ jr z, .asm_3fb94
+ ld a, [W_ENEMYMOVENUM]
+.asm_3fb94
+ and a
+ ret z
+
+Func_3fb96: ; 3fb96 (f:7b96)
+ ld [W_ANIMATIONID], a
+ ld a, [H_WHOSETURN]
+ and a
+ ld a, $6
+ jr z, .asm_3fba2
+ ld a, $3
+.asm_3fba2
+ ld [wcc5b], a
+ jp Func_3fbbc
+
+Func_3fba8: ; 3fba8 (f:7ba8)
+ xor a
+ ld [wcc5b], a
+ ld a, [H_WHOSETURN]
+ and a
+ ld a, [W_PLAYERMOVENUM]
+ jr z, .asm_3fbb7
+ ld a, [W_ENEMYMOVENUM]
+.asm_3fbb7
+ and a
+ ret z
+
+Func_3fbb9: ; 3fbb9 (f:7bb9)
+ ld [W_ANIMATIONID], a
+
+Func_3fbbc: ; 3fbbc (f:7bbc)
+ push hl
+ push de
+ push bc
+ predef MoveAnimation
+ pop bc
+ pop de
+ pop hl
+ ret
diff --git a/engine/battle/d.asm b/engine/battle/d.asm
index d23c9114..94a07eb6 100755
--- a/engine/battle/d.asm
+++ b/engine/battle/d.asm
@@ -1,21 +1,23 @@
-Func_372d6: ; 372d6 (d:72d6)
+; display "[player] VS [enemy]" text box with pokeballs representing their parties next to the names
+DisplayLinkBattleVersusTextBox: ; 372d6 (d:72d6)
call LoadTextBoxTilePatterns
hlCoord 3, 4
ld b, $7
ld c, $c
call TextBoxBorder
hlCoord 4, 5
- ld de, wPlayerName ; wd158
+ ld de, wPlayerName
call PlaceString
hlCoord 4, 10
- ld de, W_GRASSRATE ; W_GRASSRATE
+ ld de, W_GRASSRATE ; enemy name
call PlaceString
+; place bold "VS" tiles between the names
hlCoord 9, 8
ld a, $69
ld [hli], a
ld [hl], $6a
xor a
- ld [wcfcb], a
+ ld [wUpdateSpritesEnabled], a
callab SetupPlayerAndEnemyPokeballs
- ld c, $96
+ ld c, 150
jp DelayFrames
diff --git a/engine/battle/e.asm b/engine/battle/e.asm
index 9abeeec8..072aca49 100755
--- a/engine/battle/e.asm
+++ b/engine/battle/e.asm
@@ -1203,11 +1203,11 @@ Func_3a72a: ; 3a72a (e:672a)
ld a,d ; how many available monsters are there?
cp 2 ; don't bother if only 1 or 2
- jp nc,Func_3a74b
+ jp nc,SwitchEnemyMon
and a
ret
-Func_3a74b: ; 3a74b (e:674b)
+SwitchEnemyMon: ; 3a74b (e:674b)
; prepare to withdraw the active monster: copy hp, number, and status to roster
diff --git a/engine/battle/e_2.asm b/engine/battle/e_2.asm
index 665807fe..b0e08982 100755
--- a/engine/battle/e_2.asm
+++ b/engine/battle/e_2.asm
@@ -93,7 +93,7 @@ HealEffect_: ; 3b9ec (e:79ec)
.asm_3ba83
ld [wListMenuID], a ; wListMenuID
predef UpdateHPBar2
- ld hl, Func_3cd5a ; $4d5a
+ ld hl, DrawHUDsAndHPBars ; $4d5a
call BankswitchEtoF
ld hl, RegainedHealthText ; $7aac
jp PrintText
@@ -226,8 +226,8 @@ TransformEffect_: ; 3bab1 (e:7ab1)
ld a, [hl]
ld [wd11e], a
call GetMonName
- ld hl, wcd26
- ld de, wcd12
+ ld hl, wEnemyMonUnmodifiedAttack
+ ld de, wPlayerMonUnmodifiedAttack
call Func_3bb7d
ld hl, wEnemyMonStatMods ; wcd2e
ld de, wPlayerMonStatMods ; wcd1a
diff --git a/engine/battle/safari_zone.asm b/engine/battle/safari_zone.asm
index 99e1492d..6b0e2220 100755
--- a/engine/battle/safari_zone.asm
+++ b/engine/battle/safari_zone.asm
@@ -1,5 +1,5 @@
PrintSafariZoneBattleText: ; 4277 (1:4277)
- ld hl, wcce9
+ ld hl, wSafariBaitFactor
ld a, [hl]
and a
jr z, .asm_4284
@@ -19,7 +19,7 @@ PrintSafariZoneBattleText: ; 4277 (1:4277)
ld [wd0b5], a
call GetMonHeader
ld a, [W_MONHCATCHRATE]
- ld [wd007], a
+ ld [wEnemyMonCatchRate], a
pop hl
.asm_429f
push hl
diff --git a/engine/cable_club.asm b/engine/cable_club.asm
index 06f69a73..a8a1f90f 100755
--- a/engine/cable_club.asm
+++ b/engine/cable_club.asm
@@ -570,13 +570,13 @@ Func_577d: ; 577d (1:577d)
xor a
ld [wd72d], a
dec a
- ld [wd42f], a
+ ld [wDestinationWarpID], a
call LoadMapData
- callba Func_c335
+ callba ClearVariablesAfterLoadingMapData
pop hl
pop af
ld [hl], a
- call GBFadeIn2
+ call GBFadeInFromWhite
ret
Func_57a2:
@@ -826,7 +826,7 @@ TradeCenter_Trade:
.asm_59d9
predef Func_410f3
.asm_59de
- callab Func_3ad0e
+ callab TryEvolvingMon
call ClearScreen
call LoadTrainerInfoTextBoxTiles
call Func_226e
diff --git a/engine/evolution.asm b/engine/evolution.asm
index a52e0071..5842f1a2 100755
--- a/engine/evolution.asm
+++ b/engine/evolution.asm
@@ -19,7 +19,7 @@ Func_7bde9: ; 7bde9 (1e:7de9)
call Delay3
xor a
ld [H_AUTOBGTRANSFERENABLED], a ; $ffba
- ld [$ffd7], a
+ ld [hTilesetType], a
ld a, [wHPBarMaxHP]
ld [wcf1d], a
ld c, $0
diff --git a/engine/evolve_trade.asm b/engine/evolve_trade.asm
index ffb8a778..7fbd4607 100755
--- a/engine/evolve_trade.asm
+++ b/engine/evolve_trade.asm
@@ -38,7 +38,7 @@ EvolveTradeMon: ; 17d7d (5:7d7d)
ld [wccd4], a
ld a, $32
ld [W_ISLINKBATTLE], a ; W_ISLINKBATTLE
- callab Func_3ad0e
+ callab TryEvolvingMon
xor a
ld [W_ISLINKBATTLE], a ; W_ISLINKBATTLE
- jp Func_2307
+ jp PlayDefaultMusic
diff --git a/engine/evos_moves.asm b/engine/evos_moves.asm
index 9869153e..3a7dda43 100755
--- a/engine/evos_moves.asm
+++ b/engine/evos_moves.asm
@@ -1,45 +1,49 @@
-Func_3ad0e: ; 3ad0e (e:6d0e)
+; try to evolve the mon in [wWhichPokemon]
+TryEvolvingMon: ; 3ad0e (e:6d0e)
ld hl, wccd3
xor a
ld [hl], a
- ld a, [wWhichPokemon] ; wWhichPokemon
+ ld a, [wWhichPokemon]
ld c, a
ld b, $1
- call Func_3b057
+ call Evolution_FlagAction
-Func_3ad1c: ; 3ad1c (e:6d1c)
- ld a, [$ffd7]
+; this is only called after battle
+; it is supposed to do level up evolutions, though there is a bug that allows item evolutions to occur
+EvolutionAfterBattle: ; 3ad1c (e:6d1c)
+ ld a, [hTilesetType]
push af
xor a
ld [wd121], a
dec a
- ld [wWhichPokemon], a ; wWhichPokemon
+ ld [wWhichPokemon], a
push hl
push bc
push de
- ld hl, wPartyCount ; wPartyCount
+ ld hl, wPartyCount
push hl
-asm_3ad2e: ; 3ad2e (e:6d2e)
- ld hl, wWhichPokemon ; wWhichPokemon
+
+Evolution_PartyMonLoop: ; loop over party mons
+ ld hl, wWhichPokemon
inc [hl]
pop hl
inc hl
ld a, [hl]
- cp $ff
- jp z, Func_3aede
+ cp $ff ; have we reached the end of the party?
+ jp z, .done
ld [wHPBarMaxHP], a
push hl
- ld a, [wWhichPokemon] ; wWhichPokemon
+ ld a, [wWhichPokemon]
ld c, a
ld hl, wccd3
ld b, $2
- call Func_3b057
+ call Evolution_FlagAction
ld a, c
- and a
- jp z, asm_3ad2e
+ and a ; is the mon's bit set?
+ jp z, Evolution_PartyMonLoop ; if not, go to the next mon
ld a, [wHPBarMaxHP]
dec a
- ld b, $0
+ ld b, 0
ld hl, EvosMovesPointerTable
add a
rl b
@@ -58,56 +62,57 @@ asm_3ad2e: ; 3ad2e (e:6d2e)
ld [wcf91], a
pop hl
-Func_3ad71: ; 3ad71 (e:6d71)
+.evoEntryLoop ; loop over evolution entries
ld a, [hli]
- and a
- jr z, asm_3ad2e
- ld b, a
- cp $3
- jr z, .asm_3ad91
- ld a, [W_ISLINKBATTLE] ; W_ISLINKBATTLE
- cp $32
- jr z, asm_3ad2e
+ and a ; have we reached the end of the evolution data?
+ jr z, Evolution_PartyMonLoop
+ ld b, a ; evolution type
+ cp EV_TRADE
+ jr z, .checkTradeEvo
+; not trade evolution
+ ld a, [W_ISLINKBATTLE]
+ cp $32 ; in a trade?
+ jr z, Evolution_PartyMonLoop ; if so, go the next mon
ld a, b
- cp $2
- jr z, .asm_3ada4
+ cp EV_ITEM
+ jr z, .checkItemEvo
ld a, [wccd4]
and a
- jr nz, asm_3ad2e
+ jr nz, Evolution_PartyMonLoop
ld a, b
- cp $1
- jr z, .asm_3adad
-.asm_3ad91
- ld a, [W_ISLINKBATTLE] ; W_ISLINKBATTLE
- cp $32
- jp nz, Func_3aed9
- ld a, [hli]
+ cp EV_LEVEL
+ jr z, .checkLevel
+.checkTradeEvo
+ ld a, [W_ISLINKBATTLE]
+ cp $32 ; in a trade?
+ jp nz, .nextEvoEntry1 ; if not, go to the next evolution entry
+ ld a, [hli] ; level requirement
ld b, a
ld a, [wcfb9]
- cp b
- jp c, asm_3ad2e
+ cp b ; is the mon's level greater than the evolution requirement?
+ jp c, Evolution_PartyMonLoop ; if so, go the next mon
jr .asm_3adb6
-.asm_3ada4
- ld a, [hli]
- ld b, a
- ld a, [wcf91]
- cp b
- jp nz, Func_3aed9
-.asm_3adad
+.checkItemEvo
ld a, [hli]
+ ld b, a ; evolution item
+ ld a, [wcf91] ; this is supposed to be the last item used, but it is also used to hold species numbers
+ cp b ; was the evolution item in this entry used?
+ jp nz, .nextEvoEntry1 ; if not, go to the next evolution entry
+.checkLevel
+ ld a, [hli] ; level requirement
ld b, a
ld a, [wcfb9]
- cp b
- jp c, Func_3aeda
+ cp b ; is the mon's level greater than the evolution requirement?
+ jp c, .nextEvoEntry2 ; if so, go the next evolution entry
.asm_3adb6
- ld [W_CURENEMYLVL], a ; W_CURENEMYLVL
+ ld [W_CURENEMYLVL], a
ld a, $1
ld [wd121], a
push hl
ld a, [hl]
ld [wHPBarMaxHP + 1], a
- ld a, [wWhichPokemon] ; wWhichPokemon
- ld hl, wPartyMonNicks ; wPartyMonNicks
+ ld a, [wWhichPokemon]
+ ld hl, wPartyMonNicks
call GetPartyMonName
call CopyStringToCF4B
ld hl, IsEvolvingText
@@ -115,17 +120,17 @@ Func_3ad71: ; 3ad71 (e:6d71)
ld c, $32
call DelayFrames
xor a
- ld [H_AUTOBGTRANSFERENABLED], a ; $ffba
+ ld [H_AUTOBGTRANSFERENABLED], a
ld hl, wTileMap
ld bc, $c14
call ClearScreenArea
ld a, $1
- ld [H_AUTOBGTRANSFERENABLED], a ; $ffba
+ ld [H_AUTOBGTRANSFERENABLED], a
ld a, $ff
- ld [wcfcb], a
+ ld [wUpdateSpritesEnabled], a
call ClearSprites
callab Func_7bde9
- jp c, Func_3af2e
+ jp c, CancelledEvolution
ld hl, EvolvedText
call PrintText
pop hl
@@ -147,7 +152,7 @@ Func_3ad71: ; 3ad71 (e:6d71)
ld c, $28
call DelayFrames
call ClearScreen
- call Func_3aef7
+ call RenameEvolvedMon
ld a, [wd11e]
push af
ld a, [wd0b5]
@@ -168,15 +173,15 @@ Func_3ad71: ; 3ad71 (e:6d71)
ld de, wcfba
ld b, $1
call CalcStats
- ld a, [wWhichPokemon] ; wWhichPokemon
- ld hl, wPartyMon1Species ; wPartyMon1Species (aliases: wPartyMon1)
- ld bc, $2c
+ ld a, [wWhichPokemon]
+ ld hl, wPartyMon1
+ ld bc, wPartyMon2 - wPartyMon1
call AddNTimes
ld e, l
ld d, h
push hl
push bc
- ld bc, $22
+ ld bc, wPartyMon1MaxHP - wPartyMon1
add hl, bc
ld a, [hli]
ld b, a
@@ -202,23 +207,23 @@ Func_3ad71: ; 3ad71 (e:6d71)
ld [wd11e], a
xor a
ld [wcc49], a
- call Func_3af5b
+ call LearnMoveFromLevelUp
pop hl
predef SetPartyMonTypes
- ld a, [W_ISINBATTLE] ; W_ISINBATTLE
+ ld a, [W_ISINBATTLE]
and a
- call z, Func_3af52
+ call z, Evolution_ReloadTilesetTilePatterns
predef IndexToPokedex
ld a, [wd11e]
dec a
ld c, a
ld b, $1
- ld hl, wPokedexOwned ; wPokedexOwned
+ ld hl, wPokedexOwned
push bc
- call Func_3b057
+ call Evolution_FlagAction
pop bc
- ld hl, wPokedexSeen ; wd30a
- call Func_3b057
+ ld hl, wPokedexSeen
+ call Evolution_FlagAction
pop de
pop hl
ld a, [wcf98]
@@ -226,33 +231,35 @@ Func_3ad71: ; 3ad71 (e:6d71)
push hl
ld l, e
ld h, d
- jr Func_3aeda
+ jr .nextEvoEntry2
-Func_3aed9: ; 3aed9 (e:6ed9)
+.nextEvoEntry1
inc hl
-Func_3aeda: ; 3aeda (e:6eda)
+.nextEvoEntry2
inc hl
- jp Func_3ad71
+ jp .evoEntryLoop
-Func_3aede: ; 3aede (e:6ede)
+.done
pop de
pop bc
pop hl
pop af
- ld [$ffd7], a
- ld a, [W_ISLINKBATTLE] ; W_ISLINKBATTLE
+ ld [hTilesetType], a
+ ld a, [W_ISLINKBATTLE]
cp $32
ret z
- ld a, [W_ISINBATTLE] ; W_ISINBATTLE
+ ld a, [W_ISINBATTLE]
and a
ret nz
ld a, [wd121]
and a
- call nz, Func_2307
+ call nz, PlayDefaultMusic
ret
-Func_3aef7: ; 3aef7 (e:6ef7)
+; checks if the evolved mon's name is different from the standard name (i.e. it has a nickname)
+; if so, rename it to is evolved form's standard name
+RenameEvolvedMon: ; 3aef7 (e:6ef7)
ld a, [wd0b5]
push af
ld a, [W_MONHDEXNUM]
@@ -262,17 +269,17 @@ Func_3aef7: ; 3aef7 (e:6ef7)
ld [wd0b5], a
ld hl, wcd6d
ld de, wcf4b
-.asm_3af0e
+.compareNamesLoop
ld a, [de]
inc de
cp [hl]
inc hl
ret nz
cp $50
- jr nz, .asm_3af0e
- ld a, [wWhichPokemon] ; wWhichPokemon
+ jr nz, .compareNamesLoop
+ ld a, [wWhichPokemon]
ld bc, $b
- ld hl, wPartyMonNicks ; wPartyMonNicks
+ ld hl, wPartyMonNicks
call AddNTimes
push hl
call GetName
@@ -280,13 +287,13 @@ Func_3aef7: ; 3aef7 (e:6ef7)
pop de
jp CopyData
-Func_3af2e: ; 3af2e (e:6f2e)
+CancelledEvolution: ; 3af2e (e:6f2e)
ld hl, StoppedEvolvingText
call PrintText
call ClearScreen
pop hl
- call Func_3af52
- jp asm_3ad2e
+ call Evolution_ReloadTilesetTilePatterns
+ jp Evolution_PartyMonLoop
EvolvedText: ; 3af3e (e:6f3e)
TX_FAR _EvolvedText
@@ -304,18 +311,18 @@ IsEvolvingText: ; 3af4d (e:6f4d)
TX_FAR _IsEvolvingText
db "@"
-Func_3af52: ; 3af52 (e:6f52)
+Evolution_ReloadTilesetTilePatterns: ; 3af52 (e:6f52)
ld a, [W_ISLINKBATTLE] ; W_ISLINKBATTLE
- cp $32
- ret z
+ cp $32 ; in a trade?
+ ret z ; if so, return
jp ReloadTilesetTilePatterns
-Func_3af5b: ; 3af5b (e:6f5b)
+LearnMoveFromLevelUp: ; 3af5b (e:6f5b)
ld hl, EvosMovesPointerTable
- ld a, [wd11e]
+ ld a, [wd11e] ; species
ld [wcf91], a
dec a
- ld bc, $0
+ ld bc, 0
ld hl, EvosMovesPointerTable
add a
rl b
@@ -324,42 +331,45 @@ Func_3af5b: ; 3af5b (e:6f5b)
ld a, [hli]
ld h, [hl]
ld l, a
-.asm_3af73
+.skipEvolutionDataLoop ; loop to skip past the evolution data, which comes before the move data
ld a, [hli]
- and a
- jr nz, .asm_3af73
-.asm_3af77
+ and a ; have we reached the end of the evolution data?
+ jr nz, .skipEvolutionDataLoop ; if not, jump back up
+.learnSetLoop ; loop over the learn set until we reach a move that is learnt at the current level or the end of the list
ld a, [hli]
- and a
- jr z, .asm_3afb1
- ld b, a
- ld a, [W_CURENEMYLVL] ; W_CURENEMYLVL
- cp b
- ld a, [hli]
- jr nz, .asm_3af77
- ld d, a
+ and a ; have we reached the end of the learn set?
+ jr z, .done ; if we've reached the end of the learn set, jump
+ ld b, a ; level the move is learnt at
+ ld a, [W_CURENEMYLVL]
+ cp b ; is the move learnt at the mon's current level?
+ ld a, [hli] ; move ID
+ jr nz, .learnSetLoop
+ ld d, a ; ID of move to learn
ld a, [wcc49]
and a
- jr nz, .asm_3af96
- ld hl, wPartyMon1Moves ; wPartyMon1Moves
- ld a, [wWhichPokemon] ; wWhichPokemon
- ld bc, $2c
+ jr nz, .next
+; if [wcc49] is 0, get the address of the mon's current moves
+; there is no reason to make this conditional because the code wouldn't work properly without doing this
+; every call to this function sets [wcc49] to 0
+ ld hl, wPartyMon1Moves
+ ld a, [wWhichPokemon]
+ ld bc, wPartyMon2 - wPartyMon1
call AddNTimes
-.asm_3af96
+.next
ld b, $4
-.asm_3af98
+.checkCurrentMovesLoop ; check if the move to learn is already known
ld a, [hli]
cp d
- jr z, .asm_3afb1
+ jr z, .done ; if already known, jump
dec b
- jr nz, .asm_3af98
+ jr nz, .checkCurrentMovesLoop
ld a, d
ld [wd0e0], a
ld [wd11e], a
call GetMoveName
call CopyStringToCF4B
predef LearnMove
-.asm_3afb1
+.done
ld a, [wcf91]
ld [wd11e], a
ret
@@ -484,7 +494,7 @@ WriteMonMoves_ShiftMoveData: ; 3b04e (e:704e)
jr nz, .asm_3b050
ret
-Func_3b057: ; 3b057 (e:7057)
+Evolution_FlagAction: ; 3b057 (e:7057)
predef_jump FlagActionPredef
INCLUDE "data/evos_moves.asm"
diff --git a/engine/experience.asm b/engine/experience.asm
index 07726821..91f1dd5d 100755
--- a/engine/experience.asm
+++ b/engine/experience.asm
@@ -1,28 +1,30 @@
-Func_58f43: ; 58f43 (16:4f43)
+; calculates the level a mon should be based on its current exp
+CalcLevelFromExperience: ; 58f43 (16:4f43)
ld a, [wcf98]
ld [wd0b5], a
call GetMonHeader
- ld d, $1
-.asm_58f4e
- inc d
+ ld d, $1 ; init level to 1
+.loop
+ inc d ; increment level
call CalcExperience
push hl
- ld hl, wcfa8
- ld a, [$ff98]
+ ld hl, wcfa8 ; current exp
+; compare exp needed for level d with current exp
+ ld a, [H_MULTIPLICAND + 2]
ld c, a
ld a, [hld]
sub c
- ld a, [$ff97]
+ ld a, [H_MULTIPLICAND + 1]
ld c, a
ld a, [hld]
sbc c
- ld a, [H_NUMTOPRINT] ; $ff96 (aliases: H_MULTIPLICAND)
+ ld a, [H_MULTIPLICAND]
ld c, a
ld a, [hl]
sbc c
pop hl
- jr nc, .asm_58f4e
- dec d
+ jr nc, .loop ; if exp needed for level d is not greater than exp, try the next level
+ dec d ; since the exp was too high on the last loop iteration, go back to the previous value and return
ret
; calculates the amount of experience needed for level d
diff --git a/engine/give_pokemon.asm b/engine/give_pokemon.asm
index f3bd7f78..d4d58d33 100755
--- a/engine/give_pokemon.asm
+++ b/engine/give_pokemon.asm
@@ -12,7 +12,7 @@ _GivePokemon: ; 4fda5 (13:7da5)
ld [W_ENEMYBATTSTATUS3], a ; W_ENEMYBATTSTATUS3
ld a, [wcf91]
ld [wEnemyMonSpecies2], a
- callab Func_3eb01
+ callab LoadEnemyMonData
call SetPokedexOwnedFlag
callab Func_e7a4
ld hl, wcf4b
@@ -43,7 +43,7 @@ _GivePokemon: ; 4fda5 (13:7da5)
call SetPokedexOwnedFlag
call AddPartyMon
ld a, $1
- ld [wcc3c], a
+ ld [wDoNotWaitForButtonPressAfterDisplayingText], a
ld [wccd3], a
scf
ret
diff --git a/engine/hall_of_fame.asm b/engine/hall_of_fame.asm
index f4384b91..406fac01 100755
--- a/engine/hall_of_fame.asm
+++ b/engine/hall_of_fame.asm
@@ -18,8 +18,8 @@ AnimateHallOfFame: ; 701a0 (1c:41a0)
ld bc, HOF_TEAM
call FillMemory
xor a
- ld [wcfcb], a
- ld [$ffd7], a
+ ld [wUpdateSpritesEnabled], a
+ ld [hTilesetType], a
ld [W_SPRITEFLIPPED], a
ld [wd358], a
ld [wTrainerScreenY], a
@@ -32,7 +32,7 @@ AnimateHallOfFame: ; 701a0 (1c:41a0)
inc [hl]
.asm_701eb
ld a, $90
- ld [$ffb0], a
+ ld [hVBlankWY], a
ld c, BANK(Music_HallOfFame)
ld a, MUSIC_HALL_OF_FAME
call PlayMusic
@@ -66,7 +66,7 @@ AnimateHallOfFame: ; 701a0 (1c:41a0)
call PlaceString
ld c, 180
call DelayFrames
- call GBFadeOut2
+ call GBFadeOutToWhite
pop bc
pop hl
jr .asm_701fb
@@ -86,7 +86,7 @@ AnimateHallOfFame: ; 701a0 (1c:41a0)
call Func_70377
call Func_70423
xor a
- ld [$ffb0], a
+ ld [hVBlankWY], a
ld hl, rLCDC ; $ff40
res 3, [hl]
ret
@@ -125,7 +125,7 @@ Func_70278: ; 70278 (1c:4278)
call Func_7036d
ld d, $a0
ld e, $4
- ld a, [wcf1b]
+ ld a, [wOnSGB]
and a
jr z, .asm_702c7
sla e
@@ -282,4 +282,4 @@ Func_70423: ; 70423 (1c:4423)
ld [wcfc9], a
ld a, $ff
ld [wMusicHeaderPointer], a
- jp GBFadeOut2
+ jp GBFadeOutToWhite
diff --git a/engine/hidden_object_functions14.asm b/engine/hidden_object_functions14.asm
index 0d3598f2..a162c905 100755
--- a/engine/hidden_object_functions14.asm
+++ b/engine/hidden_object_functions14.asm
@@ -1,7 +1,7 @@
PrintNotebookText: ; 52996 (14:6996)
call EnableAutoTextBoxDrawing
ld a, $1
- ld [wcc3c], a
+ ld [wDoNotWaitForButtonPressAfterDisplayingText], a
ld a, [wTrainerSpriteOffset]
jp PrintPredefTextID
diff --git a/engine/hidden_object_functions17.asm b/engine/hidden_object_functions17.asm
index f0126b65..f1a07542 100755
--- a/engine/hidden_object_functions17.asm
+++ b/engine/hidden_object_functions17.asm
@@ -64,7 +64,7 @@ DisplayMonFrontSpriteInBox: ; 5dbd9 (17:5bd9)
ld [H_AUTOBGTRANSFERENABLED], a ; $ffba
call Delay3
xor a
- ld [$ffb0], a
+ ld [hVBlankWY], a
call SaveScreenTilesToBuffer1
ld a, $11
ld [wd125], a
@@ -83,13 +83,13 @@ DisplayMonFrontSpriteInBox: ; 5dbd9 (17:5bd9)
call LoadScreenTilesFromBuffer1
call Delay3
ld a, $90
- ld [$ffb0], a
+ ld [hVBlankWY], a
ret
PrintBlackboardLinkCableText: ; 5dc1a (17:5c1a)
call EnableAutoTextBoxDrawing
ld a, $1
- ld [wcc3c], a
+ ld [wDoNotWaitForButtonPressAfterDisplayingText], a
ld a, [wWhichTrade]
call PrintPredefTextID
ret
diff --git a/engine/hidden_object_functions18.asm b/engine/hidden_object_functions18.asm
index 5ccb43c2..7696626f 100755
--- a/engine/hidden_object_functions18.asm
+++ b/engine/hidden_object_functions18.asm
@@ -70,7 +70,7 @@ PrintBenchGuyText: ; 6245d (18:645d)
ld a, [hl]
jp PrintPredefTextID
-; format: db map id, 08, text id of PointerTable_3f22
+; format: db map id, 08, text id of PredefTextIDPointerTable
PokeCenterMapIDList: ; 6247e (18:647e)
db VIRIDIAN_POKECENTER,$08,$0F
db PEWTER_POKECENTER,$08,$10
@@ -181,7 +181,7 @@ OpenPokemonCenterPC: ; 62516 (18:6516)
ret nz
call EnableAutoTextBoxDrawing
ld a, $1
- ld [wcf0c], a
+ ld [wAutoTextBoxDrawingControl], a
ld a, $1f ; PredefText1f
jp PrintPredefTextID
diff --git a/engine/hidden_object_functions3.asm b/engine/hidden_object_functions3.asm
index e613df2e..d3d83f08 100755
--- a/engine/hidden_object_functions3.asm
+++ b/engine/hidden_object_functions3.asm
@@ -1,22 +1,23 @@
; prints text for bookshelves in buildings without sign events
PrintBookshelfText: ; fb50 (3:7b50)
- ld a, [wSpriteStateData1 + 9]
- cp $4
- jr nz, .asm_fb7f
- ld a, [W_CURMAPTILESET] ; W_CURMAPTILESET
+ ld a, [wSpriteStateData1 + 9] ; player's sprite facing direction
+ cp SPRITE_FACING_UP
+ jr nz, .noMatch
+; facing up
+ ld a, [W_CURMAPTILESET]
ld b, a
aCoord 8, 7
ld c, a
- ld hl, BookshelfTileIDs ; $7b8b
-.asm_fb62
+ ld hl, BookshelfTileIDs
+.loop
ld a, [hli]
cp $ff
- jr z, .asm_fb7f
+ jr z, .noMatch
cp b
- jr nz, .asm_fb7b
+ jr nz, .nextBookshelfEntry1
ld a, [hli]
cp c
- jr nz, .asm_fb7c
+ jr nz, .nextBookshelfEntry2
ld a, [hl]
push af
call EnableAutoTextBoxDrawing
@@ -25,12 +26,12 @@ PrintBookshelfText: ; fb50 (3:7b50)
xor a
ld [$ffdb], a
ret
-.asm_fb7b
+.nextBookshelfEntry1
inc hl
-.asm_fb7c
+.nextBookshelfEntry2
inc hl
- jr .asm_fb62
-.asm_fb7f
+ jr .loop
+.noMatch
ld a, $ff
ld [$ffdb], a
ld b, BANK(PrintCardKeyText)
@@ -114,12 +115,12 @@ TownMapText: ; fc12 (3:7c12)
db $06
db $08 ; asm
ld a, $1
- ld [wcc3c], a
+ ld [wDoNotWaitForButtonPressAfterDisplayingText], a
ld hl, wd730
set 6, [hl]
call GBPalWhiteOutWithDelay3
xor a
- ld [$ffb0], a
+ ld [hVBlankWY], a
inc a
ld [H_AUTOBGTRANSFERENABLED], a
call LoadFontTilePatterns
diff --git a/engine/hidden_object_functions7.asm b/engine/hidden_object_functions7.asm
index 848f6f3d..012e941d 100755
--- a/engine/hidden_object_functions7.asm
+++ b/engine/hidden_object_functions7.asm
@@ -60,7 +60,7 @@ SafariZoneCheckSteps: ; 1e997 (7:6997)
ld [wSafariSteps + 1], a ; wd70e
asm_1e9ab: ; 1e9ab (7:69ab)
xor a
- ld [wda46], a
+ ld [wSafariZoneGameOver], a
ret
asm_1e9b0: ; 1e9b0 (7:69b0)
call EnableAutoTextBoxDrawing
@@ -83,13 +83,13 @@ asm_1e9b0: ; 1e9b0 (7:69b0)
ld a, $9c
ld [H_DOWNARROWBLINKCNT1], a ; $ff8b
ld a, $3
- ld [wd42f], a
+ ld [wDestinationWarpID], a
ld a, $5
ld [W_SAFARIZONEENTRANCECURSCRIPT], a
ld hl, wd790
set 6, [hl]
ld a, $1
- ld [wda46], a
+ ld [wSafariZoneGameOver], a
ret
PrintSafariGameOverText: ; 1e9ed (7:69ed)
@@ -152,7 +152,7 @@ CinnabarGymQuiz: ; 1ea25 (7:6a25)
ld l, a
call PrintText
ld a, $1
- ld [wcc3c], a
+ ld [wDoNotWaitForButtonPressAfterDisplayingText], a
call CinnabarGymQuiz_1ea92
jp TextScriptEnd
@@ -291,7 +291,7 @@ CinnabarGymQuiz_1eb0a: ; 1eb0a (7:6b0a)
.asm_1eb38
pop bc
ld [wd09f], a
- predef Func_ee9e
+ predef ReplaceTileBlock
ld hl, $ffdb
dec [hl]
jr nz, .asm_1eb0e
@@ -334,7 +334,7 @@ BillsHousePC: ; 1eb6e (7:6b6e)
jp PrintPredefTextID
.asm_1eb8b
ld a, $1
- ld [wcc3c], a
+ ld [wDoNotWaitForButtonPressAfterDisplayingText], a
ld a, $2e
call PrintPredefTextID
ld c, $20
@@ -357,13 +357,13 @@ BillsHousePC: ; 1eb6e (7:6b6e)
ld a, (SFX_02_3a - SFX_Headers_02) / 3
call PlaySound
call WaitForSoundToFinish
- call Func_2307
+ call PlayDefaultMusic
ld hl, wd7f2
set 3, [hl]
ret
.asm_1ebd2
ld a, $1
- ld [wcc3c], a
+ ld [wDoNotWaitForButtonPressAfterDisplayingText], a
ld a, $2f
call PrintPredefTextID
ret
diff --git a/engine/in_game_trades.asm b/engine/in_game_trades.asm
index 7f0b21c1..7464edb3 100755
--- a/engine/in_game_trades.asm
+++ b/engine/in_game_trades.asm
@@ -88,7 +88,7 @@ Func_71c07: ; 71c07 (1c:5c07)
xor a
ld [wd07d],a
dec a
- ld [wcfcb],a
+ ld [wUpdateSpritesEnabled],a
call DisplayPartyMenu
push af
call Func_71ca2
@@ -138,7 +138,7 @@ Func_71c07: ; 71c07 (1c:5c07)
callab EvolveTradeMon
call ClearScreen
call Func_71ca2
- callba Func_eedc
+ callba RedrawMapView
and a
ld a,$3
jr .asm_ee803 ; 0x71c9b $1
@@ -150,7 +150,7 @@ Func_71c07: ; 71c07 (1c:5c07)
Func_71ca2: ; 71ca2 (1c:5ca2)
call GBPalWhiteOutWithDelay3
- call Func_3dbe
+ call RestoreScreenTilesAndReloadTilePatterns
call ReloadTilesetTilePatterns
call LoadScreenTilesFromBuffer2
call Delay3
diff --git a/engine/intro.asm b/engine/intro.asm
index 801324a5..68bf8b50 100755
--- a/engine/intro.asm
+++ b/engine/intro.asm
@@ -5,7 +5,7 @@ PlayIntro: ; 41682 (10:5682)
ld [H_AUTOBGTRANSFERENABLED], a
call PlayShootingStar
call PlayIntroScene
- call GBFadeOut2
+ call GBFadeOutToWhite
xor a
ld [$ffae], a
ld [H_AUTOBGTRANSFERENABLED], a
diff --git a/engine/items/items.asm b/engine/items/items.asm
index 0609e685..af6c9552 100755
--- a/engine/items/items.asm
+++ b/engine/items/items.asm
@@ -237,7 +237,7 @@ ItemUseBall: ; d687 (3:5687)
ld [H_QUOTIENT + 3],a
.next9 ;$5776
pop bc
- ld a,[wd007] ;enemy: Catch Rate
+ ld a,[wEnemyMonCatchRate] ;enemy: Catch Rate
cp b
jr c,.next10
ld a,[H_QUOTIENT + 2]
@@ -256,7 +256,7 @@ ItemUseBall: ; d687 (3:5687)
xor a
ld [H_MULTIPLICAND],a
ld [H_MULTIPLICAND + 1],a
- ld a,[wd007] ;enemy: Catch Rate
+ ld a,[wEnemyMonCatchRate] ;enemy: Catch Rate
ld [H_MULTIPLICAND + 2],a
ld a,100
ld [H_MULTIPLIER],a
@@ -376,7 +376,7 @@ ItemUseBall: ; d687 (3:5687)
ld [wcf91],a
ld a,[wEnemyMonLevel]
ld [W_CURENEMYLVL],a
- callab Func_3eb01
+ callab LoadEnemyMonData
pop af
ld [wcf91],a
pop hl
@@ -507,8 +507,8 @@ ItemUseBicycle: ; d977 (3:5977)
ld a,[W_ISINBATTLE]
and a
jp nz,ItemUseNotTime
- ld a,[wd700]
- ld [wd11a],a
+ ld a,[wWalkBikeSurfState]
+ ld [wWalkBikeSurfStateCopy],a
cp a,2 ; is the player surfing?
jp z,ItemUseNotTime
dec a ; is player already bicycling?
@@ -516,8 +516,8 @@ ItemUseBicycle: ; d977 (3:5977)
.getOffBike
call ItemUseReloadOverworldData
xor a
- ld [wd700],a ; change player state to walking
- call Func_2307 ; play walking music
+ ld [wWalkBikeSurfState],a ; change player state to walking
+ call PlayDefaultMusic ; play walking music
ld hl,GotOffBicycleText
jr .printText
.tryToGetOnBike
@@ -527,16 +527,16 @@ ItemUseBicycle: ; d977 (3:5977)
xor a ; no keys pressed
ld [hJoyHeld],a ; current joypad state
inc a
- ld [wd700],a ; change player state to bicycling
+ ld [wWalkBikeSurfState],a ; change player state to bicycling
ld hl,GotOnBicycleText
- call Func_2307 ; play bike riding music
+ call PlayDefaultMusic ; play bike riding music
.printText
jp PrintText
; used for Surf out-of-battle effect
ItemUseSurfboard: ; d9b4 (3:59b4)
- ld a,[wd700]
- ld [wd11a],a
+ ld a,[wWalkBikeSurfState]
+ ld [wWalkBikeSurfStateCopy],a
cp a,2 ; is the player already surfing?
jr z,.tryToStopSurfing
.tryToSurf
@@ -550,8 +550,8 @@ ItemUseSurfboard: ; d9b4 (3:59b4)
ld hl,wd730
set 7,[hl]
ld a,2
- ld [wd700],a ; change player state to surfing
- call Func_2307 ; play surfing music
+ ld [wWalkBikeSurfState],a ; change player state to surfing
+ call PlayDefaultMusic ; play surfing music
ld hl,SurfingGotOnText
jp PrintText
.tryToStopSurfing
@@ -570,7 +570,7 @@ ItemUseSurfboard: ; d9b4 (3:59b4)
ld a,[hli]
ld h,[hl]
ld l,a ; hl now points to passable tiles
- ld a,[wcfc6] ; tile in front of the player
+ ld a,[wTileInFrontOfPlayer] ; tile in front of the player
ld b,a
.passableTileLoop
ld a,[hli]
@@ -586,31 +586,31 @@ ItemUseSurfboard: ; d9b4 (3:59b4)
ld hl,wd730
set 7,[hl]
xor a
- ld [wd700],a ; change player state to walking
+ ld [wWalkBikeSurfState],a ; change player state to walking
dec a
ld [wJoyIgnore],a
- call Func_2307 ; play walking music
+ call PlayDefaultMusic ; play walking music
jp LoadWalkingPlayerSpriteGraphics
; uses a simulated button press to make the player move forward
.makePlayerMoveForward
ld a,[wd52a] ; direction the player is going
bit 3,a
- ld b,%01000000 ; Up key
+ ld b,D_UP
jr nz,.storeSimulatedButtonPress
bit 2,a
- ld b,%10000000 ; Down key
+ ld b,D_DOWN
jr nz,.storeSimulatedButtonPress
bit 1,a
- ld b,%00100000 ; Left key
+ ld b,D_LEFT
jr nz,.storeSimulatedButtonPress
- ld b,%00010000 ; Right key
+ ld b,D_RIGHT
.storeSimulatedButtonPress
ld a,b
- ld [wccd3],a ; base address of simulated button presses
+ ld [wSimulatedJoypadStatesEnd],a
xor a
- ld [wcd39],a
+ ld [wWastedByteCD39],a
inc a
- ld [wcd38],a ; index of current simulated button press
+ ld [wSimulatedJoypadStatesIndex],a
ret
SurfingGotOnText: ; da4c (3:5a4c)
@@ -636,7 +636,7 @@ ItemUseEvoStone: ; da5b (3:5a5b)
ld a,$05 ; evolution stone party menu
ld [wd07d],a
ld a,$ff
- ld [wcfcb],a
+ ld [wUpdateSpritesEnabled],a
call DisplayPartyMenu
pop bc
jr c,.canceledItemUse
@@ -647,7 +647,7 @@ ItemUseEvoStone: ; da5b (3:5a5b)
ld a,(SFX_02_3e - SFX_Headers_02) / 3
call PlaySoundWaitForCurrent ; play sound
call WaitForSoundToFinish ; wait for sound to end
- callab Func_3ad0e ; try to evolve pokemon
+ callab TryEvolvingMon ; try to evolve pokemon
ld a,[wd121]
and a
jr z,.noEffect
@@ -681,7 +681,7 @@ ItemUseMedicine: ; dabb (3:5abb)
ld a,$01
ld [wd07d],a ; item use party menu
ld a,$ff
- ld [wcfcb],a
+ ld [wUpdateSpritesEnabled],a
ld a,[wd152]
and a ; using Softboiled?
jr z,.notUsingSoftboiled
@@ -805,7 +805,7 @@ ItemUseMedicine: ; dabb (3:5abb)
push bc
ld a,[wcf06]
ld c,a
- ld hl,wccf5
+ ld hl,wPartyFoughtCurrentEnemyFlags
ld b,$02
predef FlagActionPredef
ld a,c
@@ -813,7 +813,7 @@ ItemUseMedicine: ; dabb (3:5abb)
jr z,.next
ld a,[wcf06]
ld c,a
- ld hl,wPartyAliveFlags
+ ld hl,wPartyGainExpFlags
ld b,$01
predef FlagActionPredef
.next
@@ -1096,7 +1096,7 @@ ItemUseMedicine: ; dabb (3:5abb)
ld [H_AUTOBGTRANSFERENABLED],a
call ClearScreen
dec a
- ld [wcfcb],a
+ ld [wUpdateSpritesEnabled],a
call RedrawPartyMenu ; redraws the party menu and displays the message
ld a,1
ld [H_AUTOBGTRANSFERENABLED],a
@@ -1273,12 +1273,12 @@ ItemUseMedicine: ; dabb (3:5abb)
call WaitForTextScrollButtonPress ; wait for button press
xor a
ld [wcc49],a
- predef Func_3af5b ; learn level up move, if any
+ predef LearnMoveFromLevelUp ; learn level up move, if any
xor a
ld [wccd4],a
- callab Func_3ad0e ; evolve pokemon, if appropriate
+ callab TryEvolvingMon ; evolve pokemon, if appropriate
ld a,$01
- ld [wcfcb],a
+ ld [wUpdateSpritesEnabled],a
pop af
ld [wcf91],a
pop af
@@ -1303,17 +1303,17 @@ VitaminText: ; df2e (3:5f2e)
ItemUseBait: ; df52 (3:5f52)
ld hl,ThrewBaitText
call PrintText
- ld hl,wd007 ; catch rate
+ ld hl,wEnemyMonCatchRate ; catch rate
srl [hl] ; halve catch rate
ld a,BAIT_ANIM
- ld hl,wcce9 ; bait factor
- ld de,wcce8 ; escape factor
+ ld hl,wSafariBaitFactor ; bait factor
+ ld de,wSafariEscapeFactor ; escape factor
jr BaitRockCommon
ItemUseRock: ; df67 (3:5f67)
ld hl,ThrewRockText
call PrintText
- ld hl,wd007 ; catch rate
+ ld hl,wEnemyMonCatchRate ; catch rate
ld a,[hl]
add a ; double catch rate
jr nc,.noCarry
@@ -1321,8 +1321,8 @@ ItemUseRock: ; df67 (3:5f67)
.noCarry
ld [hl],a
ld a,ROCK_ANIM
- ld hl,wcce8 ; escape factor
- ld de,wcce9 ; bait factor
+ ld hl,wSafariEscapeFactor ; escape factor
+ ld de,wSafariBaitFactor ; bait factor
BaitRockCommon: ; df7f (3:5f7f)
ld [W_ANIMATIONID],a
@@ -1383,7 +1383,7 @@ ItemUseEscapeRope: ; dfaf (3:5faf)
ld [W_NUMSAFARIBALLS],a
ld [W_SAFARIZONEENTRANCECURSCRIPT],a
inc a
- ld [wd078],a
+ ld [wEscapedFromBattle],a
ld [wcd6a],a ; item used
ld a,[wd152]
and a ; using Dig?
@@ -1424,8 +1424,8 @@ ItemUseXAccuracy: ; e013 (3:6013)
ItemUseCardKey: ; e022 (3:6022)
xor a
ld [wd71f],a
- call Func_c586
- ld a,[Func_c586] ; $4586
+ call GetTileAndCoordsInFrontOfPlayer
+ ld a,[GetTileAndCoordsInFrontOfPlayer] ; $4586
cp a,$18
jr nz,.next0
ld hl,CardKeyTable1
@@ -1517,7 +1517,7 @@ ItemUsePokedoll: ; e0cd (3:60cd)
dec a
jp nz,ItemUseNotTime
ld a,$01
- ld [wd078],a
+ ld [wEscapedFromBattle],a
jp PrintItemUseTextAndRemoveItem
ItemUseGuardSpec: ; e0dc (3:60dc)
@@ -1727,7 +1727,7 @@ PlayedFluteHadEffectText: ; e215 (3:6215)
ld a,[wc028]
cp a,$b8
jr z,.musicWaitLoop
- call Func_2307 ; start playing normal music again
+ call PlayDefaultMusic ; start playing normal music again
.done
jp TextScriptEnd ; end text
@@ -1796,7 +1796,7 @@ RodResponse: ; e28d (3:628d)
ld [W_CUROPPONENT], a
.next
- ld hl, wd700
+ ld hl, wWalkBikeSurfState
ld a, [hl] ; store the value in a
push af
push hl
@@ -1818,7 +1818,7 @@ FishingInit: ; e2b4 (3:62b4)
.notInBattle
call IsNextTileShoreOrWater
ret c
- ld a,[wd700]
+ ld a,[wWalkBikeSurfState]
cp a,2 ; Surfing?
jr z,.surfing
call ItemUseReloadOverworldData
@@ -1877,7 +1877,7 @@ ItemUsePPRestore: ; e31e (3:631e)
ld [wWhichTrade],a
.chooseMon
xor a
- ld [wcfcb],a
+ ld [wUpdateSpritesEnabled],a
ld a,$01 ; item use party menu
ld [wd07d],a
call DisplayPartyMenu
@@ -2117,7 +2117,7 @@ ItemUseTMHM: ; e479 (3:6479)
ld bc,14
call CopyData
ld a,$ff
- ld [wcfcb],a
+ ld [wUpdateSpritesEnabled],a
ld a,$03 ; teach TM/HM party menu
ld [wd07d],a
call DisplayPartyMenu
@@ -2744,7 +2744,7 @@ IsNextTileShoreOrWater: ; e8b8 (3:68b8)
jr nc, .notShoreOrWater
ld a, [W_CURMAPTILESET]
cp SHIP_PORT ; Vermilion Dock tileset
- ld a, [wcfc6] ; tile in front of player
+ ld a, [wTileInFrontOfPlayer] ; tile in front of player
jr z, .skipShoreTiles ; if it's the Vermilion Dock tileset
cp $48 ; eastern shore tile in Safari Zone
jr z, .shoreOrWater
diff --git a/engine/menu/bills_pc.asm b/engine/menu/bills_pc.asm
index b06927d8..f1a0e798 100644
--- a/engine/menu/bills_pc.asm
+++ b/engine/menu/bills_pc.asm
@@ -320,7 +320,7 @@ Func_21673: ; 21673 (8:5673)
jp Func_214e8
Func_216b3: ; 216b3 (8:56b3)
- callba Func_738a1
+ callba ChangeBox
jp Func_214e8
Func_216be: ; 216be (8:56be)
diff --git a/engine/menu/diploma.asm b/engine/menu/diploma.asm
index 023c6177..95b2a87d 100755
--- a/engine/menu/diploma.asm
+++ b/engine/menu/diploma.asm
@@ -3,7 +3,7 @@ DisplayDiploma: ; 566e2 (15:66e2)
call GBPalWhiteOutWithDelay3
call ClearScreen
xor a
- ld [wcfcb], a
+ ld [wUpdateSpritesEnabled], a
ld hl, wd730
set 6, [hl]
call DisableLCD
@@ -61,7 +61,7 @@ DisplayDiploma: ; 566e2 (15:66e2)
ld hl, wd730
res 6, [hl]
call GBPalWhiteOutWithDelay3
- call Func_3dbe
+ call RestoreScreenTilesAndReloadTilePatterns
call Delay3
jp GBPalNormal
diff --git a/engine/menu/league_pc.asm b/engine/menu/league_pc.asm
index 4833e57d..a6dd7021 100755
--- a/engine/menu/league_pc.asm
+++ b/engine/menu/league_pc.asm
@@ -4,14 +4,14 @@ PKMNLeaguePC: ; 0x7657e
ld hl, wd730
set 6, [hl]
push hl
- ld a, [wcfcb]
+ ld a, [wUpdateSpritesEnabled]
push af
- ld a, [$ffD7]
+ ld a, [hTilesetType]
push af
xor a
- ld [$ffD7], a
+ ld [hTilesetType], a
ld [W_SPRITEFLIPPED], a
- ld [wcfcb], a
+ ld [wUpdateSpritesEnabled], a
ld [wTrainerScreenX], a
ld [wcd42], a
ld a, [wd5a2]
@@ -38,9 +38,9 @@ PKMNLeaguePC: ; 0x7657e
jr nz, .first
.second
pop af
- ld [$ffD7], a
+ ld [hTilesetType], a
pop af
- ld [wcfcb], a
+ ld [wUpdateSpritesEnabled], a
pop hl
res 6, [hl]
call GBPalWhiteOutWithDelay3
diff --git a/engine/menu/main_menu.asm b/engine/menu/main_menu.asm
index 5f8f0c1d..c6052f03 100755
--- a/engine/menu/main_menu.asm
+++ b/engine/menu/main_menu.asm
@@ -111,16 +111,16 @@ MainMenu: ; 5af2 (1:5af2)
call DelayFrames
ld a,[wd5a2]
and a
- jp z,Func_5d5f
+ jp z,SpecialEnterMap
ld a,[W_CURMAP] ; map ID
cp a,HALL_OF_FAME
- jp nz,Func_5d5f
+ jp nz,SpecialEnterMap
xor a
- ld [wd71a],a
+ ld [wDestinationMap],a
ld hl,wd732
- set 2,[hl]
- call Func_62ce
- jp Func_5d5f
+ set 2,[hl] ; fly warp or dungeon warp
+ call SpecialWarpIn
+ jp SpecialEnterMap
Func_5bff: ; 5bff (1:5bff)
ld a,1
ld [wd358],a
@@ -247,7 +247,7 @@ LinkMenu: ; 5c0a (1:5c0a)
cp $2
jr z, .asm_5d2d
xor a
- ld [wd700], a
+ ld [wWalkBikeSurfState], a
ld a, [wCurrentMenuItem] ; wCurrentMenuItem
and a
ld a, TRADE_CENTER
@@ -262,8 +262,8 @@ LinkMenu: ; 5c0a (1:5c0a)
ld hl, wd732
res 1, [hl]
ld a, [W_ANIMATIONID] ; W_ANIMATIONID
- ld [wd71a], a
- call Func_62ce
+ ld [wDestinationMap], a
+ call SpecialWarpIn
ld c, $14
call DelayFrames
xor a
@@ -272,7 +272,7 @@ LinkMenu: ; 5c0a (1:5c0a)
inc a
ld [W_ISLINKBATTLE], a ; W_ISLINKBATTLE
ld [wcc47], a
- jr Func_5d5f
+ jr SpecialEnterMap
.asm_5d2d
xor a
ld [wMenuJoypadPollCount], a ; wMenuJoypadPollCount
@@ -303,16 +303,17 @@ Func_5d52: ; 5d52 (1:5d52)
ld c, $14
call DelayFrames
-Func_5d5f: ; 5d5f (1:5d5f)
+; enter map after using a special warp or loading the game from the main menu
+SpecialEnterMap: ; 5d5f (1:5d5f)
xor a
ld [hJoyPressed], a
ld [hJoyHeld], a
ld [hJoy5], a
ld [wd72d], a
ld hl, wd732
- set 0, [hl]
+ set 0, [hl] ; count play time
call ResetPlayerSpriteData
- ld c, $14
+ ld c, 20
call DelayFrames
ld a, [wcc47]
and a
diff --git a/engine/menu/naming_screen.asm b/engine/menu/naming_screen.asm
index 17aa96e6..b7db452a 100755
--- a/engine/menu/naming_screen.asm
+++ b/engine/menu/naming_screen.asm
@@ -22,10 +22,10 @@ AskName: ; 64eb (1:64eb)
ld a, [wCurrentMenuItem] ; wCurrentMenuItem
and a
jr nz, .asm_654c
- ld a, [wcfcb]
+ ld a, [wUpdateSpritesEnabled]
push af
xor a
- ld [wcfcb], a
+ ld [wUpdateSpritesEnabled], a
push hl
ld a, $2
ld [wd07d], a
@@ -33,12 +33,12 @@ AskName: ; 64eb (1:64eb)
ld a, [W_ISINBATTLE] ; W_ISINBATTLE
and a
jr nz, .asm_653e
- call Func_3e08
+ call ReloadMapSpriteTilePatterns
.asm_653e
call LoadScreenTilesFromBuffer1
pop hl
pop af
- ld [wcfcb], a
+ ld [wUpdateSpritesEnabled], a
ld a, [wcf4b]
cp $50
ret nz
@@ -56,12 +56,12 @@ DoYouWantToNicknameText: ; 0x6557
Func_655c: ; 655c (1:655c)
ld hl, wHPBarMaxHP
xor a
- ld [wcfcb], a
+ ld [wUpdateSpritesEnabled], a
ld a, $2
ld [wd07d], a
call DisplayNamingScreen
call GBPalWhiteOutWithDelay3
- call Func_3dbe
+ call RestoreScreenTilesAndReloadTilePatterns
call LoadGBPal
ld a, [wcf4b]
cp $50
@@ -171,8 +171,8 @@ DisplayNamingScreen: ; 6596 (1:6596)
ld a, [W_ISINBATTLE] ; W_ISINBATTLE
and a
jp z, LoadTextBoxTilePatterns
- ld hl, Func_3ee5b
- ld b, BANK(Func_3ee5b)
+ ld hl, LoadHudTilePatterns
+ ld b, BANK(LoadHudTilePatterns)
jp Bankswitch
.unknownPointerTable_665e: ; 665e (1:665e)
diff --git a/engine/menu/party_menu.asm b/engine/menu/party_menu.asm
index 4e47361b..10fc4182 100755
--- a/engine/menu/party_menu.asm
+++ b/engine/menu/party_menu.asm
@@ -57,7 +57,7 @@ RedrawPartyMenu_: ; 12ce3 (4:6ce3)
call LoadMonData
pop hl
push hl
- ld a,[wcc35]
+ ld a,[wMenuItemToSwap]
and a ; is the player swapping pokemon positions?
jr z,.skipUnfilledRightArrow
; if the player is swapping pokemon positions
diff --git a/engine/menu/pc.asm b/engine/menu/pc.asm
index 4df6c826..97895ca6 100755
--- a/engine/menu/pc.asm
+++ b/engine/menu/pc.asm
@@ -86,7 +86,7 @@ BillsPC: ; 17ee4 (5:7ee4)
callba BillsPC_
ReloadMainMenu: ; 17f06 (5:7f06)
xor a
- ld [wcc3c], a
+ ld [wDoNotWaitForButtonPressAfterDisplayingText], a
call ReloadMapData
call UpdateSprites ;XXX: moves sprites
jp PCMainMenu
diff --git a/engine/menu/players_pc.asm b/engine/menu/players_pc.asm
index 4ff1b16f..5f1175eb 100755
--- a/engine/menu/players_pc.asm
+++ b/engine/menu/players_pc.asm
@@ -78,7 +78,7 @@ Func_796d: ; 796d (1:796d)
ld hl, wd730
res 6, [hl]
xor a
- ld [wcc3c], a
+ ld [wDoNotWaitForButtonPressAfterDisplayingText], a
ret
Func_7995: ; 7995 (1:7995)
diff --git a/engine/menu/pokedex.asm b/engine/menu/pokedex.asm
index f35b93e0..227728a0 100755
--- a/engine/menu/pokedex.asm
+++ b/engine/menu/pokedex.asm
@@ -36,8 +36,8 @@ ShowPokedexMenu: ; 40000 (10:4000)
ld [wCurrentMenuItem],a
ld [wLastMenuItem],a
ld [hJoy7],a
- ld [wcd3a],a
- ld [wcd3b],a
+ ld [wWastedByteCD3A],a
+ ld [wOverrideSimulatedJoypadStatesMask],a
pop af
ld [wListScrollOffset],a
call GBPalWhiteOutWithDelay3
@@ -404,10 +404,10 @@ ShowPokedexDataInternal: ; 402e2 (10:42e2)
call GoPAL_SET
pop af
ld [wd11e],a
- ld a,[$ffd7]
+ ld a,[hTilesetType]
push af
xor a
- ld [$ffd7],a
+ ld [hTilesetType],a
hlCoord 0, 0
ld de,1
ld bc,$6414
@@ -554,7 +554,7 @@ ShowPokedexDataInternal: ; 402e2 (10:42e2)
and a,%00000011 ; A button and B button
jr z,.waitForButtonPress
pop af
- ld [$ffd7],a
+ ld [hTilesetType],a
call GBPalWhiteOut
call ClearScreen
call GoPAL_SET_CF1C
diff --git a/engine/menu/pokedex.asm.orig b/engine/menu/pokedex.asm.orig
new file mode 100755
index 00000000..7d7d2b38
--- /dev/null
+++ b/engine/menu/pokedex.asm.orig
@@ -0,0 +1,647 @@
+ShowPokedexMenu: ; 40000 (10:4000)
+ call GBPalWhiteOut
+ call ClearScreen
+ call UpdateSprites ; move sprites
+ ld a,[wListScrollOffset]
+ push af
+ xor a
+ ld [wCurrentMenuItem],a
+ ld [wListScrollOffset],a
+ ld [wLastMenuItem],a
+ inc a
+ ld [wd11e],a
+ ld [hJoy7],a
+.setUpGraphics
+ ld b,$08
+ call GoPAL_SET
+ callab LoadPokedexTilePatterns
+.doPokemonListMenu
+ ld hl,wTopMenuItemY
+ ld a,3
+ ld [hli],a ; top menu item Y
+ xor a
+ ld [hli],a ; top menu item X
+ inc a
+ ld [wcc37],a
+ inc hl
+ inc hl
+ ld a,6
+ ld [hli],a ; max menu item ID
+ ld [hl],%00110011 ; menu watched keys (Left, Right, B button, A button)
+ call HandlePokedexListMenu
+ jr c,.goToSideMenu ; if the player chose a pokemon from the list
+.exitPokedex
+ xor a
+ ld [wcc37],a
+ ld [wCurrentMenuItem],a
+ ld [wLastMenuItem],a
+<<<<<<< HEAD
+ ld [hJoy7],a
+ ld [wcd3a],a
+ ld [wcd3b],a
+=======
+ ld [$ffb7],a
+ ld [wWastedByteCD3A],a
+ ld [wOverrideSimulatedJoypadStatesMask],a
+>>>>>>> yama/master
+ pop af
+ ld [wListScrollOffset],a
+ call GBPalWhiteOutWithDelay3
+ call GoPAL_SET_CF1C
+ jp ReloadMapData
+.goToSideMenu
+ call HandlePokedexSideMenu
+ dec b
+ jr z,.exitPokedex ; if the player chose Quit
+ dec b
+ jr z,.doPokemonListMenu ; if pokemon not seen or player pressed B button
+ jp .setUpGraphics ; if pokemon data or area was shown
+
+; handles the menu on the lower right in the pokedex screen
+; OUTPUT:
+; b = reason for exiting menu
+; 00: showed pokemon data or area
+; 01: the player chose Quit
+; 02: the pokemon has not been seen yet or the player pressed the B button
+HandlePokedexSideMenu: ; 4006d (10:406d)
+ call PlaceUnfilledArrowMenuCursor
+ ld a,[wCurrentMenuItem]
+ push af
+ ld b,a
+ ld a,[wLastMenuItem]
+ push af
+ ld a,[wListScrollOffset]
+ push af
+ add b
+ inc a
+ ld [wd11e],a
+ ld a,[wd11e]
+ push af
+ ld a,[wWhichTrade]
+ push af
+ ld hl,wPokedexSeen
+ call IsPokemonBitSet
+ ld b,2
+ jr z,.exitSideMenu
+ call PokedexToIndex
+ ld hl,wTopMenuItemY
+ ld a,10
+ ld [hli],a ; top menu item Y
+ ld a,15
+ ld [hli],a ; top menu item X
+ xor a
+ ld [hli],a ; current menu item ID
+ inc hl
+ ld a,3
+ ld [hli],a ; max menu item ID
+ ld [hli],a ; menu watched keys (A button and B button)
+ xor a
+ ld [hli],a ; old menu item ID
+ ld [wcc37],a
+.handleMenuInput
+ call HandleMenuInput
+ bit 1,a ; was the B button pressed?
+ ld b,2
+ jr nz,.buttonBPressed
+ ld a,[wCurrentMenuItem]
+ and a
+ jr z,.choseData
+ dec a
+ jr z,.choseCry
+ dec a
+ jr z,.choseArea
+.choseQuit
+ ld b,1
+.exitSideMenu
+ pop af
+ ld [wWhichTrade],a
+ pop af
+ ld [wd11e],a
+ pop af
+ ld [wListScrollOffset],a
+ pop af
+ ld [wLastMenuItem],a
+ pop af
+ ld [wCurrentMenuItem],a
+ push bc
+ hlCoord 0, 3
+ ld de,20
+ ld bc,$7f0d ; 13 blank tiles
+ call DrawTileLine ; cover up the menu cursor in the pokemon list
+ pop bc
+ ret
+.buttonBPressed
+ push bc
+ hlCoord 15, 10
+ ld de,20
+ ld bc,$7f07 ; 7 blank tiles
+ call DrawTileLine ; cover up the menu cursor in the side menu
+ pop bc
+ jr .exitSideMenu
+.choseData
+ call ShowPokedexDataInternal
+ ld b,0
+ jr .exitSideMenu
+; play pokemon cry
+.choseCry
+ ld a,[wd11e]
+ call GetCryData ; get cry data
+ call PlaySound ; play sound
+ jr .handleMenuInput
+.choseArea
+ predef LoadTownMap_Nest ; display pokemon areas
+ ld b,0
+ jr .exitSideMenu
+
+; handles the list of pokemon on the left of the pokedex screen
+; sets carry flag if player presses A, unsets carry flag if player presses B
+HandlePokedexListMenu: ; 40111 (10:4111)
+ xor a
+ ld [H_AUTOBGTRANSFERENABLED],a
+; draw the horizontal line separating the seen and owned amounts from the menu
+ hlCoord 15, 8
+ ld a,$7a ; horizontal line tile
+ ld [hli],a
+ ld [hli],a
+ ld [hli],a
+ ld [hli],a
+ ld [hli],a
+ hlCoord 14, 0
+ ld [hl],$71 ; vertical line tile
+ hlCoord 14, 1
+ call DrawPokedexVerticalLine
+ hlCoord 14, 9
+ call DrawPokedexVerticalLine
+ ld hl,wPokedexSeen
+ ld b,wPokedexSeenEnd - wPokedexSeen
+ call CountSetBits
+ ld de,wd11e
+ hlCoord 16, 3
+ ld bc,$0103
+ call PrintNumber ; print number of seen pokemon
+ ld hl,wPokedexOwned
+ ld b,wPokedexOwnedEnd - wPokedexOwned
+ call CountSetBits
+ ld de,wd11e
+ hlCoord 16, 6
+ ld bc,$0103
+ call PrintNumber ; print number of owned pokemon
+ hlCoord 16, 2
+ ld de,PokedexSeenText
+ call PlaceString
+ hlCoord 16, 5
+ ld de,PokedexOwnText
+ call PlaceString
+ hlCoord 1, 1
+ ld de,PokedexContentsText
+ call PlaceString
+ hlCoord 16, 10
+ ld de,PokedexMenuItemsText
+ call PlaceString
+; find the highest pokedex number among the pokemon the player has seen
+ ld hl,wPokedexSeenEnd - 1
+ ld b,153
+.maxSeenPokemonLoop
+ ld a,[hld]
+ ld c,8
+.maxSeenPokemonInnerLoop
+ dec b
+ sla a
+ jr c,.storeMaxSeenPokemon
+ dec c
+ jr nz,.maxSeenPokemonInnerLoop
+ jr .maxSeenPokemonLoop
+.storeMaxSeenPokemon
+ ld a,b
+ ld [wWhichTrade],a ; max seen pokemon
+.loop
+ xor a
+ ld [H_AUTOBGTRANSFERENABLED],a
+ hlCoord 4, 2
+ ld bc,$0e0a
+ call ClearScreenArea
+ hlCoord 1, 3
+ ld a,[wListScrollOffset]
+ ld [wd11e],a
+ ld d,7
+ ld a,[wWhichTrade]
+ cp a,7
+ jr nc,.printPokemonLoop
+ ld d,a
+ dec a
+ ld [wMaxMenuItem],a
+; loop to print pokemon pokedex numbers and names
+; if the player has owned the pokemon, it puts a pokeball beside the name
+.printPokemonLoop
+ ld a,[wd11e]
+ inc a
+ ld [wd11e],a
+ push af
+ push de
+ push hl
+ ld de,-20
+ add hl,de
+ ld de,wd11e
+ ld bc,$8103
+ call PrintNumber ; print the pokedex number
+ ld de,20
+ add hl,de
+ dec hl
+ push hl
+ ld hl,wPokedexOwned
+ call IsPokemonBitSet
+ pop hl
+ ld a," "
+ jr z,.writeTile
+ ld a,$72 ; pokeball tile
+.writeTile
+ ld [hl],a ; put a pokeball next to pokemon that the player has owned
+ push hl
+ ld hl,wPokedexSeen
+ call IsPokemonBitSet
+ jr nz,.getPokemonName ; if the player has seen the pokemon
+ ld de,.dashedLine ; print a dashed line in place of the name if the player hasn't seen the pokemon
+ jr .skipGettingName
+.dashedLine ; for unseen pokemon in the list
+ db "----------@"
+.getPokemonName
+ call PokedexToIndex
+ call GetMonName
+.skipGettingName
+ pop hl
+ inc hl
+ call PlaceString
+ pop hl
+ ld bc,2 * 20
+ add hl,bc
+ pop de
+ pop af
+ ld [wd11e],a
+ dec d
+ jr nz,.printPokemonLoop
+ ld a,01
+ ld [H_AUTOBGTRANSFERENABLED],a
+ call Delay3
+ call GBPalNormal
+ call HandleMenuInput
+ bit 1,a ; was the B button pressed?
+ jp nz,.buttonBPressed
+.checkIfUpPressed
+ bit 6,a ; was Up pressed?
+ jr z,.checkIfDownPressed
+.upPressed ; scroll up one row
+ ld a,[wListScrollOffset]
+ and a
+ jp z,.loop
+ dec a
+ ld [wListScrollOffset],a
+ jp .loop
+.checkIfDownPressed
+ bit 7,a ; was Down pressed?
+ jr z,.checkIfRightPressed
+.downPressed ; scroll down one row
+ ld a,[wWhichTrade]
+ cp a,7
+ jp c,.loop
+ sub a,7
+ ld b,a
+ ld a,[wListScrollOffset]
+ cp b
+ jp z,.loop
+ inc a
+ ld [wListScrollOffset],a
+ jp .loop
+.checkIfRightPressed
+ bit 4,a ; was Right pressed?
+ jr z,.checkIfLeftPressed
+.rightPressed ; scroll down 7 rows
+ ld a,[wWhichTrade]
+ cp a,7
+ jp c,.loop
+ sub a,6
+ ld b,a
+ ld a,[wListScrollOffset]
+ add a,7
+ ld [wListScrollOffset],a
+ cp b
+ jp c,.loop
+ dec b
+ ld a,b
+ ld [wListScrollOffset],a
+ jp .loop
+.checkIfLeftPressed ; scroll up 7 rows
+ bit 5,a ; was Left pressed?
+ jr z,.buttonAPressed
+.leftPressed
+ ld a,[wListScrollOffset]
+ sub a,7
+ ld [wListScrollOffset],a
+ jp nc,.loop
+ xor a
+ ld [wListScrollOffset],a
+ jp .loop
+.buttonAPressed
+ scf
+ ret
+.buttonBPressed
+ and a
+ ret
+
+DrawPokedexVerticalLine: ; 4028e (10:428e)
+ ld c,9 ; height of line
+ ld de,20 ; width of screen
+ ld a,$71 ; vertical line tile
+.loop
+ ld [hl],a
+ add hl,de
+ xor a,1 ; toggle between vertical line tile and box tile
+ dec c
+ jr nz,.loop
+ ret
+
+PokedexSeenText: ; 4029d (10:429d)
+ db "SEEN@"
+
+PokedexOwnText: ; 402a2 (10:42a2)
+ db "OWN@"
+
+PokedexContentsText: ; 402a6 (10:42a6)
+ db "CONTENTS@"
+
+PokedexMenuItemsText: ; 402af (10:42af)
+ db "DATA"
+ next "CRY"
+ next "AREA"
+ next "QUIT@"
+
+; tests if a pokemon's bit is set in the seen or owned pokemon bit fields
+; INPUT:
+; [wd11e] = pokedex number
+; hl = address of bit field
+IsPokemonBitSet: ; 402c2 (10:42c2)
+ ld a,[wd11e]
+ dec a
+ ld c,a
+ ld b,2
+ predef FlagActionPredef
+ ld a,c
+ and a
+ ret
+
+; function to display pokedex data from outside the pokedex
+ShowPokedexData: ; 402d1 (10:42d1)
+ call GBPalWhiteOutWithDelay3
+ call ClearScreen
+ call UpdateSprites
+ callab LoadPokedexTilePatterns ; load pokedex tiles
+
+; function to display pokedex data from inside the pokedex
+ShowPokedexDataInternal: ; 402e2 (10:42e2)
+ ld hl,wd72c
+ set 1,[hl]
+ ld a,$33 ; 3/7 volume
+ ld [$ff24],a
+ call GBPalWhiteOut ; zero all palettes
+ call ClearScreen
+ ld a,[wd11e] ; pokemon ID
+ ld [wcf91],a
+ push af
+ ld b,04
+ call GoPAL_SET
+ pop af
+ ld [wd11e],a
+ ld a,[hTilesetType]
+ push af
+ xor a
+ ld [hTilesetType],a
+ hlCoord 0, 0
+ ld de,1
+ ld bc,$6414
+ call DrawTileLine ; draw top border
+ hlCoord 0, 17
+ ld b,$6f
+ call DrawTileLine ; draw bottom border
+ hlCoord 0, 1
+ ld de,20
+ ld bc,$6610
+ call DrawTileLine ; draw left border
+ hlCoord 19, 1
+ ld b,$67
+ call DrawTileLine ; draw right border
+ ld a,$63 ; upper left corner tile
+ Coorda 0, 0
+ ld a,$65 ; upper right corner tile
+ Coorda 19, 0
+ ld a,$6c ; lower left corner tile
+ Coorda 0, 17
+ ld a,$6e ; lower right corner tile
+ Coorda 19, 17
+ hlCoord 0, 9
+ ld de,PokedexDataDividerLine
+ call PlaceString ; draw horizontal divider line
+ hlCoord 9, 6
+ ld de,HeightWeightText
+ call PlaceString
+ call GetMonName
+ hlCoord 9, 2
+ call PlaceString
+ ld hl,PokedexEntryPointers
+ ld a,[wd11e]
+ dec a
+ ld e,a
+ ld d,0
+ add hl,de
+ add hl,de
+ ld a,[hli]
+ ld e,a
+ ld d,[hl] ; de = address of pokedex entry
+ hlCoord 9, 4
+ call PlaceString ; print species name
+ ld h,b
+ ld l,c
+ push de
+ ld a,[wd11e]
+ push af
+ call IndexToPokedex
+ hlCoord 2, 8
+ ld a, "№"
+ ld [hli],a
+ ld a,$f2
+ ld [hli],a
+ ld de,wd11e
+ ld bc,$8103
+ call PrintNumber ; print pokedex number
+ ld hl,wPokedexOwned
+ call IsPokemonBitSet
+ pop af
+ ld [wd11e],a
+ ld a,[wcf91]
+ ld [wd0b5],a
+ pop de
+ push af
+ push bc
+ push de
+ push hl
+ call Delay3
+ call GBPalNormal
+ call GetMonHeader ; load pokemon picture location
+ hlCoord 1, 1
+ call LoadFlippedFrontSpriteByMonIndex ; draw pokemon picture
+ ld a,[wcf91]
+ call PlayCry ; play pokemon cry
+ pop hl
+ pop de
+ pop bc
+ pop af
+ ld a,c
+ and a
+ jp z,.waitForButtonPress ; if the pokemon has not been owned, don't print the height, weight, or description
+ inc de ; de = address of feet (height)
+ ld a,[de] ; reads feet, but a is overwritten without being used
+ hlCoord 12, 6
+ ld bc,$0102
+ call PrintNumber ; print feet (height)
+ ld a,$60 ; feet symbol tile (one tick)
+ ld [hl],a
+ inc de
+ inc de ; de = address of inches (height)
+ hlCoord 15, 6
+ ld bc,$8102
+ call PrintNumber ; print inches (height)
+ ld a,$61 ; inches symbol tile (two ticks)
+ ld [hl],a
+; now print the weight (note that weight is stored in tenths of pounds internally)
+ inc de
+ inc de
+ inc de ; de = address of upper byte of weight
+ push de
+; put weight in big-endian order at $ff8b
+ ld hl,$ff8b
+ ld a,[hl] ; save existing value of [$ff8b]
+ push af
+ ld a,[de] ; a = upper byte of weight
+ ld [hli],a ; store upper byte of weight in [$ff8b]
+ ld a,[hl] ; save existing value of [$ff8c]
+ push af
+ dec de
+ ld a,[de] ; a = lower byte of weight
+ ld [hl],a ; store lower byte of weight in [$ff8c]
+ ld de,$ff8b
+ hlCoord 11, 8
+ ld bc,$0205 ; no leading zeroes, right-aligned, 2 bytes, 5 digits
+ call PrintNumber ; print weight
+ hlCoord 14, 8
+ ld a,[$ff8c]
+ sub a,10
+ ld a,[$ff8b]
+ sbc a,0
+ jr nc,.next
+ ld [hl],"0" ; if the weight is less than 10, put a 0 before the decimal point
+.next
+ inc hl
+ ld a,[hli]
+ ld [hld],a ; make space for the decimal point by moving the last digit forward one tile
+ ld [hl],$f2 ; decimal point tile
+ pop af
+ ld [$ff8c],a ; restore original value of [$ff8c]
+ pop af
+ ld [$ff8b],a ; restore original value of [$ff8b]
+ pop hl
+ inc hl ; hl = address of pokedex description text
+ bcCoord 1, 11
+ ld a,2
+ ld [$fff4],a
+ call TextCommandProcessor ; print pokedex description text
+ xor a
+ ld [$fff4],a
+.waitForButtonPress
+ call JoypadLowSensitivity
+ ld a,[hJoy5]
+ and a,%00000011 ; A button and B button
+ jr z,.waitForButtonPress
+ pop af
+ ld [hTilesetType],a
+ call GBPalWhiteOut
+ call ClearScreen
+ call GoPAL_SET_CF1C
+ call LoadTextBoxTilePatterns
+ call GBPalNormal
+ ld hl,wd72c
+ res 1,[hl]
+ ld a,$77 ; max volume
+ ld [$ff24],a
+ ret
+
+HeightWeightText: ; 40448 (10:4448)
+ db "HT ?",$60,"??",$61,$4E,"WT ???lb@"
+
+; XXX does anything point to this?
+Unknown_4045D: ; 4045d (10:445d)
+ db $54,$50
+
+; horizontal line that divides the pokedex text description from the rest of the data
+PokedexDataDividerLine: ; 4045f (10:445f)
+ db $68,$69,$6B,$69,$6B
+ db $69,$6B,$69,$6B,$6B
+ db $6B,$6B,$69,$6B,$69
+ db $6B,$69,$6B,$69,$6A
+ db $50
+
+; draws a line of tiles
+; INPUT:
+; b = tile ID
+; c = number of tile ID's to write
+; de = amount to destination address after each tile (1 for horizontal, 20 for vertical)
+; hl = destination address
+DrawTileLine: ; 40474 (10:4474)
+ push bc
+ push de
+.loop
+ ld [hl],b
+ add hl,de
+ dec c
+ jr nz,.loop
+ pop de
+ pop bc
+ ret
+
+INCLUDE "data/pokedex_entries.asm"
+
+PokedexToIndex: ; 40ff9 (10:4ff9)
+ ; converts the Pokédex number at wd11e to an index
+ push bc
+ push hl
+ ld a,[wd11e]
+ ld b,a
+ ld c,0
+ ld hl,PokedexOrder
+
+.loop ; go through the list until we find an entry with a matching dex number
+ inc c
+ ld a,[hli]
+ cp b
+ jr nz,.loop
+
+ ld a,c
+ ld [wd11e],a
+ pop hl
+ pop bc
+ ret
+
+IndexToPokedex: ; 41010 (10:5010)
+ ; converts the indexédex number at wd11e to a Pokédex number
+ push bc
+ push hl
+ ld a,[wd11e]
+ dec a
+ ld hl,PokedexOrder
+ ld b,0
+ ld c,a
+ add hl,bc
+ ld a,[hl]
+ ld [wd11e],a
+ pop hl
+ pop bc
+ ret
+
+INCLUDE "data/pokedex_order.asm"
diff --git a/engine/menu/start_menu.asm b/engine/menu/start_menu.asm
index be172a67..da17822b 100755
--- a/engine/menu/start_menu.asm
+++ b/engine/menu/start_menu.asm
@@ -2,8 +2,8 @@ DisplayStartMenu:: ; 2acd (0:2acd)
ld a,$04 ; hardcoded Bank, not sure what's it refers to
ld [H_LOADEDROMBANK],a
ld [$2000],a ; ROM bank 4
- ld a,[wd700] ; walking/biking/surfing
- ld [wd11a],a
+ ld a,[wWalkBikeSurfState] ; walking/biking/surfing
+ ld [wWalkBikeSurfStateCopy],a
ld a, (SFX_02_3f - SFX_Headers_02) / 3 ; Start menu sound
call PlaySound
diff --git a/engine/menu/start_sub_menus.asm b/engine/menu/start_sub_menus.asm
index 7c6fe4d6..c6373e76 100755
--- a/engine/menu/start_sub_menus.asm
+++ b/engine/menu/start_sub_menus.asm
@@ -11,21 +11,21 @@ StartMenu_Pokemon: ; 130a9 (4:70a9)
and a
jp z,RedisplayStartMenu
xor a
- ld [wcc35],a
+ ld [wMenuItemToSwap],a
ld [wd07d],a
- ld [wcfcb],a
+ ld [wUpdateSpritesEnabled],a
call DisplayPartyMenu
jr .checkIfPokemonChosen
.loop
xor a
- ld [wcc35],a
+ ld [wMenuItemToSwap],a
ld [wd07d],a
call GoBackToPartyMenu
.checkIfPokemonChosen
jr nc,.chosePokemon
.exitMenu
call GBPalWhiteOutWithDelay3
- call Func_3dbe
+ call RestoreScreenTilesAndReloadTilePatterns
call LoadGBPal
jp RedisplayStartMenu
.chosePokemon
@@ -184,7 +184,7 @@ StartMenu_Pokemon: ; 130a9 (4:70a9)
bit 0,a ; does the player have the Boulder Badge?
jp z,.newBadgeRequired
xor a
- ld [wd35d],a
+ ld [wMapPalOffset],a
ld hl,.flashLightsAreaText
call PrintText
call GBPalWhiteOutWithDelay3
@@ -273,7 +273,7 @@ StartMenu_Pokemon: ; 130a9 (4:70a9)
TX_FAR _NotHealthyEnoughText
db "@"
.goBackToMap
- call Func_3dbe
+ call RestoreScreenTilesAndReloadTilePatterns
jp CloseTextDisplay
.newBadgeRequired
ld hl,.newBadgeRequiredText
@@ -336,7 +336,7 @@ StartMenu_Item: ; 13302 (4:7302)
Coorda 5, 10
call PlaceUnfilledArrowMenuCursor
xor a
- ld [wcc35],a
+ ld [wMenuItemToSwap],a
ld a,[wcf91]
cp a,BICYCLE
jp z,.useOrTossItem
@@ -406,20 +406,20 @@ StartMenu_Item: ; 13302 (4:7302)
jp z,ItemMenuLoop
jp CloseStartMenu
.useItem_partyMenu
- ld a,[wcfcb]
+ ld a,[wUpdateSpritesEnabled]
push af
call UseItem
ld a,[wcd6a]
cp a,$02
jp z,.partyMenuNotDisplayed
call GBPalWhiteOutWithDelay3
- call Func_3dbe
+ call RestoreScreenTilesAndReloadTilePatterns
pop af
- ld [wcfcb],a
+ ld [wUpdateSpritesEnabled],a
jp StartMenu_Item
.partyMenuNotDisplayed
pop af
- ld [wcfcb],a
+ ld [wUpdateSpritesEnabled],a
jp ItemMenuLoop
.tossItem
call IsKeyItem
@@ -500,10 +500,10 @@ StartMenu_TrainerInfo: ; 13460 (4:7460)
call GBPalWhiteOut
call ClearScreen
call UpdateSprites ; move sprites
- ld a,[$ffd7]
+ ld a,[hTilesetType]
push af
xor a
- ld [$ffd7],a
+ ld [hTilesetType],a
call DrawTrainerInfo
predef DrawBadges ; draw badges
ld b,$0d
@@ -517,7 +517,7 @@ StartMenu_TrainerInfo: ; 13460 (4:7460)
call ReloadMapData
call LoadGBPal
pop af
- ld [$ffd7],a
+ ld [hTilesetType],a
jp RedisplayStartMenu
; loads tile patterns and draws everything except for gym leader faces / badges
@@ -738,17 +738,17 @@ SwitchPartyMon_OAM: ; 13625 (4:7625)
jp PlaySound
SwitchPartyMon_Stats: ; 13653 (4:7653)
- ld a, [wcc35]
+ ld a, [wMenuItemToSwap]
and a
jr nz, .asm_13661
ld a, [wWhichPokemon] ; wWhichPokemon
inc a
- ld [wcc35], a
+ ld [wMenuItemToSwap], a
ret
.asm_13661
xor a
ld [wd07d], a
- ld a, [wcc35]
+ ld a, [wMenuItemToSwap]
dec a
ld b, a
ld a, [wCurrentMenuItem] ; wCurrentMenuItem
@@ -756,12 +756,12 @@ SwitchPartyMon_Stats: ; 13653 (4:7653)
cp b
jr nz, .asm_1367b
xor a
- ld [wcc35], a
+ ld [wMenuItemToSwap], a
ld [wd07d], a
ret
.asm_1367b
ld a, b
- ld [wcc35], a
+ ld [wMenuItemToSwap], a
push hl
push de
ld hl, wPartySpecies
@@ -773,7 +773,7 @@ SwitchPartyMon_Stats: ; 13653 (4:7653)
jr nc, .asm_1368e
inc h
.asm_1368e
- ld a, [wcc35]
+ ld a, [wMenuItemToSwap]
add e
ld e, a
jr nc, .asm_13696
@@ -790,61 +790,61 @@ SwitchPartyMon_Stats: ; 13653 (4:7653)
ld a, [wCurrentMenuItem] ; wCurrentMenuItem
call AddNTimes
push hl
- ld de, wcc97
+ ld de, wSwitchPartyMonTempBuffer
ld bc, $2c
call CopyData
ld hl, wPartyMons
ld bc, $2c
- ld a, [wcc35]
+ ld a, [wMenuItemToSwap]
call AddNTimes
pop de
push hl
ld bc, $2c
call CopyData
pop de
- ld hl, wcc97
+ ld hl, wSwitchPartyMonTempBuffer
ld bc, $2c
call CopyData
ld hl, wPartyMonOT ; wd273
ld a, [wCurrentMenuItem] ; wCurrentMenuItem
call SkipFixedLengthTextEntries
push hl
- ld de, wcc97
+ ld de, wSwitchPartyMonTempBuffer
ld bc, $b
call CopyData
ld hl, wPartyMonOT ; wd273
- ld a, [wcc35]
+ ld a, [wMenuItemToSwap]
call SkipFixedLengthTextEntries
pop de
push hl
ld bc, $b
call CopyData
pop de
- ld hl, wcc97
+ ld hl, wSwitchPartyMonTempBuffer
ld bc, $b
call CopyData
ld hl, wPartyMonNicks ; wPartyMonNicks
ld a, [wCurrentMenuItem] ; wCurrentMenuItem
call SkipFixedLengthTextEntries
push hl
- ld de, wcc97
+ ld de, wSwitchPartyMonTempBuffer
ld bc, $b
call CopyData
ld hl, wPartyMonNicks ; wPartyMonNicks
- ld a, [wcc35]
+ ld a, [wMenuItemToSwap]
call SkipFixedLengthTextEntries
pop de
push hl
ld bc, $b
call CopyData
pop de
- ld hl, wcc97
+ ld hl, wSwitchPartyMonTempBuffer
ld bc, $b
call CopyData
- ld a, [wcc35]
+ ld a, [wMenuItemToSwap]
ld [wWhichTrade], a ; wWhichTrade
xor a
- ld [wcc35], a
+ ld [wMenuItemToSwap], a
ld [wd07d], a
pop de
pop hl
diff --git a/engine/menu/status_screen.asm b/engine/menu/status_screen.asm
index 65b06e9d..f215fd0e 100755
--- a/engine/menu/status_screen.asm
+++ b/engine/menu/status_screen.asm
@@ -36,10 +36,10 @@ StatusScreen: ; 12953 (4:6953)
ld hl, vChars2 + $720
ld bc,(BANK(PTile) << 8 | $01)
call CopyVideoDataDouble ; P (for PP), inline
- ld a, [$ffd7]
+ ld a, [hTilesetType]
push af
xor a
- ld [$ffd7], a
+ ld [hTilesetType], a
hlCoord 19, 1
ld bc, $060a
call DrawLineBox ; Draws the box around name, HP and status
@@ -109,7 +109,7 @@ StatusScreen: ; 12953 (4:6953)
call PlayCry ; play Pokémon cry
call WaitForTextScrollButtonPress ; wait for button
pop af
- ld [$ffd7], a
+ ld [hTilesetType], a
ret
.unk_12a7e ; 0x12a7e ; I don't know what this does, iterates over pointers?
ld a, [wcc49]
@@ -227,10 +227,10 @@ StatsText: ; 12b3a (4:6b3a)
next "SPECIAL@"
StatusScreen2: ; 12b57 (4:6b57)
- ld a, [$ffd7]
+ ld a, [hTilesetType]
push af
xor a
- ld [$ffd7], a
+ ld [hTilesetType], a
ld [$ffba], a
ld bc, $0005
ld hl, wd0dc
@@ -360,7 +360,7 @@ StatusScreen2: ; 12b57 (4:6b57)
call Delay3
call WaitForTextScrollButtonPress ; wait for button
pop af
- ld [$ffd7], a
+ ld [hTilesetType], a
ld hl, wd72c
res 1, [hl]
ld a, $77
diff --git a/engine/mon_party_sprites.asm b/engine/mon_party_sprites.asm
index e05bdd55..5fa5c3bc 100755
--- a/engine/mon_party_sprites.asm
+++ b/engine/mon_party_sprites.asm
@@ -21,7 +21,7 @@ GetAnimationSpeed: ; 7170a (1c:570a)
ld c, a
ld hl, PartyMonSpeeds
add hl, bc
- ld a, [wcf1b]
+ ld a, [wOnSGB]
xor $1
add [hl]
ld c, a
diff --git a/engine/oak_speech.asm b/engine/oak_speech.asm
index e54741f2..0cbdaa3d 100755
--- a/engine/oak_speech.asm
+++ b/engine/oak_speech.asm
@@ -49,10 +49,10 @@ OakSpeech: ; 6115 (1:6115)
ld [wcf96],a
call AddItemToInventory ; give one potion
ld a,[W_ANIMATIONID]
- ld [wd71a],a
- call Func_62ce
+ ld [wDestinationMap],a
+ call SpecialWarpIn
xor a
- ld [$FFD7],a
+ ld [hTilesetType],a
ld a,[wd732]
bit 1,a ; XXX when is bit 1 set?
jp nz,Func_61bc ; easter egg: skip the intro
@@ -62,7 +62,7 @@ OakSpeech: ; 6115 (1:6115)
call FadeInIntroPic
ld hl,OakSpeechText1
call PrintText ; prints text box
- call GBFadeOut2
+ call GBFadeOutToWhite
call ClearScreen
ld a,NIDORINO
ld [wd0b5],a ; pic displayed is stored at this location
@@ -73,7 +73,7 @@ OakSpeech: ; 6115 (1:6115)
call MovePicLeft
ld hl,OakSpeechText2
call PrintText ; Prints text box
- call GBFadeOut2
+ call GBFadeOutToWhite
call ClearScreen
ld de,RedPicFront
ld bc,(Bank(RedPicFront) << 8) | $00
@@ -82,7 +82,7 @@ OakSpeech: ; 6115 (1:6115)
ld hl,IntroducePlayerText
call PrintText
call LoadDefaultNamesPlayer ; brings up NewName/Red/etc menu
- call GBFadeOut2
+ call GBFadeOutToWhite
call ClearScreen
ld de,Rival1Pic
ld bc,(Bank(Rival1Pic) << 8) | $00
@@ -93,12 +93,12 @@ OakSpeech: ; 6115 (1:6115)
call LoadDefaultNamesRival
Func_61bc: ; 61bc (1:61bc)
- call GBFadeOut2
+ call GBFadeOutToWhite
call ClearScreen
ld de,RedPicFront
ld bc,(Bank(RedPicFront) << 8) | $00
call IntroPredef3B
- call GBFadeIn2
+ call GBFadeInFromWhite
ld a,[wd72d]
and a
jr nz,.next
@@ -148,10 +148,10 @@ Func_61bc: ; 61bc (1:61bc)
call ClearScreenArea
call LoadTextBoxTilePatterns
ld a,1
- ld [wcfcb],a
+ ld [wUpdateSpritesEnabled],a
ld c,$32
call DelayFrames
- call GBFadeOut2
+ call GBFadeOutToWhite
jp ClearScreen
OakSpeechText1: ; 6253 (1:6253)
TX_FAR _OakSpeechText1
diff --git a/engine/overworld/cable_club_npc.asm b/engine/overworld/cable_club_npc.asm
index 9ae5b508..d071eee5 100755
--- a/engine/overworld/cable_club_npc.asm
+++ b/engine/overworld/cable_club_npc.asm
@@ -24,7 +24,7 @@ Func_71e1: ; 71e1 (1:71e1)
ld a, $ff
ld [$ffaa], a
ld a, $2
- ld [$ff01], a
+ ld [rSB], a
xor a
ld [$ffad], a
ld a, $80
@@ -34,7 +34,7 @@ Func_71e1: ; 71e1 (1:71e1)
ld [wcc47], a
jr z, .asm_7287 ; 0x720b $7a
ld a, $1
- ld [$ff01], a
+ ld [rSB], a
ld a, $81
ld [$ff02], a
call DelayFrame
@@ -148,7 +148,7 @@ Func_72d7: ; 72d7 (1:72d7)
ld a, $ff
ld [$ffaa], a
ld a, $2
- ld [$ff01], a
+ ld [rSB], a
xor a
ld [$ffad], a
ld a, $80
diff --git a/engine/overworld/card_key.asm b/engine/overworld/card_key.asm
index f48c26f4..c4df0d51 100755
--- a/engine/overworld/card_key.asm
+++ b/engine/overworld/card_key.asm
@@ -2,18 +2,18 @@ PrintCardKeyText: ; 52673 (14:6673)
ld hl, SilphCoMapList
ld a, [W_CURMAP]
ld b, a
-.asm_5267a
+.silphCoMapListLoop
ld a, [hli]
cp $ff
ret z
cp b
- jr nz, .asm_5267a
- predef Func_c586
- ld a, [wcfc6]
+ jr nz, .silphCoMapListLoop
+ predef GetTileAndCoordsInFrontOfPlayer
+ ld a, [wTileInFrontOfPlayer]
cp $18
- jr z, .asm_5269c
+ jr z, .cardKeyDoorInFrontOfPlayer
cp $24
- jr z, .asm_5269c
+ jr z, .cardKeyDoorInFrontOfPlayer
ld b, a
ld a, [W_CURMAP]
cp SILPH_CO_11F
@@ -21,41 +21,41 @@ PrintCardKeyText: ; 52673 (14:6673)
ld a, b
cp $5e
ret nz
-.asm_5269c
+.cardKeyDoorInFrontOfPlayer
ld b, CARD_KEY
call IsItemInBag
- jr z, .asm_526dc
- call Func_526fd
+ jr z, .noCardKey
+ call GetCoordsInFrontOfPlayer
push de
ld a, $1
- ld [H_DOWNARROWBLINKCNT2], a ; $ff8c
+ ld [H_DOWNARROWBLINKCNT2], a
call PrintPredefTextID
pop de
srl d
ld a, d
ld b, a
- ld [wd73f], a
+ ld [wCardKeyDoorY], a
srl e
ld a, e
ld c, a
- ld [wd740], a
- ld a, [W_CURMAP] ; W_CURMAP
+ ld [wCardKeyDoorX], a
+ ld a, [W_CURMAP]
cp SILPH_CO_11F
- jr nz, .asm_526c8
+ jr nz, .notSilphCo11F
ld a, $3
- jr .asm_526ca
-.asm_526c8
+ jr .replaceCardKeyDoorTileBlock
+.notSilphCo11F
ld a, $e
-.asm_526ca
+.replaceCardKeyDoorTileBlock
ld [wd09f], a
- predef Func_ee9e
+ predef ReplaceTileBlock
ld hl, wd126
set 5, [hl]
ld a, (SFX_1f_57 - SFX_Headers_1f) / 3
jp PlaySound
-.asm_526dc
+.noCardKey
ld a, $2
- ld [H_DOWNARROWBLINKCNT2], a ; $ff8c
+ ld [H_DOWNARROWBLINKCNT2], a
jp PrintPredefTextID
SilphCoMapList: ; 526e3 (14:66e3)
@@ -81,26 +81,32 @@ CardKeyFailText: ; 526f8 (14:66f8)
TX_FAR _CardKeyFailText
db "@"
-Func_526fd: ; 526fd (14:66fd)
- ld a, [W_YCOORD] ; wd361
+; d = Y
+; e = X
+GetCoordsInFrontOfPlayer: ; 526fd (14:66fd)
+ ld a, [W_YCOORD]
ld d, a
- ld a, [W_XCOORD] ; wd362
+ ld a, [W_XCOORD]
ld e, a
- ld a, [wSpriteStateData1 + 9]
+ ld a, [wSpriteStateData1 + 9] ; player's sprite facing direction
and a
- jr nz, .asm_5270d
+ jr nz, .notFacingDown
+; facing down
inc d
ret
-.asm_5270d
- cp $4
- jr nz, .asm_52713
+.notFacingDown
+ cp SPRITE_FACING_UP
+ jr nz, .notFacingUp
+; facing up
dec d
ret
-.asm_52713
- cp $8
- jr nz, .asm_52719
+.notFacingUp
+ cp SPRITE_FACING_LEFT
+ jr nz, .notFacingLeft
+; facing left
dec e
ret
-.asm_52719
+.notFacingLeft
+; facing right
inc e
ret
diff --git a/engine/overworld/cut.asm b/engine/overworld/cut.asm
index 29b52eb9..f57b6465 100755
--- a/engine/overworld/cut.asm
+++ b/engine/overworld/cut.asm
@@ -6,13 +6,13 @@ UsedCut: ; ef54 (3:6f54)
jr z, .asm_ef6b
cp GYM
jr nz, .asm_ef77
- ld a, [wcfc6]
+ ld a, [wTileInFrontOfPlayer]
cp $50 ; gym cut tree
jr nz, .asm_ef77
jr asm_ef82
.asm_ef6b
dec a
- ld a, [wcfc6]
+ ld a, [wTileInFrontOfPlayer]
cp $3d ; cut tree
jr z, asm_ef82
cp $52 ; grass
@@ -36,36 +36,36 @@ asm_ef82: ; ef82 (3:6f82)
set 6, [hl]
call GBPalWhiteOutWithDelay3
call ClearSprites
- call Func_3dbe
+ call RestoreScreenTilesAndReloadTilePatterns
ld a, $90
- ld [$ffb0], a
+ ld [hVBlankWY], a
call Delay3
call LoadGBPal
call LoadCurrentMapView
call SaveScreenTilesToBuffer2
call Delay3
xor a
- ld [$ffb0], a
+ ld [hVBlankWY], a
ld hl, UsedCutText
call PrintText
call LoadScreenTilesFromBuffer2
ld hl, wd730
res 6, [hl]
ld a, $ff
- ld [wcfcb], a
+ ld [wUpdateSpritesEnabled], a
call AnimateCutTree
ld de, CutTreeBlockSwaps ; $7100
call Func_f09f
- call Func_eedc
+ call RedrawMapView
callba Func_79e96
ld a, $1
- ld [wcfcb], a
+ ld [wUpdateSpritesEnabled], a
ld a, (SFX_02_56 - SFX_Headers_02) / 3
call PlaySound
ld a, $90
- ld [$ffb0], a
+ ld [hVBlankWY], a
call UpdateSprites
- jp Func_eedc
+ jp RedrawMapView
UsedCutText: ; eff2 (3:6ff2)
TX_FAR _UsedCutText
@@ -87,17 +87,17 @@ AnimateCutTree: ; eff7 (3:6ff7)
ld hl, vChars1 + $7e0
ld bc, (BANK(Overworld_GFX) << 8) + $02
call CopyVideoData
- jr asm_f055
+ jr WriteCutTreeBoulderDustAnimationOAMBlock
.asm_f020
ld hl, vChars1 + $7c0
- call LoadCutTreeOAM
+ call LoadCutTreeAnimationTilePattern
ld hl, vChars1 + $7d0
- call LoadCutTreeOAM
+ call LoadCutTreeAnimationTilePattern
ld hl, vChars1 + $7e0
- call LoadCutTreeOAM
+ call LoadCutTreeAnimationTilePattern
ld hl, vChars1 + $7f0
- call LoadCutTreeOAM
- call asm_f055
+ call LoadCutTreeAnimationTilePattern
+ call WriteCutTreeBoulderDustAnimationOAMBlock
ld hl, wOAMBuffer + $93
ld de, $4
ld a, $30
@@ -110,26 +110,27 @@ AnimateCutTree: ; eff7 (3:6ff7)
jr nz, .asm_f044
ret
-LoadCutTreeOAM: ; f04c (3:704c)
+LoadCutTreeAnimationTilePattern: ; f04c (3:704c)
ld de, AnimationTileset2 + $60 ; $474e ; tile depicting a leaf
ld bc, (BANK(AnimationTileset2) << 8) + $01
jp CopyVideoData
-asm_f055: ; f055 (3:7055)
- call Func_f068
+
+WriteCutTreeBoulderDustAnimationOAMBlock: ; f055 (3:7055)
+ call GetCutTreeBoulderDustAnimationOffsets
ld a, $9
- ld de, CutTreeOAM ; $7060
+ ld de, CutTreeBoulderDustAnimationTilesAndAttributes
jp WriteOAMBlock
-CutTreeOAM: ; f060 (3:7060)
+CutTreeBoulderDustAnimationTilesAndAttributes: ; f060 (3:7060)
db $FC,$10,$FD,$10
db $FE,$10,$FF,$10
-Func_f068: ; f068 (3:7068)
+GetCutTreeBoulderDustAnimationOffsets: ; f068 (3:7068)
ld hl, wSpriteStateData1 + 4
- ld a, [hli]
+ ld a, [hli] ; player's sprite screen Y position
ld b, a
inc hl
- ld a, [hli]
+ ld a, [hli] ; player's sprite screen X position
ld c, a ; bc holds ypos/xpos of player's sprite
inc hl
inc hl
@@ -139,9 +140,9 @@ Func_f068: ; f068 (3:7068)
ld d, $0 ; de holds direction (00: down, 02: up, 04: left, 06: right)
ld a, [wcd50]
and a
- ld hl, CutTreeAnimationOffsets ; $708f
+ ld hl, CutTreeAnimationOffsets
jr z, .asm_f084
- ld hl, CutTreeAnimationOffsets2 ; $7097
+ ld hl, BoulderDustAnimationOffsets
.asm_f084
add hl, de
ld e, [hl]
@@ -162,8 +163,7 @@ CutTreeAnimationOffsets: ; f08f (3:708f)
db -8, 20 ; player is facing left
db 24, 20 ; player is facing right
-CutTreeAnimationOffsets2: ; f097 (3:7097)
-; Not sure if these ever get used. CutTreeAnimationOffsets only seems to be used.
+BoulderDustAnimationOffsets: ; f097 (3:7097)
; Each pair represents the x and y pixels offsets from the player of where the cut tree animation should be drawn
; These offsets represent 2 blocks away from the player
db 8, 52 ; player is facing down
@@ -178,7 +178,7 @@ Func_f09f: ; f09f (3:709f)
ld c, a
ld b, $0
ld d, $0
- ld hl, wd35f
+ ld hl, wCurrentTileBlockMapViewPointer
ld a, [hli]
ld h, [hl]
ld l, a
diff --git a/engine/overworld/cut2.asm b/engine/overworld/cut2.asm
index 08f6d651..de2b9d55 100755
--- a/engine/overworld/cut2.asm
+++ b/engine/overworld/cut2.asm
@@ -9,12 +9,12 @@ Func_79e96: ; 79e96 (1e:5e96)
ld a, $1
ld [wd08a], a
ld c, $2
- call Func_79339
+ call AdjustOAMBlockXPos2
ld hl, wOAMBuffer + $99
ld a, $ff
ld [wd08a], a
ld c, $2
- call Func_79339
+ call AdjustOAMBlockXPos2
ld a, [rOBP1] ; $ff49
xor $64
ld [rOBP1], a ; $ff49
@@ -37,7 +37,7 @@ Func_79e96: ; 79e96 (1e:5e96)
ld a, $2
ld [wd08a], a
ld c, $4
- call Func_79352
+ call AdjustOAMBlockYPos2
pop bc
dec c
jr nz, .asm_79eca
@@ -49,22 +49,22 @@ Func_79eed: ; 79eed (1e:5eed)
ld a, $1
ld [wd08a], a
ld c, $1
- call Func_79339
+ call AdjustOAMBlockXPos2
ld hl, wOAMBuffer + $95
ld a, $2
ld [wd08a], a
ld c, $1
- call Func_79339
+ call AdjustOAMBlockXPos2
ld hl, wOAMBuffer + $99
ld a, $fe
ld [wd08a], a
ld c, $1
- call Func_79339
+ call AdjustOAMBlockXPos2
ld hl, wOAMBuffer + $9d
ld a, $ff
ld [wd08a], a
ld c, $1
- call Func_79339
+ call AdjustOAMBlockXPos2
ld a, [rOBP1] ; $ff49
xor $64
ld [rOBP1], a ; $ff49
diff --git a/engine/overworld/doors.asm b/engine/overworld/doors.asm
index 42ebb174..ac345af9 100755
--- a/engine/overworld/doors.asm
+++ b/engine/overworld/doors.asm
@@ -1,26 +1,27 @@
-HandleDoors: ; 1a609 (6:6609)
+; returns whether the player is standing on a door tile in carry
+IsPlayerStandingOnDoorTile: ; 1a609 (6:6609)
push de
ld hl, DoorTileIDPointers ; $662c
ld a, [W_CURMAPTILESET] ; W_CURMAPTILESET
ld de, $3
call IsInArray
pop de
- jr nc, .asm_1a62a
+ jr nc, .notStandingOnDoor
inc hl
ld a, [hli]
ld h, [hl]
ld l, a
- aCoord 8, 9
+ aCoord 8, 9 ; a = lower left background tile under player's sprite
ld b, a
-.asm_1a621
+.loop
ld a, [hli]
and a
- jr z, .asm_1a62a
+ jr z, .notStandingOnDoor
cp b
- jr nz, .asm_1a621
+ jr nz, .loop
scf
ret
-.asm_1a62a
+.notStandingOnDoor
and a
ret
diff --git a/engine/overworld/elevator.asm b/engine/overworld/elevator.asm
index 10b3b003..c2191b91 100755
--- a/engine/overworld/elevator.asm
+++ b/engine/overworld/elevator.asm
@@ -38,10 +38,10 @@ ShakeElevator: ; 7bf15 (1e:7f15)
cp $b9
jr z, .asm_7bf57
call UpdateSprites
- jp Func_2307
+ jp PlayDefaultMusic
Func_7bf64: ; 7bf64 (1e:7f64)
- ld hl, wd527
+ ld hl, wMapViewVRAMPointer + 1
ld a, [hld]
push af
ld a, [hl]
diff --git a/engine/overworld/emotion_bubbles.asm b/engine/overworld/emotion_bubbles.asm
index ae7702b4..7106063b 100755
--- a/engine/overworld/emotion_bubbles.asm
+++ b/engine/overworld/emotion_bubbles.asm
@@ -11,10 +11,10 @@ EmotionBubble: ; 17c47 (5:7c47)
ld hl, vChars1 + $780
ld bc, (BANK(EmotionBubblesPointerTable) << 8) + $04
call CopyVideoData
- ld a, [wcfcb]
+ ld a, [wUpdateSpritesEnabled]
push af
ld a, $ff
- ld [wcfcb], a
+ ld [wUpdateSpritesEnabled], a
ld a, [wd736]
bit 6, a
ld hl, wOAMBuffer + $8f
@@ -51,7 +51,7 @@ EmotionBubble: ; 17c47 (5:7c47)
ld c, $3c
call DelayFrames
pop af
- ld [wcfcb], a
+ ld [wUpdateSpritesEnabled], a
call DelayFrame
jp UpdateSprites
diff --git a/engine/overworld/healing_machine.asm b/engine/overworld/healing_machine.asm
index 9c93583d..53174630 100755
--- a/engine/overworld/healing_machine.asm
+++ b/engine/overworld/healing_machine.asm
@@ -3,7 +3,7 @@ AnimateHealingMachine: ; 70433 (1c:4433)
ld hl, vChars0 + $7c0
ld bc, (BANK(PokeCenterFlashingMonitorAndHealBall) << 8) + $03
call CopyVideoData
- ld hl, wcfcb
+ ld hl, wUpdateSpritesEnabled
ld a, [hl]
push af
ld [hl], $ff
diff --git a/engine/overworld/hidden_items.asm b/engine/overworld/hidden_items.asm
index 77bd8fe6..befe2935 100755
--- a/engine/overworld/hidden_items.asm
+++ b/engine/overworld/hidden_items.asm
@@ -12,7 +12,7 @@ HiddenItems: ; 76688 (1d:6688)
ret nz
call EnableAutoTextBoxDrawing
ld a, $1
- ld [wcc3c], a
+ ld [wDoNotWaitForButtonPressAfterDisplayingText], a
ld a, [wWhichTrade] ; item ID
ld [wd11e], a
call GetItemName
@@ -42,7 +42,7 @@ FoundHiddenItemText: ; 7675b (1d:675b)
.BagFull
call WaitForTextScrollButtonPress ; wait for button press
xor a
- ld [wcc3c], a
+ ld [wDoNotWaitForButtonPressAfterDisplayingText], a
ld hl, HiddenItemBagFullText
call PrintText
jp TextScriptEnd
diff --git a/engine/overworld/hidden_objects.asm b/engine/overworld/hidden_objects.asm
index d2114293..ae67aeed 100755
--- a/engine/overworld/hidden_objects.asm
+++ b/engine/overworld/hidden_objects.asm
@@ -1,20 +1,21 @@
Func_46981: ; 46981 (11:6981)
xor a
- ld [wd71e], a
+ ld [wWhichDungeonWarp], a
ld a, [wd72d]
bit 4, a
ret nz
call ArePlayerCoordsInArray
ret nc
- ld a, [wWhichTrade] ; wWhichTrade
- ld [wd71e], a
+ ld a, [wWhichTrade]
+ ld [wWhichDungeonWarp], a
ld hl, wd72d
set 4, [hl]
ld hl, wd732
set 4, [hl]
ret
-Func_469a0: ; 469a0 (11:69a0)
+; if a hidden object was found, stores $00 in [$ffee], else stores $ff
+CheckForHiddenObject: ; 469a0 (11:69a0)
ld hl, $ffeb
xor a
ld [hli], a
@@ -22,107 +23,110 @@ Func_469a0: ; 469a0 (11:69a0)
ld [hli], a
ld [hl], a
ld de, $0
- ld hl, HiddenObjectMaps ; $6a40
-.asm_469ae
+ ld hl, HiddenObjectMaps
+.hiddenMapLoop
ld a, [hli]
ld b, a
cp $ff
- jr z, .asm_469fc
- ld a, [W_CURMAP] ; W_CURMAP
+ jr z, .noMatch
+ ld a, [W_CURMAP]
cp b
- jr z, .asm_469be
+ jr z, .foundMatchingMap
inc de
inc de
- jr .asm_469ae
-.asm_469be
- ld hl, HiddenObjectPointers ; $6a96
+ jr .hiddenMapLoop
+.foundMatchingMap
+ ld hl, HiddenObjectPointers
add hl, de
ld a, [hli]
ld h, [hl]
ld l, a
push hl
- ld hl, wWhichTrade ; wWhichTrade
+ ld hl, wHiddenObjectFunctionArgument
xor a
ld [hli], a
ld [hli], a
ld [hl], a
pop hl
-.asm_469ce
+.hiddenObjectLoop
ld a, [hli]
cp $ff
- jr z, .asm_469fc
- ld [wTrainerScreenY], a
+ jr z, .noMatch
+ ld [wHiddenObjectY], a
ld b, a
ld a, [hli]
- ld [wTrainerScreenX], a
+ ld [wHiddenObjectX], a
ld c, a
- call Func_46a01
+ call CheckIfCoordsInFrontOfPlayerMatch
ld a, [$ffea]
and a
- jr z, .asm_469f0
+ jr z, .foundMatchingObject
inc hl
inc hl
inc hl
inc hl
push hl
- ld hl, wTrainerFacingDirection
+ ld hl, wHiddenObjectIndex
inc [hl]
pop hl
- jr .asm_469ce
-.asm_469f0
+ jr .hiddenObjectLoop
+.foundMatchingObject
ld a, [hli]
- ld [wWhichTrade], a ; wWhichTrade
+ ld [wHiddenObjectFunctionArgument], a
ld a, [hli]
- ld [wTrainerEngageDistance], a
+ ld [wHiddenObjectFunctionRomBank], a
ld a, [hli]
ld h, [hl]
ld l, a
ret
-.asm_469fc
+.noMatch
ld a, $ff
ld [$ffee], a
ret
-Func_46a01: ; 46a01 (11:6a01)
- ld a, [wSpriteStateData1 + 9]
- cp $4
- jr z, .asm_46a16
- cp $8
- jr z, .asm_46a25
- cp $c
- jr z, .asm_46a2b
- ld a, [W_YCOORD] ; wd361
+; checks if the coordinates in front of the player's sprite match Y in b and X in c
+; [$ffea] = $00 if they match, $ff if they don't match
+CheckIfCoordsInFrontOfPlayerMatch: ; 46a01 (11:6a01)
+ ld a, [wSpriteStateData1 + 9] ; player's sprite facing direction
+ cp SPRITE_FACING_UP
+ jr z, .facingUp
+ cp SPRITE_FACING_LEFT
+ jr z, .facingLeft
+ cp SPRITE_FACING_RIGHT
+ jr z, .facingRight
+; facing down
+ ld a, [W_YCOORD]
inc a
- jr .asm_46a1a
-.asm_46a16
- ld a, [W_YCOORD] ; wd361
+ jr .upDownCommon
+.facingUp
+ ld a, [W_YCOORD]
dec a
-.asm_46a1a
+.upDownCommon
cp b
- jr nz, .asm_46a3b
- ld a, [W_XCOORD] ; wd362
+ jr nz, .didNotMatch
+ ld a, [W_XCOORD]
cp c
- jr nz, .asm_46a3b
- jr .asm_46a38
-.asm_46a25
- ld a, [W_XCOORD] ; wd362
+ jr nz, .didNotMatch
+ jr .matched
+.facingLeft
+ ld a, [W_XCOORD]
dec a
- jr .asm_46a2f
-.asm_46a2b
- ld a, [W_XCOORD] ; wd362
+ jr .leftRightCommon
+.facingRight
+ ld a, [W_XCOORD]
inc a
-.asm_46a2f
+.leftRightCommon
cp c
- jr nz, .asm_46a3b
- ld a, [W_YCOORD] ; wd361
+ jr nz, .didNotMatch
+ ld a, [W_YCOORD]
cp b
- jr nz, .asm_46a3b
-.asm_46a38
+ jr nz, .didNotMatch
+.matched
xor a
- jr .asm_46a3d
-.asm_46a3b
+ jr .done
+.didNotMatch
ld a, $ff
-.asm_46a3d
+.done
ld [$ffea], a
ret
diff --git a/engine/overworld/item.asm b/engine/overworld/item.asm
index a69ec106..a49fc268 100644
--- a/engine/overworld/item.asm
+++ b/engine/overworld/item.asm
@@ -34,7 +34,7 @@ PickupItem:
ld [wcc4d], a
predef HideObject
ld a, 1
- ld [wcc3c], a
+ ld [wDoNotWaitForButtonPressAfterDisplayingText], a
ld hl, FoundItemText
jr .print
diff --git a/engine/overworld/ledges.asm b/engine/overworld/ledges.asm
index 43df82e2..b8c19181 100755
--- a/engine/overworld/ledges.asm
+++ b/engine/overworld/ledges.asm
@@ -1,54 +1,54 @@
HandleLedges: ; 1a672 (6:6672)
ld a, [wd736]
- bit 6, a
+ bit 6, a ; already jumping down ledge
ret nz
ld a, [W_CURMAPTILESET] ; W_CURMAPTILESET
and a ; OVERWORLD
ret nz
- predef Func_c586
+ predef GetTileAndCoordsInFrontOfPlayer
ld a, [wSpriteStateData1 + 9]
ld b, a
aCoord 8, 9
ld c, a
- ld a, [wcfc6]
+ ld a, [wTileInFrontOfPlayer]
ld d, a
- ld hl, LedgeTiles ; $66cf
-.asm_1a691
+ ld hl, LedgeTiles
+.loop
ld a, [hli]
cp $ff
ret z
cp b
- jr nz, .asm_1a6a4
+ jr nz, .nextLedgeTile1
ld a, [hli]
cp c
- jr nz, .asm_1a6a5
+ jr nz, .nextLedgeTile2
ld a, [hli]
cp d
- jr nz, .asm_1a6a6
+ jr nz, .nextLedgeTile3
ld a, [hl]
ld e, a
- jr .asm_1a6a9
-.asm_1a6a4
+ jr .foundMatch
+.nextLedgeTile1
inc hl
-.asm_1a6a5
+.nextLedgeTile2
inc hl
-.asm_1a6a6
+.nextLedgeTile3
inc hl
- jr .asm_1a691
-.asm_1a6a9
+ jr .loop
+.foundMatch
ld a, [hJoyHeld]
and e
ret z
ld a, $ff
ld [wJoyIgnore], a
ld hl, wd736
- set 6, [hl]
- call Func_3486
+ set 6, [hl] ; jumping down ledge
+ call StartSimulatingJoypadStates
ld a, e
- ld [wccd3], a
- ld [wccd4], a
+ ld [wSimulatedJoypadStatesEnd], a
+ ld [wSimulatedJoypadStatesEnd + 1], a
ld a, $2
- ld [wcd38], a
+ ld [wSimulatedJoypadStatesIndex], a
call LoadHoppingShadowOAM
ld a, (SFX_02_4e - SFX_Headers_02) / 3
call PlaySound
@@ -56,24 +56,24 @@ HandleLedges: ; 1a672 (6:6672)
; (player direction) (tile player standing on) (ledge tile) (input required)
LedgeTiles: ; 1a6cf (6:66cf)
- db $00,$2C,$37,$80
- db $00,$39,$36,$80
- db $00,$39,$37,$80
- db $08,$2C,$27,$20
- db $08,$39,$27,$20
- db $0C,$2C,$0D,$10
- db $0C,$2C,$1D,$10
- db $0C,$39,$0D,$10
+ db SPRITE_FACING_DOWN, $2C,$37,D_DOWN
+ db SPRITE_FACING_DOWN, $39,$36,D_DOWN
+ db SPRITE_FACING_DOWN, $39,$37,D_DOWN
+ db SPRITE_FACING_LEFT, $2C,$27,D_LEFT
+ db SPRITE_FACING_LEFT, $39,$27,D_LEFT
+ db SPRITE_FACING_RIGHT,$2C,$0D,D_RIGHT
+ db SPRITE_FACING_RIGHT,$2C,$1D,D_RIGHT
+ db SPRITE_FACING_RIGHT,$39,$0D,D_RIGHT
db $FF
LoadHoppingShadowOAM: ; 1a6f0 (6:66f0)
ld hl, vChars1 + $7f0
- ld de, LedgeHoppingShadow ; $6708
+ ld de, LedgeHoppingShadow
ld bc, (BANK(LedgeHoppingShadow) << 8) + $01
call CopyVideoDataDouble
ld a, $9
ld bc, $5448 ; b, c = y, x coordinates of shadow
- ld de, LedgeHoppingShadowOAM ; $6710
+ ld de, LedgeHoppingShadowOAM
call WriteOAMBlock
ret
diff --git a/engine/overworld/movement.asm b/engine/overworld/movement.asm
index f08a20cb..3b9cac7d 100644
--- a/engine/overworld/movement.asm
+++ b/engine/overworld/movement.asm
@@ -1,23 +1,26 @@
UpdatePlayerSprite: ; 4e31 (1:4e31)
ld a, [wSpriteStateData2]
and a
- jr z, .asm_4e41
+ jr z, .checkIfTextBoxInFrontOfSprite
cp $ff
- jr z, .asm_4e4a
+ jr z, .disableSprite
dec a
ld [wSpriteStateData2], a
- jr .asm_4e4a
-.asm_4e41
+ jr .disableSprite
+; check if a text box is in front of the sprite by checking if the lower left
+; background tile the sprite is standing on is greater than $5F, which is
+; the maximum number for map tiles
+.checkIfTextBoxInFrontOfSprite
aCoord 8, 9
ld [$ff93], a
cp $60
- jr c, .asm_4e50
-.asm_4e4a
+ jr c, .lowerLeftTileIsMapTile
+.disableSprite
ld a, $ff
ld [wSpriteStateData1 + 2], a
ret
-.asm_4e50
- call Func_4c70
+.lowerLeftTileIsMapTile
+ call DetectCollisionBetweenSprites
ld h, $c1
ld a, [wWalkCounter] ; wcfc5
and a
@@ -165,8 +168,8 @@ Func_4ed1: ; 4ed1 (1:4ed1)
ld hl, wd730
res 0, [hl]
xor a
- ld [wcd38], a
- ld [wcd3a], a
+ ld [wSimulatedJoypadStatesIndex], a
+ ld [wWastedByteCD3A], a
ret
.asm_4f4b
cp $fe
@@ -490,6 +493,8 @@ CheckSpriteAvailability: ; 50dc (1:50dc)
cp b
jr c, .spriteInvisible ; right of screen region
.skipXVisibilityTest
+; make the sprite invisible if a text box is in front of it
+; $5F is the maximum number for map tiles
call getTileSpriteStandsOn
ld d, $60
ld a, [hli]
@@ -604,16 +609,16 @@ CanWalkOntoTile: ; 516e (1:516e)
jr nc, .impassable ; don't walk off screen
push de
push bc
- call Func_4c70
+ call DetectCollisionBetweenSprites
pop bc
pop de
ld h, $c1
ld a, [H_CURRENTSPRITEOFFSET]
add $c
ld l, a
- ld a, [hl] ; c1xc (forbidden directions flags(?))
+ ld a, [hl] ; c1xc (directions in which sprite collision would occur)
and b ; check against chosen direction (1,2,4 or 8)
- jr nz, .impassable ; direction forbidden, don't go there
+ jr nz, .impassable ; collision between sprites, don't go there
ld h, $c2
ld a, [H_CURRENTSPRITEOFFSET]
add $2
@@ -716,8 +721,8 @@ Func_5236: ; 5236 (1:5236)
bit 7, [hl]
set 7, [hl]
jp z, Func_52a6
- ld hl, wcc97
- ld a, [wcd37]
+ ld hl, wNPCMovementDirections2
+ ld a, [wNPCMovementDirections2Index]
add l
ld l, a
jr nc, .asm_5251
@@ -770,13 +775,13 @@ Func_5236: ; 5236 (1:5236)
ret nz
ld a, $8
ld [wcf18], a
- ld hl, wcd37
+ ld hl, wNPCMovementDirections2Index
inc [hl]
ret
Func_52a6: ; 52a6 (1:52a6)
xor a
- ld [wcd37], a
+ ld [wNPCMovementDirections2Index], a
ld a, $8
ld [wcf18], a
jp Func_52c3
diff --git a/engine/overworld/npc_movement.asm b/engine/overworld/npc_movement.asm
index 2cf6fea9..84e39853 100755
--- a/engine/overworld/npc_movement.asm
+++ b/engine/overworld/npc_movement.asm
@@ -1,25 +1,25 @@
-Func_1a3e0: ; 1a3e0 (6:63e0)
+PlayerStepOutFromDoor: ; 1a3e0 (6:63e0)
ld hl, wd730
res 1, [hl]
- call HandleDoors
- jr nc, .asm_1a406
+ call IsPlayerStandingOnDoorTile
+ jr nc, .notStandingOnDoor
ld a, $fc
ld [wJoyIgnore], a
ld hl, wd736
set 1, [hl]
ld a, $1
- ld [wcd38], a
- ld a, $80
- ld [wccd3], a
+ ld [wSimulatedJoypadStatesIndex], a
+ ld a, D_DOWN
+ ld [wSimulatedJoypadStatesEnd], a
xor a
ld [wSpriteStateData1 + 2], a
- call Func_3486
+ call StartSimulatingJoypadStates
ret
-.asm_1a406
+.notStandingOnDoor
xor a
- ld [wcd3a], a
- ld [wcd38], a
- ld [wccd3], a
+ ld [wWastedByteCD3A], a
+ ld [wSimulatedJoypadStatesIndex], a
+ ld [wSimulatedJoypadStatesEnd], a
ld hl, wd736
res 0, [hl]
res 1, [hl]
@@ -27,7 +27,7 @@ Func_1a3e0: ; 1a3e0 (6:63e0)
res 7, [hl]
ret
-Func_1a41d: ; 1a41d (6:641d)
+_EndNPCMovementScript: ; 1a41d (6:641d)
ld hl, wd730
res 7, [hl]
ld hl, wd72e
@@ -36,15 +36,15 @@ Func_1a41d: ; 1a41d (6:641d)
res 0, [hl]
res 1, [hl]
xor a
- ld [wcf17], a
- ld [wcc57], a
- ld [wcf10], a
- ld [wcd3a], a
- ld [wcd38], a
- ld [wccd3], a
+ ld [wNPCMovementScriptSpriteOffset], a
+ ld [wNPCMovementScriptPointerTableNum], a
+ ld [wNPCMovementScriptFunctionNum], a
+ ld [wWastedByteCD3A], a
+ ld [wSimulatedJoypadStatesIndex], a
+ ld [wSimulatedJoypadStatesEnd], a
ret
-PointerTable_1a442: ; 1a442 (6:6442)
+ProfOakMovementScriptPointerTable: ; 1a442 (6:6442)
dw Func_1a44c
dw Func_1a485
dw Func_1a4a1
@@ -58,20 +58,20 @@ Func_1a44c: ; 1a44c (6:644c)
jr z, .asm_1a475
ld b, $0
ld c, a
- ld hl, wcc97
+ ld hl, wNPCMovementDirections2
ld a, $80
call FillMemory
ld [hl], $ff
- ld a, [wcf13]
+ ld a, [wSpriteIndex]
ld [H_DOWNARROWBLINKCNT2], a ; $ff8c
- ld de, wcc97
+ ld de, wNPCMovementDirections2
call MoveSprite
ld a, $1
- ld [wcf10], a
+ ld [wNPCMovementScriptFunctionNum], a
jr .asm_1a47a
.asm_1a475
ld a, $3
- ld [wcf10], a
+ ld [wNPCMovementScriptFunctionNum], a
.asm_1a47a
ld hl, W_FLAGS_D733
set 1, [hl]
@@ -84,44 +84,44 @@ Func_1a485: ; 1a485 (6:6485)
bit 0, a
ret nz
ld a, [wcca1]
- ld [wcd38], a
+ ld [wSimulatedJoypadStatesIndex], a
ld [$ff95], a
- predef Func_f9a0
- call Func_3486
+ predef ConvertNPCMovementDirectionsToJoypadMasks
+ call StartSimulatingJoypadStates
ld a, $2
- ld [wcf10], a
+ ld [wNPCMovementScriptFunctionNum], a
ret
Func_1a4a1: ; 1a4a1 (6:64a1)
- ld a, [wcd38]
+ ld a, [wSimulatedJoypadStatesIndex]
and a
ret nz
Func_1a4a6: ; 1a4a6 (6:64a6)
xor a
- ld [wcd3b], a
- ld a, [wcf13]
+ ld [wOverrideSimulatedJoypadStatesMask], a
+ ld a, [wSpriteIndex]
swap a
- ld [wcf17], a
+ ld [wNPCMovementScriptSpriteOffset], a
xor a
ld [wSpriteStateData2 + $06], a
- ld hl, wccd3
- ld de, RLEList_1a4e9
+ ld hl, wSimulatedJoypadStatesEnd
+ ld de, RLEList_PlayerWalkToLab
call DecodeRLEList
dec a
- ld [wcd38], a
- ld hl, wcc97
- ld de, RLEList_1a4dc
+ ld [wSimulatedJoypadStatesIndex], a
+ ld hl, wNPCMovementDirections2
+ ld de, RLEList_ProfOakWalkToLab
call DecodeRLEList
ld hl, wd72e
res 7, [hl]
ld hl, wd730
set 7, [hl]
ld a, $4
- ld [wcf10], a
+ ld [wNPCMovementScriptFunctionNum], a
ret
-RLEList_1a4dc: ; 1a4dc (6:64dc)
+RLEList_ProfOakWalkToLab: ; 1a4dc (6:64dc)
db $00, $05
db $80, $01
db $00, $05
@@ -130,16 +130,16 @@ RLEList_1a4dc: ; 1a4dc (6:64dc)
db $E0, $01
db $FF
-RLEList_1a4e9: ; 1a4e9 (6:64e9)
- db $40, $02
- db $10, $03
- db $80, $05
- db $20, $01
- db $80, $06
+RLEList_PlayerWalkToLab: ; 1a4e9 (6:64e9)
+ db D_UP, $02
+ db D_RIGHT, $03
+ db D_DOWN, $05
+ db D_LEFT, $01
+ db D_DOWN, $06
db $FF
Func_1a4f4: ; 1a4f4 (6:64f4)
- ld a, [wcd38]
+ ld a, [wSimulatedJoypadStatesIndex]
and a
ret nz
ld a, $0
@@ -149,11 +149,11 @@ Func_1a4f4: ; 1a4f4 (6:64f4)
res 7, [hl]
ld hl, wd72e
res 7, [hl]
- jp Func_314e
+ jp EndNPCMovementScript
-PointerTable_1a510: ; 1a510 (6:6510)
+PewterMuseumGuyMovementScriptPointerTable: ; 1a510 (6:6510)
dw Func_1a514
- dw Func_1a56b
+ dw PewterMovementScriptDone
Func_1a514: ; 1a514 (6:6514)
ld a, BANK(Music_MuseumGuy)
@@ -162,32 +162,32 @@ Func_1a514: ; 1a514 (6:6514)
ld a, MUSIC_MUSEUM_GUY
ld [wc0ee], a
call PlaySound
- ld a, [wcf13]
+ ld a, [wSpriteIndex]
swap a
- ld [wcf17], a
- call Func_3486
- ld hl, wccd3
+ ld [wNPCMovementScriptSpriteOffset], a
+ call StartSimulatingJoypadStates
+ ld hl, wSimulatedJoypadStatesEnd
ld de, RLEList_PewterMuseumPlayer
call DecodeRLEList
dec a
- ld [wcd38], a
+ ld [wSimulatedJoypadStatesIndex], a
xor a
ld [wd12f], a
predef PewterGuys
- ld hl, wcc97
+ ld hl, wNPCMovementDirections2
ld de, RLEList_PewterMuseumGuy
call DecodeRLEList
ld hl, wd72e
res 7, [hl]
ld a, $1
- ld [wcf10], a
+ ld [wNPCMovementScriptFunctionNum], a
ret
RLEList_PewterMuseumPlayer: ; 1a559 (6:6559)
- db $00, $01
- db $40, $03
- db $20, $0D
- db $40, $06
+ db 0, $01
+ db D_UP, $03
+ db D_LEFT, $0D
+ db D_UP, $06
db $FF
RLEList_PewterMuseumGuy: ; 1a562 (6:6562)
@@ -197,19 +197,19 @@ RLEList_PewterMuseumGuy: ; 1a562 (6:6562)
db $80, $01
db $FF
-Func_1a56b: ; 1a56b (6:656b)
- ld a, [wcd38]
+PewterMovementScriptDone: ; 1a56b (6:656b)
+ ld a, [wSimulatedJoypadStatesIndex]
and a
ret nz
ld hl, wd730
res 7, [hl]
ld hl, wd72e
res 7, [hl]
- jp Func_314e
+ jp EndNPCMovementScript
-PointerTable_1a57d: ; 1a57d (6:657d)
+PewterGymGuyMovementScriptPointerTable: ; 1a57d (6:657d)
dw Func_1a581
- dw Func_1a56b
+ dw PewterMovementScriptDone
Func_1a581: ; 1a581 (6:6581)
ld a, BANK(Music_MuseumGuy)
@@ -218,20 +218,20 @@ Func_1a581: ; 1a581 (6:6581)
ld a, MUSIC_MUSEUM_GUY
ld [wc0ee], a
call PlaySound
- ld a, [wcf13]
+ ld a, [wSpriteIndex]
swap a
- ld [wcf17], a
+ ld [wNPCMovementScriptSpriteOffset], a
xor a
ld [wSpriteStateData2 + $06], a
- ld hl, wccd3
+ ld hl, wSimulatedJoypadStatesEnd
ld de, RLEList_PewterGymPlayer
call DecodeRLEList
dec a
- ld [wcd38], a
+ ld [wSimulatedJoypadStatesIndex], a
ld a, $1
ld [wd12f], a
predef PewterGuys
- ld hl, wcc97
+ ld hl, wNPCMovementDirections2
ld de, RLEList_PewterGymGuy
call DecodeRLEList
ld hl, wd72e
@@ -239,16 +239,16 @@ Func_1a581: ; 1a581 (6:6581)
ld hl, wd730
set 7, [hl]
ld a, $1
- ld [wcf10], a
+ ld [wNPCMovementScriptFunctionNum], a
ret
RLEList_PewterGymPlayer: ; 1a5cd (6:65cd)
- db $00, $01
- db $10, $02
- db $80, $05
- db $20, $0B
- db $40, $05
- db $20, $0F
+ db 0, $01
+ db D_RIGHT, $02
+ db D_DOWN, $05
+ db D_LEFT, $0B
+ db D_UP, $05
+ db D_LEFT, $0F
db $FF
RLEList_PewterGymGuy: ; 1a5da (6:65da)
@@ -260,12 +260,11 @@ RLEList_PewterGymGuy: ; 1a5da (6:65da)
db $C0, $03
db $FF
-; XXX why would this function want to return on POKEMONTOWER_7?
-Func_1a5e7: ; 1a5e7 (6:65e7)
- ld a, [W_CURMAP] ; W_CURMAP
+FreezeEnemyTrainerSprite: ; 1a5e7 (6:65e7)
+ ld a, [W_CURMAP]
cp POKEMONTOWER_7
- ret z
- ld hl, RivalIDs ; $6605
+ ret z ; the Rockets on Pokemon Tower 7F leave after battling, so don't freeze them
+ ld hl, RivalIDs
ld a, [wEngagedTrainerClass]
ld b, a
.loop
@@ -273,11 +272,11 @@ Func_1a5e7: ; 1a5e7 (6:65e7)
cp $ff
jr z, .notRival
cp b
- ret z
+ ret z ; the rival leaves after battling, so don't freeze him
jr .loop
.notRival
- ld a, [wcf13]
- ld [H_DOWNARROWBLINKCNT2], a ; $ff8c
+ ld a, [wSpriteIndex]
+ ld [H_SPRITEINDEX], a
jp SetSpriteMovementBytesToFF
RivalIDs: ; 1a605 (6:6605)
diff --git a/engine/overworld/oam.asm b/engine/overworld/oam.asm
index 63495d22..b4247257 100644
--- a/engine/overworld/oam.asm
+++ b/engine/overworld/oam.asm
@@ -2,13 +2,13 @@ PrepareOAMData:
; Determine OAM data for currently visible
; sprites and write it to wOAMBuffer.
- ld a, [wcfcb]
+ ld a, [wUpdateSpritesEnabled]
dec a
jr z, .asm_4b1e
cp 0 - 1
ret nz
- ld [wcfcb], a
+ ld [wUpdateSpritesEnabled], a
jp HideSprites
.asm_4b1e
diff --git a/engine/overworld/pewter_guys.asm b/engine/overworld/pewter_guys.asm
index 2f3001fb..eb6dd5ac 100755
--- a/engine/overworld/pewter_guys.asm
+++ b/engine/overworld/pewter_guys.asm
@@ -1,8 +1,8 @@
PewterGuys: ; 37ca1 (d:7ca1)
- ld hl, wccd3
- ld a, [wcd38]
- dec a
- ld [wcd38], a
+ ld hl, wSimulatedJoypadStatesEnd
+ ld a, [wSimulatedJoypadStatesIndex]
+ dec a ; this decrement causes it to overwrite the last byte before $FF in the list
+ ld [wSimulatedJoypadStatesIndex], a
ld d, 0
ld e, a
add hl, de
@@ -37,9 +37,9 @@ PewterGuys: ; 37ca1 (d:7ca1)
ret z
ld [de], a
inc de
- ld a, [wcd38]
+ ld a, [wSimulatedJoypadStatesIndex]
inc a
- ld [wcd38], a
+ ld [wSimulatedJoypadStatesIndex], a
jr .asm_37cd2
.asm_37ce1
inc hl
diff --git a/engine/overworld/player_animations.asm b/engine/overworld/player_animations.asm
index a0d8175f..473b0d5a 100755
--- a/engine/overworld/player_animations.asm
+++ b/engine/overworld/player_animations.asm
@@ -1,66 +1,67 @@
-Func_70510: ; 70510 (1c:4510)
- call Func_706ef
+EnterMapAnim: ; 70510 (1c:4510)
+ call InitFacingDirectionBuffer
ld a, $ec
- ld [wSpriteStateData1 + 4], a
+ ld [wSpriteStateData1 + 4], a ; player's sprite Y screen position
call Delay3
push hl
- call GBFadeIn2
+ call GBFadeInFromWhite
ld hl, W_FLAGS_D733
- bit 7, [hl]
+ bit 7, [hl] ; used fly out of battle?
res 7, [hl]
- jr nz, .asm_70568
+ jr nz, .flyAnimation
ld a, (SFX_02_4c - SFX_Headers_02) / 3
call PlaySound
ld hl, wd732
- bit 4, [hl]
+ bit 4, [hl] ; used dungeon warp?
res 4, [hl]
pop hl
- jr nz, .asm_7055e
- call Func_705aa
+ jr nz, .dungeonWarpAnimation
+ call PlayerSpinWhileMovingDown
ld a, (SFX_02_4f - SFX_Headers_02) / 3
call PlaySound
- call Func_70787
+ call IsPlayerStandingOnWarpPadOrHole
ld a, b
and a
- jr nz, .asm_7055b
- ld hl, wWhichTrade ; wWhichTrade
+ jr nz, .done
+; if the player is not standing on a warp pad or hole
+ ld hl, wPlayerSpinInPlaceAnimFrameDelay
xor a
- ld [hli], a
+ ld [hli], a ; wPlayerSpinInPlaceAnimFrameDelay
inc a
- ld [hli], a
+ ld [hli], a ; wPlayerSpinInPlaceAnimFrameDelayDelta
ld a, $8
- ld [hli], a
- ld [hl], $ff
+ ld [hli], a ; wPlayerSpinInPlaceAnimFrameDelayEndValue
+ ld [hl], $ff ; wPlayerSpinInPlaceAnimSoundID
ld hl, wcd48
- call Func_70730
-.asm_70558
- call Func_2307
-.asm_7055b
- jp Func_70772
-.asm_7055e
- ld c, $32
+ call PlayerSpinInPlace
+.restoreDefaultMusic
+ call PlayDefaultMusic
+.done
+ jp RestoreFacingDirectionAndYScreenPos
+.dungeonWarpAnimation
+ ld c, 50
call DelayFrames
- call Func_705aa
- jr .asm_7055b
-.asm_70568
+ call PlayerSpinWhileMovingDown
+ jr .done
+.flyAnimation
pop hl
- ld de, BirdSprite ; $4d80
+ ld de, BirdSprite
ld hl, vNPCSprites
ld bc, (BANK(BirdSprite) << 8) + $0c
call CopyVideoData
- call Func_706d7
+ call LoadBirdSpriteGraphics
ld a, (SFX_02_50 - SFX_Headers_02) / 3
call PlaySound
- ld hl, wWhichTrade ; wWhichTrade
- xor a
- ld [hli], a
- ld a, $c
- ld [hli], a
- ld [hl], $8
+ ld hl, wFlyAnimUsingCoordList
+ xor a ; is using coord list
+ ld [hli], a ; wFlyAnimUsingCoordList
+ ld a, 12
+ ld [hli], a ; wFlyAnimCounter
+ ld [hl], $8 ; wFlyAnimBirdSpriteImageIndex (facing right)
ld de, FlyAnimationEnterScreenCoords ; $4592
- call Func_706ae
+ call DoFlyAnimation
call LoadPlayerSpriteGraphics
- jr .asm_70558
+ jr .restoreDefaultMusic
FlyAnimationEnterScreenCoords: ; 70592 (1c:4592)
; y, x pairs
@@ -79,90 +80,92 @@ FlyAnimationEnterScreenCoords: ; 70592 (1c:4592)
db $3C, $48
db $3C, $40
-Func_705aa: ; 705aa (1c:45aa)
- ld hl, wWhichTrade ; wWhichTrade
+PlayerSpinWhileMovingDown: ; 705aa (1c:45aa)
+ ld hl, wPlayerSpinWhileMovingUpOrDownAnimDeltaY
ld a, $10
- ld [hli], a
+ ld [hli], a ; wPlayerSpinWhileMovingUpOrDownAnimDeltaY
ld a, $3c
- ld [hli], a
- call Func_7077f
- ld [hl], a
- jp Func_70755
+ ld [hli], a ; wPlayerSpinWhileMovingUpOrDownAnimMaxY
+ call GetPlayerTeleportAnimFrameDelay
+ ld [hl], a ; wPlayerSpinWhileMovingUpOrDownAnimFrameDelay
+ jp PlayerSpinWhileMovingUpOrDown
_LeaveMapAnim: ; 705ba (1c:45ba)
- call Func_706ef
- call Func_70787
+ call InitFacingDirectionBuffer
+ call IsPlayerStandingOnWarpPadOrHole
ld a, b
and a
- jr z, .asm_705ef
+ jr z, .playerNotStandingOnWarpPadOrHole
dec a
- jp nz, Func_7067d
-.asm_705c8
+ jp nz, LeaveMapThroughHoleAnim
+.spinWhileMovingUp
ld a, (SFX_02_4b - SFX_Headers_02) / 3
call PlaySound
- ld hl, wWhichTrade ; wWhichTrade
- ld a, $f0
- ld [hli], a
+ ld hl, wPlayerSpinWhileMovingUpOrDownAnimDeltaY
+ ld a, -$10
+ ld [hli], a ; wPlayerSpinWhileMovingUpOrDownAnimDeltaY
ld a, $ec
- ld [hli], a
- call Func_7077f
- ld [hl], a
- call Func_70755
- call Func_70787
+ ld [hli], a ; wPlayerSpinWhileMovingUpOrDownAnimMaxY
+ call GetPlayerTeleportAnimFrameDelay
+ ld [hl], a ; wPlayerSpinWhileMovingUpOrDownAnimFrameDelay
+ call PlayerSpinWhileMovingUpOrDown
+ call IsPlayerStandingOnWarpPadOrHole
ld a, b
dec a
- jr z, .asm_705e9
- ld c, $a
+ jr z, .playerStandingOnWarpPad
+; if not standing on a warp pad, there is an extra delay
+ ld c, 10
call DelayFrames
-.asm_705e9
- call GBFadeOut2
- jp Func_70772
-.asm_705ef
+.playerStandingOnWarpPad
+ call GBFadeOutToWhite
+ jp RestoreFacingDirectionAndYScreenPos
+.playerNotStandingOnWarpPadOrHole
ld a, $4
call StopMusic
ld a, [wd732]
- bit 6, a
- jr z, .asm_70610
- ld hl, wWhichTrade ; wWhichTrade
- ld a, $10
- ld [hli], a
- ld a, $ff
- ld [hli], a
+ bit 6, a ; is the last used pokemon center the destination?
+ jr z, .flyAnimation
+; if going to the last used pokemon center
+ ld hl, wPlayerSpinInPlaceAnimFrameDelay
+ ld a, 16
+ ld [hli], a ; wPlayerSpinInPlaceAnimFrameDelay
+ ld a, -1
+ ld [hli], a ; wPlayerSpinInPlaceAnimFrameDelayDelta
xor a
- ld [hli], a
- ld [hl], $a1
+ ld [hli], a ; wPlayerSpinInPlaceAnimFrameDelayEndValue
+ ld [hl], $a1 ; wPlayerSpinInPlaceAnimSoundID
ld hl, wcd48
- call Func_70730
- jr .asm_705c8
-.asm_70610
- call Func_706d7
- ld hl, wWhichTrade ; wWhichTrade
- ld a, $ff
- ld [hli], a
- ld a, $8
- ld [hli], a
- ld [hl], $c
- call Func_706ae
+ call PlayerSpinInPlace
+ jr .spinWhileMovingUp
+.flyAnimation
+ call LoadBirdSpriteGraphics
+ ld hl, wFlyAnimUsingCoordList
+ ld a, $ff ; is not using coord list (flap in place)
+ ld [hli], a ; wFlyAnimUsingCoordList
+ ld a, 8
+ ld [hli], a ; wFlyAnimCounter
+ ld [hl], $c ; wFlyAnimBirdSpriteImageIndex
+ call DoFlyAnimation
ld a, (SFX_02_50 - SFX_Headers_02) / 3
call PlaySound
- ld hl, wWhichTrade ; wWhichTrade
- xor a
- ld [hli], a
+ ld hl, wFlyAnimUsingCoordList
+ xor a ; is using coord list
+ ld [hli], a ; wFlyAnimUsingCoordList
ld a, $c
- ld [hli], a
- ld [hl], $c
+ ld [hli], a ; wFlyAnimCounter
+ ld [hl], $c ; wFlyAnimBirdSpriteImageIndex (facing right)
ld de, FlyAnimationScreenCoords1 ; $464f
- call Func_706ae
- ld c, $28
+ call DoFlyAnimation
+ ld c, 40
call DelayFrames
- ld hl, wTrainerEngageDistance
- ld a, $b
- ld [hli], a
- ld [hl], $8
+ ld hl, wFlyAnimCounter
+ ld a, 11
+ ld [hli], a ; wFlyAnimCounter
+ ld [hl], $8 ; wFlyAnimBirdSpriteImageIndex (facing left)
ld de, FlyAnimationScreenCoords2 ; $4667
- call Func_706ae
- call GBFadeOut2
- jp Func_70772
+ call DoFlyAnimation
+ call GBFadeOutToWhite
+ jp RestoreFacingDirectionAndYScreenPos
FlyAnimationScreenCoords1: ; 7064f (1c:464f)
; y, x pairs
@@ -198,33 +201,35 @@ FlyAnimationScreenCoords2: ; 70667 (1c:4667)
db $F0, $00
-Func_7067d: ; 7067d (1c:467d)
+LeaveMapThroughHoleAnim: ; 7067d (1c:467d)
ld a, $ff
- ld [wcfcb], a
- ld a, [wOAMBuffer + $02]
- ld [wOAMBuffer + $0a], a
- ld a, [wOAMBuffer + $06]
- ld [wOAMBuffer + $0e], a
+ ld [wUpdateSpritesEnabled], a ; disable UpdateSprites
+ ; shift upper half of player's sprite down 8 pixels and hide lower half
+ ld a, [wOAMBuffer + 0 * 4 + 2]
+ ld [wOAMBuffer + 2 * 4 + 2], a
+ ld a, [wOAMBuffer + 1 * 4 + 2]
+ ld [wOAMBuffer + 3 * 4 + 2], a
ld a, $a0
- ld [wOAMBuffer], a
- ld [wOAMBuffer + $04], a
- ld c, $2
+ ld [wOAMBuffer + 0 * 4], a
+ ld [wOAMBuffer + 1 * 4], a
+ ld c, 2
call DelayFrames
+ ; hide lower half of player's sprite
ld a, $a0
- ld [wOAMBuffer + $08], a
- ld [wOAMBuffer + $0c], a
- call GBFadeOut2
+ ld [wOAMBuffer + 2 * 4], a
+ ld [wOAMBuffer + 3 * 4], a
+ call GBFadeOutToWhite
ld a, $1
- ld [wcfcb], a
- jp Func_70772
+ ld [wUpdateSpritesEnabled], a ; enable UpdateSprites
+ jp RestoreFacingDirectionAndYScreenPos
-Func_706ae: ; 706ae (1c:46ae)
- ld a, [wTrainerFacingDirection]
- xor $1
- ld [wTrainerFacingDirection], a
+DoFlyAnimation: ; 706ae (1c:46ae)
+ ld a, [wFlyAnimBirdSpriteImageIndex]
+ xor $1 ; make the bird flap its wings
+ ld [wFlyAnimBirdSpriteImageIndex], a
ld [wSpriteStateData1 + 2], a
call Delay3
- ld a, [wWhichTrade] ; wWhichTrade
+ ld a, [wFlyAnimUsingCoordList]
cp $ff
jr z, .asm_706cd
ld hl, wSpriteStateData1 + 4
@@ -236,13 +241,13 @@ Func_706ae: ; 706ae (1c:46ae)
inc de
ld [hl], a
.asm_706cd
- ld a, [wTrainerEngageDistance]
+ ld a, [wFlyAnimCounter]
dec a
- ld [wTrainerEngageDistance], a
- jr nz, Func_706ae
+ ld [wFlyAnimCounter], a
+ jr nz, DoFlyAnimation
ret
-Func_706d7: ; 706d7 (1c:46d7)
+LoadBirdSpriteGraphics: ; 706d7 (1c:46d7)
ld de, BirdSprite ; $4d80
ld hl, vNPCSprites
ld bc, (BANK(BirdSprite) << 8) + $0c
@@ -252,32 +257,32 @@ Func_706d7: ; 706d7 (1c:46d7)
ld bc, (BANK(BirdSprite) << 8) + $0c
jp CopyVideoData
-Func_706ef: ; 706ef (1c:46ef)
- ld a, [wSpriteStateData1 + 2]
+InitFacingDirectionBuffer: ; 706ef (1c:46ef)
+ ld a, [wSpriteStateData1 + 2] ; player's sprite facing direction (image index is locked to standing images)
ld [wcd50], a
- ld a, [wSpriteStateData1 + 4]
+ ld a, [wSpriteStateData1 + 4] ; player's sprite Y screen position
ld [wcd4f], a
- ld hl, PlayerSpinningFacingOrder ; $4713
+ ld hl, PlayerSpinningFacingOrder
ld de, wcd48
ld bc, $4
call CopyData
- ld a, [wSpriteStateData1 + 2]
+ ld a, [wSpriteStateData1 + 2] ; player's sprite facing direction (image index is locked to standing images)
ld hl, wcd48
-.asm_7070d
+.loop
cp [hl]
inc hl
- jr nz, .asm_7070d
+ jr nz, .loop
dec hl
ret
PlayerSpinningFacingOrder: ; 70713 (1c:4713)
; The order of the direction the player's sprite is facing when teleporting
; away. Creates a spinning effect.
- db $00, $08, $04, $0C ; down, left, up, right
+ db SPRITE_FACING_DOWN, SPRITE_FACING_LEFT, SPRITE_FACING_UP, SPRITE_FACING_RIGHT
-Func_70717: ; 70717 (1c:4717)
+SpinPlayerSprite: ; 70717 (1c:4717)
ld a, [hl]
- ld [wSpriteStateData1 + 2], a
+ ld [wSpriteStateData1 + 2], a ; player's sprite facing direction (image index is locked to standing images)
push hl
ld hl, wcd48
ld de, wcd47
@@ -288,84 +293,85 @@ Func_70717: ; 70717 (1c:4717)
pop hl
ret
-Func_70730: ; 70730 (1c:4730)
- call Func_70717
- ld a, [wWhichTrade] ; wWhichTrade
+PlayerSpinInPlace: ; 70730 (1c:4730)
+ call SpinPlayerSprite
+ ld a, [wPlayerSpinInPlaceAnimFrameDelay]
ld c, a
and $3
jr nz, .asm_70743
- ld a, [wTrainerScreenY]
+ ld a, [wPlayerSpinInPlaceAnimSoundID]
cp $ff
call nz, PlaySound
.asm_70743
- ld a, [wTrainerEngageDistance]
+ ld a, [wPlayerSpinInPlaceAnimFrameDelayDelta]
add c
- ld [wWhichTrade], a ; wWhichTrade
+ ld [wPlayerSpinInPlaceAnimFrameDelay], a
ld c, a
- ld a, [wTrainerFacingDirection]
+ ld a, [wPlayerSpinInPlaceAnimFrameDelayEndValue]
cp c
ret z
call DelayFrames
- jr Func_70730
+ jr PlayerSpinInPlace
-Func_70755: ; 70755 (1c:4755)
- call Func_70717
- ld a, [wWhichTrade] ; wWhichTrade
+PlayerSpinWhileMovingUpOrDown: ; 70755 (1c:4755)
+ call SpinPlayerSprite
+ ld a, [wPlayerSpinWhileMovingUpOrDownAnimDeltaY]
ld c, a
- ld a, [wSpriteStateData1 + 4]
+ ld a, [wSpriteStateData1 + 4] ; player's sprite Y screen position
add c
ld [wSpriteStateData1 + 4], a
ld c, a
- ld a, [wTrainerEngageDistance]
+ ld a, [wPlayerSpinWhileMovingUpOrDownAnimMaxY]
cp c
ret z
- ld a, [wTrainerFacingDirection]
+ ld a, [wPlayerSpinWhileMovingUpOrDownAnimFrameDelay]
ld c, a
call DelayFrames
- jr Func_70755
+ jr PlayerSpinWhileMovingUpOrDown
-Func_70772: ; 70772 (1c:4772)
+RestoreFacingDirectionAndYScreenPos: ; 70772 (1c:4772)
ld a, [wcd4f]
ld [wSpriteStateData1 + 4], a
ld a, [wcd50]
ld [wSpriteStateData1 + 2], a
ret
-Func_7077f: ; 7077f (1c:477f)
- ld a, [wcf1b]
+; if SGB, 2 frames, else 3 frames
+GetPlayerTeleportAnimFrameDelay: ; 7077f (1c:477f)
+ ld a, [wOnSGB]
xor $1
inc a
inc a
ret
-Func_70787: ; 70787 (1c:4787)
+IsPlayerStandingOnWarpPadOrHole: ; 70787 (1c:4787)
ld b, 0
- ld hl, DataTable_707a9 ; $47a9
- ld a, [W_CURMAPTILESET] ; W_CURMAPTILESET
+ ld hl, .warpPadAndHoleData
+ ld a, [W_CURMAPTILESET]
ld c, a
-.asm_70790
+.loop
ld a, [hli]
cp $ff
- jr z, .asm_707a4
+ jr z, .done
cp c
- jr nz, .asm_7079e
+ jr nz, .nextEntry
aCoord 8, 9
cp [hl]
- jr z, .asm_707a2
-.asm_7079e
+ jr z, .foundMatch
+.nextEntry
inc hl
inc hl
- jr .asm_70790
-.asm_707a2
+ jr .loop
+.foundMatch
inc hl
ld b, [hl]
-.asm_707a4
+.done
ld a, b
ld [wcd5b], a
ret
; format: db tileset id, tile id, value to be put in wcd5b
-DataTable_707a9: ; 707a9 (1c:47a9)
+.warpPadAndHoleData: ; 707a9 (1c:47a9)
db FACILITY, $20, 1 ; warp pad
db FACILITY, $11, 2 ; hole
db CAVERN, $22, 2 ; hole
@@ -454,7 +460,7 @@ ItsABiteText: ; 70851 (1c:4851)
db "@"
FishingRodGfxProperties: ; 70856 (1c:4856)
-; specicies how the fishing rod should be drawn on the screen
+; specifies how the fishing rod should be drawn on the screen
; first byte = screen y coordinate
; second byte = screen x coordinate
; third byte = tile number
@@ -482,21 +488,21 @@ RedFishingTiles: ; 70866 (1c:4866)
dw vNPCSprites2 + $7d0
_HandleMidJump: ; 7087e (1c:487e)
- ld a, [wd714]
+ ld a, [wPlayerJumpingYScreenCoordsIndex]
ld c, a
inc a
cp $10
- jr nc, .asm_70895
- ld [wd714], a
- ld b, $0
- ld hl, PlayerJumpingYScreenCoords ; $48ba
+ jr nc, .finishedJump
+ ld [wPlayerJumpingYScreenCoordsIndex], a
+ ld b, 0
+ ld hl, PlayerJumpingYScreenCoords
add hl, bc
ld a, [hl]
ld [wSpriteStateData1 + 4], a ; player's sprite y coordinate
ret
-.asm_70895
- ld a, [wWalkCounter] ; wcfc5
- cp $0
+.finishedJump
+ ld a, [wWalkCounter]
+ cp 0
ret nz
call UpdateSprites
call Delay3
@@ -504,11 +510,11 @@ _HandleMidJump: ; 7087e (1c:487e)
ld [hJoyHeld], a
ld [hJoyPressed], a
ld [hJoyReleased], a
- ld [wd714], a
+ ld [wPlayerJumpingYScreenCoordsIndex], a
ld hl, wd736
- res 6, [hl]
+ res 6, [hl] ; not jumping down a ledge any more
ld hl, wd730
- res 7, [hl]
+ res 7, [hl] ; not simulating joypad states any more
xor a
ld [wJoyIgnore], a
ret
diff --git a/engine/overworld/pokemart.asm b/engine/overworld/pokemart.asm
index 3b06bd2c..a27f6b0a 100755
--- a/engine/overworld/pokemart.asm
+++ b/engine/overworld/pokemart.asm
@@ -173,13 +173,13 @@ DisplayPokemartDialogue_: ; 6c20 (1:6c20)
ld [wcf0a],a
.skipSettingFlag2
ld a,(SFX_02_5a - SFX_Headers_02) / 3
- call PlaySoundWaitForCurrent ; play sound
- call WaitForSoundToFinish ; wait until sound is done playing
+ call PlaySoundWaitForCurrent
+ call WaitForSoundToFinish
ld hl,PokemartBoughtItemText
call PrintText
jp .buyMenuLoop
.returnToMainPokemartMenu
- call LoadScreenTilesFromBuffer1 ; restore save screen
+ call LoadScreenTilesFromBuffer1
ld a,$13
ld [wd125],a
call DisplayTextBoxID ; draw money text box
@@ -203,7 +203,7 @@ DisplayPokemartDialogue_: ; 6c20 (1:6c20)
ld hl,PokemartThankYouText
call PrintText
ld a,$01
- ld [wcfcb],a
+ ld [wUpdateSpritesEnabled],a
call UpdateSprites ; move sprites
ld a,[wd07e]
ld [wListScrollOffset],a
diff --git a/engine/overworld/ssanne.asm b/engine/overworld/ssanne.asm
index 8fd8f99a..f1a8ecf9 100755
--- a/engine/overworld/ssanne.asm
+++ b/engine/overworld/ssanne.asm
@@ -1,37 +1,37 @@
-Func_79f54: ; 79f54 (1e:5f54)
+AnimateBoulderDust: ; 79f54 (1e:5f54)
ld a, $1
- ld [wcd50], a
- ld a, [wcfcb]
+ ld [wcd50], a ; select the boulder dust offsets
+ ld a, [wUpdateSpritesEnabled]
push af
ld a, $ff
- ld [wcfcb], a
- ld a, $e4
- ld [rOBP1], a ; $ff49
+ ld [wUpdateSpritesEnabled], a
+ ld a, %11100100
+ ld [rOBP1], a
call LoadSmokeTileFourTimes
- callba asm_f055
- ld c, $8
-.asm_79f73
+ callba WriteCutTreeBoulderDustAnimationOAMBlock
+ ld c, 8 ; number of steps in animation
+.loop
push bc
- call Func_79f92
- ld bc, .asm_79f7e
+ call GetMoveBoulderDustFunctionPointer
+ ld bc, .returnAddress
push bc
ld c, $4
jp [hl]
-.asm_79f7e
- ld a, [rOBP1] ; $ff49
- xor $64
- ld [rOBP1], a ; $ff49
+.returnAddress
+ ld a, [rOBP1]
+ xor %01100100
+ ld [rOBP1], a
call Delay3
pop bc
dec c
- jr nz, .asm_79f73
+ jr nz, .loop
pop af
- ld [wcfcb], a
+ ld [wUpdateSpritesEnabled], a
jp LoadPlayerSpriteGraphics
-Func_79f92: ; 79f92 (1e:5f92)
- ld a, [wSpriteStateData1 + 9]
- ld hl, PointerTable_79fb0 ; $5fb0
+GetMoveBoulderDustFunctionPointer: ; 79f92 (1e:5f92)
+ ld a, [wSpriteStateData1 + 9] ; player's sprite facing direction
+ ld hl, MoveBoulderDustFunctionPointerTable
ld c, a
ld b, $0
add hl, bc
@@ -51,18 +51,22 @@ Func_79f92: ; 79f92 (1e:5f92)
pop hl
ret
-PointerTable_79fb0: ; 79fb0 (1e:5fb0)
+MoveBoulderDustFunctionPointerTable: ; 79fb0 (1e:5fb0)
+; facing down
db $FF,$00
- dw Func_79350
+ dw AdjustOAMBlockYPos
+; facing up
db $01,$00
- dw Func_79350
+ dw AdjustOAMBlockYPos
+; facing left
db $01,$01
- dw Func_79337
+ dw AdjustOAMBlockXPos
+; facing right
db $FF,$01
- dw Func_79337
+ dw AdjustOAMBlockXPos
LoadSmokeTileFourTimes: ; 79fc0 (1e:5fc0)
ld hl, vChars1 + $7c0
diff --git a/engine/overworld/trainers.asm b/engine/overworld/trainers.asm
index b05ddbf1..4aaab3ed 100755
--- a/engine/overworld/trainers.asm
+++ b/engine/overworld/trainers.asm
@@ -1,9 +1,9 @@
-Func_567f9: ; 567f9 (15:67f9)
+_GetSpritePosition1: ; 567f9 (15:67f9)
ld hl, wSpriteStateData1
ld de, $4
- ld a, [wcf13]
- ld [H_DOWNARROWBLINKCNT2], a ; $ff8c
- call Func_56903
+ ld a, [wSpriteIndex]
+ ld [H_SPRITEINDEX], a
+ call GetSpriteDataPointer
ld a, [hli]
ld [$ffeb], a
inc hl
@@ -17,50 +17,50 @@ Func_567f9: ; 567f9 (15:67f9)
ld [$ffee], a
ret
-Func_56819: ; 56819 (15:6819)
+_GetSpritePosition2: ; 56819 (15:6819)
ld hl, wSpriteStateData1
- ld de, $0004
- ld a, [wcf13]
- ld [H_DOWNARROWBLINKCNT2], a ; $ff8c
- call Func_56903
- ld a, [hli]
+ ld de, $4
+ ld a, [wSpriteIndex]
+ ld [H_SPRITEINDEX], a
+ call GetSpriteDataPointer
+ ld a, [hli] ; c1x4 (screen Y pos)
ld [wd130], a
inc hl
- ld a, [hl]
+ ld a, [hl] ; c1x6 (screen X pos)
ld [wd131], a
- ld de, $00fe
+ ld de, $104 - $6
add hl, de
- ld a, [hli]
+ ld a, [hli] ; c2x4 (map Y pos)
ld [wd132], a
- ld a, [hl]
+ ld a, [hl] ; c2x5 (map X pos)
ld [wd133], a
ret
-Func_5683d: ; 5683d (15:683d)
+_SetSpritePosition1: ; 5683d (15:683d)
ld hl, wSpriteStateData1
ld de, $4
- ld a, [wcf13]
- ld [H_DOWNARROWBLINKCNT2], a ; $ff8c
- call Func_56903
- ld a, [$ffeb]
+ ld a, [wSpriteIndex]
+ ld [H_SPRITEINDEX], a
+ call GetSpriteDataPointer
+ ld a, [$ffeb] ; c1x4 (screen Y pos)
ld [hli], a
inc hl
- ld a, [$ffec]
+ ld a, [$ffec] ; c1x6 (screen X pos)
ld [hl], a
- ld de, $fe
+ ld de, $104 - $6
add hl, de
- ld a, [$ffed]
+ ld a, [$ffed] ; c2x4 (map Y pos)
ld [hli], a
- ld a, [$ffee]
+ ld a, [$ffee] ; c2x5 (map X pos)
ld [hl], a
ret
-Func_5685d: ; 5685d (15:685d)
+_SetSpritePosition2: ; 5685d (15:685d)
ld hl, wSpriteStateData1
ld de, $0004
- ld a, [wcf13]
- ld [H_DOWNARROWBLINKCNT2], a ; $ff8c
- call Func_56903
+ ld a, [wSpriteIndex]
+ ld [H_SPRITEINDEX], a
+ call GetSpriteDataPointer
ld a, [wd130]
ld [hli], a
inc hl
@@ -75,7 +75,7 @@ Func_5685d: ; 5685d (15:685d)
ret
TrainerWalkUpToPlayer: ; 56881 (15:6881)
- ld a, [wcf13]
+ ld a, [wSpriteIndex]
swap a
ld [wTrainerSpriteOffset], a ; wWhichTrade
call ReadTrainerScreenPosition
@@ -139,18 +139,20 @@ TrainerWalkUpToPlayer: ; 56881 (15:6881)
ld b, $0
ld a, $80 ; a = direction to go to
.writeWalkScript
- ld hl, wcc97
- ld de, wcc97
+ ld hl, wNPCMovementDirections2
+ ld de, wNPCMovementDirections2
call FillMemory ; write the necessary steps to reach player
ld [hl], $ff ; write end of list sentinel
- ld a, [wcf13]
- ld [H_DOWNARROWBLINKCNT2], a ; $ff8c
+ ld a, [wSpriteIndex]
+ ld [H_SPRITEINDEX], a
jp MoveSprite_
-Func_56903: ; 56903 (15:6903)
+; input: de = offset within sprite entry
+; output: de = pointer to sprite data
+GetSpriteDataPointer: ; 56903 (15:6903)
push de
add hl, de
- ld a, [H_DOWNARROWBLINKCNT2] ; $ff8c
+ ld a, [H_SPRITEINDEX]
swap a
ld d, $0
ld e, a
diff --git a/engine/palettes.asm b/engine/palettes.asm
index eafd8ef6..67afc12d 100755
--- a/engine/palettes.asm
+++ b/engine/palettes.asm
@@ -380,11 +380,11 @@ SendSGBPacket: ; 71feb (1c:5feb)
LoadSGB: ; 7202b (1c:602b)
xor a
- ld [wcf1b], a
+ ld [wOnSGB], a
call Func_7209b
ret nc
ld a, $1
- ld [wcf1b], a
+ ld [wOnSGB], a
ld a, [wGBC]
and a
jr z, .asm_7203f
diff --git a/engine/play_time.asm b/engine/play_time.asm
index db7d6f67..74da9c59 100755
--- a/engine/play_time.asm
+++ b/engine/play_time.asm
@@ -1,25 +1,25 @@
-Func_18dee: ; 18dee (6:4dee)
- call Func_18e36
+TrackPlayTime: ; 18dee (6:4dee)
+ call CountDownIgnoreInputBitReset
ld a, [wd732]
bit 0, a
ret z
- ld a, [W_PLAYTIMEMINUTES] ; wda42
+ ld a, [W_PLAYTIMEMINUTES]
and a
ret nz
- ld a, [W_PLAYTIMEFRAMES] ; wda45
+ ld a, [W_PLAYTIMEFRAMES]
inc a
- ld [W_PLAYTIMEFRAMES], a ; wda45
+ ld [W_PLAYTIMEFRAMES], a
cp 60
ret nz
xor a
- ld [W_PLAYTIMEFRAMES], a ; wda45
- ld a, [W_PLAYTIMESECONDS] ; wda44
+ ld [W_PLAYTIMEFRAMES], a
+ ld a, [W_PLAYTIMESECONDS]
inc a
- ld [W_PLAYTIMESECONDS], a ; wda44
+ ld [W_PLAYTIMESECONDS], a
cp 60
ret nz
xor a
- ld [W_PLAYTIMESECONDS], a ; wda44
+ ld [W_PLAYTIMESECONDS], a
ld a, [W_PLAYTIMEMINUTES + 1]
inc a
ld [W_PLAYTIMEMINUTES + 1], a
@@ -33,11 +33,11 @@ Func_18dee: ; 18dee (6:4dee)
cp $ff
ret nz
ld a, $ff
- ld [W_PLAYTIMEMINUTES], a ; wda42
+ ld [W_PLAYTIMEMINUTES], a
ret
-Func_18e36: ; 18e36 (6:4e36)
- ld a, [wd13a]
+CountDownIgnoreInputBitReset: ; 18e36 (6:4e36)
+ ld a, [wIgnoreInputCounter]
and a
jr nz, .asm_18e40
ld a, $ff
@@ -45,7 +45,7 @@ Func_18e36: ; 18e36 (6:4e36)
.asm_18e40
dec a
.asm_18e41
- ld [wd13a], a
+ ld [wIgnoreInputCounter], a
and a
ret nz
ld a, [wd730]
diff --git a/engine/predefs.asm b/engine/predefs.asm
index 3ac99585..b73c485a 100755
--- a/engine/predefs.asm
+++ b/engine/predefs.asm
@@ -52,13 +52,13 @@ GetPredefPointer:
PredefPointers:: ; 4fe79 (13:7e79)
; these are pointers to ASM routines.
; they appear to be used in overworld map scripts.
- add_predef Func_3cd60
+ add_predef DrawPlayerHUDAndHPBar
add_predef Func_3f0c6
add_predef Func_3f073
add_predef ScaleSpriteByTwo
add_predef LoadMonBackPic
add_predef Func_79aba
- add_predef Func_f132
+ add_predef LoadMissableObjects
add_predef HealParty
add_predef MoveAnimation; 08 play move animation
add_predef DivideBCDPredef
@@ -71,30 +71,30 @@ PredefPointers:: ; 4fe79 (13:7e79)
add_predef FlagActionPredef
add_predef HideObject
add_predef IsObjectHidden
- add_predef Func_c69c
+ add_predef ApplyOutOfBattlePoisonDamage
add_predef AnyPartyAlive
add_predef ShowObject
add_predef ShowObject2
- add_predef Func_ee9e
+ add_predef ReplaceTileBlock
add_predef InitPlayerData2
- add_predef Func_c754
- add_predef Func_3af5b
+ add_predef LoadTilesetHeader
+ add_predef LearnMoveFromLevelUp
add_predef LearnMove
add_predef IsItemInBag_ ; 1C, used in Pokémon Tower
- dbw $03,Func_3eb5 ; for these two, the bank number is actually 0
+ dbw $03,CheckForHiddenObjectOrBookshelfOrCardKeyDoor ; for these two, the bank number is actually 0
dbw $03,GiveItem
- add_predef Func_480eb
- add_predef Func_f8ba
+ add_predef ChangeBGPalColor0_4Frames
+ add_predef FindPathToPlayer
add_predef Func_480ff
- add_predef Func_f929
- add_predef Func_f9a0
+ add_predef CalcPositionOfPlayerRelativeToNPC
+ add_predef ConvertNPCMovementDirectionsToJoypadMasks
add_predef Func_48125
add_predef UpdateHPBar
add_predef HPBarLength
add_predef Func_5ab0
add_predef Func_3ed02
add_predef ShowPokedexMenu
- add_predef Func_3ad1c
+ add_predef EvolutionAfterBattle
add_predef SaveSAVtoSRAM0
add_predef InitOpponent
add_predef Func_5a5f
@@ -105,7 +105,7 @@ PredefPointers:: ; 4fe79 (13:7e79)
add_predef PlayIntro
add_predef Func_79869
add_predef FlashScreen
- add_predef Func_c586
+ add_predef GetTileAndCoordsInFrontOfPlayer
add_predef StatusScreen
add_predef StatusScreen2
add_predef Func_410e2
@@ -117,7 +117,7 @@ PredefPointers:: ; 4fe79 (13:7e79)
add_predef WriteMonMoves
add_predef SaveSAV
add_predef LoadSGB
- add_predef Func_f113
+ add_predef MarkTownVisitedAndLoadMissableObjects
add_predef SetPartyMonTypes
add_predef CanLearnTM
add_predef TMToMove
@@ -125,7 +125,7 @@ PredefPointers:: ; 4fe79 (13:7e79)
add_predef StarterDex ; 46
add_predef _AddPartyMon
add_predef UpdateHPBar2
- add_predef Func_3cdec
+ add_predef DrawEnemyHUDAndHPBar
add_predef LoadTownMap_Nest
add_predef Func_27d6b
add_predef EmotionBubble; 4C player exclamation
@@ -140,9 +140,9 @@ PredefPointers:: ; 4fe79 (13:7e79)
add_predef HallOfFamePC
add_predef DisplayDexRating
dbw $1E, _LeaveMapAnim ; wrong bank
- dbw $1E, Func_70510 ; wrong bank
- add_predef Func_c5be
- add_predef Func_c60b
+ dbw $1E, EnterMapAnim ; wrong bank
+ add_predef GetTileTwoStepsInFrontOfPlayer
+ add_predef CheckForCollisionWhenPushingBoulder
add_predef PrintStrengthTxt
add_predef PickupItem
add_predef Func_27d98
diff --git a/engine/predefs12.asm b/engine/predefs12.asm
index 380cfc1c..90032a14 100755
--- a/engine/predefs12.asm
+++ b/engine/predefs12.asm
@@ -1,13 +1,14 @@
-Func_480eb: ; 480eb (12:40eb)
+; b = new colour for BG colour 0 (usually white) for 4 frames
+ChangeBGPalColor0_4Frames: ; 480eb (12:40eb)
call GetPredefRegisters
- ld a, [rBGP] ; $ff47
+ ld a, [rBGP]
or b
- ld [rBGP], a ; $ff47
+ ld [rBGP], a
ld c, $4
call DelayFrames
- ld a, [rBGP] ; $ff47
- and $fc
- ld [rBGP], a ; $ff47
+ ld a, [rBGP]
+ and %11111100
+ ld [rBGP], a
ret
Func_480ff: ; 480ff (12:40ff)
diff --git a/engine/predefs7.asm b/engine/predefs7.asm
index 469fe0c4..b6c3bbbc 100755
--- a/engine/predefs7.asm
+++ b/engine/predefs7.asm
@@ -31,7 +31,7 @@ Func_1c9c6: ; 1c9c6 (7:49c6)
ld b, a
ld a, [hl]
ld c, a
- ld hl, wd3af
+ ld hl, wWarpEntries
call Func_1ca0d
Func_1ca0d: ; 1ca0d (7:4a0d)
diff --git a/engine/save.asm b/engine/save.asm
index b473f1cd..e6b1bd94 100755
--- a/engine/save.asm
+++ b/engine/save.asm
@@ -32,11 +32,11 @@ FileDataDestroyedText: ; 7361e (1c:761e)
db "@"
LoadSAVCheckSum: ; 73623 (1c:7623)
- ld a, $a
- ld [$0], a
+ ld a, SRAM_ENABLE
+ ld [MBC1SRamEnable], a
ld a, $1
- ld [$6000], a
- ld [$4000], a
+ ld [MBC1SRamBankingMode], a
+ ld [MBC1SRamBank], a
ld hl, $a598 ; hero name located in SRAM
ld bc, $f8b ; but here checks the full SAV
call SAVCheckSum
@@ -58,30 +58,30 @@ LoadSAVCheckSum: ; 73623 (1c:7623)
ld bc, $b
call CopyData
ld hl, $a5a3
- ld de, wPokedexOwned ; wPokedexOwned
+ ld de, wPokedexOwned
ld bc, $789
call CopyData
- ld hl, W_CURMAPTILESET ; W_CURMAPTILESET
+ ld hl, W_CURMAPTILESET
set 7, [hl]
ld hl, $ad2c
ld de, wSpriteStateData1
ld bc, $200
call CopyData
ld a, [$b522]
- ld [$ffd7], a
+ ld [hTilesetType], a
ld hl, $b0c0
- ld de, W_NUMINBOX ; wda80
- ld bc, $462
+ ld de, W_NUMINBOX
+ ld bc, wBoxMonNicksEnd - W_NUMINBOX
call CopyData
and a
jp SAVGoodChecksum
LoadSAVCheckSum1: ; 73690 (1c:7690)
- ld a, $a
- ld [$0], a
+ ld a, SRAM_ENABLE
+ ld [MBC1SRamEnable], a
ld a, $1
- ld [$6000], a
- ld [$4000], a
+ ld [MBC1SRamBankingMode], a
+ ld [MBC1SRamBank], a
ld hl, $a598 ; hero name located in SRAM
ld bc, $f8b ; but here checks the full SAV
call SAVCheckSum
@@ -90,18 +90,18 @@ LoadSAVCheckSum1: ; 73690 (1c:7690)
cp c
jr nz, SAVBadCheckSum
ld hl, $b0c0
- ld de, W_NUMINBOX ; wda80
- ld bc, $462
+ ld de, W_NUMINBOX
+ ld bc, wBoxMonNicksEnd - W_NUMINBOX
call CopyData
and a
jp SAVGoodChecksum
LoadSAVCheckSum2: ; 736bd (1c:76bd)
- ld a, $a
- ld [$0], a
+ ld a, SRAM_ENABLE
+ ld [MBC1SRamEnable], a
ld a, $1
- ld [$6000], a
- ld [$4000], a
+ ld [MBC1SRamBankingMode], a
+ ld [MBC1SRamBank], a
ld hl, $a598 ; hero name located in SRAM
ld bc, $f8b ; but here checks the full SAV
call SAVCheckSum
@@ -125,8 +125,8 @@ SAVBadCheckSum: ; 736f7 (1c:76f7)
SAVGoodChecksum: ; 736f8 (1c:76f8)
ld a, $0
- ld [$6000], a
- ld [$0], a
+ ld [MBC1SRamBankingMode], a
+ ld [MBC1SRamEnable], a
ret
Func_73701: ; 0x73701
@@ -193,67 +193,67 @@ OlderFileWillBeErasedText: ; 73787 (1c:7787)
db "@"
SaveSAVtoSRAM0: ; 7378c (1c:778c)
- ld a, $a
- ld [$0], a
+ ld a, SRAM_ENABLE
+ ld [MBC1SRamEnable], a
ld a, $1
- ld [$6000], a
- ld [$4000], a
- ld hl, wPlayerName ; wd158
+ ld [MBC1SRamBankingMode], a
+ ld [MBC1SRamBank], a
+ ld hl, wPlayerName
ld de, $a598
ld bc, $b
call CopyData
- ld hl, wPokedexOwned ; wPokedexOwned
+ ld hl, wPokedexOwned
ld de, $a5a3
- ld bc, $789
+ ld bc, W_NUMINBOX - wPokedexOwned
call CopyData
- ld hl, wSpriteStateData1 ; OAM?
+ ld hl, wSpriteStateData1
ld de, $ad2c
ld bc, $200
call CopyData
- ld hl, W_NUMINBOX ; wda80
+ ld hl, W_NUMINBOX
ld de, $b0c0
- ld bc, $462
+ ld bc, wBoxMonNicksEnd - W_NUMINBOX
call CopyData
- ld a, [$ffd7]
+ ld a, [hTilesetType]
ld [$b522], a
ld hl, $a598
ld bc, $f8b
call SAVCheckSum
ld [$b523], a
xor a
- ld [$6000], a
- ld [$0], a
+ ld [MBC1SRamBankingMode], a
+ ld [MBC1SRamEnable], a
ret
SaveSAVtoSRAM1: ; 737e2 (1c:77e2)
; stored pokémon
- ld a, $a
- ld [$0], a
+ ld a, SRAM_ENABLE
+ ld [MBC1SRamEnable], a
ld a, $1
- ld [$6000], a
- ld [$4000], a
- ld hl, W_NUMINBOX ; wda80
+ ld [MBC1SRamBankingMode], a
+ ld [MBC1SRamBank], a
+ ld hl, W_NUMINBOX
ld de, $b0c0
- ld bc, $462
+ ld bc, wBoxMonNicksEnd - W_NUMINBOX
call CopyData
ld hl, $a598
ld bc, $f8b
call SAVCheckSum
ld [$b523], a
xor a
- ld [$6000], a
- ld [$0], a
+ ld [MBC1SRamBankingMode], a
+ ld [MBC1SRamEnable], a
ret
SaveSAVtoSRAM2: ; 7380f (1c:780f)
- ld a, $a
- ld [$0], a
+ ld a, SRAM_ENABLE
+ ld [MBC1SRamEnable], a
ld a, $1
- ld [$6000], a
- ld [$4000], a
- ld hl, wPartyCount ; wPartyCount
+ ld [MBC1SRamBankingMode], a
+ ld [MBC1SRamBank], a
+ ld hl, wPartyCount
ld de, $af2c
- ld bc, $194
+ ld bc, wPokedexOwned - wPartyCount
call CopyData
ld hl, wPokedexOwned ; pokédex only
ld de, $a5a3
@@ -264,8 +264,8 @@ SaveSAVtoSRAM2: ; 7380f (1c:780f)
call SAVCheckSum
ld [$b523], a
xor a
- ld [$6000], a
- ld [$0], a
+ ld [MBC1SRamBankingMode], a
+ ld [MBC1SRamEnable], a
ret
SaveSAVtoSRAM: ; 73848 (1c:7848)
@@ -334,13 +334,13 @@ PointerTable_73895: ; 73895 (1c:7895)
dw $B188
dw $B5EA
-Func_738a1:: ; 738a1 (1c:78a1)
+ChangeBox:: ; 738a1 (1c:78a1)
ld hl, WhenYouChangeBoxText
call PrintText
call YesNoChoice
- ld a, [wCurrentMenuItem] ; wCurrentMenuItem
+ ld a, [wCurrentMenuItem]
and a
- ret nz
+ ret nz ; return if No was chosen
ld hl, wd5a0
bit 7, [hl]
call z, Func_73a29
@@ -356,25 +356,25 @@ Func_738a1:: ; 738a1 (1c:78a1)
call Func_7387b
ld e, l
ld d, h
- ld hl, W_NUMINBOX ; wda80
+ ld hl, W_NUMINBOX
call Func_7390e
- ld a, [wCurrentMenuItem] ; wCurrentMenuItem
+ ld a, [wCurrentMenuItem]
set 7, a
ld [wd5a0], a
call Func_7387b
- ld de, W_NUMINBOX ; wda80
+ ld de, W_NUMINBOX
call Func_7390e
- ld hl, W_MAPTEXTPTR ; wd36c
- ld de, wWhichTrade ; wWhichTrade
+ ld hl, W_MAPTEXTPTR
+ ld de, wChangeBoxSavedMapTextPointer
ld a, [hli]
ld [de], a
inc de
ld a, [hl]
ld [de], a
- call Func_3f05
+ call RestoreMapTextPointer
call SaveSAVtoSRAM
- ld hl, wWhichTrade ; wWhichTrade
- call Func_3f0f
+ ld hl, wChangeBoxSavedMapTextPointer
+ call SetMapTextPointer
ld a, (SFX_02_5d - SFX_Headers_02) / 3
call PlaySoundWaitForCurrent
call WaitForSoundToFinish
@@ -386,12 +386,12 @@ WhenYouChangeBoxText: ; 73909 (1c:7909)
Func_7390e: ; 7390e (1c:790e)
push hl
- ld a, $a
- ld [$0], a
+ ld a, SRAM_ENABLE
+ ld [MBC1SRamEnable], a
ld a, $1
- ld [$6000], a
+ ld [MBC1SRamBankingMode], a
ld a, b
- ld [$4000], a
+ ld [MBC1SRamBank], a
ld bc, $462
call CopyData
pop hl
@@ -405,8 +405,8 @@ Func_7390e: ; 7390e (1c:790e)
ld [$ba4c], a
call Func_73863
xor a
- ld [$6000], a
- ld [$0], a
+ ld [MBC1SRamBankingMode], a
+ ld [MBC1SRamEnable], a
ret
Func_7393f: ; 7393f (1c:793f)
@@ -502,19 +502,19 @@ BoxNoText: ; 73a21 (1c:7a21)
db "BOX No.@"
Func_73a29: ; 73a29 (1c:7a29)
- ld a, $a
- ld [$0], a
+ ld a, SRAM_ENABLE
+ ld [MBC1SRamEnable], a
ld a, $1
- ld [$6000], a
+ ld [MBC1SRamBankingMode], a
ld a, $2
- ld [$4000], a
+ ld [MBC1SRamBank], a
call Func_73a4b
ld a, $3
- ld [$4000], a
+ ld [MBC1SRamBank], a
call Func_73a4b
xor a
- ld [$6000], a
- ld [$0], a
+ ld [MBC1SRamBankingMode], a
+ ld [MBC1SRamEnable], a
ret
Func_73a4b: ; 73a4b (1c:7a4b)
@@ -547,19 +547,19 @@ Func_73a7f: ; 73a7f (1c:7a7f)
Func_73a84: ; 73a84 (1c:7a84)
ld hl, wWhichTrade ; wWhichTrade
push hl
- ld a, $a
- ld [$0], a
+ ld a, SRAM_ENABLE
+ ld [MBC1SRamEnable], a
ld a, $1
- ld [$6000], a
+ ld [MBC1SRamBankingMode], a
ld a, $2
- ld [$4000], a
+ ld [MBC1SRamBank], a
call Func_73ab8
ld a, $3
- ld [$4000], a
+ ld [MBC1SRamBank], a
call Func_73ab8
xor a
- ld [$6000], a
- ld [$0], a
+ ld [MBC1SRamBankingMode], a
+ ld [MBC1SRamEnable], a
pop hl
ld a, [wd5a0]
and $7f
@@ -592,8 +592,8 @@ SAVCheckRandomID: ;$7ad1
ld a,$0a
ld [$0000],a
ld a,$01
- ld [$6000],a
- ld [$4000],a
+ ld [MBC1SRamBankingMode],a
+ ld [MBC1SRamBank],a
ld a,[$a598]
and a
jr z,.next
@@ -615,7 +615,7 @@ SAVCheckRandomID: ;$7ad1
cp h
.next
ld a,$00
- ld [$6000],a
+ ld [MBC1SRamBankingMode],a
ld [$0000],a
ret
@@ -653,23 +653,23 @@ LoadHallOfFameTeams: ; 73b3f (1c:7b3f)
; fallthrough
HallOfFame_Copy: ; 73b51 (1c:7b51)
- ld a, $a
- ld [$0], a
+ ld a, SRAM_ENABLE
+ ld [MBC1SRamEnable], a
ld a, $1
- ld [$6000], a
+ ld [MBC1SRamBankingMode], a
xor a
- ld [$4000], a
+ ld [MBC1SRamBank], a
call CopyData
xor a
- ld [$6000], a
- ld [$0], a
+ ld [MBC1SRamBankingMode], a
+ ld [MBC1SRamEnable], a
ret
Func_73b6a: ; 73b6a (1c:7b6a)
- ld a, $a
- ld [$0], a
+ ld a, SRAM_ENABLE
+ ld [MBC1SRamEnable], a
ld a, $1
- ld [$6000], a
+ ld [MBC1SRamBankingMode], a
xor a
call PadSRAM_FF
ld a, $1
@@ -679,12 +679,12 @@ Func_73b6a: ; 73b6a (1c:7b6a)
ld a, $3
call PadSRAM_FF
xor a
- ld [$6000], a
- ld [$0], a
+ ld [MBC1SRamBankingMode], a
+ ld [MBC1SRamEnable], a
ret
PadSRAM_FF: ; 73b8f (1c:7b8f)
- ld [$4000], a
+ ld [MBC1SRamBank], a
ld hl, $a000
ld bc, $2000
ld a, $ff
diff --git a/engine/slot_machine.asm b/engine/slot_machine.asm
index 9ded4f36..b24b2d25 100755
--- a/engine/slot_machine.asm
+++ b/engine/slot_machine.asm
@@ -1,7 +1,7 @@
PromptUserToPlaySlots: ; 3730e (d:730e)
call SaveScreenTilesToBuffer2
ld a, BANK(DisplayTextIDInit)
- ld [wcf0c], a
+ ld [wAutoTextBoxDrawingControl], a
ld b, a
ld hl, DisplayTextIDInit
call Bankswitch
@@ -12,7 +12,7 @@ PromptUserToPlaySlots: ; 3730e (d:730e)
and a
jr nz, .skip
dec a
- ld [wcfcb], a
+ ld [wUpdateSpritesEnabled], a
ld hl, wcd4f
xor a
ld [hli], a
@@ -40,9 +40,9 @@ PromptUserToPlaySlots: ; 3730e (d:730e)
ld [W_SUBANIMSUBENTRYADDR], a
call GBPalWhiteOutWithDelay3
ld a, $1
- ld [wcfcb], a
+ ld [wUpdateSpritesEnabled], a
call GoPAL_SET_CF1C
- call Func_3e08
+ call ReloadMapSpriteTilePatterns
call ReloadTilesetTilePatterns
.skip
call LoadScreenTilesFromBuffer2
@@ -221,7 +221,7 @@ SlotMachine_374ad: ; 374ad (d:74ad)
call SlotMachine_374fb
call SlotMachine_37517
ret c
- ld a, [wcf1b]
+ ld a, [wOnSGB]
xor $1
inc a
ld c, a
diff --git a/engine/titlescreen.asm b/engine/titlescreen.asm
index 10c5fad4..ca81eff8 100755
--- a/engine/titlescreen.asm
+++ b/engine/titlescreen.asm
@@ -11,7 +11,7 @@ SetDefaultNamesBeforeTitlescreen: ; 42b7 (1:42b7)
ld de, W_RIVALNAME ; wd34a
call CopyFixedLengthText
xor a
- ld [$ffb0], a
+ ld [hVBlankWY], a
ld [wd358], a
ld hl, wd732
ld [hli], a
@@ -26,12 +26,12 @@ LoadTitlescreenGraphics: ; 42dd (1:42dd)
ld a, $1
ld [H_AUTOBGTRANSFERENABLED], a ; $ffba
xor a
- ld [$ffd7], a
+ ld [hTilesetType], a
ld [$ffae], a
ld a, $40
ld [$ffaf], a
ld a, $90
- ld [$ffb0], a
+ ld [hVBlankWY], a
call ClearScreen
call DisableLCD
call LoadFontTilePatterns
@@ -127,7 +127,7 @@ ENDC
call Func_4533
call SaveScreenTilesToBuffer1
ld a, $40
- ld [$ffb0], a
+ ld [hVBlankWY], a
call LoadScreenTilesFromBuffer2
ld a, $98
call Func_4533
@@ -182,7 +182,7 @@ ENDC
call PlaySound
call PrintGameVersionOnTitleScreen
ld a, $90
- ld [$ffb0], a
+ ld [hVBlankWY], a
ld d, $90
.asm_440a
ld h, d
@@ -225,7 +225,7 @@ ENDC
call GBPalWhiteOutWithDelay3
call ClearSprites
xor a
- ld [$ffb0], a
+ ld [hVBlankWY], a
inc a
ld [H_AUTOBGTRANSFERENABLED], a ; $ffba
call ClearScreen
@@ -270,7 +270,7 @@ Func_4496: ; 4496 (1:4496)
call Func_4524
ld a, $90
- ld [$ffb0], a
+ ld [hVBlankWY], a
ld d, 1 ; scroll out
callba TitleScroll
ret
@@ -279,7 +279,7 @@ Func_44c1: ; 44c1 (1:44c1)
ld d, 0 ; scroll in
callba TitleScroll
xor a
- ld [$ffb0], a
+ ld [hVBlankWY], a
ret
Func_44cf: ; 44cf (1:44cf)
@@ -353,7 +353,7 @@ Func_4533: ; 4533 (1:4533)
LoadCopyrightAndTextBoxTiles: ; 4538 (1:4538)
xor a
- ld [$ffb0], a
+ ld [hVBlankWY], a
call ClearScreen
call LoadTextBoxTilePatterns
diff --git a/engine/town_map.asm b/engine/town_map.asm
index 5e8b77de..dece8d1f 100755
--- a/engine/town_map.asm
+++ b/engine/town_map.asm
@@ -1,6 +1,6 @@
DisplayTownMap: ; 70e3e (1c:4e3e)
call LoadTownMap
- ld hl, wcfcb
+ ld hl, wUpdateSpritesEnabled
ld a, [hl]
push af
ld [hl], $ff
@@ -64,7 +64,7 @@ Func_70e92: ; 70e92 (1c:4e92)
ld bc, $10
call CopyData
.asm_70ec8
- call Func_716c6
+ call TownMapSpriteBlinkingAnimation
call JoypadLowSensitivity
ld a, [hJoy5]
ld b, a
@@ -77,9 +77,9 @@ Func_70e92: ; 70e92 (1c:4e92)
bit 7, b
jr nz, .asm_70f01
xor a
- ld [wd09b], a
+ ld [wTownMapSpriteBlinkingEnabled], a
ld [hJoy7], a
- ld [W_SUBANIMTRANSFORM], a ; W_SUBANIMTRANSFORM
+ ld [wTownMapSpriteBlinkingCounter], a
call Func_711ab
pop hl
pop af
@@ -111,7 +111,7 @@ TownMapCursor: ; 70f40 (1c:4f40)
LoadTownMap_Nest: ; 70f60 (1c:4f60)
call LoadTownMap
- ld hl, wcfcb
+ ld hl, wUpdateSpritesEnabled
ld a, [hl]
push af
ld [hl], $ff
@@ -148,7 +148,7 @@ LoadTownMap_Fly: ; 70f90 (1c:4f90)
ld bc, (BANK(TownMapUpArrow) << 8) + $01
call CopyVideoDataDouble
call Func_71070
- ld hl, wcfcb
+ ld hl, wUpdateSpritesEnabled
ld a, [hl]
push af
ld [hl], $ff
@@ -206,14 +206,14 @@ LoadTownMap_Fly: ; 70f90 (1c:4f90)
ld a, (SFX_02_3e - SFX_Headers_02) / 3
call PlaySound
ld a, [hl]
- ld [wd71a], a
+ ld [wDestinationMap], a
ld hl, wd732
set 3, [hl]
inc hl
set 7, [hl]
.asm_71037
xor a
- ld [wd09b], a
+ ld [wTownMapSpriteBlinkingEnabled], a
call GBPalWhiteOutWithDelay3
pop hl
pop af
@@ -319,9 +319,9 @@ LoadTownMap: ; 7109b (1c:509b)
call Delay3
call GBPalNormal
xor a
- ld [W_SUBANIMTRANSFORM], a ; W_SUBANIMTRANSFORM
+ ld [wTownMapSpriteBlinkingCounter], a
inc a
- ld [wd09b], a
+ ld [wTownMapSpriteBlinkingEnabled], a
ret
CompressedMap: ; 71100 (1c:5100)
@@ -330,7 +330,7 @@ CompressedMap: ; 71100 (1c:5100)
Func_711ab: ; 711ab (1c:51ab)
xor a
- ld [wd09b], a
+ ld [wTownMapSpriteBlinkingEnabled], a
call GBPalWhiteOut
call ClearScreen
call ClearSprites
@@ -570,29 +570,30 @@ INCLUDE "text/map_names.asm"
MonNestIcon: ; 716be (1c:56be)
INCBIN "gfx/mon_nest_icon.1bpp"
-Func_716c6: ; 716c6 (1c:56c6)
- ld a, [W_SUBANIMTRANSFORM] ; W_SUBANIMTRANSFORM
+TownMapSpriteBlinkingAnimation: ; 716c6 (1c:56c6)
+ ld a, [wTownMapSpriteBlinkingCounter]
inc a
- cp $19
- jr z, .asm_716e1
- cp $32
- jr nz, .asm_716f1
+ cp 25
+ jr z, .hideSprites
+ cp 50
+ jr nz, .done
+; show sprites when the counter reaches 50
ld hl, wTileMapBackup
ld de, wOAMBuffer
ld bc, $90
call CopyData
xor a
- jr .asm_716f1
-.asm_716e1
+ jr .done
+.hideSprites
ld hl, wOAMBuffer
ld b, $24
ld de, $4
-.asm_716e9
+.hideSpritesLoop
ld [hl], $a0
add hl, de
dec b
- jr nz, .asm_716e9
- ld a, $19
-.asm_716f1
- ld [W_SUBANIMTRANSFORM], a ; W_SUBANIMTRANSFORM
+ jr nz, .hideSpritesLoop
+ ld a, 25
+.done
+ ld [wTownMapSpriteBlinkingCounter], a
jp DelayFrame
diff --git a/engine/town_map.asm.orig b/engine/town_map.asm.orig
new file mode 100755
index 00000000..9ccc03c0
--- /dev/null
+++ b/engine/town_map.asm.orig
@@ -0,0 +1,605 @@
+DisplayTownMap: ; 70e3e (1c:4e3e)
+ call LoadTownMap
+ ld hl, wUpdateSpritesEnabled
+ ld a, [hl]
+ push af
+ ld [hl], $ff
+ push hl
+ ld a, $1
+ ld [hJoy7], a
+ ld a, [W_CURMAP] ; W_CURMAP
+ push af
+ ld b, $0
+ call Func_711c4
+ hlCoord 1, 0
+ ld de, wcd6d
+ call PlaceString
+ ld hl, wOAMBuffer
+ ld de, wTileMapBackup
+ ld bc, $10
+ call CopyData
+ ld hl, vSprites + $40
+ ld de, TownMapCursor ; $4f40
+ ld bc, (BANK(TownMapCursor) << 8) + $04
+ call CopyVideoDataDouble
+ xor a
+ ld [wWhichTrade], a ; wWhichTrade
+ pop af
+ jr Func_70e92
+
+Func_70e7e: ; 70e7e (1c:4e7e)
+ ld hl, wTileMap
+ ld bc, $114
+ call ClearScreenArea
+ ld hl, TownMapOrder ; $4f11
+ ld a, [wWhichTrade] ; wWhichTrade
+ ld c, a
+ ld b, $0
+ add hl, bc
+ ld a, [hl]
+
+Func_70e92: ; 70e92 (1c:4e92)
+ ld de, wHPBarMaxHP
+ call Func_712f1
+ ld a, [de]
+ push hl
+ call Func_71258
+ ld a, $4
+ ld [wcd5b], a
+ ld hl, wOAMBuffer + $10
+ call Func_71279
+ pop hl
+ ld de, wcd6d
+.asm_70eac
+ ld a, [hli]
+ ld [de], a
+ inc de
+ cp $50
+ jr nz, .asm_70eac
+ hlCoord 1, 0
+ ld de, wcd6d
+ call PlaceString
+ ld hl, wOAMBuffer + $10
+ ld de, wTileMapBackup + 16
+ ld bc, $10
+ call CopyData
+.asm_70ec8
+ call TownMapSpriteBlinkingAnimation
+ call JoypadLowSensitivity
+ ld a, [hJoy5]
+ ld b, a
+ and $c3
+ jr z, .asm_70ec8
+ ld a, (SFX_02_3c - SFX_Headers_02) / 3
+ call PlaySound
+ bit 6, b
+ jr nz, .asm_70ef2
+ bit 7, b
+ jr nz, .asm_70f01
+ xor a
+<<<<<<< HEAD
+ ld [wd09b], a
+ ld [hJoy7], a
+ ld [W_SUBANIMTRANSFORM], a ; W_SUBANIMTRANSFORM
+=======
+ ld [wTownMapSpriteBlinkingEnabled], a
+ ld [$ffb7], a
+ ld [wTownMapSpriteBlinkingCounter], a
+>>>>>>> yama/master
+ call Func_711ab
+ pop hl
+ pop af
+ ld [hl], a
+ ret
+.asm_70ef2
+ ld a, [wWhichTrade] ; wWhichTrade
+ inc a
+ cp $2f
+ jr nz, .asm_70efb
+ xor a
+.asm_70efb
+ ld [wWhichTrade], a ; wWhichTrade
+ jp Func_70e7e
+.asm_70f01
+ ld a, [wWhichTrade] ; wWhichTrade
+ dec a
+ cp $ff
+ jr nz, .asm_70f0b
+ ld a, $2e
+.asm_70f0b
+ ld [wWhichTrade], a ; wWhichTrade
+ jp Func_70e7e
+
+INCLUDE "data/town_map_order.asm"
+
+TownMapCursor: ; 70f40 (1c:4f40)
+ INCBIN "gfx/town_map_cursor.1bpp"
+
+LoadTownMap_Nest: ; 70f60 (1c:4f60)
+ call LoadTownMap
+ ld hl, wUpdateSpritesEnabled
+ ld a, [hl]
+ push af
+ ld [hl], $ff
+ push hl
+ call Func_711ef
+ call GetMonName
+ hlCoord 1, 0
+ call PlaceString
+ ld h, b
+ ld l, c
+ ld de, MonsNestText
+ call PlaceString
+ call WaitForTextScrollButtonPress
+ call Func_711ab
+ pop hl
+ pop af
+ ld [hl], a
+ ret
+
+MonsNestText: ; 70f89 (1c:4f89)
+ db "'s NEST@"
+
+LoadTownMap_Fly: ; 70f90 (1c:4f90)
+ call ClearSprites
+ call LoadTownMap
+ call LoadPlayerSpriteGraphics
+ call LoadFontTilePatterns
+ ld de, BirdSprite ; $4d80
+ ld hl, vSprites + $40
+ ld bc, (BANK(BirdSprite) << 8) + $0c
+ call CopyVideoData
+ ld de, TownMapUpArrow ; $5093
+ ld hl, vChars1 + $6d0
+ ld bc, (BANK(TownMapUpArrow) << 8) + $01
+ call CopyVideoDataDouble
+ call Func_71070
+ ld hl, wUpdateSpritesEnabled
+ ld a, [hl]
+ push af
+ ld [hl], $ff
+ push hl
+ ld hl, wTileMap
+ ld de, ToText
+ call PlaceString
+ ld a, [W_CURMAP] ; W_CURMAP
+ ld b, $0
+ call Func_711c4
+ ld hl, wTrainerEngageDistance
+ deCoord 18, 0
+
+.townMapFlyLoop
+ ld a, $7f
+ ld [de], a
+ push hl
+ push hl
+ hlCoord 3, 0
+ ld bc, $10f
+ call ClearScreenArea
+ pop hl
+ ld a, [hl]
+ ld b, $4
+ call Func_711c4
+ hlCoord 3, 0
+ ld de, wcd6d
+ call PlaceString
+ ld c, $f
+ call DelayFrames
+ hlCoord 18, 0
+ ld [hl], $ed
+ hlCoord 19, 0
+ ld [hl], $ee
+ pop hl
+.asm_71004
+ push hl
+ call DelayFrame
+ call JoypadLowSensitivity
+ ld a, [hJoy5]
+ ld b, a
+ pop hl
+ and $c3
+ jr z, .asm_71004
+ bit 0, b
+ jr nz, .asm_71026
+ ld a, (SFX_02_3c - SFX_Headers_02) / 3
+ call PlaySound
+ bit 6, b
+ jr nz, .asm_71042
+ bit 7, b
+ jr nz, .asm_71058
+ jr .asm_71037
+.asm_71026
+ ld a, (SFX_02_3e - SFX_Headers_02) / 3
+ call PlaySound
+ ld a, [hl]
+ ld [wDestinationMap], a
+ ld hl, wd732
+ set 3, [hl]
+ inc hl
+ set 7, [hl]
+.asm_71037
+ xor a
+ ld [wTownMapSpriteBlinkingEnabled], a
+ call GBPalWhiteOutWithDelay3
+ pop hl
+ pop af
+ ld [hl], a
+ ret
+.asm_71042
+ deCoord 18, 0
+ inc hl
+ ld a, [hl]
+ cp $ff
+ jr z, .asm_71052
+ cp $fe
+ jr z, .asm_71042
+ jp .townMapFlyLoop
+.asm_71052
+ ld hl, wTrainerEngageDistance
+ jp .townMapFlyLoop
+.asm_71058
+ deCoord 19, 0
+ dec hl
+ ld a, [hl]
+ cp $ff
+ jr z, .asm_71068
+ cp $fe
+ jr z, .asm_71058
+ jp .townMapFlyLoop
+.asm_71068
+ ld hl, wcd49
+ jr .asm_71058
+
+ToText: ; 7106d (1c:506d)
+ db "To@"
+
+Func_71070: ; 71070 (1c:5070)
+ ld hl, wWhichTrade ; wWhichTrade
+ ld [hl], $ff
+ inc hl
+ ld a, [W_TOWNVISITEDFLAG]
+ ld e, a
+ ld a, [W_TOWNVISITEDFLAG + 1]
+ ld d, a
+ ld bc, $b
+.asm_71081
+ srl d
+ rr e
+ ld a, $fe
+ jr nc, .asm_7108a
+ ld a, b
+.asm_7108a
+ ld [hl], a
+ inc hl
+ inc b
+ dec c
+ jr nz, .asm_71081
+ ld [hl], $ff
+ ret
+
+TownMapUpArrow: ; 71093 (1c:5093)
+ INCBIN "gfx/up_arrow.1bpp"
+
+LoadTownMap: ; 7109b (1c:509b)
+ call GBPalWhiteOutWithDelay3
+ call ClearScreen
+ call UpdateSprites
+ ld hl, wTileMap
+ ld b, $12
+ ld c, $12
+ call TextBoxBorder
+ call DisableLCD
+ ld hl, WorldMapTileGraphics ; $65a8
+ ld de, vChars2 + $600
+ ld bc, $100
+ ld a, BANK(WorldMapTileGraphics)
+ call FarCopyData2
+ ld hl, MonNestIcon ; $56be
+ ld de, vSprites + $40
+ ld bc, $8
+ ld a, BANK(MonNestIcon)
+ call FarCopyDataDouble
+ ld hl, wTileMap
+ ld de, CompressedMap ; $5100
+.asm_710d3
+ ld a, [de]
+ and a
+ jr z, .asm_710e9
+ ld b, a
+ and $f
+ ld c, a
+ ld a, b
+ swap a
+ and $f
+ add $60
+.asm_710e2
+ ld [hli], a
+ dec c
+ jr nz, .asm_710e2
+ inc de
+ jr .asm_710d3
+.asm_710e9
+ call EnableLCD
+ ld b, $2
+ call GoPAL_SET
+ call Delay3
+ call GBPalNormal
+ xor a
+ ld [wTownMapSpriteBlinkingCounter], a
+ inc a
+ ld [wTownMapSpriteBlinkingEnabled], a
+ ret
+
+CompressedMap: ; 71100 (1c:5100)
+; you can decompress this file with the redrle program in the extras/ dir
+ INCBIN "gfx/town_map.rle"
+
+Func_711ab: ; 711ab (1c:51ab)
+ xor a
+ ld [wTownMapSpriteBlinkingEnabled], a
+ call GBPalWhiteOut
+ call ClearScreen
+ call ClearSprites
+ call LoadPlayerSpriteGraphics
+ call LoadFontTilePatterns
+ call UpdateSprites
+ jp GoPAL_SET_CF1C
+
+Func_711c4: ; 711c4 (1c:51c4)
+ push af
+ ld a, b
+ ld [wcd5b], a
+ pop af
+ ld de, wHPBarMaxHP
+ call Func_712f1
+ ld a, [de]
+ push hl
+ call Func_71258
+ call Func_7126d
+ pop hl
+ ld de, wcd6d
+.asm_711dc
+ ld a, [hli]
+ ld [de], a
+ inc de
+ cp $50
+ jr nz, .asm_711dc
+ ld hl, wOAMBuffer
+ ld de, wTileMapBackup
+ ld bc, $a0
+ jp CopyData
+
+Func_711ef: ; 711ef (1c:51ef)
+ callba Func_e9cb
+ call Func_712d9
+ ld hl, wOAMBuffer
+ ld de, wHPBarMaxHP
+.asm_71200
+ ld a, [de]
+ cp $ff
+ jr z, .asm_7121d
+ and a
+ jr z, .asm_7121a
+ push hl
+ call Func_712f1
+ pop hl
+ ld a, [de]
+ cp $19
+ jr z, .asm_7121a
+ call Func_71258
+ ld a, $4
+ ld [hli], a
+ xor a
+ ld [hli], a
+.asm_7121a
+ inc de
+ jr .asm_71200
+.asm_7121d
+ ld a, l
+ and a
+ jr nz, .asm_71236
+ hlCoord 1, 7
+ ld b, $2
+ ld c, $f
+ call TextBoxBorder
+ hlCoord 2, 9
+ ld de, AreaUnknownText
+ call PlaceString
+ jr .asm_7123e
+.asm_71236
+ ld a, [W_CURMAP] ; W_CURMAP
+ ld b, $0
+ call Func_711c4
+.asm_7123e
+ ld hl, wOAMBuffer
+ ld de, wTileMapBackup
+ ld bc, $a0
+ jp CopyData
+
+AreaUnknownText: ; 7124a (1c:524a)
+ db " AREA UNKNOWN@"
+
+Func_71258: ; 71258 (1c:5258)
+ push af
+ and $f0
+ srl a
+ add $18
+ ld b, a
+ ld [hli], a
+ pop af
+ and $f
+ swap a
+ srl a
+ add $18
+ ld c, a
+ ld [hli], a
+ ret
+
+Func_7126d: ; 7126d (1c:526d)
+ ld a, [wcd5b]
+ and a
+ ld hl, wOAMBuffer + $90
+ jr z, Func_71279
+ ld hl, wOAMBuffer + $80
+
+Func_71279: ; 71279 (1c:5279)
+ push hl
+ ld hl, $fcfc
+ add hl, bc
+ ld b, h
+ ld c, l
+ pop hl
+
+Func_71281: ; 71281 (1c:5281)
+ ld de, $202
+.asm_71284
+ push de
+ push bc
+.asm_71286
+ ld a, b
+ ld [hli], a
+ ld a, c
+ ld [hli], a
+ ld a, [wcd5b]
+ ld [hli], a
+ inc a
+ ld [wcd5b], a
+ xor a
+ ld [hli], a
+ inc d
+ ld a, $8
+ add c
+ ld c, a
+ dec e
+ jr nz, .asm_71286
+ pop bc
+ pop de
+ ld a, $8
+ add b
+ ld b, a
+ dec d
+ jr nz, .asm_71284
+ ret
+
+Func_712a6: ; 712a6 (1c:52a6)
+ xor a
+ ld [wcd5c], a
+ ld de, $202
+.asm_712ad
+ push de
+ push bc
+.asm_712af
+ ld a, b
+ ld [hli], a
+ ld a, c
+ ld [hli], a
+ ld a, [wcd5b]
+ ld [hli], a
+ ld a, [wcd5c]
+ ld [hli], a
+ xor $20
+ ld [wcd5c], a
+ inc d
+ ld a, $8
+ add c
+ ld c, a
+ dec e
+ jr nz, .asm_712af
+ pop bc
+ pop de
+ push hl
+ ld hl, wcd5b
+ inc [hl]
+ inc [hl]
+ pop hl
+ ld a, $8
+ add b
+ ld b, a
+ dec d
+ jr nz, .asm_712ad
+ ret
+
+Func_712d9: ; 712d9 (1c:52d9)
+ ld de, wHPBarMaxHP
+.asm_712dc
+ ld a, [de]
+ inc de
+ cp $ff
+ ret z
+ ld c, a
+ ld l, e
+ ld h, d
+.asm_712e4
+ ld a, [hl]
+ cp $ff
+ jr z, .asm_712dc
+ cp c
+ jr nz, .asm_712ee
+ xor a
+ ld [hl], a
+.asm_712ee
+ inc hl
+ jr .asm_712e4
+
+Func_712f1: ; 712f1 (1c:52f1)
+ cp REDS_HOUSE_1F
+ jr c, .asm_71304
+ ld bc, $4
+ ld hl, InternalMapEntries ; $5382
+.asm_712fb
+ cp [hl]
+ jr c, .asm_71301
+ add hl, bc
+ jr .asm_712fb
+.asm_71301
+ inc hl
+ jr .asm_7130d
+.asm_71304
+ ld hl, ExternalMapEntries ; $5313
+ ld c, a
+ ld b, $0
+ add hl, bc
+ add hl, bc
+ add hl, bc
+.asm_7130d
+ ld a, [hli]
+ ld [de], a
+ ld a, [hli]
+ ld h, [hl]
+ ld l, a
+ ret
+
+INCLUDE "data/town_map_entries.asm"
+
+INCLUDE "text/map_names.asm"
+
+MonNestIcon: ; 716be (1c:56be)
+ INCBIN "gfx/mon_nest_icon.1bpp"
+
+TownMapSpriteBlinkingAnimation: ; 716c6 (1c:56c6)
+ ld a, [wTownMapSpriteBlinkingCounter]
+ inc a
+ cp 25
+ jr z, .hideSprites
+ cp 50
+ jr nz, .done
+; show sprites when the counter reaches 50
+ ld hl, wTileMapBackup
+ ld de, wOAMBuffer
+ ld bc, $90
+ call CopyData
+ xor a
+ jr .done
+.hideSprites
+ ld hl, wOAMBuffer
+ ld b, $24
+ ld de, $4
+.hideSpritesLoop
+ ld [hl], $a0
+ add hl, de
+ dec b
+ jr nz, .hideSpritesLoop
+ ld a, 25
+.done
+ ld [wTownMapSpriteBlinkingCounter], a
+ jp DelayFrame
diff --git a/engine/trade.asm b/engine/trade.asm
index 199513af..4d6c044c 100755
--- a/engine/trade.asm
+++ b/engine/trade.asm
@@ -119,10 +119,10 @@ LoadTradingGFXAndMonNames: ; 411a1 (10:51a1)
call FillMemory
call ClearSprites
ld a, $ff
- ld [wcfcb], a
+ ld [wUpdateSpritesEnabled], a
ld hl, wd730
set 6, [hl]
- ld a, [wcf1b]
+ ld a, [wOnSGB]
and a
ld a, $e4
jr z, .asm_411e5
@@ -175,7 +175,7 @@ Func_41245: ; 41245 (10:5245)
ld a, $ab
ld [rLCDC], a ; $ff40
ld a, $50
- ld [$ffb0], a
+ ld [hVBlankWY], a
ld a, $86
ld [rWX], a ; $ff4b
ld [$ffae], a
@@ -397,7 +397,7 @@ Func_41411: ; 41411 (10:5411)
xor a
ld [$ffae], a
ld a, $90
- ld [$ffb0], a
+ ld [hVBlankWY], a
ret
Func_4142d: ; 4142d (10:542d)
@@ -475,7 +475,7 @@ Func_4149f: ; 4149f (10:549f)
Func_414ae: ; 414ae (10:54ae)
push hl
hlCoord 0, 4
- call ScheduleRowRedrawHelper
+ call CopyToScreenEdgeTiles
pop hl
ld a, h
ld [H_SCREENEDGEREDRAWADDR + 1], a
@@ -655,7 +655,7 @@ Func_415c8: ; 415c8 (10:55c8)
ld a, $7
ld [rWX], a ; $ff4b
xor a
- ld [$ffb0], a
+ ld [hVBlankWY], a
ld a, $90
ld [$ffae], a
ret
diff --git a/engine/turn_sprite.asm b/engine/turn_sprite.asm
index ecd8cf02..84037cfe 100755
--- a/engine/turn_sprite.asm
+++ b/engine/turn_sprite.asm
@@ -1,25 +1,25 @@
-Func_13074: ; 13074 (4:7074)
+UpdateSpriteFacingOffsetAndDelayMovement: ; 13074 (4:7074)
ld h, $c2
ld a, [H_CURRENTSPRITEOFFSET]
add $8
ld l, a
- ld a, $7f
- ld [hl], a
+ ld a, $7f ; maximum movement delay
+ ld [hl], a ; c2x8 (movement delay)
dec h
ld a, [H_CURRENTSPRITEOFFSET]
add $9
ld l, a
- ld a, [hld]
+ ld a, [hld] ; c1x9 (facing direction)
ld b, a
xor a
ld [hld], a
- ld [hl], a
+ ld [hl], a ; c1x8 (walk animation frame)
ld a, [H_CURRENTSPRITEOFFSET]
add $2
ld l, a
- ld a, [hl]
- or b
+ ld a, [hl] ; c1x2 (facing and animation table offset)
+ or b ; or in the facing direction
ld [hld], a
- ld a, $2
- ld [hl], a
+ ld a, $2 ; delayed movement status
+ ld [hl], a ; c1x1 (movement status)
ret