summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--charmap.asm11
-rw-r--r--constants/battle_constants.asm1
-rw-r--r--data/battle/effect_command_pointers.asm181
-rw-r--r--data/battle/stat_multipliers_2.asm20
-rwxr-xr-xdata/text/common_1.asm16
-rw-r--r--data/wild/unlocked_unowns.asm24
-rw-r--r--engine/battle/core.asm4106
-rw-r--r--engine/battle/sliding_intro.asm57
-rwxr-xr-xengine/events/specials.asm2
-rwxr-xr-xengine/items/item_effects.asm8
-rwxr-xr-xengine/items/pack.asm92
-rw-r--r--engine/pokemon/correct_nick_errors.asm2
-rw-r--r--engine/pokemon/learn.asm2
-rw-r--r--gfx/battle/dude.2bpp.lzbin0 -> 320 bytes
-rw-r--r--gfx/player/chris_back.2bpp.lzbin0 -> 400 bytes
-rw-r--r--home/text.asm2
-rw-r--r--main.asm153
-rw-r--r--pokegold.link4
-rw-r--r--pokesilver.link4
-rwxr-xr-xsram.asm35
-rw-r--r--wram.asm58
21 files changed, 4572 insertions, 206 deletions
diff --git a/charmap.asm b/charmap.asm
index 595c7cf3..31283ae3 100644
--- a/charmap.asm
+++ b/charmap.asm
@@ -1,9 +1,12 @@
-; Control characters
- charmap "<START>", $00
+; $00-$16 are TX_* constants (see macros/scripts/text.asm)
+
+; Control characters (see home/text.asm)
+ charmap "<NULL>", $00
charmap "<PLAY_G>", $14 ; <PLAYER> + gender
- charmap "<DAY>", $15
+ charmap "<MOBILE>", $15
+ charmap "<CR>", $16
charmap "¯", $1f
- charmap "<LNBRK>", $22
+ charmap "<LF>", $22
charmap "<POKE>", $24
charmap "%", $25
charmap "<RED>", $38
diff --git a/constants/battle_constants.asm b/constants/battle_constants.asm
index 5442e2c3..ba373a0a 100644
--- a/constants/battle_constants.asm
+++ b/constants/battle_constants.asm
@@ -15,6 +15,7 @@ MIN_NEUTRAL_DAMAGE EQU 2
; turns that sleep lasts
REST_SLEEP_TURNS EQU 2
+TREEMON_SLEEP_TURNS EQU 7
; default move priority
BASE_PRIORITY EQU 1
diff --git a/data/battle/effect_command_pointers.asm b/data/battle/effect_command_pointers.asm
new file mode 100644
index 00000000..d5c044d7
--- /dev/null
+++ b/data/battle/effect_command_pointers.asm
@@ -0,0 +1,181 @@
+; battle commands are defined in engine/battle/effect_commands.asm
+
+ dw 0 ; padding
+
+BattleCommandPointers:
+; entries correspond to macros/scripts/battle_commands.asm
+ dw BattleCommand_CheckTurn
+ dw BattleCommand_CheckObedience
+ dw BattleCommand_UsedMoveText
+ dw BattleCommand_DoTurn
+ dw BattleCommand_Critical
+ dw BattleCommand_DamageStats
+ dw BattleCommand_Stab
+ dw BattleCommand_DamageVariation
+ dw BattleCommand_CheckHit
+ dw BattleCommand_LowerSub
+ dw BattleCommand_MoveAnimNoSub
+ dw BattleCommand_RaiseSub
+ dw BattleCommand_FailureText
+ dw BattleCommand_ApplyDamage
+ dw BattleCommand_CriticalText
+ dw BattleCommand_SuperEffectiveText
+ dw BattleCommand_CheckFaint
+ dw BattleCommand_BuildOpponentRage
+ dw BattleCommand_PoisonTarget
+ dw BattleCommand_SleepTarget
+ dw BattleCommand_DrainTarget
+ dw BattleCommand_EatDream
+ dw BattleCommand_BurnTarget
+ dw BattleCommand_FreezeTarget
+ dw BattleCommand_ParalyzeTarget
+ dw BattleCommand_Selfdestruct
+ dw BattleCommand_MirrorMove
+ dw BattleCommand_StatUp
+ dw BattleCommand_StatDown
+ dw BattleCommand_PayDay
+ dw BattleCommand_Conversion
+ dw BattleCommand_ResetStats
+ dw BattleCommand_StoreEnergy
+ dw BattleCommand_UnleashEnergy
+ dw BattleCommand_ForceSwitch
+ dw BattleCommand_EndLoop
+ dw BattleCommand_FlinchTarget
+ dw BattleCommand_OHKO
+ dw BattleCommand_Recoil
+ dw BattleCommand_Mist
+ dw BattleCommand_FocusEnergy
+ dw BattleCommand_Confuse
+ dw BattleCommand_ConfuseTarget
+ dw BattleCommand_Heal
+ dw BattleCommand_Transform
+ dw BattleCommand_Screen
+ dw BattleCommand_Poison
+ dw BattleCommand_Paralyze
+ dw BattleCommand_Substitute
+ dw BattleCommand_RechargeNextTurn
+ dw BattleCommand_Mimic
+ dw BattleCommand_Metronome
+ dw BattleCommand_LeechSeed
+ dw BattleCommand_Splash
+ dw BattleCommand_Disable
+ dw BattleCommand_ClearText
+ dw BattleCommand_Charge
+ dw BattleCommand_CheckCharge
+ dw BattleCommand_TrapTarget
+ dw BattleCommand3c
+ dw BattleCommand_Rampage
+ dw BattleCommand_CheckRampage
+ dw BattleCommand_ConstantDamage
+ dw BattleCommand_Counter
+ dw BattleCommand_Encore
+ dw BattleCommand_PainSplit
+ dw BattleCommand_Snore
+ dw BattleCommand_Conversion2
+ dw BattleCommand_LockOn
+ dw BattleCommand_Sketch
+ dw BattleCommand_DefrostOpponent
+ dw BattleCommand_SleepTalk
+ dw BattleCommand_DestinyBond
+ dw BattleCommand_Spite
+ dw BattleCommand_FalseSwipe
+ dw BattleCommand_HealBell
+ dw BattleCommand_HeldFlinch
+ dw BattleCommand_TripleKick
+ dw BattleCommand_KickCounter
+ dw BattleCommand_Thief
+ dw BattleCommand_ArenaTrap
+ dw BattleCommand_Nightmare
+ dw BattleCommand_Defrost
+ dw BattleCommand_Curse
+ dw BattleCommand_Protect
+ dw BattleCommand_Spikes
+ dw BattleCommand_Foresight
+ dw BattleCommand_PerishSong
+ dw BattleCommand_StartSandstorm
+ dw BattleCommand_Endure
+ dw BattleCommand_CheckCurl
+ dw BattleCommand_RolloutPower
+ dw BattleCommand5d
+ dw BattleCommand_FuryCutter
+ dw BattleCommand_Attract
+ dw BattleCommand_HappinessPower
+ dw BattleCommand_Present
+ dw BattleCommand_DamageCalc
+ dw BattleCommand_FrustrationPower
+ dw BattleCommand_Safeguard
+ dw BattleCommand_CheckSafeguard
+ dw BattleCommand_GetMagnitude
+ dw BattleCommand_BatonPass
+ dw BattleCommand_Pursuit
+ dw BattleCommand_ClearHazards
+ dw BattleCommand_HealMorn
+ dw BattleCommand_HealDay
+ dw BattleCommand_HealNite
+ dw BattleCommand_HiddenPower
+ dw BattleCommand_StartRain
+ dw BattleCommand_StartSun
+ dw BattleCommand_AttackUp
+ dw BattleCommand_DefenseUp
+ dw BattleCommand_SpeedUp
+ dw BattleCommand_SpecialAttackUp
+ dw BattleCommand_SpecialDefenseUp
+ dw BattleCommand_AccuracyUp
+ dw BattleCommand_EvasionUp
+ dw BattleCommand_AttackUp2
+ dw BattleCommand_DefenseUp2
+ dw BattleCommand_SpeedUp2
+ dw BattleCommand_SpecialAttackUp2
+ dw BattleCommand_SpecialDefenseUp2
+ dw BattleCommand_AccuracyUp2
+ dw BattleCommand_EvasionUp2
+ dw BattleCommand_AttackDown
+ dw BattleCommand_DefenseDown
+ dw BattleCommand_SpeedDown
+ dw BattleCommand_SpecialAttackDown
+ dw BattleCommand_SpecialDefenseDown
+ dw BattleCommand_AccuracyDown
+ dw BattleCommand_EvasionDown
+ dw BattleCommand_AttackDown2
+ dw BattleCommand_DefenseDown2
+ dw BattleCommand_SpeedDown2
+ dw BattleCommand_SpecialAttackDown2
+ dw BattleCommand_SpecialDefenseDown2
+ dw BattleCommand_AccuracyDown2
+ dw BattleCommand_EvasionDown2
+ dw BattleCommand_StatUpMessage
+ dw BattleCommand_StatDownMessage
+ dw BattleCommand_StatUpFailText
+ dw BattleCommand_StatDownFailText
+ dw BattleCommand_EffectChance
+ dw BattleCommand_StatDownAnim
+ dw BattleCommand_StatUpAnim
+ dw BattleCommand_SwitchTurn
+ dw BattleCommand_FakeOut
+ dw BattleCommand_BellyDrum
+ dw BattleCommand_PsychUp
+ dw BattleCommand_Rage
+ dw BattleCommand_DoubleFlyingDamage
+ dw BattleCommand_DoubleUndergroundDamage
+ dw BattleCommand_MirrorCoat
+ dw BattleCommand_CheckFutureSight
+ dw BattleCommand_FutureSight
+ dw BattleCommand_DoubleMinimizeDamage
+ dw BattleCommand_SkipSunCharge
+ dw BattleCommand_ThunderAccuracy
+ dw BattleCommand_Teleport
+ dw BattleCommand_BeatUp
+ dw BattleCommand_RageDamage
+ dw BattleCommand_ResetTypeMatchup
+ dw BattleCommand_AllStatsUp
+ dw BattleCommand_BideFailText
+ dw BattleCommand_RaiseSubNoAnim
+ dw BattleCommand_LowerSubNoAnim
+ dw BattleCommand_BeatUpFailText
+ dw BattleCommand_ClearMissDamage
+ dw BattleCommand_MoveDelay
+ dw BattleCommand_MoveAnim
+ dw BattleCommand_TriStatusChance
+ dw BattleCommand_SuperEffectiveLoopText
+ dw BattleCommand_StartLoop
+ dw BattleCommand_Curl
diff --git a/data/battle/stat_multipliers_2.asm b/data/battle/stat_multipliers_2.asm
new file mode 100644
index 00000000..3f3dc234
--- /dev/null
+++ b/data/battle/stat_multipliers_2.asm
@@ -0,0 +1,20 @@
+; Multiplier ratios for all stats from modifier -6 to +6
+; (except accuracy, see data/battle/accuracy_multipliers.asm).
+
+; This table is identical to data/battle/stat_multipliers.asm.
+; This one is used by ApplyStatLevelMultiplier.
+
+StatLevelMultipliers_Applied:
+ db 25, 100 ; -6 = 25%
+ db 28, 100 ; -5 = 28%
+ db 33, 100 ; -4 = 33%
+ db 40, 100 ; -3 = 40%
+ db 50, 100 ; -2 = 50%
+ db 66, 100 ; -1 = 66%
+ db 1, 1 ; 0 = 100%
+ db 15, 10 ; +1 = 150%
+ db 2, 1 ; +2 = 200%
+ db 25, 10 ; +3 = 250%
+ db 3, 1 ; +4 = 300%
+ db 35, 10 ; +5 = 350%
+ db 4, 1 ; +6 = 400%
diff --git a/data/text/common_1.asm b/data/text/common_1.asm
index 69e3c49e..ca1a8e9a 100755
--- a/data/text/common_1.asm
+++ b/data/text/common_1.asm
@@ -1633,7 +1633,7 @@ Text_Gained::
text_ram wStringBuffer1
text " gained@@"
-Text_ABoostedStringBuffer2ExpPoints::
+_BoostedExpPointsText::
text_start
line "a boosted"
cont "@"
@@ -1641,7 +1641,7 @@ Text_ABoostedStringBuffer2ExpPoints::
text " EXP. Points!"
prompt
-Text_StringBuffer2ExpPoints::
+_ExpPointsText::
text_start
line "@"
text_decimal wStringBuffer2, 2, 4
@@ -1674,29 +1674,31 @@ Text_YourFoesWeakGetmMon::
text "!"
done
-Text_ThatsEnoughComeBack::
+Text_BattleMonNickComma::
text_ram wBattleMonNick
text ",@@"
+
+_ThatsEnoughComeBackText::
text " that's"
line "enough! Come back!"
done
-Text_OKComeBack::
+_OKComeBackText::
text " OK!"
line "Come back!"
done
-Text_GoodComeBack::
+_GoodComeBackText::
text " good!"
line "Come back!"
done
-Text_ComeBack::
+_ComeBackText::
text " come"
line "back!"
done
-BattleText_PlayerPickedUpPayDayMoney:
+_PlayerPickedUpPayDayMoney::
text "<PLAYER> picked up"
line "¥@"
text_decimal wPayDayMoney, 3, 6
diff --git a/data/wild/unlocked_unowns.asm b/data/wild/unlocked_unowns.asm
new file mode 100644
index 00000000..d09064c4
--- /dev/null
+++ b/data/wild/unlocked_unowns.asm
@@ -0,0 +1,24 @@
+unown_set: MACRO
+rept _NARG
+ db UNOWN_\1
+ shift
+endr
+ db -1
+ENDM
+
+UnlockedUnownLetterSets:
+; entries correspond to wUnlockedUnowns bits
+ dw .Set_A_K ; ENGINE_UNLOCKED_UNOWNS_A_TO_K
+ dw .Set_L_R ; ENGINE_UNLOCKED_UNOWNS_L_TO_R
+ dw .Set_S_W ; ENGINE_UNLOCKED_UNOWNS_S_TO_W
+ dw .Set_X_Z ; ENGINE_UNLOCKED_UNOWNS_X_TO_Z
+.End
+
+.Set_A_K:
+ unown_set A, B, C, D, E, F, G, H, I, J, K
+.Set_L_R:
+ unown_set L, M, N, O, P, Q, R
+.Set_S_W:
+ unown_set S, T, U, V, W
+.Set_X_Z:
+ unown_set X, Y, Z
diff --git a/engine/battle/core.asm b/engine/battle/core.asm
index 04769f46..734d151b 100644
--- a/engine/battle/core.asm
+++ b/engine/battle/core.asm
@@ -4621,3 +4621,4109 @@ UpdateHPPal:
ret_3df99:
ret
+
+BattleMenu:
+ xor a
+ ldh [hBGMapMode], a
+ call LoadTempTilemapToTilemap
+
+ ld a, [wBattleType]
+ cp BATTLETYPE_DEBUG
+ jr z, .ok
+ cp BATTLETYPE_TUTORIAL
+ jr z, .ok
+ call UpdateBattleHuds
+ call EmptyBattleTextbox
+ call LoadTilemapToTempTilemap
+.ok
+
+.loop
+ ld a, [wBattleType]
+ cp BATTLETYPE_CONTEST
+ jr nz, .not_contest
+ callfar ContestBattleMenu
+ jr .next
+.not_contest
+
+ ; Auto input: choose "ITEM"
+ ld a, [wInputType]
+ or a
+ jr z, .skip_dude_pack_select
+ farcall _DudeAutoInput_DownA
+.skip_dude_pack_select
+ callfar LoadBattleMenu
+
+.next
+ ld a, $1
+ ldh [hBGMapMode], a
+ ld a, [wBattleMenuCursorBuffer]
+ cp $1
+ jp z, BattleMenu_Fight
+ cp $3
+ jp z, BattleMenu_Pack
+ cp $2
+ jp z, BattleMenu_PKMN
+ cp $4
+ jp z, BattleMenu_Run
+ jr .loop
+
+BattleMenu_Fight:
+ xor a
+ ld [wNumFleeAttempts], a
+ call SafeLoadTempTilemapToTilemap
+ and a
+ ret
+
+BattleMenu_Pack:
+ ld a, [wLinkMode]
+ and a
+ jp nz, .ItemsCantBeUsed
+
+ call LoadStandardMenuHeader
+
+ ld a, [wBattleType]
+ cp BATTLETYPE_TUTORIAL
+ jr z, .tutorial
+ cp BATTLETYPE_CONTEST
+ jr z, .contest
+
+ farcall BattlePack
+ ld a, [wBattlePlayerAction]
+ and a ; BATTLEPLAYERACTION_USEMOVE?
+ jr z, .didnt_use_item
+ jr .got_item
+
+.tutorial
+ farcall TutorialPack
+ ld a, POKE_BALL
+ ld [wCurItem], a
+ call DoItemEffect
+ jr .got_item
+
+.contest
+ ld a, PARK_BALL
+ ld [wCurItem], a
+ call DoItemEffect
+
+.got_item
+ call .UseItem
+ ret
+
+.didnt_use_item
+ call ClearPalettes
+ call DelayFrame
+ call _LoadBattleFontsHPBar
+ call GetBattleMonBackpic
+ call GetEnemyMonFrontpic
+ call ExitMenu
+ call WaitBGMap
+ call FinishBattleAnim
+ call LoadTilemapToTempTilemap
+ jp BattleMenu
+
+.ItemsCantBeUsed:
+ ld hl, BattleText_ItemsCantBeUsedHere
+ call StdBattleTextbox
+ jp BattleMenu
+
+.UseItem:
+ ld a, [wWildMon]
+ and a
+ jr nz, .run
+ callfar CheckItemPocket
+ ld a, [wItemAttributeParamBuffer]
+ cp BALL
+ jr z, .ball
+ call ClearBGPalettes
+
+.ball
+ xor a
+ ldh [hBGMapMode], a
+ call _LoadBattleFontsHPBar
+ call ClearSprites
+ ld a, [wBattleType]
+ cp BATTLETYPE_TUTORIAL
+ jr z, .tutorial2
+ call GetBattleMonBackpic
+
+.tutorial2
+ call GetEnemyMonFrontpic
+ ld a, $1
+ ld [wMenuCursorY], a
+ call ExitMenu
+ call UpdateBattleHUDs
+ call WaitBGMap
+ call LoadTilemapToTempTilemap
+ call ClearWindowData
+ call FinishBattleAnim
+ and a
+ ret
+
+.run
+ xor a
+ ld [wWildMon], a
+ ld a, [wBattleResult]
+ and BATTLERESULT_BITMASK
+ ld [wBattleResult], a ; WIN
+ call ClearWindowData
+ call SetPalettes
+ scf
+ ret
+
+BattleMenu_PKMN:
+ call LoadStandardMenuHeader
+BattleMenuPKMN_ReturnFromStats:
+ call ExitMenu
+ call LoadStandardMenuHeader
+ call ClearBGPalettes
+BattleMenuPKMN_Loop:
+ farcall LoadPartyMenuGFX
+ farcall InitPartyMenuWithCancel
+ farcall InitPartyMenuGFX
+ xor a
+ ld [wPartyMenuActionText], a
+ farcall WritePartyMenuTilemap
+ farcall PrintPartyMenuText
+ call WaitBGMap
+ call SetPalettes
+ call DelayFrame
+ farcall PartyMenuSelect
+ jr c, .Cancel
+.loop
+ callfar FreezeMonIcons
+ callfar GetMenu
+ jr c, BattleMenuPKMN_Loop
+ call PlaceHollowCursor
+ ld a, [wMenuCursorY]
+ cp $1 ; SWITCH
+ jp z, TryPlayerSwitch
+ cp $2 ; STATS
+ jr z, .Stats
+ cp $3 ; CANCEL
+ jr z, .Cancel
+ jr .loop
+
+.Stats:
+ call Battle_StatsScreen
+ jp BattleMenuPKMN_ReturnFromStats
+
+.Cancel:
+ call ClearSprites
+ call ClearPalettes
+ call DelayFrame
+ call _LoadHPBar
+ call CloseWindow
+ call LoadTilemapToTempTilemap
+ call GetMemSGBLayout
+ call SetPalettes
+ jp BattleMenu
+
+Battle_StatsScreen:
+ call DisableLCD
+
+ ld hl, vTiles2 tile $31
+ ld de, vTiles0
+ ld bc, $11 tiles
+ call CopyBytes
+
+ ld hl, vTiles2
+ ld de, vTiles0 tile $11
+ ld bc, $31 tiles
+ call CopyBytes
+
+ call EnableLCD
+
+ call ClearSprites
+ call LowVolume
+ xor a ; PARTYMON
+ ld [wMonType], a
+ ld hl, wPartyMons
+ predef StatsScreenInit
+ call MaxVolume
+
+ call DisableLCD
+
+ ld hl, vTiles0
+ ld de, vTiles2 tile $31
+ ld bc, $11 tiles
+ call CopyBytes
+
+ ld hl, vTiles0 tile $11
+ ld de, vTiles2
+ ld bc, $31 tiles
+ call CopyBytes
+
+ call EnableLCD
+ ret
+
+TryPlayerSwitch:
+ ld a, [wCurBattleMon]
+ ld d, a
+ ld a, [wCurPartyMon]
+ cp d
+ jr nz, .check_trapped
+ ld hl, BattleText_MonIsAlreadyOut
+ call StdBattleTextbox
+ jp BattleMenuPKMN_Loop
+
+.check_trapped
+ ld a, [wPlayerWrapCount]
+ and a
+ jr nz, .trapped
+ ld a, [wEnemySubStatus5]
+ bit SUBSTATUS_CANT_RUN, a
+ jr z, .try_switch
+
+.trapped
+ ld hl, BattleText_MonCantBeRecalled
+ call StdBattleTextbox
+ jp BattleMenuPKMN_Loop
+
+.try_switch
+ call CheckIfCurPartyMonIsFitToFight
+ jp z, BattleMenuPKMN_Loop
+ ld a, [wCurBattleMon]
+ ld [wLastPlayerMon], a
+ ld a, BATTLEPLAYERACTION_SWITCH
+ ld [wBattlePlayerAction], a
+ call ClearPalettes
+ call DelayFrame
+ call ClearSprites
+ call _LoadHPBar
+ call CloseWindow
+ call GetMemSGBLayout
+ call SetPalettes
+ ld a, [wCurPartyMon]
+ ld [wCurBattleMon], a
+PlayerSwitch:
+ ld a, 1
+ ld [wPlayerIsSwitching], a
+ ld a, [wLinkMode]
+ and a
+ jr z, .not_linked
+ call LoadStandardMenuHeader
+ call LinkBattleSendReceiveAction
+ call CloseWindow
+
+.not_linked
+ call ParseEnemyAction
+ ld a, [wLinkMode]
+ and a
+ jr nz, .linked
+
+.switch
+ call BattleMonEntrance
+ and a
+ ret
+
+.linked
+ ld a, [wBattleAction]
+ cp BATTLEACTION_STRUGGLE
+ jp z, .switch
+ cp BATTLEACTION_SKIPTURN
+ jp z, .switch
+ cp BATTLEACTION_SWITCH1
+ jp c, .switch
+ cp BATTLEACTION_FORFEIT
+ jr nz, .dont_run
+ call WildFled_EnemyFled_LinkBattleCanceled
+ ret
+
+.dont_run
+ ldh a, [hSerialConnectionStatus]
+ cp USING_EXTERNAL_CLOCK
+ jr z, .player_1
+ call BattleMonEntrance
+ call EnemyMonEntrance
+ and a
+ ret
+
+.player_1
+ call EnemyMonEntrance
+ call BattleMonEntrance
+ and a
+ ret
+
+EnemyMonEntrance:
+ callfar AI_Switch
+ call SetEnemyTurn
+ jp SpikesDamage
+
+BattleMonEntrance:
+ call WithdrawMonText
+
+ ld c, 50
+ call DelayFrames
+
+ ld hl, wPlayerSubStatus4
+ res SUBSTATUS_RAGE, [hl]
+
+ call SetEnemyTurn
+ call PursuitSwitch
+ jr c, .ok
+ call RecallPlayerMon
+.ok
+
+ hlcoord 9, 7
+ lb bc, 5, 11
+ call ClearBox
+
+ ld a, [wCurBattleMon]
+ ld [wCurPartyMon], a
+ call AddBattleParticipant
+ call InitBattleMon
+ call ResetPlayerStatLevels
+ call SendOutMonText
+ call NewBattleMonStatus
+ call BreakAttraction
+ call SendOutPlayerMon
+ call EmptyBattleTextbox
+ call LoadTilemapToTempTilemap
+ call SetPlayerTurn
+ call SpikesDamage
+ ld a, $2
+ ld [wMenuCursorY], a
+ ret
+
+PassedBattleMonEntrance:
+ ld c, 50
+ call DelayFrames
+
+ hlcoord 9, 7
+ lb bc, 5, 11
+ call ClearBox
+
+ ld a, [wCurPartyMon]
+ ld [wCurBattleMon], a
+ call AddBattleParticipant
+ call InitBattleMon
+ xor a ; FALSE
+ ld [wApplyStatLevelMultipliersToEnemy], a
+ call ApplyStatLevelMultiplierOnAllStats
+ call SendOutPlayerMon
+ call EmptyBattleTextbox
+ call LoadTilemapToTempTilemap
+ call SetPlayerTurn
+ jp SpikesDamage
+
+BattleMenu_Run:
+ call SafeLoadTempTilemapToTilemap
+ ld a, $3
+ ld [wMenuCursorY], a
+ ld hl, wBattleMonSpeed
+ ld de, wEnemyMonSpeed
+ call TryToRunAwayFromBattle
+ ld a, FALSE
+ ld [wFailedToFlee], a
+ ret c
+ ld a, [wBattlePlayerAction]
+ and a ; BATTLEPLAYERACTION_USEMOVE?
+ ret nz
+ jp BattleMenu
+
+CheckAmuletCoin:
+ ld a, [wBattleMonItem]
+ ld b, a
+ callfar GetItemHeldEffect
+ ld a, b
+ cp HELD_AMULET_COIN
+ ret nz
+ ld a, 1
+ ld [wAmuletCoin], a
+ ret
+
+MoveSelectionScreen:
+ ld hl, wEnemyMonMoves
+ ld a, [wMoveSelectionMenuType]
+ dec a
+ jr z, .got_menu_type
+ dec a
+ jr z, .ether_elixer_menu
+ call .CheckPlayerHasUsableMoves
+ ret z ; use Struggle
+ ld hl, wBattleMonMoves
+ jr .got_menu_type
+
+.ether_elixer_menu
+ ld a, MON_MOVES
+ call GetPartyParamLocation
+
+.got_menu_type
+ ld de, wListMoves_MoveIndicesBuffer
+ ld bc, NUM_MOVES
+ call CopyBytes
+ xor a
+ ldh [hBGMapMode], a
+
+ hlcoord 4, 17 - NUM_MOVES - 1
+ ld b, 4
+ ld c, 14
+ ld a, [wMoveSelectionMenuType]
+ cp $2
+ jr nz, .got_dims
+ hlcoord 4, 17 - NUM_MOVES - 1 - 4
+ ld b, 4
+ ld c, 14
+.got_dims
+ call Textbox
+
+ hlcoord 6, 17 - NUM_MOVES
+ ld a, [wMoveSelectionMenuType]
+ cp $2
+ jr nz, .got_start_coord
+ hlcoord 6, 17 - NUM_MOVES - 4
+.got_start_coord
+ ld a, SCREEN_WIDTH
+ ld [wBuffer1], a
+ predef ListMoves
+
+ ld b, 5
+ ld a, [wMoveSelectionMenuType]
+ cp $2
+ ld a, 17 - NUM_MOVES
+ jr nz, .got_default_coord
+ ld b, 5
+ ld a, 17 - NUM_MOVES - 4
+
+.got_default_coord
+ ld [w2DMenuCursorInitY], a
+ ld a, b
+ ld [w2DMenuCursorInitX], a
+ ld a, [wMoveSelectionMenuType]
+ cp $1
+ jr z, .skip_inc
+ ld a, [wCurMoveNum]
+ inc a
+
+.skip_inc
+ ld [wMenuCursorY], a
+ ld a, 1
+ ld [wMenuCursorX], a
+ ld a, [wNumMoves]
+ inc a
+ ld [w2DMenuNumRows], a
+ ld a, 1
+ ld [w2DMenuNumCols], a
+ ld c, STATICMENU_ENABLE_LEFT_RIGHT | STATICMENU_ENABLE_START | STATICMENU_WRAP
+ ld a, [wMoveSelectionMenuType]
+ dec a
+ ld b, D_DOWN | D_UP | A_BUTTON
+ jr z, .okay
+ dec a
+ ld b, D_DOWN | D_UP | A_BUTTON | B_BUTTON
+ jr z, .okay
+ ld a, [wLinkMode]
+ cp LINK_COLOSSEUM
+ jr z, .okay
+ ld b, D_DOWN | D_UP | A_BUTTON | B_BUTTON | SELECT
+
+.okay
+ ld a, b
+ ld [wMenuJoypadFilter], a
+ ld a, c
+ ld [w2DMenuFlags1], a
+ xor a
+ ld [w2DMenuFlags2], a
+ ld a, $10
+ ld [w2DMenuCursorOffsets], a
+.menu_loop
+ ld a, [wMoveSelectionMenuType]
+ and a
+ jr z, .battle_player_moves
+ dec a
+ jr nz, .interpret_joypad
+ hlcoord 11, 14
+ ld de, .string_3e61c
+ call PlaceString
+ jr .interpret_joypad
+
+.battle_player_moves
+ call MoveInfoBox
+ ld a, [wMoveSwapBuffer]
+ and a
+ jr z, .interpret_joypad
+ hlcoord 5, 13
+ ld bc, SCREEN_WIDTH
+ dec a
+ call AddNTimes
+ ld [hl], "▷"
+
+.interpret_joypad
+ ld a, $1
+ ldh [hBGMapMode], a
+ call ScrollingMenuJoypad
+ bit D_UP_F, a
+ jp nz, .pressed_up
+ bit D_DOWN_F, a
+ jp nz, .pressed_down
+ bit SELECT_F, a
+ jp nz, .pressed_select
+ bit B_BUTTON_F, a
+ ; A button
+ push af
+
+ xor a
+ ld [wMoveSwapBuffer], a
+ ld a, [wMenuCursorY]
+ dec a
+ ld [wMenuCursorY], a
+ ld b, a
+ ld a, [wMoveSelectionMenuType]
+ dec a
+ jr nz, .not_enemy_moves_process_b
+
+ pop af
+ ret
+
+.not_enemy_moves_process_b
+ dec a
+ ld a, b
+ ld [wCurMoveNum], a
+ jr nz, .use_move
+
+ pop af
+ ret
+
+.use_move
+ pop af
+ ret nz
+
+ ld hl, wBattleMonPP
+ ld a, [wMenuCursorY]
+ ld c, a
+ ld b, 0
+ add hl, bc
+ ld a, [hl]
+ and PP_MASK
+ jr z, .no_pp_left
+ ld a, [wPlayerDisableCount]
+ swap a
+ and $f
+ dec a
+ cp c
+ jr z, .move_disabled
+ ld a, [wUnusedPlayerLockedMove]
+ and a
+ jr nz, .skip2
+ ld a, [wMenuCursorY]
+ ld hl, wBattleMonMoves
+ ld c, a
+ ld b, 0
+ add hl, bc
+ ld a, [hl]
+
+.skip2
+ ld [wCurPlayerMove], a
+ xor a
+ ret
+
+.move_disabled
+ ld hl, BattleText_TheMoveIsDisabled
+ jr .place_textbox_start_over
+
+.no_pp_left
+ ld hl, BattleText_TheresNoPPLeftForThisMove
+
+.place_textbox_start_over
+ call StdBattleTextbox
+ call SafeLoadTempTilemapToTilemap
+ jp MoveSelectionScreen
+
+.string_3e61c
+ db "@"
+
+.pressed_up
+ ld a, [wMenuCursorY]
+ and a
+ jp nz, .menu_loop
+ ld a, [wNumMoves]
+ inc a
+ ld [wMenuCursorY], a
+ jp .menu_loop
+
+.pressed_down
+ ld a, [wMenuCursorY]
+ ld b, a
+ ld a, [wNumMoves]
+ inc a
+ inc a
+ cp b
+ jp nz, .menu_loop
+ ld a, $1
+ ld [wMenuCursorY], a
+ jp .menu_loop
+
+.CheckPlayerHasUsableMoves:
+ ld a, STRUGGLE
+ ld [wCurPlayerMove], a
+ ld a, [wPlayerDisableCount]
+ and a
+ ld hl, wBattleMonPP
+ jr nz, .disabled
+
+ ld a, [hli]
+ or [hl]
+ inc hl
+ or [hl]
+ inc hl
+ or [hl]
+ and PP_MASK
+ ret nz
+ jr .force_struggle
+
+.disabled
+ swap a
+ and $f
+ ld b, a
+ ld d, NUM_MOVES + 1
+ xor a
+.loop
+ dec d
+ jr z, .done
+ ld c, [hl]
+ inc hl
+ dec b
+ jr z, .loop
+ or c
+ jr .loop
+
+.done
+ ; Bug: this will result in a move with PP Up confusing the game.
+ and a ; should be "and PP_MASK"
+ ret nz
+
+.force_struggle
+ ld hl, BattleText_MonHasNoMovesLeft
+ call StdBattleTextbox
+ ld c, 60
+ call DelayFrames
+ xor a
+ ret
+
+.pressed_select
+ ld a, [wMoveSwapBuffer]
+ and a
+ jr z, .start_swap
+ ld hl, wBattleMonMoves
+ call .swap_bytes
+ ld hl, wBattleMonPP
+ call .swap_bytes
+ ld hl, wPlayerDisableCount
+ ld a, [hl]
+ swap a
+ and $f
+ ld b, a
+ ld a, [wMenuCursorY]
+ cp b
+ jr nz, .not_swapping_disabled_move
+ ld a, [hl]
+ and $f
+ ld b, a
+ ld a, [wMoveSwapBuffer]
+ swap a
+ add b
+ ld [hl], a
+ jr .swap_moves_in_party_struct
+
+.not_swapping_disabled_move
+ ld a, [wMoveSwapBuffer]
+ cp b
+ jr nz, .swap_moves_in_party_struct
+ ld a, [hl]
+ and $f
+ ld b, a
+ ld a, [wMenuCursorY]
+ swap a
+ add b
+ ld [hl], a
+
+.swap_moves_in_party_struct
+; Fixes the COOLTRAINER glitch
+ ld a, [wPlayerSubStatus5]
+ bit SUBSTATUS_TRANSFORMED, a
+ jr nz, .transformed
+ ld hl, wPartyMon1Moves
+ ld a, [wCurBattleMon]
+ call GetPartyLocation
+ push hl
+ call .swap_bytes
+ pop hl
+ ld bc, MON_PP - MON_MOVES
+ add hl, bc
+ call .swap_bytes
+
+.transformed
+ xor a
+ ld [wMoveSwapBuffer], a
+ jp MoveSelectionScreen
+
+.swap_bytes
+ push hl
+ ld a, [wMoveSwapBuffer]
+ dec a
+ ld c, a
+ ld b, 0
+ add hl, bc
+ ld d, h
+ ld e, l
+ pop hl
+ ld a, [wMenuCursorY]
+ dec a
+ ld c, a
+ ld b, 0
+ add hl, bc
+ ld a, [de]
+ ld b, [hl]
+ ld [hl], a
+ ld a, b
+ ld [de], a
+ ret
+
+.start_swap
+ ld a, [wMenuCursorY]
+ ld [wMoveSwapBuffer], a
+ jp MoveSelectionScreen
+
+MoveInfoBox:
+ xor a
+ ldh [hBGMapMode], a
+
+ hlcoord 0, 8
+ ld b, 3
+ ld c, 9
+ call Textbox
+
+ ld a, [wPlayerDisableCount]
+ and a
+ jr z, .not_disabled
+
+ swap a
+ and $f
+ ld b, a
+ ld a, [wMenuCursorY]
+ cp b
+ jr nz, .not_disabled
+
+ hlcoord 1, 10
+ ld de, .Disabled
+ call PlaceString
+ jr .done
+
+.not_disabled
+ ld hl, wMenuCursorY
+ dec [hl]
+ call SetPlayerTurn
+ ld hl, wBattleMonMoves
+ ld a, [wMenuCursorY]
+ ld c, a
+ ld b, 0
+ add hl, bc
+ ld a, [hl]
+ ld [wCurPlayerMove], a
+
+ ld a, [wCurBattleMon]
+ ld [wCurPartyMon], a
+ ld a, WILDMON
+ ld [wMonType], a
+ callfar GetMaxPPOfMove
+
+ ld hl, wMenuCursorY
+ ld c, [hl]
+ inc [hl]
+ ld b, 0
+ ld hl, wBattleMonPP
+ add hl, bc
+ ld a, [hl]
+ and PP_MASK
+ ld [wStringBuffer1], a
+ hlcoord 1, 9
+ ld de, .Type
+ call PlaceString
+
+ hlcoord 7, 11
+ ld [hl], "/"
+ hlcoord 5, 11
+ ld de, wStringBuffer1
+ lb bc, 1, 2
+ call PrintNum
+
+ hlcoord 8, 11
+ ld de, wNamedObjectIndexBuffer
+ lb bc, 1, 2
+ call PrintNum
+
+ callfar UpdateMoveData
+ ld a, [wPlayerMoveStruct + MOVE_ANIM]
+ ld b, a
+ hlcoord 2, 10
+ predef PrintMoveType
+
+.done
+ ret
+
+.Disabled:
+ db "Disabled!@"
+.Type:
+ db "TYPE/@"
+
+ParseEnemyAction:
+ ld a, [wEnemyIsSwitching]
+ and a
+ ret nz
+ ld a, [wLinkMode]
+ and a
+ jr z, .not_linked
+ call EmptyBattleTextbox
+ call LoadTilemapToTempTilemap
+ ld a, [wBattlePlayerAction]
+ and a ; BATTLEPLAYERACTION_USEMOVE?
+ call z, LinkBattleSendReceiveAction
+ call SafeLoadTempTilemapToTilemap
+ ld a, [wBattleAction]
+ cp BATTLEACTION_STRUGGLE
+ jp z, .struggle
+ cp BATTLEACTION_SKIPTURN
+ jp z, .skip_turn
+ cp BATTLEACTION_SWITCH1
+ jp nc, ResetVarsForSubstatusRage
+ ld [wCurEnemyMoveNum], a
+ ld c, a
+ ld a, [wEnemySubStatus1]
+ bit SUBSTATUS_ROLLOUT, a
+ jp nz, .skip_load
+ ld a, [wEnemySubStatus3]
+ and 1 << SUBSTATUS_CHARGED | 1 << SUBSTATUS_RAMPAGE | 1 << SUBSTATUS_BIDE
+ jp nz, .skip_load
+
+ ld hl, wEnemySubStatus5
+ bit SUBSTATUS_ENCORED, [hl]
+ ld a, [wLastEnemyMove]
+ jp nz, .finish
+ ld hl, wEnemyMonMoves
+ ld b, 0
+ add hl, bc
+ ld a, [hl]
+ jp .finish
+
+.not_linked
+ ld hl, wEnemySubStatus5
+ bit SUBSTATUS_ENCORED, [hl]
+ jr z, .skip_encore
+ ld a, [wLastEnemyMove]
+ jp .finish
+
+.skip_encore
+ call CheckEnemyLockedIn
+ jp nz, ResetVarsForSubstatusRage
+ jr .continue
+
+.skip_turn
+ ld a, $ff
+ jr .finish
+
+.continue
+ ld hl, wEnemyMonMoves
+ ld de, wEnemyMonPP
+ ld b, NUM_MOVES
+.loop
+ ld a, [hl]
+ and a
+ jp z, .struggle
+ ld a, [wEnemyDisabledMove]
+ cp [hl]
+ jr z, .disabled
+ ld a, [de]
+ and PP_MASK
+ jr nz, .enough_pp
+
+.disabled
+ inc hl
+ inc de
+ dec b
+ jr nz, .loop
+ jr .struggle
+
+.enough_pp
+ ld a, [wBattleMode]
+ dec a
+ jr nz, .skip_load
+; wild
+.loop2
+ ld hl, wEnemyMonMoves
+ call BattleRandom
+ maskbits NUM_MOVES
+ ld c, a
+ ld b, 0
+ add hl, bc
+ ld a, [wEnemyDisableCount]
+ swap a
+ and $f
+ dec a
+ cp c
+ jr z, .loop2
+ ld a, [hl]
+ and a
+ jr z, .loop2
+ ld hl, wEnemyMonPP
+ add hl, bc
+ ld b, a
+ ld a, [hl]
+ and PP_MASK
+ jr z, .loop2
+ ld a, c
+ ld [wCurEnemyMoveNum], a
+ ld a, b
+
+.finish
+ ld [wCurEnemyMove], a
+
+.skip_load
+ call SetEnemyTurn
+ callfar UpdateMoveData
+ call CheckEnemyLockedIn
+ jr nz, .raging
+ xor a
+ ld [wEnemyCharging], a
+
+.raging
+ ld a, [wEnemyMoveStruct + MOVE_EFFECT]
+ cp EFFECT_FURY_CUTTER
+ jr z, .fury_cutter
+ xor a
+ ld [wEnemyFuryCutterCount], a
+
+.fury_cutter
+ ld a, [wEnemyMoveStruct + MOVE_EFFECT]
+ cp EFFECT_RAGE
+ jr z, .no_rage
+ ld hl, wEnemySubStatus4
+ res SUBSTATUS_RAGE, [hl]
+ xor a
+ ld [wEnemyRageCounter], a
+
+.no_rage
+ ld a, [wEnemyMoveStruct + MOVE_EFFECT]
+ cp EFFECT_PROTECT
+ ret z
+ cp EFFECT_ENDURE
+ ret z
+ xor a
+ ld [wEnemyProtectCount], a
+ ret
+
+.struggle
+ ld a, STRUGGLE
+ jr .finish
+
+ResetVarsForSubstatusRage:
+ xor a
+ ld [wEnemyFuryCutterCount], a
+ ld [wEnemyProtectCount], a
+ ld [wEnemyRageCounter], a
+ ld hl, wEnemySubStatus4
+ res SUBSTATUS_RAGE, [hl]
+ ret
+
+CheckEnemyLockedIn:
+ ld a, [wEnemySubStatus4]
+ and 1 << SUBSTATUS_RECHARGE
+ ret nz
+
+ ld hl, wEnemySubStatus3
+ ld a, [hl]
+ and 1 << SUBSTATUS_CHARGED | 1 << SUBSTATUS_RAMPAGE | 1 << SUBSTATUS_BIDE
+ ret nz
+
+ ld hl, wEnemySubStatus1
+ bit SUBSTATUS_ROLLOUT, [hl]
+ ret
+
+LinkBattleSendReceiveAction:
+ ld a, $ff
+ ld [wOtherPlayerLinkAction], a
+ ld a, [wBattlePlayerAction]
+ and a ; BATTLEPLAYERACTION_USEMOVE?
+ jr nz, .switch
+ ld a, [wCurPlayerMove]
+ cp STRUGGLE
+ ld b, BATTLEACTION_STRUGGLE
+ jr z, .struggle
+ dec b
+ inc a
+ jr z, .struggle
+ ld a, [wCurMoveNum]
+ jr .use_move
+
+.switch
+ ld a, [wCurPartyMon]
+ add BATTLEACTION_SWITCH1
+ ld b, a
+
+.struggle
+ ld a, b
+
+.use_move
+ ld [wPlayerLinkAction], a
+ callfar PlaceWaitingText
+
+.waiting
+ call LinkTransfer
+ call DelayFrame
+ ld a, [wOtherPlayerLinkAction]
+ inc a
+ jr z, .waiting
+
+ ld b, 10
+.receive
+ call DelayFrame
+ call LinkTransfer
+ dec b
+ jr nz, .receive
+
+ ld b, 10
+.acknowledge
+ call DelayFrame
+ call LinkDataReceived
+ dec b
+ jr nz, .acknowledge
+
+ ret
+
+LoadEnemyMon:
+; Initialize enemy monster parameters
+; To do this we pull the species from wTempEnemyMonSpecies
+
+; Notes:
+; BattleRandom is used to ensure sync between Game Boys
+
+; Clear the whole enemy mon struct (wEnemyMon)
+ xor a
+ ld hl, wEnemyMonSpecies
+ ld bc, wEnemyMonEnd - wEnemyMon
+ call ByteFill
+
+; We don't need to be here if we're in a link battle
+ ld a, [wLinkMode]
+ and a
+ jp nz, InitEnemyMon
+
+; Make sure everything knows what species we're working with
+ ld a, [wTempEnemyMonSpecies]
+ ld [wEnemyMonSpecies], a
+ ld [wCurSpecies], a
+ ld [wCurPartySpecies], a
+
+; Grab the BaseData for this species
+ call GetBaseData
+
+; Let's get the item:
+
+; Is the item predetermined?
+ ld a, [wBattleMode]
+ dec a
+ jr z, .WildItem
+
+; If we're in a trainer battle, the item is in the party struct
+ ld a, [wCurPartyMon]
+ ld hl, wOTPartyMon1Item
+ call GetPartyLocation ; bc = PartyMon[wCurPartyMon] - wPartyMons
+ ld a, [hl]
+ jr .UpdateItem
+
+.WildItem:
+; In a wild battle, we pull from the item slots in BaseData
+
+; Force Item1
+; Used for Ho-Oh, Lugia and Snorlax encounters
+ ld a, [wBattleType]
+ cp BATTLETYPE_FORCEITEM
+ ld a, [wBaseItem1]
+ jr z, .UpdateItem
+
+; Failing that, it's all up to chance
+; Effective chances:
+; 75% None
+; 23% Item1
+; 2% Item2
+
+; 25% chance of getting an item
+ call BattleRandom
+ cp 75 percent + 1
+ ld a, NO_ITEM
+ jr c, .UpdateItem
+
+; From there, an 8% chance for Item2
+ call BattleRandom
+ cp 8 percent ; 8% of 25% = 2% Item2
+ ld a, [wBaseItem1]
+ jr nc, .UpdateItem
+ ld a, [wBaseItem2]
+
+.UpdateItem:
+ ld [wEnemyMonItem], a
+
+; Initialize DVs
+
+; If we're in a trainer battle, DVs are predetermined
+ ld a, [wBattleMode]
+ and a
+ jr z, .InitDVs
+
+ ld a, [wEnemySubStatus5]
+ bit SUBSTATUS_TRANSFORMED, a
+ jr z, .InitDVs
+
+; Unknown
+ ld hl, wEnemyBackupDVs
+ ld de, wEnemyMonDVs
+ ld a, [hli]
+ ld [de], a
+ inc de
+ ld a, [hl]
+ ld [de], a
+ jp .Happiness
+
+.InitDVs:
+; Trainer DVs
+
+; All trainers have preset DVs, determined by class
+; See GetTrainerDVs for more on that
+ farcall GetTrainerDVs
+; These are the DVs we'll use if we're actually in a trainer battle
+ ld a, [wBattleMode]
+ dec a
+ jr nz, .UpdateDVs
+
+; Wild DVs
+; Here's where the fun starts
+
+; Roaming monsters (Entei, Raikou, Suicune) work differently
+; They have their own structs, which are shorter than normal
+ ld a, [wBattleType]
+ cp BATTLETYPE_ROAMING
+ jr nz, .NotRoaming
+
+; Grab HP
+ call GetRoamMonHP
+ ld a, [hl]
+; Check if the HP has been initialized
+ and a
+; We'll do something with the result in a minute
+ push af
+
+; Grab DVs
+ call GetRoamMonDVs
+ inc hl
+ ld a, [hld]
+ ld c, a
+ ld b, [hl]
+
+; Get back the result of our check
+ pop af
+; If the RoamMon struct has already been initialized, we're done
+ jr nz, .UpdateDVs
+
+; If it hasn't, we need to initialize the DVs
+; (HP is initialized at the end of the battle)
+ call GetRoamMonDVs
+ inc hl
+ call BattleRandom
+ ld [hld], a
+ ld c, a
+ call BattleRandom
+ ld [hl], a
+ ld b, a
+; We're done with DVs
+ jr .UpdateDVs
+
+.NotRoaming:
+; Register a contains wBattleType
+
+; Forced shiny battle type
+; Used by Red Gyarados at Lake of Rage
+ cp BATTLETYPE_SHINY
+ jr nz, .GenerateDVs
+
+ ld b, ATKDEFDV_SHINY ; $ea
+ ld c, SPDSPCDV_SHINY ; $aa
+ jr .UpdateDVs
+
+.GenerateDVs:
+; Generate new random DVs
+ call BattleRandom
+ ld b, a
+ call BattleRandom
+ ld c, a
+
+.UpdateDVs:
+; Input DVs in register bc
+ ld hl, wEnemyMonDVs
+ ld a, b
+ ld [hli], a
+ ld [hl], c
+
+; We've still got more to do if we're dealing with a wild monster
+ ld a, [wBattleMode]
+ dec a
+ jr nz, .Happiness
+
+; Species-specfic:
+
+; Unown
+ ld a, [wTempEnemyMonSpecies]
+ cp UNOWN
+ jr nz, .Magikarp
+
+; Get letter based on DVs
+ ld hl, wEnemyMonDVs
+ predef GetUnownLetter
+; Can't use any letters that haven't been unlocked
+; If combined with forced shiny battletype, causes an infinite loop
+ call CheckUnownLetter
+ jr c, .GenerateDVs ; try again
+
+.Magikarp:
+; These filters are untranslated.
+; They expect at wMagikarpLength a 2-byte value in mm,
+; but the value is in feet and inches (one byte each).
+
+; The first filter is supposed to make very large Magikarp even rarer,
+; by targeting those 1600 mm (= 5'3") or larger.
+; After the conversion to feet, it is unable to target any,
+; since the largest possible Magikarp is 5'3", and $0503 = 1283 mm.
+ ld a, [wTempEnemyMonSpecies]
+ cp MAGIKARP
+ jr nz, .Happiness
+
+; Get Magikarp's length
+ ld de, wEnemyMonDVs
+ ld bc, wPlayerID
+ callfar CalcMagikarpLength
+
+; No reason to keep going if length > 1536 mm (i.e. if HIGH(length) > 6 feet)
+ ld a, [wMagikarpLength]
+ cp HIGH(1536) ; should be "cp 5", since 1536 mm = 5'0", but HIGH(1536) = 6
+ jr nz, .CheckMagikarpArea
+
+; 5% chance of skipping both size checks
+ call Random
+ cp 5 percent
+ jr c, .CheckMagikarpArea
+; Try again if length >= 1616 mm (i.e. if LOW(length) >= 4 inches)
+ ld a, [wMagikarpLength + 1]
+ cp LOW(1616) ; should be "cp 4", since 1616 mm = 5'4", but LOW(1616) = 80
+ jr nc, .GenerateDVs
+
+; 20% chance of skipping this check
+ call Random
+ cp 20 percent - 1
+ jr c, .CheckMagikarpArea
+; Try again if length >= 1600 mm (i.e. if LOW(length) >= 3 inches)
+ ld a, [wMagikarpLength + 1]
+ cp LOW(1600) ; should be "cp 3", since 1600 mm = 5'3", but LOW(1600) = 64
+ jr nc, .GenerateDVs
+
+.CheckMagikarpArea:
+; The "jr z" checks are supposed to be "jr nz".
+
+; Instead, all maps in GROUP_LAKE_OF_RAGE (Mahogany area)
+; and Routes 20 and 44 are treated as Lake of Rage.
+
+; This also means Lake of Rage Magikarp can be smaller than ones
+; caught elsewhere rather than the other way around.
+
+; Intended behavior enforces a minimum size at Lake of Rage.
+; The real behavior prevents a minimum size in the Lake of Rage area.
+
+; Moreover, due to the check not being translated to feet+inches, all Magikarp
+; smaller than 4'0" may be caught by the filter, a lot more than intended.
+ ld a, [wMapGroup]
+ cp GROUP_LAKE_OF_RAGE
+ jr z, .Happiness
+ ld a, [wMapNumber]
+ cp MAP_LAKE_OF_RAGE
+ jr z, .Happiness
+; 40% chance of not flooring
+ call Random
+ cp 40 percent - 2
+ jr c, .Happiness
+; Try again if length < 1024 mm (i.e. if HIGH(length) < 3 feet)
+ ld a, [wMagikarpLength]
+ cp HIGH(1024) ; should be "cp 3", since 1024 mm = 3'4", but HIGH(1024) = 4
+ jr c, .GenerateDVs ; try again
+
+; Finally done with DVs
+
+.Happiness:
+; Set happiness
+ ld a, BASE_HAPPINESS
+ ld [wEnemyMonHappiness], a
+; Set level
+ ld a, [wCurPartyLevel]
+ ld [wEnemyMonLevel], a
+; Fill stats
+ ld de, wEnemyMonMaxHP
+ ld b, FALSE
+ ld hl, wEnemyMonDVs - (MON_DVS - MON_STAT_EXP + 1) ; wLinkBattleRNs + 7 ; ?
+ predef CalcMonStats
+
+; If we're in a trainer battle,
+; get the rest of the parameters from the party struct
+ ld a, [wBattleMode]
+ cp TRAINER_BATTLE
+ jr z, .OpponentParty
+
+; If we're in a wild battle, check wild-specific stuff
+ and a
+ jr z, .TreeMon
+
+ ld a, [wEnemySubStatus5]
+ bit SUBSTATUS_TRANSFORMED, a
+ jr nz, .Moves
+
+.TreeMon:
+; If we're headbutting trees, some monsters enter battle asleep
+ ld a, [wTempEnemyMonSpecies]
+
+; Hoothoot/Noctowl are asleep if MORN/DAY
+ cp HOOTHOOT
+ jr z, .sleeping_if_not_nite
+ cp NOCTOWL
+ jr z, .sleeping_if_not_nite
+
+; Pidgey/Spearow are asleep if NITE
+ cp PIDGEY
+ jr z, .sleeping_if_nite
+ cp SPEAROW
+ jr z, .sleeping_if_nite
+
+; Other species are never asleep
+ jr .not_sleeping
+
+.sleeping_if_not_nite
+ ld a, [wTimeOfDay]
+ cp NITE_F
+ jr nz, .sleeping
+ jr .not_sleeping
+
+.sleeping_if_nite
+ ld a, [wTimeOfDay]
+ cp NITE_F
+ jr z, .sleeping
+ jr .not_sleeping
+
+.sleeping
+ ld a, TREEMON_SLEEP_TURNS
+ jr .UpdateStatus
+
+.not_sleeping
+ xor a
+
+.UpdateStatus:
+ ld hl, wEnemyMonStatus
+ ld [hli], a
+
+; Unused byte
+ xor a
+ ld [hli], a
+
+; Full HP..
+ ld a, [wEnemyMonMaxHP]
+ ld [hli], a
+ ld a, [wEnemyMonMaxHP + 1]
+ ld [hl], a
+
+; ..unless it's a RoamMon
+ ld a, [wBattleType]
+ cp BATTLETYPE_ROAMING
+ jr nz, .Moves
+
+; Grab HP
+ call GetRoamMonHP
+ ld a, [hl]
+; Check if it's been initialized again
+ and a
+ jr z, .InitRoamHP
+; Update from the struct if it has
+ ld a, [hl]
+ ld [wEnemyMonHP + 1], a
+ jr .Moves
+
+.InitRoamHP:
+; HP only uses the lo byte in the RoamMon struct since
+; Raikou and Entei will have < 256 hp at level 40
+ ld a, [wEnemyMonHP + 1]
+ ld [hl], a
+ jr .Moves
+
+.OpponentParty:
+; Get HP from the party struct
+ ld hl, (wOTPartyMon1HP + 1)
+ ld a, [wCurPartyMon]
+ call GetPartyLocation
+ ld a, [hld]
+ ld [wEnemyMonHP + 1], a
+ ld a, [hld]
+ ld [wEnemyMonHP], a
+
+; Make sure everything knows which monster the opponent is using
+ ld a, [wCurPartyMon]
+ ld [wCurOTMon], a
+
+; Get status from the party struct
+ dec hl
+ ld a, [hl] ; OTPartyMonStatus
+ ld [wEnemyMonStatus], a
+
+.Moves:
+ ld hl, wBaseType1
+ ld de, wEnemyMonType1
+ ld a, [hli]
+ ld [de], a
+ inc de
+ ld a, [hl]
+ ld [de], a
+
+; Get moves
+ ld de, wEnemyMonMoves
+; Are we in a trainer battle?
+ ld a, [wBattleMode]
+ cp TRAINER_BATTLE
+ jr nz, .WildMoves
+; Then copy moves from the party struct
+ ld hl, wOTPartyMon1Moves
+ ld a, [wCurPartyMon]
+ call GetPartyLocation
+ ld bc, NUM_MOVES
+ call CopyBytes
+ jr .PP
+
+.WildMoves:
+; Clear wEnemyMonMoves
+ xor a
+ ld h, d
+ ld l, e
+ ld [hli], a
+ ld [hli], a
+ ld [hli], a
+ ld [hl], a
+; Make sure the predef knows this isn't a partymon
+ ld [wEvolutionOldSpecies], a
+; Fill moves based on level
+ predef FillMoves
+
+.PP:
+; Trainer battle?
+ ld a, [wBattleMode]
+ cp TRAINER_BATTLE
+ jr z, .TrainerPP
+
+; Fill wild PP
+ ld hl, wEnemyMonMoves
+ ld de, wEnemyMonPP
+ predef FillPP
+ jr .Finish
+
+.TrainerPP:
+; Copy PP from the party struct
+ ld hl, wOTPartyMon1PP
+ ld a, [wCurPartyMon]
+ call GetPartyLocation
+ ld de, wEnemyMonPP
+ ld bc, NUM_MOVES
+ call CopyBytes
+
+.Finish:
+; Only the first five base stats are copied..
+ ld hl, wBaseStats
+ ld de, wEnemyMonBaseStats
+ ld b, wBaseSpecialDefense - wBaseStats
+.loop
+ ld a, [hli]
+ ld [de], a
+ inc de
+ dec b
+ jr nz, .loop
+
+ ld a, [wBaseCatchRate]
+ ld [de], a
+ inc de
+
+ ld a, [wBaseExp]
+ ld [de], a
+
+ ld a, [wTempEnemyMonSpecies]
+ ld [wNamedObjectIndexBuffer], a
+
+ call GetPokemonName
+
+; Did we catch it?
+ ld a, [wBattleMode]
+ and a
+ ret z
+
+; Update enemy nick
+ ld hl, wStringBuffer1
+ ld de, wEnemyMonNick
+ ld bc, MON_NAME_LENGTH
+ call CopyBytes
+
+; Saw this mon
+ ld a, [wTempEnemyMonSpecies]
+ dec a
+ ld c, a
+ ld b, SET_FLAG
+ ld hl, wPokedexSeen
+ predef SmallFarFlagAction
+
+ ld hl, wEnemyMonStats
+ ld de, wEnemyStats
+ ld bc, wEnemyMonStatsEnd - wEnemyMonStats
+ call CopyBytes
+
+ ret
+
+CheckUnownLetter:
+; Return carry if the Unown letter hasn't been unlocked yet
+
+ ld a, [wUnlockedUnowns]
+ ld c, a
+ ld de, 0
+
+.loop
+
+; Don't check this set unless it's been unlocked
+ srl c
+ jr nc, .next
+
+; Is our letter in the set?
+ ld hl, UnlockedUnownLetterSets
+ add hl, de
+ ld a, [hli]
+ ld h, [hl]
+ ld l, a
+
+ push de
+ ld a, [wUnownLetter]
+ ld de, 1
+ push bc
+ call IsInArray
+ pop bc
+ pop de
+
+ jr c, .match
+
+.next
+; Make sure we haven't gone past the end of the table
+ inc e
+ inc e
+ ld a, e
+ cp UnlockedUnownLetterSets.End - UnlockedUnownLetterSets
+ jr c, .loop
+
+; Hasn't been unlocked, or the letter is invalid
+ scf
+ ret
+
+.match
+; Valid letter
+ and a
+ ret
+
+INCLUDE "data/wild/unlocked_unowns.asm"
+
+Unreferenced_SwapBattlerLevels:
+ push bc
+ ld a, [wBattleMonLevel]
+ ld b, a
+ ld a, [wEnemyMonLevel]
+ ld [wBattleMonLevel], a
+ ld a, b
+ ld [wEnemyMonLevel], a
+ pop bc
+ ret
+
+BattleWinSlideInEnemyTrainerFrontpic:
+ xor a
+ ld [wTempEnemyMonSpecies], a
+ call FinishBattleAnim
+ ld a, [wOtherTrainerClass]
+ ld [wTrainerClass], a
+ ld de, vTiles2
+ callfar GetTrainerPic
+ hlcoord 19, 0
+ ld c, 0
+
+.outer_loop
+ inc c
+ ld a, c
+ cp 7
+ ret z
+ xor a
+ ldh [hBGMapMode], a
+ ldh [hBGMapThird], a
+ ld d, $0
+ push bc
+ push hl
+
+.inner_loop
+ call .CopyColumn
+ inc hl
+ ld a, 7
+ add d
+ ld d, a
+ dec c
+ jr nz, .inner_loop
+
+ ld a, $1
+ ldh [hBGMapMode], a
+ ld c, 4
+ call DelayFrames
+ pop hl
+ pop bc
+ dec hl
+ jr .outer_loop
+
+.CopyColumn:
+ push hl
+ push de
+ push bc
+ ld e, 7
+
+.loop
+ ld [hl], d
+ ld bc, SCREEN_WIDTH
+ add hl, bc
+ inc d
+ dec e
+ jr nz, .loop
+
+ pop bc
+ pop de
+ pop hl
+ ret
+
+ApplyStatusEffectOnPlayerStats:
+ ld a, 1
+ jr ApplyStatusEffectOnStats
+
+ApplyStatusEffectOnEnemyStats:
+ xor a
+
+ApplyStatusEffectOnStats:
+ ldh [hBattleTurn], a
+ call ApplyPrzEffectOnSpeed
+ jp ApplyBrnEffectOnAttack
+
+ApplyPrzEffectOnSpeed:
+ ldh a, [hBattleTurn]
+ and a
+ jr z, .enemy
+ ld a, [wBattleMonStatus]
+ and 1 << PAR
+ ret z
+ ld hl, wBattleMonSpeed + 1
+ ld a, [hld]
+ ld b, a
+ ld a, [hl]
+ srl a
+ rr b
+ srl a
+ rr b
+ ld [hli], a
+ or b
+ jr nz, .player_ok
+ ld b, $1 ; min speed
+
+.player_ok
+ ld [hl], b
+ ret
+
+.enemy
+ ld a, [wEnemyMonStatus]
+ and 1 << PAR
+ ret z
+ ld hl, wEnemyMonSpeed + 1
+ ld a, [hld]
+ ld b, a
+ ld a, [hl]
+ srl a
+ rr b
+ srl a
+ rr b
+ ld [hli], a
+ or b
+ jr nz, .enemy_ok
+ ld b, $1 ; min speed
+
+.enemy_ok
+ ld [hl], b
+ ret
+
+ApplyBrnEffectOnAttack:
+ ldh a, [hBattleTurn]
+ and a
+ jr z, .enemy
+ ld a, [wBattleMonStatus]
+ and 1 << BRN
+ ret z
+ ld hl, wBattleMonAttack + 1
+ ld a, [hld]
+ ld b, a
+ ld a, [hl]
+ srl a
+ rr b
+ ld [hli], a
+ or b
+ jr nz, .player_ok
+ ld b, $1 ; min attack
+
+.player_ok
+ ld [hl], b
+ ret
+
+.enemy
+ ld a, [wEnemyMonStatus]
+ and 1 << BRN
+ ret z
+ ld hl, wEnemyMonAttack + 1
+ ld a, [hld]
+ ld b, a
+ ld a, [hl]
+ srl a
+ rr b
+ ld [hli], a
+ or b
+ jr nz, .enemy_ok
+ ld b, $1 ; min attack
+
+.enemy_ok
+ ld [hl], b
+ ret
+
+ApplyStatLevelMultiplierOnAllStats:
+; Apply StatLevelMultipliers on all 5 Stats
+ ld c, 0
+.stat_loop
+ call ApplyStatLevelMultiplier
+ inc c
+ ld a, c
+ cp NUM_BATTLE_STATS
+ jr nz, .stat_loop
+ ret
+
+ApplyStatLevelMultiplier:
+ push bc
+ push bc
+ ld a, [wApplyStatLevelMultipliersToEnemy]
+ and a
+ ld a, c
+ ld hl, wBattleMonAttack
+ ld de, wPlayerStats
+ ld bc, wPlayerAtkLevel
+ jr z, .got_pointers
+ ld hl, wEnemyMonAttack
+ ld de, wEnemyStats
+ ld bc, wEnemyAtkLevel
+
+.got_pointers
+ add c
+ ld c, a
+ jr nc, .okay
+ inc b
+.okay
+ ld a, [bc]
+ pop bc
+ ld b, a
+ push bc
+ sla c
+ ld b, 0
+ add hl, bc
+ ld a, c
+ add e
+ ld e, a
+ jr nc, .okay2
+ inc d
+.okay2
+ pop bc
+ push hl
+ ld hl, StatLevelMultipliers_Applied
+ dec b
+ sla b
+ ld c, b
+ ld b, 0
+ add hl, bc
+ xor a
+ ldh [hMultiplicand + 0], a
+ ld a, [de]
+ ldh [hMultiplicand + 1], a
+ inc de
+ ld a, [de]
+ ldh [hMultiplicand + 2], a
+ ld a, [hli]
+ ldh [hMultiplier], a
+ call Multiply
+ ld a, [hl]
+ ldh [hDivisor], a
+ ld b, 4
+ call Divide
+ pop hl
+
+; Cap at 999.
+ ldh a, [hQuotient + 3]
+ sub LOW(MAX_STAT_VALUE)
+ ldh a, [hQuotient + 2]
+ sbc HIGH(MAX_STAT_VALUE)
+ jp c, .okay3
+
+ ld a, HIGH(MAX_STAT_VALUE)
+ ldh [hQuotient + 2], a
+ ld a, LOW(MAX_STAT_VALUE)
+ ldh [hQuotient + 3], a
+
+.okay3
+ ldh a, [hQuotient + 2]
+ ld [hli], a
+ ld b, a
+ ldh a, [hQuotient + 3]
+ ld [hl], a
+ or b
+ jr nz, .okay4
+ inc [hl]
+
+.okay4
+ pop bc
+ ret
+
+INCLUDE "data/battle/stat_multipliers_2.asm"
+
+BadgeStatBoosts:
+; Raise the stats of the battle mon in wBattleMon
+; depending on which badges have been obtained.
+
+; Every other badge boosts a stat, starting from the first.
+; GlacierBadge also boosts Special Defense, although the relevant code is buggy (see below).
+
+; ZephyrBadge: Attack
+; PlainBadge: Speed
+; MineralBadge: Defense
+; GlacierBadge: Special Attack and Special Defense
+
+; The boosted stats are in order, except PlainBadge and MineralBadge's boosts are swapped.
+
+ ld a, [wLinkMode]
+ and a
+ ret nz
+
+ ld a, [wJohtoBadges]
+
+; Swap badges 3 (PlainBadge) and 5 (MineralBadge).
+ ld d, a
+ and (1 << PLAINBADGE)
+ add a
+ add a
+ ld b, a
+ ld a, d
+ and (1 << MINERALBADGE)
+ rrca
+ rrca
+ ld c, a
+ ld a, d
+ and ((1 << ZEPHYRBADGE) | (1 << HIVEBADGE) | (1 << FOGBADGE) | (1 << STORMBADGE) | (1 << GLACIERBADGE) | (1 << RISINGBADGE))
+ or b
+ or c
+ ld b, a
+
+ ld hl, wBattleMonAttack
+ ld c, 4
+.CheckBadge:
+ ld a, b
+ srl b
+ call c, BoostStat
+ inc hl
+ inc hl
+; Check every other badge.
+ srl b
+ dec c
+ jr nz, .CheckBadge
+; Check GlacierBadge again for Special Defense.
+; This check is buggy because it assumes that a is set by the "ld a, b" in the above loop,
+; but it can actually be overwritten by the call to BoostStat.
+ srl a
+ call c, BoostStat
+ ret
+
+BoostStat:
+; Raise stat at hl by 1/8.
+
+ ld a, [hli]
+ ld d, a
+ ld e, [hl]
+ srl d
+ rr e
+ srl d
+ rr e
+ srl d
+ rr e
+ ld a, [hl]
+ add e
+ ld [hld], a
+ ld a, [hl]
+ adc d
+ ld [hli], a
+
+; Cap at 999.
+ ld a, [hld]
+ sub LOW(MAX_STAT_VALUE)
+ ld a, [hl]
+ sbc HIGH(MAX_STAT_VALUE)
+ ret c
+ ld a, HIGH(MAX_STAT_VALUE)
+ ld [hli], a
+ ld a, LOW(MAX_STAT_VALUE)
+ ld [hld], a
+ ret
+
+_LoadBattleFontsHPBar:
+ callfar LoadBattleFontsHPBar
+ ret
+
+_LoadHPBar:
+ callfar LoadHPBar
+ ret
+
+Unreferenced_LoadHPExpBarGFX:
+ ld de, EnemyHPBarBorderGFX
+ ld hl, vTiles2 tile $6c
+ lb bc, BANK(EnemyHPBarBorderGFX), 4
+ call Get1bpp
+ ld de, HPExpBarBorderGFX
+ ld hl, vTiles2 tile $73
+ lb bc, BANK(HPExpBarBorderGFX), 6
+ call Get1bpp
+ ld de, ExpBarGFX
+ ld hl, vTiles2 tile $55
+ lb bc, BANK(ExpBarGFX), 8
+ jp Get2bpp
+
+EmptyBattleTextbox:
+ ld hl, .empty
+ jp PrintText
+
+.empty:
+ text_end
+
+_BattleRandom::
+; If the normal RNG is used in a link battle it'll desync.
+; To circumvent this a shared PRNG is used instead.
+
+; But if we're in a non-link battle we're safe to use it
+ ld a, [wLinkMode]
+ and a
+ jp z, Random
+
+; The PRNG operates in streams of 10 values.
+
+; Which value are we trying to pull?
+ push hl
+ push bc
+ ld a, [wLinkBattleRNCount]
+ ld c, a
+ ld b, 0
+ ld hl, wLinkBattleRNs
+ add hl, bc
+ inc a
+ ld [wLinkBattleRNCount], a
+
+; If we haven't hit the end yet, we're good
+ cp 10 - 1 ; Exclude last value. See the closing comment
+ ld a, [hl]
+ pop bc
+ pop hl
+ ret c
+
+; If we have, we have to generate new pseudorandom data
+; Instead of having multiple PRNGs, ten seeds are used
+ push hl
+ push bc
+ push af
+
+; Reset count to 0
+ xor a
+ ld [wLinkBattleRNCount], a
+ ld hl, wLinkBattleRNs
+ ld b, 10 ; number of seeds
+
+; Generate next number in the sequence for each seed
+; a[n+1] = (a[n] * 5 + 1) % 256
+.loop
+ ; get last #
+ ld a, [hl]
+
+ ; a * 5 + 1
+ ld c, a
+ add a
+ add a
+ add c
+ inc a
+
+ ; update #
+ ld [hli], a
+ dec b
+ jr nz, .loop
+
+; This has the side effect of pulling the last value first,
+; then wrapping around. As a result, when we check to see if
+; we've reached the end, we check the one before it.
+
+ pop af
+ pop bc
+ pop hl
+ ret
+
+Call_PlayBattleAnim_OnlyIfVisible:
+ ld a, BATTLE_VARS_SUBSTATUS3
+ call GetBattleVar
+ and 1 << SUBSTATUS_FLYING | 1 << SUBSTATUS_UNDERGROUND
+ ret nz
+
+Call_PlayBattleAnim:
+ ld a, e
+ ld [wFXAnimID], a
+ ld a, d
+ ld [wFXAnimID + 1], a
+ call WaitBGMap
+ predef_jump PlayBattleAnim
+
+FinishBattleAnim:
+ push af
+ push bc
+ push de
+ push hl
+ ld b, SCGB_BATTLE_COLORS
+ call GetSGBLayout
+ call SetPalettes
+ call DelayFrame
+ pop hl
+ pop de
+ pop bc
+ pop af
+ ret
+
+GiveExperiencePoints:
+; Give experience.
+; Don't give experience if linked or in the Battle Tower.
+ ld a, [wLinkMode]
+ and a
+ ret nz
+
+ call .EvenlyDivideExpAmongParticipants
+ xor a
+ ld [wCurPartyMon], a
+ ld bc, wPartyMon1Species
+
+.loop
+ ld hl, MON_HP
+ add hl, bc
+ ld a, [hli]
+ or [hl]
+ jp z, .next_mon ; fainted
+
+ push bc
+ ld hl, wBattleParticipantsNotFainted
+ ld a, [wCurPartyMon]
+ ld c, a
+ ld b, CHECK_FLAG
+ ld d, 0
+ predef SmallFarFlagAction
+ ld a, c
+ and a
+ pop bc
+ jp z, .next_mon
+
+; give stat exp
+ ld hl, MON_STAT_EXP + 1
+ add hl, bc
+ ld d, h
+ ld e, l
+ ld hl, wEnemyMonBaseStats - 1
+ push bc
+ ld c, NUM_EXP_STATS
+.stat_exp_loop
+ inc hl
+ ld a, [de]
+ add [hl]
+ ld [de], a
+ jr nc, .no_carry_stat_exp
+ dec de
+ ld a, [de]
+ inc a
+ jr z, .stat_exp_maxed_out
+ ld [de], a
+ inc de
+
+.no_carry_stat_exp
+ push hl
+ push bc
+ ld a, MON_PKRUS
+ call GetPartyParamLocation
+ ld a, [hl]
+ and a
+ pop bc
+ pop hl
+ jr z, .stat_exp_awarded
+ ld a, [de]
+ add [hl]
+ ld [de], a
+ jr nc, .stat_exp_awarded
+ dec de
+ ld a, [de]
+ inc a
+ jr z, .stat_exp_maxed_out
+ ld [de], a
+ inc de
+ jr .stat_exp_awarded
+
+.stat_exp_maxed_out
+ ld a, $ff
+ ld [de], a
+ inc de
+ ld [de], a
+
+.stat_exp_awarded
+ inc de
+ inc de
+ dec c
+ jr nz, .stat_exp_loop
+ xor a
+ ldh [hMultiplicand + 0], a
+ ldh [hMultiplicand + 1], a
+ ld a, [wEnemyMonBaseExp]
+ ldh [hMultiplicand + 2], a
+ ld a, [wEnemyMonLevel]
+ ldh [hMultiplier], a
+ call Multiply
+ ld a, 7
+ ldh [hDivisor], a
+ ld b, 4
+ call Divide
+; Boost Experience for traded Pokemon
+ pop bc
+ ld hl, MON_ID
+ add hl, bc
+ ld a, [wPlayerID]
+ cp [hl]
+ jr nz, .boosted
+ inc hl
+ ld a, [wPlayerID + 1]
+ cp [hl]
+ ld a, 0
+ jr z, .no_boost
+
+.boosted
+ call BoostExp
+ ld a, 1
+
+.no_boost
+; Boost experience for a Trainer Battle
+ ld [wStringBuffer2 + 2], a
+ ld a, [wBattleMode]
+ dec a
+ call nz, BoostExp
+; Boost experience for Lucky Egg
+ push bc
+ ld a, MON_ITEM
+ call GetPartyParamLocation
+ ld a, [hl]
+ cp LUCKY_EGG
+ call z, BoostExp
+ ldh a, [hQuotient + 3]
+ ld [wStringBuffer2 + 1], a
+ ldh a, [hQuotient + 2]
+ ld [wStringBuffer2], a
+ ld a, [wCurPartyMon]
+ ld hl, wPartyMonNicknames
+ call GetNick
+ ld hl, Text_MonGainedExpPoint
+ call PrintText
+ ld a, [wStringBuffer2 + 1]
+ ldh [hQuotient + 3], a
+ ld a, [wStringBuffer2]
+ ldh [hQuotient + 2], a
+ pop bc
+ call AnimateExpBar
+ push bc
+ call LoadTilemapToTempTilemap
+ pop bc
+ ld hl, MON_EXP + 2
+ add hl, bc
+ ld d, [hl]
+ ldh a, [hQuotient + 3]
+ add d
+ ld [hld], a
+ ld d, [hl]
+ ldh a, [hQuotient + 2]
+ adc d
+ ld [hl], a
+ jr nc, .no_exp_overflow
+ dec hl
+ inc [hl]
+
+.no_exp_overflow
+ ld a, [wCurPartyMon]
+ ld e, a
+ ld d, 0
+ ld hl, wPartySpecies
+ add hl, de
+ ld a, [hl]
+ ld [wCurSpecies], a
+ call GetBaseData
+ push bc
+ ld d, MAX_LEVEL
+ callfar CalcExpAtLevel
+ pop bc
+ ld hl, MON_EXP + 2
+ add hl, bc
+ push bc
+ ldh a, [hQuotient + 1]
+ ld b, a
+ ldh a, [hQuotient + 2]
+ ld c, a
+ ldh a, [hQuotient + 3]
+ ld d, a
+ ld a, [hld]
+ sub d
+ ld a, [hld]
+ sbc c
+ ld a, [hl]
+ sbc b
+ jr c, .not_max_exp
+ ld a, b
+ ld [hli], a
+ ld a, c
+ ld [hli], a
+ ld a, d
+ ld [hld], a
+
+.not_max_exp
+; Check if the mon leveled up
+ xor a ; PARTYMON
+ ld [wMonType], a
+ predef CopyMonToTempMon
+ callfar CalcLevel
+ pop bc
+ ld hl, MON_LEVEL
+ add hl, bc
+ ld a, [hl]
+ cp d
+ jp z, .next_mon
+; <NICKNAME> grew to level ##!
+ ld [wTempLevel], a
+ ld a, [wCurPartyLevel]
+ push af
+ ld a, d
+ ld [wCurPartyLevel], a
+ ld [hl], a
+ ld hl, MON_SPECIES
+ add hl, bc
+ ld a, [hl]
+ ld [wCurSpecies], a
+ ld [wTempSpecies], a ; unused?
+ call GetBaseData
+ ld hl, MON_MAXHP + 1
+ add hl, bc
+ ld a, [hld]
+ ld e, a
+ ld d, [hl]
+ push de
+ ld hl, MON_MAXHP
+ add hl, bc
+ ld d, h
+ ld e, l
+ ld hl, MON_STAT_EXP - 1
+ add hl, bc
+ push bc
+ ld b, TRUE
+ predef CalcMonStats
+ pop bc
+ pop de
+ ld hl, MON_MAXHP + 1
+ add hl, bc
+ ld a, [hld]
+ sub e
+ ld e, a
+ ld a, [hl]
+ sbc d
+ ld d, a
+ dec hl
+ ld a, [hl]
+ add e
+ ld [hld], a
+ ld a, [hl]
+ adc d
+ ld [hl], a
+ ld a, [wCurBattleMon]
+ ld d, a
+ ld a, [wCurPartyMon]
+ cp d
+ jr nz, .skip_active_mon_update
+ ld de, wBattleMonHP
+ ld a, [hli]
+ ld [de], a
+ inc de
+ ld a, [hli]
+ ld [de], a
+ ld de, wBattleMonMaxHP
+ push bc
+ ld bc, PARTYMON_STRUCT_LENGTH - MON_MAXHP
+ call CopyBytes
+ pop bc
+ ld hl, MON_LEVEL
+ add hl, bc
+ ld a, [hl]
+ ld [wBattleMonLevel], a
+ ld a, [wPlayerSubStatus5]
+ bit SUBSTATUS_TRANSFORMED, a
+ jr nz, .transformed
+ ld hl, MON_ATK
+ add hl, bc
+ ld de, wPlayerStats
+ ld bc, PARTYMON_STRUCT_LENGTH - MON_ATK
+ call CopyBytes
+
+.transformed
+ xor a ; FALSE
+ ld [wApplyStatLevelMultipliersToEnemy], a
+ call ApplyStatLevelMultiplierOnAllStats
+ callfar ApplyStatusEffectOnPlayerStats
+ callfar BadgeStatBoosts
+ callfar UpdatePlayerHUD
+ call EmptyBattleTextbox
+ call LoadTilemapToTempTilemap
+ ld a, $1
+ ldh [hBGMapMode], a
+
+.skip_active_mon_update
+ ; level up happiness mod
+ ld c, 1
+ callfar ChangeHappiness
+ ld a, [wCurBattleMon]
+ ld b, a
+ ld a, [wCurPartyMon]
+ cp b
+ jr z, .skip_exp_bar_animation
+ ld de, SFX_HIT_END_OF_EXP_BAR
+ call PlaySFX
+ call WaitSFX
+ ld hl, BattleText_StringBuffer1GrewToLevel
+ call StdBattleTextbox
+ call LoadTilemapToTempTilemap
+
+.skip_exp_bar_animation
+ xor a ; PARTYMON
+ ld [wMonType], a
+ predef CopyMonToTempMon
+ hlcoord 9, 0
+ ld b, 10
+ ld c, 9
+ call Textbox
+ hlcoord 11, 1
+ ld bc, 4
+ predef PrintTempMonStats
+ ld c, 30
+ call DelayFrames
+ call WaitPressAorB_BlinkCursor
+ call SafeLoadTempTilemapToTilemap
+ xor a ; PARTYMON
+ ld [wMonType], a
+ ld a, [wCurSpecies]
+ ld [wTempSpecies], a ; unused?
+ ld a, [wCurPartyLevel]
+ push af
+ ld c, a
+ ld a, [wTempLevel]
+ ld b, a
+
+.level_loop
+ inc b
+ ld a, b
+ ld [wCurPartyLevel], a
+ push bc
+ predef LearnLevelMoves
+ pop bc
+ ld a, b
+ cp c
+ jr nz, .level_loop
+ pop af
+ ld [wCurPartyLevel], a
+ ld hl, wEvolvableFlags
+ ld a, [wCurPartyMon]
+ ld c, a
+ ld b, SET_FLAG
+ predef SmallFarFlagAction
+ pop af
+ ld [wCurPartyLevel], a
+
+.next_mon
+ ld a, [wPartyCount]
+ ld b, a
+ ld a, [wCurPartyMon]
+ inc a
+ cp b
+ jr z, .done
+ ld [wCurPartyMon], a
+ ld a, MON_SPECIES
+ call GetPartyParamLocation
+ ld b, h
+ ld c, l
+ jp .loop
+
+.done
+ jp ResetBattleParticipants
+
+.EvenlyDivideExpAmongParticipants:
+; count number of battle participants
+ ld a, [wBattleParticipantsNotFainted]
+ ld b, a
+ ld c, PARTY_LENGTH
+ ld d, 0
+.count_loop
+ xor a
+ srl b
+ adc d
+ ld d, a
+ dec c
+ jr nz, .count_loop
+ cp 2
+ ret c
+
+ ld [wTempByteValue], a
+ ld hl, wEnemyMonBaseStats
+ ld c, wEnemyMonEnd - wEnemyMonBaseStats
+.base_stat_division_loop
+ xor a
+ ldh [hDividend + 0], a
+ ld a, [hl]
+ ldh [hDividend + 1], a
+ ld a, [wTempByteValue]
+ ldh [hDivisor], a
+ ld b, 2
+ call Divide
+ ldh a, [hQuotient + 3]
+ ld [hli], a
+ dec c
+ jr nz, .base_stat_division_loop
+ ret
+
+BoostExp:
+; Multiply experience by 1.5x
+ push bc
+; load experience value
+ ldh a, [hProduct + 2]
+ ld b, a
+ ldh a, [hProduct + 3]
+ ld c, a
+; halve it
+ srl b
+ rr c
+; add it back to the whole exp value
+ add c
+ ldh [hProduct + 3], a
+ ldh a, [hProduct + 2]
+ adc b
+ ldh [hProduct + 2], a
+ pop bc
+ ret
+
+Text_MonGainedExpPoint:
+ text_far Text_Gained
+ text_asm
+ ld hl, ExpPointsText
+ ld a, [wStringBuffer2 + 2] ; IsTradedMon
+ and a
+ ret z
+
+ ld hl, BoostedExpPointsText
+ ret
+
+BoostedExpPointsText:
+ text_far _BoostedExpPointsText
+ text_end
+
+ExpPointsText:
+ text_far _ExpPointsText
+ text_end
+
+AnimateExpBar:
+ push bc
+
+ ld hl, wCurPartyMon
+ ld a, [wCurBattleMon]
+ cp [hl]
+ jp nz, .finish
+
+ ld a, [wBattleMonLevel]
+ cp MAX_LEVEL
+ jp z, .finish
+
+ ldh a, [hProduct + 3]
+ ld [wceef], a
+ push af
+ ldh a, [hProduct + 2]
+ ld [wceee], a
+ push af
+ xor a
+ ld [wceed], a
+ xor a ; PARTYMON
+ ld [wMonType], a
+ predef CopyMonToTempMon
+ ld a, [wTempMonLevel]
+ ld b, a
+ ld e, a
+ push de
+ ld de, wTempMonExp + 2
+ call CalcExpBar
+ push bc
+ ld hl, wTempMonExp + 2
+ ld a, [wceef]
+ add [hl]
+ ld [hld], a
+ ld a, [wceee]
+ adc [hl]
+ ld [hld], a
+ jr nc, .NoOverflow
+ inc [hl]
+
+.NoOverflow:
+ ld d, MAX_LEVEL
+ callfar CalcExpAtLevel
+ ldh a, [hProduct + 1]
+ ld b, a
+ ldh a, [hProduct + 2]
+ ld c, a
+ ldh a, [hProduct + 3]
+ ld d, a
+ ld hl, wTempMonExp + 2
+ ld a, [hld]
+ sub d
+ ld a, [hld]
+ sbc c
+ ld a, [hl]
+ sbc b
+ jr c, .AlreadyAtMaxExp
+ ld a, b
+ ld [hli], a
+ ld a, c
+ ld [hli], a
+ ld a, d
+ ld [hld], a
+
+.AlreadyAtMaxExp:
+ callfar CalcLevel
+ ld a, d
+ pop bc
+ pop de
+ ld d, a
+
+.LoopLevels:
+ ld a, e
+ cp d
+ jr z, .FinishExpBar
+ inc a
+ ld [wTempMonLevel], a
+ ld [wCurPartyLevel], a
+ ld [wBattleMonLevel], a
+ push de
+ call .PlayExpBarSound
+ ld c, $40
+ call .LoopBarAnimation
+ call PrintPlayerHUD
+ ld hl, wBattleMonNick
+ ld de, wStringBuffer1
+ ld bc, MON_NAME_LENGTH
+ call CopyBytes
+ call TerminateExpBarSound
+ ld de, SFX_HIT_END_OF_EXP_BAR
+ call PlaySFX
+ farcall AnimateEndOfExpBar
+ call WaitSFX
+ ld hl, BattleText_StringBuffer1GrewToLevel
+ call StdBattleTextbox
+ pop de
+ inc e
+ ld b, $0
+ jr .LoopLevels
+
+.FinishExpBar:
+ push bc
+ ld b, d
+ ld de, wTempMonExp + 2
+ call CalcExpBar
+ ld a, b
+ pop bc
+ ld c, a
+ call .PlayExpBarSound
+ call .LoopBarAnimation
+ call TerminateExpBarSound
+ pop af
+ ldh [hProduct + 2], a
+ pop af
+ ldh [hProduct + 3], a
+
+.finish
+ pop bc
+ ret
+
+.PlayExpBarSound:
+ push bc
+ call WaitSFX
+ ld de, SFX_EXP_BAR
+ call PlaySFX
+ ld c, 10
+ call DelayFrames
+ pop bc
+ ret
+
+.LoopBarAnimation:
+ ld d, 3
+ dec b
+.anim_loop
+ inc b
+ push bc
+ push de
+ hlcoord 17, 11
+ call PlaceExpBar
+ pop de
+ ld a, $1
+ ldh [hBGMapMode], a
+ ld c, d
+ call DelayFrames
+ xor a
+ ldh [hBGMapMode], a
+ pop bc
+ ld a, c
+ cp b
+ jr z, .end_animation
+ inc b
+ push bc
+ push de
+ hlcoord 17, 11
+ call PlaceExpBar
+ pop de
+ ld a, $1
+ ldh [hBGMapMode], a
+ ld c, d
+ call DelayFrames
+ xor a
+ ldh [hBGMapMode], a
+ dec d
+ jr nz, .min_number_of_frames
+ ld d, 1
+.min_number_of_frames
+ pop bc
+ ld a, c
+ cp b
+ jr nz, .anim_loop
+.end_animation
+ ld a, $1
+ ldh [hBGMapMode], a
+ ret
+
+SendOutMonText:
+ ld a, [wLinkMode]
+ and a
+ jr z, .not_linked
+
+ ld hl, JumpText_GoMon ; If we're in a LinkBattle print just "Go <PlayerMon>"
+
+ ld a, [wBattleHasJustStarted] ; unless this (unidentified) variable is set
+ and a
+ jr nz, .skip_to_textbox
+
+.not_linked
+; Depending on the HP of the enemy mon, the game prints a different text
+ ld hl, wEnemyMonHP
+ ld a, [hli]
+ or [hl]
+ ld hl, JumpText_GoMon
+ jr z, .skip_to_textbox
+
+ ; compute enemy helth remaining as a percentage
+ xor a
+ ldh [hMultiplicand + 0], a
+ ld hl, wEnemyMonHP
+ ld a, [hli]
+ ld [wEnemyHPAtTimeOfPlayerSwitch], a
+ ldh [hMultiplicand + 1], a
+ ld a, [hl]
+ ld [wEnemyHPAtTimeOfPlayerSwitch + 1], a
+ ldh [hMultiplicand + 2], a
+ ld a, 25
+ ldh [hMultiplier], a
+ call Multiply
+ ld hl, wEnemyMonMaxHP
+ ld a, [hli]
+ ld b, [hl]
+ srl a
+ rr b
+ srl a
+ rr b
+ ld a, b
+ ld b, 4
+ ldh [hDivisor], a
+ call Divide
+
+ ldh a, [hQuotient + 3]
+ ld hl, JumpText_GoMon
+ cp 70
+ jr nc, .skip_to_textbox
+
+ ld hl, JumpText_DoItMon
+ cp 40
+ jr nc, .skip_to_textbox
+
+ ld hl, JumpText_GoForItMon
+ cp 10
+ jr nc, .skip_to_textbox
+
+ ld hl, JumpText_YourFoesWeakGetmMon
+.skip_to_textbox
+ jp PrintText
+
+JumpText_GoMon:
+ text_far Text_GoMon
+ text_end
+
+JumpText_DoItMon:
+ text_far Text_DoItMon
+ text_end
+
+JumpText_GoForItMon:
+ text_far Text_GoForItMon
+ text_end
+
+JumpText_YourFoesWeakGetmMon:
+ text_far Text_YourFoesWeakGetmMon
+ text_end
+
+WithdrawMonText:
+ ld hl, .WithdrawMonText
+ jp PrintText
+
+.WithdrawMonText:
+ text_far Text_BattleMonNickComma
+ text_asm
+; Print text to withdraw mon
+; depending on HP the message is different
+ push de
+ push bc
+ ld hl, wEnemyMonHP + 1
+ ld de, wEnemyHPAtTimeOfPlayerSwitch + 1
+ ld b, [hl]
+ dec hl
+ ld a, [de]
+ sub b
+ ldh [hMultiplicand + 2], a
+ dec de
+ ld b, [hl]
+ ld a, [de]
+ sbc b
+ ldh [hMultiplicand + 1], a
+ ld a, 25
+ ldh [hMultiplier], a
+ call Multiply
+ ld hl, wEnemyMonMaxHP
+ ld a, [hli]
+ ld b, [hl]
+ srl a
+ rr b
+ srl a
+ rr b
+ ld a, b
+ ld b, 4
+ ldh [hDivisor], a
+ call Divide
+ pop bc
+ pop de
+ ldh a, [hQuotient + 3]
+ ld hl, ThatsEnoughComeBackText
+ and a
+ ret z
+
+ ld hl, ComeBackText
+ cp 30
+ ret c
+
+ ld hl, OKComeBackText
+ cp 70
+ ret c
+
+ ld hl, GoodComeBackText
+ ret
+
+ThatsEnoughComeBackText:
+ text_far _ThatsEnoughComeBackText
+ text_end
+
+OKComeBackText:
+ text_far _OKComeBackText
+ text_end
+
+GoodComeBackText:
+ text_far _GoodComeBackText
+ text_end
+
+ComeBackText:
+ text_far _ComeBackText
+ text_end
+
+Unreferenced_HandleSafariAngerEatingStatus:
+ ld hl, wSafariMonEating
+ ld a, [hl]
+ and a
+ jr z, .angry
+ dec [hl]
+ ld hl, BattleText_WildMonIsEating
+ jr .finish
+
+.angry
+ dec hl ; wSafariMonAngerCount
+ ld a, [hl]
+ and a
+ ret z
+ dec [hl]
+ ld hl, BattleText_WildMonIsAngry
+ jr nz, .finish
+ push hl
+ ld a, [wEnemyMonSpecies]
+ ld [wCurSpecies], a
+ call GetBaseData
+ ld a, [wBaseCatchRate]
+ ld [wEnemyMonCatchRate], a
+ pop hl
+
+.finish
+ push hl
+ call SafeLoadTempTilemapToTilemap
+ pop hl
+ jp StdBattleTextbox
+
+FillInExpBar:
+ push hl
+ call CalcExpBar
+ pop hl
+ ld de, 7
+ add hl, de
+ jp PlaceExpBar
+
+CalcExpBar:
+; Calculate the percent exp between this level and the next
+; Level in b
+ push de
+ ld d, b
+ push de
+ callfar CalcExpAtLevel
+ pop de
+; exp at current level gets pushed to the stack
+ ld hl, hMultiplicand
+ ld a, [hli]
+ push af
+ ld a, [hli]
+ push af
+ ld a, [hl]
+ push af
+; next level
+ inc d
+ callfar CalcExpAtLevel
+; back up the next level exp, and subtract the two levels
+ ld hl, hMultiplicand + 2
+ ld a, [hl]
+ ldh [hMathBuffer + 2], a
+ pop bc
+ sub b
+ ld [hld], a
+ ld a, [hl]
+ ldh [hMathBuffer + 1], a
+ pop bc
+ sbc b
+ ld [hld], a
+ ld a, [hl]
+ ldh [hMathBuffer], a
+ pop bc
+ sbc b
+ ld [hl], a
+ pop de
+
+ ld hl, hMultiplicand + 1
+ ld a, [hli]
+ push af
+ ld a, [hl]
+ push af
+
+; get the amount of exp remaining to the next level
+ ld a, [de]
+ dec de
+ ld c, a
+ ldh a, [hMathBuffer + 2]
+ sub c
+ ld [hld], a
+ ld a, [de]
+ dec de
+ ld b, a
+ ldh a, [hMathBuffer + 1]
+ sbc b
+ ld [hld], a
+ ld a, [de]
+ ld c, a
+ ldh a, [hMathBuffer]
+ sbc c
+ ld [hld], a
+ xor a
+ ld [hl], a
+ ld a, 64
+ ldh [hMultiplier], a
+ call Multiply
+ pop af
+ ld c, a
+ pop af
+ ld b, a
+.loop
+ ld a, b
+ and a
+ jr z, .done
+ srl b
+ rr c
+ ld hl, hProduct
+ srl [hl]
+ inc hl
+ rr [hl]
+ inc hl
+ rr [hl]
+ inc hl
+ rr [hl]
+ jr .loop
+
+.done
+ ld a, c
+ ldh [hDivisor], a
+ ld b, 4
+ call Divide
+ ldh a, [hQuotient + 3]
+ ld b, a
+ ld a, $40
+ sub b
+ ld b, a
+ ret
+
+PlaceExpBar:
+ ld c, $8 ; number of tiles
+.loop1
+ ld a, b
+ sub $8
+ jr c, .next
+ ld b, a
+ ld a, $6a ; full bar
+ ld [hld], a
+ dec c
+ jr z, .finish
+ jr .loop1
+
+.next
+ add $8
+ jr z, .loop2
+ add $54 ; tile to the left of small exp bar tile
+ jr .skip
+
+.loop2
+ ld a, $62 ; empty bar
+
+.skip
+ ld [hld], a
+ ld a, $62 ; empty bar
+ dec c
+ jr nz, .loop2
+
+.finish
+ ret
+
+GetBattleMonBackpic:
+ ld a, [wPlayerSubStatus4]
+ bit SUBSTATUS_SUBSTITUTE, a
+ ld hl, BattleAnimCmd_RaiseSub
+ jr nz, GetBattleMonBackpic_DoAnim ; substitute
+
+DropPlayerSub:
+ ld a, [wPlayerMinimized]
+ and a
+ ld hl, BattleAnimCmd_MinimizeOpp
+ jr nz, GetBattleMonBackpic_DoAnim
+ ld a, [wCurPartySpecies]
+ push af
+ ld a, [wBattleMonSpecies]
+ ld [wCurPartySpecies], a
+ ld hl, wBattleMonDVs
+ predef GetUnownLetter
+ ld de, vTiles2 tile $31
+ predef GetMonBackpic
+ pop af
+ ld [wCurPartySpecies], a
+ ret
+
+GetBattleMonBackpic_DoAnim:
+ ldh a, [hBattleTurn]
+ push af
+ xor a
+ ldh [hBattleTurn], a
+ ld a, BANK("Move Animations")
+ rst FarCall
+ pop af
+ ldh [hBattleTurn], a
+ ret
+
+GetEnemyMonFrontpic:
+ ld a, [wEnemySubStatus4]
+ bit SUBSTATUS_SUBSTITUTE, a
+ ld hl, BattleAnimCmd_RaiseSub
+ jr nz, GetEnemyMonFrontpic_DoAnim
+
+DropEnemySub:
+ ld a, [wEnemyMinimized]
+ and a
+ ld hl, BattleAnimCmd_MinimizeOpp
+ jr nz, GetEnemyMonFrontpic_DoAnim
+
+ ld a, [wCurPartySpecies]
+ push af
+ ld a, [wEnemyMonSpecies]
+ ld [wCurSpecies], a
+ ld [wCurPartySpecies], a
+ call GetBaseData
+ ld hl, wEnemyMonDVs
+ predef GetUnownLetter
+ ld de, vTiles2
+ predef GetMonFrontpic
+ pop af
+ ld [wCurPartySpecies], a
+ ret
+
+GetEnemyMonFrontpic_DoAnim:
+ ldh a, [hBattleTurn]
+ push af
+ call SetEnemyTurn
+ ld a, BANK(BattleAnimCmd_MinimizeOpp)
+ rst FarCall
+ pop af
+ ldh [hBattleTurn], a
+ ret
+
+StartBattle:
+; This check prevents you from entering a battle without any Pokemon.
+; Those using walk-through-walls to bypass getting a Pokemon experience
+; the effects of this check.
+ ld a, [wPartyCount]
+ and a
+ ret z
+
+ ld a, [wOtherTrainerClass]
+ and a
+ jr nz, .battle_intro
+
+ ld a, [wTempWildMonSpecies]
+ ld [wCurPartySpecies], a
+
+.battle_intro
+ ld [wTempEnemyMonSpecies], a
+ ld a, [wTimeOfDayPal]
+ push af
+ xor a
+ ldh [hMapAnims], a
+ xor a
+ ld [wTempBattleMonSpecies], a
+ ld [wBattleMenuCursorBuffer], a
+ farcall PlayBattleMusic
+ ld a, 0
+ ld [wSpriteUpdatesEnabled], a
+ call ShowLinkBattleParticipants
+ farcall ClearBattleRAM
+ ld hl, rLCDC
+ res rLCDC_WINDOW_TILEMAP, [hl] ; select 9800-9BFF
+ ld a, [wOtherTrainerClass]
+ and a
+ jr nz, .trainer
+
+ call InitEnemyWildmon
+ jr .back_up_bgmap2
+
+.trainer
+ call InitEnemyTrainer
+
+.back_up_bgmap2
+ ld b, 0
+ call GetSGBLayout
+ ld hl, wVramState
+ res 0, [hl]
+ call InitBattleDisplay
+ call BattleStartMessage
+ xor a
+ ldh [hBGMapMode], a
+ ld hl, rLCDC
+ set rLCDC_WINDOW_TILEMAP, [hl] ; select 9C00-9FFF
+ call EmptyBattleTextbox
+ hlcoord 9, 7
+ lb bc, 5, 11
+ call ClearBox
+ hlcoord 1, 0
+ lb bc, 4, 10
+ call ClearBox
+ call ClearSprites
+ ld a, [wEnemyMonEnd]
+ cp WILD_BATTLE
+ call z, UpdateEnemyHUD
+ ld a, $1
+ ldh [hBGMapMode], a
+ call DoBattle
+ call ExitBattle
+ pop af
+ ld [wTimeOfDayPal], a
+ scf
+ ret
+
+InitEnemyTrainer:
+ ld [wTrainerClass], a
+ xor a
+ ld [wTempEnemyMonSpecies], a
+ callfar GetTrainerAttributes
+ callfar ReadTrainerParty
+
+ ; RIVAL1's first mon has no held item
+ ld a, [wTrainerClass]
+ cp RIVAL1
+ jr nz, .ok
+ xor a
+ ld [wOTPartyMon1Item], a
+
+.ok:
+ ld de, vTiles2
+ callfar GetTrainerPic
+ xor a
+ ldh [hGraphicStartTile], a
+ dec a
+ ld [wEnemyItemState], a
+ hlcoord 12, 0
+ lb bc, 7, 7
+ predef PlaceGraphic
+ ld a, -1
+ ld [wCurOTMon], a
+ ld a, TRAINER_BATTLE
+ ld [wBattleMode], a
+
+ call IsGymLeader
+ jr nc, .done
+ xor a
+ ld [wCurPartyMon], a
+ ld a, [wPartyCount]
+ ld b, a
+.partyloop
+ push bc
+ ld a, MON_HP
+ call GetPartyParamLocation
+ ld a, [hli]
+ or [hl]
+ jr z, .skipfaintedmon
+ ld c, HAPPINESS_GYMBATTLE
+ callfar ChangeHappiness
+.skipfaintedmon
+ pop bc
+ dec b
+ jr z, .done
+ ld hl, wCurPartyMon
+ inc [hl]
+ jr .partyloop
+.done
+ ret
+
+InitEnemyWildmon:
+ ld a, WILD_BATTLE
+ ld [wBattleMode], a
+ call LoadEnemyMon
+ ld hl, wEnemyMonMoves
+ ld de, wWildMonMoves
+ ld bc, NUM_MOVES
+ call CopyBytes
+ ld hl, wEnemyMonPP
+ ld de, wWildMonPP
+ ld bc, NUM_MOVES
+ call CopyBytes
+ ld hl, wEnemyMonDVs
+ predef GetUnownLetter
+ ld a, [wCurPartySpecies]
+ cp UNOWN
+ jr nz, .skip_unown
+ ld a, [wFirstUnownSeen]
+ and a
+ jr nz, .skip_unown
+ ld a, [wUnownLetter]
+ ld [wFirstUnownSeen], a
+.skip_unown
+ ld de, vTiles2
+ predef GetMonFrontpic
+ xor a
+ ld [wTrainerClass], a
+ ldh [hGraphicStartTile], a
+ hlcoord 12, 0
+ lb bc, 7, 7
+ predef PlaceGraphic
+ ret
+
+Unreferenced_Function3f41a:
+ ld hl, wEnemyMonMoves
+ ld de, wListMoves_MoveIndicesBuffer
+ ld b, NUM_MOVES
+.loop
+ ld a, [de]
+ inc de
+ ld [hli], a
+ and a
+ jr z, .clearpp
+
+ push bc
+ push hl
+
+ push hl
+ dec a
+ ld hl, Moves + MOVE_PP
+ ld bc, MOVE_LENGTH
+ call AddNTimes
+ ld a, BANK(Moves)
+ call GetFarByte
+ pop hl
+
+ ld bc, wEnemyMonPP - (wEnemyMonMoves + 1)
+ add hl, bc
+ ld [hl], a
+
+ pop hl
+ pop bc
+
+ dec b
+ jr nz, .loop
+ ret
+
+.clear
+ xor a
+ ld [hli], a
+
+.clearpp
+ push bc
+ push hl
+ ld bc, wEnemyMonPP - (wEnemyMonMoves + 1)
+ add hl, bc
+ xor a
+ ld [hl], a
+ pop hl
+ pop bc
+ dec b
+ jr nz, .clear
+ ret
+
+ExitBattle:
+ call IsLinkBattle
+ jr nz, .handle_end_of_battle
+ call ShowLinkBattleParticipantsAfterEnd
+ jr .clean_up_battle_ram
+
+.handle_end_of_battle
+ ld a, [wBattleResult]
+ and $f
+ jr nz, .clean_up_battle_ram
+ ; WIN
+ call CheckPayDay
+ xor a
+ ld [wForceEvolution], a
+ predef EvolveAfterBattle
+ farcall GivePokerusAndConvertBerries
+
+.clean_up_battle_ram
+ call BattleEnd_HandleRoamMons
+ xor a
+ ld [wLowHealthAlarm], a
+ ld [wBattleMode], a
+ ld [wBattleType], a
+ ld [wAttackMissed], a
+ ld [wTempWildMonSpecies], a
+ ld [wOtherTrainerClass], a
+ ld [wFailedToFlee], a
+ ld [wNumFleeAttempts], a
+ ld [wForcedSwitch], a
+ ld [wPartyMenuCursor], a
+ ld [wKeyItemsPocketCursor], a
+ ld [wItemsPocketCursor], a
+ ld [wBattleMenuCursorBuffer], a
+ ld [wCurMoveNum], a
+ ld [wBallsPocketCursor], a
+ ld [wLastPocket], a
+ ld [wMenuScrollPosition], a
+ ld [wKeyItemsPocketScrollPosition], a
+ ld [wItemsPocketScrollPosition], a
+ ld [wBallsPocketScrollPosition], a
+ ld hl, wPlayerSubStatus1
+ ld b, wEnemyFuryCutterCount - wPlayerSubStatus1
+.loop
+ ld [hli], a
+ dec b
+ jr nz, .loop
+ call WaitSFX
+ ret
+
+CheckPayDay:
+ ld hl, wPayDayMoney
+ ld a, [hli]
+ or [hl]
+ inc hl
+ or [hl]
+ ret z
+ ld a, [wAmuletCoin]
+ and a
+ jr z, .okay
+ ld hl, wPayDayMoney + 2
+ sla [hl]
+ dec hl
+ rl [hl]
+ dec hl
+ rl [hl]
+ jr nc, .okay
+ ld a, $ff
+ ld [hli], a
+ ld [hli], a
+ ld [hl], a
+
+.okay
+ ld hl, wPayDayMoney + 2
+ ld de, wMoney + 2
+ call AddBattleMoneyToAccount
+ ld hl, BattleText_PlayerPickedUpPayDayMoney
+ call StdBattleTextbox
+ ret
+
+PlayerPickedUpPayDayMoney:
+ text_far _PlayerPickedUpPayDayMoney
+ text_end
+
+ShowLinkBattleParticipantsAfterEnd:
+ ld a, [wCurOTMon]
+ ld hl, wOTPartyMon1Status
+ call GetPartyLocation
+ ld a, [wEnemyMonStatus]
+ ld [hl], a
+ call ClearTilemap
+ farcall _ShowLinkBattleParticipants
+ ld a, [wBattleResult]
+ and $f
+ cp LOSE
+ ld de, .Win
+ jr c, .store_result
+ ld de, .Lose
+ jr z, .store_result
+ ; DRAW
+ ld de, .Draw
+
+.store_result
+ hlcoord 6, 8
+ call PlaceString
+ ld c, 200
+ call DelayFrames
+
+ ld a, BANK(sLinkBattleStats)
+ call OpenSRAM
+
+ call AddLastMobileBattleToLinkRecord
+ call ReadAndPrintLinkBattleRecord
+
+ call CloseSRAM
+
+ call WaitPressAorB_BlinkCursor
+ call ClearTilemap
+ ret
+
+.Win:
+ db "YOU WIN@"
+.Lose:
+ db "YOU LOSE@"
+.Draw:
+ db " DRAW@"
+
+_DisplayLinkRecord:
+ ld a, BANK(sLinkBattleStats)
+ call OpenSRAM
+
+ call ReadAndPrintLinkBattleRecord
+
+ call CloseSRAM
+ hlcoord 0, 0, wAttrmap
+ xor a
+ ld bc, SCREEN_WIDTH * SCREEN_HEIGHT
+ call ByteFill
+ call WaitBGMap2
+ ld b, SCGB_DIPLOMA
+ call GetSGBLayout
+ call SetPalettes
+ ld c, 8
+ call DelayFrames
+ call WaitPressAorB_BlinkCursor
+ ret
+
+ReadAndPrintLinkBattleRecord:
+ call ClearTilemap
+ call ClearSprites
+ call .PrintBattleRecord
+ hlcoord 0, 8
+ ld b, 5
+ ld de, sLinkBattleRecord + 2
+.loop
+ push bc
+ push hl
+ push de
+ ld a, [de]
+ and a
+ jr z, .PrintFormatString
+ ld a, [wSavedAtLeastOnce]
+ and a
+ jr z, .PrintFormatString
+ push hl
+ push hl
+ ld h, d
+ ld l, e
+ ld de, wceed
+ ld bc, 10
+ call CopyBytes
+ ld a, "@"
+ ld [de], a
+ inc de
+ ld bc, 6
+ call CopyBytes
+ ld de, wceed
+ pop hl
+ call PlaceString
+ pop hl
+ ld de, 26
+ add hl, de
+ push hl
+ ld de, wcef8
+ lb bc, 2, 4
+ call PrintNum
+ pop hl
+ ld de, 5
+ add hl, de
+ push hl
+ ld de, wcefa
+ lb bc, 2, 4
+ call PrintNum
+ pop hl
+ ld de, 5
+ add hl, de
+ ld de, wcefc
+ lb bc, 2, 4
+ call PrintNum
+ jr .next
+
+.PrintFormatString:
+ ld de, .Format
+ call PlaceString
+.next
+ pop hl
+ ld bc, 18
+ add hl, bc
+ ld d, h
+ ld e, l
+ pop hl
+ ld bc, 2 * SCREEN_WIDTH
+ add hl, bc
+ pop bc
+ dec b
+ jr nz, .loop
+ ret
+
+.PrintBattleRecord:
+ hlcoord 1, 0
+ ld de, .Record
+ call PlaceString
+
+ hlcoord 0, 6
+ ld de, .Result
+ call PlaceString
+
+ hlcoord 0, 2
+ ld de, .Total
+ call PlaceString
+
+ hlcoord 6, 4
+ ld de, sLinkBattleWins
+ call .PrintZerosIfNoSaveFileExists
+
+ lb bc, 2, 4
+ call PrintNum
+
+ hlcoord 11, 4
+ ld de, sLinkBattleLosses
+ call .PrintZerosIfNoSaveFileExists
+
+ lb bc, 2, 4
+ call PrintNum
+
+ hlcoord 16, 4
+ ld de, sLinkBattleDraws
+ call .PrintZerosIfNoSaveFileExists
+
+ lb bc, 2, 4
+ call PrintNum
+
+.quit
+ ret
+
+.PrintZerosIfNoSaveFileExists:
+ ld a, [wSavedAtLeastOnce]
+ and a
+ ret nz
+ ld de, .Scores
+ ret
+
+.Scores:
+ db "<NULL><NULL>"
+.Format:
+ db " --- <LF>"
+ db " - - -@"
+.Record:
+ db "<PLAYER>'s RECORD@"
+.Result:
+ db "RESULT WIN LOSE DRAW@"
+.Total:
+ db "TOTAL WIN LOSE DRAW@"
+
+BattleEnd_HandleRoamMons:
+ ld a, [wBattleType]
+ cp BATTLETYPE_ROAMING
+ jr nz, .not_roaming
+ ld a, [wBattleResult]
+ and $f
+ jr z, .caught_or_defeated_roam_mon ; WIN
+ call GetRoamMonHP
+ ld a, [wEnemyMonHP + 1]
+ ld [hl], a
+ jr .update_roam_mons
+
+.caught_or_defeated_roam_mon
+ call GetRoamMonHP
+ ld [hl], 0
+ call GetRoamMonMapGroup
+ ld [hl], GROUP_N_A
+ call GetRoamMonMapNumber
+ ld [hl], MAP_N_A
+ call GetRoamMonSpecies
+ ld [hl], 0
+ ret
+
+.not_roaming
+ call BattleRandom
+ and $f
+ ret nz
+
+.update_roam_mons
+ callfar UpdateRoamMons
+ ret
+
+GetRoamMonMapGroup:
+ ld a, [wTempEnemyMonSpecies]
+ ld b, a
+ ld a, [wRoamMon1Species]
+ cp b
+ ld hl, wRoamMon1MapGroup
+ ret z
+ ld a, [wRoamMon2Species]
+ cp b
+ ld hl, wRoamMon2MapGroup
+ ret z
+ ld hl, wRoamMon3MapGroup
+ ret
+
+GetRoamMonMapNumber:
+ ld a, [wTempEnemyMonSpecies]
+ ld b, a
+ ld a, [wRoamMon1Species]
+ cp b
+ ld hl, wRoamMon1MapNumber
+ ret z
+ ld a, [wRoamMon2Species]
+ cp b
+ ld hl, wRoamMon2MapNumber
+ ret z
+ ld hl, wRoamMon3MapNumber
+ ret
+
+GetRoamMonHP:
+; output: hl = wRoamMonHP
+ ld a, [wTempEnemyMonSpecies]
+ ld b, a
+ ld a, [wRoamMon1Species]
+ cp b
+ ld hl, wRoamMon1HP
+ ret z
+ ld a, [wRoamMon2Species]
+ cp b
+ ld hl, wRoamMon2HP
+ ret z
+ ld hl, wRoamMon3HP
+ ret
+
+GetRoamMonDVs:
+; output: hl = wRoamMonDVs
+ ld a, [wTempEnemyMonSpecies]
+ ld b, a
+ ld a, [wRoamMon1Species]
+ cp b
+ ld hl, wRoamMon1DVs
+ ret z
+ ld a, [wRoamMon2Species]
+ cp b
+ ld hl, wRoamMon2DVs
+ ret z
+ ld hl, wRoamMon3DVs
+ ret
+
+GetRoamMonSpecies:
+ ld a, [wTempEnemyMonSpecies]
+ ld hl, wRoamMon1Species
+ cp [hl]
+ ret z
+ ld hl, wRoamMon2Species
+ cp [hl]
+ ret z
+ ld hl, wRoamMon3Species
+ ret
+
+AddLastMobileBattleToLinkRecord:
+ ld hl, wOTPlayerID
+ ld de, wStringBuffer1
+ ld bc, 2
+ call CopyBytes
+ ld hl, wOTPlayerName
+ ld bc, NAME_LENGTH - 1
+ call CopyBytes
+ ld hl, sLinkBattleStats - 12
+ call .StoreResult
+ ld hl, sLinkBattleRecord
+ ld d, 5
+.loop
+ push hl
+ inc hl
+ inc hl
+ ld a, [hl]
+ dec hl
+ dec hl
+ and a
+ jr z, .copy
+ push de
+ ld bc, 12
+ ld de, wStringBuffer1
+ call CompareBytesLong
+ pop de
+ pop hl
+ jr c, .done
+ ld bc, 18
+ add hl, bc
+ dec d
+ jr nz, .loop
+ ld bc, -18
+ add hl, bc
+ push hl
+
+.copy
+ ld d, h
+ ld e, l
+ ld hl, wStringBuffer1
+ ld bc, 12
+ call CopyBytes
+ ld b, 6
+ xor a
+.loop2
+ ld [de], a
+ inc de
+ dec b
+ jr nz, .loop2
+ pop hl
+
+.done
+ call .StoreResult
+ call .FindOpponentAndAppendRecord
+ ret
+.StoreResult:
+ ld a, [wBattleResult]
+ and $f
+ cp LOSE
+ ld bc, sLinkBattleWins + 1 - (sLinkBattleStats - 12)
+ jr c, .okay ; WIN
+ ld bc, sLinkBattleLosses + 1 - (sLinkBattleStats - 12)
+ jr z, .okay ; LOSE
+ ; DRAW
+ ld bc, sLinkBattleDraws + 1 - (sLinkBattleStats - 12)
+.okay
+ add hl, bc
+ call .CheckOverflow
+ ret nc
+ inc [hl]
+ ret nz
+ dec hl
+ inc [hl]
+ ret
+
+.CheckOverflow:
+ dec hl
+ ld a, [hl]
+ inc hl
+ cp HIGH(MAX_LINK_RECORD)
+ ret c
+ ld a, [hl]
+ cp LOW(MAX_LINK_RECORD)
+ ret
+
+.FindOpponentAndAppendRecord:
+ ld b, 5
+ ld hl, sLinkBattleRecord + 17
+ ld de, wceed
+.loop3
+ push bc
+ push de
+ push hl
+ call .LoadPointer
+ pop hl
+ ld a, e
+ pop de
+ ld [de], a
+ inc de
+ ld a, b
+ ld [de], a
+ inc de
+ ld a, c
+ ld [de], a
+ inc de
+ ld bc, 18
+ add hl, bc
+ pop bc
+ dec b
+ jr nz, .loop3
+ ld b, $0
+ ld c, $1
+.loop4
+ ld a, b
+ add b
+ add b
+ ld e, a
+ ld d, $0
+ ld hl, wceed
+ add hl, de
+ push hl
+ ld a, c
+ add c
+ add c
+ ld e, a
+ ld d, $0
+ ld hl, wceed
+ add hl, de
+ ld d, h
+ ld e, l
+ pop hl
+ push bc
+ ld c, 3
+ call CompareBytes
+ pop bc
+ jr z, .equal
+ jr nc, .done2
+
+.equal
+ inc c
+ ld a, c
+ cp $5
+ jr nz, .loop4
+ inc b
+ ld c, b
+ inc c
+ ld a, b
+ cp $4
+ jr nz, .loop4
+ ret
+
+.done2
+ push bc
+ ld a, b
+ ld bc, 18
+ ld hl, sLinkBattleRecord
+ call AddNTimes
+ push hl
+ ld de, wceed
+ ld bc, 18
+ call CopyBytes
+ pop hl
+ pop bc
+ push hl
+ ld a, c
+ ld bc, 18
+ ld hl, sLinkBattleRecord
+ call AddNTimes
+ pop de
+ push hl
+ ld bc, 18
+ call CopyBytes
+ ld hl, wceed
+ ld bc, 18
+ pop de
+ call CopyBytes
+ ret
+
+.LoadPointer:
+ ld e, $0
+ ld a, [hld]
+ ld c, a
+ ld a, [hld]
+ ld b, a
+ ld a, [hld]
+ add c
+ ld c, a
+ ld a, [hld]
+ adc b
+ ld b, a
+ jr nc, .okay2
+ inc e
+
+.okay2
+ ld a, [hld]
+ add c
+ ld c, a
+ ld a, [hl]
+ adc b
+ ld b, a
+ ret nc
+ inc e
+ ret
+
+InitBattleDisplay:
+ call InitBackPic
+ hlcoord 0, 12
+ ld b, 4
+ ld c, 18
+ call Textbox
+ hlcoord 1, 5
+ lb bc, 3, 7
+ call ClearBox
+ call LoadStandardFont
+ call _LoadBattleFontsHPBar
+ call .BlankBGMap
+ xor a
+ ldh [hMapAnims], a
+ ldh [hSCY], a
+ ld a, $90
+ ldh [hWY], a
+ ldh [rWY], a
+ call WaitBGMap
+ xor a
+ ldh [hBGMapMode], a
+ call BattleIntroSlidingPics
+ ld a, $1
+ ldh [hBGMapMode], a
+ ld a, $31
+ ldh [hGraphicStartTile], a
+ hlcoord 2, 6
+ lb bc, 6, 6
+ predef PlaceGraphic
+ xor a
+ ldh [hWY], a
+ ldh [rWY], a
+ call WaitBGMap
+ call HideSprites
+ ld b, SCGB_BATTLE_COLORS
+ call GetSGBLayout
+ call SetPalettes
+ ld a, $90
+ ldh [hWY], a
+ xor a
+ ldh [hSCX], a
+ ret
+
+.BlankBGMap:
+ ld a, BANK(sDecompressScratch)
+ call OpenSRAM
+
+ ld hl, sDecompressScratch
+ ld bc, sScratchAttrmap - sDecompressScratch
+ ld a, " "
+ call ByteFill
+
+ ld de, sDecompressScratch
+ hlbgcoord 0, 0
+ lb bc, BANK(.BlankBGMap), $40
+ call Request2bpp
+ call CloseSRAM
+ ret
+
+INCLUDE "engine/battle/sliding_intro.asm"
+
+InitBackPic:
+ call GetTrainerBackpic
+ call CopyBackpic
+ ret
+
+GetTrainerBackpic:
+ ld hl, ChrisBackpic
+ ld a, [wBattleType]
+ cp BATTLETYPE_TUTORIAL
+ jr nz, .ok
+ ld hl, DudeBackpic
+
+.ok:
+ ld de, vTiles2 tile $31
+ ld b, BANK(ChrisBackpic)
+ ld c, 7 * 7
+ predef DecompressGet2bpp
+ ret
+
+CopyBackpic:
+ ld a, BANK(sDecompressBuffer)
+ call OpenSRAM
+ ld hl, vTiles3
+ ld de, sDecompressBuffer
+ ldh a, [hROMBank]
+ ld b, a
+ ld c, 7 * 7
+ call Request2bpp
+ call CloseSRAM
+ call .LoadTrainerBackpicAsOAM
+ ld a, 7 * 7
+ ldh [hGraphicStartTile], a
+ hlcoord 2, 6
+ lb bc, 6, 6
+ predef PlaceGraphic
+ ret
+
+.LoadTrainerBackpicAsOAM:
+ ld hl, wVirtualOAMSprite00
+ xor a
+ ldh [hMapObjectIndexBuffer], a
+ ld b, 6
+ ld e, (SCREEN_WIDTH + 1) * TILE_WIDTH
+.outer_loop
+ ld c, 3
+ ld d, 8 * TILE_WIDTH
+.inner_loop
+ ld [hl], d ; y
+ inc hl
+ ld [hl], e ; x
+ inc hl
+ ldh a, [hMapObjectIndexBuffer]
+ ld [hli], a ; tile id
+ inc a
+ ldh [hMapObjectIndexBuffer], a
+ ld a, PAL_BATTLE_OB_PLAYER
+ ld [hli], a ; attributes
+ ld a, d
+ add 1 * TILE_WIDTH
+ ld d, a
+ dec c
+ jr nz, .inner_loop
+ ldh a, [hMapObjectIndexBuffer]
+ add $3
+ ldh [hMapObjectIndexBuffer], a
+ ld a, e
+ add 1 * TILE_WIDTH
+ ld e, a
+ dec b
+ jr nz, .outer_loop
+ ret
+
+ChrisBackpic:
+INCBIN "gfx/player/chris_back.2bpp.lz"
+
+DudeBackpic:
+INCBIN "gfx/battle/dude.2bpp.lz"
+
+BattleStartMessage:
+ ld a, [wBattleMode]
+ dec a
+ jr z, .wild
+
+ ld de, SFX_SHINE
+ call PlaySFX
+ call WaitSFX
+
+ ld c, 20
+ call DelayFrames
+
+ callfar Battle_GetTrainerName
+
+ ld hl, WantsToBattleText
+ jr .PlaceBattleStartText
+
+.wild
+ call BattleCheckEnemyShininess
+ jr nc, .not_shiny
+
+ xor a
+ ld [wNumHits], a
+ ld a, 1
+ ldh [hBattleTurn], a
+ ld a, 1
+ ld [wBattleAnimParam], a
+ ld de, ANIM_SEND_OUT_MON
+ call Call_PlayBattleAnim
+
+.not_shiny
+ ld a, $f
+ ld [wCryTracks], a
+ ld a, [wTempEnemyMonSpecies]
+ call PlayStereoCry
+ ld hl, HookedPokemonAttackedText
+ ld a, [wBattleType]
+ cp BATTLETYPE_FISH
+ jr z, .PlaceBattleStartText
+ ld hl, PokemonFellFromTreeText
+ cp BATTLETYPE_TREE
+ jr z, .PlaceBattleStartText
+ ld hl, WildPokemonAppearedText
+
+.PlaceBattleStartText:
+ push hl
+ farcall BattleStart_TrainerHuds
+ pop hl
+ call StdBattleTextbox
+ ret
+
+ShowLinkBattleParticipants:
+ call IsLinkBattle
+ jr nz, .ok
+ farcall _ShowLinkBattleParticipants
+ call ClearTilemap
+ call ClearSprites
+
+.ok
+ xor a
+ ldh [hMapAnims], a
+ call DelayFrame
+ predef DoBattleTransition
+ call _LoadBattleFontsHPBar
+ ld a, $1
+ ldh [hBGMapMode], a
+ call ClearSprites
+ call ClearTilemap
+ xor a
+ ldh [hBGMapMode], a
+ ldh [hWY], a
+ ldh [rWY], a
+ ldh [hMapAnims], a
+ ret
+
+IsLinkBattle:
+ push bc
+ push af
+ ld a, [wLinkMode]
+ cp LINK_COLOSSEUM
+ pop bc
+ ld a, b
+ pop bc
+ ret
diff --git a/engine/battle/sliding_intro.asm b/engine/battle/sliding_intro.asm
new file mode 100644
index 00000000..f872a8de
--- /dev/null
+++ b/engine/battle/sliding_intro.asm
@@ -0,0 +1,57 @@
+BattleIntroSlidingPics:
+ ld b, $70
+ ld c, $90
+ ld a, c
+ ldh [hSCX], a
+ call DelayFrame
+ ld a, %11100100
+ call DmgToCgbBGPals
+ lb de, %11100100, %11100100
+ call DmgToCgbObjPals
+
+.loop1
+ push bc
+ ld h, b
+ ld l, $40
+ call .subfunction2
+ ld h, $00
+ ld l, $60
+ call .subfunction2
+ call .subfunction1
+ pop bc
+ ld a, c
+ ldh [hSCX], a
+ inc b
+ inc b
+ dec c
+ dec c
+ jr nz, .loop1
+ ret
+
+.subfunction1
+ push bc
+ ld hl, wVirtualOAMSprite00XCoord
+ ld c, $12 ; 18
+ ld de, SPRITEOAMSTRUCT_LENGTH
+.loop2
+ dec [hl]
+ dec [hl]
+ add hl, de
+ dec c
+ jr nz, .loop2
+ pop bc
+ ret
+
+.subfunction2
+.loop3
+ ldh a, [rLY]
+ cp l
+ jr nz, .loop3
+ ld a, h
+ ldh [rSCX], a
+
+.loop4
+ ldh a, [rLY]
+ cp h
+ jr z, .loop4
+ ret
diff --git a/engine/events/specials.asm b/engine/events/specials.asm
index 605346b4..e030f68a 100755
--- a/engine/events/specials.asm
+++ b/engine/events/specials.asm
@@ -241,7 +241,7 @@ UnownPrinter: ; c427 (3:4427)
DisplayLinkRecord: ; c434 (3:4434)
call FadeToMenu
- farcall Function3f55d
+ farcall _DisplayLinkRecord
call ExitAllMenus
ret
diff --git a/engine/items/item_effects.asm b/engine/items/item_effects.asm
index 6735ec16..ac360409 100755
--- a/engine/items/item_effects.asm
+++ b/engine/items/item_effects.asm
@@ -1023,7 +1023,7 @@ WaterStone: ; ee63
cp EVERSTONE
jr z, .failed
ld a, $1
- ld [wd0d2], a
+ ld [wForceEvolution], a
farcall EvolvePokemon ; 10:61db
ld a, [wd154]
and a
@@ -1218,7 +1218,7 @@ RareCandy: ; ef68 (3:6f68)
ld [wd151], a
predef LearnLevelMoves
xor a
- ld [wd0d2], a
+ ld [wForceEvolution], a
farcall EvolvePokemon
jp Functionf7dc
@@ -2307,7 +2307,7 @@ Functionf6f6: ; f6f6 (3:76f6)
jr z, .asm_f715
call Functionf72f
jr z, .asm_f715
- ld hl, wcee1
+ ld hl, wMenuCursorX
inc [hl]
.asm_f715
ld hl, wMenuCursorY
@@ -2315,7 +2315,7 @@ Functionf6f6: ; f6f6 (3:76f6)
pop bc
dec b
jr nz, .asm_f6fe
- ld a, [wcee1]
+ ld a, [wMenuCursorX]
and a
jp nz, asm_f699
Functionf724: ; f724 (3:7724)
diff --git a/engine/items/pack.asm b/engine/items/pack.asm
index 8edd2555..5225362a 100755
--- a/engine/items/pack.asm
+++ b/engine/items/pack.asm
@@ -13,7 +13,7 @@ Pack:
.asm_1044a
ld a, [wce65]
- ld [wcfc8], a
+ ld [wLastPocket], a
ld hl, wOptions
res NO_TEXT_SCROLL, [hl]
ret
@@ -58,15 +58,15 @@ Pack_InitItemsPocket:
Pack_ItemsPocketMenu:
ld hl, ItemsPocketMenuDataHeader
call CopyMenuHeader
- ld a, [wcfca]
+ ld a, [wItemsPocketCursor]
ld [wMenuCursorBuffer], a
- ld a, [wcfcf]
+ ld a, [wItemsPocketScrollPosition]
ld [wMenuScrollPosition], a
call ScrollingMenu
ld a, [wMenuScrollPosition]
- ld [wcfcf], a
+ ld [wItemsPocketScrollPosition], a
ld a, [wMenuCursorY]
- ld [wcfca], a
+ ld [wItemsPocketCursor], a
.asm_104b7
ld b, $7
ld c, $3
@@ -87,15 +87,15 @@ Pack_InitKeyItemsPocket:
Pack_KeyItemsPocketMenu:
ld hl, KeyItemsPocketMenuDataHeader ; $4e9a
call CopyMenuHeader
- ld a, [wcfcb]
+ ld a, [wKeyItemsPocketCursor]
ld [wMenuCursorBuffer], a
- ld a, [wcfd0]
+ ld a, [wKeyItemsPocketScrollPosition]
ld [wMenuScrollPosition], a
call ScrollingMenu
ld a, [wMenuScrollPosition]
- ld [wcfd0], a
+ ld [wKeyItemsPocketScrollPosition], a
ld a, [wMenuCursorY]
- ld [wcfcb], a
+ ld [wKeyItemsPocketCursor], a
ld b, $3
ld c, $7
call Function10cef
@@ -211,15 +211,15 @@ Pack_InitBallsPocket:
Pack_BallsPocketMenu:
ld hl, BallsPocketMenuDataHeader ; $4eca
call CopyMenuHeader
- ld a, [wcfcc]
+ ld a, [wBallsPocketCursor]
ld [wMenuCursorBuffer], a
- ld a, [wcfd1]
+ ld a, [wBallsPocketScrollPosition]
ld [wMenuScrollPosition], a
call ScrollingMenu
ld a, [wMenuScrollPosition]
- ld [wcfd1], a
+ ld [wBallsPocketScrollPosition], a
ld a, [wMenuCursorY]
- ld [wcfcc], a
+ ld [wBallsPocketCursor], a
ld b, $1
ld c, $5
call Function10cef
@@ -504,20 +504,20 @@ Function107cd:
.asm_107da
xor a
- ld [wcfcc], a
- ld [wcfd1], a
+ ld [wBallsPocketCursor], a
+ ld [wBallsPocketScrollPosition], a
ret
.asm_107e2
xor a
- ld [wcfca], a
- ld [wcfcf], a
+ ld [wItemsPocketCursor], a
+ ld [wItemsPocketScrollPosition], a
ret
.asm_107ea
xor a
- ld [wcfcb], a
- ld [wcfd0], a
+ ld [wKeyItemsPocketCursor], a
+ ld [wKeyItemsPocketScrollPosition], a
ret
RegisterItem:
@@ -630,7 +630,7 @@ BattlePack:
.asm_108dd
ld a, [wce65]
- ld [wcfc8], a
+ ld [wLastPocket], a
ld hl, wOptions
res 4, [hl]
ret
@@ -675,15 +675,15 @@ BattlePack_InitItemsPocket:
BattlePack_ItemsPocketMenu:
ld hl, $4e6a
call CopyMenuHeader
- ld a, [wcfca]
+ ld a, [wItemsPocketCursor]
ld [wMenuCursorBuffer], a
- ld a, [wcfcf]
+ ld a, [wItemsPocketScrollPosition]
ld [wMenuScrollPosition], a
call ScrollingMenu
ld a, [wMenuScrollPosition]
- ld [wcfcf], a
+ ld [wItemsPocketScrollPosition], a
ld a, [wMenuCursorY]
- ld [wcfca], a
+ ld [wItemsPocketCursor], a
ld b, $7
ld c, $3
call Function10cef
@@ -703,15 +703,15 @@ BattlePack_InitKeyItemsPocket:
BattlePack_KeyItemsPocketMenu:
ld hl, $4e9a
call CopyMenuHeader
- ld a, [wcfcb]
+ ld a, [wKeyItemsPocketCursor]
ld [wMenuCursorBuffer], a
- ld a, [wcfd0]
+ ld a, [wKeyItemsPocketScrollPosition]
ld [wMenuScrollPosition], a
call ScrollingMenu
ld a, [wMenuScrollPosition]
- ld [wcfd0], a
+ ld [wKeyItemsPocketScrollPosition], a
ld a, [wMenuCursorY]
- ld [wcfcb], a
+ ld [wKeyItemsPocketCursor], a
ld b, $3
ld c, $7
call Function10cef
@@ -754,15 +754,15 @@ BattlePack_InitBallsPocket:
BattlePack_BallsPocketMenu:
ld hl, $4eca
call CopyMenuHeader
- ld a, [wcfcc]
+ ld a, [wBallsPocketCursor]
ld [wMenuCursorBuffer], a
- ld a, [wcfd1]
+ ld a, [wBallsPocketScrollPosition]
ld [wMenuScrollPosition], a
call ScrollingMenu
ld a, [wMenuScrollPosition]
- ld [wcfd1], a
+ ld [wBallsPocketScrollPosition], a
ld a, [wMenuCursorY]
- ld [wcfcc], a
+ ld [wBallsPocketCursor], a
ld b, $1
ld c, $5
call Function10cef
@@ -893,7 +893,7 @@ BattlePack_QuitSubmenu:
Function10aba: ; 10aba (4:4aba)
xor a
ld [wce63], a
- ld a, [wcfc8]
+ ld a, [wLastPocket]
and $3
ld [wCurPocket], a
inc a
@@ -942,15 +942,15 @@ DepositOrSell_ItemPocket:
call Function10b92
ld hl, PC_Mart_ItemsPocketMenuDataHeader ; $4e82
call CopyMenuHeader
- ld a, [wcfca]
+ ld a, [wItemsPocketCursor]
ld [wMenuCursorBuffer], a
- ld a, [wcfcf]
+ ld a, [wItemsPocketScrollPosition]
ld [wMenuScrollPosition], a
call ScrollingMenu
ld a, [wMenuScrollPosition]
- ld [wcfcf], a
+ ld [wItemsPocketScrollPosition], a
ld a, [wMenuCursorY]
- ld [wcfca], a
+ ld [wItemsPocketCursor], a
ret
DepositOrSell_KeyItemsPocket:
@@ -958,15 +958,15 @@ DepositOrSell_KeyItemsPocket:
call Function10b92
ld hl, PC_Mart_KeyItemsPocketMenuDataHeader ; $4eb2
call CopyMenuHeader
- ld a, [wcfcb]
+ ld a, [wKeyItemsPocketCursor]
ld [wMenuCursorBuffer], a
- ld a, [wcfd0]
+ ld a, [wKeyItemsPocketScrollPosition]
ld [wMenuScrollPosition], a
call ScrollingMenu
ld a, [wMenuScrollPosition]
- ld [wcfd0], a
+ ld [wKeyItemsPocketScrollPosition], a
ld a, [wMenuCursorY]
- ld [wcfcb], a
+ ld [wKeyItemsPocketCursor], a
ret
DepositOrSell_TMHMPocket:
@@ -983,15 +983,15 @@ DepositOrSell_BallsPocket:
call Function10b92
ld hl, PC_Mart_BallsPocketMenuDataHeader ; $4ee2
call CopyMenuHeader
- ld a, [wcfcc]
+ ld a, [wBallsPocketCursor]
ld [wMenuCursorBuffer], a
- ld a, [wcfd1]
+ ld a, [wBallsPocketScrollPosition]
ld [wMenuScrollPosition], a
call ScrollingMenu
ld a, [wMenuScrollPosition]
- ld [wcfd1], a
+ ld [wBallsPocketScrollPosition], a
ld a, [wMenuCursorY]
- ld [wcfcc], a
+ ld [wBallsPocketCursor], a
ret
Function10b92: ; 10b92 (4:4b92)
@@ -1059,7 +1059,7 @@ TutorialPack:
ld a, [wInputType]
or a
jr z, .asm_10bfa
- farcall DudeAutoInput_RightA ; 70:4dee
+ farcall _DudeAutoInput_RightA ; 70:4dee
.asm_10bfa
call Function10c07
call Function10b9f
diff --git a/engine/pokemon/correct_nick_errors.asm b/engine/pokemon/correct_nick_errors.asm
index 0f264a36..c8056251 100644
--- a/engine/pokemon/correct_nick_errors.asm
+++ b/engine/pokemon/correct_nick_errors.asm
@@ -43,7 +43,7 @@ CorrectNickErrors:: ; 677e (1:677e)
; table defining which characters are actually text commands
; format:
; ≥ <
- db "<START>", $04 + 1
+ db "<NULL>", $04 + 1
db "<PLAY_G>", $18 + 1
db $1d, "%" + 1
db $35, "<GREEN>" + 1
diff --git a/engine/pokemon/learn.asm b/engine/pokemon/learn.asm
index 65816783..fe6ff121 100644
--- a/engine/pokemon/learn.asm
+++ b/engine/pokemon/learn.asm
@@ -136,7 +136,7 @@ LearnMove:
ld a, $1
ld [w2DMenuNumCols], a
ld [wMenuCursorY], a
- ld [wcee1], a
+ ld [wMenuCursorX], a
ld a, $3
ld [wMenuJoypadFilter], a
ld a, $20
diff --git a/gfx/battle/dude.2bpp.lz b/gfx/battle/dude.2bpp.lz
new file mode 100644
index 00000000..b8e96a09
--- /dev/null
+++ b/gfx/battle/dude.2bpp.lz
Binary files differ
diff --git a/gfx/player/chris_back.2bpp.lz b/gfx/player/chris_back.2bpp.lz
new file mode 100644
index 00000000..aec84bba
--- /dev/null
+++ b/gfx/player/chris_back.2bpp.lz
Binary files differ
diff --git a/home/text.asm b/home/text.asm
index 628bc0f6..c296e378 100644
--- a/home/text.asm
+++ b/home/text.asm
@@ -213,7 +213,7 @@ ENDM
dict "<TM>", TMChar
dict "<TRNER>", TrainerChar
dict $23, PlaceKougeki
- dict "<LNBRK>", HalfLineChar
+ dict "<LF>", HalfLineChar
dict "<CONT>", ContText
dict "<……>", SixDotsChar
dict "<DONE>", DoneText
diff --git a/main.asm b/main.asm
index 40eda172..65c28928 100644
--- a/main.asm
+++ b/main.asm
@@ -154,7 +154,13 @@ StartMenu_PrintBugContestStatus:
Function24b8d:
dr $24b8d, $24c89
MonSubmenu:
- dr $24c89, $24f20
+ dr $24c89, $24e09
+GetMenu::
+ dr $24e09, $24e62
+LoadBattleMenu::
+ dr $24e62, $24e72
+ContestBattleMenu::
+ dr $24e72, $24f20
SelectQuantityToToss:
dr $24f20, $24f2a
SelectQuantityToBuy:
@@ -259,13 +265,17 @@ JohtoGrassWildMons:
dr $2ab35, $2bee3
SECTION "bankb", ROMX
- dr $2c000, $2c045
+ dr $2c000, $2c033
+BattleStart_TrainerHuds:
+ dr $2c033, $2c045
EnemySwitch_TrainerHud:
dr $2c045, $2c0c8
DrawPlayerHUDBorder:
dr $2c0c8, $2c0f8
DrawEnemyHUDBorder:
- dr $2c0f8, $2c225
+ dr $2c0f8, $2c1e4
+_ShowLinkBattleParticipants:
+ dr $2c1e4, $2c225
INCLUDE "engine/battle/ai/redundant.asm"
MoveDeletion:
dr $2c352, $2c57a
@@ -278,7 +288,9 @@ ChooseMonToLearnTMHM:
TeachTMHM:
dr $2c672, $2c943
PrintMoveDesc::
- dr $2c943, $2ca31
+ dr $2c943, $2c95d
+GivePokerusAndConvertBerries::
+ dr $2c95d, $2ca31
SECTION "bankc", ROMX
dr $30000, $33d81
@@ -300,75 +312,8 @@ INCLUDE "engine/battle/read_trainer_party.asm"
SECTION "Battle Core", ROMX
INCLUDE "engine/battle/core.asm"
+INCLUDE "data/battle/effect_command_pointers.asm"
-BattleMenu:
- dr $3df9a, $3e1e4
-
-PlayerSwitch:
- dr $3e1e4, $3e290
-PassedBattleMonEntrance:
- 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, $3ea16
-BattleWinSlideInEnemyTrainerFrontpic:
- dr $3ea16, $3ea6a
-ApplyStatusEffectOnPlayerStats:
- dr $3ea6a, $3ea6e
-ApplyStatusEffectOnEnemyStats:
- dr $3ea6e, $3ea77
-ApplyPrzEffectOnSpeed:
- dr $3ea77, $3eab4
-ApplyBrnEffectOnAttack:
- dr $3eab4, $3eae9
-ApplyStatLevelMultiplierOnAllStats:
- dr $3eae9, $3eb83
-BadgeStatBoosts:
- dr $3eb83, $3ebd8
-_LoadBattleFontsHPBar:
- dr $3ebd8, $3ebdf
-_LoadHPBar:
- dr $3ebdf, $3ec0a
-EmptyBattleTextbox:
- dr $3ec0a, $3ec11
-_BattleRandom::
- 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::
- dr $3f243, $3f24d
-DropPlayerSub:
- dr $3f24d, $3f282
-GetEnemyMonFrontpic::
- dr $3f282, $3f28c
-DropEnemySub:
- dr $3f28c, $3f2c7
-StartBattle::
- dr $3f2c7, $3f55d
-Function3f55d:
- dr $3f55d, $3fd3d
-BattleCommandPointers:
- dr $3fd3d, $3fe9b
SECTION "bank10", ROMX
@@ -396,7 +341,11 @@ SECTION "bank11", ROMX
INCLUDE "engine/battle/ai/move.asm"
dr $441c2, $44360
PokedexDataPointerTable::
- dr $44360, $44648
+ dr $44360, $44556
+PlayBattleMusic::
+ dr $44556, $445f2
+ClearBattleRAM::
+ dr $445f2, $44648
PlaceGraphic::
dr $44648, $44679
SendMailToPC::
@@ -559,28 +508,37 @@ PlaySpriteAnimations:
dr $8d18a, $8d1f7
_InitSpriteAnimStruct::
dr $8d1f7, $8d332
-_ReinitSpriteAnimFrame::
IF DEF(_GOLD)
- dr $8d332, $8e774
+_ReinitSpriteAnimFrame::
+ dr $8d332, $8e6fd
+AnimateEndOfExpBar::
+ dr $8e6fd, $8e774
ClearSpriteAnims2::
dr $8e774, $8e78b
LoadOverworldMonIcon::
dr $8e78b, $8e79f
LoadMenuMonIcon::
- dr $8e79f, $8e922
+ dr $8e79f, $8e8fb
+FreezeMonIcons::
+ dr $8e8fb, $8e922
UnfreezeMonIcons::
dr $8e922, $8e93d
HoldSwitchmonIcon::
dr $8e93d, $8fe43
ELIF DEF(_SILVER)
- dr $8d332, $8e75a
+_ReinitSpriteAnimFrame::
+ dr $8d332, $8e6e3
+AnimateEndOfExpBar::
+ dr $8e6e3, $8e75a
ClearSpriteAnims2::
dr $8e75a, $8e771
LoadOverworldMonIcon::
dr $8e771, $8e785
LoadMenuMonIcon::
- dr $8e785, $8e908
+ dr $8e785, $8e8e1
+FreezeMonIcons::
+ dr $8e8e1, $8e908
UnfreezeMonIcons::
dr $8e908, $8e923
HoldSwitchmonIcon::
@@ -693,7 +651,7 @@ INCLUDE "data/moves/animations.asm"
LoadPoisonBGPals::
dr $cbc76, $cbdba
-SECTION "bank33", ROMX
+SECTION "Move Animations", ROMX
DisplayCaughtContestMonStats:
dr $cc000, $cc0c8
@@ -705,7 +663,11 @@ DummyPredef39::
PlayBattleAnim::
dr $cc0d7, $cc283
ClearBattleAnims::
- dr $cc283, $cfce3
+ dr $cc283, $cc5f7
+BattleAnimCmd_RaiseSub::
+ dr $cc5f7, $cc67c
+BattleAnimCmd_MinimizeOpp::
+ dr $cc67c, $cfce3
SECTION "bank36", ROMX
dr $d8000, $d8400
@@ -772,9 +734,19 @@ Functionf8000::
Functionf800c::
dr $f800c, $f8032
_LoadFontsBattleExtra::
- dr $f8032, $f80d9
+ dr $f8032, $f8066
+LoadBattleFontsHPBar::
+ dr $f8066, $f8081
+LoadHPBar::
+ dr $f8081, $f80d9
LoadStatsScreenPageTilesGFX::
- dr $f80d9, $fb4be
+ dr $f80d9, $f8bb2
+EnemyHPBarBorderGFX::
+ dr $f8bb2, $f8bd2
+HPExpBarBorderGFX::
+ dr $f8bd2, $f8c02
+ExpBarGFX::
+ dr $f8c02, $fb4be
TileCollisionTable::
dr $fb4be, $fb5be
@@ -793,7 +765,9 @@ ConvertMon_1to2::
UpdateUnownDex:
dr $fbb22, $fbc3c
CheckMagikarpLength:
- dr $fbc3c, $fbdd6
+ dr $fbc3c, $fbd00
+CalcMagikarpLength::
+ dr $fbd00, $fbdd6
MagikarpHouseSign:
dr $fbdd6, $fbdf1
HiddenPowerDamage:
@@ -853,14 +827,15 @@ Function1c0a7b::
dr $1c0a7b, $1c0de9
_DudeAutoInput_A::
dr $1c0de9, $1c0dee
+_DudeAutoInput_RightA::
+ dr $1c0dee, $1c0df3
+_DudeAutoInput_DownA::
+ dr $1c0df3, $1c168b
-IF DEF(_GOLD)
-DudeAutoInput_RightA::
- dr $1c0dee, $1c168b
-ELIF DEF(_SILVER)
-DudeAutoInput_RightA::
- dr $1c0dee, $1c168c
+IF DEF(_SILVER)
+ dr $1c168b, $1c168c
ENDC
+
SECTION "bank7f", ROMX
dr $1ffdf8, $200000
diff --git a/pokegold.link b/pokegold.link
index ecbf1577..952b76df 100644
--- a/pokegold.link
+++ b/pokegold.link
@@ -141,8 +141,7 @@ ROMX $32
org $4000
"bank32"
ROMX $33
- org $4000
- "bank33"
+ "Move Animations"
"Extra Songs 2"
ROMX $36
org $4000
@@ -297,7 +296,6 @@ VRAM $00
VRAM $01
SRAM $00
"Scratch"
- "Decompress Buffer"
org $a600
"SRAM Bank 0"
"Backup Save 1"
diff --git a/pokesilver.link b/pokesilver.link
index ecbf1577..952b76df 100644
--- a/pokesilver.link
+++ b/pokesilver.link
@@ -141,8 +141,7 @@ ROMX $32
org $4000
"bank32"
ROMX $33
- org $4000
- "bank33"
+ "Move Animations"
"Extra Songs 2"
ROMX $36
org $4000
@@ -297,7 +296,6 @@ VRAM $00
VRAM $01
SRAM $00
"Scratch"
- "Decompress Buffer"
org $a600
"SRAM Bank 0"
"Backup Save 1"
diff --git a/sram.asm b/sram.asm
index c62d71a7..68ebb228 100755
--- a/sram.asm
+++ b/sram.asm
@@ -1,11 +1,13 @@
SECTION "Scratch", SRAM
-sDecompressScratch:: ds $188 ; a000
+UNION ; a000
+sScratchTilemap:: ds BG_MAP_WIDTH * BG_MAP_HEIGHT
+sScratchAttrmap:: ds $200
-
-SECTION "Decompress Buffer", SRAM
-
-sDecompressBuffer:: ds 7 * 7 * $10 ; a188
+NEXTU ; a000
+sDecompressScratch:: ds $188
+sDecompressBuffer:: ds 7 * 7 tiles ; a188
+ENDU
SECTION "SRAM Bank 0", SRAM
@@ -82,15 +84,17 @@ sLuckyIDNumber:: dw
SECTION "Backup Save 1", SRAM
+; ac6b
sBackupPlayerData3:: ds wPlayerDataEnd - wPlayerData3
+; b0e8
sBackupPokemonData:: ds wPokemonDataEnd - wPokemonData
+; b5c7
sBackupPlayerData1:: ds wPlayerData1End - wPlayerData
SECTION "SRAM Stack", SRAM
sStackTop:: dw
-
s0_b7ef:: db
s0_b7f0:: db
@@ -122,15 +126,15 @@ sCheckValue2:: db ; loaded with SAVE_CHECK_VALUE_2, used to check save corruptio
SECTION "Active Box", SRAM
-sBox:: curbox sBox
+sBox:: curbox sBox ; ad6c
SECTION "Link Battle Data", SRAM
sLinkBattleStats::
-sLinkBattleWins:: dw
-sLinkBattleLosses:: dw
-sLinkBattleDraws:: dw
+sLinkBattleWins:: dw ; b1ba
+sLinkBattleLosses:: dw ; b1bc
+sLinkBattleDraws:: dw ; b1be
sLinkBattleRecord::
sLinkBattleRecord1:: link_battle_record sLinkBattleRecord1
@@ -143,7 +147,7 @@ sLinkBattleStatsEnd::
SECTION "SRAM Hall of Fame", SRAM
-sHallOfFame::
+sHallOfFame:: ; b21a
sHallOfFame01:: hall_of_fame sHallOfFame01
sHallOfFame02:: hall_of_fame sHallOfFame02
sHallOfFame03:: hall_of_fame sHallOfFame03
@@ -179,6 +183,7 @@ sHallOfFameEnd::
SECTION "Backup Save 2", SRAM
+; bd96
sBackupPlayerData2:: ds wPlayerData2End - wPlayerData2
@@ -206,12 +211,10 @@ sBox14:: box sBox14
SECTION "Backup Save 3", SRAM
+; be30
sBackupOptions:: ds wOptionsEnd - wOptions
-
sBackupCheckValue1:: db ; loaded with SAVE_CHECK_VALUE_1, used to check save corruption
-
-sBackupCurMapData:: ds wCurMapDataEnd - wCurMapData
-
+; be39
+sBackupCurMapData:: ds wCurMapDataEnd - wCurMapData
sBackupChecksum:: dw
-
sBackupCheckValue2:: db ; loaded with SAVE_CHECK_VALUE_2, used to check save corruption
diff --git a/wram.asm b/wram.asm
index fbd35b8a..53a4c346 100644
--- a/wram.asm
+++ b/wram.asm
@@ -1809,11 +1809,11 @@ wPlayerTurnsTaken:: db ; cbbb
wcbbc:: ds 1 ; cbbc
wPlayerSubstituteHP:: db ; cbbd
wEnemySubstituteHP:: db ; cbbe
-wcbbf:: ds 1 ; cbbf
+wUnusedPlayerLockedMove:: db ; cbbf
wcbc0:: ds 1 ; cbc0
-wCurPlayerMove:: ds 1 ; cbc1
-wCurEnemyMove:: ds 1 ; cbc2
-wcbc3:: ds 1 ; cbc3
+wCurPlayerMove:: db ; cbc1
+wCurEnemyMove:: db ; cbc2
+wLinkBattleRNCount:: db ; cbc3
wEnemyItemState:: db ; cbc4
wcbc5:: ds 1 ; cbc5
wcbc6:: ds 1 ; cbc6
@@ -1822,7 +1822,7 @@ wEnemyHPAtTimeOfPlayerSwitch:: dw ; cbc8
wPayDayMoney:: ds 3 ; cbca
wcbcd:: ds 1 ; cbcd
-wcbce:: ds 1 ; cbce
+wSafariMonEating:: db ; cbce
wcbcf:: ds 1 ; cbcf
wEnemyBackupDVs:: dw
wAlreadyDisobeyed:: db ; cbd2
@@ -1866,7 +1866,7 @@ wPlayerUsedMoves:: ; cbf0
wEnemyAISwitchScore:: db ; cbf4
wEnemySwitchMonParam:: db ; cbf5
wEnemySwitchMonIndex:: db ; cbf6
-wcbf7:: ds 1 ; cbf7
+wTempLevel:: db ; cbf7
wLastPlayerMon:: db ; cbf8
wLastPlayerMove:: db ; cbf9
wLastEnemyMove:: db ; cbfa
@@ -2287,8 +2287,8 @@ w2DMenuFlags2:: db ; cedd
w2DMenuCursorOffsets:: db ; cede
wMenuJoypadFilter:: db ; cedf
w2DMenuDataEnd::
-wMenuCursorY:: ds 1 ; cee0
-wcee1:: ds 1 ; cee1
+wMenuCursorY:: db ; cee0
+wMenuCursorX:: db ; cee1
wcee2:: ds 1 ; cee2
wCursorCurrentTile:: ds 1 ; cee3
wcee4:: ds 1 ; cee4
@@ -2553,18 +2553,18 @@ NEXTU
wBattleMenuCursorBuffer:: dw ; cfc4
wCurBattleMon:: db ; cfc6
wCurMoveNum:: db; cfc7
-wcfc8:: ds 1 ; cfc8
+wLastPocket:: db ; cfc8
wPartyMenuCursor:: ds 1 ; cfc9
ENDU
-wcfca:: ds 1 ; cfca
-wcfcb:: ds 1 ; cfcb
-wcfcc:: ds 1 ; cfcc
+wItemsPocketCursor:: db ; cfca
+wKeyItemsPocketCursor:: db ; cfcb
+wBallsPocketCursor:: db ; cfcc
wcfcd:: ds 1 ; cfcd
wcfce:: ds 1 ; cfce
-wcfcf:: ds 1 ; cfcf
-wcfd0:: ds 1 ; cfd0
-wcfd1:: ds 1 ; cfd1
+wItemsPocketScrollPosition:: db ; cfcf
+wKeyItemsPocketScrollPosition:: db; cfd0
+wBallsPocketScrollPosition:: db ; cfd1
wcfd2:: ds 1 ; cfd2
wSwitchMon::
@@ -2789,8 +2789,8 @@ wd0cc:: ds 1 ; d0cc
wd0cd:: ds 1 ; d0cd
wd0ce:: ds 1 ; d0ce
wTilesetPalettes:: dw ; d0cf
-wd0d1:: ds 1 ; d0d1
-wd0d2:: ds 1 ; d0d2
+wEvolvableFlags:: db ; d0d1
+wForceEvolution:: db ; d0d2
UNION ; d0d3
; general-purpose buffers
@@ -2814,6 +2814,13 @@ wCurHPAnimLowHP:: db ; d0de
wCurHPAnimHighHP:: db ; d0df
NEXTU ; d0d3
+; evolution data
+wEvolutionOldSpecies:: db ; d0d3
+wEvolutionNewSpecies:: db ; d0d4
+wEvolutionPicOffset:: db ; d0d5
+wEvolutionCanceled:: db ; d0d6
+
+NEXTU ; d0d3
; miscellaneous
wMagikarpLength:: dw
wSelectedDecoration:: db
@@ -2822,19 +2829,10 @@ wOtherDecoration:: db
wCurEnemyItem:: db
ENDU ; d0e0
-wd0e0:: ds 1 ; d0e0
-wd0e1:: ds 1 ; d0e1
-wd0e2:: ds 1 ; d0e2
-wd0e3:: ds 1 ; d0e3
-wd0e4:: ds 1 ; d0e4
-wd0e5:: ds 1 ; d0e5
-wd0e6:: ds 1 ; d0e6
-wd0e7:: ds 1 ; d0e7
-wd0e8:: ds 1 ; d0e8
-wd0e9:: ds 1 ; d0e9
-wd0ea:: ds 1 ; d0ea
-wd0eb:: ds 1 ; d0eb
-wd0ec:: ds 1 ; d0ec
+ ds 3
+
+wLinkBattleRNs:: ds 10 ; d0e3
+
wTempEnemyMonSpecies:: db ; d0ed
wTempBattleMonSpecies:: db ; d0ee