pokecrystal-board/engine/battle/core.asm

8841 lines
140 KiB
NASM
Raw Normal View History

; Core components of the battle engine.
2018-06-24 07:09:41 -07:00
DoBattle:
xor a
2015-11-07 18:04:54 -08:00
ld [wBattleParticipantsNotFainted], a
2016-01-12 09:46:18 -08:00
ld [wBattleParticipantsIncludingFainted], a
ld [wBattlePlayerAction], a
2018-01-23 14:39:09 -08:00
ld [wBattleEnded], a
inc a
2016-08-07 15:14:20 -07:00
ld [wBattleHasJustStarted], a
2018-01-23 14:39:09 -08:00
ld hl, wOTPartyMon1HP
2015-11-06 06:04:27 -08:00
ld bc, PARTYMON_STRUCT_LENGTH - 1
ld d, BATTLEACTION_SWITCH1 - 1
.loop
inc d
ld a, [hli]
or [hl]
2015-11-06 06:04:27 -08:00
jr nz, .alive
add hl, bc
2015-11-06 06:04:27 -08:00
jr .loop
2015-11-06 06:04:27 -08:00
.alive
ld a, d
ld [wBattleAction], a
ld a, [wLinkMode]
and a
2015-11-06 06:04:27 -08:00
jr z, .not_linked
ldh a, [hSerialConnectionStatus]
cp USING_INTERNAL_CLOCK
2015-11-06 06:04:27 -08:00
jr z, .player_2
2015-11-06 06:04:27 -08:00
.not_linked
ld a, [wBattleMode]
dec a
2015-11-06 06:04:27 -08:00
jr z, .wild
xor a
2015-11-08 16:09:36 -08:00
ld [wEnemySwitchMonIndex], a
call NewEnemyMonStatus
call ResetEnemyStatLevels
call BreakAttraction
2015-11-07 18:04:54 -08:00
call EnemySwitch
2015-11-06 06:04:27 -08:00
.wild
ld c, 40
call DelayFrames
2015-11-06 06:04:27 -08:00
.player_2
call LoadTilemapToTempTilemap
call CheckPlayerPartyForFitMon
ld a, d
and a
jp z, LostBattle
call SafeLoadTempTilemapToTilemap
2018-01-23 14:39:09 -08:00
ld a, [wBattleType]
2015-09-09 16:27:07 -07:00
cp BATTLETYPE_DEBUG
2015-11-06 06:04:27 -08:00
jp z, .tutorial_debug
cp BATTLETYPE_TUTORIAL
2015-11-06 06:04:27 -08:00
jp z, .tutorial_debug
xor a
2018-01-23 14:39:09 -08:00
ld [wCurPartyMon], a
2015-11-06 06:04:27 -08:00
.loop2
2016-03-01 19:31:21 -08:00
call CheckIfCurPartyMonIsFitToFight
2015-11-06 06:04:27 -08:00
jr nz, .alive2
2018-01-23 14:39:09 -08:00
ld hl, wCurPartyMon
inc [hl]
2015-11-06 06:04:27 -08:00
jr .loop2
2015-11-06 06:04:27 -08:00
.alive2
2018-01-23 14:39:09 -08:00
ld a, [wCurBattleMon]
ld [wLastPlayerMon], a
ld a, [wCurPartyMon]
ld [wCurBattleMon], a
inc a
2018-01-23 14:39:09 -08:00
ld hl, wPartySpecies - 1
ld c, a
ld b, 0
add hl, bc
ld a, [hl]
2018-01-23 14:39:09 -08:00
ld [wCurPartySpecies], a
ld [wTempBattleMonSpecies], a
hlcoord 1, 5
ld a, 9
call SlideBattlePicOut
call LoadTilemapToTempTilemap
2015-11-07 18:04:54 -08:00
call ResetBattleParticipants
2015-11-06 13:42:38 -08:00
call InitBattleMon
call ResetPlayerStatLevels
call SendOutMonText
call NewBattleMonStatus
call BreakAttraction
2015-11-07 06:48:32 -08:00
call SendOutPlayerMon
2019-04-08 05:15:10 -07:00
call EmptyBattleTextbox
call LoadTilemapToTempTilemap
call SetPlayerTurn
call SpikesDamage
ld a, [wLinkMode]
and a
2015-11-06 06:04:27 -08:00
jr z, .not_linked_2
ldh a, [hSerialConnectionStatus]
cp USING_INTERNAL_CLOCK
2015-11-06 06:04:27 -08:00
jr nz, .not_linked_2
xor a
2015-11-08 16:09:36 -08:00
ld [wEnemySwitchMonIndex], a
call NewEnemyMonStatus
call ResetEnemyStatLevels
call BreakAttraction
2015-11-07 18:04:54 -08:00
call EnemySwitch
call SetEnemyTurn
call SpikesDamage
2015-11-06 06:04:27 -08:00
.not_linked_2
jp BattleTurn
2015-11-06 06:04:27 -08:00
.tutorial_debug
jp BattleMenu
2018-06-24 07:09:41 -07:00
WildFled_EnemyFled_LinkBattleCanceled:
call SafeLoadTempTilemapToTilemap
2015-10-24 07:34:19 -07:00
ld a, [wBattleResult]
2018-04-05 08:44:02 -07:00
and BATTLERESULT_BITMASK
add DRAW
2015-10-24 07:34:19 -07:00
ld [wBattleResult], a
ld a, [wLinkMode]
and a
2015-08-24 16:56:30 -07:00
ld hl, BattleText_WildFled
jr z, .print_text
2015-10-24 07:34:19 -07:00
ld a, [wBattleResult]
2018-04-05 08:44:02 -07:00
and BATTLERESULT_BITMASK
ld [wBattleResult], a ; WIN
2015-08-24 16:56:30 -07:00
ld hl, BattleText_EnemyFled
.print_text
2019-04-08 05:15:10 -07:00
call StdBattleTextbox
.skip_text
2015-10-19 13:49:29 -07:00
call StopDangerSound
; BUG: SFX_RUN does not play correctly when a wild Pokémon flees from battle (see docs/bugs_and_glitches.md)
ld de, SFX_RUN
call PlaySFX
.skip_sfx
call SetPlayerTurn
ld a, 1
2018-01-23 14:39:09 -08:00
ld [wBattleEnded], a
ret
2018-06-24 07:09:41 -07:00
BattleTurn:
.loop
2015-11-08 10:27:26 -08:00
call CheckContestBattleOver
jp c, .quit
xor a
ld [wPlayerIsSwitching], a
ld [wEnemyIsSwitching], a
2016-08-07 15:14:20 -07:00
ld [wBattleHasJustStarted], a
ld [wPlayerJustGotFrozen], a
ld [wEnemyJustGotFrozen], a
2018-01-23 14:39:09 -08:00
ld [wCurDamage], a
ld [wCurDamage + 1], a
2015-11-08 16:09:36 -08:00
call HandleBerserkGene
call UpdateBattleMonInParty
2017-12-24 09:47:30 -08:00
farcall AIChooseMove
2015-11-08 16:09:36 -08:00
call CheckPlayerLockedIn
2015-11-08 10:27:26 -08:00
jr c, .skip_iteration
.loop1
call BattleMenu
jr c, .quit
2018-01-23 14:39:09 -08:00
ld a, [wBattleEnded]
and a
jr nz, .quit
2015-11-08 16:09:36 -08:00
ld a, [wForcedSwitch] ; roared/whirlwinded/teleported
and a
jr nz, .quit
2015-11-08 10:27:26 -08:00
.skip_iteration
2015-11-08 16:09:36 -08:00
call ParsePlayerAction
2015-11-08 10:27:26 -08:00
jr nz, .loop1
2015-11-08 16:09:36 -08:00
call EnemyTriesToFlee
jr c, .quit
2015-11-06 06:04:27 -08:00
call DetermineMoveOrder
2015-11-08 10:27:26 -08:00
jr c, .false
2015-11-08 16:09:36 -08:00
call Battle_EnemyFirst
2015-11-08 10:27:26 -08:00
jr .proceed
.false
2015-11-08 16:09:36 -08:00
call Battle_PlayerFirst
2015-11-08 10:27:26 -08:00
.proceed
2015-11-08 16:09:36 -08:00
ld a, [wForcedSwitch]
and a
jr nz, .quit
2018-01-23 14:39:09 -08:00
ld a, [wBattleEnded]
and a
jr nz, .quit
2015-11-08 10:27:26 -08:00
call HandleBetweenTurnEffects
2018-01-23 14:39:09 -08:00
ld a, [wBattleEnded]
and a
jr nz, .quit
jp .loop
.quit
ret
2018-06-24 07:09:41 -07:00
HandleBetweenTurnEffects:
ldh a, [hSerialConnectionStatus]
cp USING_EXTERNAL_CLOCK
2015-10-19 13:49:29 -07:00
jr z, .CheckEnemyFirst
call CheckFaint_PlayerThenEnemy
ret c
2015-11-08 10:27:26 -08:00
call HandleFutureSight
2015-10-19 13:49:29 -07:00
call CheckFaint_PlayerThenEnemy
ret c
call HandleWeather
2015-10-19 13:49:29 -07:00
call CheckFaint_PlayerThenEnemy
ret c
2015-11-08 10:27:26 -08:00
call HandleWrap
2015-10-19 13:49:29 -07:00
call CheckFaint_PlayerThenEnemy
ret c
2015-11-08 10:27:26 -08:00
call HandlePerishSong
2015-10-19 13:49:29 -07:00
call CheckFaint_PlayerThenEnemy
ret c
2015-10-19 13:49:29 -07:00
jr .NoMoreFaintingConditions
.CheckEnemyFirst:
2015-10-19 13:49:29 -07:00
call CheckFaint_EnemyThenPlayer
ret c
2015-11-08 10:27:26 -08:00
call HandleFutureSight
2015-10-19 13:49:29 -07:00
call CheckFaint_EnemyThenPlayer
ret c
call HandleWeather
2015-10-19 13:49:29 -07:00
call CheckFaint_EnemyThenPlayer
ret c
2015-11-08 10:27:26 -08:00
call HandleWrap
2015-10-19 13:49:29 -07:00
call CheckFaint_EnemyThenPlayer
ret c
2015-11-08 10:27:26 -08:00
call HandlePerishSong
2015-10-19 13:49:29 -07:00
call CheckFaint_EnemyThenPlayer
ret c
.NoMoreFaintingConditions:
2015-11-08 10:27:26 -08:00
call HandleLeftovers
call HandleMysteryberry
2018-04-05 02:41:06 -07:00
call HandleDefrost
call HandleSafeguard
call HandleScreens
2015-11-08 10:27:26 -08:00
call HandleStatBoostingHeldItems
call HandleHealingItems
call UpdateBattleMonInParty
call LoadTilemapToTempTilemap
2015-11-23 13:04:53 -08:00
jp HandleEncore
2018-06-24 07:09:41 -07:00
CheckFaint_PlayerThenEnemy:
; BUG: Perish Song and Spikes can leave a Pokemon with 0 HP and not faint (see docs/bugs_and_glitches.md)
call HasPlayerFainted
2015-10-19 13:49:29 -07:00
jr nz, .PlayerNotFainted
call HandlePlayerMonFaint
2018-01-23 14:39:09 -08:00
ld a, [wBattleEnded]
and a
2015-10-19 13:49:29 -07:00
jr nz, .BattleIsOver
.PlayerNotFainted:
call HasEnemyFainted
2015-10-19 13:49:29 -07:00
jr nz, .BattleContinues
call HandleEnemyMonFaint
2018-01-23 14:39:09 -08:00
ld a, [wBattleEnded]
and a
2015-10-19 13:49:29 -07:00
jr nz, .BattleIsOver
.BattleContinues:
and a
ret
.BattleIsOver:
scf
ret
2018-06-24 07:09:41 -07:00
CheckFaint_EnemyThenPlayer:
; BUG: Perish Song and Spikes can leave a Pokemon with 0 HP and not faint (see docs/bugs_and_glitches.md)
call HasEnemyFainted
2015-10-19 13:49:29 -07:00
jr nz, .EnemyNotFainted
call HandleEnemyMonFaint
2018-01-23 14:39:09 -08:00
ld a, [wBattleEnded]
and a
2015-10-19 13:49:29 -07:00
jr nz, .BattleIsOver
.EnemyNotFainted:
call HasPlayerFainted
2015-10-19 13:49:29 -07:00
jr nz, .BattleContinues
call HandlePlayerMonFaint
2018-01-23 14:39:09 -08:00
ld a, [wBattleEnded]
and a
2015-10-19 13:49:29 -07:00
jr nz, .BattleIsOver
.BattleContinues:
and a
ret
.BattleIsOver:
scf
ret
2018-06-24 07:09:41 -07:00
HandleBerserkGene:
ldh a, [hSerialConnectionStatus]
cp USING_EXTERNAL_CLOCK
jr z, .reverse
call .player
jr .enemy
.reverse
call .enemy
2018-08-26 19:34:59 -07:00
; fallthrough
.player
call SetPlayerTurn
2018-01-23 14:39:09 -08:00
ld de, wPartyMon1Item
ld a, [wCurBattleMon]
ld b, a
jr .go
.enemy
call SetEnemyTurn
2018-01-23 14:39:09 -08:00
ld de, wOTPartyMon1Item
ld a, [wCurOTMon]
ld b, a
2018-08-26 19:34:59 -07:00
; fallthrough
.go
push de
push bc
2017-12-24 09:47:30 -08:00
callfar GetUserItem
ld a, [hl]
ld [wNamedObjectIndex], a
sub BERSERK_GENE
pop bc
pop de
ret nz
ld [hl], a
ld h, d
ld l, e
ld a, b
call GetPartyLocation
xor a
ld [hl], a
; BUG: Berserk Gene's confusion lasts for 256 turns or the previous Pokémon's confusion count (see docs/bugs_and_glitches.md)
ld a, BATTLE_VARS_SUBSTATUS3
call GetBattleVarAddr
push af
set SUBSTATUS_CONFUSED, [hl]
ld a, BATTLE_VARS_MOVE_ANIM
call GetBattleVarAddr
push hl
push af
xor a
ld [hl], a
2018-01-23 14:39:09 -08:00
ld [wAttackMissed], a
ld [wEffectFailed], a
2017-12-24 09:47:30 -08:00
farcall BattleCommand_AttackUp2
pop af
pop hl
ld [hl], a
call GetItemName
2015-09-09 16:27:07 -07:00
ld hl, BattleText_UsersStringBuffer1Activated
2019-04-08 05:15:10 -07:00
call StdBattleTextbox
2017-12-24 09:47:30 -08:00
callfar BattleCommand_StatUpMessage
pop af
bit SUBSTATUS_CONFUSED, a
ret nz
xor a
2015-12-23 11:00:29 -08:00
ld [wNumHits], a
ld de, ANIM_CONFUSED
2015-11-07 18:04:54 -08:00
call Call_PlayBattleAnim_OnlyIfVisible
call SwitchTurnCore
2014-01-05 04:28:55 -08:00
ld hl, BecameConfusedText
2019-04-08 05:15:10 -07:00
jp StdBattleTextbox
2018-06-24 07:09:41 -07:00
EnemyTriesToFlee:
ld a, [wLinkMode]
and a
2015-11-06 06:04:27 -08:00
jr z, .not_linked
ld a, [wBattleAction]
2015-11-06 06:04:27 -08:00
cp BATTLEACTION_FORFEIT
jr z, .forfeit
2015-11-06 06:04:27 -08:00
.not_linked
and a
ret
2015-11-06 06:04:27 -08:00
.forfeit
call WildFled_EnemyFled_LinkBattleCanceled
scf
ret
2018-06-24 07:09:41 -07:00
DetermineMoveOrder:
ld a, [wLinkMode]
and a
2015-11-06 06:04:27 -08:00
jr z, .use_move
ld a, [wBattleAction]
cp BATTLEACTION_STRUGGLE
2015-11-06 06:04:27 -08:00
jr z, .use_move
cp BATTLEACTION_SKIPTURN
2015-11-06 06:04:27 -08:00
jr z, .use_move
sub BATTLEACTION_SWITCH1
jr c, .use_move
ld a, [wBattlePlayerAction]
cp BATTLEPLAYERACTION_SWITCH
2015-11-05 16:13:09 -08:00
jr nz, .switch
ldh a, [hSerialConnectionStatus]
cp USING_INTERNAL_CLOCK
2015-11-06 06:04:27 -08:00
jr z, .player_2
2015-11-05 16:13:09 -08:00
call BattleRandom
2018-02-04 18:21:34 -08:00
cp 50 percent + 1
2015-11-06 06:04:27 -08:00
jp c, .player_first
jp .enemy_first
2015-11-06 06:04:27 -08:00
.player_2
call BattleRandom
2018-02-04 18:21:34 -08:00
cp 50 percent + 1
2015-11-06 06:04:27 -08:00
jp c, .enemy_first
jp .player_first
2015-11-05 16:13:09 -08:00
.switch
2017-12-24 09:47:30 -08:00
callfar AI_Switch
call SetEnemyTurn
call SpikesDamage
2015-11-06 06:04:27 -08:00
jp .enemy_first
2015-11-06 06:04:27 -08:00
.use_move
ld a, [wBattlePlayerAction]
and a ; BATTLEPLAYERACTION_USEMOVE?
2015-11-06 06:04:27 -08:00
jp nz, .player_first
2013-12-30 20:32:37 -08:00
call CompareMovePriority
2015-11-06 06:04:27 -08:00
jr z, .equal_priority
jp c, .player_first ; player goes first
jp .enemy_first
2015-11-06 06:04:27 -08:00
.equal_priority
call SetPlayerTurn
2017-12-24 09:47:30 -08:00
callfar GetUserItem
push bc
2017-12-24 09:47:30 -08:00
callfar GetOpponentItem
pop de
ld a, d
cp HELD_QUICK_CLAW
2015-11-06 06:04:27 -08:00
jr nz, .player_no_quick_claw
ld a, b
cp HELD_QUICK_CLAW
2015-11-06 06:04:27 -08:00
jr z, .both_have_quick_claw
call BattleRandom
cp e
2015-11-06 06:04:27 -08:00
jr nc, .speed_check
jp .player_first
2015-11-06 06:04:27 -08:00
.player_no_quick_claw
ld a, b
cp HELD_QUICK_CLAW
2015-11-06 06:04:27 -08:00
jr nz, .speed_check
call BattleRandom
cp c
2015-11-06 06:04:27 -08:00
jr nc, .speed_check
jp .enemy_first
2015-11-06 06:04:27 -08:00
.both_have_quick_claw
ldh a, [hSerialConnectionStatus]
cp USING_INTERNAL_CLOCK
2015-11-06 06:04:27 -08:00
jr z, .player_2b
call BattleRandom
cp c
2015-11-06 06:04:27 -08:00
jp c, .enemy_first
call BattleRandom
cp e
2015-11-06 06:04:27 -08:00
jp c, .player_first
jr .speed_check
2015-11-06 06:04:27 -08:00
.player_2b
call BattleRandom
cp e
2015-11-06 06:04:27 -08:00
jp c, .player_first
call BattleRandom
cp c
2015-11-06 06:04:27 -08:00
jp c, .enemy_first
jr .speed_check
2015-11-06 06:04:27 -08:00
.speed_check
2018-01-23 14:39:09 -08:00
ld de, wBattleMonSpeed
ld hl, wEnemyMonSpeed
2015-11-06 06:04:27 -08:00
ld c, 2
call CompareBytes
2015-11-06 06:04:27 -08:00
jr z, .speed_tie
jp nc, .player_first
jp .enemy_first
2015-11-06 06:04:27 -08:00
.speed_tie
ldh a, [hSerialConnectionStatus]
cp USING_INTERNAL_CLOCK
2015-11-06 06:04:27 -08:00
jr z, .player_2c
call BattleRandom
2018-02-04 18:21:34 -08:00
cp 50 percent + 1
2015-11-06 06:04:27 -08:00
jp c, .player_first
jp .enemy_first
2015-11-06 06:04:27 -08:00
.player_2c
call BattleRandom
2018-02-04 18:21:34 -08:00
cp 50 percent + 1
2015-11-06 06:04:27 -08:00
jp c, .enemy_first
.player_first
scf
ret
2018-06-24 07:09:41 -07:00
.enemy_first
and a
ret
2018-06-24 07:09:41 -07:00
CheckContestBattleOver:
2018-01-23 14:39:09 -08:00
ld a, [wBattleType]
cp BATTLETYPE_CONTEST
2015-11-08 10:27:26 -08:00
jr nz, .contest_not_over
ld a, [wParkBallsRemaining]
and a
2015-11-08 10:27:26 -08:00
jr nz, .contest_not_over
2015-10-24 07:34:19 -07:00
ld a, [wBattleResult]
2018-04-05 08:44:02 -07:00
and BATTLERESULT_BITMASK
add DRAW
2015-10-24 07:34:19 -07:00
ld [wBattleResult], a
scf
ret
2015-11-08 10:27:26 -08:00
.contest_not_over
and a
ret
2018-06-24 07:09:41 -07:00
CheckPlayerLockedIn:
2018-01-23 14:39:09 -08:00
ld a, [wPlayerSubStatus4]
and 1 << SUBSTATUS_RECHARGE
jp nz, .quit
2018-01-23 14:39:09 -08:00
ld hl, wEnemySubStatus3
res SUBSTATUS_FLINCHED, [hl]
2018-01-23 14:39:09 -08:00
ld hl, wPlayerSubStatus3
res SUBSTATUS_FLINCHED, [hl]
ld a, [hl]
and 1 << SUBSTATUS_CHARGED | 1 << SUBSTATUS_RAMPAGE
jp nz, .quit
2018-01-23 14:39:09 -08:00
ld hl, wPlayerSubStatus1
bit SUBSTATUS_ROLLOUT, [hl]
jp nz, .quit
and a
ret
.quit
scf
ret
2018-06-24 07:09:41 -07:00
ParsePlayerAction:
2015-11-08 16:09:36 -08:00
call CheckPlayerLockedIn
jp c, .locked_in
2018-01-23 14:39:09 -08:00
ld hl, wPlayerSubStatus5
bit SUBSTATUS_ENCORED, [hl]
2015-11-08 16:09:36 -08:00
jr z, .not_encored
2018-01-23 14:39:09 -08:00
ld a, [wLastPlayerMove]
ld [wCurPlayerMove], a
2015-11-08 16:09:36 -08:00
jr .encored
2015-11-08 16:09:36 -08:00
.not_encored
ld a, [wBattlePlayerAction]
cp BATTLEPLAYERACTION_SWITCH
2015-11-08 16:09:36 -08:00
jr z, .reset_rage
and a
2015-11-08 16:09:36 -08:00
jr nz, .reset_bide
2018-01-23 14:39:09 -08:00
ld a, [wPlayerSubStatus3]
and 1 << SUBSTATUS_BIDE
2015-11-08 16:09:36 -08:00
jr nz, .locked_in
xor a
2015-11-23 13:04:53 -08:00
ld [wMoveSelectionMenuType], a
inc a ; POUND
2018-01-23 14:39:09 -08:00
ld [wFXAnimID], a
2015-10-10 04:45:39 -07:00
call MoveSelectionScreen
push af
call SafeLoadTempTilemapToTilemap
call UpdateBattleHuds
2018-01-23 14:39:09 -08:00
ld a, [wCurPlayerMove]
cp STRUGGLE
2015-11-08 16:09:36 -08:00
jr z, .struggle
call PlayClickSFX
2015-11-08 16:09:36 -08:00
.struggle
ld a, $1
ldh [hBGMapMode], a
pop af
ret nz
2015-11-08 16:09:36 -08:00
.encored
call SetPlayerTurn
2017-12-24 09:47:30 -08:00
callfar UpdateMoveData
xor a
2015-11-07 18:04:54 -08:00
ld [wPlayerCharging], a
ld a, [wPlayerMoveStruct + MOVE_EFFECT]
cp EFFECT_FURY_CUTTER
2015-11-08 16:09:36 -08:00
jr z, .continue_fury_cutter
xor a
2018-01-23 14:39:09 -08:00
ld [wPlayerFuryCutterCount], a
2015-11-08 16:09:36 -08:00
.continue_fury_cutter
ld a, [wPlayerMoveStruct + MOVE_EFFECT]
cp EFFECT_RAGE
2015-11-08 16:09:36 -08:00
jr z, .continue_rage
2018-01-23 14:39:09 -08:00
ld hl, wPlayerSubStatus4
res SUBSTATUS_RAGE, [hl]
xor a
2015-11-05 16:13:09 -08:00
ld [wPlayerRageCounter], a
2015-11-08 16:09:36 -08:00
.continue_rage
ld a, [wPlayerMoveStruct + MOVE_EFFECT]
cp EFFECT_PROTECT
2015-11-08 16:09:36 -08:00
jr z, .continue_protect
cp EFFECT_ENDURE
2015-11-08 16:09:36 -08:00
jr z, .continue_protect
xor a
2018-01-23 14:39:09 -08:00
ld [wPlayerProtectCount], a
2015-11-08 16:09:36 -08:00
jr .continue_protect
2015-11-08 16:09:36 -08:00
.reset_bide
2018-01-23 14:39:09 -08:00
ld hl, wPlayerSubStatus3
res SUBSTATUS_BIDE, [hl]
2015-11-08 16:09:36 -08:00
.locked_in
xor a
2018-01-23 14:39:09 -08:00
ld [wPlayerFuryCutterCount], a
ld [wPlayerProtectCount], a
2015-11-05 16:13:09 -08:00
ld [wPlayerRageCounter], a
2018-01-23 14:39:09 -08:00
ld hl, wPlayerSubStatus4
res SUBSTATUS_RAGE, [hl]
2015-11-08 16:09:36 -08:00
.continue_protect
call ParseEnemyAction
xor a
ret
2015-11-08 16:09:36 -08:00
.reset_rage
xor a
2018-01-23 14:39:09 -08:00
ld [wPlayerFuryCutterCount], a
ld [wPlayerProtectCount], a
2015-11-05 16:13:09 -08:00
ld [wPlayerRageCounter], a
2018-01-23 14:39:09 -08:00
ld hl, wPlayerSubStatus4
res SUBSTATUS_RAGE, [hl]
xor a
ret
2018-06-24 07:09:41 -07:00
HandleEncore:
ldh a, [hSerialConnectionStatus]
cp USING_EXTERNAL_CLOCK
2015-11-23 13:04:53 -08:00
jr z, .player_1
call .do_player
jr .do_enemy
2015-11-23 13:04:53 -08:00
.player_1
call .do_enemy
.do_player
2018-01-23 14:39:09 -08:00
ld hl, wPlayerSubStatus5
bit SUBSTATUS_ENCORED, [hl]
ret z
2018-01-23 14:39:09 -08:00
ld a, [wPlayerEncoreCount]
dec a
2018-01-23 14:39:09 -08:00
ld [wPlayerEncoreCount], a
2015-11-23 13:04:53 -08:00
jr z, .end_player_encore
2018-01-23 14:39:09 -08:00
ld hl, wBattleMonPP
ld a, [wCurMoveNum]
ld c, a
ld b, 0
add hl, bc
ld a, [hl]
2018-01-11 09:00:01 -08:00
and PP_MASK
ret nz
2015-11-23 13:04:53 -08:00
.end_player_encore
2018-01-23 14:39:09 -08:00
ld hl, wPlayerSubStatus5
res SUBSTATUS_ENCORED, [hl]
call SetEnemyTurn
2015-09-09 16:27:07 -07:00
ld hl, BattleText_TargetsEncoreEnded
2019-04-08 05:15:10 -07:00
jp StdBattleTextbox
2015-11-23 13:04:53 -08:00
.do_enemy
2018-01-23 14:39:09 -08:00
ld hl, wEnemySubStatus5
bit SUBSTATUS_ENCORED, [hl]
ret z
2018-01-23 14:39:09 -08:00
ld a, [wEnemyEncoreCount]
dec a
2018-01-23 14:39:09 -08:00
ld [wEnemyEncoreCount], a
2015-11-23 13:04:53 -08:00
jr z, .end_enemy_encore
2018-01-23 14:39:09 -08:00
ld hl, wEnemyMonPP
ld a, [wCurEnemyMoveNum]
ld c, a
ld b, 0
add hl, bc
ld a, [hl]
2018-01-11 09:00:01 -08:00
and PP_MASK
ret nz
2015-11-23 13:04:53 -08:00
.end_enemy_encore
2018-01-23 14:39:09 -08:00
ld hl, wEnemySubStatus5
res SUBSTATUS_ENCORED, [hl]
call SetPlayerTurn
2015-09-09 16:27:07 -07:00
ld hl, BattleText_TargetsEncoreEnded
2019-04-08 05:15:10 -07:00
jp StdBattleTextbox
2018-06-24 07:09:41 -07:00
TryEnemyFlee:
ld a, [wBattleMode]
dec a
jr nz, .Stay
2018-01-23 14:39:09 -08:00
ld a, [wPlayerSubStatus5]
bit SUBSTATUS_CANT_RUN, a
jr nz, .Stay
2015-11-08 10:27:26 -08:00
ld a, [wEnemyWrapCount]
and a
jr nz, .Stay
2018-01-23 14:39:09 -08:00
ld a, [wEnemyMonStatus]
and 1 << FRZ | SLP_MASK
jr nz, .Stay
2018-01-23 14:39:09 -08:00
ld a, [wTempEnemyMonSpecies]
ld de, 1
2013-12-24 14:19:39 -08:00
ld hl, AlwaysFleeMons
call IsInArray
jr c, .Flee
call BattleRandom
ld b, a
2018-02-04 18:21:34 -08:00
cp 50 percent + 1
jr nc, .Stay
push bc
2018-01-23 14:39:09 -08:00
ld a, [wTempEnemyMonSpecies]
ld de, 1
2013-12-24 14:19:39 -08:00
ld hl, OftenFleeMons
call IsInArray
pop bc
jr c, .Flee
ld a, b
2018-02-04 18:21:34 -08:00
cp 10 percent + 1
jr nc, .Stay
2018-01-23 14:39:09 -08:00
ld a, [wTempEnemyMonSpecies]
ld de, 1
2013-12-24 14:19:39 -08:00
ld hl, SometimesFleeMons
call IsInArray
jr c, .Flee
.Stay:
and a
ret
.Flee:
scf
ret
INCLUDE "data/wild/flee_mons.asm"
2018-06-24 07:09:41 -07:00
CompareMovePriority:
2013-12-30 20:32:37 -08:00
; Compare the priority of the player and enemy's moves.
; Return carry if the player goes first, or z if they match.
2018-01-23 14:39:09 -08:00
ld a, [wCurPlayerMove]
call GetMovePriority
ld b, a
push bc
2018-01-23 14:39:09 -08:00
ld a, [wCurEnemyMove]
call GetMovePriority
pop bc
cp b
ret
2018-06-24 07:09:41 -07:00
GetMovePriority:
2013-12-30 20:32:37 -08:00
; Return the priority (0-3) of move a.
ld b, a
2013-12-30 20:32:37 -08:00
; Vital Throw goes last.
cp VITAL_THROW
ld a, 0
ret z
2013-12-30 20:32:37 -08:00
call GetMoveEffect
ld hl, MoveEffectPriorities
.loop
ld a, [hli]
cp b
2013-12-30 20:32:37 -08:00
jr z, .done
inc hl
2013-12-30 20:32:37 -08:00
cp -1
jr nz, .loop
2013-12-30 20:32:37 -08:00
2018-01-09 12:39:48 -08:00
ld a, BASE_PRIORITY
ret
2013-12-30 20:32:37 -08:00
.done
ld a, [hl]
ret
INCLUDE "data/moves/effects_priorities.asm"
2018-06-24 07:09:41 -07:00
GetMoveEffect:
ld a, b
dec a
2013-12-30 20:22:27 -08:00
ld hl, Moves + MOVE_EFFECT
ld bc, MOVE_LENGTH
call AddNTimes
2013-12-30 20:22:27 -08:00
ld a, BANK(Moves)
call GetFarByte
ld b, a
ret
2018-06-24 07:09:41 -07:00
Battle_EnemyFirst:
call LoadTilemapToTempTilemap
2015-11-07 18:04:54 -08:00
call TryEnemyFlee
jp c, WildFled_EnemyFled_LinkBattleCanceled
call SetEnemyTurn
ld a, $1
2015-11-08 16:09:36 -08:00
ld [wEnemyGoesFirst], a
2017-12-24 09:47:30 -08:00
callfar AI_SwitchOrTryItem
2015-11-07 18:04:54 -08:00
jr c, .switch_item
call EnemyTurn_EndOpponentProtectEndureDestinyBond
2015-11-08 16:09:36 -08:00
ld a, [wForcedSwitch]
and a
ret nz
call HasPlayerFainted
2015-10-19 13:49:29 -07:00
jp z, HandlePlayerMonFaint
call HasEnemyFainted
2015-10-19 13:49:29 -07:00
jp z, HandleEnemyMonFaint
2015-11-07 18:04:54 -08:00
.switch_item
call SetEnemyTurn
call ResidualDamage
2015-10-19 13:49:29 -07:00
jp z, HandleEnemyMonFaint
call RefreshBattleHuds
2015-11-07 18:04:54 -08:00
call PlayerTurn_EndOpponentProtectEndureDestinyBond
2015-11-08 16:09:36 -08:00
ld a, [wForcedSwitch]
and a
ret nz
call HasEnemyFainted
2015-10-19 13:49:29 -07:00
jp z, HandleEnemyMonFaint
call HasPlayerFainted
2015-10-19 13:49:29 -07:00
jp z, HandlePlayerMonFaint
call SetPlayerTurn
call ResidualDamage
2015-10-19 13:49:29 -07:00
jp z, HandlePlayerMonFaint
call RefreshBattleHuds
xor a ; BATTLEPLAYERACTION_USEMOVE
ld [wBattlePlayerAction], a
ret
2018-06-24 07:09:41 -07:00
Battle_PlayerFirst:
xor a
2015-11-08 16:09:36 -08:00
ld [wEnemyGoesFirst], a
call SetEnemyTurn
2017-12-24 09:47:30 -08:00
callfar AI_SwitchOrTryItem
push af
2015-11-07 18:04:54 -08:00
call PlayerTurn_EndOpponentProtectEndureDestinyBond
pop bc
2015-11-08 16:09:36 -08:00
ld a, [wForcedSwitch]
and a
ret nz
call HasEnemyFainted
2015-10-19 13:49:29 -07:00
jp z, HandleEnemyMonFaint
call HasPlayerFainted
2015-10-19 13:49:29 -07:00
jp z, HandlePlayerMonFaint
push bc
call SetPlayerTurn
call ResidualDamage
pop bc
2015-10-19 13:49:29 -07:00
jp z, HandlePlayerMonFaint
push bc
call RefreshBattleHuds
pop af
2015-11-07 18:04:54 -08:00
jr c, .switched_or_used_item
call LoadTilemapToTempTilemap
2015-11-07 18:04:54 -08:00
call TryEnemyFlee
jp c, WildFled_EnemyFled_LinkBattleCanceled
2015-11-07 18:04:54 -08:00
call EnemyTurn_EndOpponentProtectEndureDestinyBond
2015-11-08 16:09:36 -08:00
ld a, [wForcedSwitch]
and a
ret nz
call HasPlayerFainted
2015-10-19 13:49:29 -07:00
jp z, HandlePlayerMonFaint
call HasEnemyFainted
2015-10-19 13:49:29 -07:00
jp z, HandleEnemyMonFaint
2015-11-07 18:04:54 -08:00
.switched_or_used_item
call SetEnemyTurn
call ResidualDamage
2015-10-19 13:49:29 -07:00
jp z, HandleEnemyMonFaint
call RefreshBattleHuds
xor a ; BATTLEPLAYERACTION_USEMOVE
ld [wBattlePlayerAction], a
ret
2018-06-24 07:09:41 -07:00
PlayerTurn_EndOpponentProtectEndureDestinyBond:
call SetPlayerTurn
2015-11-07 18:04:54 -08:00
call EndUserDestinyBond
2017-12-24 09:47:30 -08:00
callfar DoPlayerTurn
2015-11-07 18:04:54 -08:00
jp EndOpponentProtectEndureDestinyBond
2018-06-24 07:09:41 -07:00
EnemyTurn_EndOpponentProtectEndureDestinyBond:
call SetEnemyTurn
2015-11-07 18:04:54 -08:00
call EndUserDestinyBond
2017-12-24 09:47:30 -08:00
callfar DoEnemyTurn
2015-11-07 18:04:54 -08:00
jp EndOpponentProtectEndureDestinyBond
2018-06-24 07:09:41 -07:00
EndOpponentProtectEndureDestinyBond:
ld a, BATTLE_VARS_SUBSTATUS1_OPP
call GetBattleVarAddr
res SUBSTATUS_PROTECT, [hl]
res SUBSTATUS_ENDURE, [hl]
ld a, BATTLE_VARS_SUBSTATUS5_OPP
call GetBattleVarAddr
res SUBSTATUS_DESTINY_BOND, [hl]
ret
2018-06-24 07:09:41 -07:00
EndUserDestinyBond:
ld a, BATTLE_VARS_SUBSTATUS5
call GetBattleVarAddr
res SUBSTATUS_DESTINY_BOND, [hl]
ret
2018-06-24 07:09:41 -07:00
HasUserFainted:
ldh a, [hBattleTurn]
and a
jr z, HasPlayerFainted
2018-06-24 07:09:41 -07:00
HasEnemyFainted:
2018-01-23 14:39:09 -08:00
ld hl, wEnemyMonHP
2015-09-09 16:27:07 -07:00
jr CheckIfHPIsZero
2018-06-24 07:09:41 -07:00
HasPlayerFainted:
2018-01-23 14:39:09 -08:00
ld hl, wBattleMonHP
2018-06-24 07:09:41 -07:00
CheckIfHPIsZero:
ld a, [hli]
or [hl]
ret
2018-06-24 07:09:41 -07:00
ResidualDamage:
; Return z if the user fainted before
; or as a result of residual damage.
; For Sandstorm damage, see HandleWeather.
call HasUserFainted
ret z
ld a, BATTLE_VARS_STATUS
call GetBattleVar
and 1 << PSN | 1 << BRN
jr z, .did_psn_brn
ld hl, HurtByPoisonText
ld de, ANIM_PSN
and 1 << BRN
jr z, .got_anim
ld hl, HurtByBurnText
ld de, ANIM_BRN
.got_anim
push de
2019-04-08 05:15:10 -07:00
call StdBattleTextbox
pop de
xor a
2015-12-23 11:00:29 -08:00
ld [wNumHits], a
2015-11-07 18:04:54 -08:00
call Call_PlayBattleAnim_OnlyIfVisible
call GetEighthMaxHP
2018-01-23 14:39:09 -08:00
ld de, wPlayerToxicCount
ldh a, [hBattleTurn]
and a
2015-11-07 18:04:54 -08:00
jr z, .check_toxic
2018-01-23 14:39:09 -08:00
ld de, wEnemyToxicCount
2015-11-07 18:04:54 -08:00
.check_toxic
ld a, BATTLE_VARS_SUBSTATUS5
call GetBattleVar
bit SUBSTATUS_TOXIC, a
jr z, .did_toxic
call GetSixteenthMaxHP
ld a, [de]
inc a
ld [de], a
ld hl, 0
.add
add hl, bc
dec a
jr nz, .add
ld b, h
ld c, l
.did_toxic
2015-11-06 17:55:16 -08:00
call SubtractHPFromUser
.did_psn_brn
call HasUserFainted
jp z, .fainted
ld a, BATTLE_VARS_SUBSTATUS4
call GetBattleVarAddr
bit SUBSTATUS_LEECH_SEED, [hl]
2015-11-07 18:04:54 -08:00
jr z, .not_seeded
call SwitchTurnCore
xor a
2015-12-23 11:00:29 -08:00
ld [wNumHits], a
ld de, ANIM_SAP
ld a, BATTLE_VARS_SUBSTATUS3_OPP
call GetBattleVar
and 1 << SUBSTATUS_FLYING | 1 << SUBSTATUS_UNDERGROUND
2015-11-07 18:04:54 -08:00
call z, Call_PlayBattleAnim_OnlyIfVisible
call SwitchTurnCore
call GetEighthMaxHP
2015-11-06 17:55:16 -08:00
call SubtractHPFromUser
ld a, $1
ldh [hBGMapMode], a
2015-11-06 19:36:06 -08:00
call RestoreHP
ld hl, LeechSeedSapsText
2019-04-08 05:15:10 -07:00
call StdBattleTextbox
2015-11-07 18:04:54 -08:00
.not_seeded
call HasUserFainted
jr z, .fainted
ld a, BATTLE_VARS_SUBSTATUS1
call GetBattleVarAddr
bit SUBSTATUS_NIGHTMARE, [hl]
2015-11-07 18:04:54 -08:00
jr z, .not_nightmare
xor a
2015-12-23 11:00:29 -08:00
ld [wNumHits], a
ld de, ANIM_IN_NIGHTMARE
2015-11-07 18:04:54 -08:00
call Call_PlayBattleAnim_OnlyIfVisible
call GetQuarterMaxHP
2015-11-06 17:55:16 -08:00
call SubtractHPFromUser
ld hl, HasANightmareText
2019-04-08 05:15:10 -07:00
call StdBattleTextbox
2015-11-07 18:04:54 -08:00
.not_nightmare
call HasUserFainted
jr z, .fainted
ld a, BATTLE_VARS_SUBSTATUS1
call GetBattleVarAddr
bit SUBSTATUS_CURSE, [hl]
2015-11-07 18:04:54 -08:00
jr z, .not_cursed
xor a
2015-12-23 11:00:29 -08:00
ld [wNumHits], a
ld de, ANIM_IN_NIGHTMARE
2015-11-07 18:04:54 -08:00
call Call_PlayBattleAnim_OnlyIfVisible
call GetQuarterMaxHP
2015-11-06 17:55:16 -08:00
call SubtractHPFromUser
ld hl, HurtByCurseText
2019-04-08 05:15:10 -07:00
call StdBattleTextbox
2015-11-07 18:04:54 -08:00
.not_cursed
2018-01-23 14:39:09 -08:00
ld hl, wBattleMonHP
ldh a, [hBattleTurn]
and a
2015-11-07 18:04:54 -08:00
jr z, .check_fainted
2018-01-23 14:39:09 -08:00
ld hl, wEnemyMonHP
2015-11-07 18:04:54 -08:00
.check_fainted
ld a, [hli]
or [hl]
ret nz
.fainted
call RefreshBattleHuds
ld c, 20
call DelayFrames
xor a
ret
2018-06-24 07:09:41 -07:00
HandlePerishSong:
ldh a, [hSerialConnectionStatus]
cp USING_EXTERNAL_CLOCK
2015-11-08 10:27:26 -08:00
jr z, .EnemyFirst
call SetPlayerTurn
2015-11-08 10:27:26 -08:00
call .do_it
call SetEnemyTurn
2015-11-08 10:27:26 -08:00
jp .do_it
.EnemyFirst:
call SetEnemyTurn
2015-11-08 10:27:26 -08:00
call .do_it
call SetPlayerTurn
2015-11-08 10:27:26 -08:00
.do_it
2018-01-23 14:39:09 -08:00
ld hl, wPlayerPerishCount
ldh a, [hBattleTurn]
and a
2015-11-08 10:27:26 -08:00
jr z, .got_count
2018-01-23 14:39:09 -08:00
ld hl, wEnemyPerishCount
2015-11-08 10:27:26 -08:00
.got_count
ld a, BATTLE_VARS_SUBSTATUS1
call GetBattleVar
bit SUBSTATUS_PERISH, a
ret z
dec [hl]
ld a, [hl]
ld [wTextDecimalByte], a
push af
ld hl, PerishCountText
2019-04-08 05:15:10 -07:00
call StdBattleTextbox
pop af
ret nz
ld a, BATTLE_VARS_SUBSTATUS1
call GetBattleVarAddr
res SUBSTATUS_PERISH, [hl]
ldh a, [hBattleTurn]
and a
2016-01-17 21:39:01 -08:00
jr nz, .kill_enemy
2018-01-23 14:39:09 -08:00
ld hl, wBattleMonHP
xor a
ld [hli], a
ld [hl], a
2018-01-23 14:39:09 -08:00
ld hl, wPartyMon1HP
ld a, [wCurBattleMon]
call GetPartyLocation
xor a
ld [hli], a
ld [hl], a
ret
2016-01-17 21:39:01 -08:00
.kill_enemy
2018-01-23 14:39:09 -08:00
ld hl, wEnemyMonHP
xor a
ld [hli], a
ld [hl], a
ld a, [wBattleMode]
dec a
ret z
2018-01-23 14:39:09 -08:00
ld hl, wOTPartyMon1HP
ld a, [wCurOTMon]
call GetPartyLocation
xor a
ld [hli], a
ld [hl], a
ret
2018-06-24 07:09:41 -07:00
HandleWrap:
ldh a, [hSerialConnectionStatus]
cp USING_EXTERNAL_CLOCK
2015-11-08 10:27:26 -08:00
jr z, .EnemyFirst
call SetPlayerTurn
2015-11-08 10:27:26 -08:00
call .do_it
call SetEnemyTurn
2015-11-08 10:27:26 -08:00
jp .do_it
.EnemyFirst:
call SetEnemyTurn
2015-11-08 10:27:26 -08:00
call .do_it
call SetPlayerTurn
2015-11-08 10:27:26 -08:00
.do_it
ld hl, wPlayerWrapCount
ld de, wPlayerTrappingMove
ldh a, [hBattleTurn]
and a
2015-11-08 10:27:26 -08:00
jr z, .got_addrs
ld hl, wEnemyWrapCount
ld de, wEnemyTrappingMove
2015-11-08 10:27:26 -08:00
.got_addrs
ld a, [hl]
and a
ret z
2015-11-08 10:27:26 -08:00
ld a, BATTLE_VARS_SUBSTATUS4
call GetBattleVar
bit SUBSTATUS_SUBSTITUTE, a
ret nz
2015-11-08 10:27:26 -08:00
ld a, [de]
ld [wNamedObjectIndex], a
2018-01-23 14:39:09 -08:00
ld [wFXAnimID], a
call GetMoveName
dec [hl]
2015-11-08 10:27:26 -08:00
jr z, .release_from_bounds
ld a, BATTLE_VARS_SUBSTATUS3
call GetBattleVar
and 1 << SUBSTATUS_FLYING | 1 << SUBSTATUS_UNDERGROUND
2015-11-08 10:27:26 -08:00
jr nz, .skip_anim
call SwitchTurnCore
xor a
2015-12-23 11:00:29 -08:00
ld [wNumHits], a
2018-01-23 14:39:09 -08:00
ld [wFXAnimID + 1], a
predef PlayBattleAnim
call SwitchTurnCore
2015-11-08 10:27:26 -08:00
.skip_anim
call GetSixteenthMaxHP
2015-11-06 17:55:16 -08:00
call SubtractHPFromUser
2015-09-09 16:27:07 -07:00
ld hl, BattleText_UsersHurtByStringBuffer1
2016-01-17 21:39:01 -08:00
jr .print_text
2015-11-08 10:27:26 -08:00
.release_from_bounds
2015-09-09 16:27:07 -07:00
ld hl, BattleText_UserWasReleasedFromStringBuffer1
2016-01-17 21:39:01 -08:00
.print_text
2019-04-08 05:15:10 -07:00
jp StdBattleTextbox
2018-06-24 07:09:41 -07:00
SwitchTurnCore:
ldh a, [hBattleTurn]
xor 1
ldh [hBattleTurn], a
ret
2018-06-24 07:09:41 -07:00
HandleLeftovers:
ldh a, [hSerialConnectionStatus]
cp USING_EXTERNAL_CLOCK
2015-11-08 10:27:26 -08:00
jr z, .DoEnemyFirst
call SetPlayerTurn
2015-11-08 10:27:26 -08:00
call .do_it
call SetEnemyTurn
2015-11-08 10:27:26 -08:00
jp .do_it
.DoEnemyFirst:
call SetEnemyTurn
2015-11-08 10:27:26 -08:00
call .do_it
call SetPlayerTurn
2015-11-08 10:27:26 -08:00
.do_it
2017-12-24 09:47:30 -08:00
callfar GetUserItem
ld a, [hl]
ld [wNamedObjectIndex], a
call GetItemName
ld a, b
cp HELD_LEFTOVERS
ret nz
2015-11-08 10:27:26 -08:00
2018-01-23 14:39:09 -08:00
ld hl, wBattleMonHP
ldh a, [hBattleTurn]
and a
2015-11-08 10:27:26 -08:00
jr z, .got_hp
2018-01-23 14:39:09 -08:00
ld hl, wEnemyMonHP
2015-11-08 10:27:26 -08:00
.got_hp
; Don't restore if we're already at max HP
ld a, [hli]
ld b, a
ld a, [hli]
ld c, a
ld a, [hli]
cp b
2015-11-08 10:27:26 -08:00
jr nz, .restore
ld a, [hl]
cp c
ret z
2015-11-08 10:27:26 -08:00
.restore
call GetSixteenthMaxHP
call SwitchTurnCore
2015-11-06 19:36:06 -08:00
call RestoreHP
2016-01-17 21:39:01 -08:00
ld hl, BattleText_TargetRecoveredWithItem
2019-04-08 05:15:10 -07:00
jp StdBattleTextbox
2018-06-24 07:09:41 -07:00
HandleMysteryberry:
ldh a, [hSerialConnectionStatus]
cp USING_EXTERNAL_CLOCK
2015-11-08 10:27:26 -08:00
jr z, .DoEnemyFirst
call SetPlayerTurn
2015-11-08 10:27:26 -08:00
call .do_it
call SetEnemyTurn
2015-11-08 10:27:26 -08:00
jp .do_it
.DoEnemyFirst:
call SetEnemyTurn
2015-11-08 10:27:26 -08:00
call .do_it
call SetPlayerTurn
2015-11-08 10:27:26 -08:00
.do_it
2017-12-24 09:47:30 -08:00
callfar GetUserItem
ld a, b
cp HELD_RESTORE_PP
2015-11-08 10:27:26 -08:00
jr nz, .quit
2018-01-23 14:39:09 -08:00
ld hl, wPartyMon1PP
ld a, [wCurBattleMon]
call GetPartyLocation
ld d, h
ld e, l
2018-01-23 14:39:09 -08:00
ld hl, wPartyMon1Moves
ld a, [wCurBattleMon]
call GetPartyLocation
ldh a, [hBattleTurn]
and a
2015-11-08 10:27:26 -08:00
jr z, .wild
2015-11-29 18:34:59 -08:00
ld de, wWildMonPP
ld hl, wWildMonMoves
ld a, [wBattleMode]
dec a
2015-11-08 10:27:26 -08:00
jr z, .wild
2018-01-23 14:39:09 -08:00
ld hl, wOTPartyMon1PP
ld a, [wCurOTMon]
call GetPartyLocation
ld d, h
ld e, l
2018-01-23 14:39:09 -08:00
ld hl, wOTPartyMon1Moves
ld a, [wCurOTMon]
call GetPartyLocation
2015-11-08 10:27:26 -08:00
.wild
ld c, $0
2015-11-08 10:27:26 -08:00
.loop
ld a, [hl]
and a
2015-11-08 10:27:26 -08:00
jr z, .quit
ld a, [de]
2018-01-11 09:00:01 -08:00
and PP_MASK
2015-11-08 10:27:26 -08:00
jr z, .restore
inc hl
inc de
inc c
ld a, c
cp NUM_MOVES
2015-11-08 10:27:26 -08:00
jr nz, .loop
2015-11-08 10:27:26 -08:00
.quit
ret
2015-11-08 10:27:26 -08:00
.restore
; lousy hack
ld a, [hl]
cp SKETCH
ld b, 1
2015-11-08 10:27:26 -08:00
jr z, .sketch
ld b, 5
2015-11-08 10:27:26 -08:00
.sketch
ld a, [de]
add b
ld [de], a
push bc
push bc
ld a, [hl]
ld [wTempByteValue], a
2018-01-23 14:39:09 -08:00
ld de, wBattleMonMoves - 1
ld hl, wBattleMonPP
ldh a, [hBattleTurn]
and a
2015-11-08 10:27:26 -08:00
jr z, .player_pp
2018-01-23 14:39:09 -08:00
ld de, wEnemyMonMoves - 1
ld hl, wEnemyMonPP
2015-11-08 10:27:26 -08:00
.player_pp
inc de
pop bc
ld b, 0
add hl, bc
push hl
ld h, d
ld l, e
add hl, bc
pop de
pop bc
ld a, [wTempByteValue]
cp [hl]
2015-11-08 10:27:26 -08:00
jr nz, .skip_checks
ldh a, [hBattleTurn]
and a
2018-01-23 14:39:09 -08:00
ld a, [wPlayerSubStatus5]
2015-11-08 10:27:26 -08:00
jr z, .check_transform
2018-01-23 14:39:09 -08:00
ld a, [wEnemySubStatus5]
2015-11-08 10:27:26 -08:00
.check_transform
bit SUBSTATUS_TRANSFORMED, a
2015-11-08 10:27:26 -08:00
jr nz, .skip_checks
ld a, [de]
add b
ld [de], a
2015-11-08 10:27:26 -08:00
.skip_checks
2017-12-24 09:47:30 -08:00
callfar GetUserItem
ld a, [hl]
ld [wNamedObjectIndex], a
xor a
ld [hl], a
2015-11-08 10:27:26 -08:00
call GetPartymonItem
ldh a, [hBattleTurn]
and a
2015-11-08 10:27:26 -08:00
jr z, .consume_item
ld a, [wBattleMode]
dec a
2015-11-08 10:27:26 -08:00
jr z, .skip_consumption
call GetOTPartymonItem
2015-11-08 10:27:26 -08:00
.consume_item
xor a
ld [hl], a
2015-11-08 10:27:26 -08:00
.skip_consumption
call GetItemName
call SwitchTurnCore
2015-11-06 19:36:06 -08:00
call ItemRecoveryAnim
call SwitchTurnCore
ld hl, BattleText_UserRecoveredPPUsing
2019-04-08 05:15:10 -07:00
jp StdBattleTextbox
2018-06-24 07:09:41 -07:00
HandleFutureSight:
ldh a, [hSerialConnectionStatus]
cp USING_EXTERNAL_CLOCK
2015-11-08 10:27:26 -08:00
jr z, .enemy_first
call SetPlayerTurn
2015-11-08 10:27:26 -08:00
call .do_it
call SetEnemyTurn
2015-11-08 10:27:26 -08:00
jp .do_it
2015-11-08 10:27:26 -08:00
.enemy_first
call SetEnemyTurn
2015-11-08 10:27:26 -08:00
call .do_it
call SetPlayerTurn
2015-11-08 10:27:26 -08:00
.do_it
ld hl, wPlayerFutureSightCount
ldh a, [hBattleTurn]
and a
2015-11-08 10:27:26 -08:00
jr z, .okay
ld hl, wEnemyFutureSightCount
2015-11-08 10:27:26 -08:00
.okay
ld a, [hl]
and a
ret z
dec a
ld [hl], a
cp $1
ret nz
2016-01-17 21:39:01 -08:00
ld hl, BattleText_TargetWasHitByFutureSight
2019-04-08 05:15:10 -07:00
call StdBattleTextbox
ld a, BATTLE_VARS_MOVE
call GetBattleVarAddr
push af
ld a, FUTURE_SIGHT
ld [hl], a
2017-12-24 09:47:30 -08:00
callfar UpdateMoveData
xor a
2018-01-23 14:39:09 -08:00
ld [wAttackMissed], a
ld [wAlreadyDisobeyed], a
2018-03-09 13:09:03 -08:00
ld a, EFFECTIVE
2018-01-23 14:39:09 -08:00
ld [wTypeModifier], a
2017-12-24 09:47:30 -08:00
callfar DoMove
xor a
2018-01-23 14:39:09 -08:00
ld [wCurDamage], a
ld [wCurDamage + 1], a
ld a, BATTLE_VARS_MOVE
call GetBattleVarAddr
pop af
ld [hl], a
call UpdateBattleMonInParty
jp UpdateEnemyMonInParty
2018-06-24 07:09:41 -07:00
HandleDefrost:
ldh a, [hSerialConnectionStatus]
cp USING_EXTERNAL_CLOCK
jr z, .enemy_first
call .do_player_turn
jr .do_enemy_turn
.enemy_first
call .do_enemy_turn
.do_player_turn
2018-01-23 14:39:09 -08:00
ld a, [wBattleMonStatus]
bit FRZ, a
ret z
ld a, [wPlayerJustGotFrozen]
and a
ret nz
call BattleRandom
cp 10 percent
ret nc
xor a
2018-01-23 14:39:09 -08:00
ld [wBattleMonStatus], a
ld a, [wCurBattleMon]
ld hl, wPartyMon1Status
call GetPartyLocation
ld [hl], 0
call UpdateBattleHuds
call SetEnemyTurn
2014-01-05 04:28:55 -08:00
ld hl, DefrostedOpponentText
2019-04-08 05:15:10 -07:00
jp StdBattleTextbox
.do_enemy_turn
2018-01-23 14:39:09 -08:00
ld a, [wEnemyMonStatus]
bit FRZ, a
ret z
ld a, [wEnemyJustGotFrozen]
and a
ret nz
call BattleRandom
cp 10 percent
ret nc
xor a
2018-01-23 14:39:09 -08:00
ld [wEnemyMonStatus], a
ld a, [wBattleMode]
dec a
2016-01-17 21:39:01 -08:00
jr z, .wild
2018-01-23 14:39:09 -08:00
ld a, [wCurOTMon]
ld hl, wOTPartyMon1Status
call GetPartyLocation
ld [hl], 0
2016-01-17 21:39:01 -08:00
.wild
call UpdateBattleHuds
call SetPlayerTurn
2014-01-05 04:28:55 -08:00
ld hl, DefrostedOpponentText
2019-04-08 05:15:10 -07:00
jp StdBattleTextbox
2018-06-24 07:09:41 -07:00
HandleSafeguard:
ldh a, [hSerialConnectionStatus]
cp USING_EXTERNAL_CLOCK
2016-01-17 21:39:01 -08:00
jr z, .player1
call .CheckPlayer
jr .CheckEnemy
2016-01-17 21:39:01 -08:00
.player1
call .CheckEnemy
.CheckPlayer:
2018-01-23 14:39:09 -08:00
ld a, [wPlayerScreens]
bit SCREENS_SAFEGUARD, a
ret z
2018-01-23 14:39:09 -08:00
ld hl, wPlayerSafeguardCount
dec [hl]
ret nz
res SCREENS_SAFEGUARD, a
2018-01-23 14:39:09 -08:00
ld [wPlayerScreens], a
xor a
2016-01-17 21:39:01 -08:00
jr .print
.CheckEnemy:
2018-01-23 14:39:09 -08:00
ld a, [wEnemyScreens]
bit SCREENS_SAFEGUARD, a
ret z
2018-01-23 14:39:09 -08:00
ld hl, wEnemySafeguardCount
dec [hl]
ret nz
res SCREENS_SAFEGUARD, a
2018-01-23 14:39:09 -08:00
ld [wEnemyScreens], a
ld a, $1
2016-01-17 21:39:01 -08:00
.print
ldh [hBattleTurn], a
ld hl, BattleText_SafeguardFaded
2019-04-08 05:15:10 -07:00
jp StdBattleTextbox
2018-06-24 07:09:41 -07:00
HandleScreens:
ldh a, [hSerialConnectionStatus]
cp USING_EXTERNAL_CLOCK
jr z, .Both
call .CheckPlayer
jr .CheckEnemy
.Both:
call .CheckEnemy
.CheckPlayer:
call SetPlayerTurn
ld de, .Your
call .Copy
2018-01-23 14:39:09 -08:00
ld hl, wPlayerScreens
ld de, wPlayerLightScreenCount
2016-01-17 21:39:01 -08:00
jr .TickScreens
.CheckEnemy:
call SetEnemyTurn
ld de, .Enemy
call .Copy
2018-01-23 14:39:09 -08:00
ld hl, wEnemyScreens
ld de, wEnemyLightScreenCount
.TickScreens:
bit SCREENS_LIGHT_SCREEN, [hl]
2016-01-17 21:39:01 -08:00
call nz, .LightScreenTick
bit SCREENS_REFLECT, [hl]
2016-01-17 21:39:01 -08:00
call nz, .ReflectTick
ret
.Copy:
2018-01-23 14:39:09 -08:00
ld hl, wStringBuffer1
jp CopyName2
.Your:
db "Your@"
.Enemy:
db "Enemy@"
2018-06-24 07:09:41 -07:00
.LightScreenTick:
ld a, [de]
dec a
ld [de], a
ret nz
res SCREENS_LIGHT_SCREEN, [hl]
push hl
push de
ld hl, BattleText_MonsLightScreenFell
2019-04-08 05:15:10 -07:00
call StdBattleTextbox
pop de
pop hl
ret
2018-06-24 07:09:41 -07:00
.ReflectTick:
inc de
ld a, [de]
dec a
ld [de], a
ret nz
res SCREENS_REFLECT, [hl]
ld hl, BattleText_MonsReflectFaded
2019-04-08 05:15:10 -07:00
jp StdBattleTextbox
2018-06-24 07:09:41 -07:00
HandleWeather:
ld a, [wBattleWeather]
cp WEATHER_NONE
ret z
2018-01-23 14:39:09 -08:00
ld hl, wWeatherCount
dec [hl]
jr z, .ended
ld hl, .WeatherMessages
call .PrintWeatherMessage
ld a, [wBattleWeather]
cp WEATHER_SANDSTORM
ret nz
ldh a, [hSerialConnectionStatus]
cp USING_EXTERNAL_CLOCK
jr z, .enemy_first
; player first
call SetPlayerTurn
call .SandstormDamage
call SetEnemyTurn
jr .SandstormDamage
.enemy_first
call SetEnemyTurn
call .SandstormDamage
call SetPlayerTurn
.SandstormDamage:
ld a, BATTLE_VARS_SUBSTATUS3
call GetBattleVar
bit SUBSTATUS_UNDERGROUND, a
ret nz
2018-01-23 14:39:09 -08:00
ld hl, wBattleMonType1
ldh a, [hBattleTurn]
and a
jr z, .ok
2018-01-23 14:39:09 -08:00
ld hl, wEnemyMonType1
.ok
ld a, [hli]
cp ROCK
ret z
cp GROUND
ret z
cp STEEL
ret z
ld a, [hl]
cp ROCK
ret z
cp GROUND
ret z
cp STEEL
ret z
call SwitchTurnCore
xor a
2015-12-23 11:00:29 -08:00
ld [wNumHits], a
ld de, ANIM_IN_SANDSTORM
2015-09-09 16:27:07 -07:00
call Call_PlayBattleAnim
call SwitchTurnCore
call GetEighthMaxHP
2015-11-06 17:55:16 -08:00
call SubtractHPFromUser
ld hl, SandstormHitsText
2019-04-08 05:15:10 -07:00
jp StdBattleTextbox
.ended
ld hl, .WeatherEndedMessages
call .PrintWeatherMessage
xor a
ld [wBattleWeather], a
ret
.PrintWeatherMessage:
ld a, [wBattleWeather]
dec a
ld c, a
ld b, 0
add hl, bc
2015-12-26 18:59:03 -08:00
add hl, bc
ld a, [hli]
ld h, [hl]
ld l, a
2019-04-08 05:15:10 -07:00
jp StdBattleTextbox
.WeatherMessages:
2018-01-25 18:34:42 -08:00
; entries correspond to WEATHER_* constants
dw BattleText_RainContinuesToFall
dw BattleText_TheSunlightIsStrong
dw BattleText_TheSandstormRages
2018-01-25 18:34:42 -08:00
.WeatherEndedMessages:
2018-01-25 18:34:42 -08:00
; entries correspond to WEATHER_* constants
dw BattleText_TheRainStopped
dw BattleText_TheSunlightFaded
dw BattleText_TheSandstormSubsided
2018-06-24 07:09:41 -07:00
SubtractHPFromTarget:
2015-11-06 17:55:16 -08:00
call SubtractHP
jp UpdateHPBar
2018-06-24 07:09:41 -07:00
SubtractHPFromUser:
; Subtract HP from mon
2015-11-06 17:55:16 -08:00
call SubtractHP
jp UpdateHPBarBattleHuds
2018-06-24 07:09:41 -07:00
SubtractHP:
2018-01-23 14:39:09 -08:00
ld hl, wBattleMonHP
ldh a, [hBattleTurn]
and a
jr z, .ok
2018-01-23 14:39:09 -08:00
ld hl, wEnemyMonHP
.ok
inc hl
ld a, [hl]
ld [wHPBuffer2], a
sub c
ld [hld], a
ld [wHPBuffer3], a
ld a, [hl]
ld [wHPBuffer2 + 1], a
sbc b
ld [hl], a
ld [wHPBuffer3 + 1], a
ret nc
2015-09-09 16:27:07 -07:00
ld a, [wHPBuffer2]
ld c, a
ld a, [wHPBuffer2 + 1]
ld b, a
xor a
ld [hli], a
ld [hl], a
ld [wHPBuffer3], a
ld [wHPBuffer3 + 1], a
ret
2018-06-24 07:09:41 -07:00
GetSixteenthMaxHP:
call GetQuarterMaxHP
2020-02-21 06:56:47 -08:00
; quarter result
srl c
srl c
2020-02-21 06:56:47 -08:00
; at least 1
ld a, c
and a
jr nz, .ok
inc c
.ok
ret
2018-06-24 07:09:41 -07:00
GetEighthMaxHP:
; output: bc
call GetQuarterMaxHP
; assumes nothing can have 1024 or more hp
; halve result
srl c
2020-02-21 06:56:47 -08:00
; at least 1
ld a, c
and a
jr nz, .end
inc c
.end
ret
2018-06-24 07:09:41 -07:00
GetQuarterMaxHP:
; output: bc
call GetMaxHP
; quarter result
srl b
rr c
srl b
rr c
; assumes nothing can have 1024 or more hp
2020-02-21 06:56:47 -08:00
; at least 1
ld a, c
and a
jr nz, .end
inc c
.end
ret
2018-06-24 07:09:41 -07:00
GetHalfMaxHP:
; output: bc
call GetMaxHP
; halve result
srl b
rr c
2020-02-21 06:56:47 -08:00
; at least 1
ld a, c
or b
jr nz, .end
inc c
.end
ret
2018-06-24 07:09:41 -07:00
GetMaxHP:
; output: bc, wHPBuffer1
2018-01-23 14:39:09 -08:00
ld hl, wBattleMonMaxHP
ldh a, [hBattleTurn]
and a
jr z, .ok
2018-01-23 14:39:09 -08:00
ld hl, wEnemyMonMaxHP
.ok
ld a, [hli]
ld [wHPBuffer1 + 1], a
ld b, a
ld a, [hl]
ld [wHPBuffer1], a
ld c, a
ret
GetHalfHP: ; unreferenced
2018-01-23 14:39:09 -08:00
ld hl, wBattleMonHP
ldh a, [hBattleTurn]
and a
jr z, .ok
2018-01-23 14:39:09 -08:00
ld hl, wEnemyMonHP
.ok
ld a, [hli]
ld b, a
ld a, [hli]
ld c, a
srl b
rr c
ld a, [hli]
ld [wHPBuffer1 + 1], a
ld a, [hl]
ld [wHPBuffer1], a
ret
2018-06-24 07:09:41 -07:00
CheckUserHasEnoughHP:
2018-01-23 14:39:09 -08:00
ld hl, wBattleMonHP + 1
ldh a, [hBattleTurn]
and a
jr z, .ok
2018-01-23 14:39:09 -08:00
ld hl, wEnemyMonHP + 1
.ok
ld a, c
sub [hl]
dec hl
ld a, b
sbc [hl]
ret
2019-04-08 05:15:10 -07:00
RestoreHP:
2018-01-23 14:39:09 -08:00
ld hl, wEnemyMonMaxHP
ldh a, [hBattleTurn]
and a
jr z, .ok
2018-01-23 14:39:09 -08:00
ld hl, wBattleMonMaxHP
.ok
ld a, [hli]
ld [wHPBuffer1 + 1], a
ld a, [hld]
ld [wHPBuffer1], a
dec hl
ld a, [hl]
ld [wHPBuffer2], a
add c
ld [hld], a
ld [wHPBuffer3], a
ld a, [hl]
ld [wHPBuffer2 + 1], a
adc b
ld [hli], a
ld [wHPBuffer3 + 1], a
ld a, [wHPBuffer1]
ld c, a
ld a, [hld]
sub c
ld a, [wHPBuffer1 + 1]
ld b, a
ld a, [hl]
sbc b
jr c, .overflow
ld a, b
ld [hli], a
ld [wHPBuffer3 + 1], a
ld a, c
ld [hl], a
ld [wHPBuffer3], a
.overflow
call SwitchTurnCore
call UpdateHPBarBattleHuds
jp SwitchTurnCore
2018-06-24 07:09:41 -07:00
UpdateHPBarBattleHuds:
call UpdateHPBar
jp UpdateBattleHuds
2018-06-24 07:09:41 -07:00
UpdateHPBar:
hlcoord 10, 9
ldh a, [hBattleTurn]
and a
ld a, 1
jr z, .ok
hlcoord 2, 2
xor a
.ok
push bc
ld [wWhichHPBar], a
predef AnimateHPBar
pop bc
ret
2018-06-24 07:09:41 -07:00
HandleEnemyMonFaint:
2015-10-19 13:49:29 -07:00
call FaintEnemyPokemon
2018-01-23 14:39:09 -08:00
ld hl, wBattleMonHP
ld a, [hli]
or [hl]
2015-10-19 13:49:29 -07:00
call z, FaintYourPokemon
xor a
2016-01-12 09:46:18 -08:00
ld [wWhichMonFaintedFirst], a
call UpdateBattleStateAndExperienceAfterEnemyFaint
call CheckPlayerPartyForFitMon
ld a, d
and a
jp z, LostBattle
2018-01-23 14:39:09 -08:00
ld hl, wBattleMonHP
ld a, [hli]
or [hl]
call nz, UpdatePlayerHUD
ld a, $1
ldh [hBGMapMode], a
ld c, 60
call DelayFrames
ld a, [wBattleMode]
dec a
2015-10-19 13:49:29 -07:00
jr nz, .trainer
ld a, 1
2018-01-23 14:39:09 -08:00
ld [wBattleEnded], a
ret
2015-10-19 13:49:29 -07:00
.trainer
call CheckEnemyTrainerDefeated
jp z, WinTrainerBattle
2018-01-23 14:39:09 -08:00
ld hl, wBattleMonHP
ld a, [hli]
or [hl]
2015-11-10 16:51:13 -08:00
jr nz, .player_mon_not_fainted
2015-11-07 18:04:54 -08:00
call AskUseNextPokemon
jr nc, .dont_flee
ld a, 1
2018-01-23 14:39:09 -08:00
ld [wBattleEnded], a
ret
2015-11-07 18:04:54 -08:00
.dont_flee
2015-11-10 16:51:13 -08:00
call ForcePlayerMonChoice
ld a, BATTLEPLAYERACTION_USEITEM
ld [wBattlePlayerAction], a
2016-01-12 21:39:41 -08:00
call HandleEnemySwitch
jp z, WildFled_EnemyFled_LinkBattleCanceled
2015-11-23 13:04:53 -08:00
jr DoubleSwitch
2015-11-10 16:51:13 -08:00
.player_mon_not_fainted
ld a, BATTLEPLAYERACTION_USEITEM
ld [wBattlePlayerAction], a
2016-01-12 21:39:41 -08:00
call HandleEnemySwitch
jp z, WildFled_EnemyFled_LinkBattleCanceled
xor a ; BATTLEPLAYERACTION_USEMOVE
ld [wBattlePlayerAction], a
ret
2018-06-24 07:09:41 -07:00
DoubleSwitch:
ldh a, [hSerialConnectionStatus]
cp USING_EXTERNAL_CLOCK
2015-11-10 16:51:13 -08:00
jr z, .player_1
call ClearSprites
hlcoord 1, 0
lb bc, 4, 10
call ClearBox
2015-11-10 16:51:13 -08:00
call PlayerPartyMonEntrance
ld a, $1
call EnemyPartyMonEntrance
2015-11-10 16:51:13 -08:00
jr .done
2015-11-10 16:51:13 -08:00
.player_1
2018-01-23 14:39:09 -08:00
ld a, [wCurPartyMon]
push af
ld a, $1
call EnemyPartyMonEntrance
call ClearSprites
call LoadTilemapToTempTilemap
pop af
2018-01-23 14:39:09 -08:00
ld [wCurPartyMon], a
2015-11-10 16:51:13 -08:00
call PlayerPartyMonEntrance
2015-11-10 16:51:13 -08:00
.done
xor a ; BATTLEPLAYERACTION_USEMOVE
ld [wBattlePlayerAction], a
ret
2018-06-24 07:09:41 -07:00
UpdateBattleStateAndExperienceAfterEnemyFaint:
call UpdateBattleMonInParty
ld a, [wBattleMode]
dec a
2015-11-10 16:51:13 -08:00
jr z, .wild
2018-01-23 14:39:09 -08:00
ld a, [wCurOTMon]
ld hl, wOTPartyMon1HP
call GetPartyLocation
xor a
ld [hli], a
ld [hl], a
2015-11-10 16:51:13 -08:00
.wild
2018-01-23 14:39:09 -08:00
ld hl, wPlayerSubStatus3
res SUBSTATUS_IN_LOOP, [hl]
xor a
2018-01-23 14:39:09 -08:00
ld hl, wEnemyDamageTaken
ld [hli], a
ld [hl], a
call NewEnemyMonStatus
call BreakAttraction
ld a, [wBattleMode]
dec a
2015-11-10 16:51:13 -08:00
jr z, .wild2
jr .trainer
2015-11-10 16:51:13 -08:00
.wild2
2015-10-19 13:49:29 -07:00
call StopDangerSound
ld a, $1
ld [wBattleLowHealthAlarm], a
2015-11-10 16:51:13 -08:00
.trainer
2018-01-23 14:39:09 -08:00
ld hl, wBattleMonHP
ld a, [hli]
or [hl]
2015-11-10 16:51:13 -08:00
jr nz, .player_mon_did_not_faint
2016-01-12 09:46:18 -08:00
ld a, [wWhichMonFaintedFirst]
and a
2015-11-10 16:51:13 -08:00
jr nz, .player_mon_did_not_faint
call UpdateFaintedPlayerMon
2015-11-10 16:51:13 -08:00
.player_mon_did_not_faint
call CheckPlayerPartyForFitMon
ld a, d
and a
ret z
ld a, [wBattleMode]
dec a
2015-09-09 16:27:07 -07:00
call z, PlayVictoryMusic
2019-04-08 05:15:10 -07:00
call EmptyBattleTextbox
call LoadTilemapToTempTilemap
2015-10-24 07:34:19 -07:00
ld a, [wBattleResult]
2018-04-05 08:44:02 -07:00
and BATTLERESULT_BITMASK
ld [wBattleResult], a ; WIN
2016-01-12 09:46:18 -08:00
call IsAnyMonHoldingExpShare
2015-11-10 16:51:13 -08:00
jr z, .skip_exp
2018-01-23 14:39:09 -08:00
ld hl, wEnemyMonBaseStats
ld b, wEnemyMonEnd - wEnemyMonBaseStats
2015-11-10 16:51:13 -08:00
.loop
srl [hl]
inc hl
dec b
2015-11-10 16:51:13 -08:00
jr nz, .loop
2015-11-10 16:51:13 -08:00
.skip_exp
2018-01-23 14:39:09 -08:00
ld hl, wEnemyMonBaseStats
2016-01-12 09:46:18 -08:00
ld de, wBackupEnemyMonBaseStats
2018-01-23 14:39:09 -08:00
ld bc, wEnemyMonEnd - wEnemyMonBaseStats
call CopyBytes
xor a
2016-01-12 09:46:18 -08:00
ld [wGivingExperienceToExpShareHolders], a
2015-09-09 16:27:07 -07:00
call GiveExperiencePoints
2016-01-12 09:46:18 -08:00
call IsAnyMonHoldingExpShare
ret z
2015-11-07 18:04:54 -08:00
ld a, [wBattleParticipantsNotFainted]
push af
ld a, d
2015-11-07 18:04:54 -08:00
ld [wBattleParticipantsNotFainted], a
2016-01-12 09:46:18 -08:00
ld hl, wBackupEnemyMonBaseStats
2018-01-23 14:39:09 -08:00
ld de, wEnemyMonBaseStats
ld bc, wEnemyMonEnd - wEnemyMonBaseStats
call CopyBytes
ld a, $1
2016-01-12 09:46:18 -08:00
ld [wGivingExperienceToExpShareHolders], a
2015-09-09 16:27:07 -07:00
call GiveExperiencePoints
pop af
2015-11-07 18:04:54 -08:00
ld [wBattleParticipantsNotFainted], a
ret
2018-06-24 07:09:41 -07:00
IsAnyMonHoldingExpShare:
2018-01-23 14:39:09 -08:00
ld a, [wPartyCount]
ld b, a
2018-01-23 14:39:09 -08:00
ld hl, wPartyMon1
ld c, 1
ld d, 0
2015-11-07 18:04:54 -08:00
.loop
push hl
push bc
ld bc, MON_HP
add hl, bc
ld a, [hli]
or [hl]
pop bc
pop hl
2015-11-07 18:04:54 -08:00
jr z, .next
push hl
push bc
ld bc, MON_ITEM
add hl, bc
pop bc
ld a, [hl]
pop hl
cp EXP_SHARE
2015-11-07 18:04:54 -08:00
jr nz, .next
ld a, d
or c
ld d, a
2015-11-07 18:04:54 -08:00
.next
sla c
push de
ld de, PARTYMON_STRUCT_LENGTH
add hl, de
pop de
dec b
2015-11-07 18:04:54 -08:00
jr nz, .loop
ld a, d
ld e, 0
ld b, PARTY_LENGTH
2015-11-07 18:04:54 -08:00
.loop2
srl a
2015-11-07 18:04:54 -08:00
jr nc, .okay
inc e
2015-11-07 18:04:54 -08:00
.okay
dec b
2015-11-07 18:04:54 -08:00
jr nz, .loop2
ld a, e
and a
ret
2018-06-24 07:09:41 -07:00
StopDangerSound:
xor a
ld [wLowHealthAlarm], a
ret
2018-06-24 07:09:41 -07:00
FaintYourPokemon:
2015-10-19 13:49:29 -07:00
call StopDangerSound
call WaitSFX
ld a, $f0
2018-01-23 14:39:09 -08:00
ld [wCryTracks], a
ld a, [wBattleMonSpecies]
2014-07-18 10:25:03 -07:00
call PlayStereoCry
2015-10-19 13:49:29 -07:00
call PlayerMonFaintedAnimation
hlcoord 9, 7
lb bc, 5, 11
call ClearBox
ld hl, BattleText_MonFainted
2019-04-08 05:15:10 -07:00
jp StdBattleTextbox
2018-06-24 07:09:41 -07:00
FaintEnemyPokemon:
call WaitSFX
ld de, SFX_KINESIS
call PlaySFX
2015-10-19 13:49:29 -07:00
call EnemyMonFaintedAnimation
ld de, SFX_FAINT
call PlaySFX
hlcoord 1, 0
lb bc, 4, 10
call ClearBox
ld hl, BattleText_EnemyMonFainted
2019-04-08 05:15:10 -07:00
jp StdBattleTextbox
2018-06-24 07:09:41 -07:00
CheckEnemyTrainerDefeated:
2018-01-23 14:39:09 -08:00
ld a, [wOTPartyCount]
ld b, a
xor a
2018-01-23 14:39:09 -08:00
ld hl, wOTPartyMon1HP
ld de, PARTYMON_STRUCT_LENGTH
2015-10-19 13:49:29 -07:00
.loop
or [hl]
inc hl
or [hl]
dec hl
add hl, de
dec b
2015-10-19 13:49:29 -07:00
jr nz, .loop
and a
ret
2018-06-24 07:09:41 -07:00
HandleEnemySwitch:
2018-01-23 14:39:09 -08:00
ld hl, wEnemyHPPal
ld e, HP_BAR_LENGTH_PX
2015-11-23 13:04:53 -08:00
call UpdateHPPal
call WaitBGMap
2017-12-24 09:47:30 -08:00
farcall EnemySwitch_TrainerHud
ld a, [wLinkMode]
and a
2015-11-06 06:04:27 -08:00
jr z, .not_linked
2015-09-09 16:27:07 -07:00
2015-11-23 13:04:53 -08:00
call LinkBattleSendReceiveAction
ld a, [wBattleAction]
2015-11-06 06:04:27 -08:00
cp BATTLEACTION_FORFEIT
ret z
2015-09-09 16:27:07 -07:00
call SafeLoadTempTilemapToTilemap
2015-11-06 06:04:27 -08:00
.not_linked
2018-01-23 14:39:09 -08:00
ld hl, wBattleMonHP
ld a, [hli]
or [hl]
ld a, $0
jr nz, EnemyPartyMonEntrance
inc a
ret
2018-06-24 07:09:41 -07:00
EnemyPartyMonEntrance:
push af
xor a
2015-11-08 16:09:36 -08:00
ld [wEnemySwitchMonIndex], a
call NewEnemyMonStatus
call ResetEnemyStatLevels
call BreakAttraction
pop af
and a
2016-01-12 21:39:41 -08:00
jr nz, .set
2015-11-07 18:04:54 -08:00
call EnemySwitch
2016-01-12 21:39:41 -08:00
jr .done_switch
2016-01-12 21:39:41 -08:00
.set
2015-11-07 18:04:54 -08:00
call EnemySwitch_SetMode
2016-01-12 21:39:41 -08:00
.done_switch
2015-11-07 18:04:54 -08:00
call ResetBattleParticipants
call SetEnemyTurn
call SpikesDamage
xor a
ld [wEnemyMoveStruct + MOVE_ANIM], a
ld [wBattlePlayerAction], a
inc a
ret
2018-06-24 07:09:41 -07:00
WinTrainerBattle:
2015-09-09 16:27:07 -07:00
; Player won the battle
2015-10-19 13:49:29 -07:00
call StopDangerSound
ld a, $1
ld [wBattleLowHealthAlarm], a
2018-01-23 14:39:09 -08:00
ld [wBattleEnded], a
ld a, [wLinkMode]
and a
ld a, b
2015-09-09 16:27:07 -07:00
call z, PlayVictoryMusic
2017-12-24 09:47:30 -08:00
callfar Battle_GetTrainerName
ld hl, BattleText_EnemyWasDefeated
2019-04-08 05:15:10 -07:00
call StdBattleTextbox
2015-09-09 16:27:07 -07:00
ld a, [wLinkMode]
and a
ret nz
call BattleWinSlideInEnemyTrainerFrontpic
ld c, 40
call DelayFrames
2020-11-17 08:09:02 -08:00
2018-01-23 14:39:09 -08:00
ld a, [wBattleType]
cp BATTLETYPE_CANLOSE
2015-11-03 19:35:36 -08:00
jr nz, .skip_heal
predef HealParty
2015-11-03 19:35:36 -08:00
.skip_heal
2020-11-17 08:09:02 -08:00
2018-09-15 17:15:55 -07:00
ld a, [wDebugFlags]
bit DEBUG_BATTLE_F, a
2015-11-04 12:35:29 -08:00
jr nz, .skip_win_loss_text
call PrintWinLossText
.skip_win_loss_text
2020-11-17 08:09:02 -08:00
jp .give_coins
.give_coins
2015-11-22 21:21:21 -08:00
ld a, [wAmuletCoin]
and a
2015-11-22 21:21:21 -08:00
call nz, .DoubleReward
2018-01-22 10:57:44 -08:00
ld c, 4
2015-11-22 21:21:21 -08:00
.loop2
ld a, c
and a
2015-11-22 21:21:21 -08:00
jr z, .done
call .AddCoinsToWallet
dec c
2015-11-22 21:21:21 -08:00
jr .loop2
2015-11-22 21:21:21 -08:00
.done
call .DoubleReward
call .DoubleReward
ld hl, GotCoinsForWinningText
2019-04-08 05:15:10 -07:00
jp StdBattleTextbox
.AddCoinsToWallet:
push bc
2015-11-22 21:21:21 -08:00
ld hl, wBattleReward + 2
ld de, wCurLevelCoins + 2
call AddBattleCoinsToAccount
pop bc
ret
2018-06-24 07:09:41 -07:00
.DoubleReward:
2015-11-22 21:21:21 -08:00
ld hl, wBattleReward + 2
sla [hl]
dec hl
rl [hl]
dec hl
rl [hl]
ret nc
ld a, $ff
ld [hli], a
2015-12-26 18:59:03 -08:00
ld [hli], a
ld [hl], a
ret
AddBattleCoinsToAccount:
2018-01-22 10:57:44 -08:00
ld c, 3
and a
push de
push hl
push bc
ld b, h
ld c, l
pop bc
pop hl
2015-11-22 21:21:21 -08:00
.loop
ld a, [de]
adc [hl]
ld [de], a
dec de
dec hl
dec c
2015-11-22 21:21:21 -08:00
jr nz, .loop
pop hl
ld a, [hld]
cp LOW(MAX_LEVEL_COINS)
ld a, [hld]
sbc HIGH(MAX_LEVEL_COINS) ; mid
ld a, [hl]
sbc HIGH(MAX_LEVEL_COINS >> 8)
ret c
ld [hl], HIGH(MAX_LEVEL_COINS >> 8)
inc hl
ld [hl], HIGH(MAX_LEVEL_COINS) ; mid
inc hl
ld [hl], LOW(MAX_LEVEL_COINS)
ret
2018-06-24 07:09:41 -07:00
PlayVictoryMusic:
push de
ld de, MUSIC_NONE
call PlayMusic
call DelayFrame
ld de, MUSIC_WILD_VICTORY
ld a, [wBattleMode]
dec a
2015-11-07 18:04:54 -08:00
jr nz, .trainer_victory
push de
2016-01-12 09:46:18 -08:00
call IsAnyMonHoldingExpShare
pop de
2015-11-07 18:04:54 -08:00
jr nz, .play_music
ld hl, wPayDayCoins
ld a, [hli]
or [hl]
2015-11-07 18:04:54 -08:00
jr nz, .play_music
ld a, [wBattleParticipantsNotFainted]
and a
2015-11-07 18:04:54 -08:00
jr z, .lost
jr .play_music
2015-11-07 18:04:54 -08:00
.trainer_victory
ld de, MUSIC_GYM_VICTORY
call IsGymLeader
2015-11-07 18:04:54 -08:00
jr c, .play_music
ld de, MUSIC_TRAINER_VICTORY
2015-11-07 18:04:54 -08:00
.play_music
call PlayMusic
2015-11-07 18:04:54 -08:00
.lost
pop de
ret
IsKantoGymLeader:
ld hl, KantoGymLeaders
jr IsGymLeaderCommon
IsGymLeader:
ld hl, GymLeaders
IsGymLeaderCommon:
push de
2018-01-23 14:39:09 -08:00
ld a, [wOtherTrainerClass]
2018-01-22 10:57:44 -08:00
ld de, 1
call IsInArray
pop de
ret
INCLUDE "data/trainers/leaders.asm"
2018-06-24 07:09:41 -07:00
HandlePlayerMonFaint:
2015-10-19 13:49:29 -07:00
call FaintYourPokemon
2018-01-23 14:39:09 -08:00
ld hl, wEnemyMonHP
ld a, [hli]
or [hl]
2015-10-19 13:49:29 -07:00
call z, FaintEnemyPokemon
ld a, $1
2016-01-12 09:46:18 -08:00
ld [wWhichMonFaintedFirst], a
call UpdateFaintedPlayerMon
call CheckPlayerPartyForFitMon
ld a, d
and a
jp z, LostBattle
2018-01-23 14:39:09 -08:00
ld hl, wEnemyMonHP
ld a, [hli]
or [hl]
2015-10-19 13:49:29 -07:00
jr nz, .notfainted
2016-01-12 09:46:18 -08:00
call UpdateBattleStateAndExperienceAfterEnemyFaint
ld a, [wBattleMode]
dec a
2015-10-19 13:49:29 -07:00
jr nz, .trainer
ld a, $1
2018-01-23 14:39:09 -08:00
ld [wBattleEnded], a
ret
2015-10-19 13:49:29 -07:00
.trainer
call CheckEnemyTrainerDefeated
jp z, WinTrainerBattle
2015-10-19 13:49:29 -07:00
.notfainted
2015-11-07 18:04:54 -08:00
call AskUseNextPokemon
2015-11-10 16:51:13 -08:00
jr nc, .switch
ld a, $1
2018-01-23 14:39:09 -08:00
ld [wBattleEnded], a
ret
2015-11-10 16:51:13 -08:00
.switch
call ForcePlayerMonChoice
ld a, c
and a
ret nz
ld a, BATTLEPLAYERACTION_USEITEM
ld [wBattlePlayerAction], a
2016-01-12 21:39:41 -08:00
call HandleEnemySwitch
jp z, WildFled_EnemyFled_LinkBattleCanceled
2015-11-23 13:04:53 -08:00
jp DoubleSwitch
UpdateFaintedPlayerMon:
2018-01-23 14:39:09 -08:00
ld a, [wCurBattleMon]
ld c, a
2015-11-07 18:04:54 -08:00
ld hl, wBattleParticipantsNotFainted
2015-11-22 21:21:21 -08:00
ld b, RESET_FLAG
predef SmallFarFlagAction
2018-01-23 14:39:09 -08:00
ld hl, wEnemySubStatus3
res SUBSTATUS_IN_LOOP, [hl]
xor a
ld [wLowHealthAlarm], a
2018-01-23 14:39:09 -08:00
ld hl, wPlayerDamageTaken
ld [hli], a
ld [hl], a
2018-01-23 14:39:09 -08:00
ld [wBattleMonStatus], a
call UpdateBattleMonInParty
2015-10-12 09:33:24 -07:00
ld c, HAPPINESS_FAINTED
; If TheirLevel > (YourLevel + 30), use a different parameter
2018-01-23 14:39:09 -08:00
ld a, [wBattleMonLevel]
2015-10-12 09:33:24 -07:00
add 30
ld b, a
2018-01-23 14:39:09 -08:00
ld a, [wEnemyMonLevel]
cp b
2015-11-10 16:51:13 -08:00
jr c, .got_param
2015-10-12 09:33:24 -07:00
ld c, HAPPINESS_BEATENBYSTRONGFOE
2015-11-10 16:51:13 -08:00
.got_param
2018-01-23 14:39:09 -08:00
ld a, [wCurBattleMon]
ld [wCurPartyMon], a
2017-12-24 09:47:30 -08:00
callfar ChangeHappiness
2015-10-24 07:34:19 -07:00
ld a, [wBattleResult]
2018-04-05 08:44:02 -07:00
and BATTLERESULT_BITMASK
add LOSE
2015-10-24 07:34:19 -07:00
ld [wBattleResult], a
2016-01-12 09:46:18 -08:00
ld a, [wWhichMonFaintedFirst]
and a
ret z
2020-11-17 08:09:02 -08:00
; code was probably dummied out here
ret
2018-06-24 07:09:41 -07:00
AskUseNextPokemon:
2019-04-08 05:15:10 -07:00
call EmptyBattleTextbox
call LoadTilemapToTempTilemap
2015-11-07 18:04:54 -08:00
; We don't need to be here if we're in a Trainer battle,
; as that decision is made for us.
ld a, [wBattleMode]
and a
dec a
ret nz
2015-11-07 18:04:54 -08:00
ld hl, BattleText_UseNextMon
2019-04-08 05:15:10 -07:00
call StdBattleTextbox
2015-11-07 18:04:54 -08:00
.loop
lb bc, 1, 7
call PlaceYesNoBox
2015-12-15 15:59:49 -08:00
ld a, [wMenuCursorY]
2015-11-07 18:04:54 -08:00
jr c, .pressed_b
and a
ret
2015-11-07 18:04:54 -08:00
.pressed_b
2015-12-15 15:59:49 -08:00
ld a, [wMenuCursorY]
2015-11-07 18:04:54 -08:00
cp $1 ; YES
jr z, .loop
2018-01-23 14:39:09 -08:00
ld hl, wPartyMon1Speed
ld de, wEnemyMonSpeed
2015-09-09 16:27:07 -07:00
jp TryToRunAwayFromBattle
2018-06-24 07:09:41 -07:00
ForcePlayerMonChoice:
2019-04-08 05:15:10 -07:00
call EmptyBattleTextbox
call LoadStandardMenuHeader
call SetUpBattlePartyMenu
call ForcePickPartyMonInBattle
ld a, [wLinkMode]
and a
2015-11-07 18:04:54 -08:00
jr z, .skip_link
ld a, BATTLEPLAYERACTION_USEITEM
ld [wBattlePlayerAction], a
2015-11-23 13:04:53 -08:00
call LinkBattleSendReceiveAction
2015-11-07 18:04:54 -08:00
.skip_link
xor a ; BATTLEPLAYERACTION_USEMOVE
ld [wBattlePlayerAction], a
2018-01-23 14:39:09 -08:00
ld hl, wEnemyMonHP
ld a, [hli]
or [hl]
2015-11-10 16:51:13 -08:00
jr nz, .send_out_pokemon
call ClearSprites
2015-11-11 20:38:57 -08:00
call ClearBGPalettes
2015-11-10 16:51:13 -08:00
call _LoadHPBar
call ExitMenu
call LoadTilemapToTempTilemap
call WaitBGMap
call GetMemCGBLayout
2024-02-10 15:16:00 -08:00
call SetDefaultBGPAndOBP
xor a
ld c, a
ret
2015-11-10 16:51:13 -08:00
.send_out_pokemon
call ClearSprites
2018-01-23 14:39:09 -08:00
ld a, [wCurBattleMon]
ld [wLastPlayerMon], a
ld a, [wCurPartyMon]
ld [wCurBattleMon], a
2015-11-07 18:04:54 -08:00
call AddBattleParticipant
2015-11-06 13:42:38 -08:00
call InitBattleMon
call ResetPlayerStatLevels
call ClearPalettes
call DelayFrame
2015-11-10 16:51:13 -08:00
call _LoadHPBar
call CloseWindow
call GetMemCGBLayout
2024-02-10 15:16:00 -08:00
call SetDefaultBGPAndOBP
call SendOutMonText
call NewBattleMonStatus
call BreakAttraction
2015-11-07 06:48:32 -08:00
call SendOutPlayerMon
2019-04-08 05:15:10 -07:00
call EmptyBattleTextbox
call LoadTilemapToTempTilemap
call SetPlayerTurn
call SpikesDamage
ld a, $1
and a
ld c, a
ret
2018-06-24 07:09:41 -07:00
PlayerPartyMonEntrance:
2018-01-23 14:39:09 -08:00
ld a, [wCurBattleMon]
ld [wLastPlayerMon], a
ld a, [wCurPartyMon]
ld [wCurBattleMon], a
2015-11-07 18:04:54 -08:00
call AddBattleParticipant
2015-11-06 13:42:38 -08:00
call InitBattleMon
call ResetPlayerStatLevels
call SendOutMonText
call NewBattleMonStatus
call BreakAttraction
2015-11-07 06:48:32 -08:00
call SendOutPlayerMon
2019-04-08 05:15:10 -07:00
call EmptyBattleTextbox
call LoadTilemapToTempTilemap
call SetPlayerTurn
jp SpikesDamage
SetUpBattlePartyMenu:
2015-11-11 20:38:57 -08:00
call ClearBGPalettes
SetUpBattlePartyMenu_Loop: ; switch to fullscreen menu?
2017-12-24 09:47:30 -08:00
farcall LoadPartyMenuGFX
farcall InitPartyMenuWithCancel
farcall InitPartyMenuBGPal7
farcall InitPartyMenuGFX
ret
2018-06-24 07:09:41 -07:00
JumpToPartyMenuAndPrintText:
2017-12-24 09:47:30 -08:00
farcall WritePartyMenuTilemap
farcall PlacePartyMenuText
call WaitBGMap
2024-02-10 15:16:00 -08:00
call SetDefaultBGPAndOBP
call DelayFrame
ret
2018-06-24 07:09:41 -07:00
SelectBattleMon:
2017-12-24 09:47:30 -08:00
farcall PartyMenuSelect
ret
2018-06-24 07:09:41 -07:00
PickPartyMonInBattle:
.loop
ld a, PARTYMENUACTION_SWITCH ; Which PKMN?
2018-01-23 14:39:09 -08:00
ld [wPartyMenuActionText], a
2016-01-12 21:39:41 -08:00
call JumpToPartyMenuAndPrintText
call SelectBattleMon
ret c
2016-03-01 19:31:21 -08:00
call CheckIfCurPartyMonIsFitToFight
jr z, .loop
xor a
ret
2018-06-24 07:09:41 -07:00
SwitchMonAlreadyOut:
2018-01-23 14:39:09 -08:00
ld hl, wCurBattleMon
ld a, [wCurPartyMon]
cp [hl]
jr nz, .notout
ld hl, BattleText_MonIsAlreadyOut
2019-04-08 05:15:10 -07:00
call StdBattleTextbox
scf
ret
.notout
xor a
ret
2018-06-24 07:09:41 -07:00
ForcePickPartyMonInBattle:
; Can't back out.
.pick
call PickPartyMonInBattle
ret nc
ld de, SFX_WRONG
call PlaySFX
call WaitSFX
jr .pick
2018-06-24 07:09:41 -07:00
PickSwitchMonInBattle:
.pick
call PickPartyMonInBattle
ret c
call SwitchMonAlreadyOut
jr c, .pick
xor a
ret
2018-06-24 07:09:41 -07:00
ForcePickSwitchMonInBattle:
; Can't back out.
.pick
call ForcePickPartyMonInBattle
call SwitchMonAlreadyOut
jr c, .pick
xor a
ret
2018-06-24 07:09:41 -07:00
LostBattle:
ld a, 1
2018-01-23 14:39:09 -08:00
ld [wBattleEnded], a
2018-01-23 14:39:09 -08:00
ld a, [wBattleType]
cp BATTLETYPE_CANLOSE
2015-11-03 19:35:36 -08:00
jr nz, .not_canlose
; Remove the enemy from the screen.
hlcoord 0, 0
2015-10-19 13:49:29 -07:00
lb bc, 8, 21
call ClearBox
call BattleWinSlideInEnemyTrainerFrontpic
ld c, 40
call DelayFrames
2018-09-15 17:15:55 -07:00
ld a, [wDebugFlags]
bit DEBUG_BATTLE_F, a
2015-11-04 12:35:29 -08:00
jr nz, .skip_win_loss_text
call PrintWinLossText
.skip_win_loss_text
ret
2015-11-03 19:35:36 -08:00
.not_canlose
ld a, [wLinkMode]
and a
jr nz, .LostLinkBattle
2020-12-08 11:34:54 -08:00
; Grayscale
ld b, CGB_BATTLE_GRAYSCALE
call GetCGBLayout
2024-02-10 15:16:00 -08:00
call SetDefaultBGPAndOBP
jr .end
.LostLinkBattle:
call UpdateEnemyMonInParty
2015-10-19 13:49:29 -07:00
call CheckEnemyTrainerDefeated
2015-11-03 19:35:36 -08:00
jr nz, .not_tied
ld hl, TiedAgainstText
2015-10-24 07:34:19 -07:00
ld a, [wBattleResult]
2018-04-05 08:44:02 -07:00
and BATTLERESULT_BITMASK
add DRAW
2015-10-24 07:34:19 -07:00
ld [wBattleResult], a
jr .text
2015-11-03 19:35:36 -08:00
.not_tied
ld hl, LostAgainstText
.text
2019-04-08 05:15:10 -07:00
call StdBattleTextbox
.end
scf
ret
2018-06-24 07:09:41 -07:00
EnemyMonFaintedAnimation:
hlcoord 12, 5
decoord 12, 6
2015-10-19 13:49:29 -07:00
jp MonFaintedAnimation
2018-06-24 07:09:41 -07:00
PlayerMonFaintedAnimation:
hlcoord 1, 10
decoord 1, 11
2015-10-19 13:49:29 -07:00
jp MonFaintedAnimation
2018-06-24 07:09:41 -07:00
MonFaintedAnimation:
ld a, [wJoypadDisable]
push af
set JOYPAD_DISABLE_MON_FAINT_F, a
ld [wJoypadDisable], a
2015-10-19 13:49:29 -07:00
ld b, 7
.OuterLoop:
push bc
push de
push hl
2015-10-19 13:49:29 -07:00
ld b, 6
.InnerLoop:
push bc
push hl
push de
2015-10-19 13:49:29 -07:00
ld bc, 7
call CopyBytes
pop de
pop hl
2015-10-19 13:49:29 -07:00
ld bc, -SCREEN_WIDTH
add hl, bc
push hl
ld h, d
ld l, e
add hl, bc
ld d, h
ld e, l
pop hl
pop bc
dec b
2015-10-19 13:49:29 -07:00
jr nz, .InnerLoop
ld bc, 20
add hl, bc
ld de, .Spaces
call PlaceString
ld c, 2
call DelayFrames
pop hl
pop de
pop bc
dec b
2015-10-19 13:49:29 -07:00
jr nz, .OuterLoop
pop af
ld [wJoypadDisable], a
ret
.Spaces:
db " @"
2018-06-24 07:09:41 -07:00
SlideBattlePicOut:
ldh [hMapObjectIndex], a
ld c, a
.loop
push bc
push hl
ld b, $7
.loop2
push hl
call .DoFrame
pop hl
ld de, SCREEN_WIDTH
add hl, de
dec b
jr nz, .loop2
ld c, 2
call DelayFrames
pop hl
pop bc
dec c
jr nz, .loop
ret
2018-06-24 07:09:41 -07:00
.DoFrame:
ldh a, [hMapObjectIndex]
ld c, a
cp $8
jr nz, .back
.forward
ld a, [hli]
ld [hld], a
dec hl
dec c
jr nz, .forward
ret
.back
ld a, [hld]
ld [hli], a
inc hl
dec c
jr nz, .back
ret
2018-06-24 07:09:41 -07:00
ForceEnemySwitch:
call ResetEnemyBattleVars
2015-11-08 16:09:36 -08:00
ld a, [wEnemySwitchMonIndex]
dec a
ld b, a
call LoadEnemyMonToSwitchTo
2015-11-10 16:51:13 -08:00
call ClearEnemyMonBox
call NewEnemyMonStatus
call ResetEnemyStatLevels
call ShowSetEnemyMonAndSendOutAnimation
call BreakAttraction
2015-11-07 18:04:54 -08:00
call ResetBattleParticipants
ret
2018-06-24 07:09:41 -07:00
EnemySwitch:
2015-11-10 16:51:13 -08:00
call CheckWhetherToAskSwitch
2015-11-07 18:04:54 -08:00
jr nc, EnemySwitch_SetMode
; Shift Mode
call ResetEnemyBattleVars
2015-11-10 16:51:13 -08:00
call CheckWhetherSwitchmonIsPredetermined
2015-11-07 18:04:54 -08:00
jr c, .skip
call FindMonInOTPartyToSwitchIntoBattle
2015-11-07 18:04:54 -08:00
.skip
; 'b' contains the PartyNr of the mon the AI will switch to
call LoadEnemyMonToSwitchTo
2015-11-07 18:04:54 -08:00
call OfferSwitch
push af
2015-11-10 16:51:13 -08:00
call ClearEnemyMonBox
call ShowBattleTextEnemySentOut
call ShowSetEnemyMonAndSendOutAnimation
pop af
ret c
2015-11-07 18:04:54 -08:00
; If we're here, then we're switching too
xor a
2015-11-07 18:04:54 -08:00
ld [wBattleParticipantsNotFainted], a
2016-01-12 09:46:18 -08:00
ld [wBattleParticipantsIncludingFainted], a
ld [wBattlePlayerAction], a
inc a
ld [wEnemyIsSwitching], a
call LoadTilemapToTempTilemap
2015-11-07 18:04:54 -08:00
jp PlayerSwitch
2018-06-24 07:09:41 -07:00
EnemySwitch_SetMode:
call ResetEnemyBattleVars
2015-11-10 16:51:13 -08:00
call CheckWhetherSwitchmonIsPredetermined
2015-11-07 18:04:54 -08:00
jr c, .skip
call FindMonInOTPartyToSwitchIntoBattle
2015-11-07 18:04:54 -08:00
.skip
; 'b' contains the PartyNr of the mon the AI will switch to
call LoadEnemyMonToSwitchTo
ld a, 1
ld [wEnemyIsSwitching], a
2015-11-10 16:51:13 -08:00
call ClearEnemyMonBox
call ShowBattleTextEnemySentOut
jp ShowSetEnemyMonAndSendOutAnimation
2018-06-24 07:09:41 -07:00
CheckWhetherSwitchmonIsPredetermined:
2020-11-17 08:09:02 -08:00
; returns the enemy switchmon index in b, or
; returns carry if the index is not yet determined.
ld a, [wLinkMode]
and a
2015-11-06 06:04:27 -08:00
jr z, .not_linked
ld a, [wBattleAction]
2015-11-06 06:04:27 -08:00
sub BATTLEACTION_SWITCH1
ld b, a
2015-11-06 06:04:27 -08:00
jr .return_carry
2015-11-06 06:04:27 -08:00
.not_linked
2015-11-08 16:09:36 -08:00
ld a, [wEnemySwitchMonIndex]
and a
2016-08-07 15:14:20 -07:00
jr z, .check_wBattleHasJustStarted
dec a
ld b, a
2015-11-06 06:04:27 -08:00
jr .return_carry
2016-08-07 15:14:20 -07:00
.check_wBattleHasJustStarted
ld a, [wBattleHasJustStarted]
and a
2020-11-17 08:09:02 -08:00
ld b, 0
2015-11-06 06:04:27 -08:00
jr nz, .return_carry
and a
ret
2015-11-06 06:04:27 -08:00
.return_carry
scf
ret
2018-06-24 07:09:41 -07:00
ResetEnemyBattleVars:
2019-04-08 05:15:10 -07:00
; and draw empty Textbox
xor a
2018-01-23 14:39:09 -08:00
ld [wLastPlayerCounterMove], a
ld [wLastEnemyCounterMove], a
ld [wLastEnemyMove], a
ld [wCurEnemyMove], a
dec a
2016-01-12 09:46:18 -08:00
ld [wEnemyItemState], a
xor a
2015-11-08 10:27:26 -08:00
ld [wPlayerWrapCount], a
hlcoord 18, 0
ld a, 8
call SlideBattlePicOut
2019-04-08 05:15:10 -07:00
call EmptyBattleTextbox
jp LoadStandardMenuHeader
2018-06-24 07:09:41 -07:00
ResetBattleParticipants:
xor a
2015-11-07 18:04:54 -08:00
ld [wBattleParticipantsNotFainted], a
2016-01-12 09:46:18 -08:00
ld [wBattleParticipantsIncludingFainted], a
2018-06-24 07:09:41 -07:00
AddBattleParticipant:
2018-01-23 14:39:09 -08:00
ld a, [wCurBattleMon]
ld c, a
2015-11-07 18:04:54 -08:00
ld hl, wBattleParticipantsNotFainted
ld b, SET_FLAG
push bc
predef SmallFarFlagAction
pop bc
2016-01-12 09:46:18 -08:00
ld hl, wBattleParticipantsIncludingFainted
predef_jump SmallFarFlagAction
2018-06-24 07:09:41 -07:00
FindMonInOTPartyToSwitchIntoBattle:
2018-02-25 16:50:48 -08:00
ld b, -1
2020-11-03 19:45:12 -08:00
ld a, %000001
ld [wEnemyEffectivenessVsPlayerMons], a
ld [wPlayerEffectivenessVsEnemyMons], a
2016-01-12 21:39:41 -08:00
.loop
2020-11-03 19:45:12 -08:00
ld hl, wEnemyEffectivenessVsPlayerMons
sla [hl]
2020-11-03 19:45:12 -08:00
inc hl ; wPlayerEffectivenessVsEnemyMons
sla [hl]
inc b
2018-01-23 14:39:09 -08:00
ld a, [wOTPartyCount]
cp b
2016-01-12 21:39:41 -08:00
jp z, ScoreMonTypeMatchups
2018-01-23 14:39:09 -08:00
ld a, [wCurOTMon]
cp b
2016-01-12 21:39:41 -08:00
jr z, .discourage
2018-01-23 14:39:09 -08:00
ld hl, wOTPartyMon1HP
push bc
ld a, b
call GetPartyLocation
ld a, [hli]
ld c, a
ld a, [hl]
or c
pop bc
2016-01-12 21:39:41 -08:00
jr z, .discourage
call LookUpTheEffectivenessOfEveryMove
call IsThePlayerMonTypesEffectiveAgainstOTMon
2016-01-12 21:39:41 -08:00
jr .loop
2016-01-12 21:39:41 -08:00
.discourage
2020-11-03 19:45:12 -08:00
ld hl, wPlayerEffectivenessVsEnemyMons
set 0, [hl]
2016-01-12 21:39:41 -08:00
jr .loop
2018-06-24 07:09:41 -07:00
LookUpTheEffectivenessOfEveryMove:
push bc
2018-01-23 14:39:09 -08:00
ld hl, wOTPartyMon1Moves
ld a, b
call GetPartyLocation
pop bc
ld e, NUM_MOVES + 1
.loop
dec e
jr z, .done
ld a, [hli]
and a
jr z, .done
push hl
push de
push bc
dec a
ld hl, Moves
ld bc, MOVE_LENGTH
call AddNTimes
ld de, wEnemyMoveStruct
2013-12-30 20:22:27 -08:00
ld a, BANK(Moves)
call FarCopyBytes
call SetEnemyTurn
2017-12-24 09:47:30 -08:00
callfar BattleCheckTypeMatchup
pop bc
pop de
pop hl
ld a, [wTypeMatchup]
cp EFFECTIVE + 1
jr c, .loop
2020-11-03 19:45:12 -08:00
ld hl, wEnemyEffectivenessVsPlayerMons
set 0, [hl]
ret
.done
ret
2018-06-24 07:09:41 -07:00
IsThePlayerMonTypesEffectiveAgainstOTMon:
; Calculates the effectiveness of the types of the PlayerMon
; against the OTMon
push bc
2018-01-23 14:39:09 -08:00
ld hl, wOTPartyCount
ld a, b
inc a
ld c, a
ld b, 0
add hl, bc
ld a, [hl]
dec a
ld hl, BaseData + BASE_TYPES
ld bc, BASE_DATA_SIZE
call AddNTimes
2018-01-23 14:39:09 -08:00
ld de, wEnemyMonType
ld bc, BASE_CATCH_RATE - BASE_TYPES
2014-01-05 04:28:55 -08:00
ld a, BANK(BaseData)
call FarCopyBytes
2018-01-23 14:39:09 -08:00
ld a, [wBattleMonType1]
ld [wPlayerMoveStruct + MOVE_TYPE], a
call SetPlayerTurn
2017-12-24 09:47:30 -08:00
callfar BattleCheckTypeMatchup
ld a, [wTypeMatchup]
cp EFFECTIVE + 1
2016-01-12 21:39:41 -08:00
jr nc, .super_effective
2018-01-23 14:39:09 -08:00
ld a, [wBattleMonType2]
ld [wPlayerMoveStruct + MOVE_TYPE], a
2017-12-24 09:47:30 -08:00
callfar BattleCheckTypeMatchup
ld a, [wTypeMatchup]
cp EFFECTIVE + 1
2016-01-12 21:39:41 -08:00
jr nc, .super_effective
pop bc
ret
2016-01-12 21:39:41 -08:00
.super_effective
pop bc
2020-11-03 19:45:12 -08:00
ld hl, wEnemyEffectivenessVsPlayerMons
bit 0, [hl]
2016-01-12 21:39:41 -08:00
jr nz, .reset
2020-11-03 19:45:12 -08:00
inc hl ; wPlayerEffectivenessVsEnemyMons
set 0, [hl]
ret
2016-01-12 21:39:41 -08:00
.reset
res 0, [hl]
ret
2018-06-24 07:09:41 -07:00
ScoreMonTypeMatchups:
2016-01-12 21:39:41 -08:00
.loop1
2020-11-03 19:45:12 -08:00
ld hl, wEnemyEffectivenessVsPlayerMons
sla [hl]
2020-11-03 19:45:12 -08:00
inc hl ; wPlayerEffectivenessVsEnemyMons
sla [hl]
2016-01-12 21:39:41 -08:00
jr nc, .loop1
2018-01-23 14:39:09 -08:00
ld a, [wOTPartyCount]
ld b, a
ld c, [hl]
2016-01-12 21:39:41 -08:00
.loop2
sla c
2016-01-12 21:39:41 -08:00
jr nc, .okay
dec b
2016-01-12 21:39:41 -08:00
jr z, .loop5
jr .loop2
2016-01-12 21:39:41 -08:00
.okay
2020-11-03 19:45:12 -08:00
ld a, [wEnemyEffectivenessVsPlayerMons]
and a
2016-01-12 21:39:41 -08:00
jr z, .okay2
2018-02-25 16:50:48 -08:00
ld b, -1
ld c, a
2016-01-12 21:39:41 -08:00
.loop3
inc b
sla c
2016-01-12 21:39:41 -08:00
jr nc, .loop3
jr .quit
2016-01-12 21:39:41 -08:00
.okay2
2018-02-25 16:50:48 -08:00
ld b, -1
2020-11-03 19:45:12 -08:00
ld a, [wPlayerEffectivenessVsEnemyMons]
ld c, a
2016-01-12 21:39:41 -08:00
.loop4
inc b
sla c
2016-01-12 21:39:41 -08:00
jr c, .loop4
jr .quit
2016-01-12 21:39:41 -08:00
.loop5
2018-01-23 14:39:09 -08:00
ld a, [wOTPartyCount]
ld b, a
call BattleRandom
and $7
cp b
2016-01-12 21:39:41 -08:00
jr nc, .loop5
ld b, a
2018-01-23 14:39:09 -08:00
ld a, [wCurOTMon]
cp b
2016-01-12 21:39:41 -08:00
jr z, .loop5
2018-01-23 14:39:09 -08:00
ld hl, wOTPartyMon1HP
push bc
ld a, b
call GetPartyLocation
pop bc
ld a, [hli]
ld c, a
ld a, [hl]
or c
2016-01-12 21:39:41 -08:00
jr z, .loop5
2016-01-12 21:39:41 -08:00
.quit
ret
2018-06-24 07:09:41 -07:00
LoadEnemyMonToSwitchTo:
; 'b' contains the PartyNr of the mon the AI will switch to
ld a, b
2018-01-23 14:39:09 -08:00
ld [wCurPartyMon], a
ld hl, wOTPartyMon1Level
call GetPartyLocation
ld a, [hl]
2018-01-23 14:39:09 -08:00
ld [wCurPartyLevel], a
ld a, [wCurPartyMon]
inc a
2018-01-23 14:39:09 -08:00
ld hl, wOTPartyCount
ld c, a
ld b, 0
add hl, bc
ld a, [hl]
2018-01-23 14:39:09 -08:00
ld [wTempEnemyMonSpecies], a
ld [wCurPartySpecies], a
call LoadEnemyMon
2015-09-09 16:27:07 -07:00
2018-01-23 14:39:09 -08:00
ld a, [wCurPartySpecies]
2014-03-05 02:42:09 -08:00
cp UNOWN
2015-11-09 20:55:39 -08:00
jr nz, .skip_unown
2015-11-29 18:34:59 -08:00
ld a, [wFirstUnownSeen]
and a
2015-11-09 20:55:39 -08:00
jr nz, .skip_unown
2018-01-23 14:39:09 -08:00
ld hl, wEnemyMonDVs
predef GetUnownLetter
2018-01-23 14:39:09 -08:00
ld a, [wUnownLetter]
2015-11-29 18:34:59 -08:00
ld [wFirstUnownSeen], a
2015-11-09 20:55:39 -08:00
.skip_unown
2015-09-09 16:27:07 -07:00
2018-01-23 14:39:09 -08:00
ld hl, wEnemyMonHP
ld a, [hli]
ld [wEnemyHPAtTimeOfPlayerSwitch], a
ld a, [hl]
ld [wEnemyHPAtTimeOfPlayerSwitch + 1], a
ret
2018-06-24 07:09:41 -07:00
CheckWhetherToAskSwitch:
2016-08-07 15:14:20 -07:00
ld a, [wBattleHasJustStarted]
dec a
2015-11-10 16:51:13 -08:00
jp z, .return_nc
2018-01-23 14:39:09 -08:00
ld a, [wPartyCount]
dec a
2015-11-10 16:51:13 -08:00
jp z, .return_nc
ld a, [wLinkMode]
and a
2015-11-10 16:51:13 -08:00
jp nz, .return_nc
2018-01-23 14:39:09 -08:00
ld a, [wOptions]
bit BATTLE_SHIFT, a
2015-11-10 16:51:13 -08:00
jr nz, .return_nc
2018-01-23 14:39:09 -08:00
ld a, [wCurPartyMon]
push af
2018-01-23 14:39:09 -08:00
ld a, [wCurBattleMon]
ld [wCurPartyMon], a
2017-12-24 09:47:30 -08:00
farcall CheckCurPartyMonFainted
pop bc
ld a, b
2018-01-23 14:39:09 -08:00
ld [wCurPartyMon], a
2015-11-10 16:51:13 -08:00
jr c, .return_nc
scf
ret
2015-11-10 16:51:13 -08:00
.return_nc
and a
ret
2018-06-24 07:09:41 -07:00
OfferSwitch:
2018-01-23 14:39:09 -08:00
ld a, [wCurPartyMon]
push af
2017-12-24 09:47:30 -08:00
callfar Battle_GetTrainerName
ld hl, BattleText_EnemyIsAboutToUseWillPlayerChangeMon
2019-04-08 05:15:10 -07:00
call StdBattleTextbox
lb bc, 1, 7
call PlaceYesNoBox
2015-12-15 15:59:49 -08:00
ld a, [wMenuCursorY]
dec a
2015-11-07 18:04:54 -08:00
jr nz, .said_no
call SetUpBattlePartyMenu
call PickSwitchMonInBattle
2015-11-07 18:04:54 -08:00
jr c, .canceled_switch
2018-01-23 14:39:09 -08:00
ld a, [wCurBattleMon]
ld [wLastPlayerMon], a
ld a, [wCurPartyMon]
ld [wCurBattleMon], a
call ClearPalettes
call DelayFrame
2015-11-10 16:51:13 -08:00
call _LoadHPBar
pop af
2018-01-23 14:39:09 -08:00
ld [wCurPartyMon], a
xor a
2018-01-23 14:39:09 -08:00
ld [wCurEnemyMove], a
ld [wCurPlayerMove], a
and a
ret
2015-11-07 18:04:54 -08:00
.canceled_switch
call ClearPalettes
call DelayFrame
2015-11-10 16:51:13 -08:00
call _LoadHPBar
2015-11-07 18:04:54 -08:00
.said_no
pop af
2018-01-23 14:39:09 -08:00
ld [wCurPartyMon], a
scf
ret
2018-06-24 07:09:41 -07:00
ClearEnemyMonBox:
xor a
ldh [hBGMapMode], a
call ExitMenu
call ClearSprites
hlcoord 1, 0
lb bc, 4, 10
call ClearBox
call WaitBGMap
2015-11-09 13:41:09 -08:00
jp FinishBattleAnim
ShowBattleTextEnemySentOut:
2017-12-24 09:47:30 -08:00
callfar Battle_GetTrainerName
2015-08-23 06:09:56 -07:00
ld hl, BattleText_EnemySentOut
2019-04-08 05:15:10 -07:00
call StdBattleTextbox
jp WaitBGMap
ShowSetEnemyMonAndSendOutAnimation:
2018-01-23 14:39:09 -08:00
ld a, [wTempEnemyMonSpecies]
ld [wCurPartySpecies], a
ld [wCurSpecies], a
call GetBaseData
ld a, OTPARTYMON
2018-01-23 14:39:09 -08:00
ld [wMonType], a
predef CopyMonToTempMon
call GetEnemyMonFrontpic
xor a
2015-12-23 11:00:29 -08:00
ld [wNumHits], a
2015-12-23 17:46:23 -08:00
ld [wBattleAnimParam], a
call SetEnemyTurn
ld de, ANIM_SEND_OUT_MON
2015-09-09 16:27:07 -07:00
call Call_PlayBattleAnim
2015-11-06 13:42:38 -08:00
call BattleCheckEnemyShininess
2015-11-07 06:48:32 -08:00
jr nc, .not_shiny
ld a, 1 ; shiny anim
2015-12-23 17:46:23 -08:00
ld [wBattleAnimParam], a
ld de, ANIM_SEND_OUT_MON
2015-09-09 16:27:07 -07:00
call Call_PlayBattleAnim
.not_shiny
2018-01-23 14:39:09 -08:00
ld bc, wTempMonSpecies
2017-12-24 09:47:30 -08:00
farcall CheckFaintedFrzSlp
2015-11-07 06:48:32 -08:00
jr c, .skip_cry
2017-12-24 09:47:30 -08:00
farcall CheckBattleScene
2015-11-07 06:48:32 -08:00
jr c, .cry_no_anim
hlcoord 12, 0
ld d, $0
2015-11-07 06:48:32 -08:00
ld e, ANIM_MON_SLOW
predef AnimateFrontpic
2015-11-07 06:48:32 -08:00
jr .skip_cry
2015-11-07 06:48:32 -08:00
.cry_no_anim
ld a, $f
2018-01-23 14:39:09 -08:00
ld [wCryTracks], a
ld a, [wTempEnemyMonSpecies]
2014-07-18 10:25:03 -07:00
call PlayStereoCry
2015-11-07 06:48:32 -08:00
.skip_cry
call UpdateEnemyHUD
ld a, $1
ldh [hBGMapMode], a
ret
2018-06-24 07:09:41 -07:00
NewEnemyMonStatus:
xor a
2018-01-23 14:39:09 -08:00
ld [wLastPlayerCounterMove], a
ld [wLastEnemyCounterMove], a
ld [wLastEnemyMove], a
ld hl, wEnemySubStatus1
2015-07-20 19:18:18 -07:00
rept 4
ld [hli], a
2015-07-20 19:18:18 -07:00
endr
ld [hl], a
2018-01-23 14:39:09 -08:00
ld [wEnemyDisableCount], a
ld [wEnemyFuryCutterCount], a
ld [wEnemyProtectCount], a
2015-11-05 16:13:09 -08:00
ld [wEnemyRageCounter], a
2018-01-23 14:39:09 -08:00
ld [wEnemyDisabledMove], a
ld [wEnemyMinimized], a
2015-11-08 10:27:26 -08:00
ld [wPlayerWrapCount], a
ld [wEnemyWrapCount], a
2018-01-23 14:39:09 -08:00
ld [wEnemyTurnsTaken], a
ld hl, wPlayerSubStatus5
res SUBSTATUS_CANT_RUN, [hl]
ret
2018-06-24 07:09:41 -07:00
ResetEnemyStatLevels:
2015-11-06 17:55:16 -08:00
ld a, BASE_STAT_LEVEL
ld b, NUM_LEVEL_STATS
2018-01-23 14:39:09 -08:00
ld hl, wEnemyStatLevels
.loop
ld [hli], a
dec b
jr nz, .loop
ret
2018-06-24 07:09:41 -07:00
CheckPlayerPartyForFitMon:
; Has the player any mon in his Party that can fight?
2018-01-23 14:39:09 -08:00
ld a, [wPartyCount]
ld e, a
xor a
2018-01-23 14:39:09 -08:00
ld hl, wPartyMon1HP
ld bc, PARTYMON_STRUCT_LENGTH - 1
2016-03-01 19:31:21 -08:00
.loop
or [hl]
inc hl ; + 1
or [hl]
add hl, bc
dec e
2016-03-01 19:31:21 -08:00
jr nz, .loop
ld d, a
ret
2018-06-24 07:09:41 -07:00
CheckIfCurPartyMonIsFitToFight:
2018-01-23 14:39:09 -08:00
ld a, [wCurPartyMon]
ld hl, wPartyMon1HP
call GetPartyLocation
ld a, [hli]
or [hl]
ret nz
2016-08-07 15:14:20 -07:00
ld a, [wBattleHasJustStarted]
and a
2016-03-01 19:31:21 -08:00
jr nz, .finish_fail
2018-01-23 14:39:09 -08:00
ld hl, wPartySpecies
ld a, [wCurPartyMon]
ld c, a
ld b, 0
add hl, bc
ld a, [hl]
cp EGG
ld hl, BattleText_AnEGGCantBattle
2016-03-01 19:31:21 -08:00
jr z, .print_textbox
ld hl, BattleText_TheresNoWillToBattle
2016-03-01 19:31:21 -08:00
.print_textbox
2019-04-08 05:15:10 -07:00
call StdBattleTextbox
2016-03-01 19:31:21 -08:00
.finish_fail
xor a
ret
2018-06-24 07:09:41 -07:00
TryToRunAwayFromBattle:
2015-09-09 16:27:07 -07:00
; Run away from battle, with or without item
2018-01-23 14:39:09 -08:00
ld a, [wBattleType]
2015-09-09 16:27:07 -07:00
cp BATTLETYPE_DEBUG
2015-11-06 06:04:27 -08:00
jp z, .can_escape
cp BATTLETYPE_CONTEST
2015-11-06 06:04:27 -08:00
jp z, .can_escape
cp BATTLETYPE_TRAP
2015-11-06 06:04:27 -08:00
jp z, .cant_escape
cp BATTLETYPE_CELEBI
2015-11-06 06:04:27 -08:00
jp z, .cant_escape
2023-07-26 17:50:16 -07:00
cp BATTLETYPE_FORCESHINY
2015-11-06 06:04:27 -08:00
jp z, .cant_escape
cp BATTLETYPE_SUICUNE
2015-11-06 06:04:27 -08:00
jp z, .cant_escape
ld a, [wLinkMode]
and a
2015-11-06 06:04:27 -08:00
jp nz, .can_escape
ld a, [wBattleMode]
dec a
2015-11-06 06:04:27 -08:00
jp nz, .cant_run_from_trainer
2018-01-23 14:39:09 -08:00
ld a, [wEnemySubStatus5]
bit SUBSTATUS_CANT_RUN, a
2015-11-06 06:04:27 -08:00
jp nz, .cant_escape
2015-11-08 10:27:26 -08:00
ld a, [wPlayerWrapCount]
and a
2015-11-06 06:04:27 -08:00
jp nz, .cant_escape
push hl
push de
2018-01-23 14:39:09 -08:00
ld a, [wBattleMonItem]
ld [wNamedObjectIndex], a
ld b, a
2017-12-24 09:47:30 -08:00
callfar GetItemHeldEffect
ld a, b
cp HELD_ESCAPE
pop de
pop hl
2015-11-06 06:04:27 -08:00
jr nz, .no_flee_item
call SetPlayerTurn
call GetItemName
2015-09-09 16:27:07 -07:00
ld hl, BattleText_UserFledUsingAStringBuffer1
2019-04-08 05:15:10 -07:00
call StdBattleTextbox
2015-11-06 06:04:27 -08:00
jp .can_escape
2015-11-06 06:04:27 -08:00
.no_flee_item
2015-11-23 13:04:53 -08:00
ld a, [wNumFleeAttempts]
inc a
2015-11-23 13:04:53 -08:00
ld [wNumFleeAttempts], a
ld a, [hli]
ldh [hMultiplicand + 1], a
ld a, [hl]
ldh [hMultiplicand + 2], a
ld a, [de]
inc de
ldh [hEnemyMonSpeed + 0], a
ld a, [de]
ldh [hEnemyMonSpeed + 1], a
call SafeLoadTempTilemapToTilemap
ld de, hMultiplicand + 1
ld hl, hEnemyMonSpeed
ld c, 2
call CompareBytes
2015-11-06 06:04:27 -08:00
jr nc, .can_escape
xor a
ldh [hMultiplicand + 0], a
ld a, 32
ldh [hMultiplier], a
call Multiply
ldh a, [hProduct + 2]
ldh [hDividend + 0], a
ldh a, [hProduct + 3]
ldh [hDividend + 1], a
ldh a, [hEnemyMonSpeed + 0]
ld b, a
ldh a, [hEnemyMonSpeed + 1]
srl b
rr a
srl b
rr a
and a
2015-11-06 06:04:27 -08:00
jr z, .can_escape
ldh [hDivisor], a
2016-01-17 21:39:01 -08:00
ld b, 2
call Divide
ldh a, [hQuotient + 2]
and a
2015-11-06 06:04:27 -08:00
jr nz, .can_escape
2015-11-23 13:04:53 -08:00
ld a, [wNumFleeAttempts]
ld c, a
2015-11-06 06:04:27 -08:00
.loop
dec c
2015-11-06 06:04:27 -08:00
jr z, .cant_escape_2
2015-11-23 13:04:53 -08:00
ld b, 30
ldh a, [hQuotient + 3]
add b
ldh [hQuotient + 3], a
2015-11-06 06:04:27 -08:00
jr c, .can_escape
jr .loop
2015-11-06 06:04:27 -08:00
.cant_escape_2
call BattleRandom
ld b, a
ldh a, [hQuotient + 3]
cp b
2015-11-06 06:04:27 -08:00
jr nc, .can_escape
ld a, BATTLEPLAYERACTION_USEITEM
ld [wBattlePlayerAction], a
ld hl, BattleText_CantEscape2
2015-11-06 06:04:27 -08:00
jr .print_inescapable_text
2015-11-06 06:04:27 -08:00
.cant_escape
ld hl, BattleText_CantEscape
2015-11-06 06:04:27 -08:00
jr .print_inescapable_text
2015-11-06 06:04:27 -08:00
.cant_run_from_trainer
ld hl, BattleText_TheresNoEscapeFromTrainerBattle
2015-11-06 06:04:27 -08:00
.print_inescapable_text
2019-04-08 05:15:10 -07:00
call StdBattleTextbox
ld a, TRUE
2015-11-23 13:04:53 -08:00
ld [wFailedToFlee], a
call LoadTilemapToTempTilemap
and a
ret
2015-11-06 06:04:27 -08:00
.can_escape
ld a, [wLinkMode]
and a
2015-11-06 06:04:27 -08:00
ld a, DRAW
jr z, .fled
call LoadTilemapToTempTilemap
xor a ; BATTLEPLAYERACTION_USEMOVE
ld [wBattlePlayerAction], a
ld a, BATTLEACTION_FORFEIT
2018-01-23 14:39:09 -08:00
ld [wCurMoveNum], a
xor a
2018-01-23 14:39:09 -08:00
ld [wCurPlayerMove], a
2015-11-23 13:04:53 -08:00
call LinkBattleSendReceiveAction
call SafeLoadTempTilemapToTilemap
; Got away safely
ld a, [wBattleAction]
2015-11-06 06:04:27 -08:00
cp BATTLEACTION_FORFEIT
ld a, DRAW
jr z, .fled
2018-04-05 08:44:02 -07:00
dec a ; LOSE
2015-11-06 06:04:27 -08:00
.fled
ld b, a
2015-10-24 07:34:19 -07:00
ld a, [wBattleResult]
2018-04-05 08:44:02 -07:00
and BATTLERESULT_BITMASK
add b
2015-10-24 07:34:19 -07:00
ld [wBattleResult], a
2015-10-19 13:49:29 -07:00
call StopDangerSound
push de
ld de, SFX_RUN
call WaitPlaySFX
pop de
call WaitSFX
ld hl, BattleText_GotAwaySafely
2019-04-08 05:15:10 -07:00
call StdBattleTextbox
call WaitSFX
call LoadTilemapToTempTilemap
scf
ret
2018-06-24 07:09:41 -07:00
InitBattleMon:
ld a, MON_SPECIES
call GetPartyParamLocation
2018-01-23 14:39:09 -08:00
ld de, wBattleMonSpecies
2015-11-06 06:04:27 -08:00
ld bc, MON_ID
call CopyBytes
ld bc, MON_DVS - MON_ID
add hl, bc
2018-01-23 14:39:09 -08:00
ld de, wBattleMonDVs
2021-06-07 17:00:21 -07:00
ld bc, MON_POKERUS - MON_DVS
call CopyBytes
inc hl
inc hl
inc hl
2018-01-23 14:39:09 -08:00
ld de, wBattleMonLevel
ld bc, PARTYMON_STRUCT_LENGTH - MON_LEVEL
call CopyBytes
2018-01-23 14:39:09 -08:00
ld a, [wBattleMonSpecies]
ld [wTempBattleMonSpecies], a
ld [wCurPartySpecies], a
ld [wCurSpecies], a
call GetBaseData
2018-01-23 14:39:09 -08:00
ld a, [wBaseType1]
ld [wBattleMonType1], a
ld a, [wBaseType2]
ld [wBattleMonType2], a
ld hl, wPartyMonNicknames
ld a, [wCurBattleMon]
call SkipNames
ld de, wBattleMonNickname
2018-01-20 09:25:55 -08:00
ld bc, MON_NAME_LENGTH
call CopyBytes
2018-01-23 14:39:09 -08:00
ld hl, wBattleMonAttack
ld de, wPlayerStats
ld bc, PARTYMON_STRUCT_LENGTH - MON_ATK
call CopyBytes
2015-11-07 18:04:54 -08:00
call ApplyStatusEffectOnPlayerStats
call BadgeStatBoosts
ret
2018-06-24 07:09:41 -07:00
BattleCheckPlayerShininess:
2015-11-06 13:42:38 -08:00
call GetPartyMonDVs
jr BattleCheckShininess
2018-06-24 07:09:41 -07:00
BattleCheckEnemyShininess:
2015-11-06 13:42:38 -08:00
call GetEnemyMonDVs
2018-06-24 07:09:41 -07:00
BattleCheckShininess:
ld b, h
ld c, l
2017-12-24 09:47:30 -08:00
callfar CheckShininess
ret
2018-06-24 07:09:41 -07:00
GetPartyMonDVs:
2018-01-23 14:39:09 -08:00
ld hl, wBattleMonDVs
ld a, [wPlayerSubStatus5]
bit SUBSTATUS_TRANSFORMED, a
ret z
2018-01-23 14:39:09 -08:00
ld hl, wPartyMon1DVs
ld a, [wCurBattleMon]
jp GetPartyLocation
2018-06-24 07:09:41 -07:00
GetEnemyMonDVs:
2018-01-23 14:39:09 -08:00
ld hl, wEnemyMonDVs
ld a, [wEnemySubStatus5]
bit SUBSTATUS_TRANSFORMED, a
ret z
2016-01-10 14:44:09 -08:00
ld hl, wEnemyBackupDVs
ld a, [wBattleMode]
dec a
ret z
2018-01-23 14:39:09 -08:00
ld hl, wOTPartyMon1DVs
ld a, [wCurOTMon]
jp GetPartyLocation
2018-06-24 07:09:41 -07:00
ResetPlayerStatLevels:
2015-11-06 17:55:16 -08:00
ld a, BASE_STAT_LEVEL
ld b, NUM_LEVEL_STATS
2018-01-23 14:39:09 -08:00
ld hl, wPlayerStatLevels
.loop
ld [hli], a
dec b
jr nz, .loop
ret
2018-06-24 07:09:41 -07:00
InitEnemyMon:
2018-01-23 14:39:09 -08:00
ld a, [wCurPartyMon]
ld hl, wOTPartyMon1Species
call GetPartyLocation
2018-01-23 14:39:09 -08:00
ld de, wEnemyMonSpecies
2015-11-06 06:04:27 -08:00
ld bc, MON_ID
call CopyBytes
ld bc, MON_DVS - MON_ID
add hl, bc
2018-01-23 14:39:09 -08:00
ld de, wEnemyMonDVs
2021-06-07 17:00:21 -07:00
ld bc, MON_POKERUS - MON_DVS
call CopyBytes
inc hl
inc hl
inc hl
2018-01-23 14:39:09 -08:00
ld de, wEnemyMonLevel
ld bc, PARTYMON_STRUCT_LENGTH - MON_LEVEL
call CopyBytes
2018-01-23 14:39:09 -08:00
ld a, [wEnemyMonSpecies]
ld [wCurSpecies], a
call GetBaseData
2018-01-23 14:39:09 -08:00
ld hl, wOTPartyMonNicknames
ld a, [wCurPartyMon]
call SkipNames
ld de, wEnemyMonNickname
2018-01-20 09:25:55 -08:00
ld bc, MON_NAME_LENGTH
call CopyBytes
2018-01-23 14:39:09 -08:00
ld hl, wEnemyMonAttack
ld de, wEnemyStats
ld bc, PARTYMON_STRUCT_LENGTH - MON_ATK
call CopyBytes
2015-11-07 18:04:54 -08:00
call ApplyStatusEffectOnEnemyStats
2018-01-23 14:39:09 -08:00
ld hl, wBaseType1
ld de, wEnemyMonType1
ld a, [hli]
ld [de], a
inc de
ld a, [hl]
ld [de], a
; The enemy mon's base Sp. Def isn't needed since its base
; Sp. Atk is also used to calculate Sp. Def stat experience.
2018-01-23 14:39:09 -08:00
ld hl, wBaseStats
ld de, wEnemyMonBaseStats
ld b, NUM_STATS - 1
2016-01-12 21:39:41 -08:00
.loop
ld a, [hli]
ld [de], a
inc de
dec b
2016-01-12 21:39:41 -08:00
jr nz, .loop
2018-01-23 14:39:09 -08:00
ld a, [wCurPartyMon]
ld [wCurOTMon], a
ret
2018-06-24 07:09:41 -07:00
SwitchPlayerMon:
call ClearSprites
2018-01-23 14:39:09 -08:00
ld a, [wCurBattleMon]
ld [wLastPlayerMon], a
ld a, [wCurPartyMon]
ld [wCurBattleMon], a
2015-11-07 18:04:54 -08:00
call AddBattleParticipant
2015-11-06 13:42:38 -08:00
call InitBattleMon
call ResetPlayerStatLevels
call NewBattleMonStatus
call BreakAttraction
2015-11-07 06:48:32 -08:00
call SendOutPlayerMon
2019-04-08 05:15:10 -07:00
call EmptyBattleTextbox
call LoadTilemapToTempTilemap
2018-01-23 14:39:09 -08:00
ld hl, wEnemyMonHP
ld a, [hli]
or [hl]
ret
2018-06-24 07:09:41 -07:00
SendOutPlayerMon:
2018-01-23 14:39:09 -08:00
ld hl, wBattleMonDVs
predef GetUnownLetter
hlcoord 1, 5
ld b, 7
ld c, 8
call ClearBox
call WaitBGMap
xor a
ldh [hBGMapMode], a
call GetBattleMonBackpic
xor a
ldh [hGraphicStartTile], a
ld [wBattleMenuCursorPosition], a
2018-01-23 14:39:09 -08:00
ld [wCurMoveNum], a
ld [wTypeModifier], a
ld [wPlayerMoveStruct + MOVE_ANIM], a
2018-01-23 14:39:09 -08:00
ld [wLastPlayerCounterMove], a
ld [wLastEnemyCounterMove], a
ld [wLastPlayerMove], a
call CheckAmuletCoin
2015-11-09 13:41:09 -08:00
call FinishBattleAnim
xor a
2015-11-08 10:27:26 -08:00
ld [wEnemyWrapCount], a
call SetPlayerTurn
xor a
2015-12-23 11:00:29 -08:00
ld [wNumHits], a
2015-12-23 17:46:23 -08:00
ld [wBattleAnimParam], a
ld de, ANIM_SEND_OUT_MON
2015-09-09 16:27:07 -07:00
call Call_PlayBattleAnim
2015-11-06 13:42:38 -08:00
call BattleCheckPlayerShininess
2015-11-07 06:48:32 -08:00
jr nc, .not_shiny
2015-12-23 17:46:23 -08:00
ld a, 1
ld [wBattleAnimParam], a
ld de, ANIM_SEND_OUT_MON
2015-09-09 16:27:07 -07:00
call Call_PlayBattleAnim
2015-11-07 06:48:32 -08:00
.not_shiny
ld a, MON_SPECIES
call GetPartyParamLocation
ld b, h
ld c, l
2017-12-24 09:47:30 -08:00
farcall CheckFaintedFrzSlp
2015-11-07 06:48:32 -08:00
jr c, .statused
ld a, $f0
2018-01-23 14:39:09 -08:00
ld [wCryTracks], a
ld a, [wCurPartySpecies]
2014-07-18 10:25:03 -07:00
call PlayStereoCry
2015-11-07 06:48:32 -08:00
.statused
call UpdatePlayerHUD
ld a, $1
ldh [hBGMapMode], a
ret
2018-06-24 07:09:41 -07:00
NewBattleMonStatus:
xor a
2018-01-23 14:39:09 -08:00
ld [wLastPlayerCounterMove], a
ld [wLastEnemyCounterMove], a
ld [wLastPlayerMove], a
ld hl, wPlayerSubStatus1
2015-07-20 19:18:18 -07:00
rept 4
ld [hli], a
2015-07-20 19:18:18 -07:00
endr
ld [hl], a
2018-01-23 14:39:09 -08:00
ld hl, wPlayerUsedMoves
ld [hli], a
ld [hli], a
ld [hli], a
ld [hl], a
2018-01-23 14:39:09 -08:00
ld [wPlayerDisableCount], a
ld [wPlayerFuryCutterCount], a
ld [wPlayerProtectCount], a
2015-11-05 16:13:09 -08:00
ld [wPlayerRageCounter], a
2018-01-23 14:39:09 -08:00
ld [wDisabledMove], a
ld [wPlayerMinimized], a
2015-11-08 10:27:26 -08:00
ld [wEnemyWrapCount], a
ld [wPlayerWrapCount], a
2018-01-23 14:39:09 -08:00
ld [wPlayerTurnsTaken], a
ld hl, wEnemySubStatus5
res SUBSTATUS_CANT_RUN, [hl]
ret
2018-06-24 07:09:41 -07:00
BreakAttraction:
2018-01-23 14:39:09 -08:00
ld hl, wPlayerSubStatus1
res SUBSTATUS_IN_LOVE, [hl]
2018-01-23 14:39:09 -08:00
ld hl, wEnemySubStatus1
res SUBSTATUS_IN_LOVE, [hl]
ret
2018-06-24 07:09:41 -07:00
SpikesDamage:
2018-01-23 14:39:09 -08:00
ld hl, wPlayerScreens
ld de, wBattleMonType
ld bc, UpdatePlayerHUD
ldh a, [hBattleTurn]
and a
jr z, .ok
2018-01-23 14:39:09 -08:00
ld hl, wEnemyScreens
ld de, wEnemyMonType
ld bc, UpdateEnemyHUD
.ok
bit SCREENS_SPIKES, [hl]
ret z
; Flying-types aren't affected by Spikes.
ld a, [de]
cp FLYING
ret z
inc de
ld a, [de]
cp FLYING
ret z
push bc
2015-09-09 16:27:07 -07:00
ld hl, BattleText_UserHurtBySpikes ; "hurt by SPIKES!"
2019-04-08 05:15:10 -07:00
call StdBattleTextbox
call GetEighthMaxHP
2015-11-06 17:55:16 -08:00
call SubtractHPFromTarget
pop hl
call .hl
jp WaitBGMap
.hl
jp hl
2018-06-24 07:09:41 -07:00
PursuitSwitch:
ld a, BATTLE_VARS_MOVE
call GetBattleVar
ld b, a
2013-12-30 20:32:37 -08:00
call GetMoveEffect
ld a, b
cp EFFECT_PURSUIT
2015-11-05 16:13:09 -08:00
jr nz, .done
2018-01-23 14:39:09 -08:00
ld a, [wCurBattleMon]
push af
ld hl, DoPlayerTurn
ldh a, [hBattleTurn]
and a
2015-11-05 16:13:09 -08:00
jr z, .do_turn
ld hl, DoEnemyTurn
2018-01-23 14:39:09 -08:00
ld a, [wLastPlayerMon]
ld [wCurBattleMon], a
2015-11-05 16:13:09 -08:00
.do_turn
ld a, BANK(DoPlayerTurn) ; aka BANK(DoEnemyTurn)
rst FarCall
ld a, BATTLE_VARS_MOVE
call GetBattleVarAddr
ld a, $ff
ld [hl], a
pop af
2018-01-23 14:39:09 -08:00
ld [wCurBattleMon], a
ldh a, [hBattleTurn]
and a
2015-11-05 16:13:09 -08:00
jr z, .check_enemy_fainted
2018-01-23 14:39:09 -08:00
ld a, [wLastPlayerMon]
2015-07-20 22:52:46 -07:00
call UpdateBattleMon
2018-01-23 14:39:09 -08:00
ld hl, wBattleMonHP
ld a, [hli]
or [hl]
2015-11-05 16:13:09 -08:00
jr nz, .done
; BUG: A Pokémon that fainted from Pursuit will have its old status condition when revived (see docs/bugs_and_glitches.md)
ld a, $f0
2018-01-23 14:39:09 -08:00
ld [wCryTracks], a
ld a, [wBattleMonSpecies]
2014-07-18 10:25:03 -07:00
call PlayStereoCry
2018-01-23 14:39:09 -08:00
ld a, [wLastPlayerMon]
ld c, a
2015-11-07 18:04:54 -08:00
ld hl, wBattleParticipantsNotFainted
ld b, RESET_FLAG
predef SmallFarFlagAction
2015-10-19 13:49:29 -07:00
call PlayerMonFaintedAnimation
ld hl, BattleText_MonFainted
2015-11-05 16:13:09 -08:00
jr .done_fainted
2015-11-05 16:13:09 -08:00
.check_enemy_fainted
2018-01-23 14:39:09 -08:00
ld hl, wEnemyMonHP
ld a, [hli]
or [hl]
2015-11-05 16:13:09 -08:00
jr nz, .done
ld de, SFX_KINESIS
call PlaySFX
call WaitSFX
ld de, SFX_FAINT
call PlaySFX
call WaitSFX
2015-10-19 13:49:29 -07:00
call EnemyMonFaintedAnimation
ld hl, BattleText_EnemyMonFainted
2015-11-05 16:13:09 -08:00
.done_fainted
2019-04-08 05:15:10 -07:00
call StdBattleTextbox
scf
ret
2015-11-05 16:13:09 -08:00
.done
and a
ret
2018-06-24 07:09:41 -07:00
RecallPlayerMon:
ldh a, [hBattleTurn]
push af
xor a
ldh [hBattleTurn], a
2015-12-23 11:00:29 -08:00
ld [wNumHits], a
ld de, ANIM_RETURN_MON
2015-09-09 16:27:07 -07:00
call Call_PlayBattleAnim
pop af
ldh [hBattleTurn], a
ret
2018-06-24 07:09:41 -07:00
HandleHealingItems:
ldh a, [hSerialConnectionStatus]
cp USING_EXTERNAL_CLOCK
2015-11-06 06:04:27 -08:00
jr z, .player_1
call SetPlayerTurn
2015-11-08 10:27:26 -08:00
call HandleHPHealingItem
2015-11-06 19:36:06 -08:00
call UseHeldStatusHealingItem
call UseConfusionHealingItem
call SetEnemyTurn
2015-11-08 10:27:26 -08:00
call HandleHPHealingItem
2015-11-06 19:36:06 -08:00
call UseHeldStatusHealingItem
jp UseConfusionHealingItem
2015-11-06 06:04:27 -08:00
.player_1
call SetEnemyTurn
2015-11-08 10:27:26 -08:00
call HandleHPHealingItem
2015-11-06 19:36:06 -08:00
call UseHeldStatusHealingItem
call UseConfusionHealingItem
call SetPlayerTurn
2015-11-08 10:27:26 -08:00
call HandleHPHealingItem
2015-11-06 19:36:06 -08:00
call UseHeldStatusHealingItem
jp UseConfusionHealingItem
2018-06-24 07:09:41 -07:00
HandleHPHealingItem:
2017-12-24 09:47:30 -08:00
callfar GetOpponentItem
ld a, b
cp HELD_BERRY
ret nz
2018-01-23 14:39:09 -08:00
ld de, wEnemyMonHP + 1
ld hl, wEnemyMonMaxHP
ldh a, [hBattleTurn]
and a
2015-11-08 10:27:26 -08:00
jr z, .go
2018-01-23 14:39:09 -08:00
ld de, wBattleMonHP + 1
ld hl, wBattleMonMaxHP
2015-11-08 10:27:26 -08:00
.go
2016-03-01 19:31:21 -08:00
; If, and only if, Pokemon's HP is less than half max, use the item.
; Store current HP in Buffer 3/4
push bc
ld a, [de]
ld [wHPBuffer2], a
add a
ld c, a
dec de
ld a, [de]
inc de
ld [wHPBuffer2 + 1], a
adc a
ld b, a
ld a, b
cp [hl]
ld a, c
pop bc
2015-11-08 10:27:26 -08:00
jr z, .equal
jr c, .less
ret
2015-11-08 10:27:26 -08:00
.equal
inc hl
cp [hl]
dec hl
ret nc
2015-11-08 10:27:26 -08:00
.less
2015-11-06 19:36:06 -08:00
call ItemRecoveryAnim
; store max HP in wHPBuffer1
ld a, [hli]
ld [wHPBuffer1 + 1], a
ld a, [hl]
ld [wHPBuffer1], a
ld a, [de]
add c
ld [wHPBuffer3], a
ld c, a
dec de
ld a, [de]
2018-02-04 10:16:40 -08:00
adc 0
ld [wHPBuffer3 + 1], a
ld b, a
ld a, [hld]
cp c
ld a, [hl]
sbc b
2015-11-08 10:27:26 -08:00
jr nc, .okay
ld a, [hli]
ld [wHPBuffer3 + 1], a
ld a, [hl]
ld [wHPBuffer3], a
2015-11-08 10:27:26 -08:00
.okay
ld a, [wHPBuffer3 + 1]
ld [de], a
inc de
ld a, [wHPBuffer3]
ld [de], a
ldh a, [hBattleTurn]
ld [wWhichHPBar], a
and a
hlcoord 2, 2
2015-11-08 10:27:26 -08:00
jr z, .got_hp_bar_coords
hlcoord 10, 9
2015-11-08 10:27:26 -08:00
.got_hp_bar_coords
ld [wWhichHPBar], a
predef AnimateHPBar
2015-11-06 19:36:06 -08:00
UseOpponentItem:
call RefreshBattleHuds
2017-12-24 09:47:30 -08:00
callfar GetOpponentItem
ld a, [hl]
ld [wNamedObjectIndex], a
call GetItemName
2017-12-24 09:47:30 -08:00
callfar ConsumeHeldItem
ld hl, RecoveredUsingText
2019-04-08 05:15:10 -07:00
jp StdBattleTextbox
2018-06-24 07:09:41 -07:00
ItemRecoveryAnim:
push hl
push de
push bc
2019-04-08 05:15:10 -07:00
call EmptyBattleTextbox
ld a, RECOVER
2018-01-23 14:39:09 -08:00
ld [wFXAnimID], a
call SwitchTurnCore
xor a
2015-12-23 11:00:29 -08:00
ld [wNumHits], a
2018-01-23 14:39:09 -08:00
ld [wFXAnimID + 1], a
predef PlayBattleAnim
call SwitchTurnCore
pop bc
pop de
pop hl
ret
2018-06-24 07:09:41 -07:00
UseHeldStatusHealingItem:
2017-12-24 09:47:30 -08:00
callfar GetOpponentItem
2018-01-25 18:34:42 -08:00
ld hl, HeldStatusHealingEffects
2015-11-06 19:36:06 -08:00
.loop
ld a, [hli]
cp $ff
ret z
inc hl
cp b
2015-11-06 19:36:06 -08:00
jr nz, .loop
dec hl
ld b, [hl]
ld a, BATTLE_VARS_STATUS_OPP
call GetBattleVarAddr
and b
ret z
xor a
ld [hl], a
push bc
call UpdateOpponentInParty
pop bc
ld a, BATTLE_VARS_SUBSTATUS5_OPP
call GetBattleVarAddr
and [hl]
res SUBSTATUS_TOXIC, [hl]
ld a, BATTLE_VARS_SUBSTATUS1_OPP
call GetBattleVarAddr
and [hl]
res SUBSTATUS_NIGHTMARE, [hl]
ld a, b
2015-11-08 10:27:26 -08:00
cp ALL_STATUS
2015-11-06 19:36:06 -08:00
jr nz, .skip_confuse
ld a, BATTLE_VARS_SUBSTATUS3_OPP
call GetBattleVarAddr
res SUBSTATUS_CONFUSED, [hl]
2015-11-06 19:36:06 -08:00
.skip_confuse
2015-11-06 17:55:16 -08:00
ld hl, CalcEnemyStats
ldh a, [hBattleTurn]
and a
2015-11-06 19:36:06 -08:00
jr z, .got_pointer
2015-11-06 17:55:16 -08:00
ld hl, CalcPlayerStats
2015-11-06 19:36:06 -08:00
.got_pointer
call SwitchTurnCore
ld a, BANK(CalcPlayerStats) ; aka BANK(CalcEnemyStats)
rst FarCall
call SwitchTurnCore
2015-11-06 19:36:06 -08:00
call ItemRecoveryAnim
call UseOpponentItem
ld a, $1
and a
ret
2018-01-25 18:34:42 -08:00
INCLUDE "data/battle/held_heal_status.asm"
2018-06-24 07:09:41 -07:00
UseConfusionHealingItem:
ld a, BATTLE_VARS_SUBSTATUS3_OPP
call GetBattleVar
bit SUBSTATUS_CONFUSED, a
ret z
2017-12-24 09:47:30 -08:00
callfar GetOpponentItem
ld a, b
cp HELD_HEAL_CONFUSION
2015-11-08 10:27:26 -08:00
jr z, .heal_status
cp HELD_HEAL_STATUS
ret nz
2015-11-08 10:27:26 -08:00
.heal_status
ld a, [hl]
ld [wNamedObjectIndex], a
ld a, BATTLE_VARS_SUBSTATUS3_OPP
call GetBattleVarAddr
res SUBSTATUS_CONFUSED, [hl]
call GetItemName
2015-11-06 19:36:06 -08:00
call ItemRecoveryAnim
ld hl, BattleText_ItemHealedConfusion
2019-04-08 05:15:10 -07:00
call StdBattleTextbox
ldh a, [hBattleTurn]
and a
2015-11-08 10:27:26 -08:00
jr nz, .do_partymon
call GetOTPartymonItem
xor a
ld [bc], a
ld a, [wBattleMode]
dec a
ret z
ld [hl], $0
ret
2015-11-08 10:27:26 -08:00
.do_partymon
call GetPartymonItem
xor a
ld [bc], a
ld [hl], a
ret
2018-06-24 07:09:41 -07:00
HandleStatBoostingHeldItems:
2015-11-08 10:27:26 -08:00
; The effects handled here are not used in-game.
ldh a, [hSerialConnectionStatus]
cp USING_EXTERNAL_CLOCK
2015-11-06 06:04:27 -08:00
jr z, .player_1
2015-11-08 10:27:26 -08:00
call .DoPlayer
jp .DoEnemy
.player_1
call .DoEnemy
jp .DoPlayer
2018-06-24 07:09:41 -07:00
.DoPlayer:
2015-11-08 10:27:26 -08:00
call GetPartymonItem
ld a, $0
2015-11-08 10:27:26 -08:00
jp .HandleItem
2018-06-24 07:09:41 -07:00
.DoEnemy:
2015-11-08 10:27:26 -08:00
call GetOTPartymonItem
ld a, $1
2018-06-24 07:09:41 -07:00
.HandleItem:
ldh [hBattleTurn], a
ld d, h
ld e, l
push de
push bc
ld a, [bc]
ld b, a
2017-12-24 09:47:30 -08:00
callfar GetItemHeldEffect
2018-01-25 18:34:42 -08:00
ld hl, HeldStatUpItems
2015-11-08 10:27:26 -08:00
.loop
ld a, [hli]
2018-01-25 18:34:42 -08:00
cp -1
2015-11-08 10:27:26 -08:00
jr z, .finish
inc hl
2015-12-26 18:59:03 -08:00
inc hl
cp b
2015-11-08 10:27:26 -08:00
jr nz, .loop
pop bc
ld a, [bc]
ld [wNamedObjectIndex], a
push bc
dec hl
2015-12-26 18:59:03 -08:00
dec hl
ld a, [hli]
ld h, [hl]
ld l, a
ld a, BANK(BattleCommand_AttackUp)
rst FarCall
pop bc
pop de
2018-01-23 14:39:09 -08:00
ld a, [wFailedMessage]
and a
ret nz
xor a
ld [bc], a
ld [de], a
call GetItemName
2015-09-09 16:27:07 -07:00
ld hl, BattleText_UsersStringBuffer1Activated
2019-04-08 05:15:10 -07:00
call StdBattleTextbox
2017-12-24 09:47:30 -08:00
callfar BattleCommand_StatUpMessage
ret
2015-11-08 10:27:26 -08:00
.finish
pop bc
pop de
ret
2018-01-25 18:34:42 -08:00
INCLUDE "data/battle/held_stat_up.asm"
2018-06-24 07:09:41 -07:00
GetPartymonItem:
2018-01-23 14:39:09 -08:00
ld hl, wPartyMon1Item
ld a, [wCurBattleMon]
call GetPartyLocation
2018-01-23 14:39:09 -08:00
ld bc, wBattleMonItem
ret
2018-06-24 07:09:41 -07:00
GetOTPartymonItem:
2018-01-23 14:39:09 -08:00
ld hl, wOTPartyMon1Item
ld a, [wCurOTMon]
call GetPartyLocation
2018-01-23 14:39:09 -08:00
ld bc, wEnemyMonItem
ret
2018-06-24 07:09:41 -07:00
UpdateBattleHUDs:
push hl
push de
push bc
call DrawPlayerHUD
2018-01-23 14:39:09 -08:00
ld hl, wPlayerHPPal
call SetHPPal
call CheckDanger
call DrawEnemyHUD
2018-01-23 14:39:09 -08:00
ld hl, wEnemyHPPal
call SetHPPal
pop bc
pop de
pop hl
ret
2018-06-24 07:09:41 -07:00
UpdatePlayerHUD::
push hl
push de
push bc
call DrawPlayerHUD
call UpdatePlayerHPPal
call CheckDanger
pop bc
pop de
pop hl
ret
2018-06-24 07:09:41 -07:00
DrawPlayerHUD:
xor a
ldh [hBGMapMode], a
; Clear the area
hlcoord 9, 7
lb bc, 5, 11
call ClearBox
2017-12-24 09:47:30 -08:00
farcall DrawPlayerHUDBorder
hlcoord 18, 9
ld [hl], $73 ; vertical bar
call PrintPlayerHUD
; HP bar
hlcoord 10, 9
ld b, 1
xor a ; PARTYMON
2018-01-23 14:39:09 -08:00
ld [wMonType], a
predef DrawPlayerHP
; Exp bar
push de
2018-01-23 14:39:09 -08:00
ld a, [wCurBattleMon]
ld hl, wPartyMon1Exp + 2
call GetPartyLocation
ld d, h
ld e, l
hlcoord 10, 11
2018-01-23 14:39:09 -08:00
ld a, [wTempMonLevel]
ld b, a
call FillInExpBar
pop de
ret
2018-06-24 07:09:41 -07:00
UpdatePlayerHPPal:
2018-01-23 14:39:09 -08:00
ld hl, wPlayerHPPal
2015-11-23 13:04:53 -08:00
jp UpdateHPPal
2018-06-24 07:09:41 -07:00
CheckDanger:
2018-01-23 14:39:09 -08:00
ld hl, wBattleMonHP
ld a, [hli]
or [hl]
jr z, .no_danger
ld a, [wBattleLowHealthAlarm]
and a
jr nz, .done
2018-01-23 14:39:09 -08:00
ld a, [wPlayerHPPal]
cp HP_RED
jr z, .danger
.no_danger
ld hl, wLowHealthAlarm
res DANGER_ON_F, [hl]
jr .done
.danger
ld hl, wLowHealthAlarm
set DANGER_ON_F, [hl]
.done
ret
2018-06-24 07:09:41 -07:00
PrintPlayerHUD:
ld de, wBattleMonNickname
hlcoord 10, 7
call Battle_DummyFunction
call PlaceString
push bc
2018-01-23 14:39:09 -08:00
ld a, [wCurBattleMon]
ld hl, wPartyMon1DVs
call GetPartyLocation
2018-01-23 14:39:09 -08:00
ld de, wTempMonDVs
ld a, [hli]
ld [de], a
inc de
ld a, [hl]
ld [de], a
2018-01-23 14:39:09 -08:00
ld hl, wBattleMonLevel
ld de, wTempMonLevel
ld bc, wTempMonStructEnd - wTempMonLevel
call CopyBytes ; battle_struct and party_struct end with the same data
2018-01-23 14:39:09 -08:00
ld a, [wCurBattleMon]
ld hl, wPartyMon1Species
call GetPartyLocation
ld a, [hl]
2018-01-23 14:39:09 -08:00
ld [wCurPartySpecies], a
ld [wCurSpecies], a
call GetBaseData
pop hl
dec hl
2016-05-11 14:16:03 -07:00
ld a, TEMPMON
2018-01-23 14:39:09 -08:00
ld [wMonType], a
callfar GetGender
ld a, " "
2016-01-17 21:39:01 -08:00
jr c, .got_gender_char
ld a, "♂"
2016-01-17 21:39:01 -08:00
jr nz, .got_gender_char
ld a, "♀"
2016-01-17 21:39:01 -08:00
.got_gender_char
hlcoord 17, 8
ld [hl], a
hlcoord 14, 8
2016-01-17 21:39:01 -08:00
push af ; back up gender
push hl
2018-01-23 14:39:09 -08:00
ld de, wBattleMonStatus
predef PlaceNonFaintStatus
pop hl
pop bc
ret nz
ld a, b
cp " "
2016-01-17 21:39:01 -08:00
jr nz, .copy_level ; male or female
dec hl ; genderless
2016-01-17 21:39:01 -08:00
.copy_level
2018-01-23 14:39:09 -08:00
ld a, [wBattleMonLevel]
ld [wTempMonLevel], a
jp PrintLevel
2018-06-24 07:09:41 -07:00
UpdateEnemyHUD::
push hl
push de
push bc
call DrawEnemyHUD
call UpdateEnemyHPPal
pop bc
pop de
pop hl
ret
2018-06-24 07:09:41 -07:00
DrawEnemyHUD:
xor a
ldh [hBGMapMode], a
hlcoord 1, 0
lb bc, 4, 11
call ClearBox
2017-12-24 09:47:30 -08:00
farcall DrawEnemyHUDBorder
2018-01-23 14:39:09 -08:00
ld a, [wTempEnemyMonSpecies]
ld [wCurSpecies], a
ld [wCurPartySpecies], a
call GetBaseData
ld de, wEnemyMonNickname
hlcoord 1, 0
call Battle_DummyFunction
call PlaceString
ld h, b
ld l, c
dec hl
2018-01-23 14:39:09 -08:00
ld hl, wEnemyMonDVs
ld de, wTempMonDVs
ld a, [wEnemySubStatus5]
bit SUBSTATUS_TRANSFORMED, a
jr z, .ok
2016-01-10 14:44:09 -08:00
ld hl, wEnemyBackupDVs
.ok
ld a, [hli]
ld [de], a
inc de
ld a, [hl]
ld [de], a
2016-05-11 14:16:03 -07:00
ld a, TEMPMON
2018-01-23 14:39:09 -08:00
ld [wMonType], a
callfar GetGender
ld a, " "
2015-11-23 13:04:53 -08:00
jr c, .got_gender
ld a, "♂"
2015-11-23 13:04:53 -08:00
jr nz, .got_gender
ld a, "♀"
2015-11-23 13:04:53 -08:00
.got_gender
hlcoord 9, 1
ld [hl], a
hlcoord 6, 1
push af
push hl
2018-01-23 14:39:09 -08:00
ld de, wEnemyMonStatus
predef PlaceNonFaintStatus
pop hl
pop bc
2015-11-23 13:04:53 -08:00
jr nz, .skip_level
ld a, b
cp " "
2015-11-23 13:04:53 -08:00
jr nz, .print_level
dec hl
2015-11-23 13:04:53 -08:00
.print_level
2018-01-23 14:39:09 -08:00
ld a, [wEnemyMonLevel]
ld [wTempMonLevel], a
call PrintLevel
2015-11-23 13:04:53 -08:00
.skip_level
2018-01-23 14:39:09 -08:00
ld hl, wEnemyMonHP
ld a, [hli]
ldh [hMultiplicand + 1], a
ld a, [hld]
ldh [hMultiplicand + 2], a
or [hl]
2015-11-23 13:04:53 -08:00
jr nz, .not_fainted
ld c, a
ld e, a
ld d, HP_BAR_LENGTH
2015-11-23 13:04:53 -08:00
jp .draw_bar
2015-11-23 13:04:53 -08:00
.not_fainted
xor a
ldh [hMultiplicand + 0], a
ld a, HP_BAR_LENGTH_PX
ldh [hMultiplier], a
call Multiply
2018-01-23 14:39:09 -08:00
ld hl, wEnemyMonMaxHP
ld a, [hli]
ld b, a
ld a, [hl]
ldh [hMultiplier], a
ld a, b
and a
2015-11-23 13:04:53 -08:00
jr z, .less_than_256_max
ldh a, [hMultiplier]
srl b
rr a
srl b
rr a
ldh [hDivisor], a
ldh a, [hProduct + 2]
ld b, a
srl b
ldh a, [hProduct + 3]
rr a
srl b
rr a
ldh [hProduct + 3], a
ld a, b
ldh [hProduct + 2], a
2015-11-23 13:04:53 -08:00
.less_than_256_max
ldh a, [hProduct + 2]
ldh [hDividend + 0], a
ldh a, [hProduct + 3]
ldh [hDividend + 1], a
2015-11-23 13:04:53 -08:00
ld a, 2
ld b, a
call Divide
ldh a, [hQuotient + 3]
ld e, a
ld a, HP_BAR_LENGTH
ld d, a
ld c, a
2015-11-23 13:04:53 -08:00
.draw_bar
xor a
ld [wWhichHPBar], a
hlcoord 2, 2
ld b, 0
2015-11-08 07:59:28 -08:00
call DrawBattleHPBar
ret
2018-06-24 07:09:41 -07:00
UpdateEnemyHPPal:
2018-01-23 14:39:09 -08:00
ld hl, wEnemyHPPal
2015-11-23 13:04:53 -08:00
call UpdateHPPal
ret
2018-06-24 07:09:41 -07:00
UpdateHPPal:
ld b, [hl]
call SetHPPal
ld a, [hl]
cp b
ret z
2015-11-09 13:41:09 -08:00
jp FinishBattleAnim
Battle_DummyFunction:
; called before placing either battler's nickname in the HUD
ret
2018-06-24 07:09:41 -07:00
BattleMenu:
xor a
ldh [hBGMapMode], a
call LoadTempTilemapToTilemap
2018-01-23 14:39:09 -08:00
ld a, [wBattleType]
2015-09-09 16:27:07 -07:00
cp BATTLETYPE_DEBUG
jr z, .ok
cp BATTLETYPE_TUTORIAL
jr z, .ok
2019-04-08 05:15:10 -07:00
call EmptyBattleTextbox
call UpdateBattleHuds
2019-04-08 05:15:10 -07:00
call EmptyBattleTextbox
call LoadTilemapToTempTilemap
.ok
.loop
2018-01-23 14:39:09 -08:00
ld a, [wBattleType]
cp BATTLETYPE_CONTEST
jr nz, .not_contest
2017-12-24 09:47:30 -08:00
farcall ContestBattleMenu
jr .next
.not_contest
; Auto input: choose "ITEM"
2018-01-23 14:39:09 -08:00
ld a, [wInputType]
or a
jr z, .skip_dude_pack_select
2017-12-24 09:47:30 -08:00
farcall _DudeAutoInput_DownA
.skip_dude_pack_select
call LoadBattleMenu2
ret c
.next
ld a, $1
ldh [hBGMapMode], a
ld a, [wBattleMenuCursorPosition]
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
2018-06-24 07:09:41 -07:00
BattleMenu_Fight:
xor a
2015-11-23 13:04:53 -08:00
ld [wNumFleeAttempts], a
call SafeLoadTempTilemapToTilemap
and a
ret
2018-06-24 07:09:41 -07:00
LoadBattleMenu2:
2017-12-24 09:47:30 -08:00
farcall LoadBattleMenu
and a
ret
2018-06-24 07:09:41 -07:00
BattleMenu_Pack:
ld a, [wLinkMode]
and a
jp nz, .ItemsCantBeUsed
call LoadStandardMenuHeader
2018-01-23 14:39:09 -08:00
ld a, [wBattleType]
cp BATTLETYPE_TUTORIAL
jr z, .tutorial
cp BATTLETYPE_CONTEST
jr z, .contest
2017-12-24 09:47:30 -08:00
farcall BattlePack
ld a, [wBattlePlayerAction]
and a ; BATTLEPLAYERACTION_USEMOVE?
jr z, .didnt_use_item
jr .got_item
.tutorial
2017-12-24 09:47:30 -08:00
farcall TutorialPack
ld a, POKE_BALL
2018-01-23 14:39:09 -08:00
ld [wCurItem], a
call DoItemEffect
jr .got_item
.contest
ld a, PARK_BALL
2018-01-23 14:39:09 -08:00
ld [wCurItem], a
call DoItemEffect
.got_item
call .UseItem
ret
.didnt_use_item
call ClearPalettes
call DelayFrame
2015-11-10 16:51:13 -08:00
call _LoadBattleFontsHPBar
call GetBattleMonBackpic
call GetEnemyMonFrontpic
call ExitMenu
call WaitBGMap
2015-11-09 13:41:09 -08:00
call FinishBattleAnim
call LoadTilemapToTempTilemap
jp BattleMenu
2018-06-24 07:09:41 -07:00
.ItemsCantBeUsed:
2015-09-09 16:27:07 -07:00
ld hl, BattleText_ItemsCantBeUsedHere
2019-04-08 05:15:10 -07:00
call StdBattleTextbox
jp BattleMenu
2018-06-24 07:09:41 -07:00
.UseItem:
2015-12-07 08:28:58 -08:00
ld a, [wWildMon]
and a
jr nz, .run
2017-12-24 09:47:30 -08:00
callfar CheckItemPocket
ld a, [wItemAttributeValue]
cp BALL
jr z, .ball
2015-11-11 20:38:57 -08:00
call ClearBGPalettes
.ball
xor a
ldh [hBGMapMode], a
2015-11-10 16:51:13 -08:00
call _LoadBattleFontsHPBar
call ClearSprites
2018-01-23 14:39:09 -08:00
ld a, [wBattleType]
cp BATTLETYPE_TUTORIAL
jr z, .tutorial2
call GetBattleMonBackpic
.tutorial2
call GetEnemyMonFrontpic
ld a, $1
2015-12-15 15:59:49 -08:00
ld [wMenuCursorY], a
call ExitMenu
2015-11-08 10:27:26 -08:00
call UpdateBattleHUDs
call WaitBGMap
call LoadTilemapToTempTilemap
call ClearMenuAndWindowData
2015-11-09 13:41:09 -08:00
call FinishBattleAnim
and a
ret
.run
xor a
2015-12-07 08:28:58 -08:00
ld [wWildMon], a
2015-10-24 07:34:19 -07:00
ld a, [wBattleResult]
2018-04-05 08:44:02 -07:00
and BATTLERESULT_BITMASK
ld [wBattleResult], a ; WIN
call ClearMenuAndWindowData
2024-02-10 15:16:00 -08:00
call SetDefaultBGPAndOBP
scf
ret
2018-06-24 07:09:41 -07:00
BattleMenu_PKMN:
call LoadStandardMenuHeader
2016-01-12 21:39:41 -08:00
BattleMenuPKMN_ReturnFromStats:
call ExitMenu
call LoadStandardMenuHeader
2015-11-11 20:38:57 -08:00
call ClearBGPalettes
BattleMenuPKMN_Loop:
call SetUpBattlePartyMenu_Loop
xor a
2018-01-23 14:39:09 -08:00
ld [wPartyMenuActionText], a
2016-01-12 21:39:41 -08:00
call JumpToPartyMenuAndPrintText
call SelectBattleMon
jr c, .Cancel
.loop
2017-12-24 09:47:30 -08:00
farcall FreezeMonIcons
call .GetMenu
jr c, .PressedB
2015-12-17 19:31:16 -08:00
call PlaceHollowCursor
2015-12-15 15:59:49 -08:00
ld a, [wMenuCursorY]
cp $1 ; SWITCH
jp z, TryPlayerSwitch
cp $2 ; STATS
jr z, .Stats
cp $3 ; CANCEL
jr z, .Cancel
jr .loop
.PressedB:
jr BattleMenuPKMN_Loop
.Stats:
2015-12-23 06:12:29 -08:00
call Battle_StatsScreen
2016-01-12 21:39:41 -08:00
jp BattleMenuPKMN_ReturnFromStats
.Cancel:
call ClearSprites
call ClearPalettes
call DelayFrame
2015-11-10 16:51:13 -08:00
call _LoadHPBar
call CloseWindow
call LoadTilemapToTempTilemap
call GetMemCGBLayout
2024-02-10 15:16:00 -08:00
call SetDefaultBGPAndOBP
jp BattleMenu
2018-06-24 07:09:41 -07:00
.GetMenu:
2017-12-24 09:47:30 -08:00
farcall BattleMonMenu
ret
2018-06-24 07:09:41 -07:00
Battle_StatsScreen:
call DisableLCD
2016-06-07 05:08:51 -07:00
2017-12-28 04:32:33 -08:00
ld hl, vTiles2 tile $31
ld de, vTiles0
2016-06-07 05:08:51 -07:00
ld bc, $11 tiles
call CopyBytes
2016-06-07 05:08:51 -07:00
2017-12-28 04:32:33 -08:00
ld hl, vTiles2
ld de, vTiles0 tile $11
ld bc, $31 tiles
call CopyBytes
2016-06-07 05:08:51 -07:00
call EnableLCD
2016-06-07 05:08:51 -07:00
call ClearSprites
call LowVolume
xor a ; PARTYMON
2018-01-23 14:39:09 -08:00
ld [wMonType], a
2017-12-24 09:47:30 -08:00
farcall BattleStatsScreenInit
call MaxVolume
2016-06-07 05:08:51 -07:00
call DisableLCD
2016-06-07 05:08:51 -07:00
2017-12-28 04:32:33 -08:00
ld hl, vTiles0
ld de, vTiles2 tile $31
ld bc, $11 tiles
call CopyBytes
2016-06-07 05:08:51 -07:00
2017-12-28 04:32:33 -08:00
ld hl, vTiles0 tile $11
ld de, vTiles2
ld bc, $31 tiles
call CopyBytes
2016-06-07 05:08:51 -07:00
call EnableLCD
ret
2018-06-24 07:09:41 -07:00
TryPlayerSwitch:
2018-01-23 14:39:09 -08:00
ld a, [wCurBattleMon]
ld d, a
2018-01-23 14:39:09 -08:00
ld a, [wCurPartyMon]
cp d
jr nz, .check_trapped
ld hl, BattleText_MonIsAlreadyOut
2019-04-08 05:15:10 -07:00
call StdBattleTextbox
jp BattleMenuPKMN_Loop
.check_trapped
2015-11-08 10:27:26 -08:00
ld a, [wPlayerWrapCount]
and a
jr nz, .trapped
2018-01-23 14:39:09 -08:00
ld a, [wEnemySubStatus5]
bit SUBSTATUS_CANT_RUN, a
jr z, .try_switch
.trapped
ld hl, BattleText_MonCantBeRecalled
2019-04-08 05:15:10 -07:00
call StdBattleTextbox
jp BattleMenuPKMN_Loop
.try_switch
2016-03-01 19:31:21 -08:00
call CheckIfCurPartyMonIsFitToFight
jp z, BattleMenuPKMN_Loop
2018-01-23 14:39:09 -08:00
ld a, [wCurBattleMon]
ld [wLastPlayerMon], a
ld a, BATTLEPLAYERACTION_SWITCH
ld [wBattlePlayerAction], a
call ClearPalettes
call DelayFrame
call ClearSprites
2015-11-10 16:51:13 -08:00
call _LoadHPBar
call CloseWindow
call GetMemCGBLayout
2024-02-10 15:16:00 -08:00
call SetDefaultBGPAndOBP
2018-01-23 14:39:09 -08:00
ld a, [wCurPartyMon]
ld [wCurBattleMon], a
2018-06-24 07:09:41 -07:00
PlayerSwitch:
ld a, 1
ld [wPlayerIsSwitching], a
ld a, [wLinkMode]
and a
2015-11-07 18:04:54 -08:00
jr z, .not_linked
call LoadStandardMenuHeader
2015-11-23 13:04:53 -08:00
call LinkBattleSendReceiveAction
call CloseWindow
2015-11-07 18:04:54 -08:00
.not_linked
2015-11-08 16:09:36 -08:00
call ParseEnemyAction
ld a, [wLinkMode]
and a
2015-11-07 18:04:54 -08:00
jr nz, .linked
2015-11-06 06:04:27 -08:00
.switch
call BattleMonEntrance
and a
ret
2015-11-07 18:04:54 -08:00
.linked
ld a, [wBattleAction]
cp BATTLEACTION_STRUGGLE
2015-11-06 06:04:27 -08:00
jp z, .switch
cp BATTLEACTION_SKIPTURN
2015-11-06 06:04:27 -08:00
jp z, .switch
cp BATTLEACTION_SWITCH1
jp c, .switch
cp BATTLEACTION_FORFEIT
jr nz, .dont_run
call WildFled_EnemyFled_LinkBattleCanceled
ret
2015-11-06 06:04:27 -08:00
.dont_run
ldh a, [hSerialConnectionStatus]
cp USING_EXTERNAL_CLOCK
2015-11-06 06:04:27 -08:00
jr z, .player_1
call BattleMonEntrance
2015-11-06 06:04:27 -08:00
call EnemyMonEntrance
and a
ret
2015-11-06 06:04:27 -08:00
.player_1
call EnemyMonEntrance
call BattleMonEntrance
and a
ret
2018-06-24 07:09:41 -07:00
EnemyMonEntrance:
2017-12-24 09:47:30 -08:00
callfar AI_Switch
call SetEnemyTurn
jp SpikesDamage
2018-06-24 07:09:41 -07:00
BattleMonEntrance:
call WithdrawMonText
ld c, 50
call DelayFrames
2018-01-23 14:39:09 -08:00
ld hl, wPlayerSubStatus4
res SUBSTATUS_RAGE, [hl]
call SetEnemyTurn
2015-11-05 16:13:09 -08:00
call PursuitSwitch
jr c, .ok
2016-01-12 21:39:41 -08:00
call RecallPlayerMon
.ok
hlcoord 9, 7
lb bc, 5, 11
call ClearBox
2018-01-23 14:39:09 -08:00
ld a, [wCurBattleMon]
ld [wCurPartyMon], a
2015-11-07 18:04:54 -08:00
call AddBattleParticipant
2015-11-06 13:42:38 -08:00
call InitBattleMon
call ResetPlayerStatLevels
call SendOutMonText
call NewBattleMonStatus
call BreakAttraction
2015-11-07 06:48:32 -08:00
call SendOutPlayerMon
2019-04-08 05:15:10 -07:00
call EmptyBattleTextbox
call LoadTilemapToTempTilemap
call SetPlayerTurn
call SpikesDamage
ld a, $2
2015-12-15 15:59:49 -08:00
ld [wMenuCursorY], a
ret
2018-06-24 07:09:41 -07:00
PassedBattleMonEntrance:
ld c, 50
call DelayFrames
hlcoord 9, 7
lb bc, 5, 11
call ClearBox
2018-01-23 14:39:09 -08:00
ld a, [wCurPartyMon]
ld [wCurBattleMon], a
2015-11-07 18:04:54 -08:00
call AddBattleParticipant
2015-11-06 13:42:38 -08:00
call InitBattleMon
xor a ; FALSE
ld [wApplyStatLevelMultipliersToEnemy], a
2015-09-09 16:27:07 -07:00
call ApplyStatLevelMultiplierOnAllStats
2015-11-07 06:48:32 -08:00
call SendOutPlayerMon
2019-04-08 05:15:10 -07:00
call EmptyBattleTextbox
call LoadTilemapToTempTilemap
call SetPlayerTurn
jp SpikesDamage
2018-06-24 07:09:41 -07:00
BattleMenu_Run:
call SafeLoadTempTilemapToTilemap
ld a, $3
2015-12-15 15:59:49 -08:00
ld [wMenuCursorY], a
2018-01-23 14:39:09 -08:00
ld hl, wBattleMonSpeed
ld de, wEnemyMonSpeed
2015-09-09 16:27:07 -07:00
call TryToRunAwayFromBattle
ld a, FALSE
2015-11-23 13:04:53 -08:00
ld [wFailedToFlee], a
ret c
ld a, [wBattlePlayerAction]
and a ; BATTLEPLAYERACTION_USEMOVE?
ret nz
jp BattleMenu
2018-06-24 07:09:41 -07:00
CheckAmuletCoin:
2018-01-23 14:39:09 -08:00
ld a, [wBattleMonItem]
ld b, a
2017-12-24 09:47:30 -08:00
callfar GetItemHeldEffect
ld a, b
cp HELD_AMULET_COIN
ret nz
ld a, 1
2015-11-22 21:21:21 -08:00
ld [wAmuletCoin], a
ret
2018-06-24 07:09:41 -07:00
MoveSelectionScreen:
2018-01-23 14:39:09 -08:00
ld hl, wEnemyMonMoves
2015-11-23 13:04:53 -08:00
ld a, [wMoveSelectionMenuType]
dec a
2015-11-23 13:04:53 -08:00
jr z, .got_menu_type
dec a
2015-11-23 13:04:53 -08:00
jr z, .ether_elixer_menu
call CheckPlayerHasUsableMoves
ret z ; use Struggle
2018-01-23 14:39:09 -08:00
ld hl, wBattleMonMoves
2015-11-23 13:04:53 -08:00
jr .got_menu_type
2015-11-23 13:04:53 -08:00
.ether_elixer_menu
ld a, MON_MOVES
call GetPartyParamLocation
2015-11-23 13:04:53 -08:00
.got_menu_type
2015-10-17 14:18:52 -07:00
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
2015-11-23 13:04:53 -08:00
ld a, [wMoveSelectionMenuType]
cp $2
2015-11-23 13:04:53 -08:00
jr nz, .got_dims
hlcoord 4, 17 - NUM_MOVES - 1 - 4
ld b, 4
ld c, 14
2015-11-23 13:04:53 -08:00
.got_dims
call Textbox1bpp
hlcoord 6, 17 - NUM_MOVES
2015-11-23 13:04:53 -08:00
ld a, [wMoveSelectionMenuType]
cp $2
2015-11-23 13:04:53 -08:00
jr nz, .got_start_coord
hlcoord 6, 17 - NUM_MOVES - 4
2015-11-23 13:04:53 -08:00
.got_start_coord
ld a, SCREEN_WIDTH
2020-11-03 16:53:07 -08:00
ld [wListMovesLineSpacing], a
predef ListMoves
ld b, 5
2015-11-23 13:04:53 -08:00
ld a, [wMoveSelectionMenuType]
cp $2
ld a, 17 - NUM_MOVES
2015-11-23 13:04:53 -08:00
jr nz, .got_default_coord
ld b, 5
ld a, 17 - NUM_MOVES - 4
2015-11-23 13:04:53 -08:00
.got_default_coord
ld [w2DMenuCursorInitY], a
ld a, b
ld [w2DMenuCursorInitX], a
2015-11-23 13:04:53 -08:00
ld a, [wMoveSelectionMenuType]
cp $1
2015-11-23 13:04:53 -08:00
jr z, .skip_inc
2018-01-23 14:39:09 -08:00
ld a, [wCurMoveNum]
inc a
2015-11-23 13:04:53 -08:00
.skip_inc
2015-12-15 15:59:49 -08:00
ld [wMenuCursorY], a
2018-12-31 11:25:53 -08:00
ld a, 1
2015-12-15 15:59:49 -08:00
ld [wMenuCursorX], a
2015-12-04 05:46:11 -08:00
ld a, [wNumMoves]
inc a
ld [w2DMenuNumRows], a
2018-12-31 11:25:53 -08:00
ld a, 1
ld [w2DMenuNumCols], a
2018-12-31 11:25:53 -08:00
ld c, STATICMENU_ENABLE_LEFT_RIGHT | STATICMENU_ENABLE_START | STATICMENU_WRAP
2015-11-23 13:04:53 -08:00
ld a, [wMoveSelectionMenuType]
dec a
2016-03-01 19:31:21 -08:00
ld b, D_DOWN | D_UP | A_BUTTON
2015-11-23 13:04:53 -08:00
jr z, .okay
dec a
2016-03-01 19:31:21 -08:00
ld b, D_DOWN | D_UP | A_BUTTON | B_BUTTON
2015-11-23 13:04:53 -08:00
jr z, .okay
ld a, [wLinkMode]
and a
2015-11-23 13:04:53 -08:00
jr nz, .okay
2016-03-01 19:31:21 -08:00
ld b, D_DOWN | D_UP | A_BUTTON | B_BUTTON | SELECT
2015-11-23 13:04:53 -08:00
.okay
ld a, b
ld [wMenuJoypadFilter], a
ld a, c
ld [w2DMenuFlags1], a
xor a
ld [w2DMenuFlags2], a
ld a, $10
2015-12-21 11:10:16 -08:00
ld [w2DMenuCursorOffsets], a
2015-11-23 13:04:53 -08:00
.menu_loop
ld a, [wMoveSelectionMenuType]
and a
2015-11-23 13:04:53 -08:00
jr z, .battle_player_moves
dec a
2015-11-23 13:04:53 -08:00
jr nz, .interpret_joypad
hlcoord 11, 14
2020-06-20 19:44:01 -07:00
ld de, .empty_string
call PlaceString
2015-11-23 13:04:53 -08:00
jr .interpret_joypad
2015-11-23 13:04:53 -08:00
.battle_player_moves
call MoveInfoBox
ld a, [wSwappingMove]
and a
2015-11-23 13:04:53 -08:00
jr z, .interpret_joypad
hlcoord 5, 13
ld bc, SCREEN_WIDTH
dec a
call AddNTimes
ld [hl], "▷"
2015-11-23 13:04:53 -08:00
.interpret_joypad
ld a, $1
ldh [hBGMapMode], a
2015-12-15 15:59:49 -08:00
call ScrollingMenuJoypad
2015-11-23 13:04:53 -08:00
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
2016-03-01 19:31:21 -08:00
; A button
push af
xor a
ld [wSwappingMove], a
2015-12-15 15:59:49 -08:00
ld a, [wMenuCursorY]
dec a
2015-12-15 15:59:49 -08:00
ld [wMenuCursorY], a
ld b, a
2015-11-23 13:04:53 -08:00
ld a, [wMoveSelectionMenuType]
dec a
2015-11-23 13:04:53 -08:00
jr nz, .not_enemy_moves_process_b
pop af
ret
2015-11-23 13:04:53 -08:00
.not_enemy_moves_process_b
dec a
ld a, b
2018-01-23 14:39:09 -08:00
ld [wCurMoveNum], a
2015-11-23 13:04:53 -08:00
jr nz, .use_move
pop af
ret
2015-11-23 13:04:53 -08:00
.use_move
pop af
ret nz
2018-01-23 14:39:09 -08:00
ld hl, wBattleMonPP
2015-12-15 15:59:49 -08:00
ld a, [wMenuCursorY]
ld c, a
ld b, 0
add hl, bc
ld a, [hl]
2018-01-11 09:00:01 -08:00
and PP_MASK
2015-11-23 13:04:53 -08:00
jr z, .no_pp_left
2018-01-23 14:39:09 -08:00
ld a, [wPlayerDisableCount]
swap a
and $f
dec a
cp c
2015-11-23 13:04:53 -08:00
jr z, .move_disabled
2016-01-12 09:46:18 -08:00
ld a, [wUnusedPlayerLockedMove]
and a
2015-11-23 13:04:53 -08:00
jr nz, .skip2
2015-12-15 15:59:49 -08:00
ld a, [wMenuCursorY]
2018-01-23 14:39:09 -08:00
ld hl, wBattleMonMoves
ld c, a
ld b, 0
add hl, bc
ld a, [hl]
2015-11-23 13:04:53 -08:00
.skip2
2018-01-23 14:39:09 -08:00
ld [wCurPlayerMove], a
xor a
ret
2015-11-23 13:04:53 -08:00
.move_disabled
2015-09-09 16:27:07 -07:00
ld hl, BattleText_TheMoveIsDisabled
2015-11-23 13:04:53 -08:00
jr .place_textbox_start_over
2015-11-23 13:04:53 -08:00
.no_pp_left
2015-09-09 16:27:07 -07:00
ld hl, BattleText_TheresNoPPLeftForThisMove
2015-11-23 13:04:53 -08:00
.place_textbox_start_over
2019-04-08 05:15:10 -07:00
call StdBattleTextbox
call SafeLoadTempTilemapToTilemap
2015-10-10 04:45:39 -07:00
jp MoveSelectionScreen
2020-06-20 19:44:01 -07:00
.empty_string
db "@"
2015-11-23 13:04:53 -08:00
.pressed_up
2015-12-15 15:59:49 -08:00
ld a, [wMenuCursorY]
and a
2015-11-23 13:04:53 -08:00
jp nz, .menu_loop
2015-12-04 05:46:11 -08:00
ld a, [wNumMoves]
inc a
2015-12-15 15:59:49 -08:00
ld [wMenuCursorY], a
2015-11-23 13:04:53 -08:00
jp .menu_loop
2018-06-24 07:09:41 -07:00
.pressed_down
2015-12-15 15:59:49 -08:00
ld a, [wMenuCursorY]
ld b, a
2015-12-04 05:46:11 -08:00
ld a, [wNumMoves]
inc a
2015-12-26 18:59:03 -08:00
inc a
cp b
2015-11-23 13:04:53 -08:00
jp nz, .menu_loop
ld a, $1
2015-12-15 15:59:49 -08:00
ld [wMenuCursorY], a
2015-11-23 13:04:53 -08:00
jp .menu_loop
2018-06-24 07:09:41 -07:00
.pressed_select
ld a, [wSwappingMove]
and a
2015-11-23 13:04:53 -08:00
jr z, .start_swap
2018-01-23 14:39:09 -08:00
ld hl, wBattleMonMoves
2015-11-23 13:04:53 -08:00
call .swap_bytes
2018-01-23 14:39:09 -08:00
ld hl, wBattleMonPP
2015-11-23 13:04:53 -08:00
call .swap_bytes
2018-01-23 14:39:09 -08:00
ld hl, wPlayerDisableCount
ld a, [hl]
swap a
and $f
ld b, a
2015-12-15 15:59:49 -08:00
ld a, [wMenuCursorY]
cp b
2015-11-23 13:04:53 -08:00
jr nz, .not_swapping_disabled_move
ld a, [hl]
and $f
ld b, a
ld a, [wSwappingMove]
swap a
add b
ld [hl], a
2015-11-23 13:04:53 -08:00
jr .swap_moves_in_party_struct
2015-11-23 13:04:53 -08:00
.not_swapping_disabled_move
ld a, [wSwappingMove]
cp b
2015-11-23 13:04:53 -08:00
jr nz, .swap_moves_in_party_struct
ld a, [hl]
and $f
ld b, a
2015-12-15 15:59:49 -08:00
ld a, [wMenuCursorY]
swap a
add b
ld [hl], a
2015-11-23 13:04:53 -08:00
.swap_moves_in_party_struct
; Fixes the COOLTRAINER glitch
2018-01-23 14:39:09 -08:00
ld a, [wPlayerSubStatus5]
bit SUBSTATUS_TRANSFORMED, a
2015-11-23 13:04:53 -08:00
jr nz, .transformed
2018-01-23 14:39:09 -08:00
ld hl, wPartyMon1Moves
ld a, [wCurBattleMon]
call GetPartyLocation
push hl
2015-11-23 13:04:53 -08:00
call .swap_bytes
pop hl
ld bc, MON_PP - MON_MOVES
add hl, bc
2015-11-23 13:04:53 -08:00
call .swap_bytes
2015-11-23 13:04:53 -08:00
.transformed
xor a
ld [wSwappingMove], a
2015-10-10 04:45:39 -07:00
jp MoveSelectionScreen
2015-11-23 13:04:53 -08:00
.swap_bytes
push hl
ld a, [wSwappingMove]
dec a
ld c, a
ld b, 0
add hl, bc
ld d, h
ld e, l
pop hl
2015-12-15 15:59:49 -08:00
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
2015-11-23 13:04:53 -08:00
.start_swap
2015-12-15 15:59:49 -08:00
ld a, [wMenuCursorY]
ld [wSwappingMove], a
2015-10-10 04:45:39 -07:00
jp MoveSelectionScreen
2018-06-24 07:09:41 -07:00
MoveInfoBox:
xor a
ldh [hBGMapMode], a
hlcoord 0, 8
ld b, 3
ld c, 9
call Textbox1bpp
2018-01-23 14:39:09 -08:00
ld a, [wPlayerDisableCount]
and a
2015-11-23 13:04:53 -08:00
jr z, .not_disabled
swap a
and $f
ld b, a
2015-12-15 15:59:49 -08:00
ld a, [wMenuCursorY]
cp b
2015-11-23 13:04:53 -08:00
jr nz, .not_disabled
hlcoord 1, 10
ld de, .Disabled
call PlaceString
jr .done
2015-11-23 13:04:53 -08:00
.not_disabled
2015-12-15 15:59:49 -08:00
ld hl, wMenuCursorY
dec [hl]
call SetPlayerTurn
2018-01-23 14:39:09 -08:00
ld hl, wBattleMonMoves
2015-12-15 15:59:49 -08:00
ld a, [wMenuCursorY]
ld c, a
ld b, 0
add hl, bc
ld a, [hl]
2018-01-23 14:39:09 -08:00
ld [wCurPlayerMove], a
2018-01-23 14:39:09 -08:00
ld a, [wCurBattleMon]
ld [wCurPartyMon], a
ld a, WILDMON
2018-01-23 14:39:09 -08:00
ld [wMonType], a
2017-12-24 09:47:30 -08:00
callfar GetMaxPPOfMove
2015-12-15 15:59:49 -08:00
ld hl, wMenuCursorY
ld c, [hl]
inc [hl]
ld b, 0
2018-01-23 14:39:09 -08:00
ld hl, wBattleMonPP
add hl, bc
ld a, [hl]
2018-01-11 09:00:01 -08:00
and PP_MASK
2018-01-23 14:39:09 -08:00
ld [wStringBuffer1], a
2015-11-23 13:04:53 -08:00
call .PrintPP
hlcoord 1, 9
ld de, .Type
call PlaceString
hlcoord 7, 11
ld [hl], "/"
2017-12-24 09:47:30 -08:00
callfar UpdateMoveData
ld a, [wPlayerMoveStruct + MOVE_ANIM]
ld b, a
hlcoord 2, 10
predef PrintMoveType
.done
ret
.Disabled:
db "Disabled!@"
.Type:
db "TYPE/@"
2018-06-24 07:09:41 -07:00
.PrintPP:
hlcoord 5, 11
push hl
2018-01-23 14:39:09 -08:00
ld de, wStringBuffer1
lb bc, 1, 2
call PrintNum
pop hl
inc hl
2015-12-26 18:59:03 -08:00
inc hl
ld [hl], "/"
inc hl
ld de, wNamedObjectIndex
lb bc, 1, 2
call PrintNum
ret
2018-06-24 07:09:41 -07:00
CheckPlayerHasUsableMoves:
ld a, STRUGGLE
2018-01-23 14:39:09 -08:00
ld [wCurPlayerMove], a
ld a, [wPlayerDisableCount]
and a
2018-01-23 14:39:09 -08:00
ld hl, wBattleMonPP
2015-11-23 13:04:53 -08:00
jr nz, .disabled
ld a, [hli]
or [hl]
inc hl
or [hl]
inc hl
or [hl]
2018-01-11 09:00:01 -08:00
and PP_MASK
ret nz
2015-11-23 13:04:53 -08:00
jr .force_struggle
2015-11-23 13:04:53 -08:00
.disabled
swap a
and $f
ld b, a
2017-12-12 19:58:20 -08:00
ld d, NUM_MOVES + 1
xor a
2015-11-23 13:04:53 -08:00
.loop
dec d
2015-11-23 13:04:53 -08:00
jr z, .done
ld c, [hl]
inc hl
dec b
2015-11-23 13:04:53 -08:00
jr z, .loop
or c
2015-11-23 13:04:53 -08:00
jr .loop
2015-11-23 13:04:53 -08:00
.done
; BUG: A Disabled but PP Upenhanced move may not trigger Struggle (see docs/bugs_and_glitches.md)
and a
ret nz
2015-11-23 13:04:53 -08:00
.force_struggle
ld hl, BattleText_MonHasNoMovesLeft
2019-04-08 05:15:10 -07:00
call StdBattleTextbox
ld c, 60
call DelayFrames
xor a
ret
2018-06-24 07:09:41 -07:00
ParseEnemyAction:
ld a, [wEnemyIsSwitching]
and a
ret nz
ld a, [wLinkMode]
and a
2015-11-07 18:04:54 -08:00
jr z, .not_linked
2019-04-08 05:15:10 -07:00
call EmptyBattleTextbox
call LoadTilemapToTempTilemap
ld a, [wBattlePlayerAction]
and a ; BATTLEPLAYERACTION_USEMOVE?
2015-11-23 13:04:53 -08:00
call z, LinkBattleSendReceiveAction
call SafeLoadTempTilemapToTilemap
ld a, [wBattleAction]
cp BATTLEACTION_STRUGGLE
2015-11-07 18:04:54 -08:00
jp z, .struggle
cp BATTLEACTION_SKIPTURN
jp z, .skip_turn
2015-11-06 06:04:27 -08:00
cp BATTLEACTION_SWITCH1
2015-09-09 16:27:07 -07:00
jp nc, ResetVarsForSubstatusRage
2018-01-23 14:39:09 -08:00
ld [wCurEnemyMoveNum], a
ld c, a
2018-01-23 14:39:09 -08:00
ld a, [wEnemySubStatus1]
bit SUBSTATUS_ROLLOUT, a
2015-11-07 18:04:54 -08:00
jp nz, .skip_load
2018-01-23 14:39:09 -08:00
ld a, [wEnemySubStatus3]
and 1 << SUBSTATUS_CHARGED | 1 << SUBSTATUS_RAMPAGE | 1 << SUBSTATUS_BIDE
2015-11-07 18:04:54 -08:00
jp nz, .skip_load
2018-01-23 14:39:09 -08:00
ld hl, wEnemySubStatus5
bit SUBSTATUS_ENCORED, [hl]
2018-01-23 14:39:09 -08:00
ld a, [wLastEnemyMove]
2015-11-07 18:04:54 -08:00
jp nz, .finish
2018-01-23 14:39:09 -08:00
ld hl, wEnemyMonMoves
ld b, 0
add hl, bc
ld a, [hl]
2015-11-07 18:04:54 -08:00
jp .finish
2015-11-07 18:04:54 -08:00
.not_linked
2018-01-23 14:39:09 -08:00
ld hl, wEnemySubStatus5
bit SUBSTATUS_ENCORED, [hl]
2015-11-07 18:04:54 -08:00
jr z, .skip_encore
2018-01-23 14:39:09 -08:00
ld a, [wLastEnemyMove]
2015-11-07 18:04:54 -08:00
jp .finish
2015-11-07 18:04:54 -08:00
.skip_encore
2016-03-01 19:31:21 -08:00
call CheckEnemyLockedIn
2015-09-09 16:27:07 -07:00
jp nz, ResetVarsForSubstatusRage
2015-11-07 18:04:54 -08:00
jr .continue
.skip_turn
ld a, $ff
2015-11-07 18:04:54 -08:00
jr .finish
2015-11-07 18:04:54 -08:00
.continue
2018-01-23 14:39:09 -08:00
ld hl, wEnemyMonMoves
ld de, wEnemyMonPP
ld b, NUM_MOVES
2015-11-07 18:04:54 -08:00
.loop
ld a, [hl]
and a
2015-11-07 18:04:54 -08:00
jp z, .struggle
2018-01-23 14:39:09 -08:00
ld a, [wEnemyDisabledMove]
cp [hl]
2015-11-07 18:04:54 -08:00
jr z, .disabled
ld a, [de]
2018-01-11 09:00:01 -08:00
and PP_MASK
2015-11-07 18:04:54 -08:00
jr nz, .enough_pp
2015-11-07 18:04:54 -08:00
.disabled
inc hl
inc de
dec b
2015-11-07 18:04:54 -08:00
jr nz, .loop
jr .struggle
2015-11-07 18:04:54 -08:00
.enough_pp
ld a, [wBattleMode]
dec a
2015-11-07 18:04:54 -08:00
jr nz, .skip_load
; wild
.loop2
2018-01-23 14:39:09 -08:00
ld hl, wEnemyMonMoves
call BattleRandom
2018-01-16 14:27:50 -08:00
maskbits NUM_MOVES
ld c, a
ld b, 0
add hl, bc
2018-01-23 14:39:09 -08:00
ld a, [wEnemyDisableCount]
swap a
and $f
dec a
cp c
2015-11-07 18:04:54 -08:00
jr z, .loop2
ld a, [hl]
and a
2015-11-07 18:04:54 -08:00
jr z, .loop2
2018-01-23 14:39:09 -08:00
ld hl, wEnemyMonPP
add hl, bc
ld b, a
ld a, [hl]
2018-01-11 09:00:01 -08:00
and PP_MASK
2015-11-07 18:04:54 -08:00
jr z, .loop2
ld a, c
2018-01-23 14:39:09 -08:00
ld [wCurEnemyMoveNum], a
ld a, b
2015-11-07 18:04:54 -08:00
.finish
2018-01-23 14:39:09 -08:00
ld [wCurEnemyMove], a
2015-11-07 18:04:54 -08:00
.skip_load
call SetEnemyTurn
2017-12-24 09:47:30 -08:00
callfar UpdateMoveData
2016-03-01 19:31:21 -08:00
call CheckEnemyLockedIn
2015-11-06 17:55:16 -08:00
jr nz, .raging
xor a
2015-11-07 18:04:54 -08:00
ld [wEnemyCharging], a
2015-11-06 17:55:16 -08:00
.raging
ld a, [wEnemyMoveStruct + MOVE_EFFECT]
cp EFFECT_FURY_CUTTER
2015-11-06 17:55:16 -08:00
jr z, .fury_cutter
xor a
2018-01-23 14:39:09 -08:00
ld [wEnemyFuryCutterCount], a
2015-11-06 17:55:16 -08:00
.fury_cutter
ld a, [wEnemyMoveStruct + MOVE_EFFECT]
cp EFFECT_RAGE
2015-11-07 18:04:54 -08:00
jr z, .no_rage
2018-01-23 14:39:09 -08:00
ld hl, wEnemySubStatus4
res SUBSTATUS_RAGE, [hl]
xor a
2015-11-05 16:13:09 -08:00
ld [wEnemyRageCounter], a
2015-11-07 18:04:54 -08:00
.no_rage
ld a, [wEnemyMoveStruct + MOVE_EFFECT]
cp EFFECT_PROTECT
ret z
cp EFFECT_ENDURE
ret z
xor a
2018-01-23 14:39:09 -08:00
ld [wEnemyProtectCount], a
ret
2015-11-07 18:04:54 -08:00
.struggle
ld a, STRUGGLE
2015-11-07 18:04:54 -08:00
jr .finish
2018-06-24 07:09:41 -07:00
ResetVarsForSubstatusRage:
xor a
2018-01-23 14:39:09 -08:00
ld [wEnemyFuryCutterCount], a
ld [wEnemyProtectCount], a
2015-11-05 16:13:09 -08:00
ld [wEnemyRageCounter], a
2018-01-23 14:39:09 -08:00
ld hl, wEnemySubStatus4
res SUBSTATUS_RAGE, [hl]
ret
2018-06-24 07:09:41 -07:00
CheckEnemyLockedIn:
2018-01-23 14:39:09 -08:00
ld a, [wEnemySubStatus4]
and 1 << SUBSTATUS_RECHARGE
ret nz
2015-09-09 16:27:07 -07:00
2018-01-23 14:39:09 -08:00
ld hl, wEnemySubStatus3
ld a, [hl]
and 1 << SUBSTATUS_CHARGED | 1 << SUBSTATUS_RAMPAGE | 1 << SUBSTATUS_BIDE
ret nz
2015-09-09 16:27:07 -07:00
2018-01-23 14:39:09 -08:00
ld hl, wEnemySubStatus1
bit SUBSTATUS_ROLLOUT, [hl]
ret
2018-06-24 07:09:41 -07:00
LinkBattleSendReceiveAction:
call .StageForSend
ld [wLinkBattleSentAction], a
farcall PlaceWaitingText
call .LinkBattle_SendReceiveAction
ret
.StageForSend:
ld a, [wBattlePlayerAction]
and a ; BATTLEPLAYERACTION_USEMOVE?
jr nz, .switch
ld a, [wCurPlayerMove]
ld b, BATTLEACTION_STRUGGLE
cp STRUGGLE
jr z, .struggle
ld b, BATTLEACTION_SKIPTURN
cp $ff
jr z, .struggle
ld a, [wCurMoveNum]
jr .use_move
.switch
ld a, [wCurPartyMon]
add BATTLEACTION_SWITCH1
jr .use_move
.struggle
ld a, b
.use_move
and $0f
ret
.LinkBattle_SendReceiveAction:
ld a, [wLinkBattleSentAction]
ld [wPlayerLinkAction], a
ld a, $ff
ld [wOtherPlayerLinkAction], a
.waiting
call LinkTransfer
call DelayFrame
ld a, [wOtherPlayerLinkAction]
inc a
jr z, .waiting
vc_hook Wireless_end_exchange
vc_patch Wireless_net_delay_3
if DEF(_CRYSTAL11_VC)
ld b, 26
else
ld b, 10
endc
vc_patch_end
.receive
call DelayFrame
call LinkTransfer
dec b
jr nz, .receive
if DEF(_CRYSTAL11_VC)
ld b, 26
else
ld b, 10
endc
vc_patch_end
.acknowledge
call DelayFrame
call LinkDataReceived
dec b
jr nz, .acknowledge
vc_hook Wireless_end_send_zero_bytes
ld a, [wOtherPlayerLinkAction]
ld [wBattleAction], a
ret
2018-06-24 07:09:41 -07:00
LoadEnemyMon:
; Initialize enemy monster parameters
2018-01-23 14:39:09 -08:00
; 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
2018-01-23 14:39:09 -08:00
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
2016-01-12 21:39:41 -08:00
jp nz, InitEnemyMon
; Make sure everything knows what species we're working with
2018-01-23 14:39:09 -08:00
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
2018-01-23 14:39:09 -08:00
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
2018-01-23 14:39:09 -08:00
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
2018-02-04 18:21:34 -08:00
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:
2018-01-23 14:39:09 -08:00
ld [wEnemyMonItem], a
; Initialize DVs
; If we're in a trainer battle, DVs are predetermined
ld a, [wBattleMode]
and a
jr z, .InitDVs
2018-01-23 14:39:09 -08:00
ld a, [wEnemySubStatus5]
bit SUBSTATUS_TRANSFORMED, a
jr z, .InitDVs
; Unknown
2016-01-10 14:44:09 -08:00
ld hl, wEnemyBackupDVs
2018-01-23 14:39:09 -08:00
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
2017-12-24 09:47:30 -08:00
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) work differently
; They have their own structs, which are shorter than normal
2018-01-23 14:39:09 -08:00
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:
2018-01-23 14:39:09 -08:00
; Register a contains wBattleType
; Forced shiny battle type
; Used by Red Gyarados at Lake of Rage
2023-07-26 17:50:16 -07:00
cp BATTLETYPE_FORCESHINY
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
2018-01-23 14:39:09 -08:00
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
2018-01-23 14:39:09 -08:00
ld a, [wTempEnemyMonSpecies]
cp UNOWN
jr nz, .Magikarp
; Get letter based on DVs
2018-01-23 14:39:09 -08:00
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.
2017-12-28 07:42:57 -08:00
; They expect at wMagikarpLength a 2-byte value in mm,
; but the value is in feet and inches (one byte each).
2017-12-28 07:42:57 -08:00
; The first filter is supposed to make very large Magikarp even rarer,
2018-01-02 08:50:08 -08:00
; by targeting those 1600 mm (= 5'3") or larger.
; After the conversion to feet, it is unable to target any,
2018-01-02 08:50:08 -08:00
; since the largest possible Magikarp is 5'3", and $0503 = 1283 mm.
2018-01-23 14:39:09 -08:00
ld a, [wTempEnemyMonSpecies]
cp MAGIKARP
jr nz, .Happiness
; Get Magikarp's length
; BUG: Magikarp length limits have a unit conversion error (see docs/bugs_and_glitches.md)
2018-01-23 14:39:09 -08:00
ld de, wEnemyMonDVs
ld bc, wPlayerID
2017-12-24 09:47:30 -08:00
callfar CalcMagikarpLength
2018-01-02 08:53:06 -08:00
; No reason to keep going if length > 1536 mm (i.e. if HIGH(length) > 6 feet)
2017-12-09 16:41:03 -08:00
ld a, [wMagikarpLength]
cp HIGH(1536)
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)
2017-12-09 16:41:03 -08:00
ld a, [wMagikarpLength + 1]
cp LOW(1616)
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)
2017-12-09 16:41:03 -08:00
ld a, [wMagikarpLength + 1]
cp LOW(1600)
jr nc, .GenerateDVs
.CheckMagikarpArea:
; 40% chance of not flooring
call Random
2020-05-07 08:09:41 -07:00
cp 39 percent + 1
jr c, .Happiness
2018-01-02 08:53:06 -08:00
; Try again if length < 1024 mm (i.e. if HIGH(length) < 3 feet)
2017-12-09 16:41:03 -08:00
ld a, [wMagikarpLength]
cp HIGH(1024)
jr c, .GenerateDVs ; try again
; Finally done with DVs
.Happiness:
; Set happiness
ld a, BASE_HAPPINESS
2018-01-23 14:39:09 -08:00
ld [wEnemyMonHappiness], a
; Set level
2018-01-23 14:39:09 -08:00
ld a, [wCurPartyLevel]
ld [wEnemyMonLevel], a
; Fill stats
2018-01-23 14:39:09 -08:00
ld de, wEnemyMonMaxHP
2015-12-21 11:10:16 -08:00
ld b, FALSE
2020-04-23 13:10:46 -07:00
ld hl, wEnemyMonDVs - (MON_DVS - MON_STAT_EXP + 1)
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
2018-01-23 14:39:09 -08:00
ld a, [wEnemySubStatus5]
bit SUBSTATUS_TRANSFORMED, a
jp nz, .Moves
.TreeMon:
; If we're headbutting trees, some monsters enter battle asleep
call CheckSleepingTreeMon
ld a, TREEMON_SLEEP_TURNS
jr c, .UpdateStatus
; Otherwise, no status
xor a
.UpdateStatus:
2018-01-23 14:39:09 -08:00
ld hl, wEnemyMonStatus
ld [hli], a
; Unused byte
xor a
ld [hli], a
2015-11-23 13:04:53 -08:00
; Full HP..
2018-01-23 14:39:09 -08:00
ld a, [wEnemyMonMaxHP]
ld [hli], a
2018-01-23 14:39:09 -08:00
ld a, [wEnemyMonMaxHP + 1]
ld [hl], a
2015-11-23 13:04:53 -08:00
; ..unless it's a RoamMon
2018-01-23 14:39:09 -08:00
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]
2018-01-23 14:39:09 -08:00
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
2018-01-23 14:39:09 -08:00
ld a, [wEnemyMonHP + 1]
ld [hl], a
jr .Moves
.OpponentParty:
; Get HP from the party struct
2018-01-23 14:39:09 -08:00
ld hl, (wOTPartyMon1HP + 1)
ld a, [wCurPartyMon]
call GetPartyLocation
ld a, [hld]
2018-01-23 14:39:09 -08:00
ld [wEnemyMonHP + 1], a
ld a, [hld]
2018-01-23 14:39:09 -08:00
ld [wEnemyMonHP], a
; Make sure everything knows which monster the opponent is using
2018-01-23 14:39:09 -08:00
ld a, [wCurPartyMon]
ld [wCurOTMon], a
; Get status from the party struct
dec hl
ld a, [hl] ; OTPartyMonStatus
2018-01-23 14:39:09 -08:00
ld [wEnemyMonStatus], a
.Moves:
2018-01-23 14:39:09 -08:00
ld hl, wBaseType1
ld de, wEnemyMonType1
ld a, [hli]
ld [de], a
inc de
ld a, [hl]
ld [de], a
; Get moves
2018-01-23 14:39:09 -08:00
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
2018-01-23 14:39:09 -08:00
ld hl, wOTPartyMon1Moves
ld a, [wCurPartyMon]
call GetPartyLocation
ld bc, NUM_MOVES
call CopyBytes
jr .PP
.WildMoves:
2018-01-23 14:39:09 -08:00
; Clear wEnemyMonMoves
xor a
ld h, d
ld l, e
ld [hli], a
ld [hli], a
ld [hli], a
ld [hl], a
2020-11-03 16:53:07 -08:00
ld [wSkipMovesBeforeLevelUp], a
; Fill moves based on level
predef FillMoves
.PP:
; Trainer battle?
ld a, [wBattleMode]
cp TRAINER_BATTLE
jr z, .TrainerPP
; Fill wild PP
2018-01-23 14:39:09 -08:00
ld hl, wEnemyMonMoves
ld de, wEnemyMonPP
predef FillPP
jr .Finish
.TrainerPP:
; Copy PP from the party struct
2018-01-23 14:39:09 -08:00
ld hl, wOTPartyMon1PP
ld a, [wCurPartyMon]
call GetPartyLocation
2018-01-23 14:39:09 -08:00
ld de, wEnemyMonPP
ld bc, NUM_MOVES
call CopyBytes
.Finish:
; Copy the first five base stats (the enemy mon's base Sp. Atk
; is also used to calculate Sp. Def stat experience)
2018-01-23 14:39:09 -08:00
ld hl, wBaseStats
ld de, wEnemyMonBaseStats
ld b, NUM_STATS - 1
.loop
ld a, [hli]
ld [de], a
inc de
dec b
jr nz, .loop
2018-01-23 14:39:09 -08:00
ld a, [wBaseCatchRate]
ld [de], a
inc de
2018-01-23 14:39:09 -08:00
ld a, [wBaseExp]
ld [de], a
2018-01-23 14:39:09 -08:00
ld a, [wTempEnemyMonSpecies]
ld [wNamedObjectIndex], a
call GetPokemonName
; Did we catch it?
ld a, [wBattleMode]
and a
ret z
; Update enemy nickname
2018-01-23 14:39:09 -08:00
ld hl, wStringBuffer1
ld de, wEnemyMonNickname
2018-01-20 09:25:55 -08:00
ld bc, MON_NAME_LENGTH
call CopyBytes
2015-11-29 18:34:59 -08:00
; Saw this mon
2018-01-23 14:39:09 -08:00
ld a, [wTempEnemyMonSpecies]
dec a
ld c, a
2015-11-22 21:21:21 -08:00
ld b, SET_FLAG
2018-01-23 14:39:09 -08:00
ld hl, wPokedexSeen
predef SmallFarFlagAction
2018-01-23 14:39:09 -08:00
ld hl, wEnemyMonStats
ld de, wEnemyStats
ld bc, NUM_BATTLE_STATS * 2
call CopyBytes
; BUG: PRZ and BRN stat reductions don't apply to switched Pokémon (see docs/bugs_and_glitches.md)
ret
2018-06-24 07:09:41 -07:00
CheckSleepingTreeMon:
; Return carry if species is in the list
; for the current time of day
; Don't do anything if this isn't a tree encounter
2018-01-23 14:39:09 -08:00
ld a, [wBattleType]
cp BATTLETYPE_TREE
jr nz, .NotSleeping
; Get list for the time of day
ld hl, AsleepTreeMonsMorn
2018-01-23 14:39:09 -08:00
ld a, [wTimeOfDay]
cp DAY_F
jr c, .Check
ld hl, AsleepTreeMonsDay
jr z, .Check
ld hl, AsleepTreeMonsNite
.Check:
2018-01-23 14:39:09 -08:00
ld a, [wTempEnemyMonSpecies]
ld de, 1 ; length of species id
call IsInArray
; If it's a match, the opponent is asleep
ret c
.NotSleeping:
and a
ret
INCLUDE "data/wild/treemons_asleep.asm"
2018-06-24 07:09:41 -07:00
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
2018-01-23 14:39:09 -08:00
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
2015-12-26 18:59:03 -08:00
inc e
ld a, e
cp NUM_UNLOCKED_UNOWN_SETS * 2
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"
SwapBattlerLevels: ; unreferenced
push bc
2018-01-23 14:39:09 -08:00
ld a, [wBattleMonLevel]
ld b, a
2018-01-23 14:39:09 -08:00
ld a, [wEnemyMonLevel]
ld [wBattleMonLevel], a
ld a, b
2018-01-23 14:39:09 -08:00
ld [wEnemyMonLevel], a
pop bc
ret
2018-06-24 07:09:41 -07:00
BattleWinSlideInEnemyTrainerFrontpic:
xor a
2018-01-23 14:39:09 -08:00
ld [wTempEnemyMonSpecies], a
2015-11-09 13:41:09 -08:00
call FinishBattleAnim
2018-01-23 14:39:09 -08:00
ld a, [wOtherTrainerClass]
ld [wTrainerClass], a
2017-12-28 04:32:33 -08:00
ld de, vTiles2
callfar GetTrainerPic
hlcoord 19, 0
ld c, 0
2015-10-19 13:49:29 -07:00
.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
2015-10-19 13:49:29 -07:00
.inner_loop
call .CopyColumn
inc hl
ld a, 7
add d
ld d, a
dec c
2015-10-19 13:49:29 -07:00
jr nz, .inner_loop
ld a, $1
ldh [hBGMapMode], a
ld c, 4
call DelayFrames
pop hl
pop bc
dec hl
2015-10-19 13:49:29 -07:00
jr .outer_loop
2018-06-24 07:09:41 -07:00
.CopyColumn:
push hl
push de
push bc
ld e, 7
2015-10-19 13:49:29 -07:00
.loop
ld [hl], d
2015-10-19 13:49:29 -07:00
ld bc, SCREEN_WIDTH
add hl, bc
inc d
dec e
2015-10-19 13:49:29 -07:00
jr nz, .loop
pop bc
pop de
pop hl
ret
2018-06-24 07:09:41 -07:00
ApplyStatusEffectOnPlayerStats:
ld a, 1
2015-11-07 18:04:54 -08:00
jr ApplyStatusEffectOnStats
2018-06-24 07:09:41 -07:00
ApplyStatusEffectOnEnemyStats:
xor a
2018-06-24 07:09:41 -07:00
ApplyStatusEffectOnStats:
ldh [hBattleTurn], a
2015-11-06 17:55:16 -08:00
call ApplyPrzEffectOnSpeed
jp ApplyBrnEffectOnAttack
2018-06-24 07:09:41 -07:00
ApplyPrzEffectOnSpeed:
ldh a, [hBattleTurn]
and a
2015-11-07 18:04:54 -08:00
jr z, .enemy
2018-01-23 14:39:09 -08:00
ld a, [wBattleMonStatus]
and 1 << PAR
ret z
2018-01-23 14:39:09 -08:00
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
2015-11-07 18:04:54 -08:00
jr nz, .player_ok
ld b, $1 ; min speed
2015-11-07 18:04:54 -08:00
.player_ok
ld [hl], b
ret
2015-11-07 18:04:54 -08:00
.enemy
2018-01-23 14:39:09 -08:00
ld a, [wEnemyMonStatus]
and 1 << PAR
ret z
2018-01-23 14:39:09 -08:00
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
2015-11-07 18:04:54 -08:00
jr nz, .enemy_ok
ld b, $1 ; min speed
2015-11-07 18:04:54 -08:00
.enemy_ok
ld [hl], b
ret
2018-06-24 07:09:41 -07:00
ApplyBrnEffectOnAttack:
ldh a, [hBattleTurn]
and a
2015-11-07 18:04:54 -08:00
jr z, .enemy
2018-01-23 14:39:09 -08:00
ld a, [wBattleMonStatus]
and 1 << BRN
ret z
2018-01-23 14:39:09 -08:00
ld hl, wBattleMonAttack + 1
ld a, [hld]
ld b, a
ld a, [hl]
srl a
rr b
ld [hli], a
or b
2015-11-07 18:04:54 -08:00
jr nz, .player_ok
ld b, $1 ; min attack
2015-11-07 18:04:54 -08:00
.player_ok
ld [hl], b
ret
2015-11-07 18:04:54 -08:00
.enemy
2018-01-23 14:39:09 -08:00
ld a, [wEnemyMonStatus]
and 1 << BRN
ret z
2018-01-23 14:39:09 -08:00
ld hl, wEnemyMonAttack + 1
ld a, [hld]
ld b, a
ld a, [hl]
srl a
rr b
ld [hli], a
or b
2015-11-07 18:04:54 -08:00
jr nz, .enemy_ok
ld b, $1 ; min attack
2015-11-07 18:04:54 -08:00
.enemy_ok
ld [hl], b
ret
2018-06-24 07:09:41 -07:00
ApplyStatLevelMultiplierOnAllStats:
2015-09-09 16:27:07 -07:00
; Apply StatLevelMultipliers on all 5 Stats
ld c, 0
2015-11-07 18:04:54 -08:00
.stat_loop
2015-09-09 16:27:07 -07:00
call ApplyStatLevelMultiplier
inc c
ld a, c
cp NUM_BATTLE_STATS
2015-11-07 18:04:54 -08:00
jr nz, .stat_loop
ret
2018-06-24 07:09:41 -07:00
ApplyStatLevelMultiplier:
push bc
push bc
ld a, [wApplyStatLevelMultipliersToEnemy]
and a
ld a, c
2018-01-23 14:39:09 -08:00
ld hl, wBattleMonAttack
ld de, wPlayerStats
ld bc, wPlayerAtkLevel
2015-11-07 18:04:54 -08:00
jr z, .got_pointers
2018-01-23 14:39:09 -08:00
ld hl, wEnemyMonAttack
ld de, wEnemyStats
ld bc, wEnemyAtkLevel
2015-11-07 18:04:54 -08:00
.got_pointers
add c
ld c, a
2015-11-07 18:04:54 -08:00
jr nc, .okay
inc b
2015-11-07 18:04:54 -08:00
.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
2015-11-07 18:04:54 -08:00
jr nc, .okay2
inc d
2015-11-07 18:04:54 -08:00
.okay2
pop bc
push hl
2018-01-25 18:34:42 -08:00
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)
2015-11-07 18:04:54 -08:00
jp c, .okay3
ld a, HIGH(MAX_STAT_VALUE)
ldh [hQuotient + 2], a
ld a, LOW(MAX_STAT_VALUE)
ldh [hQuotient + 3], a
2015-11-07 18:04:54 -08:00
.okay3
ldh a, [hQuotient + 2]
ld [hli], a
ld b, a
ldh a, [hQuotient + 3]
ld [hl], a
or b
2015-11-07 18:04:54 -08:00
jr nz, .okay4
inc [hl]
2015-11-07 18:04:54 -08:00
.okay4
pop bc
ret
2018-01-25 18:34:42 -08:00
INCLUDE "data/battle/stat_multipliers_2.asm"
2018-06-24 07:09:41 -07:00
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
2015-11-07 18:04:54 -08:00
and (1 << PLAINBADGE)
add a
2015-12-26 18:59:03 -08:00
add a
ld b, a
ld a, d
2015-11-07 18:04:54 -08:00
and (1 << MINERALBADGE)
rrca
rrca
ld c, a
ld a, d
2015-11-07 18:04:54 -08:00
and ((1 << ZEPHYRBADGE) | (1 << HIVEBADGE) | (1 << FOGBADGE) | (1 << STORMBADGE) | (1 << GLACIERBADGE) | (1 << RISINGBADGE))
or b
or c
ld b, a
2018-01-23 14:39:09 -08:00
ld hl, wBattleMonAttack
ld c, 4
.CheckBadge:
; BUG: Glacier Badge may not boost Special Defense depending on the value of Special Attack (see docs/bugs_and_glitches.md)
ld a, b
srl b
call c, BoostStat
inc hl
2015-12-26 18:59:03 -08:00
inc hl
; Check every other badge.
srl b
dec c
jr nz, .CheckBadge
srl a
call c, BoostStat
ret
2018-06-24 07:09:41 -07:00
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
2018-06-24 07:09:41 -07:00
_LoadBattleFontsHPBar:
2017-12-24 09:47:30 -08:00
callfar LoadBattleFontsHPBar
ret
2018-06-24 07:09:41 -07:00
_LoadHPBar:
2017-12-24 09:47:30 -08:00
callfar LoadHPBar
ret
LoadHPExpBarGFX: ; unreferenced
2015-11-04 12:35:29 -08:00
ld de, EnemyHPBarBorderGFX
2017-12-28 04:32:33 -08:00
ld hl, vTiles2 tile $6c
2015-11-04 12:35:29 -08:00
lb bc, BANK(EnemyHPBarBorderGFX), 4
call Get1bpp
2015-11-04 12:35:29 -08:00
ld de, HPExpBarBorderGFX
2017-12-28 04:32:33 -08:00
ld hl, vTiles2 tile $73
2015-11-04 12:35:29 -08:00
lb bc, BANK(HPExpBarBorderGFX), 6
call Get1bpp
2015-11-04 11:02:11 -08:00
ld de, ExpBarGFX
2017-12-28 04:32:33 -08:00
ld hl, vTiles2 tile $55
2015-11-04 11:02:11 -08:00
lb bc, BANK(ExpBarGFX), 8
jp Get2bpp
2019-04-08 05:15:10 -07:00
EmptyBattleTextbox:
ld hl, .empty
2019-04-08 05:15:10 -07:00
jp BattleTextbox
.empty:
text_end
2018-06-24 07:09:41 -07:00
_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
2018-01-23 14:39:09 -08:00
ld a, [wLinkBattleRNCount]
ld c, a
ld b, 0
2018-01-23 14:39:09 -08:00
ld hl, wLinkBattleRNs
add hl, bc
inc a
2018-01-23 14:39:09 -08:00
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
2018-01-23 14:39:09 -08:00
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
2015-12-26 18:59:03 -08:00
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
2018-06-24 07:09:41 -07:00
Call_PlayBattleAnim_OnlyIfVisible:
ld a, BATTLE_VARS_SUBSTATUS3
call GetBattleVar
and 1 << SUBSTATUS_FLYING | 1 << SUBSTATUS_UNDERGROUND
ret nz
2018-06-24 07:09:41 -07:00
Call_PlayBattleAnim:
ld a, e
2018-01-23 14:39:09 -08:00
ld [wFXAnimID], a
ld a, d
2018-01-23 14:39:09 -08:00
ld [wFXAnimID + 1], a
call WaitBGMap
predef_jump PlayBattleAnim
2018-06-24 07:09:41 -07:00
FinishBattleAnim:
push af
push bc
push de
push hl
ld b, CGB_BATTLE_COLORS
call GetCGBLayout
2024-02-10 15:16:00 -08:00
call SetDefaultBGPAndOBP
call DelayFrame
pop hl
pop de
pop bc
pop af
ret
2018-06-24 07:09:41 -07:00
GiveExperiencePoints:
2014-06-03 14:07:10 -07:00
; Give experience.
; Don't give experience if linked.
ld a, [wLinkMode]
and a
ret nz
2015-08-24 16:56:30 -07:00
2016-01-12 09:46:18 -08:00
call .EvenlyDivideExpAmongParticipants
xor a
2018-01-23 14:39:09 -08:00
ld [wCurPartyMon], a
ld bc, wPartyMon1Species
2015-11-07 18:04:54 -08:00
.loop
ld hl, MON_HP
add hl, bc
ld a, [hli]
or [hl]
jp z, .next_mon ; fainted
2015-11-07 18:04:54 -08:00
push bc
2015-11-07 18:04:54 -08:00
ld hl, wBattleParticipantsNotFainted
2018-01-23 14:39:09 -08:00
ld a, [wCurPartyMon]
ld c, a
2015-11-07 18:04:54 -08:00
ld b, CHECK_FLAG
ld d, 0
predef SmallFarFlagAction
ld a, c
and a
pop bc
jp z, .next_mon
2016-01-12 09:46:18 -08:00
; give stat exp
2015-11-07 18:04:54 -08:00
ld hl, MON_STAT_EXP + 1
add hl, bc
ld d, h
ld e, l
2018-01-23 14:39:09 -08:00
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
2021-06-07 17:00:21 -07:00
ld a, MON_POKERUS
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
2015-12-26 18:59:03 -08:00
inc de
dec c
jr nz, .stat_exp_loop
xor a
ldh [hMultiplicand + 0], a
ldh [hMultiplicand + 1], a
2018-01-23 14:39:09 -08:00
ld a, [wEnemyMonBaseExp]
ldh [hMultiplicand + 2], a
2018-01-23 14:39:09 -08:00
ld a, [wEnemyMonLevel]
ldh [hMultiplier], a
call Multiply
2015-11-07 18:04:54 -08:00
ld a, 7
ldh [hDivisor], a
2015-11-07 18:04:54 -08:00
ld b, 4
call Divide
2016-01-12 09:46:18 -08:00
; Boost Experience for traded Pokemon
pop bc
2015-11-07 18:04:54 -08:00
ld hl, MON_ID
add hl, bc
2018-01-23 14:39:09 -08:00
ld a, [wPlayerID]
cp [hl]
2015-11-07 18:04:54 -08:00
jr nz, .boosted
inc hl
2018-01-23 14:39:09 -08:00
ld a, [wPlayerID + 1]
cp [hl]
ld a, 0
2015-11-07 18:04:54 -08:00
jr z, .no_boost
2015-11-07 18:04:54 -08:00
.boosted
2015-11-11 11:12:46 -08:00
call BoostExp
ld a, 1
2015-11-07 18:04:54 -08:00
.no_boost
2016-01-12 09:46:18 -08:00
; Boost experience for a Trainer Battle
2018-01-23 14:39:09 -08:00
ld [wStringBuffer2 + 2], a
ld a, [wBattleMode]
dec a
2015-11-11 11:12:46 -08:00
call nz, BoostExp
2016-01-12 09:46:18 -08:00
; Boost experience for Lucky Egg
push bc
ld a, MON_ITEM
call GetPartyParamLocation
ld a, [hl]
2014-06-03 14:07:10 -07:00
cp LUCKY_EGG
2015-11-11 11:12:46 -08:00
call z, BoostExp
ldh a, [hQuotient + 3]
2018-01-23 14:39:09 -08:00
ld [wStringBuffer2 + 1], a
ldh a, [hQuotient + 2]
2018-01-23 14:39:09 -08:00
ld [wStringBuffer2], a
ld a, [wCurPartyMon]
ld hl, wPartyMonNicknames
call GetNickname
ld hl, Text_MonGainedExpPoint
2019-04-08 05:15:10 -07:00
call BattleTextbox
2018-01-23 14:39:09 -08:00
ld a, [wStringBuffer2 + 1]
ldh [hQuotient + 3], a
2018-01-23 14:39:09 -08:00
ld a, [wStringBuffer2]
ldh [hQuotient + 2], a
pop bc
2016-01-12 09:46:18 -08:00
call AnimateExpBar
push bc
call LoadTilemapToTempTilemap
pop bc
2018-07-24 11:14:04 -07:00
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]
jr nz, .no_exp_overflow
ld a, $ff
ld [hli], a
2015-12-26 18:59:03 -08:00
ld [hli], a
ld [hl], a
.no_exp_overflow
2018-01-23 14:39:09 -08:00
ld a, [wCurPartyMon]
ld e, a
ld d, 0
2018-01-23 14:39:09 -08:00
ld hl, wPartySpecies
add hl, de
ld a, [hl]
2018-01-23 14:39:09 -08:00
ld [wCurSpecies], a
call GetBaseData
push bc
2014-06-03 14:07:10 -07:00
ld d, MAX_LEVEL
2017-12-24 09:47:30 -08:00
callfar CalcExpAtLevel
pop bc
2018-07-24 11:14:04 -07:00
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
2018-01-23 14:39:09 -08:00
ld [wMonType], a
predef CopyMonToTempMon
2017-12-24 09:47:30 -08:00
callfar CalcLevel
pop bc
ld hl, MON_LEVEL
add hl, bc
ld a, [hl]
2014-06-03 14:07:10 -07:00
cp MAX_LEVEL
jp nc, .next_mon
cp d
jp z, .next_mon
2015-11-07 18:04:54 -08:00
; <NICKNAME> grew to level ##!
ld [wTempLevel], a
2018-01-23 14:39:09 -08:00
ld a, [wCurPartyLevel]
push af
ld a, d
2018-01-23 14:39:09 -08:00
ld [wCurPartyLevel], a
ld [hl], a
ld hl, MON_SPECIES
add hl, bc
ld a, [hl]
2018-01-23 14:39:09 -08:00
ld [wCurSpecies], a
ld [wTempSpecies], a ; unused?
call GetBaseData
2015-11-07 18:04:54 -08:00
ld hl, MON_MAXHP + 1
add hl, bc
ld a, [hld]
ld e, a
ld d, [hl]
push de
2015-11-07 18:04:54 -08:00
ld hl, MON_MAXHP
add hl, bc
ld d, h
ld e, l
2015-12-21 11:10:16 -08:00
ld hl, MON_STAT_EXP - 1
add hl, bc
push bc
2015-12-21 11:10:16 -08:00
ld b, TRUE
predef CalcMonStats
pop bc
pop de
2015-11-07 18:04:54 -08:00
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
2018-01-23 14:39:09 -08:00
ld a, [wCurBattleMon]
ld d, a
2018-01-23 14:39:09 -08:00
ld a, [wCurPartyMon]
cp d
jr nz, .skip_active_mon_update
2018-01-23 14:39:09 -08:00
ld de, wBattleMonHP
ld a, [hli]
ld [de], a
inc de
ld a, [hli]
ld [de], a
2018-01-23 14:39:09 -08:00
ld de, wBattleMonMaxHP
push bc
2015-11-07 18:04:54 -08:00
ld bc, PARTYMON_STRUCT_LENGTH - MON_MAXHP
call CopyBytes
pop bc
2015-11-07 18:04:54 -08:00
ld hl, MON_LEVEL
add hl, bc
ld a, [hl]
2018-01-23 14:39:09 -08:00
ld [wBattleMonLevel], a
ld a, [wPlayerSubStatus5]
bit SUBSTATUS_TRANSFORMED, a
2015-11-07 18:04:54 -08:00
jr nz, .transformed
ld hl, MON_ATK
add hl, bc
2018-01-23 14:39:09 -08:00
ld de, wPlayerStats
2015-11-07 18:04:54 -08:00
ld bc, PARTYMON_STRUCT_LENGTH - MON_ATK
call CopyBytes
2015-11-07 18:04:54 -08:00
.transformed
xor a ; FALSE
ld [wApplyStatLevelMultipliersToEnemy], a
2015-09-09 16:27:07 -07:00
call ApplyStatLevelMultiplierOnAllStats
2017-12-24 09:47:30 -08:00
callfar ApplyStatusEffectOnPlayerStats
callfar BadgeStatBoosts
callfar UpdatePlayerHUD
2019-04-08 05:15:10 -07:00
call EmptyBattleTextbox
call LoadTilemapToTempTilemap
ld a, $1
ldh [hBGMapMode], a
.skip_active_mon_update
2017-12-24 09:47:30 -08:00
farcall LevelUpHappinessMod
2018-01-23 14:39:09 -08:00
ld a, [wCurBattleMon]
ld b, a
2018-01-23 14:39:09 -08:00
ld a, [wCurPartyMon]
cp b
jr z, .skip_exp_bar_animation
ld de, SFX_HIT_END_OF_EXP_BAR
call PlaySFX
call WaitSFX
2015-09-09 16:27:07 -07:00
ld hl, BattleText_StringBuffer1GrewToLevel
2019-04-08 05:15:10 -07:00
call StdBattleTextbox
call LoadTilemapToTempTilemap
.skip_exp_bar_animation
xor a ; PARTYMON
2018-01-23 14:39:09 -08:00
ld [wMonType], a
predef CopyMonToTempMon
hlcoord 9, 0
ld b, 10
ld c, 9
call Textbox1bpp
hlcoord 11, 1
ld bc, 4
predef PrintTempMonStats
ld c, 30
call DelayFrames
call WaitPressAorB_BlinkCursor
call SafeLoadTempTilemapToTilemap
xor a ; PARTYMON
2018-01-23 14:39:09 -08:00
ld [wMonType], a
ld a, [wCurSpecies]
ld [wTempSpecies], a ; unused?
2018-01-23 14:39:09 -08:00
ld a, [wCurPartyLevel]
push af
ld c, a
ld a, [wTempLevel]
ld b, a
2015-11-07 18:04:54 -08:00
.level_loop
inc b
ld a, b
2018-01-23 14:39:09 -08:00
ld [wCurPartyLevel], a
push bc
predef LearnLevelMoves
pop bc
ld a, b
cp c
2015-11-07 18:04:54 -08:00
jr nz, .level_loop
pop af
2018-01-23 14:39:09 -08:00
ld [wCurPartyLevel], a
ld hl, wEvolvableFlags
ld a, [wCurPartyMon]
ld c, a
2015-11-22 21:21:21 -08:00
ld b, SET_FLAG
predef SmallFarFlagAction
pop af
2018-01-23 14:39:09 -08:00
ld [wCurPartyLevel], a
.next_mon
2018-01-23 14:39:09 -08:00
ld a, [wPartyCount]
ld b, a
2018-01-23 14:39:09 -08:00
ld a, [wCurPartyMon]
inc a
cp b
2015-11-07 18:04:54 -08:00
jr z, .done
2018-01-23 14:39:09 -08:00
ld [wCurPartyMon], a
ld a, MON_SPECIES
call GetPartyParamLocation
ld b, h
ld c, l
2015-11-07 18:04:54 -08:00
jp .loop
2015-11-07 18:04:54 -08:00
.done
jp ResetBattleParticipants
.EvenlyDivideExpAmongParticipants:
; count number of battle participants
2015-11-07 18:04:54 -08:00
ld a, [wBattleParticipantsNotFainted]
ld b, a
ld c, PARTY_LENGTH
ld d, 0
2016-01-12 09:46:18 -08:00
.count_loop
xor a
srl b
adc d
ld d, a
dec c
2016-01-12 09:46:18 -08:00
jr nz, .count_loop
cp 2
ret c
ld [wTempByteValue], a
2018-01-23 14:39:09 -08:00
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
2018-06-24 07:09:41 -07:00
BoostExp:
2015-11-11 11:12:46 -08:00
; Multiply experience by 1.5x
push bc
2015-11-11 11:12:46 -08:00
; load experience value
ldh a, [hProduct + 2]
ld b, a
ldh a, [hProduct + 3]
ld c, a
2015-11-11 11:12:46 -08:00
; halve it
srl b
rr c
2015-11-11 11:12:46 -08:00
; 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
2018-06-24 07:09:41 -07:00
Text_MonGainedExpPoint:
text_far Text_Gained
text_asm
ld hl, ExpPointsText
2018-01-23 14:39:09 -08:00
ld a, [wStringBuffer2 + 2] ; IsTradedMon
and a
ret z
2015-09-09 16:27:07 -07:00
ld hl, BoostedExpPointsText
ret
BoostedExpPointsText:
text_far _BoostedExpPointsText
text_end
ExpPointsText:
text_far _ExpPointsText
text_end
2018-06-24 07:09:41 -07:00
AnimateExpBar:
push bc
2018-01-23 14:39:09 -08:00
ld hl, wCurPartyMon
ld a, [wCurBattleMon]
cp [hl]
2015-11-10 16:51:13 -08:00
jp nz, .finish
2018-01-23 14:39:09 -08:00
ld a, [wBattleMonLevel]
cp MAX_LEVEL
2015-11-10 16:51:13 -08:00
jp nc, .finish
ldh a, [hProduct + 3]
ld [wExperienceGained + 2], a
push af
ldh a, [hProduct + 2]
ld [wExperienceGained + 1], a
push af
xor a
ld [wExperienceGained], a
xor a ; PARTYMON
2018-01-23 14:39:09 -08:00
ld [wMonType], a
predef CopyMonToTempMon
2018-01-23 14:39:09 -08:00
ld a, [wTempMonLevel]
ld b, a
ld e, a
push de
2018-01-23 14:39:09 -08:00
ld de, wTempMonExp + 2
call CalcExpBar
push bc
2018-01-23 14:39:09 -08:00
ld hl, wTempMonExp + 2
ld a, [wExperienceGained + 2]
add [hl]
ld [hld], a
ld a, [wExperienceGained + 1]
adc [hl]
ld [hld], a
2016-01-12 09:46:18 -08:00
jr nc, .NoOverflow
inc [hl]
2016-01-12 09:46:18 -08:00
jr nz, .NoOverflow
ld a, $ff
ld [hli], a
2015-12-26 18:59:03 -08:00
ld [hli], a
ld [hl], a
.NoOverflow:
2014-06-03 14:07:10 -07:00
ld d, MAX_LEVEL
2017-12-24 09:47:30 -08:00
callfar CalcExpAtLevel
ldh a, [hProduct + 1]
ld b, a
ldh a, [hProduct + 2]
ld c, a
ldh a, [hProduct + 3]
ld d, a
2018-01-23 14:39:09 -08:00
ld hl, wTempMonExp + 2
ld a, [hld]
sub d
ld a, [hld]
sbc c
ld a, [hl]
sbc b
2016-01-12 09:46:18 -08:00
jr c, .AlreadyAtMaxExp
ld a, b
ld [hli], a
ld a, c
ld [hli], a
ld a, d
ld [hld], a
.AlreadyAtMaxExp:
2017-12-24 09:47:30 -08:00
callfar CalcLevel
ld a, d
pop bc
pop de
ld d, a
cp e
2016-01-12 09:46:18 -08:00
jr nc, .LoopLevels
ld a, e
ld d, a
.LoopLevels:
ld a, e
2014-03-05 02:42:09 -08:00
cp MAX_LEVEL
2016-01-12 09:46:18 -08:00
jr nc, .FinishExpBar
cp d
2016-01-12 09:46:18 -08:00
jr z, .FinishExpBar
inc a
2018-01-23 14:39:09 -08:00
ld [wTempMonLevel], a
ld [wCurPartyLevel], a
ld [wBattleMonLevel], a
push de
2016-01-12 09:46:18 -08:00
call .PlayExpBarSound
ld c, $40
2016-01-12 09:46:18 -08:00
call .LoopBarAnimation
call PrintPlayerHUD
ld hl, wBattleMonNickname
2018-01-23 14:39:09 -08:00
ld de, wStringBuffer1
2018-01-20 09:25:55 -08:00
ld bc, MON_NAME_LENGTH
call CopyBytes
2016-01-12 09:46:18 -08:00
call TerminateExpBarSound
ld de, SFX_HIT_END_OF_EXP_BAR
call PlaySFX
2017-12-24 09:47:30 -08:00
farcall AnimateEndOfExpBar
call WaitSFX
2015-09-09 16:27:07 -07:00
ld hl, BattleText_StringBuffer1GrewToLevel
2019-04-08 05:15:10 -07:00
call StdBattleTextbox
pop de
inc e
ld b, $0
2016-01-12 09:46:18 -08:00
jr .LoopLevels
.FinishExpBar:
push bc
ld b, d
2018-01-23 14:39:09 -08:00
ld de, wTempMonExp + 2
call CalcExpBar
ld a, b
pop bc
ld c, a
2016-01-12 09:46:18 -08:00
call .PlayExpBarSound
call .LoopBarAnimation
call TerminateExpBarSound
pop af
ldh [hProduct + 2], a
pop af
ldh [hProduct + 3], a
2015-11-10 16:51:13 -08:00
.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:
2016-01-12 09:46:18 -08:00
ld d, 3
dec b
2016-01-12 09:46:18 -08:00
.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
2016-01-12 09:46:18 -08:00
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
2016-01-12 09:46:18 -08:00
jr nz, .min_number_of_frames
ld d, 1
.min_number_of_frames
pop bc
ld a, c
cp b
2016-01-12 09:46:18 -08:00
jr nz, .anim_loop
.end_animation
ld a, $1
ldh [hBGMapMode], a
ret
2018-06-24 07:09:41 -07:00
SendOutMonText:
ld a, [wLinkMode]
and a
jr z, .not_linked
2020-11-03 16:53:07 -08:00
; If we're in a LinkBattle print just "Go <PlayerMon>"
; unless DoBattle already set [wBattleHasJustStarted]
ld hl, GoMonText
ld a, [wBattleHasJustStarted]
and a
jr nz, .skip_to_textbox
.not_linked
; Depending on the HP of the enemy mon, the game prints a different text
2018-01-23 14:39:09 -08:00
ld hl, wEnemyMonHP
ld a, [hli]
or [hl]
ld hl, GoMonText
jr z, .skip_to_textbox
; BUG: Switching out or switching against a Pokémon with max HP below 4 freezes the game (see docs/bugs_and_glitches.md)
; compute enemy health remaining as a percentage
xor a
ldh [hMultiplicand + 0], a
2018-01-23 14:39:09 -08:00
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
2018-01-23 14:39:09 -08:00
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, GoMonText
cp 70
jr nc, .skip_to_textbox
ld hl, DoItMonText
cp 40
jr nc, .skip_to_textbox
ld hl, GoForItMonText
cp 10
jr nc, .skip_to_textbox
ld hl, YourFoesWeakGetmMonText
.skip_to_textbox
2019-04-08 05:15:10 -07:00
jp BattleTextbox
GoMonText:
text_far _GoMonText
text_asm
jr PrepareBattleMonNicknameText
DoItMonText:
text_far _DoItMonText
text_asm
jr PrepareBattleMonNicknameText
GoForItMonText:
text_far _GoForItMonText
text_asm
jr PrepareBattleMonNicknameText
YourFoesWeakGetmMonText:
text_far _YourFoesWeakGetmMonText
text_asm
PrepareBattleMonNicknameText:
ld hl, BattleMonNicknameText
ret
BattleMonNicknameText:
text_far _BattleMonNicknameText
text_end
2018-06-24 07:09:41 -07:00
WithdrawMonText:
ld hl, .WithdrawMonText
2019-04-08 05:15:10 -07:00
jp BattleTextbox
.WithdrawMonText:
text_far _BattleMonNickCommaText
text_asm
; Depending on the HP lost since the enemy mon was sent out, the game prints a different text
push de
push bc
; compute enemy health lost as a percentage
2018-01-23 14:39:09 -08:00
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
2018-01-23 14:39:09 -08:00
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
2015-09-09 16:27:07 -07:00
ld hl, ComeBackText
cp 30
ret c
2015-09-09 16:27:07 -07:00
ld hl, OKComeBackText
cp 70
ret c
2015-09-09 16:27:07 -07:00
ld hl, GoodComeBackText
ret
ThatsEnoughComeBackText:
text_far _ThatsEnoughComeBackText
text_end
OKComeBackText:
text_far _OKComeBackText
text_end
GoodComeBackText:
text_far _GoodComeBackText
text_end
TextJump_ComeBack: ; unreferenced
ld hl, ComeBackText
ret
ComeBackText:
text_far _ComeBackText
text_end
HandleSafariAngerEatingStatus: ; unreferenced
ld hl, wSafariMonEating
ld a, [hl]
and a
jr z, .angry
dec [hl]
ld hl, BattleText_WildMonIsEating
jr .finish
.angry
dec hl
assert wSafariMonEating - 1 == wSafariMonAngerCount
ld a, [hl]
and a
ret z
dec [hl]
ld hl, BattleText_WildMonIsAngry
jr nz, .finish
push hl
2018-01-23 14:39:09 -08:00
ld a, [wEnemyMonSpecies]
ld [wCurSpecies], a
call GetBaseData
2018-01-23 14:39:09 -08:00
ld a, [wBaseCatchRate]
ld [wEnemyMonCatchRate], a
pop hl
.finish
push hl
call SafeLoadTempTilemapToTilemap
pop hl
2019-04-08 05:15:10 -07:00
jp StdBattleTextbox
2018-06-24 07:09:41 -07:00
FillInExpBar:
push hl
call CalcExpBar
pop hl
ld de, 7
add hl, de
jp PlaceExpBar
2018-06-24 07:09:41 -07:00
CalcExpBar:
; Calculate the percent exp between this level and the next
; Level in b
push de
ld d, b
push de
2017-12-24 09:47:30 -08:00
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
2017-12-24 09:47:30 -08:00
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
2018-06-24 07:09:41 -07:00
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
2018-06-24 07:09:41 -07:00
GetBattleMonBackpic:
2018-01-23 14:39:09 -08:00
ld a, [wPlayerSubStatus4]
bit SUBSTATUS_SUBSTITUTE, a
ld hl, BattleAnimCmd_RaiseSub
jr nz, GetBattleMonBackpic_DoAnim ; substitute
2018-06-24 07:09:41 -07:00
DropPlayerSub:
ld a, [wPlayerMinimized]
and a
ld hl, BattleAnimCmd_MinimizeOpp
jr nz, GetBattleMonBackpic_DoAnim
2018-01-23 14:39:09 -08:00
ld a, [wCurPartySpecies]
push af
2018-01-23 14:39:09 -08:00
ld a, [wBattleMonSpecies]
ld [wCurPartySpecies], a
ld hl, wBattleMonDVs
predef GetUnownLetter
2017-12-28 04:32:33 -08:00
ld de, vTiles2 tile $31
predef GetMonBackpic
pop af
2018-01-23 14:39:09 -08:00
ld [wCurPartySpecies], a
ret
2018-06-24 07:09:41 -07:00
GetBattleMonBackpic_DoAnim:
ldh a, [hBattleTurn]
push af
xor a
ldh [hBattleTurn], a
ld a, BANK(BattleAnimCommands)
rst FarCall
pop af
ldh [hBattleTurn], a
ret
2018-06-24 07:09:41 -07:00
GetEnemyMonFrontpic:
2018-01-23 14:39:09 -08:00
ld a, [wEnemySubStatus4]
bit SUBSTATUS_SUBSTITUTE, a
ld hl, BattleAnimCmd_RaiseSub
jr nz, GetEnemyMonFrontpic_DoAnim
2018-06-24 07:09:41 -07:00
DropEnemySub:
ld a, [wEnemyMinimized]
and a
ld hl, BattleAnimCmd_MinimizeOpp
jr nz, GetEnemyMonFrontpic_DoAnim
2018-01-23 14:39:09 -08:00
ld a, [wCurPartySpecies]
push af
2018-01-23 14:39:09 -08:00
ld a, [wEnemyMonSpecies]
ld [wCurSpecies], a
ld [wCurPartySpecies], a
call GetBaseData
2018-01-23 14:39:09 -08:00
ld hl, wEnemyMonDVs
predef GetUnownLetter
2017-12-28 04:32:33 -08:00
ld de, vTiles2
predef GetAnimatedFrontpic
pop af
2018-01-23 14:39:09 -08:00
ld [wCurPartySpecies], a
ret
2018-06-24 07:09:41 -07:00
GetEnemyMonFrontpic_DoAnim:
ldh a, [hBattleTurn]
push af
call SetEnemyTurn
ld a, BANK(BattleAnimCommands)
rst FarCall
pop af
ldh [hBattleTurn], a
ret
2018-06-24 07:09:41 -07:00
StartBattle:
2015-10-24 07:34:19 -07:00
; 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.
2018-01-23 14:39:09 -08:00
ld a, [wPartyCount]
and a
ret z
2015-10-24 07:34:19 -07:00
2018-01-23 14:39:09 -08:00
ld a, [wTimeOfDayPal]
push af
call BattleIntro
call DoBattle
call ExitBattle
pop af
2018-01-23 14:39:09 -08:00
ld [wTimeOfDayPal], a
scf
ret
CallDoBattle: ; unreferenced
call DoBattle
ret
2018-06-24 07:09:41 -07:00
BattleIntro:
2015-10-24 07:34:19 -07:00
call LoadTrainerOrWildMonPic
xor a
2018-01-23 14:39:09 -08:00
ld [wTempBattleMonSpecies], a
ld [wBattleMenuCursorPosition], a
xor a
ldh [hMapAnims], a
2017-12-24 09:47:30 -08:00
farcall PlayBattleMusic
farcall ShowLinkBattleParticipants
farcall FindFirstAliveMonAndStartBattle
2015-10-24 07:34:19 -07:00
call DisableSpriteUpdates
2017-12-24 09:47:30 -08:00
farcall ClearBattleRAM
2015-11-06 13:42:38 -08:00
call InitEnemy
2017-12-28 04:32:33 -08:00
call BackUpBGMap2
ld b, CGB_BATTLE_GRAYSCALE
call GetCGBLayout
ld hl, rLCDC
2020-06-21 09:21:47 -07:00
res rLCDC_WINDOW_TILEMAP, [hl] ; select vBGMap0/vBGMap2
call InitBattleDisplay
call BattleStartMessage
ld hl, rLCDC
2020-06-21 09:21:47 -07:00
set rLCDC_WINDOW_TILEMAP, [hl] ; select vBGMap1/vBGMap3
xor a
ldh [hBGMapMode], a
2019-04-08 05:15:10 -07:00
call EmptyBattleTextbox
hlcoord 9, 7
2015-11-05 16:13:09 -08:00
lb bc, 5, 11
call ClearBox
hlcoord 1, 0
2015-11-05 16:13:09 -08:00
lb bc, 4, 10
call ClearBox
call ClearSprites
ld a, [wBattleMode]
2015-11-29 18:34:59 -08:00
cp WILD_BATTLE
call z, UpdateEnemyHUD
ld a, $1
ldh [hBGMapMode], a
ret
2018-06-24 07:09:41 -07:00
LoadTrainerOrWildMonPic:
2018-01-23 14:39:09 -08:00
ld a, [wOtherTrainerClass]
and a
2015-10-24 07:34:19 -07:00
jr nz, .Trainer
2018-01-23 14:39:09 -08:00
ld a, [wTempWildMonSpecies]
ld [wCurPartySpecies], a
.Trainer:
2018-01-23 14:39:09 -08:00
ld [wTempEnemyMonSpecies], a
ret
2018-06-24 07:09:41 -07:00
InitEnemy:
2018-01-23 14:39:09 -08:00
ld a, [wOtherTrainerClass]
and a
2015-11-06 13:42:38 -08:00
jp nz, InitEnemyTrainer ; trainer
jp InitEnemyWildmon ; wild
2018-06-24 07:09:41 -07:00
BackUpBGMap2:
ldh a, [rSVBK]
push af
ld a, BANK(wDecompressScratch)
ldh [rSVBK], a
ld hl, wDecompressScratch
2017-12-28 04:32:33 -08:00
ld bc, $40 tiles ; vBGMap3 - vBGMap2
ld a, $2
call ByteFill
ldh a, [rVBK]
push af
ld a, $1
ldh [rVBK], a
ld de, wDecompressScratch
2017-12-28 04:32:33 -08:00
hlbgcoord 0, 0 ; vBGMap2
lb bc, BANK(BackUpBGMap2), $40
call Request2bpp
pop af
ldh [rVBK], a
pop af
ldh [rSVBK], a
ret
2018-06-24 07:09:41 -07:00
InitEnemyTrainer:
2018-01-23 14:39:09 -08:00
ld [wTrainerClass], a
xor a
2018-01-23 14:39:09 -08:00
ld [wTempEnemyMonSpecies], a
2017-12-24 09:47:30 -08:00
callfar GetTrainerAttributes
callfar ReadTrainerParty
2018-01-18 09:03:58 -08:00
; RIVAL1's first mon has no held item
2018-01-23 14:39:09 -08:00
ld a, [wTrainerClass]
cp RIVAL1
jr nz, .ok
xor a
2018-01-23 14:39:09 -08:00
ld [wOTPartyMon1Item], a
.ok
2017-12-28 04:32:33 -08:00
ld de, vTiles2
callfar GetTrainerPic
xor a
ldh [hGraphicStartTile], a
dec a
2016-01-12 09:46:18 -08:00
ld [wEnemyItemState], a
hlcoord 12, 0
lb bc, 7, 7
predef PlaceGraphic
ld a, -1
2018-01-23 14:39:09 -08:00
ld [wCurOTMon], a
ld a, TRAINER_BATTLE
ld [wBattleMode], a
call IsGymLeader
2015-10-12 09:33:24 -07:00
jr nc, .done
xor a
2018-01-23 14:39:09 -08:00
ld [wCurPartyMon], a
ld a, [wPartyCount]
ld b, a
2015-10-12 09:33:24 -07:00
.partyloop
push bc
ld a, MON_HP
call GetPartyParamLocation
ld a, [hli]
or [hl]
2015-10-12 09:33:24 -07:00
jr z, .skipfaintedmon
ld c, HAPPINESS_GYMBATTLE
2017-12-24 09:47:30 -08:00
callfar ChangeHappiness
2015-10-12 09:33:24 -07:00
.skipfaintedmon
pop bc
dec b
2015-10-12 09:33:24 -07:00
jr z, .done
2018-01-23 14:39:09 -08:00
ld hl, wCurPartyMon
inc [hl]
2015-10-12 09:33:24 -07:00
jr .partyloop
.done
ret
2018-06-24 07:09:41 -07:00
InitEnemyWildmon:
2015-11-29 18:34:59 -08:00
ld a, WILD_BATTLE
ld [wBattleMode], a
call LoadEnemyMon
2018-01-23 14:39:09 -08:00
ld hl, wEnemyMonMoves
2015-11-29 18:34:59 -08:00
ld de, wWildMonMoves
ld bc, NUM_MOVES
call CopyBytes
2018-01-23 14:39:09 -08:00
ld hl, wEnemyMonPP
2015-11-29 18:34:59 -08:00
ld de, wWildMonPP
ld bc, NUM_MOVES
call CopyBytes
2018-01-23 14:39:09 -08:00
ld hl, wEnemyMonDVs
predef GetUnownLetter
2018-01-23 14:39:09 -08:00
ld a, [wCurPartySpecies]
cp UNOWN
2015-11-09 20:55:39 -08:00
jr nz, .skip_unown
2015-11-29 18:34:59 -08:00
ld a, [wFirstUnownSeen]
and a
2015-11-09 20:55:39 -08:00
jr nz, .skip_unown
2018-01-23 14:39:09 -08:00
ld a, [wUnownLetter]
2015-11-29 18:34:59 -08:00
ld [wFirstUnownSeen], a
2015-11-09 20:55:39 -08:00
.skip_unown
2017-12-28 04:32:33 -08:00
ld de, vTiles2
predef GetAnimatedFrontpic
xor a
2018-01-23 14:39:09 -08:00
ld [wTrainerClass], a
ldh [hGraphicStartTile], a
hlcoord 12, 0
lb bc, 7, 7
predef PlaceGraphic
ret
2020-10-05 13:15:57 -07:00
FillEnemyMovesFromMoveIndicesBuffer: ; unreferenced
2018-01-23 14:39:09 -08:00
ld hl, wEnemyMonMoves
2015-10-17 14:18:52 -07:00
ld de, wListMoves_MoveIndicesBuffer
ld b, NUM_MOVES
2014-01-05 04:28:55 -08:00
.loop
ld a, [de]
inc de
ld [hli], a
and a
2014-01-05 04:28:55 -08:00
jr z, .clearpp
push bc
push hl
2014-01-05 04:28:55 -08:00
push hl
dec a
2014-01-05 04:28:55 -08:00
ld hl, Moves + MOVE_PP
ld bc, MOVE_LENGTH
call AddNTimes
2014-01-05 04:28:55 -08:00
ld a, BANK(Moves)
call GetFarByte
pop hl
2014-01-05 04:28:55 -08:00
2018-01-23 14:39:09 -08:00
ld bc, wEnemyMonPP - (wEnemyMonMoves + 1)
add hl, bc
ld [hl], a
2014-01-05 04:28:55 -08:00
pop hl
pop bc
2014-01-05 04:28:55 -08:00
dec b
2014-01-05 04:28:55 -08:00
jr nz, .loop
ret
2014-01-05 04:28:55 -08:00
.clear
xor a
ld [hli], a
2014-01-05 04:28:55 -08:00
.clearpp
push bc
push hl
2018-01-23 14:39:09 -08:00
ld bc, wEnemyMonPP - (wEnemyMonMoves + 1)
add hl, bc
xor a
ld [hl], a
pop hl
pop bc
dec b
2014-01-05 04:28:55 -08:00
jr nz, .clear
ret
2018-06-24 07:09:41 -07:00
ExitBattle:
call .HandleEndOfBattle
call CleanUpBattleRAM
ret
2018-06-24 07:09:41 -07:00
.HandleEndOfBattle:
ld a, [wLinkMode]
and a
2015-10-24 07:34:19 -07:00
jr z, .not_linked
call ShowLinkBattleParticipantsAfterEnd
ld c, 150
call DelayFrames
call DisplayLinkBattleResult
ret
2015-10-24 07:34:19 -07:00
.not_linked
ld a, [wBattleResult]
and $f
ret nz
call CheckPayDay
xor a
ld [wForceEvolution], a
predef EvolveAfterBattle
2017-12-24 09:47:30 -08:00
farcall GivePokerusAndConvertBerries
ret
2018-06-24 07:09:41 -07:00
CleanUpBattleRAM:
call BattleEnd_HandleRoamMons
xor a
ld [wLowHealthAlarm], a
ld [wBattleMode], a
2018-01-23 14:39:09 -08:00
ld [wBattleType], a
ld [wAttackMissed], a
ld [wTempWildMonSpecies], a
ld [wOtherTrainerClass], a
2015-11-23 13:04:53 -08:00
ld [wFailedToFlee], a
ld [wNumFleeAttempts], a
2015-11-08 16:09:36 -08:00
ld [wForcedSwitch], a
2015-12-23 11:00:29 -08:00
ld [wPartyMenuCursor], a
2015-10-24 16:49:19 -07:00
ld [wKeyItemsPocketCursor], a
ld [wItemsPocketCursor], a
ld [wBattleMenuCursorPosition], a
2018-01-23 14:39:09 -08:00
ld [wCurMoveNum], a
2015-10-24 16:49:19 -07:00
ld [wBallsPocketCursor], a
2015-11-23 13:04:53 -08:00
ld [wLastPocket], a
ld [wMenuScrollPosition], a
ld [wKeyItemsPocketScrollPosition], a
ld [wItemsPocketScrollPosition], a
ld [wBallsPocketScrollPosition], a
2018-01-23 14:39:09 -08:00
ld hl, wPlayerSubStatus1
ld b, wEnemyFuryCutterCount - wPlayerSubStatus1
.loop
ld [hli], a
dec b
jr nz, .loop
call WaitSFX
ret
2018-06-24 07:09:41 -07:00
CheckPayDay:
ld hl, wPayDayCoins
ld a, [hli]
or [hl]
inc hl
or [hl]
ret z
2015-11-22 21:21:21 -08:00
ld a, [wAmuletCoin]
and a
jr z, .okay
ld hl, wPayDayCoins + 2
sla [hl]
dec hl
rl [hl]
dec hl
rl [hl]
jr nc, .okay
ld a, $ff
ld [hli], a
2015-12-26 18:59:03 -08:00
ld [hli], a
ld [hl], a
.okay
ld hl, wPayDayCoins + 2
ld de, wCurLevelCoins + 2
call AddBattleCoinsToAccount
ld hl, BattleText_PlayerPickedUpPayDayCoins
2019-04-08 05:15:10 -07:00
call StdBattleTextbox
ret
2018-06-24 07:09:41 -07:00
ShowLinkBattleParticipantsAfterEnd:
2018-01-23 14:39:09 -08:00
ld a, [wCurOTMon]
ld hl, wOTPartyMon1Status
call GetPartyLocation
2018-01-23 14:39:09 -08:00
ld a, [wEnemyMonStatus]
ld [hl], a
call ClearTilemap
2017-12-24 09:47:30 -08:00
farcall _ShowLinkBattleParticipants
ret
2018-06-24 07:09:41 -07:00
DisplayLinkBattleResult:
2015-10-24 07:34:19 -07:00
ld a, [wBattleResult]
and $f
2018-04-05 08:44:02 -07:00
cp LOSE
jr c, .win ; WIN
jr z, .lose ; LOSE
2018-04-05 08:44:02 -07:00
; DRAW
ld de, .Draw
jr .store_result
.win
ld de, .YouWin
jr .store_result
.lose
ld de, .YouLose
jr .store_result
.store_result
hlcoord 6, 8
call PlaceString
ld c, 200
call DelayFrames
2015-10-04 11:14:51 -07:00
ld a, BANK(sLinkBattleStats)
call OpenSRAM
2020-04-23 13:10:46 -07:00
call AddLastLinkBattleToLinkRecord
2016-01-12 21:39:41 -08:00
call ReadAndPrintLinkBattleRecord
call CloseSRAM
call WaitPressAorB_BlinkCursor
call ClearTilemap
ret
.YouWin:
db "YOU WIN@"
.YouLose:
db "YOU LOSE@"
.Draw:
db " DRAW@"
2018-06-24 07:09:41 -07:00
_DisplayLinkRecord:
2015-08-19 21:21:38 -07:00
ld a, BANK(sLinkBattleStats)
call OpenSRAM
2016-01-12 21:39:41 -08:00
call ReadAndPrintLinkBattleRecord
call CloseSRAM
hlcoord 0, 0, wAttrmap
xor a
ld bc, SCREEN_WIDTH * SCREEN_HEIGHT
call ByteFill
2015-12-11 13:59:40 -08:00
call WaitBGMap2
ld b, CGB_DIPLOMA
call GetCGBLayout
2024-02-10 15:16:00 -08:00
call SetDefaultBGPAndOBP
2016-01-12 21:39:41 -08:00
ld c, 8
call DelayFrames
call WaitPressAorB_BlinkCursor
ret
2018-06-24 07:09:41 -07:00
ReadAndPrintLinkBattleRecord:
call ClearTilemap
call ClearSprites
2016-01-12 21:39:41 -08:00
call .PrintBattleRecord
hlcoord 0, 8
2020-04-23 13:10:46 -07:00
ld b, NUM_LINK_BATTLE_RECORDS
ld de, sLinkBattleRecord1Name
2016-01-12 21:39:41 -08:00
.loop
push bc
push hl
push de
ld a, [de]
and a
2016-01-12 21:39:41 -08:00
jr z, .PrintFormatString
2015-10-16 10:35:43 -07:00
ld a, [wSavedAtLeastOnce]
and a
2016-01-12 21:39:41 -08:00
jr z, .PrintFormatString
push hl
push hl
ld h, d
ld l, e
ld de, wLinkBattleRecordName
2020-04-23 13:10:46 -07:00
ld bc, NAME_LENGTH - 1
call CopyBytes
2016-01-12 21:39:41 -08:00
ld a, "@"
ld [de], a
inc de ; wLinkBattleRecordWins
2016-01-12 21:39:41 -08:00
ld bc, 6
call CopyBytes
ld de, wLinkBattleRecordName
pop hl
call PlaceString
pop hl
2016-01-12 21:39:41 -08:00
ld de, 26
add hl, de
push hl
ld de, wLinkBattleRecordWins
lb bc, 2, 4
call PrintNum
pop hl
2016-01-12 21:39:41 -08:00
ld de, 5
add hl, de
push hl
ld de, wLinkBattleRecordLosses
lb bc, 2, 4
call PrintNum
pop hl
2016-01-12 21:39:41 -08:00
ld de, 5
add hl, de
ld de, wLinkBattleRecordDraws
lb bc, 2, 4
call PrintNum
2016-01-12 21:39:41 -08:00
jr .next
.PrintFormatString:
ld de, .Format
call PlaceString
2016-01-12 21:39:41 -08:00
.next
pop hl
2020-04-23 13:10:46 -07:00
ld bc, LINK_BATTLE_RECORD_LENGTH
add hl, bc
ld d, h
ld e, l
pop hl
2016-01-12 21:39:41 -08:00
ld bc, 2 * SCREEN_WIDTH
add hl, bc
pop bc
dec b
2016-01-12 21:39:41 -08:00
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
2015-08-19 21:21:38 -07:00
ld de, sLinkBattleWins
2016-01-12 21:39:41 -08:00
call .PrintZerosIfNoSaveFileExists
jr c, .quit
lb bc, 2, 4
call PrintNum
hlcoord 11, 4
2015-08-19 21:21:38 -07:00
ld de, sLinkBattleLosses
2016-01-12 21:39:41 -08:00
call .PrintZerosIfNoSaveFileExists
lb bc, 2, 4
call PrintNum
hlcoord 16, 4
2015-08-19 21:21:38 -07:00
ld de, sLinkBattleDraws
2016-01-12 21:39:41 -08:00
call .PrintZerosIfNoSaveFileExists
lb bc, 2, 4
call PrintNum
2016-01-12 21:39:41 -08:00
.quit
ret
.PrintZerosIfNoSaveFileExists:
2015-10-16 10:35:43 -07:00
ld a, [wSavedAtLeastOnce]
and a
ret nz
ld de, .Scores
call PlaceString
scf
ret
.Scores:
db " 0 0 0@"
2018-06-24 07:09:41 -07:00
.Format:
db " --- <LF>"
2016-01-12 21:39:41 -08:00
db " - - -@"
2018-06-24 07:09:41 -07:00
.Record:
2015-10-16 10:35:43 -07:00
db "<PLAYER>'s RECORD@"
2018-06-24 07:09:41 -07:00
.Result:
db "RESULT WIN LOSE DRAW@"
2018-06-24 07:09:41 -07:00
.Total:
db "TOTAL WIN LOSE DRAW@"
2018-06-24 07:09:41 -07:00
BattleEnd_HandleRoamMons:
2018-01-23 14:39:09 -08:00
ld a, [wBattleType]
cp BATTLETYPE_ROAMING
jr nz, .not_roaming
2015-10-24 07:34:19 -07:00
ld a, [wBattleResult]
and $f
2018-04-05 08:44:02 -07:00
jr z, .caught_or_defeated_roam_mon ; WIN
call GetRoamMonHP
2018-01-23 14:39:09 -08:00
ld a, [wEnemyMonHP + 1]
ld [hl], a
jr .update_roam_mons
.caught_or_defeated_roam_mon
call GetRoamMonHP
2018-02-25 16:50:48 -08:00
ld [hl], 0
call GetRoamMonMapGroup
2018-02-25 16:50:48 -08:00
ld [hl], GROUP_N_A
call GetRoamMonMapNumber
2018-02-25 16:50:48 -08:00
ld [hl], MAP_N_A
call GetRoamMonSpecies
2018-02-25 16:50:48 -08:00
ld [hl], 0
ret
.not_roaming
call BattleRandom
and $f
ret nz
.update_roam_mons
2017-12-24 09:47:30 -08:00
callfar UpdateRoamMons
ret
2018-06-24 07:09:41 -07:00
GetRoamMonMapGroup:
2018-01-23 14:39:09 -08:00
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
2018-06-24 07:09:41 -07:00
GetRoamMonMapNumber:
2018-01-23 14:39:09 -08:00
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
2018-06-24 07:09:41 -07:00
GetRoamMonHP:
; output: hl = wRoamMonHP
2018-01-23 14:39:09 -08:00
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
2018-06-24 07:09:41 -07:00
GetRoamMonDVs:
; output: hl = wRoamMonDVs
2018-01-23 14:39:09 -08:00
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
2018-06-24 07:09:41 -07:00
GetRoamMonSpecies:
2018-01-23 14:39:09 -08:00
ld a, [wTempEnemyMonSpecies]
ld hl, wRoamMon1Species
cp [hl]
ret z
ld hl, wRoamMon2Species
cp [hl]
ret z
ld hl, wRoamMon3Species
ret
2020-04-23 13:10:46 -07:00
AddLastLinkBattleToLinkRecord:
2018-01-23 14:39:09 -08:00
ld hl, wOTPlayerID
ld de, wStringBuffer1
ld bc, 2
call CopyBytes
2018-01-23 14:39:09 -08:00
ld hl, wOTPlayerName
2016-01-12 21:39:41 -08:00
ld bc, NAME_LENGTH - 1
call CopyBytes
2020-04-23 13:10:46 -07:00
ld hl, sLinkBattleStats - (LINK_BATTLE_RECORD_LENGTH - 6)
2016-01-12 21:39:41 -08:00
call .StoreResult
ld hl, sLinkBattleRecord
2020-04-23 13:10:46 -07:00
ld d, NUM_LINK_BATTLE_RECORDS
.loop
push hl
inc hl
2015-12-26 18:59:03 -08:00
inc hl
ld a, [hl]
dec hl
2015-12-26 18:59:03 -08:00
dec hl
and a
jr z, .copy
push de
2020-04-23 13:10:46 -07:00
ld bc, LINK_BATTLE_RECORD_LENGTH - 6
2018-01-23 14:39:09 -08:00
ld de, wStringBuffer1
call CompareBytesLong
pop de
pop hl
jr c, .done
2020-04-23 13:10:46 -07:00
ld bc, LINK_BATTLE_RECORD_LENGTH
add hl, bc
dec d
jr nz, .loop
2020-04-23 13:10:46 -07:00
ld bc, -LINK_BATTLE_RECORD_LENGTH
add hl, bc
push hl
.copy
ld d, h
ld e, l
2018-01-23 14:39:09 -08:00
ld hl, wStringBuffer1
2020-04-23 13:10:46 -07:00
ld bc, LINK_BATTLE_RECORD_LENGTH - 6
call CopyBytes
ld b, 6
xor a
.loop2
ld [de], a
inc de
dec b
jr nz, .loop2
pop hl
.done
2016-01-12 21:39:41 -08:00
call .StoreResult
call .FindOpponentAndAppendRecord
ret
2020-04-23 13:10:46 -07:00
2018-06-24 07:09:41 -07:00
.StoreResult:
2015-10-24 07:34:19 -07:00
ld a, [wBattleResult]
and $f
2018-04-05 08:44:02 -07:00
cp LOSE
2020-04-23 13:10:46 -07:00
ld bc, (sLinkBattleRecord1Wins - sLinkBattleRecord1) + 1
2018-04-05 08:44:02 -07:00
jr c, .okay ; WIN
2020-04-23 13:10:46 -07:00
ld bc, (sLinkBattleRecord1Losses - sLinkBattleRecord1) + 1
2018-04-05 08:44:02 -07:00
jr z, .okay ; LOSE
; DRAW
2020-04-23 13:10:46 -07:00
ld bc, (sLinkBattleRecord1Draws - sLinkBattleRecord1) + 1
.okay
add hl, bc
2016-01-12 21:39:41 -08:00
call .CheckOverflow
ret nc
inc [hl]
ret nz
dec hl
inc [hl]
ret
2018-06-24 07:09:41 -07:00
.CheckOverflow:
dec hl
ld a, [hl]
inc hl
cp HIGH(MAX_LINK_RECORD)
ret c
ld a, [hl]
cp LOW(MAX_LINK_RECORD)
ret
2018-06-24 07:09:41 -07:00
.FindOpponentAndAppendRecord:
2020-04-23 13:10:46 -07:00
ld b, NUM_LINK_BATTLE_RECORDS
ld hl, sLinkBattleRecord1End - 1
ld de, wLinkBattleRecordBuffer
2016-01-12 21:39:41 -08:00
.loop3
push bc
push de
push hl
2016-01-12 21:39:41 -08:00
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
2020-04-23 13:10:46 -07:00
ld bc, LINK_BATTLE_RECORD_LENGTH
add hl, bc
pop bc
dec b
2016-01-12 21:39:41 -08:00
jr nz, .loop3
ld b, $0
ld c, $1
2016-01-12 21:39:41 -08:00
.loop4
ld a, b
add b
2015-12-26 18:59:03 -08:00
add b
ld e, a
ld d, 0
ld hl, wLinkBattleRecordBuffer
add hl, de
push hl
ld a, c
add c
2015-12-26 18:59:03 -08:00
add c
ld e, a
ld d, 0
ld hl, wLinkBattleRecordBuffer
add hl, de
ld d, h
ld e, l
pop hl
push bc
2016-01-12 21:39:41 -08:00
ld c, 3
call CompareBytes
pop bc
jr z, .equal
2016-01-12 21:39:41 -08:00
jr nc, .done2
.equal
inc c
ld a, c
cp $5
2016-01-12 21:39:41 -08:00
jr nz, .loop4
inc b
ld c, b
inc c
ld a, b
cp $4
2016-01-12 21:39:41 -08:00
jr nz, .loop4
ret
2016-01-12 21:39:41 -08:00
.done2
push bc
ld a, b
2020-04-23 13:10:46 -07:00
ld bc, LINK_BATTLE_RECORD_LENGTH
2016-01-12 21:39:41 -08:00
ld hl, sLinkBattleRecord
call AddNTimes
push hl
ld de, wLinkBattleRecordBuffer
2020-04-23 13:10:46 -07:00
ld bc, LINK_BATTLE_RECORD_LENGTH
call CopyBytes
pop hl
pop bc
push hl
ld a, c
2020-04-23 13:10:46 -07:00
ld bc, LINK_BATTLE_RECORD_LENGTH
2016-01-12 21:39:41 -08:00
ld hl, sLinkBattleRecord
call AddNTimes
pop de
push hl
2020-04-23 13:10:46 -07:00
ld bc, LINK_BATTLE_RECORD_LENGTH
call CopyBytes
ld hl, wLinkBattleRecordBuffer
2020-04-23 13:10:46 -07:00
ld bc, LINK_BATTLE_RECORD_LENGTH
pop de
call CopyBytes
ret
2018-06-24 07:09:41 -07:00
.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
2016-01-12 21:39:41 -08:00
jr nc, .okay2
inc e
2016-01-12 21:39:41 -08:00
.okay2
ld a, [hld]
add c
ld c, a
ld a, [hl]
adc b
ld b, a
ret nc
inc e
ret
2018-06-24 07:09:41 -07:00
InitBattleDisplay:
call .InitBackPic
hlcoord 0, 12
2015-11-06 13:42:38 -08:00
ld b, 4
ld c, 18
call Textbox1bpp
hlcoord 1, 5
lb bc, 3, 7
call ClearBox
2015-11-04 13:14:27 -08:00
call LoadStandardFont
2015-11-10 16:51:13 -08:00
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
2017-12-24 09:47:30 -08:00
farcall BattleIntroSlidingPics
ld a, $1
ldh [hBGMapMode], a
ld a, $31
ldh [hGraphicStartTile], a
hlcoord 2, 6
2015-11-06 13:42:38 -08:00
lb bc, 6, 6
predef PlaceGraphic
xor a
ldh [hWY], a
vc_hook Unknown_InitBattleDisplay
ldh [rWY], a
call WaitBGMap
call HideSprites
ld b, CGB_BATTLE_COLORS
call GetCGBLayout
2024-02-10 15:16:00 -08:00
call SetDefaultBGPAndOBP
ld a, $90
ldh [hWY], a
xor a
ldh [hSCX], a
ret
2018-06-24 07:09:41 -07:00
.BlankBGMap:
ldh a, [rSVBK]
push af
ld a, BANK(wDecompressScratch)
ldh [rSVBK], a
ld hl, wDecompressScratch
ld bc, BG_MAP_WIDTH * BG_MAP_HEIGHT
ld a, " "
call ByteFill
ld de, wDecompressScratch
2015-11-20 08:47:52 -08:00
hlbgcoord 0, 0
lb bc, BANK(@), (BG_MAP_WIDTH * BG_MAP_HEIGHT) / LEN_2BPP_TILE
call Request2bpp
pop af
ldh [rSVBK], a
ret
2018-06-24 07:09:41 -07:00
.InitBackPic:
2015-11-06 13:42:38 -08:00
call GetTrainerBackpic
call CopyBackpic
ret
2018-06-24 07:09:41 -07:00
GetTrainerBackpic:
2017-12-28 04:32:33 -08:00
; Load the player character's backpic (6x6) into VRAM starting from vTiles2 tile $31.
; Special exception for Dude.
ld hl, DudeBackpic
2018-01-23 14:39:09 -08:00
ld a, [wBattleType]
cp BATTLETYPE_TUTORIAL
jr z, .Decompress
; What gender are we?
2024-03-09 07:40:21 -08:00
ld a, [wPlayerCharacter]
2024-03-08 09:56:26 -08:00
ld e, PLAYERDATA_BACKPIC
call GetPlayerField
.Decompress
2017-12-28 04:32:33 -08:00
ld de, vTiles2 tile $31
ld c, 7 * 7
2024-03-08 09:56:26 -08:00
ld b, BANK(ChrisBackpic)
predef DecompressGet2bpp
ret
2018-06-24 07:09:41 -07:00
CopyBackpic:
ldh a, [rSVBK]
push af
ld a, BANK(wDecompressScratch)
ldh [rSVBK], a
2017-12-28 04:32:33 -08:00
ld hl, vTiles0
ld de, vTiles2 tile $31
ldh a, [hROMBank]
ld b, a
ld c, 7 * 7
call Get2bpp
pop af
ldh [rSVBK], a
2016-01-12 21:39:41 -08:00
call .LoadTrainerBackpicAsOAM
ld a, $31
ldh [hGraphicStartTile], a
hlcoord 2, 6
2015-11-06 13:42:38 -08:00
lb bc, 6, 6
predef PlaceGraphic
ret
2018-06-24 07:09:41 -07:00
.LoadTrainerBackpicAsOAM:
ld hl, wShadowOAMSprite00
xor a
ldh [hMapObjectIndex], a
2018-01-10 10:47:57 -08:00
ld b, 6
ld e, (SCREEN_WIDTH + 1) * TILE_WIDTH
2015-11-06 13:42:38 -08:00
.outer_loop
2018-01-10 10:47:57 -08:00
ld c, 3
ld d, 8 * TILE_WIDTH
2015-11-06 13:42:38 -08:00
.inner_loop
2018-01-10 10:47:57 -08:00
ld [hl], d ; y
inc hl
2018-01-10 10:47:57 -08:00
ld [hl], e ; x
inc hl
ldh a, [hMapObjectIndex]
2018-01-10 10:47:57 -08:00
ld [hli], a ; tile id
inc a
ldh [hMapObjectIndex], a
2018-01-10 10:47:57 -08:00
ld a, PAL_BATTLE_OB_PLAYER
ld [hli], a ; attributes
ld a, d
2018-01-10 10:47:57 -08:00
add 1 * TILE_WIDTH
ld d, a
dec c
2015-11-06 13:42:38 -08:00
jr nz, .inner_loop
ldh a, [hMapObjectIndex]
add $3
ldh [hMapObjectIndex], a
ld a, e
2018-01-10 10:47:57 -08:00
add 1 * TILE_WIDTH
ld e, a
dec b
2015-11-06 13:42:38 -08:00
jr nz, .outer_loop
ret
2018-06-24 07:09:41 -07:00
BattleStartMessage:
ld a, [wBattleMode]
dec a
2015-11-06 13:42:38 -08:00
jr z, .wild
ld de, SFX_SHINE
call PlaySFX
call WaitSFX
ld c, 20
call DelayFrames
2017-12-24 09:47:30 -08:00
farcall Battle_GetTrainerName
ld hl, WantsToBattleText
2024-02-10 15:16:00 -08:00
jr .PrintBattleStartText
2015-11-06 13:42:38 -08:00
.wild
call BattleCheckEnemyShininess
jr nc, .not_shiny
xor a
2015-12-23 11:00:29 -08:00
ld [wNumHits], a
ld a, 1
ldh [hBattleTurn], a
ld a, 1
2015-12-23 17:46:23 -08:00
ld [wBattleAnimParam], a
ld de, ANIM_SEND_OUT_MON
2015-09-09 16:27:07 -07:00
call Call_PlayBattleAnim
2015-11-06 13:42:38 -08:00
.not_shiny
2017-12-24 09:47:30 -08:00
farcall CheckSleepingTreeMon
2015-11-06 13:42:38 -08:00
jr c, .skip_cry
2017-12-24 09:47:30 -08:00
farcall CheckBattleScene
2015-11-07 06:48:32 -08:00
jr c, .cry_no_anim
hlcoord 12, 0
ld d, $0
2015-11-07 06:48:32 -08:00
ld e, ANIM_MON_NORMAL
predef AnimateFrontpic
2015-12-13 11:15:16 -08:00
jr .skip_cry ; cry is played during the animation
2015-11-07 06:48:32 -08:00
.cry_no_anim
2018-07-22 20:42:50 -07:00
ld a, $f
2018-01-23 14:39:09 -08:00
ld [wCryTracks], a
ld a, [wTempEnemyMonSpecies]
2014-07-18 10:25:03 -07:00
call PlayStereoCry
2015-11-06 13:42:38 -08:00
.skip_cry
2018-01-23 14:39:09 -08:00
ld a, [wBattleType]
cp BATTLETYPE_FISH
2015-11-06 13:42:38 -08:00
jr nz, .NotFishing
ld hl, HookedPokemonAttackedText
2024-02-10 15:16:00 -08:00
jr .PrintBattleStartText
.NotFishing:
ld hl, PokemonFellFromTreeText
cp BATTLETYPE_TREE
2024-02-10 15:16:00 -08:00
jr z, .PrintBattleStartText
ld hl, WildCelebiAppearedText
cp BATTLETYPE_CELEBI
2024-02-10 15:16:00 -08:00
jr z, .PrintBattleStartText
ld hl, WildPokemonAppearedText
2024-02-10 15:16:00 -08:00
.PrintBattleStartText:
push hl
2017-12-24 09:47:30 -08:00
farcall BattleStart_TrainerHuds
pop hl
2019-04-08 05:15:10 -07:00
call StdBattleTextbox
ret