summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--constants/battle_constants.asm3
-rw-r--r--data/battle/held_heal_status.asm10
-rw-r--r--data/battle/held_stat_up.asm9
-rw-r--r--data/moves/effects_priorities.asm8
-rw-r--r--data/trainers/leaders.asm32
-rw-r--r--data/wild/flee_mons.asm35
-rw-r--r--engine/battle/core.asm4623
-rwxr-xr-xengine/gfx/cgb_layouts.asm2
-rwxr-xr-xengine/gfx/color.asm6
-rwxr-xr-xengine/gfx/sgb_layouts.asm2
-rwxr-xr-xengine/items/item_effects.asm12
-rw-r--r--engine/pokemon/bills_pc_top.asm2
-rwxr-xr-xengine/pokemon/move_mon.asm4
-rw-r--r--home/map.asm4
-rw-r--r--main.asm115
-rw-r--r--wram.asm119
16 files changed, 4845 insertions, 141 deletions
diff --git a/constants/battle_constants.asm b/constants/battle_constants.asm
index 796697db..5442e2c3 100644
--- a/constants/battle_constants.asm
+++ b/constants/battle_constants.asm
@@ -16,6 +16,9 @@ MIN_NEUTRAL_DAMAGE EQU 2
; turns that sleep lasts
REST_SLEEP_TURNS EQU 2
+; default move priority
+BASE_PRIORITY EQU 1
+
; type effectiveness factors, scaled by 10
SUPER_EFFECTIVE EQU 20
MORE_EFFECTIVE EQU 15
diff --git a/data/battle/held_heal_status.asm b/data/battle/held_heal_status.asm
new file mode 100644
index 00000000..ac11b645
--- /dev/null
+++ b/data/battle/held_heal_status.asm
@@ -0,0 +1,10 @@
+; See also data/items/heal_status.asm
+
+HeldStatusHealingEffects:
+ db HELD_HEAL_POISON, 1 << PSN
+ db HELD_HEAL_FREEZE, 1 << FRZ
+ db HELD_HEAL_BURN, 1 << BRN
+ db HELD_HEAL_SLEEP, SLP
+ db HELD_HEAL_PARALYZE, 1 << PAR
+ db HELD_HEAL_STATUS, ALL_STATUS
+ db -1 ; end
diff --git a/data/battle/held_stat_up.asm b/data/battle/held_stat_up.asm
new file mode 100644
index 00000000..4f28c0d0
--- /dev/null
+++ b/data/battle/held_stat_up.asm
@@ -0,0 +1,9 @@
+HeldStatUpItems:
+ dbw HELD_ATTACK_UP, BattleCommand_AttackUp
+ dbw HELD_DEFENSE_UP, BattleCommand_DefenseUp
+ dbw HELD_SPEED_UP, BattleCommand_SpeedUp
+ dbw HELD_SP_ATTACK_UP, BattleCommand_SpecialAttackUp
+ dbw HELD_SP_DEFENSE_UP, BattleCommand_SpecialDefenseUp
+ dbw HELD_ACCURACY_UP, BattleCommand_AccuracyUp
+ dbw HELD_EVASION_UP, BattleCommand_EvasionUp
+ db -1 ; end
diff --git a/data/moves/effects_priorities.asm b/data/moves/effects_priorities.asm
new file mode 100644
index 00000000..dfdb636a
--- /dev/null
+++ b/data/moves/effects_priorities.asm
@@ -0,0 +1,8 @@
+MoveEffectPriorities:
+ db EFFECT_PROTECT, 3
+ db EFFECT_ENDURE, 3
+ db EFFECT_PRIORITY_HIT, 2
+ db EFFECT_FORCE_SWITCH, 0
+ db EFFECT_COUNTER, 0
+ db EFFECT_MIRROR_COAT, 0
+ db -1
diff --git a/data/trainers/leaders.asm b/data/trainers/leaders.asm
new file mode 100644
index 00000000..a41f641e
--- /dev/null
+++ b/data/trainers/leaders.asm
@@ -0,0 +1,32 @@
+; These lists determine the battle music and victory music, and whether to
+; award HAPPINESS_GYMBATTLE for winning.
+
+; Note: CHAMPION and RED are unused for battle music checks, since they are
+; accounted for prior to the list check.
+
+GymLeaders:
+ db FALKNER
+ db WHITNEY
+ db BUGSY
+ db MORTY
+ db PRYCE
+ db JASMINE
+ db CHUCK
+ db CLAIR
+ db WILL
+ db BRUNO
+ db KAREN
+ db KOGA
+ db CHAMPION
+ db RED
+; fallthrough
+KantoGymLeaders:
+ db BROCK
+ db MISTY
+ db LT_SURGE
+ db ERIKA
+ db JANINE
+ db SABRINA
+ db BLAINE
+ db BLUE
+ db -1
diff --git a/data/wild/flee_mons.asm b/data/wild/flee_mons.asm
new file mode 100644
index 00000000..1c3700fd
--- /dev/null
+++ b/data/wild/flee_mons.asm
@@ -0,0 +1,35 @@
+FleeMons:
+; referenced by TryEnemyFlee and FastBallMultiplier
+
+SometimesFleeMons:
+ db MAGNEMITE
+ db GRIMER
+ db TANGELA
+ db MR__MIME
+ db EEVEE
+ db PORYGON
+ db DRATINI
+ db DRAGONAIR
+ db TOGETIC
+ db UMBREON
+ db UNOWN
+ db SNUBBULL
+ db HERACROSS
+ db -1
+
+OftenFleeMons:
+ db CUBONE
+ db ARTICUNO
+ db ZAPDOS
+ db MOLTRES
+ db QUAGSIRE
+ db DELIBIRD
+ db PHANPY
+ db TEDDIURSA
+ db -1
+
+AlwaysFleeMons:
+ db RAIKOU
+ db ENTEI
+ db SUICUNE
+ db -1
diff --git a/engine/battle/core.asm b/engine/battle/core.asm
new file mode 100644
index 00000000..04769f46
--- /dev/null
+++ b/engine/battle/core.asm
@@ -0,0 +1,4623 @@
+; Core components of the battle engine.
+
+DoBattle:
+ xor a
+ ld [wBattleParticipantsNotFainted], a
+ ld [wBattleParticipantsIncludingFainted], a
+ ld [wBattlePlayerAction], a
+ ld [wBattleEnded], a
+ inc a
+ ld [wBattleHasJustStarted], a
+ ld hl, wOTPartyMon1HP
+ ld bc, PARTYMON_STRUCT_LENGTH - 1
+ ld d, BATTLEACTION_SWITCH1 - 1
+.loop
+ inc d
+ ld a, [hli]
+ or [hl]
+ jr nz, .alive
+ add hl, bc
+ jr .loop
+
+.alive
+ ld a, d
+ ld [wBattleAction], a
+ ld a, [wLinkMode]
+ and a
+ jr z, .not_linked
+
+ ldh a, [hSerialConnectionStatus]
+ cp USING_INTERNAL_CLOCK
+ jr z, .player_2
+
+.not_linked
+ ld a, [wBattleMode]
+ dec a
+ jr z, .wild
+ xor a
+ ld [wEnemySwitchMonIndex], a
+ call NewEnemyMonStatus
+ call ResetEnemyStatLevels
+ call BreakAttraction
+ call EnemySwitch
+
+.wild
+ ld c, 40
+ call DelayFrames
+
+.player_2
+ call LoadTilemapToTempTilemap
+ call CheckPlayerPartyForFitMon
+ ld a, d
+ and a
+ jp z, LostBattle
+ call SafeLoadTempTilemapToTilemap
+ ld a, [wBattleType]
+ cp BATTLETYPE_DEBUG
+ jp z, .tutorial_debug
+ cp BATTLETYPE_TUTORIAL
+ jp z, .tutorial_debug
+ xor a
+ ld [wCurPartyMon], a
+.loop2
+ call CheckIfCurPartyMonIsFitToFight
+ jr nz, .alive2
+ ld hl, wCurPartyMon
+ inc [hl]
+ jr .loop2
+
+.alive2
+ ld a, [wCurBattleMon]
+ ld [wLastPlayerMon], a
+ ld a, [wCurPartyMon]
+ ld [wCurBattleMon], a
+ inc a
+ ld hl, wPartySpecies - 1
+ ld c, a
+ ld b, 0
+ add hl, bc
+ ld a, [hl]
+ ld [wCurPartySpecies], a
+ ld [wTempBattleMonSpecies], a
+ hlcoord 1, 5
+ ld a, 9
+ call SlideBattlePicOut
+ call LoadTilemapToTempTilemap
+ call ResetBattleParticipants
+ call InitBattleMon
+ call ResetPlayerStatLevels
+ call SendOutMonText
+ call NewBattleMonStatus
+ call BreakAttraction
+ call SendOutPlayerMon
+ call EmptyBattleTextbox
+ call LoadTilemapToTempTilemap
+ call SetPlayerTurn
+ call SpikesDamage
+ ld a, [wLinkMode]
+ and a
+ jr z, .not_linked_2
+ ldh a, [hSerialConnectionStatus]
+ cp USING_INTERNAL_CLOCK
+ jr nz, .not_linked_2
+ xor a
+ ld [wEnemySwitchMonIndex], a
+ call NewEnemyMonStatus
+ call ResetEnemyStatLevels
+ call BreakAttraction
+ call EnemySwitch
+ call SetEnemyTurn
+ call SpikesDamage
+
+.not_linked_2
+ jp BattleTurn
+
+.tutorial_debug
+ jp BattleMenu
+
+WildFled_EnemyFled_LinkBattleCanceled:
+ call SafeLoadTempTilemapToTilemap
+ ld a, [wBattleResult]
+ and BATTLERESULT_BITMASK
+ add DRAW
+ ld [wBattleResult], a
+ ld a, [wLinkMode]
+ and a
+ ld hl, BattleText_WildFled
+ jr z, .print_text
+
+ ld a, [wBattleResult]
+ and BATTLERESULT_BITMASK
+ ld [wBattleResult], a ; WIN
+ ld hl, BattleText_EnemyFled
+
+.print_text
+ call StdBattleTextbox
+ call StopDangerSound
+ ld de, SFX_RUN
+ call PlaySFX
+ call SetPlayerTurn
+ callfar DummyPredef38
+ ld a, 1
+ ld [wBattleEnded], a
+ ret
+
+BattleTurn:
+.loop
+ call CheckContestBattleOver
+ jr c, .quit
+
+ xor a
+ ld [wPlayerIsSwitching], a
+ ld [wEnemyIsSwitching], a
+ ld [wBattleHasJustStarted], a
+ ld [wPlayerJustGotFrozen], a
+ ld [wEnemyJustGotFrozen], a
+ ld [wCurDamage], a
+ ld [wCurDamage + 1], a
+
+ call HandleBerserkGene
+ call UpdateBattleMonInParty
+ farcall AIChooseMove
+ call CheckPlayerLockedIn
+ jr c, .skip_iteration
+.loop1
+ call BattleMenu
+ jr c, .quit
+ ld a, [wBattleEnded]
+ and a
+ jr nz, .quit
+ ld a, [wForcedSwitch] ; roared/whirlwinded/teleported
+ and a
+ jr nz, .quit
+.skip_iteration
+ call ParsePlayerAction
+ jr nz, .loop1
+
+ call EnemyTriesToFlee
+ jr c, .quit
+
+ call DetermineMoveOrder
+ jr c, .false
+ call Battle_EnemyFirst
+ jr .proceed
+.false
+ call Battle_PlayerFirst
+.proceed
+ ld a, [wForcedSwitch]
+ and a
+ jr nz, .quit
+
+ ld a, [wBattleEnded]
+ and a
+ jr nz, .quit
+
+ call HandleBetweenTurnEffects
+ ld a, [wBattleEnded]
+ and a
+ jr nz, .quit
+ jr .loop
+
+.quit
+ ret
+
+HandleBetweenTurnEffects:
+ ldh a, [hSerialConnectionStatus]
+ cp USING_EXTERNAL_CLOCK
+ jr z, .CheckEnemyFirst
+ call CheckFaint_PlayerThenEnemy
+ ret c
+ call HandleFutureSight
+ call CheckFaint_PlayerThenEnemy
+ ret c
+ call HandleWeather
+ call CheckFaint_PlayerThenEnemy
+ ret c
+ call HandleWrap
+ call CheckFaint_PlayerThenEnemy
+ ret c
+ call HandlePerishSong
+ call CheckFaint_PlayerThenEnemy
+ ret c
+ jr .NoMoreFaintingConditions
+
+.CheckEnemyFirst:
+ call CheckFaint_EnemyThenPlayer
+ ret c
+ call HandleFutureSight
+ call CheckFaint_EnemyThenPlayer
+ ret c
+ call HandleWeather
+ call CheckFaint_EnemyThenPlayer
+ ret c
+ call HandleWrap
+ call CheckFaint_EnemyThenPlayer
+ ret c
+ call HandlePerishSong
+ call CheckFaint_EnemyThenPlayer
+ ret c
+
+.NoMoreFaintingConditions:
+ call HandleLeftovers
+ call HandleMysteryberry
+ call HandleDefrost
+ call HandleSafeguard
+ call HandleScreens
+ call HandleStatBoostingHeldItems
+ call HandleHealingItems
+ call UpdateBattleMonInParty
+ call LoadTilemapToTempTilemap
+ jp HandleEncore
+
+CheckFaint_PlayerThenEnemy:
+ call HasPlayerFainted
+ jr nz, .PlayerNotFainted
+ call HandlePlayerMonFaint
+ ld a, [wBattleEnded]
+ and a
+ jr nz, .BattleIsOver
+
+.PlayerNotFainted:
+ call HasEnemyFainted
+ jr nz, .BattleContinues
+ call HandleEnemyMonFaint
+ ld a, [wBattleEnded]
+ and a
+ jr nz, .BattleIsOver
+
+.BattleContinues:
+ and a
+ ret
+
+.BattleIsOver:
+ scf
+ ret
+
+CheckFaint_EnemyThenPlayer:
+ call HasEnemyFainted
+ jr nz, .EnemyNotFainted
+ call HandleEnemyMonFaint
+ ld a, [wBattleEnded]
+ and a
+ jr nz, .BattleIsOver
+
+.EnemyNotFainted:
+ call HasPlayerFainted
+ jr nz, .BattleContinues
+ call HandlePlayerMonFaint
+ ld a, [wBattleEnded]
+ and a
+ jr nz, .BattleIsOver
+
+.BattleContinues:
+ and a
+ ret
+
+.BattleIsOver:
+ scf
+ ret
+
+HandleBerserkGene:
+ ldh a, [hSerialConnectionStatus]
+ cp USING_EXTERNAL_CLOCK
+ jr z, .reverse
+
+ call .player
+ jr .enemy
+
+.reverse
+ call .enemy
+ ; fallthrough
+
+.player
+ call SetPlayerTurn
+ ld de, wPartyMon1Item
+ ld a, [wCurBattleMon]
+ ld b, a
+ jr .go
+
+.enemy
+ call SetEnemyTurn
+ ld de, wOTPartyMon1Item
+ ld a, [wCurOTMon]
+ ld b, a
+ ; fallthrough
+
+.go
+ push de
+ push bc
+ callfar GetUserItem
+ ld a, [hl]
+ ld [wNamedObjectIndexBuffer], a
+ sub BERSERK_GENE
+ pop bc
+ pop de
+ ret nz
+
+ ld [hl], a
+
+ ld h, d
+ ld l, e
+ ld a, b
+ call GetPartyLocation
+ xor a
+ ld [hl], a
+ ld a, BATTLE_VARS_SUBSTATUS3
+ call GetBattleVarAddr
+ push af
+ set SUBSTATUS_CONFUSED, [hl]
+ ld a, BATTLE_VARS_MOVE_ANIM
+ call GetBattleVarAddr
+ push hl
+ push af
+ xor a
+ ld [hl], a
+ ld [wAttackMissed], a
+ ld [wEffectFailed], a
+ farcall BattleCommand_AttackUp2
+ pop af
+ pop hl
+ ld [hl], a
+ call GetItemName
+ ld hl, BattleText_UsersStringBuffer1Activated
+ call StdBattleTextbox
+ callfar BattleCommand_StatUpMessage
+ pop af
+ bit SUBSTATUS_CONFUSED, a
+ ret nz
+ xor a
+ ld [wNumHits], a
+ ld de, ANIM_CONFUSED
+ call Call_PlayBattleAnim_OnlyIfVisible
+ call SwitchTurnCore
+ ld hl, BecameConfusedText
+ jp StdBattleTextbox
+
+EnemyTriesToFlee:
+ ld a, [wLinkMode]
+ and a
+ jr z, .not_linked
+ ld a, [wBattleAction]
+ cp BATTLEACTION_FORFEIT
+ jr z, .forfeit
+
+.not_linked
+ and a
+ ret
+
+.forfeit
+ call WildFled_EnemyFled_LinkBattleCanceled
+ scf
+ ret
+
+DetermineMoveOrder:
+ ld a, [wLinkMode]
+ and a
+ jr z, .use_move
+ ld a, [wBattleAction]
+ cp BATTLEACTION_STRUGGLE
+ jr z, .use_move
+ cp BATTLEACTION_SKIPTURN
+ jr z, .use_move
+ sub BATTLEACTION_SWITCH1
+ jr c, .use_move
+ ld a, [wBattlePlayerAction]
+ cp BATTLEPLAYERACTION_SWITCH
+ jr nz, .switch
+ ldh a, [hSerialConnectionStatus]
+ cp USING_INTERNAL_CLOCK
+ jr z, .player_2
+
+ call BattleRandom
+ cp 50 percent + 1
+ jp c, .player_first
+ jp .enemy_first
+
+.player_2
+ call BattleRandom
+ cp 50 percent + 1
+ jp c, .enemy_first
+ jp .player_first
+
+.switch
+ callfar AI_Switch
+ call SetEnemyTurn
+ call SpikesDamage
+ jp .enemy_first
+
+.use_move
+ ld a, [wBattlePlayerAction]
+ and a ; BATTLEPLAYERACTION_USEMOVE?
+ jp nz, .player_first
+ call CompareMovePriority
+ jr z, .equal_priority
+ jp c, .player_first ; player goes first
+ jp .enemy_first
+
+.equal_priority
+ call SetPlayerTurn
+ callfar GetUserItem
+ push bc
+ callfar GetOpponentItem
+ pop de
+ ld a, d
+ cp HELD_QUICK_CLAW
+ jr nz, .player_no_quick_claw
+ ld a, b
+ cp HELD_QUICK_CLAW
+ jr z, .both_have_quick_claw
+ call BattleRandom
+ cp e
+ jr nc, .speed_check
+ jp .player_first
+
+.player_no_quick_claw
+ ld a, b
+ cp HELD_QUICK_CLAW
+ jr nz, .speed_check
+ call BattleRandom
+ cp c
+ jr nc, .speed_check
+ jp .enemy_first
+
+.both_have_quick_claw
+ ldh a, [hSerialConnectionStatus]
+ cp USING_INTERNAL_CLOCK
+ jr z, .player_2b
+ call BattleRandom
+ cp c
+ jp c, .enemy_first
+ call BattleRandom
+ cp e
+ jp c, .player_first
+ jr .speed_check
+
+.player_2b
+ call BattleRandom
+ cp e
+ jp c, .player_first
+ call BattleRandom
+ cp c
+ jp c, .enemy_first
+ jr .speed_check
+
+.speed_check
+ ld de, wBattleMonSpeed
+ ld hl, wEnemyMonSpeed
+ ld c, 2
+ call CompareBytes
+ jr z, .speed_tie
+ jp nc, .player_first
+ jp .enemy_first
+
+.speed_tie
+ ldh a, [hSerialConnectionStatus]
+ cp USING_INTERNAL_CLOCK
+ jr z, .player_2c
+ call BattleRandom
+ cp 50 percent + 1
+ jp c, .player_first
+ jp .enemy_first
+
+.player_2c
+ call BattleRandom
+ cp 50 percent + 1
+ jp c, .enemy_first
+.player_first
+ scf
+ ret
+
+.enemy_first
+ and a
+ ret
+
+CheckContestBattleOver:
+ ld a, [wBattleType]
+ cp BATTLETYPE_CONTEST
+ jr nz, .contest_not_over
+ ld a, [wParkBallsRemaining]
+ and a
+ jr nz, .contest_not_over
+ ld a, [wBattleResult]
+ and BATTLERESULT_BITMASK
+ add DRAW
+ ld [wBattleResult], a
+ scf
+ ret
+
+.contest_not_over
+ and a
+ ret
+
+CheckPlayerLockedIn:
+ ld a, [wPlayerSubStatus4]
+ and 1 << SUBSTATUS_RECHARGE
+ jp nz, .quit
+
+ ld hl, wEnemySubStatus3
+ res SUBSTATUS_FLINCHED, [hl]
+ ld hl, wPlayerSubStatus3
+ res SUBSTATUS_FLINCHED, [hl]
+
+ ld a, [hl]
+ and 1 << SUBSTATUS_CHARGED | 1 << SUBSTATUS_RAMPAGE
+ jp nz, .quit
+
+ ld hl, wPlayerSubStatus1
+ bit SUBSTATUS_ROLLOUT, [hl]
+ jp nz, .quit
+
+ and a
+ ret
+
+.quit
+ scf
+ ret
+
+ParsePlayerAction:
+ call CheckPlayerLockedIn
+ jp c, .locked_in
+ ld hl, wPlayerSubStatus5
+ bit SUBSTATUS_ENCORED, [hl]
+ jr z, .not_encored
+ ld a, [wLastPlayerMove]
+ ld [wCurPlayerMove], a
+ jr .encored
+
+.not_encored
+ ld a, [wBattlePlayerAction]
+ cp BATTLEPLAYERACTION_SWITCH
+ jr z, .reset_rage
+ and a
+ jr nz, .reset_bide
+ ld a, [wPlayerSubStatus3]
+ and 1 << SUBSTATUS_BIDE
+ jr nz, .locked_in
+ xor a
+ ld [wMoveSelectionMenuType], a
+ inc a ; POUND
+ ld [wFXAnimID], a
+ call MoveSelectionScreen
+ push af
+ call SafeLoadTempTilemapToTilemap
+ call UpdateBattleHuds
+ ld a, [wCurPlayerMove]
+ cp STRUGGLE
+ jr z, .struggle
+ call PlayClickSFX
+
+.struggle
+ ld a, $1
+ ldh [hBGMapMode], a
+ pop af
+ ret nz
+
+.encored
+ call SetPlayerTurn
+ callfar UpdateMoveData
+ xor a
+ ld [wPlayerCharging], a
+ ld a, [wPlayerMoveStruct + MOVE_EFFECT]
+ cp EFFECT_FURY_CUTTER
+ jr z, .continue_fury_cutter
+ xor a
+ ld [wPlayerFuryCutterCount], a
+
+.continue_fury_cutter
+ ld a, [wPlayerMoveStruct + MOVE_EFFECT]
+ cp EFFECT_RAGE
+ jr z, .continue_rage
+ ld hl, wPlayerSubStatus4
+ res SUBSTATUS_RAGE, [hl]
+ xor a
+ ld [wPlayerRageCounter], a
+
+.continue_rage
+ ld a, [wPlayerMoveStruct + MOVE_EFFECT]
+ cp EFFECT_PROTECT
+ jr z, .continue_protect
+ cp EFFECT_ENDURE
+ jr z, .continue_protect
+ xor a
+ ld [wPlayerProtectCount], a
+ jr .continue_protect
+
+.reset_bide
+ ld hl, wPlayerSubStatus3
+ res SUBSTATUS_BIDE, [hl]
+
+.locked_in
+ xor a
+ ld [wPlayerFuryCutterCount], a
+ ld [wPlayerProtectCount], a
+ ld [wPlayerRageCounter], a
+ ld hl, wPlayerSubStatus4
+ res SUBSTATUS_RAGE, [hl]
+
+.continue_protect
+ call ParseEnemyAction
+ xor a
+ ret
+
+.reset_rage
+ xor a
+ ld [wPlayerFuryCutterCount], a
+ ld [wPlayerProtectCount], a
+ ld [wPlayerRageCounter], a
+ ld hl, wPlayerSubStatus4
+ res SUBSTATUS_RAGE, [hl]
+ xor a
+ ret
+
+HandleEncore:
+ ldh a, [hSerialConnectionStatus]
+ cp USING_EXTERNAL_CLOCK
+ jr z, .player_1
+ call .do_player
+ jr .do_enemy
+
+.player_1
+ call .do_enemy
+.do_player
+ ld hl, wPlayerSubStatus5
+ bit SUBSTATUS_ENCORED, [hl]
+ ret z
+ ld a, [wPlayerEncoreCount]
+ dec a
+ ld [wPlayerEncoreCount], a
+ jr z, .end_player_encore
+ ld hl, wBattleMonPP
+ ld a, [wCurMoveNum]
+ ld c, a
+ ld b, 0
+ add hl, bc
+ ld a, [hl]
+ and PP_MASK
+ ret nz
+
+.end_player_encore
+ ld hl, wPlayerSubStatus5
+ res SUBSTATUS_ENCORED, [hl]
+ call SetEnemyTurn
+ ld hl, BattleText_TargetsEncoreEnded
+ jp StdBattleTextbox
+
+.do_enemy
+ ld hl, wEnemySubStatus5
+ bit SUBSTATUS_ENCORED, [hl]
+ ret z
+ ld a, [wEnemyEncoreCount]
+ dec a
+ ld [wEnemyEncoreCount], a
+ jr z, .end_enemy_encore
+ ld hl, wEnemyMonPP
+ ld a, [wCurEnemyMoveNum]
+ ld c, a
+ ld b, 0
+ add hl, bc
+ ld a, [hl]
+ and PP_MASK
+ ret nz
+
+.end_enemy_encore
+ ld hl, wEnemySubStatus5
+ res SUBSTATUS_ENCORED, [hl]
+ call SetPlayerTurn
+ ld hl, BattleText_TargetsEncoreEnded
+ jp StdBattleTextbox
+
+TryEnemyFlee:
+ ld a, [wBattleMode]
+ dec a
+ jr nz, .Stay
+
+ ld a, [wPlayerSubStatus5]
+ bit SUBSTATUS_CANT_RUN, a
+ jr nz, .Stay
+
+ ld a, [wEnemyWrapCount]
+ and a
+ jr nz, .Stay
+
+ ld a, [wEnemyMonStatus]
+ and 1 << FRZ | SLP
+ jr nz, .Stay
+
+ ld a, [wTempEnemyMonSpecies]
+ ld de, 1
+ ld hl, AlwaysFleeMons
+ call IsInArray
+ jr c, .Flee
+
+ call BattleRandom
+ ld b, a
+ cp 50 percent + 1
+ jr nc, .Stay
+
+ push bc
+ ld a, [wTempEnemyMonSpecies]
+ ld de, 1
+ ld hl, OftenFleeMons
+ call IsInArray
+ pop bc
+ jr c, .Flee
+
+ ld a, b
+ cp 10 percent + 1
+ jr nc, .Stay
+
+ ld a, [wTempEnemyMonSpecies]
+ ld de, 1
+ ld hl, SometimesFleeMons
+ call IsInArray
+ jr c, .Flee
+
+.Stay:
+ and a
+ ret
+
+.Flee:
+ scf
+ ret
+
+INCLUDE "data/wild/flee_mons.asm"
+
+CompareMovePriority:
+; Compare the priority of the player and enemy's moves.
+; Return carry if the player goes first, or z if they match.
+
+ ld a, [wCurPlayerMove]
+ call GetMovePriority
+ ld b, a
+ push bc
+ ld a, [wCurEnemyMove]
+ call GetMovePriority
+ pop bc
+ cp b
+ ret
+
+GetMovePriority:
+; Return the priority (0-3) of move a.
+
+ ld b, a
+
+ ; Vital Throw goes last.
+ cp VITAL_THROW
+ ld a, 0
+ ret z
+
+ call GetMoveEffect
+ ld hl, MoveEffectPriorities
+.loop
+ ld a, [hli]
+ cp b
+ jr z, .done
+ inc hl
+ cp -1
+ jr nz, .loop
+
+ ld a, BASE_PRIORITY
+ ret
+
+.done
+ ld a, [hl]
+ ret
+
+INCLUDE "data/moves/effects_priorities.asm"
+
+GetMoveEffect:
+ ld a, b
+ dec a
+ ld hl, Moves + MOVE_EFFECT
+ ld bc, MOVE_LENGTH
+ call AddNTimes
+ ld a, BANK(Moves)
+ call GetFarByte
+ ld b, a
+ ret
+
+Battle_EnemyFirst:
+ call LoadTilemapToTempTilemap
+ call TryEnemyFlee
+ jp c, WildFled_EnemyFled_LinkBattleCanceled
+ call SetEnemyTurn
+ ld a, $1
+ ld [wEnemyGoesFirst], a
+ callfar AI_SwitchOrTryItem
+ jr c, .switch_item
+ call EnemyTurn_EndOpponentProtectEndureDestinyBond
+ ld a, [wForcedSwitch]
+ and a
+ ret nz
+ call HasPlayerFainted
+ jp z, HandlePlayerMonFaint
+ call HasEnemyFainted
+ jp z, HandleEnemyMonFaint
+
+.switch_item
+ call SetEnemyTurn
+ call ResidualDamage
+ jp z, HandleEnemyMonFaint
+ call RefreshBattleHuds
+ call PlayerTurn_EndOpponentProtectEndureDestinyBond
+ ld a, [wForcedSwitch]
+ and a
+ ret nz
+ call HasEnemyFainted
+ jp z, HandleEnemyMonFaint
+ call HasPlayerFainted
+ jp z, HandlePlayerMonFaint
+ call SetPlayerTurn
+ call ResidualDamage
+ jp z, HandlePlayerMonFaint
+ call RefreshBattleHuds
+ xor a ; BATTLEPLAYERACTION_USEMOVE
+ ld [wBattlePlayerAction], a
+ ret
+
+Battle_PlayerFirst:
+ xor a
+ ld [wEnemyGoesFirst], a
+ call SetEnemyTurn
+ callfar AI_SwitchOrTryItem
+ push af
+ call PlayerTurn_EndOpponentProtectEndureDestinyBond
+ pop bc
+ ld a, [wForcedSwitch]
+ and a
+ ret nz
+ call HasEnemyFainted
+ jp z, HandleEnemyMonFaint
+ call HasPlayerFainted
+ jp z, HandlePlayerMonFaint
+ push bc
+ call SetPlayerTurn
+ call ResidualDamage
+ pop bc
+ jp z, HandlePlayerMonFaint
+ push bc
+ call RefreshBattleHuds
+ pop af
+ jr c, .switched_or_used_item
+ call LoadTilemapToTempTilemap
+ call TryEnemyFlee
+ jp c, WildFled_EnemyFled_LinkBattleCanceled
+ call EnemyTurn_EndOpponentProtectEndureDestinyBond
+ ld a, [wForcedSwitch]
+ and a
+ ret nz
+ call HasPlayerFainted
+ jp z, HandlePlayerMonFaint
+ call HasEnemyFainted
+ jp z, HandleEnemyMonFaint
+
+.switched_or_used_item
+ call SetEnemyTurn
+ call ResidualDamage
+ jp z, HandleEnemyMonFaint
+ call RefreshBattleHuds
+ xor a ; BATTLEPLAYERACTION_USEMOVE
+ ld [wBattlePlayerAction], a
+ ret
+
+PlayerTurn_EndOpponentProtectEndureDestinyBond:
+ call SetPlayerTurn
+ call EndUserDestinyBond
+ callfar DoPlayerTurn
+ jp EndOpponentProtectEndureDestinyBond
+
+EnemyTurn_EndOpponentProtectEndureDestinyBond:
+ call SetEnemyTurn
+ call EndUserDestinyBond
+ callfar DoEnemyTurn
+ jp EndOpponentProtectEndureDestinyBond
+
+EndOpponentProtectEndureDestinyBond:
+ ld a, BATTLE_VARS_SUBSTATUS1_OPP
+ call GetBattleVarAddr
+ res SUBSTATUS_PROTECT, [hl]
+ res SUBSTATUS_ENDURE, [hl]
+ ld a, BATTLE_VARS_SUBSTATUS5_OPP
+ call GetBattleVarAddr
+ res SUBSTATUS_DESTINY_BOND, [hl]
+ ret
+
+EndUserDestinyBond:
+ ld a, BATTLE_VARS_SUBSTATUS5
+ call GetBattleVarAddr
+ res SUBSTATUS_DESTINY_BOND, [hl]
+ ret
+
+HasUserFainted:
+ ldh a, [hBattleTurn]
+ and a
+ jr z, HasPlayerFainted
+HasEnemyFainted:
+ ld hl, wEnemyMonHP
+ jr CheckIfHPIsZero
+
+HasPlayerFainted:
+ ld hl, wBattleMonHP
+
+CheckIfHPIsZero:
+ ld a, [hli]
+ or [hl]
+ ret
+
+ResidualDamage:
+; Return z if the user fainted before
+; or as a result of residual damage.
+; For Sandstorm damage, see HandleWeather.
+
+ call HasUserFainted
+ ret z
+
+ ld a, BATTLE_VARS_STATUS
+ call GetBattleVar
+ and 1 << PSN | 1 << BRN
+ jr z, .did_psn_brn
+
+ ld hl, HurtByPoisonText
+ ld de, ANIM_PSN
+ and 1 << BRN
+ jr z, .got_anim
+ ld hl, HurtByBurnText
+ ld de, ANIM_BRN
+.got_anim
+
+ push de
+ call StdBattleTextbox
+ pop de
+
+ xor a
+ ld [wNumHits], a
+ call Call_PlayBattleAnim_OnlyIfVisible
+ call GetEighthMaxHP
+ ld de, wPlayerToxicCount
+ ldh a, [hBattleTurn]
+ and a
+ jr z, .check_toxic
+ ld de, wEnemyToxicCount
+.check_toxic
+
+ ld a, BATTLE_VARS_SUBSTATUS5
+ call GetBattleVar
+ bit SUBSTATUS_TOXIC, a
+ jr z, .did_toxic
+ call GetSixteenthMaxHP
+ ld a, [de]
+ inc a
+ ld [de], a
+ ld hl, 0
+.add
+ add hl, bc
+ dec a
+ jr nz, .add
+ ld b, h
+ ld c, l
+.did_toxic
+
+ call SubtractHPFromUser
+.did_psn_brn
+
+ call HasUserFainted
+ jp z, .fainted
+
+ ld a, BATTLE_VARS_SUBSTATUS4
+ call GetBattleVarAddr
+ bit SUBSTATUS_LEECH_SEED, [hl]
+ jr z, .not_seeded
+
+ call SwitchTurnCore
+ xor a
+ ld [wNumHits], a
+ ld de, ANIM_SAP
+ ld a, BATTLE_VARS_SUBSTATUS3_OPP
+ call GetBattleVar
+ and 1 << SUBSTATUS_FLYING | 1 << SUBSTATUS_UNDERGROUND
+ call z, Call_PlayBattleAnim_OnlyIfVisible
+ call SwitchTurnCore
+
+ call GetEighthMaxHP
+ call SubtractHPFromUser
+ ld a, $1
+ ldh [hBGMapMode], a
+ call RestoreHP
+ ld hl, LeechSeedSapsText
+ call StdBattleTextbox
+.not_seeded
+
+ call HasUserFainted
+ jr z, .fainted
+
+ ld a, BATTLE_VARS_SUBSTATUS1
+ call GetBattleVarAddr
+ bit SUBSTATUS_NIGHTMARE, [hl]
+ jr z, .not_nightmare
+ xor a
+ ld [wNumHits], a
+ ld de, ANIM_IN_NIGHTMARE
+ call Call_PlayBattleAnim_OnlyIfVisible
+ call GetQuarterMaxHP
+ call SubtractHPFromUser
+ ld hl, HasANightmareText
+ call StdBattleTextbox
+.not_nightmare
+
+ call HasUserFainted
+ jr z, .fainted
+
+ ld a, BATTLE_VARS_SUBSTATUS1
+ call GetBattleVarAddr
+ bit SUBSTATUS_CURSE, [hl]
+ jr z, .not_cursed
+
+ xor a
+ ld [wNumHits], a
+ ld de, ANIM_IN_NIGHTMARE
+ call Call_PlayBattleAnim_OnlyIfVisible
+ call GetQuarterMaxHP
+ call SubtractHPFromUser
+ ld hl, HurtByCurseText
+ call StdBattleTextbox
+
+.not_cursed
+ ld hl, wBattleMonHP
+ ldh a, [hBattleTurn]
+ and a
+ jr z, .check_fainted
+ ld hl, wEnemyMonHP
+
+.check_fainted
+ ld a, [hli]
+ or [hl]
+ ret nz
+
+.fainted
+ call RefreshBattleHuds
+ ld c, 20
+ call DelayFrames
+ xor a
+ ret
+
+HandlePerishSong:
+ ldh a, [hSerialConnectionStatus]
+ cp USING_EXTERNAL_CLOCK
+ jr z, .EnemyFirst
+ call SetPlayerTurn
+ call .do_it
+ call SetEnemyTurn
+ jp .do_it
+
+.EnemyFirst:
+ call SetEnemyTurn
+ call .do_it
+ call SetPlayerTurn
+
+.do_it
+ ld hl, wPlayerPerishCount
+ ldh a, [hBattleTurn]
+ and a
+ jr z, .got_count
+ ld hl, wEnemyPerishCount
+
+.got_count
+ ld a, BATTLE_VARS_SUBSTATUS1
+ call GetBattleVar
+ bit SUBSTATUS_PERISH, a
+ ret z
+ dec [hl]
+ ld a, [hl]
+ ld [wDeciramBuffer], a
+ push af
+ ld hl, PerishCountText
+ call StdBattleTextbox
+ pop af
+ ret nz
+ ld a, BATTLE_VARS_SUBSTATUS1
+ call GetBattleVarAddr
+ res SUBSTATUS_PERISH, [hl]
+ ldh a, [hBattleTurn]
+ and a
+ jr nz, .kill_enemy
+ ld hl, wBattleMonHP
+ xor a
+ ld [hli], a
+ ld [hl], a
+ ld hl, wPartyMon1HP
+ ld a, [wCurBattleMon]
+ call GetPartyLocation
+ xor a
+ ld [hli], a
+ ld [hl], a
+ ret
+
+.kill_enemy
+ ld hl, wEnemyMonHP
+ xor a
+ ld [hli], a
+ ld [hl], a
+ ld a, [wBattleMode]
+ dec a
+ ret z
+ ld hl, wOTPartyMon1HP
+ ld a, [wCurOTMon]
+ call GetPartyLocation
+ xor a
+ ld [hli], a
+ ld [hl], a
+ ret
+
+HandleWrap:
+ ldh a, [hSerialConnectionStatus]
+ cp USING_EXTERNAL_CLOCK
+ jr z, .EnemyFirst
+ call SetPlayerTurn
+ call .do_it
+ call SetEnemyTurn
+ jp .do_it
+
+.EnemyFirst:
+ call SetEnemyTurn
+ call .do_it
+ call SetPlayerTurn
+
+.do_it
+ ld hl, wPlayerWrapCount
+ ld de, wPlayerTrappingMove
+ ldh a, [hBattleTurn]
+ and a
+ jr z, .got_addrs
+ ld hl, wEnemyWrapCount
+ ld de, wEnemyTrappingMove
+
+.got_addrs
+ ld a, [hl]
+ and a
+ ret z
+
+ ld a, BATTLE_VARS_SUBSTATUS4
+ call GetBattleVar
+ bit SUBSTATUS_SUBSTITUTE, a
+ ret nz
+
+ ld a, [de]
+ ld [wNamedObjectIndexBuffer], a
+ ld [wFXAnimID], a
+ call GetMoveName
+ dec [hl]
+ jr z, .release_from_bounds
+
+ ld a, BATTLE_VARS_SUBSTATUS3
+ call GetBattleVar
+ and 1 << SUBSTATUS_FLYING | 1 << SUBSTATUS_UNDERGROUND
+ jr nz, .skip_anim
+
+ call SwitchTurnCore
+ xor a
+ ld [wNumHits], a
+ ld [wFXAnimID + 1], a
+ predef PlayBattleAnim
+ call SwitchTurnCore
+
+.skip_anim
+ call GetSixteenthMaxHP
+ call SubtractHPFromUser
+ ld hl, BattleText_UsersHurtByStringBuffer1
+ jr .print_text
+
+.release_from_bounds
+ ld hl, BattleText_UserWasReleasedFromStringBuffer1
+
+.print_text
+ jp StdBattleTextbox
+
+SwitchTurnCore:
+ ldh a, [hBattleTurn]
+ xor 1
+ ldh [hBattleTurn], a
+ ret
+
+HandleLeftovers:
+ ldh a, [hSerialConnectionStatus]
+ cp USING_EXTERNAL_CLOCK
+ jr z, .DoEnemyFirst
+ call SetPlayerTurn
+ call .do_it
+ call SetEnemyTurn
+ jp .do_it
+
+.DoEnemyFirst:
+ call SetEnemyTurn
+ call .do_it
+ call SetPlayerTurn
+.do_it
+
+ callfar GetUserItem
+ ld a, [hl]
+ ld [wNamedObjectIndexBuffer], a
+ call GetItemName
+ ld a, b
+ cp HELD_LEFTOVERS
+ ret nz
+
+ ld hl, wBattleMonHP
+ ldh a, [hBattleTurn]
+ and a
+ jr z, .got_hp
+ ld hl, wEnemyMonHP
+
+.got_hp
+; Don't restore if we're already at max HP
+ ld a, [hli]
+ ld b, a
+ ld a, [hli]
+ ld c, a
+ ld a, [hli]
+ cp b
+ jr nz, .restore
+ ld a, [hl]
+ cp c
+ ret z
+
+.restore
+ call GetSixteenthMaxHP
+ call SwitchTurnCore
+ call RestoreHP
+ ld hl, BattleText_TargetRecoveredWithItem
+ jp StdBattleTextbox
+
+HandleMysteryberry:
+ ldh a, [hSerialConnectionStatus]
+ cp USING_EXTERNAL_CLOCK
+ jr z, .DoEnemyFirst
+ call SetPlayerTurn
+ call .do_it
+ call SetEnemyTurn
+ jp .do_it
+
+.DoEnemyFirst:
+ call SetEnemyTurn
+ call .do_it
+ call SetPlayerTurn
+
+.do_it
+ callfar GetUserItem
+ ld a, b
+ cp HELD_RESTORE_PP
+ jr nz, .quit
+ ld hl, wPartyMon1PP
+ ld a, [wCurBattleMon]
+ call GetPartyLocation
+ ld d, h
+ ld e, l
+ ld hl, wPartyMon1Moves
+ ld a, [wCurBattleMon]
+ call GetPartyLocation
+ ldh a, [hBattleTurn]
+ and a
+ jr z, .wild
+ ld de, wWildMonPP
+ ld hl, wWildMonMoves
+ ld a, [wBattleMode]
+ dec a
+ jr z, .wild
+ ld hl, wOTPartyMon1PP
+ ld a, [wCurOTMon]
+ call GetPartyLocation
+ ld d, h
+ ld e, l
+ ld hl, wOTPartyMon1Moves
+ ld a, [wCurOTMon]
+ call GetPartyLocation
+
+.wild
+ ld c, $0
+.loop
+ ld a, [hl]
+ and a
+ jr z, .quit
+ ld a, [de]
+ and PP_MASK
+ jr z, .restore
+ inc hl
+ inc de
+ inc c
+ ld a, c
+ cp NUM_MOVES
+ jr nz, .loop
+
+.quit
+ ret
+
+.restore
+ ; lousy hack
+ ld a, [hl]
+ cp SKETCH
+ ld b, 1
+ jr z, .sketch
+ ld b, 5
+.sketch
+ ld a, [de]
+ add b
+ ld [de], a
+ push bc
+ push bc
+ ld a, [hl]
+ ld [wTempByteValue], a
+ ld de, wBattleMonMoves - 1
+ ld hl, wBattleMonPP
+ ldh a, [hBattleTurn]
+ and a
+ jr z, .player_pp
+ ld de, wEnemyMonMoves - 1
+ ld hl, wEnemyMonPP
+.player_pp
+ inc de
+ pop bc
+ ld b, 0
+ add hl, bc
+ push hl
+ ld h, d
+ ld l, e
+ add hl, bc
+ pop de
+ pop bc
+
+ ld a, [wTempByteValue]
+ cp [hl]
+ jr nz, .skip_checks
+ ldh a, [hBattleTurn]
+ and a
+ ld a, [wPlayerSubStatus5]
+ jr z, .check_transform
+ ld a, [wEnemySubStatus5]
+.check_transform
+ bit SUBSTATUS_TRANSFORMED, a
+ jr nz, .skip_checks
+ ld a, [de]
+ add b
+ ld [de], a
+.skip_checks
+ callfar GetUserItem
+ ld a, [hl]
+ ld [wNamedObjectIndexBuffer], a
+ xor a
+ ld [hl], a
+ call GetPartymonItem
+ ldh a, [hBattleTurn]
+ and a
+ jr z, .consume_item
+ ld a, [wBattleMode]
+ dec a
+ jr z, .skip_consumption
+ call GetOTPartymonItem
+
+.consume_item
+ xor a
+ ld [hl], a
+
+.skip_consumption
+ call GetItemName
+ call SwitchTurnCore
+ call ItemRecoveryAnim
+ call SwitchTurnCore
+ ld hl, BattleText_UserRecoveredPPUsing
+ jp StdBattleTextbox
+
+HandleFutureSight:
+ ldh a, [hSerialConnectionStatus]
+ cp USING_EXTERNAL_CLOCK
+ jr z, .enemy_first
+ call SetPlayerTurn
+ call .do_it
+ call SetEnemyTurn
+ jp .do_it
+
+.enemy_first
+ call SetEnemyTurn
+ call .do_it
+ call SetPlayerTurn
+
+.do_it
+ ld hl, wPlayerFutureSightCount
+ ldh a, [hBattleTurn]
+ and a
+ jr z, .okay
+ ld hl, wEnemyFutureSightCount
+
+.okay
+ ld a, [hl]
+ and a
+ ret z
+ dec a
+ ld [hl], a
+ cp $1
+ ret nz
+
+ ld hl, BattleText_TargetWasHitByFutureSight
+ call StdBattleTextbox
+
+ ld a, BATTLE_VARS_MOVE
+ call GetBattleVarAddr
+ push af
+ ld a, FUTURE_SIGHT
+ ld [hl], a
+
+ callfar UpdateMoveData
+ xor a
+ ld [wAttackMissed], a
+ ld [wAlreadyDisobeyed], a
+ ld a, EFFECTIVE
+ ld [wTypeModifier], a
+ callfar DoMove
+ xor a
+ ld [wCurDamage], a
+ ld [wCurDamage + 1], a
+
+ ld a, BATTLE_VARS_MOVE
+ call GetBattleVarAddr
+ pop af
+ ld [hl], a
+
+ call UpdateBattleMonInParty
+ jp UpdateEnemyMonInParty
+
+HandleDefrost:
+ ldh a, [hSerialConnectionStatus]
+ cp USING_EXTERNAL_CLOCK
+ jr z, .enemy_first
+ call .do_player_turn
+ jr .do_enemy_turn
+
+.enemy_first
+ call .do_enemy_turn
+.do_player_turn
+ ld a, [wBattleMonStatus]
+ bit FRZ, a
+ ret z
+
+ ld a, [wPlayerJustGotFrozen]
+ and a
+ ret nz
+
+ call BattleRandom
+ cp 10 percent
+ ret nc
+ xor a
+ ld [wBattleMonStatus], a
+ ld a, [wCurBattleMon]
+ ld hl, wPartyMon1Status
+ call GetPartyLocation
+ ld [hl], 0
+ call UpdateBattleHuds
+ call SetEnemyTurn
+ ld hl, DefrostedOpponentText
+ jp StdBattleTextbox
+
+.do_enemy_turn
+ ld a, [wEnemyMonStatus]
+ bit FRZ, a
+ ret z
+ ld a, [wEnemyJustGotFrozen]
+ and a
+ ret nz
+ call BattleRandom
+ cp 10 percent
+ ret nc
+ xor a
+ ld [wEnemyMonStatus], a
+
+ ld a, [wBattleMode]
+ dec a
+ jr z, .wild
+ ld a, [wCurOTMon]
+ ld hl, wOTPartyMon1Status
+ call GetPartyLocation
+ ld [hl], 0
+.wild
+
+ call UpdateBattleHuds
+ call SetPlayerTurn
+ ld hl, DefrostedOpponentText
+ jp StdBattleTextbox
+
+HandleSafeguard:
+ ldh a, [hSerialConnectionStatus]
+ cp USING_EXTERNAL_CLOCK
+ jr z, .player1
+ call .CheckPlayer
+ jr .CheckEnemy
+
+.player1
+ call .CheckEnemy
+.CheckPlayer:
+ ld a, [wPlayerScreens]
+ bit SCREENS_SAFEGUARD, a
+ ret z
+ ld hl, wPlayerSafeguardCount
+ dec [hl]
+ ret nz
+ res SCREENS_SAFEGUARD, a
+ ld [wPlayerScreens], a
+ xor a
+ jr .print
+
+.CheckEnemy:
+ ld a, [wEnemyScreens]
+ bit SCREENS_SAFEGUARD, a
+ ret z
+ ld hl, wEnemySafeguardCount
+ dec [hl]
+ ret nz
+ res SCREENS_SAFEGUARD, a
+ ld [wEnemyScreens], a
+ ld a, $1
+
+.print
+ ldh [hBattleTurn], a
+ ld hl, BattleText_SafeguardFaded
+ jp StdBattleTextbox
+
+HandleScreens:
+ ldh a, [hSerialConnectionStatus]
+ cp USING_EXTERNAL_CLOCK
+ jr z, .Both
+ call .CheckPlayer
+ jr .CheckEnemy
+
+.Both:
+ call .CheckEnemy
+
+.CheckPlayer:
+ call SetPlayerTurn
+ ld de, .Your
+ call .Copy
+ ld hl, wPlayerScreens
+ ld de, wPlayerLightScreenCount
+ jr .TickScreens
+
+.CheckEnemy:
+ call SetEnemyTurn
+ ld de, .Enemy
+ call .Copy
+ ld hl, wEnemyScreens
+ ld de, wEnemyLightScreenCount
+
+.TickScreens:
+ bit SCREENS_LIGHT_SCREEN, [hl]
+ call nz, .LightScreenTick
+ bit SCREENS_REFLECT, [hl]
+ call nz, .ReflectTick
+ ret
+
+.Copy:
+ ld hl, wStringBuffer1
+ jp CopyName2
+
+.Your:
+ db "Your@"
+.Enemy:
+ db "Enemy@"
+
+.LightScreenTick:
+ ld a, [de]
+ dec a
+ ld [de], a
+ ret nz
+ res SCREENS_LIGHT_SCREEN, [hl]
+ push hl
+ push de
+ ld hl, BattleText_MonsLightScreenFell
+ call StdBattleTextbox
+ pop de
+ pop hl
+ ret
+
+.ReflectTick:
+ inc de
+ ld a, [de]
+ dec a
+ ld [de], a
+ ret nz
+ res SCREENS_REFLECT, [hl]
+ ld hl, BattleText_MonsReflectFaded
+ jp StdBattleTextbox
+
+HandleWeather:
+ ld a, [wBattleWeather]
+ cp WEATHER_NONE
+ ret z
+
+ ld hl, wWeatherCount
+ dec [hl]
+ jr z, .ended
+
+ ld hl, .WeatherMessages
+ call .PrintWeatherMessage
+
+ ld a, [wBattleWeather]
+ cp WEATHER_SANDSTORM
+ ret nz
+
+ ldh a, [hSerialConnectionStatus]
+ cp USING_EXTERNAL_CLOCK
+ jr z, .enemy_first
+
+.player_first
+ call SetPlayerTurn
+ call .SandstormDamage
+ call SetEnemyTurn
+ jr .SandstormDamage
+
+.enemy_first
+ call SetEnemyTurn
+ call .SandstormDamage
+ call SetPlayerTurn
+
+.SandstormDamage:
+ ld a, BATTLE_VARS_SUBSTATUS3
+ call GetBattleVar
+ bit SUBSTATUS_UNDERGROUND, a
+ ret nz
+
+ ld hl, wBattleMonType1
+ ldh a, [hBattleTurn]
+ and a
+ jr z, .ok
+ ld hl, wEnemyMonType1
+.ok
+ ld a, [hli]
+ cp ROCK
+ ret z
+ cp GROUND
+ ret z
+ cp STEEL
+ ret z
+
+ ld a, [hl]
+ cp ROCK
+ ret z
+ cp GROUND
+ ret z
+ cp STEEL
+ ret z
+
+ call SwitchTurnCore
+ xor a
+ ld [wNumHits], a
+ ld de, ANIM_IN_SANDSTORM
+ call Call_PlayBattleAnim
+ call SwitchTurnCore
+ call GetEighthMaxHP
+ call SubtractHPFromUser
+
+ ld hl, SandstormHitsText
+ jp StdBattleTextbox
+
+.ended
+ ld hl, .WeatherEndedMessages
+ call .PrintWeatherMessage
+ xor a
+ ld [wBattleWeather], a
+ ret
+
+.PrintWeatherMessage:
+ ld a, [wBattleWeather]
+ dec a
+ ld c, a
+ ld b, 0
+ add hl, bc
+ add hl, bc
+ ld a, [hli]
+ ld h, [hl]
+ ld l, a
+ jp StdBattleTextbox
+
+.WeatherMessages:
+; entries correspond to WEATHER_* constants
+ dw BattleText_RainContinuesToFall
+ dw BattleText_TheSunlightIsStrong
+ dw BattleText_TheSandstormRages
+
+.WeatherEndedMessages:
+; entries correspond to WEATHER_* constants
+ dw BattleText_TheRainStopped
+ dw BattleText_TheSunlightFaded
+ dw BattleText_TheSandstormSubsided
+
+SubtractHPFromTarget:
+ call SubtractHP
+ jp UpdateHPBar
+
+SubtractHPFromUser:
+; Subtract HP from mon
+ call SubtractHP
+ jp UpdateHPBarBattleHuds
+
+SubtractHP:
+ ld hl, wBattleMonHP
+ ldh a, [hBattleTurn]
+ and a
+ jr z, .ok
+ ld hl, wEnemyMonHP
+.ok
+ inc hl
+ ld a, [hl]
+ ld [wBuffer3], a
+ sub c
+ ld [hld], a
+ ld [wBuffer5], a
+ ld a, [hl]
+ ld [wBuffer4], a
+ sbc b
+ ld [hl], a
+ ld [wBuffer6], a
+ ret nc
+
+ ld a, [wBuffer3]
+ ld c, a
+ ld a, [wBuffer4]
+ ld b, a
+ xor a
+ ld [hli], a
+ ld [hl], a
+ ld [wBuffer5], a
+ ld [wBuffer6], a
+ ret
+
+GetSixteenthMaxHP:
+ call GetQuarterMaxHP
+; quarter result
+ srl c
+ srl c
+; at least 1
+ ld a, c
+ and a
+ jr nz, .ok
+ inc c
+.ok
+ ret
+
+GetEighthMaxHP:
+; output: bc
+ call GetQuarterMaxHP
+; assumes nothing can have 1024 or more hp
+; halve result
+ srl c
+; at least 1
+ ld a, c
+ and a
+ jr nz, .end
+ inc c
+.end
+ ret
+
+GetQuarterMaxHP:
+; output: bc
+ call GetMaxHP
+
+; quarter result
+ srl b
+ rr c
+ srl b
+ rr c
+
+; assumes nothing can have 1024 or more hp
+; at least 1
+ ld a, c
+ and a
+ jr nz, .end
+ inc c
+.end
+ ret
+
+GetHalfMaxHP:
+; output: bc
+ call GetMaxHP
+
+; halve result
+ srl b
+ rr c
+
+; at least 1
+ ld a, c
+ or b
+ jr nz, .end
+ inc c
+.end
+ ret
+
+GetMaxHP:
+; output: bc, wBuffer1-2
+
+ ld hl, wBattleMonMaxHP
+ ldh a, [hBattleTurn]
+ and a
+ jr z, .ok
+ ld hl, wEnemyMonMaxHP
+.ok
+ ld a, [hli]
+ ld [wBuffer2], a
+ ld b, a
+
+ ld a, [hl]
+ ld [wBuffer1], a
+ ld c, a
+ ret
+
+Unreferenced_GetHalfHP:
+ ld hl, wBattleMonHP
+ ldh a, [hBattleTurn]
+ and a
+ jr z, .ok
+ ld hl, wEnemyMonHP
+.ok
+ ld a, [hli]
+ ld b, a
+ ld a, [hli]
+ ld c, a
+ srl b
+ rr c
+ ld a, [hli]
+ ld [wBuffer2], a
+ ld a, [hl]
+ ld [wBuffer1], a
+ ret
+
+CheckUserHasEnoughHP:
+ ld hl, wBattleMonHP + 1
+ ldh a, [hBattleTurn]
+ and a
+ jr z, .ok
+ ld hl, wEnemyMonHP + 1
+.ok
+ ld a, c
+ sub [hl]
+ dec hl
+ ld a, b
+ sbc [hl]
+ ret
+
+RestoreHP:
+ ld hl, wEnemyMonMaxHP
+ ldh a, [hBattleTurn]
+ and a
+ jr z, .ok
+ ld hl, wBattleMonMaxHP
+.ok
+ ld a, [hli]
+ ld [wBuffer2], a
+ ld a, [hld]
+ ld [wBuffer1], a
+ dec hl
+ ld a, [hl]
+ ld [wBuffer3], a
+ add c
+ ld [hld], a
+ ld [wBuffer5], a
+ ld a, [hl]
+ ld [wBuffer4], a
+ adc b
+ ld [hli], a
+ ld [wBuffer6], a
+
+ ld a, [wBuffer1]
+ ld c, a
+ ld a, [hld]
+ sub c
+ ld a, [wBuffer2]
+ ld b, a
+ ld a, [hl]
+ sbc b
+ jr c, .asm_3cd2d
+ ld a, b
+ ld [hli], a
+ ld [wBuffer6], a
+ ld a, c
+ ld [hl], a
+ ld [wBuffer5], a
+.asm_3cd2d
+
+ call SwitchTurnCore
+ call UpdateHPBarBattleHuds
+ jp SwitchTurnCore
+
+UpdateHPBarBattleHuds:
+ call UpdateHPBar
+ jp UpdateBattleHuds
+
+UpdateHPBar:
+ hlcoord 10, 9
+ ldh a, [hBattleTurn]
+ and a
+ ld a, 1
+ jr z, .ok
+ hlcoord 2, 2
+ xor a
+.ok
+ push bc
+ ld [wWhichHPBar], a
+ predef AnimateHPBar
+ pop bc
+ ret
+
+HandleEnemyMonFaint:
+ call FaintEnemyPokemon
+ ld hl, wBattleMonHP
+ ld a, [hli]
+ or [hl]
+ call z, FaintYourPokemon
+ xor a
+ ld [wWhichMonFaintedFirst], a
+ call UpdateBattleStateAndExperienceAfterEnemyFaint
+ call CheckPlayerPartyForFitMon
+ ld a, d
+ and a
+ jp z, LostBattle
+
+ ld hl, wBattleMonHP
+ ld a, [hli]
+ or [hl]
+ call nz, UpdatePlayerHUD
+
+ ld a, $1
+ ldh [hBGMapMode], a
+ ld c, 60
+ call DelayFrames
+
+ ld a, [wBattleMode]
+ dec a
+ jr nz, .trainer
+
+ ld a, 1
+ ld [wBattleEnded], a
+ ret
+
+.trainer
+ call CheckEnemyTrainerDefeated
+ jp z, WinTrainerBattle
+
+ ld hl, wBattleMonHP
+ ld a, [hli]
+ or [hl]
+ jr nz, .player_mon_not_fainted
+
+ call AskUseNextPokemon
+ jr nc, .dont_flee
+
+ ld a, 1
+ ld [wBattleEnded], a
+ ret
+
+.dont_flee
+ call ForcePlayerMonChoice
+ ld a, BATTLEPLAYERACTION_USEITEM
+ ld [wBattlePlayerAction], a
+ call HandleEnemySwitch
+ jp z, WildFled_EnemyFled_LinkBattleCanceled
+ jr DoubleSwitch
+
+.player_mon_not_fainted
+ ld a, BATTLEPLAYERACTION_USEITEM
+ ld [wBattlePlayerAction], a
+ call HandleEnemySwitch
+ jp z, WildFled_EnemyFled_LinkBattleCanceled
+ xor a ; BATTLEPLAYERACTION_USEMOVE
+ ld [wBattlePlayerAction], a
+ ret
+
+DoubleSwitch:
+ ldh a, [hSerialConnectionStatus]
+ cp USING_EXTERNAL_CLOCK
+ jr z, .player_1
+ call ClearSprites
+ hlcoord 1, 0
+ lb bc, 4, 10
+ call ClearBox
+ call PlayerPartyMonEntrance
+ ld a, $1
+ call EnemyPartyMonEntrance
+ jr .done
+
+.player_1
+ ld a, [wCurPartyMon]
+ push af
+ ld a, $1
+ call EnemyPartyMonEntrance
+ call ClearSprites
+ call LoadTilemapToTempTilemap
+ pop af
+ ld [wCurPartyMon], a
+ call PlayerPartyMonEntrance
+
+.done
+ xor a ; BATTLEPLAYERACTION_USEMOVE
+ ld [wBattlePlayerAction], a
+ ret
+
+UpdateBattleStateAndExperienceAfterEnemyFaint:
+ call UpdateBattleMonInParty
+ ld a, [wBattleMode]
+ dec a
+ jr z, .wild
+ ld a, [wCurOTMon]
+ ld hl, wOTPartyMon1HP
+ call GetPartyLocation
+ xor a
+ ld [hli], a
+ ld [hl], a
+
+.wild
+ ld hl, wPlayerSubStatus3
+ res SUBSTATUS_IN_LOOP, [hl]
+ xor a
+ ld hl, wEnemyDamageTaken
+ ld [hli], a
+ ld [hl], a
+ call NewEnemyMonStatus
+ call BreakAttraction
+ ld a, [wBattleMode]
+ dec a
+ jr z, .wild2
+ jr .trainer
+
+.wild2
+ call StopDangerSound
+ ld a, $1
+ ld [wBattleLowHealthAlarm], a
+
+.trainer
+ ld hl, wBattleMonHP
+ ld a, [hli]
+ or [hl]
+ jr nz, .player_mon_did_not_faint
+ ld a, [wWhichMonFaintedFirst]
+ and a
+ jr nz, .player_mon_did_not_faint
+ call UpdateFaintedPlayerMon
+
+.player_mon_did_not_faint
+ call CheckPlayerPartyForFitMon
+ ld a, d
+ and a
+ ret z
+ ld a, [wBattleMode]
+ dec a
+ call z, PlayVictoryMusic
+ call EmptyBattleTextbox
+ call LoadTilemapToTempTilemap
+ ld a, [wBattleResult]
+ and BATTLERESULT_BITMASK
+ ld [wBattleResult], a ; WIN
+ call IsAnyMonHoldingExpShare
+ jr z, .skip_exp
+ ld hl, wEnemyMonBaseStats
+ ld b, wEnemyMonEnd - wEnemyMonBaseStats
+.loop
+ srl [hl]
+ inc hl
+ dec b
+ jr nz, .loop
+
+.skip_exp
+ ld hl, wEnemyMonBaseStats
+ ld de, wBackupEnemyMonBaseStats
+ ld bc, wEnemyMonEnd - wEnemyMonBaseStats
+ call CopyBytes
+ xor a
+ ld [wGivingExperienceToExpShareHolders], a
+ call GiveExperiencePoints
+ call IsAnyMonHoldingExpShare
+ ret z
+
+ ld a, [wBattleParticipantsNotFainted]
+ push af
+ ld a, d
+ ld [wBattleParticipantsNotFainted], a
+ ld hl, wBackupEnemyMonBaseStats
+ ld de, wEnemyMonBaseStats
+ ld bc, wEnemyMonEnd - wEnemyMonBaseStats
+ call CopyBytes
+ ld a, $1
+ ld [wGivingExperienceToExpShareHolders], a
+ call GiveExperiencePoints
+ pop af
+ ld [wBattleParticipantsNotFainted], a
+ ret
+
+IsAnyMonHoldingExpShare:
+ ld a, [wPartyCount]
+ ld b, a
+ ld hl, wPartyMon1
+ ld c, 1
+ ld d, 0
+.loop
+ push hl
+ push bc
+ ld bc, MON_HP
+ add hl, bc
+ ld a, [hli]
+ or [hl]
+ pop bc
+ pop hl
+ jr z, .next
+
+ push hl
+ push bc
+ ld bc, MON_ITEM
+ add hl, bc
+ pop bc
+ ld a, [hl]
+ pop hl
+
+ cp EXP_SHARE
+ jr nz, .next
+ ld a, d
+ or c
+ ld d, a
+
+.next
+ sla c
+ push de
+ ld de, PARTYMON_STRUCT_LENGTH
+ add hl, de
+ pop de
+ dec b
+ jr nz, .loop
+
+ ld a, d
+ ld e, 0
+ ld b, PARTY_LENGTH
+.loop2
+ srl a
+ jr nc, .okay
+ inc e
+
+.okay
+ dec b
+ jr nz, .loop2
+ ld a, e
+ and a
+ ret
+
+StopDangerSound:
+ xor a
+ ld [wLowHealthAlarm], a
+ ret
+
+FaintYourPokemon:
+ call StopDangerSound
+ call WaitSFX
+ ld a, $f0
+ ld [wCryTracks], a
+ ld a, [wBattleMonSpecies]
+ call PlayStereoCry
+ call PlayerMonFaintedAnimation
+ hlcoord 9, 7
+ lb bc, 5, 11
+ call ClearBox
+ ld hl, BattleText_MonFainted
+ jp StdBattleTextbox
+
+FaintEnemyPokemon:
+ call WaitSFX
+ ld de, SFX_KINESIS
+ call PlaySFX
+ call EnemyMonFaintedAnimation
+ ld de, SFX_FAINT
+ call PlaySFX
+ hlcoord 1, 0
+ lb bc, 4, 10
+ call ClearBox
+ ld hl, BattleText_EnemyMonFainted
+ jp StdBattleTextbox
+
+CheckEnemyTrainerDefeated:
+ ld a, [wOTPartyCount]
+ ld b, a
+ xor a
+ ld hl, wOTPartyMon1HP
+ ld de, PARTYMON_STRUCT_LENGTH
+
+.loop
+ or [hl]
+ inc hl
+ or [hl]
+ dec hl
+ add hl, de
+ dec b
+ jr nz, .loop
+
+ and a
+ ret
+
+HandleEnemySwitch:
+ ld hl, wEnemyHPPal
+ ld e, HP_BAR_LENGTH_PX
+ call UpdateHPPal
+ call WaitBGMap
+ farcall EnemySwitch_TrainerHud
+ ld a, [wLinkMode]
+ and a
+ jr z, .not_linked
+
+ call LinkBattleSendReceiveAction
+ ld a, [wBattleAction]
+ cp BATTLEACTION_FORFEIT
+ ret z
+
+ call SafeLoadTempTilemapToTilemap
+
+.not_linked
+ ld hl, wBattleMonHP
+ ld a, [hli]
+ or [hl]
+ ld a, $0
+ jr nz, EnemyPartyMonEntrance
+ inc a
+ ret
+
+EnemyPartyMonEntrance:
+ push af
+ xor a
+ ld [wEnemySwitchMonIndex], a
+ call NewEnemyMonStatus
+ call ResetEnemyStatLevels
+ call BreakAttraction
+ pop af
+ and a
+ jr nz, .set
+ call EnemySwitch
+ jr .done_switch
+
+.set
+ call EnemySwitch_SetMode
+.done_switch
+ call ResetBattleParticipants
+ call SetEnemyTurn
+ call SpikesDamage
+ xor a
+ ld [wEnemyMoveStruct + MOVE_ANIM], a
+ ld [wBattlePlayerAction], a
+ inc a
+ ret
+
+WinTrainerBattle:
+; Player won the battle
+ call StopDangerSound
+ ld a, $1
+ ld [wBattleLowHealthAlarm], a
+ ld [wBattleEnded], a
+ ld a, [wLinkMode]
+ and a
+ ld a, b
+ call z, PlayVictoryMusic
+ callfar Battle_GetTrainerName
+ ld hl, BattleText_EnemyWasDefeated
+ call StdBattleTextbox
+
+ ld a, [wLinkMode]
+ cp LINK_COLOSSEUM
+ ret z
+
+ call BattleWinSlideInEnemyTrainerFrontpic
+ ld c, 40
+ call DelayFrames
+ ld a, [wBattleType]
+ cp BATTLETYPE_CANLOSE
+ jr nz, .skip_heal
+ predef HealParty
+.skip_heal
+ ld a, [wDebugFlags]
+ bit DEBUG_BATTLE_F, a
+ jr nz, .GiveMoney
+ call PrintWinLossText
+
+.GiveMoney:
+ ld a, [wAmuletCoin]
+ and a
+ call nz, .DoubleReward
+ call .CheckMaxedOutMomMoney
+ push af
+ ld a, FALSE
+ jr nc, .okay
+ ld a, [wMomSavingMoney]
+ and MOM_SAVING_MONEY_MASK
+ cp (1 << MOM_SAVING_SOME_MONEY_F) | (1 << MOM_SAVING_HALF_MONEY_F)
+ jr nz, .okay
+ inc a ; TRUE
+
+.okay
+ ld b, a
+ ld c, 4
+.loop
+ ld a, b
+ and a
+ jr z, .loop2
+ call .AddMoneyToMom
+ dec c
+ dec b
+ jr .loop
+
+.loop2
+ ld a, c
+ and a
+ jr z, .done
+ call .AddMoneyToWallet
+ dec c
+ jr .loop2
+
+.done
+ call .DoubleReward
+ call .DoubleReward
+ pop af
+ jr nc, .KeepItAll
+ ld a, [wMomSavingMoney]
+ and MOM_SAVING_MONEY_MASK
+ jr z, .KeepItAll
+ ld hl, .SentToMomTexts
+ dec a
+ ld c, a
+ ld b, 0
+ add hl, bc
+ add hl, bc
+ ld a, [hli]
+ ld h, [hl]
+ ld l, a
+ jp StdBattleTextbox
+
+.KeepItAll:
+ ld hl, GotMoneyForWinningText
+ jp StdBattleTextbox
+
+.AddMoneyToMom:
+ push bc
+ ld hl, wBattleReward + 2
+ ld de, wMomsMoney + 2
+ call AddBattleMoneyToAccount
+ pop bc
+ ret
+
+.AddMoneyToWallet:
+ push bc
+ ld hl, wBattleReward + 2
+ ld de, wMoney + 2
+ call AddBattleMoneyToAccount
+ pop bc
+ ret
+
+.DoubleReward:
+ ld hl, wBattleReward + 2
+ sla [hl]
+ dec hl
+ rl [hl]
+ dec hl
+ rl [hl]
+ ret nc
+ ld a, $ff
+ ld [hli], a
+ ld [hli], a
+ ld [hl], a
+ ret
+
+.SentToMomTexts:
+; entries correspond to MOM_SAVING_* constants
+ dw SentSomeToMomText
+ dw SentHalfToMomText
+ dw SentAllToMomText
+
+.CheckMaxedOutMomMoney:
+ ld hl, wMomsMoney + 2
+ ld a, [hld]
+ cp LOW(MAX_MONEY)
+ ld a, [hld]
+ sbc HIGH(MAX_MONEY) ; mid
+ ld a, [hl]
+ sbc HIGH(MAX_MONEY >> 8)
+ ret
+
+AddBattleMoneyToAccount:
+ ld c, 3
+ and a
+ push de
+.loop
+ ld a, [de]
+ adc [hl]
+ ld [de], a
+ dec de
+ dec hl
+ dec c
+ jr nz, .loop
+ pop hl
+ ld a, [hld]
+ cp LOW(MAX_MONEY)
+ ld a, [hld]
+ sbc HIGH(MAX_MONEY) ; mid
+ ld a, [hl]
+ sbc HIGH(MAX_MONEY >> 8)
+ ret c
+ ld [hl], HIGH(MAX_MONEY >> 8)
+ inc hl
+ ld [hl], HIGH(MAX_MONEY) ; mid
+ inc hl
+ ld [hl], LOW(MAX_MONEY)
+ ret
+
+PlayVictoryMusic:
+ push de
+ ld de, MUSIC_NONE
+ call PlayMusic
+ call DelayFrame
+ ld de, MUSIC_WILD_VICTORY
+ ld a, [wBattleMode]
+ dec a
+ jr nz, .trainer_victory
+ push de
+ call IsAnyMonHoldingExpShare
+ pop de
+ jr nz, .play_music
+ ld hl, wPayDayMoney
+ ld a, [hli]
+ or [hl]
+ jr nz, .play_music
+ ld a, [wBattleParticipantsNotFainted]
+ and a
+ jr z, .lost
+ jr .play_music
+
+.trainer_victory
+ ld de, MUSIC_GYM_VICTORY
+ call IsGymLeader
+ jr c, .play_music
+ ld de, MUSIC_TRAINER_VICTORY
+
+.play_music
+ call PlayMusic
+
+.lost
+ pop de
+ ret
+
+IsKantoGymLeader:
+ ld hl, KantoGymLeaders
+ jr IsGymLeaderCommon
+
+IsGymLeader:
+ ld hl, GymLeaders
+IsGymLeaderCommon:
+ push de
+ ld a, [wOtherTrainerClass]
+ ld de, 1
+ call IsInArray
+ pop de
+ ret
+
+INCLUDE "data/trainers/leaders.asm"
+
+HandlePlayerMonFaint:
+ call FaintYourPokemon
+ ld hl, wEnemyMonHP
+ ld a, [hli]
+ or [hl]
+ call z, FaintEnemyPokemon
+ ld a, $1
+ ld [wWhichMonFaintedFirst], a
+ call UpdateFaintedPlayerMon
+ call CheckPlayerPartyForFitMon
+ ld a, d
+ and a
+ jp z, LostBattle
+ ld hl, wEnemyMonHP
+ ld a, [hli]
+ or [hl]
+ jr nz, .notfainted
+ call UpdateBattleStateAndExperienceAfterEnemyFaint
+ ld a, [wBattleMode]
+ dec a
+ jr nz, .trainer
+ ld a, $1
+ ld [wBattleEnded], a
+ ret
+
+.trainer
+ call CheckEnemyTrainerDefeated
+ jp z, WinTrainerBattle
+
+.notfainted
+ call AskUseNextPokemon
+ jr nc, .switch
+ ld a, $1
+ ld [wBattleEnded], a
+ ret
+
+.switch
+ call ForcePlayerMonChoice
+ ret nz
+ ld a, BATTLEPLAYERACTION_USEITEM
+ ld [wBattlePlayerAction], a
+ call HandleEnemySwitch
+ jp z, WildFled_EnemyFled_LinkBattleCanceled
+ jp DoubleSwitch
+
+UpdateFaintedPlayerMon:
+ ld a, [wCurBattleMon]
+ ld c, a
+ ld hl, wBattleParticipantsNotFainted
+ ld b, RESET_FLAG
+ predef SmallFarFlagAction
+ ld hl, wEnemySubStatus3
+ res SUBSTATUS_IN_LOOP, [hl]
+ xor a
+ ld [wLowHealthAlarm], a
+ ld hl, wPlayerDamageTaken
+ ld [hli], a
+ ld [hl], a
+ ld [wBattleMonStatus], a
+ call UpdateBattleMonInParty
+ ld c, HAPPINESS_FAINTED
+ ; If TheirLevel > (YourLevel + 30), use a different parameter
+ ld a, [wBattleMonLevel]
+ add 30
+ ld b, a
+ ld a, [wEnemyMonLevel]
+ cp b
+ jr c, .got_param
+ ld c, HAPPINESS_BEATENBYSTRONGFOE
+
+.got_param
+ ld a, [wCurBattleMon]
+ ld [wCurPartyMon], a
+ callfar ChangeHappiness
+ ld a, [wBattleResult]
+ and BATTLERESULT_BITMASK
+ add LOSE
+ ld [wBattleResult], a
+ ld a, [wWhichMonFaintedFirst]
+ and a
+ ret z
+ ret ; ??????????
+
+AskUseNextPokemon:
+ call EmptyBattleTextbox
+ call LoadTilemapToTempTilemap
+; We don't need to be here if we're in a Trainer battle,
+; as that decision is made for us.
+ ld a, [wBattleMode]
+ and a
+ dec a
+ ret nz
+
+ ld hl, BattleText_UseNextMon
+ call StdBattleTextbox
+.loop
+ lb bc, 1, 7
+ call PlaceYesNoBox
+ ld a, [wMenuCursorY]
+ jr c, .pressed_b
+ and a
+ ret
+
+.pressed_b
+ ld a, [wMenuCursorY]
+ cp $1 ; YES
+ jr z, .loop
+ ld hl, wPartyMon1Speed
+ ld de, wEnemyMonSpeed
+ jp TryToRunAwayFromBattle
+
+ForcePlayerMonChoice:
+ call EmptyBattleTextbox
+ call LoadStandardMenuHeader
+ call SetUpBattlePartyMenu_NoLoop
+ call ForcePickPartyMonInBattle
+ ld a, [wLinkMode]
+ cp LINK_COLOSSEUM
+ jr nz, .skip_link
+ ld a, BATTLEPLAYERACTION_USEITEM
+ ld [wBattlePlayerAction], a
+ call LinkBattleSendReceiveAction
+
+.skip_link
+ xor a ; BATTLEPLAYERACTION_USEMOVE
+ ld [wBattlePlayerAction], a
+ ld hl, wEnemyMonHP
+ ld a, [hli]
+ or [hl]
+ jr nz, .send_out_pokemon
+
+ call ClearSprites
+ call ClearBGPalettes
+ call _LoadHPBar
+ call ExitMenu
+ call LoadTilemapToTempTilemap
+ call WaitBGMap
+ call GetMemSGBLayout
+ call SetPalettes
+ xor a
+ ret
+
+.send_out_pokemon
+ call ClearSprites
+ ld a, [wCurBattleMon]
+ ld [wLastPlayerMon], a
+ ld a, [wCurPartyMon]
+ ld [wCurBattleMon], a
+ call AddBattleParticipant
+ call InitBattleMon
+ call ResetPlayerStatLevels
+ call ClearPalettes
+ call DelayFrame
+ call _LoadHPBar
+ call CloseWindow
+ call GetMemSGBLayout
+ call SetPalettes
+ call SendOutMonText
+ call NewBattleMonStatus
+ call BreakAttraction
+ call SendOutPlayerMon
+ call EmptyBattleTextbox
+ call LoadTilemapToTempTilemap
+ call SetPlayerTurn
+ call SpikesDamage
+ ld a, $1
+ and a
+ ret
+
+PlayerPartyMonEntrance:
+ ld a, [wCurBattleMon]
+ ld [wLastPlayerMon], a
+ ld a, [wCurPartyMon]
+ ld [wCurBattleMon], a
+ call AddBattleParticipant
+ call InitBattleMon
+ call ResetPlayerStatLevels
+ call SendOutMonText
+ call NewBattleMonStatus
+ call BreakAttraction
+ call SendOutPlayerMon
+ call EmptyBattleTextbox
+ call LoadTilemapToTempTilemap
+ call SetPlayerTurn
+ jp SpikesDamage
+
+SetUpBattlePartyMenu_NoLoop:
+ call ClearBGPalettes
+SetUpBattlePartyMenu: ; switch to fullscreen menu?
+ farcall LoadPartyMenuGFX
+ farcall InitPartyMenuWithCancel
+ farcall InitPartyMenuGFX
+ ret
+
+PickPartyMonInBattle:
+.loop
+ ld a, PARTYMENUACTION_SWITCH
+ ld [wPartyMenuActionText], a
+ farcall WritePartyMenuTilemap
+ farcall PrintPartyMenuText
+ call WaitBGMap
+ call SetPalettes
+ call DelayFrame
+ farcall PartyMenuSelect
+ ret c
+ call CheckIfCurPartyMonIsFitToFight
+ jr z, .loop
+ xor a
+ ret
+
+SwitchMonAlreadyOut:
+ ld hl, wCurBattleMon
+ ld a, [wCurPartyMon]
+ cp [hl]
+ jr nz, .notout
+
+ ld hl, BattleText_MonIsAlreadyOut
+ call StdBattleTextbox
+ scf
+ ret
+
+.notout
+ xor a
+ ret
+
+ForcePickPartyMonInBattle:
+; Can't back out.
+
+.pick
+ call PickPartyMonInBattle
+ ret nc
+
+ ld de, SFX_WRONG
+ call PlaySFX
+ call WaitSFX
+ jr .pick
+
+PickSwitchMonInBattle:
+.pick
+ call PickPartyMonInBattle
+ ret c
+ call SwitchMonAlreadyOut
+ jr c, .pick
+ xor a
+ ret
+
+ForcePickSwitchMonInBattle:
+; Can't back out.
+
+.pick
+ call ForcePickPartyMonInBattle
+ call SwitchMonAlreadyOut
+ jr c, .pick
+
+ xor a
+ ret
+
+LostBattle:
+ ld a, 1
+ ld [wBattleEnded], a
+ ld a, [wBattleType]
+ cp BATTLETYPE_CANLOSE
+ jr nz, .not_canlose
+
+; Remove the enemy from the screen.
+ hlcoord 0, 0
+ lb bc, 8, 21
+ call ClearBox
+ call BattleWinSlideInEnemyTrainerFrontpic
+
+ ld c, 40
+ call DelayFrames
+
+ ld a, [wDebugFlags]
+ bit DEBUG_BATTLE_F, a
+ jr nz, .skip_win_loss_text
+ call PrintWinLossText
+.skip_win_loss_text
+ ret
+
+.not_canlose
+ ld a, [wLinkMode]
+ and a
+ jr nz, .LostLinkBattle
+
+; Greyscale
+ ld b, SCGB_BATTLE_GRAYSCALE
+ call GetSGBLayout
+ call SetPalettes
+ jr .end
+
+.LostLinkBattle:
+ call UpdateEnemyMonInParty
+ call CheckEnemyTrainerDefeated
+ jr nz, .not_tied
+ ld hl, TiedAgainstText
+ ld a, [wBattleResult]
+ and BATTLERESULT_BITMASK
+ add DRAW
+ ld [wBattleResult], a
+ jr .text
+
+.not_tied
+ ld hl, LostAgainstText
+
+.text
+ call StdBattleTextbox
+
+.end
+ scf
+ ret
+
+EnemyMonFaintedAnimation:
+ hlcoord 12, 5
+ decoord 12, 6
+ jp MonFaintedAnimation
+
+PlayerMonFaintedAnimation:
+ hlcoord 1, 10
+ decoord 1, 11
+ jp MonFaintedAnimation
+
+MonFaintedAnimation:
+ ld a, [wd8ba]
+ push af
+ set 6, a
+ ld [wd8ba], a
+ ld b, 7
+
+.OuterLoop:
+ push bc
+ push de
+ push hl
+ ld b, 6
+
+.InnerLoop:
+ push bc
+ push hl
+ push de
+ ld bc, 7
+ call CopyBytes
+ pop de
+ pop hl
+ ld bc, -SCREEN_WIDTH
+ 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, .InnerLoop
+
+ ld bc, 20
+ add hl, bc
+ ld de, .Spaces
+ call PlaceString
+ ld c, 2
+ call DelayFrames
+ pop hl
+ pop de
+ pop bc
+ dec b
+ jr nz, .OuterLoop
+
+ pop af
+ ld [wd8ba], a
+ ret
+
+.Spaces:
+ db " @"
+
+SlideBattlePicOut:
+ ldh [hMapObjectIndexBuffer], a
+ ld c, a
+.loop
+ push bc
+ push hl
+ ld b, $7
+.loop2
+ push hl
+ call .DoFrame
+ pop hl
+ ld de, SCREEN_WIDTH
+ add hl, de
+ dec b
+ jr nz, .loop2
+ ld c, 2
+ call DelayFrames
+ pop hl
+ pop bc
+ dec c
+ jr nz, .loop
+ ret
+
+.DoFrame:
+ ldh a, [hMapObjectIndexBuffer]
+ ld c, a
+ cp $8
+ jr nz, .back
+.forward
+ ld a, [hli]
+ ld [hld], a
+ dec hl
+ dec c
+ jr nz, .forward
+ ret
+
+.back
+ ld a, [hld]
+ ld [hli], a
+ inc hl
+ dec c
+ jr nz, .back
+ ret
+
+ForceEnemySwitch:
+ call ResetEnemyBattleVars
+ ld a, [wEnemySwitchMonIndex]
+ dec a
+ ld b, a
+ call LoadEnemyMonToSwitchTo
+ call ClearEnemyMonBox
+ call NewEnemyMonStatus
+ call ResetEnemyStatLevels
+ call Function_SetEnemyMonAndSendOutAnimation
+ call BreakAttraction
+ call ResetBattleParticipants
+ ret
+
+EnemySwitch:
+ call CheckWhetherToAskSwitch
+ jr nc, EnemySwitch_SetMode
+ ; Shift Mode
+ call ResetEnemyBattleVars
+ call CheckWhetherSwitchmonIsPredetermined
+ jr c, .skip
+ call FindMonInOTPartyToSwitchIntoBattle
+.skip
+ ; 'b' contains the PartyNr of the mon the AI will switch to
+ call LoadEnemyMonToSwitchTo
+ call OfferSwitch
+ push af
+ call ClearEnemyMonBox
+ call Function_BattleTextEnemySentOut
+ call Function_SetEnemyMonAndSendOutAnimation
+ pop af
+ ret c
+ ; If we're here, then we're switching too
+ xor a
+ ld [wBattleParticipantsNotFainted], a
+ ld [wBattleParticipantsIncludingFainted], a
+ ld [wBattlePlayerAction], a
+ inc a
+ ld [wEnemyIsSwitching], a
+ call LoadTilemapToTempTilemap
+ jp PlayerSwitch
+
+EnemySwitch_SetMode:
+ call ResetEnemyBattleVars
+ call CheckWhetherSwitchmonIsPredetermined
+ jr c, .skip
+ call FindMonInOTPartyToSwitchIntoBattle
+.skip
+ ; 'b' contains the PartyNr of the mon the AI will switch to
+ call LoadEnemyMonToSwitchTo
+ ld a, 1
+ ld [wEnemyIsSwitching], a
+ call ClearEnemyMonBox
+ call Function_BattleTextEnemySentOut
+ jp Function_SetEnemyMonAndSendOutAnimation
+
+CheckWhetherSwitchmonIsPredetermined:
+; returns carry if: ???
+ ld a, [wLinkMode]
+ and a
+ jr z, .not_linked
+
+ ld a, [wBattleAction]
+ sub BATTLEACTION_SWITCH1
+ ld b, a
+ jr .return_carry
+
+.not_linked
+ ld a, [wEnemySwitchMonIndex]
+ and a
+ jr z, .check_wBattleHasJustStarted
+
+ dec a
+ ld b, a
+ jr .return_carry
+
+.check_wBattleHasJustStarted
+ ld a, [wBattleHasJustStarted]
+ and a
+ ld b, $0
+ jr nz, .return_carry
+
+ and a
+ ret
+
+.return_carry
+ scf
+ ret
+
+ResetEnemyBattleVars:
+; and draw empty Textbox
+ xor a
+ ld [wLastPlayerCounterMove], a
+ ld [wLastEnemyCounterMove], a
+ ld [wLastEnemyMove], a
+ ld [wCurEnemyMove], a
+ dec a
+ ld [wEnemyItemState], a
+ xor a
+ ld [wPlayerWrapCount], a
+ hlcoord 18, 0
+ ld a, 8
+ call SlideBattlePicOut
+ call EmptyBattleTextbox
+ jp LoadStandardMenuHeader
+
+ResetBattleParticipants:
+ xor a
+ ld [wBattleParticipantsNotFainted], a
+ ld [wBattleParticipantsIncludingFainted], a
+AddBattleParticipant:
+ ld a, [wCurBattleMon]
+ ld c, a
+ ld hl, wBattleParticipantsNotFainted
+ ld b, SET_FLAG
+ push bc
+ predef SmallFarFlagAction
+ pop bc
+ ld hl, wBattleParticipantsIncludingFainted
+ predef_jump SmallFarFlagAction
+
+FindMonInOTPartyToSwitchIntoBattle:
+ ld b, -1
+ ld a, $1
+ ld [wBuffer1], a
+ ld [wBuffer2], a
+.loop
+ ld hl, wBuffer1
+ sla [hl]
+ inc hl
+ sla [hl]
+ inc b
+ ld a, [wOTPartyCount]
+ cp b
+ jp z, ScoreMonTypeMatchups
+ ld a, [wCurOTMon]
+ cp b
+ jr z, .discourage
+ ld hl, wOTPartyMon1HP
+ push bc
+ ld a, b
+ call GetPartyLocation
+ ld a, [hli]
+ ld c, a
+ ld a, [hl]
+ or c
+ pop bc
+ jr z, .discourage
+ call LookUpTheEffectivenessOfEveryMove
+ call IsThePlayerMonTypesEffectiveAgainstOTMon
+ jr .loop
+
+.discourage
+ ld hl, wBuffer2
+ set 0, [hl]
+ jr .loop
+
+LookUpTheEffectivenessOfEveryMove:
+ push bc
+ ld hl, wOTPartyMon1Moves
+ ld a, b
+ call GetPartyLocation
+ pop bc
+ ld e, NUM_MOVES + 1
+.loop
+ dec e
+ jr z, .done
+ ld a, [hli]
+ and a
+ jr z, .done
+ push hl
+ push de
+ push bc
+ dec a
+ ld hl, Moves
+ ld bc, MOVE_LENGTH
+ call AddNTimes
+ ld de, wEnemyMoveStruct
+ ld a, BANK(Moves)
+ call FarCopyBytes
+ call SetEnemyTurn
+ callfar BattleCheckTypeMatchup
+ pop bc
+ pop de
+ pop hl
+ ld a, [wTypeMatchup]
+ cp EFFECTIVE + 1
+ jr c, .loop
+ ld hl, wBuffer1
+ set 0, [hl]
+ ret
+.done
+ ret
+
+IsThePlayerMonTypesEffectiveAgainstOTMon:
+; Calculates the effectiveness of the types of the PlayerMon
+; against the OTMon
+ push bc
+ ld hl, wOTPartyCount
+ ld a, b
+ inc a
+ ld c, a
+ ld b, 0
+ add hl, bc
+ ld a, [hl]
+ dec a
+ ld hl, BaseData + BASE_TYPES
+ ld bc, BASE_DATA_SIZE
+ call AddNTimes
+ ld de, wEnemyMonType
+ ld bc, BASE_CATCH_RATE - BASE_TYPES
+ ld a, BANK(BaseData)
+ call FarCopyBytes
+ ld a, [wBattleMonType1]
+ ld [wPlayerMoveStruct + MOVE_TYPE], a
+ call SetPlayerTurn
+ callfar BattleCheckTypeMatchup
+ ld a, [wTypeMatchup]
+ cp EFFECTIVE + 1
+ jr nc, .super_effective
+ ld a, [wBattleMonType2]
+ ld [wPlayerMoveStruct + MOVE_TYPE], a
+ callfar BattleCheckTypeMatchup
+ ld a, [wTypeMatchup]
+ cp EFFECTIVE + 1
+ jr nc, .super_effective
+ pop bc
+ ret
+
+.super_effective
+ pop bc
+ ld hl, wBuffer1
+ bit 0, [hl]
+ jr nz, .reset
+ inc hl
+ set 0, [hl]
+ ret
+
+.reset
+ res 0, [hl]
+ ret
+
+ScoreMonTypeMatchups:
+.loop1
+ ld hl, wBuffer1
+ sla [hl]
+ inc hl
+ sla [hl]
+ jr nc, .loop1
+ ld a, [wOTPartyCount]
+ ld b, a
+ ld c, [hl]
+.loop2
+ sla c
+ jr nc, .okay
+ dec b
+ jr z, .loop5
+ jr .loop2
+
+.okay
+ ld a, [wBuffer1]
+ and a
+ jr z, .okay2
+ ld b, -1
+ ld c, a
+.loop3
+ inc b
+ sla c
+ jr nc, .loop3
+ jr .quit
+
+.okay2
+ ld b, -1
+ ld a, [wBuffer2]
+ ld c, a
+.loop4
+ inc b
+ sla c
+ jr c, .loop4
+ jr .quit
+
+.loop5
+ call BattleRandom
+ and $7
+ cp 6
+ jr nc, .loop5
+ ld b, a
+ ld a, [wCurOTMon]
+ cp b
+ jr z, .loop5
+ ld hl, wOTPartyMon1HP
+ push bc
+ ld a, b
+ call GetPartyLocation
+ pop bc
+ ld a, [hli]
+ ld c, a
+ ld a, [hl]
+ or c
+ jr z, .loop5
+
+.quit
+ ret
+
+LoadEnemyMonToSwitchTo:
+ ; 'b' contains the PartyNr of the mon the AI will switch to
+ ld a, b
+ ld [wCurPartyMon], a
+ ld hl, wOTPartyMon1Level
+ call GetPartyLocation
+ ld a, [hl]
+ ld [wCurPartyLevel], a
+ ld a, [wCurPartyMon]
+ inc a
+ ld hl, wOTPartyCount
+ ld c, a
+ ld b, 0
+ add hl, bc
+ ld a, [hl]
+ ld [wTempEnemyMonSpecies], a
+ ld [wCurPartySpecies], a
+ call LoadEnemyMon
+
+ ld a, [wCurPartySpecies]
+ cp UNOWN
+ jr nz, .skip_unown
+ ld a, [wFirstUnownSeen]
+ and a
+ jr nz, .skip_unown
+ ld hl, wEnemyMonDVs
+ predef GetUnownLetter
+ ld a, [wUnownLetter]
+ ld [wFirstUnownSeen], a
+.skip_unown
+
+ ld hl, wEnemyMonHP
+ ld a, [hli]
+ ld [wEnemyHPAtTimeOfPlayerSwitch], a
+ ld a, [hl]
+ ld [wEnemyHPAtTimeOfPlayerSwitch + 1], a
+ ret
+
+CheckWhetherToAskSwitch:
+ ld a, [wBattleHasJustStarted]
+ dec a
+ jp z, .return_nc
+ ld a, [wPartyCount]
+ dec a
+ jp z, .return_nc
+ ld a, [wLinkMode]
+ and a
+ jp nz, .return_nc
+ ld a, [wOptions]
+ bit BATTLE_SHIFT, a
+ jr nz, .return_nc
+ ld a, [wCurPartyMon]
+ push af
+ ld a, [wCurBattleMon]
+ ld [wCurPartyMon], a
+ farcall CheckCurPartyMonFainted
+ pop bc
+ ld a, b
+ ld [wCurPartyMon], a
+ jr c, .return_nc
+ scf
+ ret
+
+.return_nc
+ and a
+ ret
+
+OfferSwitch:
+ ld a, [wCurPartyMon]
+ push af
+ callfar Battle_GetTrainerName
+ ld hl, BattleText_EnemyIsAboutToUseWillPlayerChangeMon
+ call StdBattleTextbox
+ lb bc, 1, 7
+ call PlaceYesNoBox
+ ld a, [wMenuCursorY]
+ dec a
+ jr nz, .said_no
+ call SetUpBattlePartyMenu_NoLoop
+ call PickSwitchMonInBattle
+ jr c, .canceled_switch
+ ld a, [wCurBattleMon]
+ ld [wLastPlayerMon], a
+ ld a, [wCurPartyMon]
+ ld [wCurBattleMon], a
+ call ClearPalettes
+ call DelayFrame
+ call _LoadHPBar
+ pop af
+ ld [wCurPartyMon], a
+ xor a
+ ld [wCurEnemyMove], a
+ ld [wCurPlayerMove], a
+ and a
+ ret
+
+.canceled_switch
+ call ClearPalettes
+ call DelayFrame
+ call _LoadHPBar
+
+.said_no
+ pop af
+ ld [wCurPartyMon], a
+ scf
+ ret
+
+ClearEnemyMonBox:
+ xor a
+ ldh [hBGMapMode], a
+ call ExitMenu
+ call ClearSprites
+ hlcoord 1, 0
+ lb bc, 4, 10
+ call ClearBox
+ call WaitBGMap
+ jp FinishBattleAnim
+
+Function_BattleTextEnemySentOut:
+ callfar Battle_GetTrainerName
+ ld hl, BattleText_EnemySentOut
+ jp StdBattleTextbox
+
+Function_SetEnemyMonAndSendOutAnimation:
+ ld a, [wTempEnemyMonSpecies]
+ ld [wCurPartySpecies], a
+ ld [wCurSpecies], a
+ call GetBaseData
+ ld a, OTPARTYMON
+ ld [wMonType], a
+ predef CopyMonToTempMon
+ call GetEnemyMonFrontpic
+
+ xor a
+ ld [wNumHits], a
+ ld [wBattleAnimParam], a
+ call SetEnemyTurn
+ ld de, ANIM_SEND_OUT_MON
+ call Call_PlayBattleAnim
+
+ call BattleCheckEnemyShininess
+ jr nc, .cry_no_anim
+
+ ld a, 1 ; shiny anim
+ ld [wBattleAnimParam], a
+ ld de, ANIM_SEND_OUT_MON
+ call Call_PlayBattleAnim
+
+.cry_no_anim
+ ld a, $f
+ ld [wCryTracks], a
+ ld a, [wTempEnemyMonSpecies]
+ call PlayStereoCry
+ call UpdateEnemyHUD
+ ld a, $1
+ ldh [hBGMapMode], a
+ ret
+
+NewEnemyMonStatus:
+ xor a
+ ld [wLastPlayerCounterMove], a
+ ld [wLastEnemyCounterMove], a
+ ld [wLastEnemyMove], a
+ ld hl, wEnemySubStatus1
+rept 4
+ ld [hli], a
+endr
+ ld [hl], a
+ ld [wEnemyDisableCount], a
+ ld [wEnemyFuryCutterCount], a
+ ld [wEnemyProtectCount], a
+ ld [wEnemyRageCounter], a
+ ld [wEnemyDisabledMove], a
+ ld [wEnemyMinimized], a
+ ld [wPlayerWrapCount], a
+ ld [wEnemyWrapCount], a
+ ld [wEnemyTurnsTaken], a
+ ld hl, wPlayerSubStatus5
+ res SUBSTATUS_CANT_RUN, [hl]
+ ret
+
+ResetEnemyStatLevels:
+ ld a, BASE_STAT_LEVEL
+ ld b, NUM_LEVEL_STATS
+ ld hl, wEnemyStatLevels
+.loop
+ ld [hli], a
+ dec b
+ jr nz, .loop
+ ret
+
+CheckPlayerPartyForFitMon:
+; Has the player any mon in his Party that can fight?
+ ld a, [wPartyCount]
+ ld e, a
+ xor a
+ ld hl, wPartyMon1HP
+ ld bc, PARTYMON_STRUCT_LENGTH - 1
+.loop
+ or [hl]
+ inc hl ; + 1
+ or [hl]
+ add hl, bc
+ dec e
+ jr nz, .loop
+ ld d, a
+ ret
+
+CheckIfCurPartyMonIsFitToFight:
+ ld a, [wCurPartyMon]
+ ld hl, wPartyMon1HP
+ call GetPartyLocation
+ ld a, [hli]
+ or [hl]
+ ret nz
+
+ ld a, [wBattleHasJustStarted]
+ and a
+ jr nz, .finish_fail
+ ld hl, wPartySpecies
+ ld a, [wCurPartyMon]
+ ld c, a
+ ld b, 0
+ add hl, bc
+ ld a, [hl]
+ cp EGG
+ ld hl, BattleText_AnEGGCantBattle
+ jr z, .print_textbox
+
+ ld hl, BattleText_TheresNoWillToBattle
+
+.print_textbox
+ call StdBattleTextbox
+
+.finish_fail
+ xor a
+ ret
+
+TryToRunAwayFromBattle:
+; Run away from battle, with or without item
+ ld a, [wBattleType]
+ cp BATTLETYPE_DEBUG
+ jp z, .can_escape
+ cp BATTLETYPE_CONTEST
+ jp z, .can_escape
+ cp BATTLETYPE_TRAP
+ jp z, .cant_escape
+ cp BATTLETYPE_SHINY
+ jp z, .cant_escape
+
+ ld a, [wLinkMode]
+ and a
+ jp nz, .can_escape
+
+ ld a, [wBattleMode]
+ dec a
+ jp nz, .cant_run_from_trainer
+
+ ld a, [wEnemySubStatus5]
+ bit SUBSTATUS_CANT_RUN, a
+ jp nz, .cant_escape
+
+ ld a, [wPlayerWrapCount]
+ and a
+ jp nz, .cant_escape
+
+ push hl
+ push de
+ ld a, [wBattleMonItem]
+ ld [wNamedObjectIndexBuffer], a
+ ld b, a
+ callfar GetItemHeldEffect
+ ld a, b
+ cp HELD_ESCAPE
+ pop de
+ pop hl
+ jr nz, .no_flee_item
+
+ call SetPlayerTurn
+ call GetItemName
+ ld hl, BattleText_UserFledUsingAStringBuffer1
+ call StdBattleTextbox
+ jp .can_escape
+
+.no_flee_item
+ ld a, [wNumFleeAttempts]
+ inc a
+ ld [wNumFleeAttempts], a
+ ld a, [hli]
+ ldh [hMultiplicand + 1], a
+ ld a, [hl]
+ ldh [hMultiplicand + 2], a
+ ld a, [de]
+ inc de
+ ldh [hEnemyMonSpeed + 0], a
+ ld a, [de]
+ ldh [hEnemyMonSpeed + 1], a
+ call SafeLoadTempTilemapToTilemap
+ ld de, hMultiplicand + 1
+ ld hl, hEnemyMonSpeed
+ ld c, 2
+ call CompareBytes
+ jr nc, .can_escape
+
+ xor a
+ ldh [hMultiplicand + 0], a
+ ld a, 32
+ ldh [hMultiplier], a
+ call Multiply
+ ldh a, [hProduct + 2]
+ ldh [hDividend + 0], a
+ ldh a, [hProduct + 3]
+ ldh [hDividend + 1], a
+ ldh a, [hEnemyMonSpeed + 0]
+ ld b, a
+ ldh a, [hEnemyMonSpeed + 1]
+ srl b
+ rr a
+ srl b
+ rr a
+ and a
+ jr z, .can_escape
+ ldh [hDivisor], a
+ ld b, 2
+ call Divide
+ ldh a, [hQuotient + 2]
+ and a
+ jr nz, .can_escape
+ ld a, [wNumFleeAttempts]
+ ld c, a
+.loop
+ dec c
+ jr z, .cant_escape_2
+ ld b, 30
+ ldh a, [hQuotient + 3]
+ add b
+ ldh [hQuotient + 3], a
+ jr c, .can_escape
+ jr .loop
+
+.cant_escape_2
+ call BattleRandom
+ ld b, a
+ ldh a, [hQuotient + 3]
+ cp b
+ jr nc, .can_escape
+ ld a, BATTLEPLAYERACTION_USEITEM
+ ld [wBattlePlayerAction], a
+ ld hl, BattleText_CantEscape2
+ jr .print_inescapable_text
+
+.cant_escape
+ ld hl, BattleText_CantEscape
+ jr .print_inescapable_text
+
+.cant_run_from_trainer
+ ld hl, BattleText_TheresNoEscapeFromTrainerBattle
+
+.print_inescapable_text
+ call StdBattleTextbox
+ ld a, TRUE
+ ld [wFailedToFlee], a
+ call LoadTilemapToTempTilemap
+ and a
+ ret
+
+.can_escape
+ ld a, [wLinkMode]
+ and a
+ ld a, DRAW
+ jr z, .fled
+ call LoadTilemapToTempTilemap
+ xor a ; BATTLEPLAYERACTION_USEMOVE
+ ld [wBattlePlayerAction], a
+ ld a, $f
+ ld [wCurMoveNum], a
+ xor a
+ ld [wCurPlayerMove], a
+ call LinkBattleSendReceiveAction
+ call SafeLoadTempTilemapToTilemap
+
+ ; Got away safely
+ ld a, [wBattleAction]
+ cp BATTLEACTION_FORFEIT
+ ld a, DRAW
+ jr z, .fled
+ dec a ; LOSE
+.fled
+ ld b, a
+ ld a, [wBattleResult]
+ and BATTLERESULT_BITMASK
+ add b
+ ld [wBattleResult], a
+ call StopDangerSound
+ push de
+ ld de, SFX_RUN
+ call WaitPlaySFX
+ pop de
+ call WaitSFX
+ ld hl, BattleText_GotAwaySafely
+ call StdBattleTextbox
+ call WaitSFX
+ call LoadTilemapToTempTilemap
+ scf
+ ret
+
+InitBattleMon:
+ ld a, MON_SPECIES
+ call GetPartyParamLocation
+ ld de, wBattleMonSpecies
+ ld bc, MON_ID
+ call CopyBytes
+ ld bc, MON_DVS - MON_ID
+ add hl, bc
+ ld de, wBattleMonDVs
+ ld bc, MON_PKRUS - MON_DVS
+ call CopyBytes
+ inc hl
+ inc hl
+ inc hl
+ ld de, wBattleMonLevel
+ ld bc, PARTYMON_STRUCT_LENGTH - MON_LEVEL
+ call CopyBytes
+ ld a, [wBattleMonSpecies]
+ ld [wTempBattleMonSpecies], a
+ ld [wCurPartySpecies], a
+ ld [wCurSpecies], a
+ call GetBaseData
+ ld a, [wBaseType1]
+ ld [wBattleMonType1], a
+ ld a, [wBaseType2]
+ ld [wBattleMonType2], a
+ ld hl, wPartyMonNicknames
+ ld a, [wCurBattleMon]
+ call SkipNames
+ ld de, wBattleMonNick
+ ld bc, MON_NAME_LENGTH
+ call CopyBytes
+ ld hl, wBattleMonAttack
+ ld de, wPlayerStats
+ ld bc, PARTYMON_STRUCT_LENGTH - MON_ATK
+ call CopyBytes
+ call ApplyStatusEffectOnPlayerStats
+ call BadgeStatBoosts
+ ret
+
+BattleCheckPlayerShininess:
+ call GetPartyMonDVs
+ jr BattleCheckShininess
+
+BattleCheckEnemyShininess:
+ call GetEnemyMonDVs
+
+BattleCheckShininess:
+ ld b, h
+ ld c, l
+ callfar CheckShininess
+ ret
+
+GetPartyMonDVs:
+ ld hl, wBattleMonDVs
+ ld a, [wPlayerSubStatus5]
+ bit SUBSTATUS_TRANSFORMED, a
+ ret z
+ ld hl, wPartyMon1DVs
+ ld a, [wCurBattleMon]
+ jp GetPartyLocation
+
+GetEnemyMonDVs:
+ ld hl, wEnemyMonDVs
+ ld a, [wEnemySubStatus5]
+ bit SUBSTATUS_TRANSFORMED, a
+ ret z
+ ld hl, wEnemyBackupDVs
+ ld a, [wBattleMode]
+ dec a
+ ret z
+ ld hl, wOTPartyMon1DVs
+ ld a, [wCurOTMon]
+ jp GetPartyLocation
+
+ResetPlayerStatLevels:
+ ld a, BASE_STAT_LEVEL
+ ld b, NUM_LEVEL_STATS
+ ld hl, wPlayerStatLevels
+.loop
+ ld [hli], a
+ dec b
+ jr nz, .loop
+ ret
+
+InitEnemyMon:
+ ld a, [wCurPartyMon]
+ ld hl, wOTPartyMon1Species
+ call GetPartyLocation
+ ld de, wEnemyMonSpecies
+ ld bc, MON_ID
+ call CopyBytes
+ ld bc, MON_DVS - MON_ID
+ add hl, bc
+ ld de, wEnemyMonDVs
+ ld bc, MON_PKRUS - MON_DVS
+ call CopyBytes
+ inc hl
+ inc hl
+ inc hl
+ ld de, wEnemyMonLevel
+ ld bc, PARTYMON_STRUCT_LENGTH - MON_LEVEL
+ call CopyBytes
+ ld a, [wEnemyMonSpecies]
+ ld [wCurSpecies], a
+ call GetBaseData
+ ld hl, wOTPartyMonNicknames
+ ld a, [wCurPartyMon]
+ call SkipNames
+ ld de, wEnemyMonNick
+ ld bc, MON_NAME_LENGTH
+ call CopyBytes
+ ld hl, wEnemyMonAttack
+ ld de, wEnemyStats
+ ld bc, PARTYMON_STRUCT_LENGTH - MON_ATK
+ call CopyBytes
+ call ApplyStatusEffectOnEnemyStats
+ ld hl, wBaseType1
+ ld de, wEnemyMonType1
+ ld a, [hli]
+ ld [de], a
+ inc de
+ ld a, [hl]
+ ld [de], a
+ ld hl, wBaseStats
+ ld de, wEnemyMonBaseStats
+ ld b, 5
+.loop
+ ld a, [hli]
+ ld [de], a
+ inc de
+ dec b
+ jr nz, .loop
+ ld a, [wCurPartyMon]
+ ld [wCurOTMon], a
+ ret
+
+SwitchPlayerMon:
+ call ClearSprites
+ ld a, [wCurBattleMon]
+ ld [wLastPlayerMon], a
+ ld a, [wCurPartyMon]
+ ld [wCurBattleMon], a
+ call AddBattleParticipant
+ call InitBattleMon
+ call ResetPlayerStatLevels
+ call NewBattleMonStatus
+ call BreakAttraction
+ call SendOutPlayerMon
+ call EmptyBattleTextbox
+ call LoadTilemapToTempTilemap
+ ld hl, wEnemyMonHP
+ ld a, [hli]
+ or [hl]
+ ret
+
+SendOutPlayerMon:
+ ld hl, wBattleMonDVs
+ predef GetUnownLetter
+ hlcoord 1, 5
+ ld b, 7
+ ld c, 8
+ call ClearBox
+ call WaitBGMap
+ xor a
+ ldh [hBGMapMode], a
+ call GetBattleMonBackpic
+ xor a
+ ldh [hGraphicStartTile], a
+ ld [wBattleMenuCursorBuffer], a
+ ld [wCurMoveNum], a
+ ld [wTypeModifier], a
+ ld [wPlayerMoveStruct + MOVE_ANIM], a
+ ld [wLastPlayerCounterMove], a
+ ld [wLastEnemyCounterMove], a
+ ld [wLastPlayerMove], a
+ call CheckAmuletCoin
+ call FinishBattleAnim
+ xor a
+ ld [wEnemyWrapCount], a
+ call SetPlayerTurn
+ xor a
+ ld [wNumHits], a
+ ld [wBattleAnimParam], a
+ ld de, ANIM_SEND_OUT_MON
+ call Call_PlayBattleAnim
+ call BattleCheckPlayerShininess
+ jr nc, .not_shiny
+ ld a, 1
+ ld [wBattleAnimParam], a
+ ld de, ANIM_SEND_OUT_MON
+ call Call_PlayBattleAnim
+
+.not_shiny
+ ld a, $f0
+ ld [wCryTracks], a
+ ld a, [wCurPartySpecies]
+ call PlayStereoCry
+ call UpdatePlayerHUD
+ ld a, $1
+ ldh [hBGMapMode], a
+ ret
+
+NewBattleMonStatus:
+ xor a
+ ld [wLastPlayerCounterMove], a
+ ld [wLastEnemyCounterMove], a
+ ld [wLastPlayerMove], a
+ ld hl, wPlayerSubStatus1
+rept 4
+ ld [hli], a
+endr
+ ld [hl], a
+ ld hl, wPlayerUsedMoves
+ ld [hli], a
+ ld [hli], a
+ ld [hli], a
+ ld [hl], a
+ ld [wPlayerDisableCount], a
+ ld [wPlayerFuryCutterCount], a
+ ld [wPlayerProtectCount], a
+ ld [wPlayerRageCounter], a
+ ld [wDisabledMove], a
+ ld [wPlayerMinimized], a
+ ld [wEnemyWrapCount], a
+ ld [wPlayerWrapCount], a
+ ld [wPlayerTurnsTaken], a
+ ld hl, wEnemySubStatus5
+ res SUBSTATUS_CANT_RUN, [hl]
+ ret
+
+BreakAttraction:
+ ld hl, wPlayerSubStatus1
+ res SUBSTATUS_IN_LOVE, [hl]
+ ld hl, wEnemySubStatus1
+ res SUBSTATUS_IN_LOVE, [hl]
+ ret
+
+SpikesDamage:
+ ld hl, wPlayerScreens
+ ld de, wBattleMonType
+ ld bc, UpdatePlayerHUD
+ ldh a, [hBattleTurn]
+ and a
+ jr z, .ok
+ ld hl, wEnemyScreens
+ ld de, wEnemyMonType
+ ld bc, UpdateEnemyHUD
+.ok
+
+ bit SCREENS_SPIKES, [hl]
+ ret z
+
+ ; Flying-types aren't affected by Spikes.
+ ld a, [de]
+ cp FLYING
+ ret z
+ inc de
+ ld a, [de]
+ cp FLYING
+ ret z
+
+ push bc
+
+ ld hl, BattleText_UserHurtBySpikes ; "hurt by SPIKES!"
+ call StdBattleTextbox
+
+ call GetEighthMaxHP
+ call SubtractHPFromTarget
+
+ pop hl
+ call .hl
+
+ jp WaitBGMap
+
+.hl
+ jp hl
+
+PursuitSwitch:
+ ld a, BATTLE_VARS_MOVE
+ call GetBattleVar
+ ld b, a
+ call GetMoveEffect
+ ld a, b
+ cp EFFECT_PURSUIT
+ jr nz, .done
+
+ ld a, [wCurBattleMon]
+ push af
+
+ ld hl, DoPlayerTurn
+ ldh a, [hBattleTurn]
+ and a
+ jr z, .do_turn
+ ld hl, DoEnemyTurn
+ ld a, [wLastPlayerMon]
+ ld [wCurBattleMon], a
+.do_turn
+ ld a, BANK(DoPlayerTurn) ; aka BANK(DoEnemyTurn)
+ rst FarCall
+
+ ld a, BATTLE_VARS_MOVE
+ call GetBattleVarAddr
+ ld a, $ff
+ ld [hl], a
+
+ pop af
+ ld [wCurBattleMon], a
+
+ ldh a, [hBattleTurn]
+ and a
+ jr z, .check_enemy_fainted
+
+ ld a, [wLastPlayerMon]
+ call UpdateBattleMon
+ ld hl, wBattleMonHP
+ ld a, [hli]
+ or [hl]
+ jr nz, .done
+
+ ld a, $f0
+ ld [wCryTracks], a
+ ld a, [wBattleMonSpecies]
+ call PlayStereoCry
+ ld a, [wLastPlayerMon]
+ ld c, a
+ ld hl, wBattleParticipantsNotFainted
+ ld b, RESET_FLAG
+ predef SmallFarFlagAction
+ call PlayerMonFaintedAnimation
+ ld hl, BattleText_MonFainted
+ jr .done_fainted
+
+.check_enemy_fainted
+ ld hl, wEnemyMonHP
+ ld a, [hli]
+ or [hl]
+ jr nz, .done
+
+ ld de, SFX_KINESIS
+ call PlaySFX
+ call WaitSFX
+ ld de, SFX_FAINT
+ call PlaySFX
+ call WaitSFX
+ call EnemyMonFaintedAnimation
+ ld hl, BattleText_EnemyMonFainted
+
+.done_fainted
+ call StdBattleTextbox
+ scf
+ ret
+
+.done
+ and a
+ ret
+
+RecallPlayerMon:
+ ldh a, [hBattleTurn]
+ push af
+ xor a
+ ldh [hBattleTurn], a
+ ld [wNumHits], a
+ ld de, ANIM_RETURN_MON
+ call Call_PlayBattleAnim
+ pop af
+ ldh [hBattleTurn], a
+ ret
+
+HandleHealingItems:
+ ldh a, [hSerialConnectionStatus]
+ cp USING_EXTERNAL_CLOCK
+ jr z, .player_1
+ call SetPlayerTurn
+ call HandleHPHealingItem
+ call UseHeldStatusHealingItem
+ call UseConfusionHealingItem
+ call SetEnemyTurn
+ call HandleHPHealingItem
+ call UseHeldStatusHealingItem
+ jp UseConfusionHealingItem
+
+.player_1
+ call SetEnemyTurn
+ call HandleHPHealingItem
+ call UseHeldStatusHealingItem
+ call UseConfusionHealingItem
+ call SetPlayerTurn
+ call HandleHPHealingItem
+ call UseHeldStatusHealingItem
+ jp UseConfusionHealingItem
+
+HandleHPHealingItem:
+ callfar GetOpponentItem
+ ld a, b
+ cp HELD_BERRY
+ ret nz
+ ld de, wEnemyMonHP + 1
+ ld hl, wEnemyMonMaxHP
+ ldh a, [hBattleTurn]
+ and a
+ jr z, .go
+ ld de, wBattleMonHP + 1
+ ld hl, wBattleMonMaxHP
+
+.go
+; If, and only if, Pokemon's HP is less than half max, use the item.
+; Store current HP in Buffer 3/4
+ push bc
+ ld a, [de]
+ ld [wBuffer3], a
+ add a
+ ld c, a
+ dec de
+ ld a, [de]
+ inc de
+ ld [wBuffer4], a
+ adc a
+ ld b, a
+ ld a, b
+ cp [hl]
+ ld a, c
+ pop bc
+ jr z, .equal
+ jr c, .less
+ ret
+
+.equal
+ inc hl
+ cp [hl]
+ dec hl
+ ret nc
+
+.less
+ call ItemRecoveryAnim
+ ; store max HP in wBuffer1/2
+ ld a, [hli]
+ ld [wBuffer2], a
+ ld a, [hl]
+ ld [wBuffer1], a
+ ld a, [de]
+ add c
+ ld [wBuffer5], a
+ ld c, a
+ dec de
+ ld a, [de]
+ adc 0
+ ld [wBuffer6], a
+ ld b, a
+ ld a, [hld]
+ cp c
+ ld a, [hl]
+ sbc b
+ jr nc, .okay
+ ld a, [hli]
+ ld [wBuffer6], a
+ ld a, [hl]
+ ld [wBuffer5], a
+
+.okay
+ ld a, [wBuffer6]
+ ld [de], a
+ inc de
+ ld a, [wBuffer5]
+ ld [de], a
+ ldh a, [hBattleTurn]
+ ld [wWhichHPBar], a
+ and a
+ hlcoord 2, 2
+ jr z, .got_hp_bar_coords
+ hlcoord 10, 9
+
+.got_hp_bar_coords
+ ld [wWhichHPBar], a
+ predef AnimateHPBar
+UseOpponentItem:
+ call RefreshBattleHuds
+ callfar GetOpponentItem
+ ld a, [hl]
+ ld [wNamedObjectIndexBuffer], a
+ call GetItemName
+ callfar ConsumeHeldItem
+ ld hl, RecoveredUsingText
+ jp StdBattleTextbox
+
+ItemRecoveryAnim:
+ push hl
+ push de
+ push bc
+ call EmptyBattleTextbox
+ ld a, RECOVER
+ ld [wFXAnimID], a
+ call SwitchTurnCore
+ xor a
+ ld [wNumHits], a
+ ld [wFXAnimID + 1], a
+ predef PlayBattleAnim
+ call SwitchTurnCore
+ pop bc
+ pop de
+ pop hl
+ ret
+
+UseHeldStatusHealingItem:
+ callfar GetOpponentItem
+ ld hl, HeldStatusHealingEffects
+.loop
+ ld a, [hli]
+ cp $ff
+ ret z
+ inc hl
+ cp b
+ jr nz, .loop
+ dec hl
+ ld b, [hl]
+ ld a, BATTLE_VARS_STATUS_OPP
+ call GetBattleVarAddr
+ and b
+ ret z
+ xor a
+ ld [hl], a
+ push bc
+ call UpdateOpponentInParty
+ pop bc
+ ld a, BATTLE_VARS_SUBSTATUS5_OPP
+ call GetBattleVarAddr
+ and [hl]
+ res SUBSTATUS_TOXIC, [hl]
+ ld a, BATTLE_VARS_SUBSTATUS1_OPP
+ call GetBattleVarAddr
+ and [hl]
+ res SUBSTATUS_NIGHTMARE, [hl]
+ ld a, b
+ cp ALL_STATUS
+ jr nz, .skip_confuse
+ ld a, BATTLE_VARS_SUBSTATUS3_OPP
+ call GetBattleVarAddr
+ res SUBSTATUS_CONFUSED, [hl]
+
+.skip_confuse
+ ld hl, CalcEnemyStats
+ ldh a, [hBattleTurn]
+ and a
+ jr z, .got_pointer
+ ld hl, CalcPlayerStats
+
+.got_pointer
+ call SwitchTurnCore
+ ld a, BANK(CalcPlayerStats) ; aka BANK(CalcEnemyStats)
+ rst FarCall
+ call SwitchTurnCore
+ call ItemRecoveryAnim
+ call UseOpponentItem
+ ld a, $1
+ and a
+ ret
+
+INCLUDE "data/battle/held_heal_status.asm"
+
+UseConfusionHealingItem:
+ ld a, BATTLE_VARS_SUBSTATUS3_OPP
+ call GetBattleVar
+ bit SUBSTATUS_CONFUSED, a
+ ret z
+ callfar GetOpponentItem
+ ld a, b
+ cp HELD_HEAL_CONFUSION
+ jr z, .heal_status
+ cp HELD_HEAL_STATUS
+ ret nz
+
+.heal_status
+ ld a, [hl]
+ ld [wNamedObjectIndexBuffer], a
+ ld a, BATTLE_VARS_SUBSTATUS3_OPP
+ call GetBattleVarAddr
+ res SUBSTATUS_CONFUSED, [hl]
+ call GetItemName
+ call ItemRecoveryAnim
+ ld hl, BattleText_ItemHealedConfusion
+ call StdBattleTextbox
+ ldh a, [hBattleTurn]
+ and a
+ jr nz, .do_partymon
+ call GetOTPartymonItem
+ xor a
+ ld [bc], a
+ ld a, [wBattleMode]
+ dec a
+ ret z
+ ld [hl], $0
+ ret
+
+.do_partymon
+ call GetPartymonItem
+ xor a
+ ld [bc], a
+ ld [hl], a
+ ret
+
+HandleStatBoostingHeldItems:
+; The effects handled here are not used in-game.
+ ldh a, [hSerialConnectionStatus]
+ cp USING_EXTERNAL_CLOCK
+ jr z, .player_1
+ call .DoPlayer
+ jp .DoEnemy
+
+.player_1
+ call .DoEnemy
+ jp .DoPlayer
+
+.DoPlayer:
+ call GetPartymonItem
+ ld a, $0
+ jp .HandleItem
+
+.DoEnemy:
+ call GetOTPartymonItem
+ ld a, $1
+.HandleItem:
+ ldh [hBattleTurn], a
+ ld d, h
+ ld e, l
+ push de
+ push bc
+ ld a, [bc]
+ ld b, a
+ callfar GetItemHeldEffect
+ ld hl, HeldStatUpItems
+.loop
+ ld a, [hli]
+ cp -1
+ jr z, .finish
+ inc hl
+ inc hl
+ cp b
+ jr nz, .loop
+ pop bc
+ ld a, [bc]
+ ld [wNamedObjectIndexBuffer], a
+ push bc
+ dec hl
+ dec hl
+ ld a, [hli]
+ ld h, [hl]
+ ld l, a
+ ld a, BANK(BattleCommand_AttackUp)
+ rst FarCall
+ pop bc
+ pop de
+ ld a, [wFailedMessage]
+ and a
+ ret nz
+ xor a
+ ld [bc], a
+ ld [de], a
+ call GetItemName
+ ld hl, BattleText_UsersStringBuffer1Activated
+ call StdBattleTextbox
+ callfar BattleCommand_StatUpMessage
+ ret
+
+.finish
+ pop bc
+ pop de
+ ret
+
+INCLUDE "data/battle/held_stat_up.asm"
+
+GetPartymonItem:
+ ld hl, wPartyMon1Item
+ ld a, [wCurBattleMon]
+ call GetPartyLocation
+ ld bc, wBattleMonItem
+ ret
+
+GetOTPartymonItem:
+ ld hl, wOTPartyMon1Item
+ ld a, [wCurOTMon]
+ call GetPartyLocation
+ ld bc, wEnemyMonItem
+ ret
+
+UpdateBattleHUDs:
+ push hl
+ push de
+ push bc
+ call DrawPlayerHUD
+ ld hl, wPlayerHPPal
+ call SetHPPal
+ call CheckDanger
+ call DrawEnemyHUD
+ ld hl, wEnemyHPPal
+ call SetHPPal
+ pop bc
+ pop de
+ pop hl
+ ret
+
+UpdatePlayerHUD::
+ push hl
+ push de
+ push bc
+ call DrawPlayerHUD
+ call UpdatePlayerHPPal
+ call CheckDanger
+ pop bc
+ pop de
+ pop hl
+ ret
+
+DrawPlayerHUD:
+ xor a
+ ldh [hBGMapMode], a
+
+ ; Clear the area
+ hlcoord 9, 7
+ lb bc, 5, 11
+ call ClearBox
+
+ farcall DrawPlayerHUDBorder
+
+ hlcoord 18, 9
+ ld [hl], $73 ; vertical bar
+ call PrintPlayerHUD
+
+ ; HP bar
+ hlcoord 10, 9
+ ld b, 1
+ xor a ; PARTYMON
+ ld [wMonType], a
+ predef DrawPlayerHP
+
+ ; Exp bar
+ push de
+ ld a, [wCurBattleMon]
+ ld hl, wPartyMon1Exp + 2
+ call GetPartyLocation
+ ld d, h
+ ld e, l
+
+ hlcoord 10, 11
+ ld a, [wTempMonLevel]
+ ld b, a
+ call FillInExpBar
+ pop de
+ ret
+
+UpdatePlayerHPPal:
+ ld hl, wPlayerHPPal
+ jp UpdateHPPal
+
+CheckDanger:
+ ld hl, wBattleMonHP
+ ld a, [hli]
+ or [hl]
+ jr z, .no_danger
+ ld a, [wBattleLowHealthAlarm]
+ and a
+ jr nz, .done
+ ld a, [wPlayerHPPal]
+ cp HP_RED
+ jr z, .danger
+
+.no_danger
+ ld hl, wLowHealthAlarm
+ res DANGER_ON_F, [hl]
+ jr .done
+
+.danger
+ ld hl, wLowHealthAlarm
+ set DANGER_ON_F, [hl]
+
+.done
+ ret
+
+PrintPlayerHUD:
+ ld de, wBattleMonNick
+ hlcoord 10, 7
+ call ret_3df99
+ call PlaceString
+
+ push bc
+
+ ld a, [wCurBattleMon]
+ ld hl, wPartyMon1DVs
+ call GetPartyLocation
+ ld de, wTempMonDVs
+ ld a, [hli]
+ ld [de], a
+ inc de
+ ld a, [hl]
+ ld [de], a
+ ld hl, wBattleMonLevel
+ ld de, wTempMonLevel
+ ld bc, $11
+ call CopyBytes
+ ld a, [wCurBattleMon]
+ ld hl, wPartyMon1Species
+ call GetPartyLocation
+ ld a, [hl]
+ ld [wCurPartySpecies], a
+ ld [wCurSpecies], a
+ call GetBaseData
+
+ pop hl
+ dec hl
+
+ ld a, TEMPMON
+ ld [wMonType], a
+ callfar GetGender
+ ld a, " "
+ jr c, .got_gender_char
+ ld a, "♂"
+ jr nz, .got_gender_char
+ ld a, "♀"
+
+.got_gender_char
+ hlcoord 17, 8
+ ld [hl], a
+ hlcoord 14, 8
+ push af ; back up gender
+ push hl
+ ld de, wBattleMonStatus
+ predef PlaceNonFaintStatus
+ pop hl
+ pop bc
+ ret nz
+ ld a, b
+ cp " "
+ jr nz, .copy_level ; male or female
+ dec hl ; genderless
+
+.copy_level
+ ld a, [wBattleMonLevel]
+ ld [wTempMonLevel], a
+ jp PrintLevel
+
+UpdateEnemyHUD::
+ push hl
+ push de
+ push bc
+ call DrawEnemyHUD
+ call UpdateEnemyHPPal
+ pop bc
+ pop de
+ pop hl
+ ret
+
+DrawEnemyHUD:
+ xor a
+ ldh [hBGMapMode], a
+
+ hlcoord 1, 0
+ lb bc, 4, 11
+ call ClearBox
+
+ farcall DrawEnemyHUDBorder
+
+ ld a, [wTempEnemyMonSpecies]
+ ld [wCurSpecies], a
+ ld [wCurPartySpecies], a
+ call GetBaseData
+ ld de, wEnemyMonNick
+ hlcoord 1, 0
+ call ret_3df99
+ call PlaceString
+ ld h, b
+ ld l, c
+ dec hl
+
+ ld hl, wEnemyMonDVs
+ ld de, wTempMonDVs
+ ld a, [wEnemySubStatus5]
+ bit SUBSTATUS_TRANSFORMED, a
+ jr z, .ok
+ ld hl, wEnemyBackupDVs
+.ok
+ ld a, [hli]
+ ld [de], a
+ inc de
+ ld a, [hl]
+ ld [de], a
+
+ ld a, TEMPMON
+ ld [wMonType], a
+ callfar GetGender
+ ld a, " "
+ jr c, .got_gender
+ ld a, "♂"
+ jr nz, .got_gender
+ ld a, "♀"
+
+.got_gender
+ hlcoord 9, 1
+ ld [hl], a
+
+ hlcoord 6, 1
+ push af
+ push hl
+ ld de, wEnemyMonStatus
+ predef PlaceNonFaintStatus
+ pop hl
+ pop bc
+ jr nz, .skip_level
+ ld a, b
+ cp " "
+ jr nz, .print_level
+ dec hl
+.print_level
+ ld a, [wEnemyMonLevel]
+ ld [wTempMonLevel], a
+ call PrintLevel
+.skip_level
+
+ ld hl, wEnemyMonHP
+ ld a, [hli]
+ ldh [hMultiplicand + 1], a
+ ld a, [hld]
+ ldh [hMultiplicand + 2], a
+ or [hl]
+ jr nz, .not_fainted
+
+ ld c, a
+ ld e, a
+ ld d, HP_BAR_LENGTH
+ jp .draw_bar
+
+.not_fainted
+ xor a
+ ldh [hMultiplicand + 0], a
+ ld a, HP_BAR_LENGTH_PX
+ ldh [hMultiplier], a
+ call Multiply
+ ld hl, wEnemyMonMaxHP
+ ld a, [hli]
+ ld b, a
+ ld a, [hl]
+ ldh [hMultiplier], a
+ ld a, b
+ and a
+ jr z, .less_than_256_max
+ ldh a, [hMultiplier]
+ srl b
+ rr a
+ srl b
+ rr a
+ ldh [hDivisor], a
+ ldh a, [hProduct + 2]
+ ld b, a
+ srl b
+ ldh a, [hProduct + 3]
+ rr a
+ srl b
+ rr a
+ ldh [hProduct + 3], a
+ ld a, b
+ ldh [hProduct + 2], a
+
+.less_than_256_max
+ ldh a, [hProduct + 2]
+ ldh [hDividend + 0], a
+ ldh a, [hProduct + 3]
+ ldh [hDividend + 1], a
+ ld a, 2
+ ld b, a
+ call Divide
+ ldh a, [hQuotient + 3]
+ ld e, a
+ ld a, HP_BAR_LENGTH
+ ld d, a
+ ld c, a
+
+.draw_bar
+ xor a
+ ld [wWhichHPBar], a
+ hlcoord 2, 2
+ ld b, 0
+ call DrawBattleHPBar
+ ret
+
+UpdateEnemyHPPal:
+ ld hl, wEnemyHPPal
+ call UpdateHPPal
+ ret
+
+UpdateHPPal:
+ ld b, [hl]
+ call SetHPPal
+ ld a, [hl]
+ cp b
+ ret z
+ jp FinishBattleAnim
+
+ret_3df99:
+ ret
diff --git a/engine/gfx/cgb_layouts.asm b/engine/gfx/cgb_layouts.asm
index cbc8d203..4392fed1 100755
--- a/engine/gfx/cgb_layouts.asm
+++ b/engine/gfx/cgb_layouts.asm
@@ -84,7 +84,7 @@ Function9399: ; 9399 (2:5399)
call Function9bba
push hl
call Function9adb
- ld a, [wcc9a]
+ ld a, [wEnemyHPPal]
ld l, a
ld h, $0
add hl, hl
diff --git a/engine/gfx/color.asm b/engine/gfx/color.asm
index 10507851..a807ff09 100755
--- a/engine/gfx/color.asm
+++ b/engine/gfx/color.asm
@@ -586,17 +586,17 @@ Function9b9c: ; 9b9c (2:5b9c)
Function9ba9: ; 9ba9 (2:5ba9)
push de
- farcall Function3d8f5
+ farcall GetPartyMonDVs
ld c, l
ld b, h
- ld a, [wd0ee]
+ ld a, [wTempBattleMonSpecies]
call Function9bcb
pop de
ret
Function9bba: ; 9bba (2:5bba)
push de
- farcall Function3d907
+ farcall GetEnemyMonDVs
ld c, l
ld b, h
ld a, [wTempEnemyMonSpecies]
diff --git a/engine/gfx/sgb_layouts.asm b/engine/gfx/sgb_layouts.asm
index e94ad9fc..623bbbca 100755
--- a/engine/gfx/sgb_layouts.asm
+++ b/engine/gfx/sgb_layouts.asm
@@ -81,7 +81,7 @@ Function8c97: ; 8c97 (2:4c97)
ld [wccae], a
ld a, [hl]
ld [wccaf], a
- ld a, [wcc9a]
+ ld a, [wEnemyHPPal]
ld l, a
ld h, $0
add hl, hl
diff --git a/engine/items/item_effects.asm b/engine/items/item_effects.asm
index bf35d84e..6735ec16 100755
--- a/engine/items/item_effects.asm
+++ b/engine/items/item_effects.asm
@@ -226,7 +226,7 @@ UltraBall: ; e926
res NO_TEXT_SCROLL, [hl]
ld hl, Text_UsedItem ; $7884
call PrintText
- ld a, [wd114]
+ ld a, [wEnemyMonCatchRate]
ld b, a
ld a, [wBattleType]
cp BATTLETYPE_TUTORIAL
@@ -835,11 +835,11 @@ LoveBallMultiplier:
; Reality: multiply catch rate by 8 if mons are of same species, same sex
ld a, [wTempEnemyMonSpecies]
ld c, a
- ld a, [wd0ee]
+ ld a, [wTempBattleMonSpecies]
cp c
ret nz
push bc
- ld a, [wd0ee]
+ ld a, [wTempBattleMonSpecies]
ld [wCurPartySpecies], a
xor a
ld [wMonType], a
@@ -1409,7 +1409,7 @@ Functionf12c: ; f12c (3:712c)
ld a, [wCurPartyMon]
ld c, a
ld d, $0
- ld hl, wcbda
+ ld hl, wBattleParticipantsIncludingFainted
ld b, CHECK_FLAG
predef SmallFarFlagAction
ld a, c
@@ -1417,7 +1417,7 @@ Functionf12c: ; f12c (3:712c)
jr z, .asm_f15a
ld a, [wCurPartyMon]
ld c, a
- ld hl, wcb42
+ ld hl, wBattleParticipantsNotFainted
ld b, SET_FLAG
predef SmallFarFlagAction
.asm_f15a
@@ -2183,7 +2183,7 @@ PPUp: ; f606 (3:7606)
xor a
ld [wCurMoveNum], a
ld a, $2
- ld [wd11f], a
+ ld [wMoveSelectionMenuType], a
ld a, $f
ld hl, $62f3
rst FarCall
diff --git a/engine/pokemon/bills_pc_top.asm b/engine/pokemon/bills_pc_top.asm
index 38cfc479..25166209 100644
--- a/engine/pokemon/bills_pc_top.asm
+++ b/engine/pokemon/bills_pc_top.asm
@@ -337,7 +337,7 @@ Function65b4:
swap a
or b
ld b, a
- ld a, [wd12d]
+ ld a, [wBaseGender]
cp b
ld a, $1
jr c, .asm_e63d
diff --git a/engine/pokemon/move_mon.asm b/engine/pokemon/move_mon.asm
index 26b0f0b9..39e6ea47 100755
--- a/engine/pokemon/move_mon.asm
+++ b/engine/pokemon/move_mon.asm
@@ -69,7 +69,7 @@ GeneratePartyMonStats:
ld a, [wCurPartySpecies]
ld [wCurSpecies], a
call GetBaseData
- ld a, [wd120]
+ ld a, [wBaseDexNo]
ld [de], a
inc de
ld a, [wBattleMode]
@@ -1288,7 +1288,7 @@ CalcMonStatC: ; e181
ld a, b
ld d, a
push hl
- ld hl, wd121
+ ld hl, wBaseStats
dec hl ; has to be decreased, because 'c' begins with 1
ld b, $0
add hl, bc
diff --git a/home/map.asm b/home/map.asm
index a5d84a5c..c210f03d 100644
--- a/home/map.asm
+++ b/home/map.asm
@@ -1029,8 +1029,8 @@ GetMapScreenCoords::
ret
LoadBlockData::
- ld hl, wOverworldMap
- ld bc, wOverworldMapEnd - wOverworldMap
+ ld hl, wOverworldMapBlocks
+ ld bc, wOverworldMapBlocksEnd - wOverworldMapBlocks
ld a, $0
call ByteFill
call ChangeMap
diff --git a/main.asm b/main.asm
index 6a3f7ef5..40eda172 100644
--- a/main.asm
+++ b/main.asm
@@ -182,7 +182,9 @@ ToggleDecorationsVisibility:
dr $27216, $27271
INCLUDE "engine/battle/read_trainer_dvs.asm"
ReturnToBattle_UseBall_:
- dr $27307, $2739f
+ dr $27307, $2733d
+ConsumeHeldItem:
+ dr $2733d, $2739f
INCLUDE "data/moves/effects.asm"
SECTION "banka", ROMX
@@ -257,7 +259,13 @@ JohtoGrassWildMons:
dr $2ab35, $2bee3
SECTION "bankb", ROMX
- dr $2c000, $2c225
+ dr $2c000, $2c045
+EnemySwitch_TrainerHud:
+ dr $2c045, $2c0c8
+DrawPlayerHUDBorder:
+ dr $2c0c8, $2c0f8
+DrawEnemyHUDBorder:
+ dr $2c0f8, $2c225
INCLUDE "engine/battle/ai/redundant.asm"
MoveDeletion:
dr $2c352, $2c57a
@@ -290,75 +298,34 @@ INCLUDE "engine/battle/read_trainer_party.asm"
SECTION "Battle Core", ROMX
- dr $3c000, $3c551
-FleeMons::
- dr $3c551, $3c5a4
-GetMoveEffect:
- dr $3c5a4, $3cbe7
-SubtractHPFromUser:
- dr $3cbe7, $3cc2b
-GetEighthMaxHP:
- dr $3cc2b, $3cc36
-GetQuarterMaxHP:
- dr $3cc36, $3cc47
-GetHalfMaxHP:
- dr $3cc47, $3cc54
-GetMaxHP:
- dr $3cc54, $3cc86
-CheckUserHasEnoughHP:
- dr $3cc86, $3cc97
-RestoreHP:
- dr $3cc97, $3d224
-
-SetUpBattlePartyMenu_NoLoop:
- dr $3d224, $3d28f
-ForcePickSwitchMonInBattle:
- dr $3d28f, $3d381
-ForceEnemySwitch:
- dr $3d381, $3d39f
-EnemySwitch:
- dr $3d39f, $3d3d5
-EnemySwitch_SetMode:
- dr $3d3d5, $3d438
-ResetBattleParticipants:
- dr $3d438, $3d6cb
-NewEnemyMonStatus:
- dr $3d6cb, $3d6fe
-ResetEnemyStatLevels:
- dr $3d6fe, $3d70a
-CheckPlayerPartyForFitMon::
- dr $3d70a, $3d8f5
-Function3d8f5:
- dr $3d8f5, $3d907
-Function3d907:
- dr $3d907, $3d9a2
-SwitchPlayerMon:
- dr $3d9a2, $3da84
-SpikesDamage:
- dr $3da84, $3dabc
-PursuitSwitch:
- dr $3dabc, $3dc4a
-UseHeldStatusHealingItem:
- dr $3dc4a, $3dcb2
-UseConfusionHealingItem:
- dr $3dcb2, $3dda9
-UpdatePlayerHUD::
- dr $3dda9, $3ddb9
-DrawPlayerHUD:
- dr $3ddb9, $3de97
-UpdateEnemyHUD::
- dr $3de97, $3dea4
-DrawEnemyHUD:
- dr $3dea4, $3e290
+INCLUDE "engine/battle/core.asm"
+
+BattleMenu:
+ dr $3df9a, $3e1e4
+
+PlayerSwitch:
+ dr $3e1e4, $3e290
PassedBattleMonEntrance:
- dr $3e290, $3e6e8
+ dr $3e290, $3e2df
+CheckAmuletCoin:
+ dr $3e2df, $3e2f3
+MoveSelectionScreen:
+ dr $3e2f3, $3e5d8
+ParseEnemyAction:
+ dr $3e5d8, $3e6e8
CheckEnemyLockedIn::
dr $3e6e8, $3e6fb
LinkBattleSendReceiveAction:
dr $3e6fb, $3e74b
LoadEnemyMon:
- dr $3e74b, $3ea77
+ dr $3e74b, $3ea16
+BattleWinSlideInEnemyTrainerFrontpic:
+ dr $3ea16, $3ea6a
+ApplyStatusEffectOnPlayerStats:
+ dr $3ea6a, $3ea6e
+ApplyStatusEffectOnEnemyStats:
+ dr $3ea6e, $3ea77
ApplyPrzEffectOnSpeed:
dr $3ea77, $3eab4
ApplyBrnEffectOnAttack:
@@ -368,10 +335,24 @@ ApplyStatLevelMultiplierOnAllStats:
BadgeStatBoosts:
dr $3eb83, $3ebd8
_LoadBattleFontsHPBar:
- dr $3ebd8, $3ec11
+ dr $3ebd8, $3ebdf
+_LoadHPBar:
+ dr $3ebdf, $3ec0a
+EmptyBattleTextbox:
+ dr $3ec0a, $3ec11
_BattleRandom::
- dr $3ec11, $3f196
-
+ dr $3ec11, $3ec48
+Call_PlayBattleAnim_OnlyIfVisible:
+ dr $3ec48, $3ec50
+Call_PlayBattleAnim:
+ dr $3ec50, $3ec60
+FinishBattleAnim:
+ dr $3ec60, $3ec74
+GiveExperiencePoints:
+ dr $3ec74, $3f086
+
+SendOutMonText:
+ dr $3f086, $3f196
FillInExpBar::
dr $3f196, $3f243
GetBattleMonBackpic::
diff --git a/wram.asm b/wram.asm
index 27306268..fbd35b8a 100644
--- a/wram.asm
+++ b/wram.asm
@@ -635,7 +635,6 @@ wc6fd:: ds 1 ; c6fd
wc6fe:: ds 1 ; c6fe
wc6ff:: ds 1 ; c6ff
-wOverworldMap::
wOverworldMapBlocks::
wLYOverrides::
wHallOfFamePokemonList::
@@ -1676,7 +1675,7 @@ wOTClassName:: ds NAME_LENGTH ; cb34
wcb3f:: ds 1 ; cb3f
wcb40:: ds 1 ; cb40
wCurOTMon:: ds 1 ; cb41
-wcb42:: ds 1 ; cb42
+wBattleParticipantsNotFainted:: db ; cb42
wTypeModifier:: db ; cb43
wCriticalHit:: db ; cb44
wAttackMissed:: db ; cb45
@@ -1819,8 +1818,7 @@ wEnemyItemState:: db ; cbc4
wcbc5:: ds 1 ; cbc5
wcbc6:: ds 1 ; cbc6
wCurEnemyMoveNum:: db ; cbc7
-wcbc8:: ds 1 ; cbc8
-wcbc9:: ds 1 ; cbc9
+wEnemyHPAtTimeOfPlayerSwitch:: dw ; cbc8
wPayDayMoney:: ds 3 ; cbca
wcbcd:: ds 1 ; cbcd
@@ -1830,7 +1828,7 @@ wEnemyBackupDVs:: dw
wAlreadyDisobeyed:: db ; cbd2
wDisabledMove:: db ; cbd3
wEnemyDisabledMove:: db ; cbd4
-wcbd5:: ds 1 ; cbd5
+wWhichMonFaintedFirst:: db ; cbd5
; exists so you can't counter on switch
wLastPlayerCounterMove:: db ; cbd6
@@ -1838,8 +1836,8 @@ wLastEnemyCounterMove:: db ; cbd7
wEnemyMinimized:: db ; cbd8
wAlreadyFailed:: db ; cbd9
-wcbda:: ds 1 ; cbda
-wcbdb:: ds 1 ; cbdb
+wBattleParticipantsIncludingFainted:: db ; cbda
+wBattleLowHealthAlarm:: db ; cbdb
wPlayerMinimized:: db ; cbdc
wPlayerScreens:: db ; cbdd
wEnemyScreens:: db ; cbde
@@ -1869,17 +1867,13 @@ wEnemyAISwitchScore:: db ; cbf4
wEnemySwitchMonParam:: db ; cbf5
wEnemySwitchMonIndex:: db ; cbf6
wcbf7:: ds 1 ; cbf7
-wcbf8:: ds 1 ; cbf8
-wLastPlayerMove:: ds 1 ; cbf9
-wLastEnemyMove:: ds 1 ; cbfa
+wLastPlayerMon:: db ; cbf8
+wLastPlayerMove:: db ; cbf9
+wLastEnemyMove:: db ; cbfa
wPlayerFutureSightCount:: db ; cbfb
wEnemyFutureSightCount:: db ; cbfc
-wcbfd:: ds 1 ; cbfd
-wcbfe:: ds 1 ; cbfe
-wcbff:: ds 1 ; cbff
-wcc00:: ds 1 ; cc00
-wcc01:: ds 1 ; cc01
-wcc02:: ds 1 ; cc02
+wGivingExperienceToExpShareHolders:: db ; cbfd
+wBackupEnemyMonBaseStats:: ds 5 ; cbfe
wcc03:: ds 1 ; cc03
wcc04:: ds 1 ; cc04
wPlayerFutureSightDamage:: dw ; cc05
@@ -1893,17 +1887,25 @@ wPlayerWrapCount:: db ; cc0e
wEnemyWrapCount:: db ; cc0f
wPlayerCharging:: db ; cc10
wEnemyCharging:: db ; cc11
-wcc12:: ds 1 ; cc12
-wWildMonMoves:: ds 1 ; cc13
-wOverworldMapEnd::
- ds NUM_MOVES +- 1
+wBattleEnded:: db ; cc12
+
+UNION
+wWildMonMoves:: ; cc13
+ ds NUM_MOVES
+NEXTU
+ ds 1
+wOverworldMapBlocksEnd::
+ ds NUM_MOVES - 1
+ENDU
+
wWildMonPP:: ds NUM_MOVES ; cc17
-wcc1b:: ds 1 ; cc1b
+wAmuletCoin:: db ; cc1b
wSomeoneIsRampaging:: db ; cc1c
wPlayerJustGotFrozen:: db ; cc1d
wEnemyJustGotFrozen:: db ; cc1e
-wcc1f:: ds 1 ; cc1f
+ ds 1
+
ENDU ; cc20
SECTION "Video", WRAM0
@@ -2029,7 +2031,7 @@ wcc96:: ds 1 ; cc96
wcc97:: ds 1 ; cc97
wColorLayoutPredefID:: ds 1 ; cc98
wPlayerHPPal:: db ; cc99
-wcc9a:: ds 1 ; cc9a
+wEnemyHPPal:: db ; cc9a
wcc9b:: ds 1 ; cc9b
wcc9c:: ds 1 ; cc9c
wcc9d:: ds 1 ; cc9d
@@ -2833,18 +2835,14 @@ wd0e9:: ds 1 ; d0e9
wd0ea:: ds 1 ; d0ea
wd0eb:: ds 1 ; d0eb
wd0ec:: ds 1 ; d0ec
-wTempEnemyMonSpecies:: ds 1 ; d0ed
-wd0ee:: ds 1 ; d0ee
+wTempEnemyMonSpecies:: db ; d0ed
+wTempBattleMonSpecies:: db ; d0ee
wEnemyMon:: battle_struct wEnemyMon ; d0ef
-
-wd10f:: ds 1 ; d10f
-wd110:: ds 1 ; d110
-wd111:: ds 1 ; d111
-wd112:: ds 1 ; d112
-wd113:: ds 1 ; d113
-wd114:: ds 1 ; d114
-wd115:: ds 1 ; d115
+wEnemyMonBaseStats:: ds 5 ; d10f
+wEnemyMonCatchRate:: db ; d114
+wEnemyMonBaseExp:: db ; d115
+wEnemyMonEnd::
wBattleMode:: ds 1 ; d116
wTempWildMonSpecies:: db ; d117
@@ -2859,34 +2857,34 @@ wOtherTrainerID:: db ; d11b
wForcedSwitch:: db ; d11c
wTrainerClass:: db ; d11d
wUnownLetter:: db ; d11e
-wd11f:: ds 1 ; d11f
+wMoveSelectionMenuType:: db ; d11f
-wBaseDexNo:: ; d120
wCurBaseData:: ; d120
-wd120:: ds 1 ; d120
-wd121:: ds 1 ; d121
+wBaseDexNo:: db ; d120
+wBaseStats:: ; d121
+wBaseHP:: db ; d121
wBaseAttack:: db ; d122
wBaseDefense:: db ; d123
-wd124:: ds 1 ; d124
-wd125:: ds 1 ; d125
-wd126:: ds 1 ; d126
-wBaseType:: db ; d127
-wd128:: ds 1 ; d128
-wd129:: ds 1 ; d129
-wd12a:: ds 1 ; d12a
-wd12b:: ds 1 ; d12b
-wd12c:: ds 1 ; d12c
-wd12d:: ds 1 ; d12d
-wd12e:: ds 1 ; d12e
+wBaseSpeed:: db ; d124
+wBaseSpecialAttack:: db ; d125
+wBaseSpecialDefense:: db ; d126
+wBaseType:: ; d127
+wBaseType1:: db ; d127
+wBaseType2:: db ; d128
+wBaseCatchRate:: db ; d129
+wBaseExp:: db ; d12a
+wBaseItems:: ; d12b
+wBaseItem1:: db ; d12b
+wBaseItem2:: db ; d12c
+wBaseGender:: db ; d12d
+wBaseUnknown1:: db ; d12e
wBaseEggSteps:: db ; d12f
-wd130:: ds 1 ; d130
+wBaseUnknown2:: db ; d130
wBasePicSize:: db ; d131
-wBaseUnusedFrontpic:: db ; d132
-wd133:: ds 1 ; d133
-wd134:: ds 1 ; d134
-wd135:: ds 1 ; d135
-wd136:: ds 1 ; d136
-wBaseEggGroups:: db
+wBaseUnusedFrontpic:: dw ; d132
+wBaseUnusedBackpic:: dw ; d134
+wBaseGrowthRate:: db ; d136
+wBaseEggGroups:: db ; d137
wd138:: ds 1 ; d138
wd139:: ds 1 ; d139
wd13a:: ds 1 ; d13a
@@ -2931,8 +2929,8 @@ wUsePPUp::
wd151::
db ; d151
-wd152:: ds 1 ; d152
-wd153:: ds 1 ; d153
+wFailedToFlee:: db ; d152
+wNumFleeAttempts:: db ; d153
wd154:: ds 1 ; d154
wROMBankBackup:: ds 1 ; d155
wBuffer:: ds 1 ; d156
@@ -3534,7 +3532,12 @@ wd8b6:: ds 1 ; d8b6
wd8b7:: ds 1 ; d8b7
wGameTimerPause:: ds 1 ; d8b8
wd8b9:: ds 1 ; d8b9
-wd8ba:: ds 1 ; d8ba
+wd8ba:: ; d8ba
+; bits 4, 6, or 7 can be used to disable joypad input
+; bit 4
+; bit 6: mon fainted?
+; bit 7: SGB flag?
+ db
wd8bb:: ds 1 ; d8bb
wCurBox:: ds 1 ; d8bc