DoPlayerTurn: ; 34000 call SetPlayerTurn ld a, [wPlayerAction] and a ret nz jr DoTurn ; 3400a DoEnemyTurn: ; 3400a call SetEnemyTurn ld a, [wLinkMode] and a jr z, DoTurn ld a, [wBattleAction] cp BATTLEACTION_E jr z, DoTurn cp BATTLEACTION_SWITCH1 ret nc ; fallthrough ; 3401d DoTurn: ; 3401d ; Read in and execute the user's move effects for this turn. xor a ld [wTurnEnded], a ; Effect command checkturn is called for every move. call CheckTurn ld a, [wTurnEnded] and a ret nz call UpdateMoveData ; 3402c DoMove: ; 3402c ; Get the user's move effect. ld a, BATTLE_VARS_MOVE_EFFECT call GetBattleVar ld c, a ld b, 0 ld hl, MoveEffectsPointers add hl, bc add hl, bc ld a, BANK(MoveEffectsPointers) call GetFarHalfword ld de, BattleScriptBuffer .GetMoveEffect: ld a, BANK(MoveEffects) call GetFarByte inc hl ld [de], a inc de cp $ff jr nz, .GetMoveEffect ; Start at the first command. ld hl, BattleScriptBuffer ld a, l ld [BattleScriptBufferAddress], a ld a, h ld [BattleScriptBufferAddress + 1], a .ReadMoveEffectCommand: ; ld a, [BattleScriptBufferAddress++] ld a, [BattleScriptBufferAddress] ld l, a ld a, [BattleScriptBufferAddress + 1] ld h, a ld a, [hli] push af ld a, l ld [BattleScriptBufferAddress], a ld a, h ld [BattleScriptBufferAddress + 1], a pop af ; endturn_command (-2) is used to terminate branches without ending the read cycle. cp endturn_command ret nc ; The rest of the commands (01-af) are read from BattleCommandPointers. push bc dec a ld c, a ld b, 0 ld hl, BattleCommandPointers add hl, bc add hl, bc pop bc ld a, BANK(BattleCommandPointers) call GetFarHalfword call .DoMoveEffectCommand jr .ReadMoveEffectCommand .DoMoveEffectCommand: jp hl ; 34084 CheckTurn: BattleCommand_CheckTurn: ; 34084 ; checkturn ; Repurposed as hardcoded turn handling. Useless as a command. ; Move $ff immediately ends the turn. ld a, BATTLE_VARS_MOVE call GetBattleVar inc a jp z, EndTurn xor a ld [AttackMissed], a ld [EffectFailed], a ld [wKickCounter], a ld [AlreadyDisobeyed], a ld [AlreadyFailed], a ld [wSomeoneIsRampaging], a ld a, 10 ; 1.0 ld [TypeModifier], a ld a, [hBattleTurn] and a jp nz, CheckEnemyTurn CheckPlayerTurn: ld hl, PlayerSubStatus4 bit SUBSTATUS_RECHARGE, [hl] jr z, .no_recharge res SUBSTATUS_RECHARGE, [hl] ld hl, MustRechargeText call StdBattleTextBox call CantMove jp EndTurn .no_recharge ld hl, BattleMonStatus ld a, [hl] and SLP jr z, .not_asleep dec a ld [BattleMonStatus], a and SLP jr z, .woke_up xor a ld [wNumHits], a ld de, ANIM_SLP call FarPlayBattleAnimation jr .fast_asleep .woke_up ld hl, WokeUpText call StdBattleTextBox call CantMove call UpdateBattleMonInParty ld hl, UpdatePlayerHUD call CallBattleCore ld a, $1 ld [hBGMapMode], a ld hl, PlayerSubStatus1 res SUBSTATUS_NIGHTMARE, [hl] jr .not_asleep .fast_asleep ld hl, FastAsleepText call StdBattleTextBox ; Snore and Sleep Talk bypass sleep. ld a, [CurPlayerMove] cp SNORE jr z, .not_asleep cp SLEEP_TALK jr z, .not_asleep call CantMove jp EndTurn .not_asleep ld hl, BattleMonStatus bit FRZ, [hl] jr z, .not_frozen ; Flame Wheel and Sacred Fire thaw the user. ld a, [CurPlayerMove] cp FLAME_WHEEL jr z, .not_frozen cp SACRED_FIRE jr z, .not_frozen ld hl, FrozenSolidText call StdBattleTextBox call CantMove jp EndTurn .not_frozen ld hl, PlayerSubStatus3 bit SUBSTATUS_FLINCHED, [hl] jr z, .not_flinched res SUBSTATUS_FLINCHED, [hl] ld hl, FlinchedText call StdBattleTextBox call CantMove jp EndTurn .not_flinched ld hl, PlayerDisableCount ld a, [hl] and a jr z, .not_disabled dec a ld [hl], a and $f jr nz, .not_disabled ld [hl], a ld [DisabledMove], a ld hl, DisabledNoMoreText call StdBattleTextBox .not_disabled ld a, [PlayerSubStatus3] add a jr nc, .not_confused ld hl, PlayerConfuseCount dec [hl] jr nz, .confused ld hl, PlayerSubStatus3 res SUBSTATUS_CONFUSED, [hl] ld hl, ConfusedNoMoreText call StdBattleTextBox jr .not_confused .confused ld hl, IsConfusedText call StdBattleTextBox xor a ld [wNumHits], a ld de, ANIM_CONFUSED call FarPlayBattleAnimation ; 50% chance of hitting itself call BattleRandom cp $80 jr nc, .not_confused ; clear confusion-dependent substatus ld hl, PlayerSubStatus3 ld a, [hl] and 1 << SUBSTATUS_CONFUSED ld [hl], a call HitConfusion call CantMove jp EndTurn .not_confused ld a, [PlayerSubStatus1] add a ; bit SUBSTATUS_ATTRACT jr nc, .not_infatuated ld hl, InLoveWithText call StdBattleTextBox xor a ld [wNumHits], a ld de, ANIM_IN_LOVE call FarPlayBattleAnimation ; 50% chance of infatuation call BattleRandom cp $80 jr c, .not_infatuated ld hl, InfatuationText call StdBattleTextBox call CantMove jp EndTurn .not_infatuated ; We can't disable a move that doesn't exist. ld a, [DisabledMove] and a jr z, .no_disabled_move ; Are we using the disabled move? ld hl, CurPlayerMove cp [hl] jr nz, .no_disabled_move call MoveDisabled call CantMove jp EndTurn .no_disabled_move ld hl, BattleMonStatus bit PAR, [hl] ret z ; 25% chance to be fully paralyzed call BattleRandom cp $3f ret nc ld hl, FullyParalyzedText call StdBattleTextBox call CantMove jp EndTurn ; 341f0 CantMove: ; 341f0 ld a, BATTLE_VARS_SUBSTATUS1 call GetBattleVarAddr res SUBSTATUS_ROLLOUT, [hl] ld a, BATTLE_VARS_SUBSTATUS3 call GetBattleVarAddr ld a, [hl] and $ff ^ (1< ReflectCount inc bc ld a, 5 ld [bc], a ld hl, ReflectEffectText .good call AnimateCurrentMove jp StdBattleTextBox .failed call AnimateFailedMove jp PrintButItFailed ; 3733d PrintDoesntAffect: ; 3733d ; 'it doesn't affect' ld hl, DoesntAffectText jp StdBattleTextBox ; 37343 PrintNothingHappened: ; 37343 ; 'but nothing happened!' ld hl, NothingHappenedText jp StdBattleTextBox ; 37349 TryPrintButItFailed: ; 37349 ld a, [AlreadyFailed] and a ret nz ; fallthrough ; 3734e PrintButItFailed: ; 3734e ; 'but it failed!' ld hl, ButItFailedText jp StdBattleTextBox ; 37354 FailSnore: FailDisable: FailConversion2: FailAttract: FailForesight: FailSpikes: call AnimateFailedMove ; fallthrough ; 37357 FailMimic: ; 37357 ld hl, ButItFailedText ; 'but it failed!' ld de, ItFailedText ; 'it failed!' jp FailText_CheckOpponentProtect ; 37360 PrintDidntAffect: ; 37360 ; 'it didn't affect' ld hl, DidntAffect1Text jp StdBattleTextBox ; 37366 PrintDidntAffect2: ; 37366 call AnimateFailedMove ld hl, DidntAffect1Text ; 'it didn't affect' ld de, DidntAffect2Text ; 'it didn't affect' jp FailText_CheckOpponentProtect ; 37372 PrintParalyze: ; 37372 ; 'paralyzed! maybe it can't attack!' ld hl, ParalyzedText jp StdBattleTextBox ; 37378 CheckSubstituteOpp: ; 37378 ld a, BATTLE_VARS_SUBSTATUS4_OPP call GetBattleVar bit SUBSTATUS_SUBSTITUTE, a ret ; 37380 BattleCommand_Selfdestruct: ; 37380 farcall TrainerRankings_Selfdestruct ld a, BATTLEANIM_PLAYER_DAMAGE ld [wNumHits], a ld c, 3 call DelayFrames ld a, BATTLE_VARS_STATUS call GetBattleVarAddr xor a ld [hli], a inc hl ld [hli], a ld [hl], a ld a, $1 ld [wKickCounter], a call BattleCommand_LowerSub call LoadMoveAnim ld a, BATTLE_VARS_SUBSTATUS4 call GetBattleVarAddr res SUBSTATUS_LEECH_SEED, [hl] ld a, BATTLE_VARS_SUBSTATUS5_OPP call GetBattleVarAddr res SUBSTATUS_DESTINY_BOND, [hl] call _CheckBattleScene ret nc farcall DrawPlayerHUD farcall DrawEnemyHUD call WaitBGMap jp RefreshBattleHuds ; 373c9 INCLUDE "battle/effects/mirror_move.asm" INCLUDE "battle/effects/metronome.asm" CheckUserMove: ; 37462 ; Return z if the user has move a. ld b, a ld de, BattleMonMoves ld a, [hBattleTurn] and a jr z, .ok ld de, EnemyMonMoves .ok ld c, NUM_MOVES .loop ld a, [de] inc de cp b ret z dec c jr nz, .loop ld a, 1 and a ret ; 3747b ResetTurn: ; 3747b ld hl, wPlayerCharging ld a, [hBattleTurn] and a jr z, .player ld hl, wEnemyCharging .player ld [hl], 1 xor a ld [AlreadyDisobeyed], a call DoMove jp EndMoveEffect ; 37492 INCLUDE "battle/effects/thief.asm" BattleCommand_ArenaTrap: ; 37517 ; arenatrap ; Doesn't work on an absent opponent. call CheckHiddenOpponent jr nz, .failed ; Don't trap if the opponent is already trapped. ld a, BATTLE_VARS_SUBSTATUS5 call GetBattleVarAddr bit SUBSTATUS_CANT_RUN, [hl] jr nz, .failed ; Otherwise trap the opponent. set SUBSTATUS_CANT_RUN, [hl] call AnimateCurrentMove ld hl, CantEscapeNowText jp StdBattleTextBox .failed call AnimateFailedMove jp PrintButItFailed ; 37536 INCLUDE "battle/effects/nightmare.asm" BattleCommand_Defrost: ; 37563 ; defrost ; Thaw the user. ld a, BATTLE_VARS_STATUS call GetBattleVarAddr bit FRZ, [hl] ret z res FRZ, [hl] ; Don't update the enemy's party struct in a wild battle. ld a, [hBattleTurn] and a jr z, .party ld a, [wBattleMode] dec a jr z, .done .party ld a, MON_STATUS call UserPartyAttr res FRZ, [hl] .done call RefreshBattleHuds ld hl, WasDefrostedText jp StdBattleTextBox ; 37588 INCLUDE "battle/effects/curse.asm" INCLUDE "battle/effects/protect.asm" INCLUDE "battle/effects/endure.asm" INCLUDE "battle/effects/spikes.asm" INCLUDE "battle/effects/foresight.asm" INCLUDE "battle/effects/perish_song.asm" INCLUDE "battle/effects/sandstorm.asm" INCLUDE "battle/effects/rollout.asm" BattleCommand5d: ; 37791 ; unused ret ; 37792 BattleCommand_FuryCutter: ; 37792 ; furycutter ld hl, PlayerFuryCutterCount ld a, [hBattleTurn] and a jr z, .go ld hl, EnemyFuryCutterCount .go ld a, [AttackMissed] and a jp nz, ResetFuryCutterCount inc [hl] ; Damage capped at 5 turns' worth (16x). ld a, [hl] ld b, a cp 6 jr c, .checkdouble ld b, 5 .checkdouble dec b ret z ; Double the damage ld hl, CurDamage + 1 sla [hl] dec hl rl [hl] jr nc, .checkdouble ; No overflow ld a, $ff ld [hli], a ld [hl], a ret ; 377be ResetFuryCutterCount: ; 377be push hl ld hl, PlayerFuryCutterCount ld a, [hBattleTurn] and a jr z, .reset ld hl, EnemyFuryCutterCount .reset xor a ld [hl], a pop hl ret ; 377ce INCLUDE "battle/effects/attract.asm" BattleCommand_HappinessPower: ; 3784b ; happinesspower push bc ld hl, BattleMonHappiness ld a, [hBattleTurn] and a jr z, .ok ld hl, EnemyMonHappiness .ok xor a ld [hMultiplicand + 0], a ld [hMultiplicand + 1], a ld a, [hl] ld [hMultiplicand + 2], a ld a, 10 ld [hMultiplier], a call Multiply ld a, 25 ld [hDivisor], a ld b, 4 call Divide ld a, [hQuotient + 2] ld d, a pop bc ret ; 37874 INCLUDE "battle/effects/present.asm" BattleCommand_FrustrationPower: ; 3790e ; frustrationpower push bc ld hl, BattleMonHappiness ld a, [hBattleTurn] and a jr z, .got_happiness ld hl, EnemyMonHappiness .got_happiness ld a, $ff sub [hl] ld [hMultiplicand + 2], a xor a ld [hMultiplicand + 0], a ld [hMultiplicand + 1], a ld a, 10 ld [hMultiplier], a call Multiply ld a, 25 ld [hDivisor], a ld b, 4 call Divide ld a, [hQuotient + 2] ld d, a pop bc ret ; 37939 BattleCommand_Safeguard: ; 37939 ; safeguard ld hl, PlayerScreens ld de, PlayerSafeguardCount ld a, [hBattleTurn] and a jr z, .ok ld hl, EnemyScreens ld de, EnemySafeguardCount .ok bit SCREENS_SAFEGUARD, [hl] jr nz, .failed set SCREENS_SAFEGUARD, [hl] ld a, 5 ld [de], a call AnimateCurrentMove ld hl, CoveredByVeilText jp StdBattleTextBox .failed call AnimateFailedMove jp PrintButItFailed ; 37962 SafeCheckSafeguard: ; 37962 push hl ld hl, EnemyScreens ld a, [hBattleTurn] and a jr z, .got_turn ld hl, PlayerScreens .got_turn bit SCREENS_SAFEGUARD, [hl] pop hl ret ; 37972 BattleCommand_CheckSafeguard: ; 37972 ; checksafeguard ld hl, EnemyScreens ld a, [hBattleTurn] and a jr z, .got_turn ld hl, PlayerScreens .got_turn bit SCREENS_SAFEGUARD, [hl] ret z ld a, 1 ld [AttackMissed], a call BattleCommand_MoveDelay ld hl, SafeguardProtectText call StdBattleTextBox jp EndMoveEffect ; 37991 BattleCommand_GetMagnitude: ; 37991 ; getmagnitude push bc call BattleRandom ld b, a ld hl, .Magnitudes .loop ld a, [hli] cp b jr nc, .ok inc hl inc hl jr .loop .ok ld d, [hl] push de inc hl ld a, [hl] ld [wTypeMatchup], a call BattleCommand_MoveDelay ld hl, MagnitudeText call StdBattleTextBox pop de pop bc ret .Magnitudes: ; /255, BP, magnitude db 13, 10, 4 db 38, 30, 5 db 89, 50, 6 db 166, 70, 7 db 217, 90, 8 db 242, 110, 9 db 255, 150, 10 ; 379c9 BattleCommand_BatonPass: ; 379c9 ; batonpass ld a, [hBattleTurn] and a jp nz, .Enemy ; Need something to switch to call CheckAnyOtherAlivePartyMons jp z, FailedBatonPass call UpdateBattleMonInParty call AnimateCurrentMove ld c, 50 call DelayFrames ; Transition into switchmon menu call LoadStandardMenuDataHeader farcall SetUpBattlePartyMenu_NoLoop farcall ForcePickSwitchMonInBattle ; Return to battle scene call ClearPalettes farcall _LoadBattleFontsHPBar call CloseWindow call ClearSprites hlcoord 1, 0 lb bc, 4, 10 call ClearBox ld b, SCGB_BATTLE_COLORS call GetSGBLayout call SetPalettes call BatonPass_LinkPlayerSwitch ; Mobile link battles handle entrances differently farcall CheckMobileBattleError jp c, EndMoveEffect ld hl, PassedBattleMonEntrance call CallBattleCore call ResetBatonPassStatus ret .Enemy: ; Wildmons don't have anything to switch to ld a, [wBattleMode] dec a ; WILDMON jp z, FailedBatonPass call CheckAnyOtherAliveEnemyMons jp z, FailedBatonPass call UpdateEnemyMonInParty call AnimateCurrentMove call BatonPass_LinkEnemySwitch ; Mobile link battles handle entrances differently farcall CheckMobileBattleError jp c, EndMoveEffect ; Passed enemy PartyMon entrance xor a ld [wEnemySwitchMonIndex], a ld hl, EnemySwitch_SetMode call CallBattleCore ld hl, ResetBattleParticipants call CallBattleCore ld a, 1 ld [wTypeMatchup], a ld hl, ApplyStatLevelMultiplierOnAllStats call CallBattleCore ld hl, SpikesDamage call CallBattleCore jr ResetBatonPassStatus ; 37a67 BatonPass_LinkPlayerSwitch: ; 37a67 ld a, [wLinkMode] and a ret z ld a, 1 ld [wPlayerAction], a call LoadStandardMenuDataHeader ld hl, LinkBattleSendReceiveAction call CallBattleCore call CloseWindow xor a ld [wPlayerAction], a ret ; 37a82 BatonPass_LinkEnemySwitch: ; 37a82 ld a, [wLinkMode] and a ret z call LoadStandardMenuDataHeader ld hl, LinkBattleSendReceiveAction call CallBattleCore ld a, [OTPartyCount] add BATTLEACTION_SWITCH1 ld b, a ld a, [wBattleAction] cp BATTLEACTION_SWITCH1 jr c, .baton_pass cp b jr c, .switch .baton_pass ld a, [CurOTMon] add BATTLEACTION_SWITCH1 ld [wBattleAction], a .switch jp CloseWindow ; 37aab FailedBatonPass: ; 37aab call AnimateFailedMove jp PrintButItFailed ; 37ab1 ResetBatonPassStatus: ; 37ab1 ; Reset status changes that aren't passed by Baton Pass. ; Nightmare isn't passed. ld a, BATTLE_VARS_STATUS call GetBattleVar and SLP jr nz, .ok ld a, BATTLE_VARS_SUBSTATUS1 call GetBattleVarAddr res SUBSTATUS_NIGHTMARE, [hl] .ok ; Disable isn't passed. call ResetActorDisable ; Attraction isn't passed. ld hl, PlayerSubStatus1 res SUBSTATUS_IN_LOVE, [hl] ld hl, EnemySubStatus1 res SUBSTATUS_IN_LOVE, [hl] ld hl, PlayerSubStatus5 ld a, BATTLE_VARS_SUBSTATUS5 call GetBattleVarAddr res SUBSTATUS_TRANSFORMED, [hl] res SUBSTATUS_ENCORED, [hl] ; New mon hasn't used a move yet. ld a, BATTLE_VARS_LAST_MOVE call GetBattleVarAddr ld [hl], 0 xor a ld [wPlayerWrapCount], a ld [wEnemyWrapCount], a ret ; 37ae9 CheckAnyOtherAlivePartyMons: ; 37ae9 ld hl, PartyMon1HP ld a, [PartyCount] ld d, a ld a, [CurBattleMon] ld e, a jr CheckAnyOtherAliveMons ; 37af6 CheckAnyOtherAliveEnemyMons: ; 37af6 ld hl, OTPartyMon1HP ld a, [OTPartyCount] ld d, a ld a, [CurOTMon] ld e, a ; fallthrough ; 37b01 CheckAnyOtherAliveMons: ; 37b01 ; Check for nonzero HP starting from partymon ; HP at hl for d partymons, besides current mon e. ; Return nz if any are alive. xor a ld b, a ld c, a .loop ld a, c cp d jr z, .done cp e jr z, .next ld a, [hli] or b ld b, a ld a, [hld] or b ld b, a .next push bc ld bc, PARTYMON_STRUCT_LENGTH add hl, bc pop bc inc c jr .loop .done ld a, b and a ret ; 37b1d BattleCommand_Pursuit: ; 37b1d ; pursuit ; Double damage if the opponent is switching. ld hl, wEnemyIsSwitching ld a, [hBattleTurn] and a jr z, .ok ld hl, wPlayerIsSwitching .ok ld a, [hl] and a ret z ld hl, CurDamage + 1 sla [hl] dec hl rl [hl] ret nc ld a, $ff ld [hli], a ld [hl], a ret ; 37b39 BattleCommand_ClearHazards: ; 37b39 ; clearhazards ld a, BATTLE_VARS_SUBSTATUS4 call GetBattleVarAddr bit SUBSTATUS_LEECH_SEED, [hl] jr z, .not_leeched res SUBSTATUS_LEECH_SEED, [hl] ld hl, ShedLeechSeedText call StdBattleTextBox .not_leeched ld hl, PlayerScreens ld de, wPlayerWrapCount ld a, [hBattleTurn] and a jr z, .got_screens_wrap ld hl, EnemyScreens ld de, wEnemyWrapCount .got_screens_wrap bit SCREENS_SPIKES, [hl] jr z, .no_spikes res SCREENS_SPIKES, [hl] ld hl, BlewSpikesText push de call StdBattleTextBox pop de .no_spikes ld a, [de] and a ret z xor a ld [de], a ld hl, ReleasedByText jp StdBattleTextBox ; 37b74 BattleCommand_HealMorn: ; 37b74 ; healmorn ld b, MORN_F jr BattleCommand_TimeBasedHealContinue ; 37b78 BattleCommand_HealDay: ; 37b78 ; healday ld b, DAY_F jr BattleCommand_TimeBasedHealContinue ; 37b7c BattleCommand_HealNite: ; 37b7c ; healnite ld b, NITE_F ; fallthrough ; 37b7e BattleCommand_TimeBasedHealContinue: ; 37b7e ; Time- and weather-sensitive heal. ld hl, BattleMonMaxHP ld de, BattleMonHP ld a, [hBattleTurn] and a jr z, .start ld hl, EnemyMonMaxHP ld de, EnemyMonHP .start ; Index for .Multipliers ; Default restores half max HP. ld c, 2 ; Don't bother healing if HP is already full. push bc call StringCmp pop bc jr z, .Full ; Don't factor in time of day in link battles. ld a, [wLinkMode] and a jr nz, .Weather ld a, [TimeOfDay] cp b jr z, .Weather dec c ; double .Weather: ld a, [Weather] and a jr z, .Heal ; x2 in sun ; /2 in rain/sandstorm inc c cp WEATHER_SUN jr z, .Heal dec c dec c .Heal: ld b, 0 ld hl, .Multipliers add hl, bc add hl, bc ld a, [hli] ld h, [hl] ld l, a ld a, BANK(GetMaxHP) rst FarCall call AnimateCurrentMove call BattleCommand_SwitchTurn callfar RestoreHP call BattleCommand_SwitchTurn call UpdateUserInParty ; 'regained health!' ld hl, RegainedHealthText jp StdBattleTextBox .Full: call AnimateFailedMove ; 'hp is full!' ld hl, HPIsFullText jp StdBattleTextBox .Multipliers: dw GetEighthMaxHP dw GetQuarterMaxHP dw GetHalfMaxHP dw GetMaxHP ; 37be8 BattleCommand_HiddenPower: ; 37be8 ; hiddenpower ld a, [AttackMissed] and a ret nz farcall HiddenPowerDamage ret ; 37bf4 BattleCommand_StartRain: ; 37bf4 ; startrain ld a, WEATHER_RAIN ld [Weather], a ld a, 5 ld [WeatherCount], a call AnimateCurrentMove ld hl, DownpourText jp StdBattleTextBox ; 37c07 BattleCommand_StartSun: ; 37c07 ; startsun ld a, WEATHER_SUN ld [Weather], a ld a, 5 ld [WeatherCount], a call AnimateCurrentMove ld hl, SunGotBrightText jp StdBattleTextBox ; 37c1a BattleCommand_BellyDrum: ; 37c1a ; bellydrum ; This command is buggy because it raises the user's attack ; before checking that it has enough HP to use the move. ; Swap the order of these two blocks to fix. call BattleCommand_AttackUp2 ld a, [AttackMissed] and a jr nz, .failed callfar GetHalfMaxHP callfar CheckUserHasEnoughHP jr nc, .failed push bc call AnimateCurrentMove pop bc callfar SubtractHPFromUser call UpdateUserInParty ld a, 5 .max_attack_loop push af call BattleCommand_AttackUp2 pop af dec a jr nz, .max_attack_loop ld hl, BellyDrumText jp StdBattleTextBox .failed call AnimateFailedMove jp PrintButItFailed ; 37c55 BattleCommand_PsychUp: ; 37c55 ; psychup ld hl, EnemyStatLevels ld de, PlayerStatLevels ld a, [hBattleTurn] and a jr z, .pointers_correct ; It's the enemy's turn, so swap the pointers. push hl ld h, d ld l, e pop de .pointers_correct push hl ld b, NUM_LEVEL_STATS ; If any of the enemy's stats is modified from its base level, ; the move succeeds. Otherwise, it fails. .loop ld a, [hli] cp BASE_STAT_LEVEL jr nz, .break dec b jr nz, .loop pop hl call AnimateFailedMove jp PrintButItFailed .break pop hl ld b, NUM_LEVEL_STATS .loop2 ld a, [hli] ld [de], a inc de dec b jr nz, .loop2 ld a, [hBattleTurn] and a jr nz, .calc_enemy_stats call CalcPlayerStats jr .merge .calc_enemy_stats call CalcEnemyStats .merge call AnimateCurrentMove ld hl, CopiedStatsText jp StdBattleTextBox ; 37c95 BattleCommand_MirrorCoat: ; 37c95 ; mirrorcoat ld a, 1 ld [AttackMissed], a ld a, BATTLE_VARS_LAST_COUNTER_MOVE_OPP call GetBattleVar and a ret z ld b, a callfar GetMoveEffect ld a, b cp EFFECT_MIRROR_COAT ret z call BattleCommand_ResetTypeMatchup ld a, [wTypeMatchup] and a ret z call CheckOpponentWentFirst ret z ld a, BATTLE_VARS_LAST_COUNTER_MOVE_OPP call GetBattleVar dec a ld de, StringBuffer1 call GetMoveData ld a, [StringBuffer1 + 2] and a ret z ld a, [StringBuffer1 + 3] cp SPECIAL ret c ld hl, CurDamage ld a, [hli] or [hl] ret z ld a, [hl] add a ld [hld], a ld a, [hl] adc a ld [hl], a jr nc, .capped ld a, $ff ld [hli], a ld [hl], a .capped xor a ld [AttackMissed], a ret ; 37ce6 BattleCommand_DoubleMinimizeDamage: ; 37ce6 ; doubleminimizedamage ld hl, wEnemyMinimized ld a, [hBattleTurn] and a jr z, .ok ld hl, wPlayerMinimized .ok ld a, [hl] and a ret z ld hl, CurDamage + 1 sla [hl] dec hl rl [hl] ret nc ld a, $ff ld [hli], a ld [hl], a ret ; 37d02 BattleCommand_SkipSunCharge: ; 37d02 ; mimicsuncharge ld a, [Weather] cp WEATHER_SUN ret nz ld b, charge_command jp SkipToBattleCommand ; 37d0d BattleCommand_CheckFutureSight: ; 37d0d ; checkfuturesight ld hl, wPlayerFutureSightCount ld de, wPlayerFutureSightDamage ld a, [hBattleTurn] and a jr z, .ok ld hl, wEnemyFutureSightCount ld de, wEnemyFutureSightDamage .ok ld a, [hl] and a ret z cp 1 ret nz ld [hl], 0 ld a, [de] inc de ld [CurDamage], a ld a, [de] ld [CurDamage + 1], a ld b, futuresight_command jp SkipToBattleCommand ; 37d34 BattleCommand_FutureSight: ; 37d34 ; futuresight call CheckUserIsCharging jr nz, .AlreadyChargingFutureSight ld a, BATTLE_VARS_MOVE_ANIM call GetBattleVar ld b, a ld a, BATTLE_VARS_LAST_COUNTER_MOVE call GetBattleVarAddr ld [hl], b ld a, BATTLE_VARS_LAST_MOVE call GetBattleVarAddr ld [hl], b .AlreadyChargingFutureSight: ld hl, wPlayerFutureSightCount ld a, [hBattleTurn] and a jr z, .GotFutureSightCount ld hl, wEnemyFutureSightCount .GotFutureSightCount: ld a, [hl] and a jr nz, .failed ld a, 4 ld [hl], a call BattleCommand_LowerSub call BattleCommand_MoveDelay ld hl, ForesawAttackText call StdBattleTextBox call BattleCommand_RaiseSub ld de, wPlayerFutureSightDamage ld a, [hBattleTurn] and a jr z, .StoreDamage ld de, wEnemyFutureSightDamage .StoreDamage: ld hl, CurDamage ld a, [hl] ld [de], a ld [hl], 0 inc hl inc de ld a, [hl] ld [de], a ld [hl], 0 jp EndMoveEffect .failed pop bc call ResetDamage call AnimateFailedMove call PrintButItFailed jp EndMoveEffect ; 37d94 BattleCommand_ThunderAccuracy: ; 37d94 ; thunderaccuracy ld a, BATTLE_VARS_MOVE_TYPE call GetBattleVarAddr inc hl ld a, [Weather] cp WEATHER_RAIN jr z, .rain cp WEATHER_SUN ret nz ld [hl], 50 percent + 1 ret .rain ; Redundant with CheckHit guranteeing hit ld [hl], 100 percent ret ; 37daa CheckHiddenOpponent: ; 37daa ; BUG: This routine should account for Lock-On and Mind Reader. ld a, BATTLE_VARS_SUBSTATUS3_OPP call GetBattleVar and 1 << SUBSTATUS_FLYING | 1 << SUBSTATUS_UNDERGROUND ret ; 37db2 GetUserItem: ; 37db2 ; Return the effect of the user's item in bc, and its id at hl. ld hl, BattleMonItem ld a, [hBattleTurn] and a jr z, .go ld hl, EnemyMonItem .go ld b, [hl] jp GetItemHeldEffect ; 37dc1 GetOpponentItem: ; 37dc1 ; Return the effect of the opponent's item in bc, and its id at hl. ld hl, EnemyMonItem ld a, [hBattleTurn] and a jr z, .go ld hl, BattleMonItem .go ld b, [hl] jp GetItemHeldEffect ; 37dd0 GetItemHeldEffect: ; 37dd0 ; Return the effect of item b in bc. ld a, b and a ret z push hl ld hl, ItemAttributes + ITEMATTR_EFFECT dec a ld c, a ld b, 0 ld a, ITEMATTR_STRUCT_LENGTH call AddNTimes ld a, BANK(ItemAttributes) call GetFarHalfword ld b, l ld c, h pop hl ret ; 37de9 AnimateCurrentMoveEitherSide: ; 37de9 push hl push de push bc ld a, [wKickCounter] push af call BattleCommand_LowerSub pop af ld [wKickCounter], a call PlayDamageAnim call BattleCommand_RaiseSub pop bc pop de pop hl ret ; 37e01 AnimateCurrentMove: ; 37e01 push hl push de push bc ld a, [wKickCounter] push af call BattleCommand_LowerSub pop af ld [wKickCounter], a call LoadMoveAnim call BattleCommand_RaiseSub pop bc pop de pop hl ret ; 37e19 PlayDamageAnim: ; 37e19 xor a ld [FXAnimID + 1], a ld a, BATTLE_VARS_MOVE_ANIM call GetBattleVar and a ret z ld [FXAnimID], a ld a, [hBattleTurn] and a ld a, BATTLEANIM_ENEMY_DAMAGE jr z, .player ld a, BATTLEANIM_PLAYER_DAMAGE .player ld [wNumHits], a jp PlayUserBattleAnim ; 37e36 LoadMoveAnim: ; 37e36 xor a ld [wNumHits], a ld [FXAnimID + 1], a ld a, BATTLE_VARS_MOVE_ANIM call GetBattleVar and a ret z ; fallthrough ; 37e44 LoadAnim: ; 37e44 ld [FXAnimID], a ; fallthrough ; 37e47 PlayUserBattleAnim: ; 37e47 push hl push de push bc callfar PlayBattleAnim pop bc pop de pop hl ret ; 37e54 PlayOpponentBattleAnim: ; 37e54 ld a, e ld [FXAnimID], a ld a, d ld [FXAnimID + 1], a xor a ld [wNumHits], a push hl push de push bc call BattleCommand_SwitchTurn callfar PlayBattleAnim call BattleCommand_SwitchTurn pop bc pop de pop hl ret ; 37e73 CallBattleCore: ; 37e73 ld a, BANK(BattleCore) rst FarCall ret ; 37e77 AnimateFailedMove: ; 37e77 call BattleCommand_LowerSub call BattleCommand_MoveDelay jp BattleCommand_RaiseSub ; 37e80 BattleCommand_MoveDelay: ; 37e80 ; movedelay ; Wait 40 frames. ld c, 40 jp DelayFrames ; 37e85 BattleCommand_ClearText: ; 37e85 ; cleartext ; Used in multi-hit moves. ld hl, .text jp BattleTextBox .text db "@" ; 37e8c SkipToBattleCommand: ; 37e8c ; Skip over commands until reaching command b. ld a, [BattleScriptBufferAddress + 1] ld h, a ld a, [BattleScriptBufferAddress] ld l, a .loop ld a, [hli] cp b jr nz, .loop ld a, h ld [BattleScriptBufferAddress + 1], a ld a, l ld [BattleScriptBufferAddress], a ret ; 37ea1 GetMoveAttr: ; 37ea1 ; Assuming hl = Moves + x, return attribute x of move a. push bc ld bc, MOVE_LENGTH call AddNTimes call GetMoveByte pop bc ret ; 37ead GetMoveData: ; 37ead ; Copy move struct a to de. ld hl, Moves ld bc, MOVE_LENGTH call AddNTimes ld a, Bank(Moves) jp FarCopyBytes ; 37ebb GetMoveByte: ; 37ebb ld a, BANK(Moves) jp GetFarByte ; 37ec0 DisappearUser: ; 37ec0 farcall _DisappearUser ret ; 37ec7 AppearUserLowerSub: ; 37ec7 farcall _AppearUserLowerSub ret ; 37ece AppearUserRaiseSub: ; 37ece farcall _AppearUserRaiseSub ret ; 37ed5 _CheckBattleScene: ; 37ed5 ; Checks the options. Returns carry if battle animations are disabled. push hl push de push bc farcall CheckBattleScene pop bc pop de pop hl ret ; 37ee2