diff options
60 files changed, 2581 insertions, 2574 deletions
diff --git a/docs/bugs_and_glitches.md b/docs/bugs_and_glitches.md index 31d642464..3755fa1a7 100644 --- a/docs/bugs_and_glitches.md +++ b/docs/bugs_and_glitches.md @@ -155,7 +155,7 @@ This is a bug with `DittoMetalPowder` in [engine/battle/effect_commands.asm](/en ([Video](https://www.youtube.com/watch?v=zuCLMikWo4Y)) -This is a bug with `BattleCommand_BellyDrum` in [engine/battle/effect_commands.asm](/engine/battle/effect_commands.asm): +This is a bug with `BattleCommand_BellyDrum` in [engine/battle/move_effects/belly_drum.asm](/engine/battle/move_effects/belly_drum.asm): ```asm BattleCommand_BellyDrum: ; 37c1a @@ -307,7 +307,7 @@ CheckHiddenOpponent: ; 37daa ([Video](https://www.youtube.com/watch?v=202-iAsrIa8)) -This is a bug with `BattleCommand_BeatUp` in [engine/battle/effect_commands.asm](/engine/battle/effect_commands.asm): +This is a bug with `BattleCommand_BeatUp` in [engine/battle/move_effects/beat_up.asm](/engine/battle/move_effects/beat_up.asm): ```asm .got_mon @@ -346,7 +346,7 @@ This is a bug with `BattleCommand_BeatUp` in [engine/battle/effect_commands.asm] This bug existed for all battles in Gold and Silver, and was only fixed for single-player battles in Crystal to preserve link compatibility. -This is a bug with `BattleCommand_Present` in [engine/battle/effect_commands/present.asm](/engine/battle/effect_commands/present.asm): +This is a bug with `BattleCommand_Present` in [engine/battle/move_effects/present.asm](/engine/battle/move_effects/present.asm): ```asm BattleCommand_Present: ; 37874 diff --git a/engine/battle/effect_commands.asm b/engine/battle/effect_commands.asm index 604d9f2d9..53c8438e5 100644 --- a/engine/battle/effect_commands.asm +++ b/engine/battle/effect_commands.asm @@ -1306,45 +1306,7 @@ INCLUDE "data/battle/critical_hits.asm" ; 346b2 -BattleCommand_TripleKick: ; 346b2 -; triplekick - - ld a, [wKickCounter] - ld b, a - inc b - ld hl, CurDamage + 1 - ld a, [hld] - ld e, a - ld a, [hli] - ld d, a -.next_kick - dec b - ret z - ld a, [hl] - add e - ld [hld], a - ld a, [hl] - adc d - ld [hli], a - -; No overflow. - jr nc, .next_kick - ld a, $ff - ld [hld], a - ld [hl], a - ret - -; 346cd - - -BattleCommand_KickCounter: ; 346cd -; kickcounter - - ld hl, wKickCounter - inc [hl] - ret - -; 346d2 +INCLUDE "engine/battle/move_effects/triple_kick.asm" BattleCommand_Stab: ; 346d2 @@ -1637,10 +1599,12 @@ BattleCommand_ResetTypeMatchup: ; 34833 ; 3484e + INCLUDE "engine/battle/ai/switch.asm" INCLUDE "data/types/type_matchups.asm" + BattleCommand_DamageVariation: ; 34cfd ; damagevariation @@ -2144,20 +2108,19 @@ BattleCommand_HitTargetNoSub: ; 34f60 ld a, BATTLE_VARS_MOVE_EFFECT call GetBattleVar cp EFFECT_MULTI_HIT - jr z, .multihit + jr z, .alternate_anim cp EFFECT_CONVERSION - jr z, .conversion + jr z, .alternate_anim cp EFFECT_DOUBLE_HIT - jr z, .doublehit + jr z, .alternate_anim cp EFFECT_POISON_MULTI_HIT - jr z, .twineedle + jr z, .alternate_anim cp EFFECT_TRIPLE_KICK jr z, .triplekick xor a ld [wKickCounter], a .triplekick - ld a, BATTLE_VARS_MOVE_ANIM call GetBattleVar ld e, a @@ -2167,18 +2130,13 @@ BattleCommand_HitTargetNoSub: ; 34f60 ld a, BATTLE_VARS_MOVE_ANIM call GetBattleVar cp FLY - jr z, .fly_dig + jr z, .clear_sprite cp DIG ret nz - -.fly_dig -; clear sprite +.clear_sprite jp AppearUserLowerSub -.multihit -.conversion -.doublehit -.twineedle +.alternate_anim ld a, [wKickCounter] and 1 xor 1 @@ -3136,225 +3094,7 @@ EnemyAttackDamage: ; 353f6 ; 35461 -BattleCommand_BeatUp: ; 35461 -; beatup - - call ResetDamage - ld a, [hBattleTurn] - and a - jp nz, .enemy_beats_up - ld a, [PlayerSubStatus3] - bit SUBSTATUS_IN_LOOP, a - jr nz, .next_mon - ld c, 20 - call DelayFrames - xor a - ld [PlayerRolloutCount], a - ld [wd002], a - ld [wBeatUpHitAtLeastOnce], a - jr .got_mon - -.next_mon - ld a, [PlayerRolloutCount] - ld b, a - ld a, [PartyCount] - sub b - ld [wd002], a - -.got_mon - ld a, [wd002] - ld hl, PartyMonNicknames - call GetNick - ld a, MON_HP - call GetBeatupMonLocation - ld a, [hli] - or [hl] - jp z, .beatup_fail ; fainted - ld a, [wd002] - ld c, a - ld a, [CurBattleMon] - ; BUG: this can desynchronize link battles - ; Change "cp [hl]" to "cp c" to fix - cp [hl] - ld hl, BattleMonStatus - jr z, .active_mon - ld a, MON_STATUS - call GetBeatupMonLocation -.active_mon - ld a, [hl] - and a - jp nz, .beatup_fail - - ld a, $1 - ld [wBeatUpHitAtLeastOnce], a - ld hl, BeatUpAttackText - call StdBattleTextBox - ld a, [EnemyMonSpecies] - ld [CurSpecies], a - call GetBaseData - ld a, [BaseDefense] - ld c, a - push bc - ld a, MON_SPECIES - call GetBeatupMonLocation - ld a, [hl] - ld [CurSpecies], a - call GetBaseData - ld a, [BaseAttack] - pop bc - ld b, a - push bc - ld a, MON_LEVEL - call GetBeatupMonLocation - ld a, [hl] - ld e, a - pop bc - ld a, [wPlayerMoveStructPower] - ld d, a - ret - -.enemy_beats_up - ld a, [EnemySubStatus3] - bit SUBSTATUS_IN_LOOP, a - jr nz, .not_first_enemy_beatup - - xor a - ld [EnemyRolloutCount], a - ld [wd002], a - ld [wBeatUpHitAtLeastOnce], a - jr .enemy_continue - -.not_first_enemy_beatup - ld a, [EnemyRolloutCount] - ld b, a - ld a, [OTPartyCount] - sub b - ld [wd002], a -.enemy_continue - ld a, [wBattleMode] - dec a - jr z, .wild - - ld a, [wLinkMode] - and a - jr nz, .link_or_tower - - ld a, [InBattleTowerBattle] - and a - jr nz, .link_or_tower - - ld a, [wd002] - ld c, a - ld b, 0 - ld hl, OTPartySpecies - add hl, bc - ld a, [hl] - ld [wNamedObjectIndexBuffer], a - call GetPokemonName - jr .got_enemy_nick - -.link_or_tower - ld a, [wd002] - ld hl, OTPartyMonNicknames - ld bc, NAME_LENGTH - call AddNTimes - ld de, StringBuffer1 - call CopyBytes -.got_enemy_nick - ld a, MON_HP - call GetBeatupMonLocation - ld a, [hli] - or [hl] - jp z, .beatup_fail - ld a, [wd002] - ld b, a - ld a, [CurOTMon] - cp b - ld hl, EnemyMonStatus - jr z, .active_enemy - - ld a, MON_STATUS - call GetBeatupMonLocation -.active_enemy - ld a, [hl] - and a - jr nz, .beatup_fail - - ld a, $1 - ld [wBeatUpHitAtLeastOnce], a - jr .finish_beatup - -.wild - ld a, [EnemyMonSpecies] - ld [wNamedObjectIndexBuffer], a - call GetPokemonName - ld hl, BeatUpAttackText - call StdBattleTextBox - jp EnemyAttackDamage - -.finish_beatup - ld hl, BeatUpAttackText - call StdBattleTextBox - ld a, [BattleMonSpecies] - ld [CurSpecies], a - call GetBaseData - ld a, [BaseDefense] - ld c, a - push bc - ld a, MON_SPECIES - call GetBeatupMonLocation - ld a, [hl] - ld [CurSpecies], a - call GetBaseData - ld a, [BaseAttack] - pop bc - ld b, a - push bc - ld a, MON_LEVEL - call GetBeatupMonLocation - ld a, [hl] - ld e, a - pop bc - ld a, [wEnemyMoveStructPower] - ld d, a - ret - -; 355b0 - - -.beatup_fail ; 355b0 - ld b, buildopponentrage_command - jp SkipToBattleCommand - -; 355b5 - - -BattleCommanda8: ; 355b5 - ld a, [wBeatUpHitAtLeastOnce] - and a - ret nz - - jp PrintButItFailed - -; 355bd - - -GetBeatupMonLocation: ; 355bd - push bc - ld c, a - ld b, 0 - ld a, [hBattleTurn] - and a - ld hl, PartyMon1Species - jr z, .got_species - ld hl, OTPartyMon1Species - -.got_species - ld a, [wd002] - add hl, bc - call GetPartyLocation - pop bc - ret +INCLUDE "engine/battle/move_effects/beat_up.asm" BattleCommand_ClearMissDamage: ; 355d5 @@ -3691,7 +3431,7 @@ BattleCommand_ConstantDamage: ; 35726 cp b jr nc, .psywave_loop ld b, a - ld a, $0 + ld a, 0 jr .got_power .super_fang @@ -3712,9 +3452,9 @@ BattleCommand_ConstantDamage: ; 35726 and a jr nz, .got_power or b - ld a, $0 + ld a, 0 jr nz, .got_power - ld b, $1 + ld b, 1 jr .got_power .got_power @@ -3806,518 +3546,19 @@ BattleCommand_ConstantDamage: ; 35726 INCLUDE "data/moves/flail_reversal_power.asm" -BattleCommand_Counter: ; 35813 -; counter - - 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_COUNTER - 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 + MOVE_POWER] - and a - ret z - - ld a, [StringBuffer1 + MOVE_TYPE] - cp SPECIAL - ret nc - - 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 - -; 35864 - - -BattleCommand_Encore: ; 35864 -; encore - - ld hl, EnemyMonMoves - ld de, EnemyEncoreCount - ld a, [hBattleTurn] - and a - jr z, .ok - ld hl, BattleMonMoves - ld de, PlayerEncoreCount -.ok - ld a, BATTLE_VARS_LAST_MOVE_OPP - call GetBattleVar - and a - jp z, .failed - cp STRUGGLE - jp z, .failed - cp ENCORE - jp z, .failed - cp MIRROR_MOVE - jp z, .failed - ld b, a - -.got_move - ld a, [hli] - cp b - jr nz, .got_move - - ld bc, BattleMonPP - BattleMonMoves - 1 - add hl, bc - ld a, [hl] - and PP_MASK - jp z, .failed - ld a, [AttackMissed] - and a - jp nz, .failed - ld a, BATTLE_VARS_SUBSTATUS5_OPP - call GetBattleVarAddr - bit SUBSTATUS_ENCORED, [hl] - jp nz, .failed - set SUBSTATUS_ENCORED, [hl] - call BattleRandom - and $3 - inc a - inc a - inc a - ld [de], a - call CheckOpponentWentFirst - jr nz, .finish_move - ld a, [hBattleTurn] - and a - jr z, .force_last_enemy_move - - push hl - ld a, [LastPlayerMove] - ld b, a - ld c, 0 - ld hl, BattleMonMoves -.find_player_move - ld a, [hli] - cp b - jr z, .got_player_move - inc c - ld a, c - cp NUM_MOVES - jr c, .find_player_move - pop hl - res SUBSTATUS_ENCORED, [hl] - xor a - ld [de], a - jr .failed - -.got_player_move - pop hl - ld a, c - ld [CurMoveNum], a - ld a, b - ld [CurPlayerMove], a - dec a - ld de, wPlayerMoveStruct - call GetMoveData - jr .finish_move - -.force_last_enemy_move - push hl - ld a, [LastEnemyMove] - ld b, a - ld c, 0 - ld hl, EnemyMonMoves -.find_enemy_move - ld a, [hli] - cp b - jr z, .got_enemy_move - inc c - ld a, c - cp NUM_MOVES - jr c, .find_enemy_move - pop hl - res SUBSTATUS_ENCORED, [hl] - xor a - ld [de], a - jr .failed - -.got_enemy_move - pop hl - ld a, c - ld [CurEnemyMoveNum], a - ld a, b - ld [CurEnemyMove], a - dec a - ld de, wEnemyMoveStruct - call GetMoveData - -.finish_move - call AnimateCurrentMove - ld hl, GotAnEncoreText - jp StdBattleTextBox - -.failed - jp PrintDidntAffect2 - -; 35926 - - -BattleCommand_PainSplit: ; 35926 -; painsplit - - ld a, [AttackMissed] - and a - jp nz, .ButItFailed - call CheckSubstituteOpp - jp nz, .ButItFailed - call AnimateCurrentMove - ld hl, BattleMonMaxHP + 1 - ld de, EnemyMonMaxHP + 1 - call .PlayerShareHP - ld a, $1 - ld [wWhichHPBar], a - hlcoord 10, 9 - predef AnimateHPBar - ld hl, EnemyMonHP - ld a, [hli] - ld [Buffer4], a - ld a, [hli] - ld [Buffer3], a - ld a, [hli] - ld [Buffer2], a - ld a, [hl] - ld [Buffer1], a - call .EnemyShareHP - xor a - ld [wWhichHPBar], a - call ResetDamage - hlcoord 2, 2 - predef AnimateHPBar - farcall _UpdateBattleHUDs - - ld hl, SharedPainText - jp StdBattleTextBox - -.PlayerShareHP: - ld a, [hld] - ld [Buffer1], a - ld a, [hld] - ld [Buffer2], a - ld a, [hld] - ld b, a - ld [Buffer3], a - ld a, [hl] - ld [Buffer4], a - dec de - dec de - ld a, [de] - dec de - add b - ld [CurDamage + 1], a - ld b, [hl] - ld a, [de] - adc b - srl a - ld [CurDamage], a - ld a, [CurDamage + 1] - rr a - ld [CurDamage + 1], a - inc hl - inc hl - inc hl - inc de - inc de - inc de - -.EnemyShareHP: ; 359ac - ld c, [hl] - dec hl - ld a, [CurDamage + 1] - sub c - ld b, [hl] - dec hl - ld a, [CurDamage] - sbc b - jr nc, .skip - - ld a, [CurDamage] - ld b, a - ld a, [CurDamage + 1] - ld c, a -.skip - ld a, c - ld [hld], a - ld [Buffer5], a - ld a, b - ld [hli], a - ld [Buffer6], a - ret - -; 359cd - -.ButItFailed: - jp PrintDidntAffect2 - -; 359d0 - - -BattleCommand_Snore: ; 359d0 -; snore - ld a, BATTLE_VARS_STATUS - call GetBattleVar - and SLP - ret nz - call ResetDamage - ld a, $1 - ld [AttackMissed], a - call FailSnore - jp EndMoveEffect - -; 359e6 +INCLUDE "engine/battle/move_effects/counter.asm" +INCLUDE "engine/battle/move_effects/encore.asm" -BattleCommand_Conversion2: ; 359e6 -; conversion2 +INCLUDE "engine/battle/move_effects/pain_split.asm" - ld a, [AttackMissed] - and a - jr nz, .failed - ld hl, BattleMonType1 - ld a, [hBattleTurn] - and a - jr z, .got_type - ld hl, EnemyMonType1 -.got_type - ld a, BATTLE_VARS_LAST_COUNTER_MOVE_OPP - call GetBattleVar - and a - jr z, .failed - push hl - dec a - ld hl, Moves + MOVE_TYPE - call GetMoveAttr - ld d, a - pop hl - cp CURSE_T - jr z, .failed - call AnimateCurrentMove - call BattleCommand_SwitchTurn +INCLUDE "engine/battle/move_effects/snore.asm" -.loop - call BattleRandom - and $1f - cp UNUSED_TYPES - jr c, .okay - cp UNUSED_TYPES_END - jr c, .loop - cp TYPES_END - jr nc, .loop -.okay - ld [hli], a - ld [hld], a - push hl - ld a, BATTLE_VARS_MOVE_TYPE - call GetBattleVarAddr - push af - push hl - ld a, d - ld [hl], a - call BattleCheckTypeMatchup - pop hl - pop af - ld [hl], a - pop hl - ld a, [wTypeMatchup] - cp 10 - jr nc, .loop - call BattleCommand_SwitchTurn +INCLUDE "engine/battle/move_effects/conversion2.asm" - ld a, [hl] - ld [wNamedObjectIndexBuffer], a - predef GetTypeName - ld hl, TransformedTypeText - jp StdBattleTextBox +INCLUDE "engine/battle/move_effects/lock_on.asm" -.failed - jp FailConversion2 - -; 35a53 - - -BattleCommand_LockOn: ; 35a53 -; lockon - - call CheckSubstituteOpp - jr nz, .fail - - ld a, [AttackMissed] - and a - jr nz, .fail - - ld a, BATTLE_VARS_SUBSTATUS5_OPP - call GetBattleVarAddr - set SUBSTATUS_LOCK_ON, [hl] - call AnimateCurrentMove - - ld hl, TookAimText - jp StdBattleTextBox - -.fail - call AnimateFailedMove - jp PrintDidntAffect - -; 35a74 - - -BattleCommand_Sketch: ; 35a74 -; sketch - - call ClearLastMove -; Don't sketch during a link battle - ld a, [wLinkMode] - and a - jr z, .not_linked - call AnimateFailedMove - jp PrintNothingHappened - -.not_linked -; If the opponent has a substitute up, fail. - call CheckSubstituteOpp - jp nz, .fail -; If the opponent is transformed, fail. - ld a, BATTLE_VARS_SUBSTATUS5_OPP - call GetBattleVarAddr - bit SUBSTATUS_TRANSFORMED, [hl] - jp nz, .fail -; Get the user's moveset in its party struct. -; This move replacement shall be permanent. -; Pointer will be in de. - ld a, MON_MOVES - call UserPartyAttr - ld d, h - ld e, l -; Get the battle move structs. - ld hl, BattleMonMoves - ld a, [hBattleTurn] - and a - jr z, .get_last_move - ld hl, EnemyMonMoves -.get_last_move - ld a, BATTLE_VARS_LAST_COUNTER_MOVE_OPP - call GetBattleVar - ld [wTypeMatchup], a - ld b, a -; Fail if move is invalid or is Struggle. - and a - jr z, .fail - cp STRUGGLE - jr z, .fail -; Fail if user already knows that move - ld c, NUM_MOVES -.does_user_already_know_move - ld a, [hli] - cp b - jr z, .fail - dec c - jr nz, .does_user_already_know_move -; Find Sketch in the user's moveset. -; Pointer in hl, and index in c. - dec hl - ld c, NUM_MOVES -.find_sketch - dec c - ld a, [hld] - cp SKETCH - jr nz, .find_sketch - inc hl -; The Sketched move is loaded to that slot. - ld a, b - ld [hl], a -; Copy the base PP from that move. - push bc - push hl - dec a - ld hl, Moves + MOVE_PP - call GetMoveAttr - pop hl - ld bc, BattleMonPP - BattleMonMoves - add hl, bc - ld [hl], a - pop bc - - ld a, [hBattleTurn] - and a - jr z, .user_trainer - ld a, [wBattleMode] - dec a - jr nz, .user_trainer -; wildmon - ld a, [hl] - push bc - ld hl, wWildMonPP - ld b, 0 - add hl, bc - ld [hl], a - ld hl, wWildMonMoves - add hl, bc - pop bc - ld [hl], b - jr .done_copy - -.user_trainer - ld a, [hl] - push af - ld l, c - ld h, 0 - add hl, de - ld a, b - ld [hl], a - pop af - ld de, MON_PP - MON_MOVES - add hl, de - ld [hl], a -.done_copy - call GetMoveName - call AnimateCurrentMove - - ld hl, SketchedText - jp StdBattleTextBox - -.fail - call AnimateFailedMove - jp PrintDidntAffect - -; 35b16 +INCLUDE "engine/battle/move_effects/sketch.asm" BattleCommand_DefrostOpponent: ; 35b16 @@ -4349,338 +3590,15 @@ BattleCommand_DefrostOpponent: ; 35b16 ; 35b33 -BattleCommand_SleepTalk: ; 35b33 -; sleeptalk - - call ClearLastMove - ld a, [AttackMissed] - and a - jr nz, .fail - ld a, [hBattleTurn] - and a - ld hl, BattleMonMoves + 1 - ld a, [DisabledMove] - ld d, a - jr z, .got_moves - ld hl, EnemyMonMoves + 1 - ld a, [EnemyDisabledMove] - ld d, a -.got_moves - ld a, BATTLE_VARS_STATUS - call GetBattleVar - and SLP - jr z, .fail - ld a, [hl] - and a - jr z, .fail - call .safely_check_has_usable_move - jr c, .fail - dec hl -.sample_move - push hl - call BattleRandom - maskbits NUM_MOVES - ld c, a - ld b, 0 - add hl, bc - ld a, [hl] - pop hl - and a - jr z, .sample_move - ld e, a - ld a, BATTLE_VARS_MOVE_ANIM - call GetBattleVar - cp e - jr z, .sample_move - ld a, e - cp d - jr z, .sample_move - call .check_two_turn_move - jr z, .sample_move - ld a, BATTLE_VARS_MOVE - call GetBattleVarAddr - ld a, e - ld [hl], a - call CheckUserIsCharging - jr nz, .charging - ld a, [wKickCounter] - push af - call BattleCommand_LowerSub - pop af - ld [wKickCounter], a -.charging - call LoadMoveAnim - call UpdateMoveData - jp ResetTurn - -.fail - call AnimateFailedMove - jp TryPrintButItFailed - -.safely_check_has_usable_move - push hl - push de - push bc - call .check_has_usable_move - pop bc - pop de - pop hl - ret - -.check_has_usable_move - ld a, [hBattleTurn] - and a - ld a, [DisabledMove] - jr z, .got_move_2 - - ld a, [EnemyDisabledMove] -.got_move_2 - ld b, a - ld a, BATTLE_VARS_MOVE - call GetBattleVar - ld c, a - dec hl - ld d, NUM_MOVES -.loop2 - ld a, [hl] - and a - jr z, .carry - - cp c - jr z, .nope - cp b - jr z, .nope - - call .check_two_turn_move - jr nz, .no_carry - -.nope - inc hl - dec d - jr nz, .loop2 - -.carry - scf - ret - -.no_carry - and a - ret - -.check_two_turn_move - push hl - push de - push bc - - ld b, a - callfar GetMoveEffect - ld a, b +INCLUDE "engine/battle/move_effects/sleep_talk.asm" - pop bc - pop de - pop hl +INCLUDE "engine/battle/move_effects/destiny_bond.asm" - cp EFFECT_SKULL_BASH - ret z - cp EFFECT_RAZOR_WIND - ret z - cp EFFECT_SKY_ATTACK - ret z - cp EFFECT_SOLARBEAM - ret z - cp EFFECT_FLY - ret z - cp EFFECT_BIDE - ret +INCLUDE "engine/battle/move_effects/spite.asm" -; 35bff +INCLUDE "engine/battle/move_effects/false_swipe.asm" - -BattleCommand_DestinyBond: ; 35bff -; destinybond - - ld a, BATTLE_VARS_SUBSTATUS5 - call GetBattleVarAddr - set SUBSTATUS_DESTINY_BOND, [hl] - call AnimateCurrentMove - ld hl, DestinyBondEffectText - jp StdBattleTextBox - -; 35c0f - - -BattleCommand_Spite: ; 35c0f -; spite - - ld a, [AttackMissed] - and a - jp nz, .failed - ld bc, PARTYMON_STRUCT_LENGTH ; ???? - ld hl, EnemyMonMoves - ld a, [hBattleTurn] - and a - jr z, .got_moves - ld hl, BattleMonMoves -.got_moves - ld a, BATTLE_VARS_LAST_COUNTER_MOVE_OPP - call GetBattleVar - and a - jr z, .failed - cp STRUGGLE - jr z, .failed - ld b, a - ld c, -1 -.loop - inc c - ld a, [hli] - cp b - jr nz, .loop - ld [wTypeMatchup], a - dec hl - ld b, 0 - push bc - ld c, BattleMonPP - BattleMonMoves - add hl, bc - pop bc - ld a, [hl] - and PP_MASK - jr z, .failed - push bc - call GetMoveName - ; lose 2-5 PP - call BattleRandom - and %11 - inc a - inc a - ld b, a - ld a, [hl] - and PP_MASK - cp b - jr nc, .deplete_pp - ld b, a -.deplete_pp - ld a, [hl] - sub b - ld [hl], a - push af - ld a, MON_PP - call OpponentPartyAttr - ld d, b - pop af - pop bc - add hl, bc - ld e, a - ld a, BATTLE_VARS_SUBSTATUS5_OPP - call GetBattleVar - bit SUBSTATUS_TRANSFORMED, a - jr nz, .transformed - ld a, [hBattleTurn] - and a - jr nz, .not_wildmon - ld a, [wBattleMode] - dec a - jr nz, .not_wildmon - ld hl, wWildMonPP - add hl, bc -.not_wildmon - ld [hl], e -.transformed - push de - call AnimateCurrentMove - pop de - ld a, d - ld [wTypeMatchup], a - ld hl, SpiteEffectText - jp StdBattleTextBox - -.failed - jp PrintDidntAffect2 - -; 35c94 - - -BattleCommand_FalseSwipe: ; 35c94 -; falseswipe - - ld hl, EnemyMonHP - ld a, [hBattleTurn] - and a - jr z, .got_hp - ld hl, BattleMonHP -.got_hp - ld de, CurDamage - ld c, 2 - push hl - push de - call StringCmp - pop de - pop hl - jr c, .done - ld a, [hli] - ld [de], a - inc de - ld a, [hl] - dec a - ld [de], a - inc a - jr nz, .okay - dec de - ld a, [de] - dec a - ld [de], a -.okay - ld a, [CriticalHit] - cp 2 - jr nz, .carry - xor a - ld [CriticalHit], a -.carry - scf - ret - -.done - and a - ret - -; 35cc9 - - -BattleCommand_HealBell: ; 35cc9 -; healbell - - ld a, BATTLE_VARS_SUBSTATUS1 - call GetBattleVarAddr - res SUBSTATUS_NIGHTMARE, [hl] - ld de, PartyMon1Status - ld a, [hBattleTurn] - and a - jr z, .got_status - ld de, OTPartyMon1Status -.got_status - ld a, BATTLE_VARS_STATUS - call GetBattleVarAddr - xor a - ld [hl], a - ld h, d - ld l, e - ld bc, PARTYMON_STRUCT_LENGTH - ld d, PARTY_LENGTH -.loop - ld [hl], a - add hl, bc - dec d - jr nz, .loop - call AnimateCurrentMove - - ld hl, BellChimedText - call StdBattleTextBox - - ld a, [hBattleTurn] - and a - jp z, CalcPlayerStats - jp CalcEnemyStats - -; 35d00 +INCLUDE "engine/battle/move_effects/heal_bell.asm" FarPlayBattleAnimation: ; 35d00 @@ -6377,111 +5295,7 @@ CalcStats: ; 3661d ; 36671 -BattleCommand_StoreEnergy: ; 36671 -; storeenergy - - ld a, BATTLE_VARS_SUBSTATUS3 - call GetBattleVar - bit SUBSTATUS_BIDE, a - ret z - - ld hl, PlayerRolloutCount - ld a, [hBattleTurn] - and a - jr z, .check_still_storing_energy - ld hl, EnemyRolloutCount -.check_still_storing_energy - dec [hl] - jr nz, .still_storing - - ld a, BATTLE_VARS_SUBSTATUS3 - call GetBattleVarAddr - res SUBSTATUS_BIDE, [hl] - - ld hl, UnleashedEnergyText - call StdBattleTextBox - - ld a, BATTLE_VARS_MOVE_POWER - call GetBattleVarAddr - ld a, 1 - ld [hl], a - ld hl, PlayerDamageTaken + 1 - ld de, wPlayerCharging ; player - ld a, [hBattleTurn] - and a - jr z, .player - ld hl, EnemyDamageTaken + 1 - ld de, wEnemyCharging ; enemy -.player - ld a, [hld] - add a - ld b, a - ld [CurDamage + 1], a - ld a, [hl] - rl a - ld [CurDamage], a - jr nc, .not_maxed - ld a, $ff - ld [CurDamage], a - ld [CurDamage + 1], a -.not_maxed - or b - jr nz, .built_up_something - ld a, 1 - ld [AttackMissed], a -.built_up_something - xor a - ld [hli], a - ld [hl], a - ld [de], a - - ld a, BATTLE_VARS_MOVE_ANIM - call GetBattleVarAddr - ld a, BIDE - ld [hl], a - - ld b, unleashenergy_command - jp SkipToBattleCommand - -.still_storing - ld hl, StoringEnergyText - call StdBattleTextBox - jp EndMoveEffect - -; 366e5 - - -BattleCommand_UnleashEnergy: ; 366e5 -; unleashenergy - - ld de, PlayerDamageTaken - ld bc, PlayerRolloutCount - ld a, [hBattleTurn] - and a - jr z, .got_damage - ld de, EnemyDamageTaken - ld bc, EnemyRolloutCount -.got_damage - ld a, BATTLE_VARS_SUBSTATUS3 - call GetBattleVarAddr - set SUBSTATUS_BIDE, [hl] - xor a - ld [de], a - inc de - ld [de], a - ld [wPlayerMoveStructEffect], a - ld [wEnemyMoveStructEffect], a - call BattleRandom - and 1 - inc a - inc a - ld [bc], a - ld a, 1 - ld [wKickCounter], a - call AnimateCurrentMove - jp EndMoveEffect - -; 3671a +INCLUDE "engine/battle/move_effects/bide.asm" BattleCommand_CheckRampage: ; 3671a @@ -6554,97 +5368,7 @@ BattleCommand_Rampage: ; 36751 ; 36778 -BattleCommand_Teleport: ; 36778 -; teleport - - ld a, [BattleType] - cp BATTLETYPE_SHINY - jr z, .failed - cp BATTLETYPE_TRAP - jr z, .failed - cp BATTLETYPE_CELEBI - jr z, .failed - cp BATTLETYPE_SUICUNE - jr z, .failed - - ld a, BATTLE_VARS_SUBSTATUS5_OPP - call GetBattleVar - bit SUBSTATUS_CANT_RUN, a - jr nz, .failed -; Only need to check these next things if it's your turn - ld a, [hBattleTurn] - and a - jr nz, .enemy_turn -; Can't teleport from a trainer battle - ld a, [wBattleMode] - dec a - jr nz, .failed -; If your level is greater than the opponent's, you run without fail. - ld a, [CurPartyLevel] - ld b, a - ld a, [BattleMonLevel] - cp b - jr nc, .run_away -; Generate a number between 0 and (YourLevel + TheirLevel). - add b - ld c, a - inc c -.loop_player - call BattleRandom - cp c - jr nc, .loop_player -; If that number is greater than 4 times your level, run away. - srl b - srl b - cp b - jr nc, .run_away - -.failed - call AnimateFailedMove - jp PrintButItFailed - -.enemy_turn - ld a, [wBattleMode] - dec a - jr nz, .failed - ld a, [BattleMonLevel] - ld b, a - ld a, [CurPartyLevel] - cp b - jr nc, .run_away - add b - ld c, a - inc c -.loop_enemy - call BattleRandom - cp c - jr nc, .loop_enemy - srl b - srl b - cp b - ; This does the wrong thing. What was - ; probably intended was jr c, .failed - ; The way this is made makes enemy use - ; of Teleport always succeed if able - jr nc, .run_away -.run_away - call UpdateBattleMonInParty - xor a - ld [wNumHits], a - inc a - ld [wForcedSwitch], a - ld [wKickCounter], a - call SetBattleDraw - call BattleCommand_LowerSub - call LoadMoveAnim - ld c, 20 - call DelayFrames - call SetBattleDraw - - ld hl, FledFromBattleText - jp StdBattleTextBox - -; 36804 +INCLUDE "engine/battle/move_effects/teleport.asm" SetBattleDraw: ; 36804 @@ -7420,42 +6144,9 @@ BattleCommand_TrapTarget: ; 36c2d ; 36c7e -BattleCommand_Mist: ; 36c7e -; mist - - ld a, BATTLE_VARS_SUBSTATUS4 - call GetBattleVarAddr - bit SUBSTATUS_MIST, [hl] - jr nz, .already_mist - set SUBSTATUS_MIST, [hl] - call AnimateCurrentMove - ld hl, MistText - jp StdBattleTextBox - -.already_mist - call AnimateFailedMove - jp PrintButItFailed - -; 36c98 +INCLUDE "engine/battle/move_effects/mist.asm" - -BattleCommand_FocusEnergy: ; 36c98 -; focusenergy - - ld a, BATTLE_VARS_SUBSTATUS4 - call GetBattleVarAddr - bit SUBSTATUS_FOCUS_ENERGY, [hl] - jr nz, .already_pumped - set SUBSTATUS_FOCUS_ENERGY, [hl] - call AnimateCurrentMove - ld hl, GettingPumpedText - jp StdBattleTextBox - -.already_pumped - call AnimateFailedMove - jp PrintButItFailed - -; 36cb2 +INCLUDE "engine/battle/move_effects/focus_energy.asm" BattleCommand_Recoil: ; 36cb2 @@ -7755,96 +6446,8 @@ CheckMoveTypeMatchesTarget: ; 36e5b ; 36e7c -BattleCommand_Substitute: ; 36e7c -; substitute - - call BattleCommand_MoveDelay - ld hl, BattleMonMaxHP - ld de, PlayerSubstituteHP - ld a, [hBattleTurn] - and a - jr z, .got_hp - ld hl, EnemyMonMaxHP - ld de, EnemySubstituteHP -.got_hp - - ld a, BATTLE_VARS_SUBSTATUS4 - call GetBattleVar - bit SUBSTATUS_SUBSTITUTE, a - jr nz, .already_has_sub - - ld a, [hli] - ld b, [hl] - srl a - rr b - srl a - rr b - dec hl - dec hl - ld a, b - ld [de], a - ld a, [hld] - sub b - ld e, a - ld a, [hl] - sbc 0 - ld d, a - jr c, .too_weak_to_sub - ld a, d - or e - jr z, .too_weak_to_sub - ld [hl], d - inc hl - ld [hl], e - - ld a, BATTLE_VARS_SUBSTATUS4 - call GetBattleVarAddr - set SUBSTATUS_SUBSTITUTE, [hl] - - ld hl, wPlayerWrapCount - ld de, wPlayerTrappingMove - ld a, [hBattleTurn] - and a - jr z, .player - ld hl, wEnemyWrapCount - ld de, wEnemyTrappingMove -.player - - xor a - ld [hl], a - ld [de], a - call _CheckBattleScene - jr c, .no_anim - - xor a - ld [wNumHits], a - ld [FXAnimID + 1], a - ld [wKickCounter], a - ld a, SUBSTITUTE - call LoadAnim - jr .finish - -.no_anim - call BattleCommand_RaiseSubNoAnim -.finish - ld hl, MadeSubstituteText - call StdBattleTextBox - jp RefreshBattleHuds - -.already_has_sub - call CheckUserIsCharging - call nz, BattleCommand_RaiseSub - ld hl, HasSubstituteText - jr .jp_stdbattletextbox - -.too_weak_to_sub - call CheckUserIsCharging - call nz, BattleCommand_RaiseSub - ld hl, TooWeakSubText -.jp_stdbattletextbox - jp StdBattleTextBox +INCLUDE "engine/battle/move_effects/substitute.asm" -; 36f0b BattleCommand_RechargeNextTurn: ; 36f0b ; rechargenextturn @@ -7867,14 +6470,7 @@ EndRechargeOpp: ; 36f13 ; 36f1d -BattleCommand_Rage: ; 36f1d -; rage - ld a, BATTLE_VARS_SUBSTATUS4 - call GetBattleVarAddr - set SUBSTATUS_RAGE, [hl] - ret - -; 36f25 +INCLUDE "engine/battle/move_effects/rage.asm" BattleCommand_DoubleFlyingDamage: ; 36f25 @@ -7915,316 +6511,17 @@ DoubleDamage: ; 36f37 ; 36f46 -BattleCommand_Mimic: ; 36f46 -; mimic - - call ClearLastMove - call BattleCommand_MoveDelay - ld a, [AttackMissed] - and a - jr nz, .fail - ld hl, BattleMonMoves - ld a, [hBattleTurn] - and a - jr z, .player_turn - ld hl, EnemyMonMoves -.player_turn - call CheckHiddenOpponent - jr nz, .fail - ld a, BATTLE_VARS_LAST_COUNTER_MOVE_OPP - call GetBattleVar - and a - jr z, .fail - cp STRUGGLE - jr z, .fail - ld b, a - ld c, NUM_MOVES -.check_already_knows_move - ld a, [hli] - cp b - jr z, .fail - dec c - jr nz, .check_already_knows_move - dec hl -.find_mimic - ld a, [hld] - cp MIMIC - jr nz, .find_mimic - inc hl - ld a, BATTLE_VARS_LAST_COUNTER_MOVE_OPP - call GetBattleVar - ld [hl], a - ld [wNamedObjectIndexBuffer], a - ld bc, BattleMonPP - BattleMonMoves - add hl, bc - ld [hl], 5 - call GetMoveName - call AnimateCurrentMove - ld hl, LearnedMoveText - jp StdBattleTextBox - -.fail - jp FailMimic - -; 36f9d - - -BattleCommand_LeechSeed: ; 36f9d -; leechseed - ld a, [AttackMissed] - and a - jr nz, .evaded - call CheckSubstituteOpp - jr nz, .evaded - - ld de, EnemyMonType1 - ld a, [hBattleTurn] - and a - jr z, .ok - ld de, BattleMonType1 -.ok - - ld a, [de] - cp GRASS - jr z, .grass - inc de - ld a, [de] - cp GRASS - jr z, .grass - - ld a, BATTLE_VARS_SUBSTATUS4_OPP - call GetBattleVarAddr - bit SUBSTATUS_LEECH_SEED, [hl] - jr nz, .evaded - set SUBSTATUS_LEECH_SEED, [hl] - call AnimateCurrentMove - ld hl, WasSeededText - jp StdBattleTextBox - -.grass - call AnimateFailedMove - jp PrintDoesntAffect - -.evaded - call AnimateFailedMove - ld hl, EvadedText - jp StdBattleTextBox - -; 36fe1 +INCLUDE "engine/battle/move_effects/mimic.asm" +INCLUDE "engine/battle/move_effects/leech_seed.asm" -BattleCommand_Splash: ; 36fe1 - call AnimateCurrentMove - farcall StubbedTrainerRankings_Splash - jp PrintNothingHappened +INCLUDE "engine/battle/move_effects/splash.asm" -; 36fed +INCLUDE "engine/battle/move_effects/disable.asm" +INCLUDE "engine/battle/move_effects/pay_day.asm" -BattleCommand_Disable: ; 36fed -; disable - - ld a, [AttackMissed] - and a - jr nz, .failed - - ld de, EnemyDisableCount - ld hl, EnemyMonMoves - ld a, [hBattleTurn] - and a - jr z, .got_moves - ld de, PlayerDisableCount - ld hl, BattleMonMoves -.got_moves - - ld a, [de] - and a - jr nz, .failed - - ld a, BATTLE_VARS_LAST_COUNTER_MOVE_OPP - call GetBattleVar - and a - jr z, .failed - cp STRUGGLE - jr z, .failed - - ld b, a - ld c, $ff -.loop - inc c - ld a, [hli] - cp b - jr nz, .loop - - ld a, [hBattleTurn] - and a - ld hl, EnemyMonPP - jr z, .got_pp - ld hl, BattleMonPP -.got_pp - ld b, 0 - add hl, bc - ld a, [hl] - and a - jr z, .failed -.loop2 - call BattleRandom - and 7 - jr z, .loop2 - inc a - inc c - swap c - add c - ld [de], a - call AnimateCurrentMove - ld hl, DisabledMove - ld a, [hBattleTurn] - and a - jr nz, .got_disabled_move_pointer - inc hl -.got_disabled_move_pointer - ld a, BATTLE_VARS_LAST_COUNTER_MOVE_OPP - call GetBattleVar - ld [hl], a - ld [wNamedObjectIndexBuffer], a - call GetMoveName - ld hl, WasDisabledText - jp StdBattleTextBox - -.failed - jp FailDisable - -; 3705c - - -BattleCommand_PayDay: ; 3705c -; payday - - xor a - ld hl, StringBuffer1 - ld [hli], a - - ld a, [hBattleTurn] - and a - ld a, [BattleMonLevel] - jr z, .ok - ld a, [EnemyMonLevel] -.ok - - add a - ld hl, wPayDayMoney + 2 - add [hl] - ld [hld], a - jr nc, .done - inc [hl] - dec hl - jr nz, .done - inc [hl] -.done - ld hl, CoinsScatteredText - jp StdBattleTextBox - -; 3707f - - -BattleCommand_Conversion: ; 3707f -; conversion - - ld hl, BattleMonMoves - ld de, BattleMonType1 - ld a, [hBattleTurn] - and a - jr z, .got_moves - ld hl, EnemyMonMoves - ld de, EnemyMonType1 -.got_moves - push de - ld c, 0 - ld de, StringBuffer1 -.loop - push hl - ld b, 0 - add hl, bc - ld a, [hl] - pop hl - and a - jr z, .okay - push hl - push bc - dec a - ld hl, Moves + MOVE_TYPE - call GetMoveAttr - ld [de], a - inc de - pop bc - pop hl - inc c - ld a, c - cp NUM_MOVES - jr c, .loop -.okay - ld a, $ff - ld [de], a - inc de - ld [de], a - inc de - ld [de], a - pop de - ld hl, StringBuffer1 -.loop2 - ld a, [hl] - cp -1 - jr z, .fail - cp CURSE_T - jr z, .next - ld a, [de] - cp [hl] - jr z, .next - inc de - ld a, [de] - dec de - cp [hl] - jr nz, .done -.next - inc hl - jr .loop2 - -.fail - call AnimateFailedMove - jp PrintButItFailed - -.done -.loop3 - call BattleRandom - maskbits NUM_MOVES - ld c, a - ld b, 0 - ld hl, StringBuffer1 - add hl, bc - ld a, [hl] - cp -1 - jr z, .loop3 - cp CURSE_T - jr z, .loop3 - ld a, [de] - cp [hl] - jr z, .loop3 - inc de - ld a, [de] - dec de - cp [hl] - jr z, .loop3 - ld a, [hl] - ld [de], a - inc de - ld [de], a - ld [wNamedObjectIndexBuffer], a - farcall GetTypeName - call AnimateCurrentMove - ld hl, TransformedTypeText - jp StdBattleTextBox - -; 3710e +INCLUDE "engine/battle/move_effects/conversion.asm" BattleCommand_ResetStats: ; 3710e @@ -8347,7 +6644,9 @@ BattleCommand_Heal: ; 3713e ; 371cd -INCLUDE "engine/battle/effect_commands/transform.asm" + +INCLUDE "engine/battle/move_effects/transform.asm" + BattleSideCopy: ; 372c6 ; Copy bc bytes from hl to de if it's the player's turn. @@ -8489,12 +6788,7 @@ PrintButItFailed: ; 3734e ; 37354 -FailSnore: -FailDisable: -FailConversion2: -FailAttract: -FailForesight: -FailSpikes: +FailMove: call AnimateFailedMove ; fallthrough ; 37357 @@ -8541,42 +6835,11 @@ CheckSubstituteOpp: ; 37378 ; 37380 -BattleCommand_Selfdestruct: ; 37380 - farcall StubbedTrainerRankings_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 "engine/battle/move_effects/selfdestruct.asm" +INCLUDE "engine/battle/move_effects/mirror_move.asm" -INCLUDE "engine/battle/effect_commands/mirror_move.asm" - -INCLUDE "engine/battle/effect_commands/metronome.asm" +INCLUDE "engine/battle/move_effects/metronome.asm" CheckUserMove: ; 37462 @@ -8623,7 +6886,7 @@ ResetTurn: ; 3747b ; 37492 -INCLUDE "engine/battle/effect_commands/thief.asm" +INCLUDE "engine/battle/move_effects/thief.asm" BattleCommand_ArenaTrap: ; 37517 @@ -8655,7 +6918,7 @@ BattleCommand_ArenaTrap: ; 37517 ; 37536 -INCLUDE "engine/battle/effect_commands/nightmare.asm" +INCLUDE "engine/battle/move_effects/nightmare.asm" BattleCommand_Defrost: ; 37563 @@ -8692,21 +6955,21 @@ BattleCommand_Defrost: ; 37563 ; 37588 -INCLUDE "engine/battle/effect_commands/curse.asm" +INCLUDE "engine/battle/move_effects/curse.asm" -INCLUDE "engine/battle/effect_commands/protect.asm" +INCLUDE "engine/battle/move_effects/protect.asm" -INCLUDE "engine/battle/effect_commands/endure.asm" +INCLUDE "engine/battle/move_effects/endure.asm" -INCLUDE "engine/battle/effect_commands/spikes.asm" +INCLUDE "engine/battle/move_effects/spikes.asm" -INCLUDE "engine/battle/effect_commands/foresight.asm" +INCLUDE "engine/battle/move_effects/foresight.asm" -INCLUDE "engine/battle/effect_commands/perish_song.asm" +INCLUDE "engine/battle/move_effects/perish_song.asm" -INCLUDE "engine/battle/effect_commands/sandstorm.asm" +INCLUDE "engine/battle/move_effects/sandstorm.asm" -INCLUDE "engine/battle/effect_commands/rollout.asm" +INCLUDE "engine/battle/move_effects/rollout.asm" BattleCommand5d: ; 37791 @@ -8716,158 +6979,17 @@ BattleCommand5d: ; 37791 ; 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 "engine/battle/effect_commands/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 "engine/battle/effect_commands/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 +INCLUDE "engine/battle/move_effects/fury_cutter.asm" +INCLUDE "engine/battle/move_effects/attract.asm" -BattleCommand_Safeguard: ; 37939 -; safeguard +INCLUDE "engine/battle/move_effects/return.asm" - 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 +INCLUDE "engine/battle/move_effects/present.asm" -.failed - call AnimateFailedMove - jp PrintButItFailed +INCLUDE "engine/battle/move_effects/frustration.asm" -; 37962 +INCLUDE "engine/battle/move_effects/safeguard.asm" SafeCheckSafeguard: ; 37962 @@ -8906,346 +7028,13 @@ BattleCommand_CheckSafeguard: ; 37972 ; 37991 -BattleCommand_GetMagnitude: ; 37991 -; getmagnitude - - push bc - call BattleRandom - ld b, a - ld hl, MagnitudePower -.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 - -INCLUDE "data/moves/magnitude_power.asm" - - -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 LoadStandardMenuHeader - 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 LoadStandardMenuHeader - 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 LoadStandardMenuHeader - 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 +INCLUDE "engine/battle/move_effects/magnitude.asm" +INCLUDE "engine/battle/move_effects/baton_pass.asm" -CheckAnyOtherAliveEnemyMons: ; 37af6 - ld hl, OTPartyMon1HP - ld a, [OTPartyCount] - ld d, a - ld a, [CurOTMon] - ld e, a - - ; fallthrough -; 37b01 +INCLUDE "engine/battle/move_effects/pursuit.asm" -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 +INCLUDE "engine/battle/move_effects/rapid_spin.asm" BattleCommand_HealMorn: ; 37b74 @@ -9352,196 +7141,17 @@ BattleCommand_TimeBasedHealContinue: ; 37b7e ; 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 +INCLUDE "engine/battle/move_effects/hidden_power.asm" -.failed - call AnimateFailedMove - jp PrintButItFailed +INCLUDE "engine/battle/move_effects/rain_dance.asm" -; 37c55 +INCLUDE "engine/battle/move_effects/sunny_day.asm" +INCLUDE "engine/battle/move_effects/belly_drum.asm" -BattleCommand_PsychUp: ; 37c55 -; psychup +INCLUDE "engine/battle/move_effects/psych_up.asm" - 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 +INCLUDE "engine/battle/move_effects/mirror_coat.asm" BattleCommand_DoubleMinimizeDamage: ; 37ce6 @@ -9580,113 +7190,9 @@ BattleCommand_SkipSunCharge: ; 37d02 ; 37d0d -BattleCommand_CheckFutureSight: ; 37d0d -; checkfuturesight +INCLUDE "engine/battle/move_effects/future_sight.asm" - 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 +INCLUDE "engine/battle/move_effects/thunder.asm" CheckHiddenOpponent: ; 37daa @@ -9828,7 +7334,6 @@ LoadMoveAnim: ; 37e36 LoadAnim: ; 37e44 - ld [FXAnimID], a ; fallthrough diff --git a/engine/battle/effect_commands/attract.asm b/engine/battle/move_effects/attract.asm index 0a6d7c975..44cb7bec4 100755 --- a/engine/battle/effect_commands/attract.asm +++ b/engine/battle/move_effects/attract.asm @@ -20,7 +20,7 @@ BattleCommand_Attract: ; 377ce jp StdBattleTextBox .failed - jp FailAttract + jp FailMove ; 377f5 diff --git a/engine/battle/move_effects/baton_pass.asm b/engine/battle/move_effects/baton_pass.asm new file mode 100644 index 000000000..0561b6db9 --- /dev/null +++ b/engine/battle/move_effects/baton_pass.asm @@ -0,0 +1,241 @@ +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 LoadStandardMenuHeader + 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 LoadStandardMenuHeader + 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 LoadStandardMenuHeader + 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 diff --git a/engine/battle/move_effects/beat_up.asm b/engine/battle/move_effects/beat_up.asm new file mode 100644 index 000000000..31b07726e --- /dev/null +++ b/engine/battle/move_effects/beat_up.asm @@ -0,0 +1,219 @@ +BattleCommand_BeatUp: ; 35461 +; beatup + + call ResetDamage + ld a, [hBattleTurn] + and a + jp nz, .enemy_beats_up + ld a, [PlayerSubStatus3] + bit SUBSTATUS_IN_LOOP, a + jr nz, .next_mon + ld c, 20 + call DelayFrames + xor a + ld [PlayerRolloutCount], a + ld [wd002], a + ld [wBeatUpHitAtLeastOnce], a + jr .got_mon + +.next_mon + ld a, [PlayerRolloutCount] + ld b, a + ld a, [PartyCount] + sub b + ld [wd002], a + +.got_mon + ld a, [wd002] + ld hl, PartyMonNicknames + call GetNick + ld a, MON_HP + call GetBeatupMonLocation + ld a, [hli] + or [hl] + jp z, .beatup_fail ; fainted + ld a, [wd002] + ld c, a + ld a, [CurBattleMon] + ; BUG: this can desynchronize link battles + ; Change "cp [hl]" to "cp c" to fix + cp [hl] + ld hl, BattleMonStatus + jr z, .active_mon + ld a, MON_STATUS + call GetBeatupMonLocation +.active_mon + ld a, [hl] + and a + jp nz, .beatup_fail + + ld a, $1 + ld [wBeatUpHitAtLeastOnce], a + ld hl, BeatUpAttackText + call StdBattleTextBox + ld a, [EnemyMonSpecies] + ld [CurSpecies], a + call GetBaseData + ld a, [BaseDefense] + ld c, a + push bc + ld a, MON_SPECIES + call GetBeatupMonLocation + ld a, [hl] + ld [CurSpecies], a + call GetBaseData + ld a, [BaseAttack] + pop bc + ld b, a + push bc + ld a, MON_LEVEL + call GetBeatupMonLocation + ld a, [hl] + ld e, a + pop bc + ld a, [wPlayerMoveStructPower] + ld d, a + ret + +.enemy_beats_up + ld a, [EnemySubStatus3] + bit SUBSTATUS_IN_LOOP, a + jr nz, .not_first_enemy_beatup + + xor a + ld [EnemyRolloutCount], a + ld [wd002], a + ld [wBeatUpHitAtLeastOnce], a + jr .enemy_continue + +.not_first_enemy_beatup + ld a, [EnemyRolloutCount] + ld b, a + ld a, [OTPartyCount] + sub b + ld [wd002], a +.enemy_continue + ld a, [wBattleMode] + dec a + jr z, .wild + + ld a, [wLinkMode] + and a + jr nz, .link_or_tower + + ld a, [InBattleTowerBattle] + and a + jr nz, .link_or_tower + + ld a, [wd002] + ld c, a + ld b, 0 + ld hl, OTPartySpecies + add hl, bc + ld a, [hl] + ld [wNamedObjectIndexBuffer], a + call GetPokemonName + jr .got_enemy_nick + +.link_or_tower + ld a, [wd002] + ld hl, OTPartyMonNicknames + ld bc, NAME_LENGTH + call AddNTimes + ld de, StringBuffer1 + call CopyBytes +.got_enemy_nick + ld a, MON_HP + call GetBeatupMonLocation + ld a, [hli] + or [hl] + jp z, .beatup_fail + ld a, [wd002] + ld b, a + ld a, [CurOTMon] + cp b + ld hl, EnemyMonStatus + jr z, .active_enemy + + ld a, MON_STATUS + call GetBeatupMonLocation +.active_enemy + ld a, [hl] + and a + jr nz, .beatup_fail + + ld a, $1 + ld [wBeatUpHitAtLeastOnce], a + jr .finish_beatup + +.wild + ld a, [EnemyMonSpecies] + ld [wNamedObjectIndexBuffer], a + call GetPokemonName + ld hl, BeatUpAttackText + call StdBattleTextBox + jp EnemyAttackDamage + +.finish_beatup + ld hl, BeatUpAttackText + call StdBattleTextBox + ld a, [BattleMonSpecies] + ld [CurSpecies], a + call GetBaseData + ld a, [BaseDefense] + ld c, a + push bc + ld a, MON_SPECIES + call GetBeatupMonLocation + ld a, [hl] + ld [CurSpecies], a + call GetBaseData + ld a, [BaseAttack] + pop bc + ld b, a + push bc + ld a, MON_LEVEL + call GetBeatupMonLocation + ld a, [hl] + ld e, a + pop bc + ld a, [wEnemyMoveStructPower] + ld d, a + ret + +; 355b0 + + +.beatup_fail ; 355b0 + ld b, buildopponentrage_command + jp SkipToBattleCommand + +; 355b5 + + +BattleCommanda8: ; 355b5 + ld a, [wBeatUpHitAtLeastOnce] + and a + ret nz + + jp PrintButItFailed + +; 355bd + + +GetBeatupMonLocation: ; 355bd + push bc + ld c, a + ld b, 0 + ld a, [hBattleTurn] + and a + ld hl, PartyMon1Species + jr z, .got_species + ld hl, OTPartyMon1Species + +.got_species + ld a, [wd002] + add hl, bc + call GetPartyLocation + pop bc + ret diff --git a/engine/battle/move_effects/belly_drum.asm b/engine/battle/move_effects/belly_drum.asm new file mode 100644 index 000000000..eea10ef8a --- /dev/null +++ b/engine/battle/move_effects/belly_drum.asm @@ -0,0 +1,36 @@ +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 diff --git a/engine/battle/move_effects/bide.asm b/engine/battle/move_effects/bide.asm new file mode 100644 index 000000000..608bcff37 --- /dev/null +++ b/engine/battle/move_effects/bide.asm @@ -0,0 +1,105 @@ +BattleCommand_StoreEnergy: ; 36671 +; storeenergy + + ld a, BATTLE_VARS_SUBSTATUS3 + call GetBattleVar + bit SUBSTATUS_BIDE, a + ret z + + ld hl, PlayerRolloutCount + ld a, [hBattleTurn] + and a + jr z, .check_still_storing_energy + ld hl, EnemyRolloutCount +.check_still_storing_energy + dec [hl] + jr nz, .still_storing + + ld a, BATTLE_VARS_SUBSTATUS3 + call GetBattleVarAddr + res SUBSTATUS_BIDE, [hl] + + ld hl, UnleashedEnergyText + call StdBattleTextBox + + ld a, BATTLE_VARS_MOVE_POWER + call GetBattleVarAddr + ld a, 1 + ld [hl], a + ld hl, PlayerDamageTaken + 1 + ld de, wPlayerCharging ; player + ld a, [hBattleTurn] + and a + jr z, .player + ld hl, EnemyDamageTaken + 1 + ld de, wEnemyCharging ; enemy +.player + ld a, [hld] + add a + ld b, a + ld [CurDamage + 1], a + ld a, [hl] + rl a + ld [CurDamage], a + jr nc, .not_maxed + ld a, $ff + ld [CurDamage], a + ld [CurDamage + 1], a +.not_maxed + or b + jr nz, .built_up_something + ld a, 1 + ld [AttackMissed], a +.built_up_something + xor a + ld [hli], a + ld [hl], a + ld [de], a + + ld a, BATTLE_VARS_MOVE_ANIM + call GetBattleVarAddr + ld a, BIDE + ld [hl], a + + ld b, unleashenergy_command + jp SkipToBattleCommand + +.still_storing + ld hl, StoringEnergyText + call StdBattleTextBox + jp EndMoveEffect + +; 366e5 + + +BattleCommand_UnleashEnergy: ; 366e5 +; unleashenergy + + ld de, PlayerDamageTaken + ld bc, PlayerRolloutCount + ld a, [hBattleTurn] + and a + jr z, .got_damage + ld de, EnemyDamageTaken + ld bc, EnemyRolloutCount +.got_damage + ld a, BATTLE_VARS_SUBSTATUS3 + call GetBattleVarAddr + set SUBSTATUS_BIDE, [hl] + xor a + ld [de], a + inc de + ld [de], a + ld [wPlayerMoveStructEffect], a + ld [wEnemyMoveStructEffect], a + call BattleRandom + and 1 + inc a + inc a + ld [bc], a + ld a, 1 + ld [wKickCounter], a + call AnimateCurrentMove + jp EndMoveEffect + +; 3671a diff --git a/engine/battle/move_effects/conversion.asm b/engine/battle/move_effects/conversion.asm new file mode 100644 index 000000000..cb20d6801 --- /dev/null +++ b/engine/battle/move_effects/conversion.asm @@ -0,0 +1,98 @@ +BattleCommand_Conversion: ; 3707f +; conversion + + ld hl, BattleMonMoves + ld de, BattleMonType1 + ld a, [hBattleTurn] + and a + jr z, .got_moves + ld hl, EnemyMonMoves + ld de, EnemyMonType1 +.got_moves + push de + ld c, 0 + ld de, StringBuffer1 +.loop + push hl + ld b, 0 + add hl, bc + ld a, [hl] + pop hl + and a + jr z, .okay + push hl + push bc + dec a + ld hl, Moves + MOVE_TYPE + call GetMoveAttr + ld [de], a + inc de + pop bc + pop hl + inc c + ld a, c + cp NUM_MOVES + jr c, .loop +.okay + ld a, $ff + ld [de], a + inc de + ld [de], a + inc de + ld [de], a + pop de + ld hl, StringBuffer1 +.loop2 + ld a, [hl] + cp -1 + jr z, .fail + cp CURSE_T + jr z, .next + ld a, [de] + cp [hl] + jr z, .next + inc de + ld a, [de] + dec de + cp [hl] + jr nz, .done +.next + inc hl + jr .loop2 + +.fail + call AnimateFailedMove + jp PrintButItFailed + +.done +.loop3 + call BattleRandom + maskbits NUM_MOVES + ld c, a + ld b, 0 + ld hl, StringBuffer1 + add hl, bc + ld a, [hl] + cp -1 + jr z, .loop3 + cp CURSE_T + jr z, .loop3 + ld a, [de] + cp [hl] + jr z, .loop3 + inc de + ld a, [de] + dec de + cp [hl] + jr z, .loop3 + ld a, [hl] + ld [de], a + inc de + ld [de], a + ld [wNamedObjectIndexBuffer], a + farcall GetTypeName + call AnimateCurrentMove + ld hl, TransformedTypeText + jp StdBattleTextBox + +; 3710e diff --git a/engine/battle/move_effects/conversion2.asm b/engine/battle/move_effects/conversion2.asm new file mode 100644 index 000000000..f4fbe768c --- /dev/null +++ b/engine/battle/move_effects/conversion2.asm @@ -0,0 +1,66 @@ +BattleCommand_Conversion2: ; 359e6 +; conversion2 + + ld a, [AttackMissed] + and a + jr nz, .failed + ld hl, BattleMonType1 + ld a, [hBattleTurn] + and a + jr z, .got_type + ld hl, EnemyMonType1 +.got_type + ld a, BATTLE_VARS_LAST_COUNTER_MOVE_OPP + call GetBattleVar + and a + jr z, .failed + push hl + dec a + ld hl, Moves + MOVE_TYPE + call GetMoveAttr + ld d, a + pop hl + cp CURSE_T + jr z, .failed + call AnimateCurrentMove + call BattleCommand_SwitchTurn + +.loop + call BattleRandom + and $1f + cp UNUSED_TYPES + jr c, .okay + cp UNUSED_TYPES_END + jr c, .loop + cp TYPES_END + jr nc, .loop +.okay + ld [hli], a + ld [hld], a + push hl + ld a, BATTLE_VARS_MOVE_TYPE + call GetBattleVarAddr + push af + push hl + ld a, d + ld [hl], a + call BattleCheckTypeMatchup + pop hl + pop af + ld [hl], a + pop hl + ld a, [wTypeMatchup] + cp 10 + jr nc, .loop + call BattleCommand_SwitchTurn + + ld a, [hl] + ld [wNamedObjectIndexBuffer], a + predef GetTypeName + ld hl, TransformedTypeText + jp StdBattleTextBox + +.failed + jp FailMove + +; 35a53 diff --git a/engine/battle/move_effects/counter.asm b/engine/battle/move_effects/counter.asm new file mode 100644 index 000000000..c32a79c14 --- /dev/null +++ b/engine/battle/move_effects/counter.asm @@ -0,0 +1,60 @@ +BattleCommand_Counter: ; 35813 +; counter + + 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_COUNTER + 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 + MOVE_POWER] + and a + ret z + + ld a, [StringBuffer1 + MOVE_TYPE] + cp SPECIAL + ret nc + + 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 + +; 35864 diff --git a/engine/battle/effect_commands/curse.asm b/engine/battle/move_effects/curse.asm index dceb3b8d5..dceb3b8d5 100644 --- a/engine/battle/effect_commands/curse.asm +++ b/engine/battle/move_effects/curse.asm diff --git a/engine/battle/move_effects/destiny_bond.asm b/engine/battle/move_effects/destiny_bond.asm new file mode 100644 index 000000000..2dc125ddf --- /dev/null +++ b/engine/battle/move_effects/destiny_bond.asm @@ -0,0 +1,11 @@ +BattleCommand_DestinyBond: ; 35bff +; destinybond + + ld a, BATTLE_VARS_SUBSTATUS5 + call GetBattleVarAddr + set SUBSTATUS_DESTINY_BOND, [hl] + call AnimateCurrentMove + ld hl, DestinyBondEffectText + jp StdBattleTextBox + +; 35c0f diff --git a/engine/battle/move_effects/disable.asm b/engine/battle/move_effects/disable.asm new file mode 100644 index 000000000..370d6cc86 --- /dev/null +++ b/engine/battle/move_effects/disable.asm @@ -0,0 +1,74 @@ +BattleCommand_Disable: ; 36fed +; disable + + ld a, [AttackMissed] + and a + jr nz, .failed + + ld de, EnemyDisableCount + ld hl, EnemyMonMoves + ld a, [hBattleTurn] + and a + jr z, .got_moves + ld de, PlayerDisableCount + ld hl, BattleMonMoves +.got_moves + + ld a, [de] + and a + jr nz, .failed + + ld a, BATTLE_VARS_LAST_COUNTER_MOVE_OPP + call GetBattleVar + and a + jr z, .failed + cp STRUGGLE + jr z, .failed + + ld b, a + ld c, $ff +.loop + inc c + ld a, [hli] + cp b + jr nz, .loop + + ld a, [hBattleTurn] + and a + ld hl, EnemyMonPP + jr z, .got_pp + ld hl, BattleMonPP +.got_pp + ld b, 0 + add hl, bc + ld a, [hl] + and a + jr z, .failed +.loop2 + call BattleRandom + and 7 + jr z, .loop2 + inc a + inc c + swap c + add c + ld [de], a + call AnimateCurrentMove + ld hl, DisabledMove + ld a, [hBattleTurn] + and a + jr nz, .got_disabled_move_pointer + inc hl +.got_disabled_move_pointer + ld a, BATTLE_VARS_LAST_COUNTER_MOVE_OPP + call GetBattleVar + ld [hl], a + ld [wNamedObjectIndexBuffer], a + call GetMoveName + ld hl, WasDisabledText + jp StdBattleTextBox + +.failed + jp FailMove + +; 3705c diff --git a/engine/battle/move_effects/encore.asm b/engine/battle/move_effects/encore.asm new file mode 100644 index 000000000..316c53f2c --- /dev/null +++ b/engine/battle/move_effects/encore.asm @@ -0,0 +1,122 @@ +BattleCommand_Encore: ; 35864 +; encore + + ld hl, EnemyMonMoves + ld de, EnemyEncoreCount + ld a, [hBattleTurn] + and a + jr z, .ok + ld hl, BattleMonMoves + ld de, PlayerEncoreCount +.ok + ld a, BATTLE_VARS_LAST_MOVE_OPP + call GetBattleVar + and a + jp z, .failed + cp STRUGGLE + jp z, .failed + cp ENCORE + jp z, .failed + cp MIRROR_MOVE + jp z, .failed + ld b, a + +.got_move + ld a, [hli] + cp b + jr nz, .got_move + + ld bc, BattleMonPP - BattleMonMoves - 1 + add hl, bc + ld a, [hl] + and PP_MASK + jp z, .failed + ld a, [AttackMissed] + and a + jp nz, .failed + ld a, BATTLE_VARS_SUBSTATUS5_OPP + call GetBattleVarAddr + bit SUBSTATUS_ENCORED, [hl] + jp nz, .failed + set SUBSTATUS_ENCORED, [hl] + call BattleRandom + and $3 + inc a + inc a + inc a + ld [de], a + call CheckOpponentWentFirst + jr nz, .finish_move + ld a, [hBattleTurn] + and a + jr z, .force_last_enemy_move + + push hl + ld a, [LastPlayerMove] + ld b, a + ld c, 0 + ld hl, BattleMonMoves +.find_player_move + ld a, [hli] + cp b + jr z, .got_player_move + inc c + ld a, c + cp NUM_MOVES + jr c, .find_player_move + pop hl + res SUBSTATUS_ENCORED, [hl] + xor a + ld [de], a + jr .failed + +.got_player_move + pop hl + ld a, c + ld [CurMoveNum], a + ld a, b + ld [CurPlayerMove], a + dec a + ld de, wPlayerMoveStruct + call GetMoveData + jr .finish_move + +.force_last_enemy_move + push hl + ld a, [LastEnemyMove] + ld b, a + ld c, 0 + ld hl, EnemyMonMoves +.find_enemy_move + ld a, [hli] + cp b + jr z, .got_enemy_move + inc c + ld a, c + cp NUM_MOVES + jr c, .find_enemy_move + pop hl + res SUBSTATUS_ENCORED, [hl] + xor a + ld [de], a + jr .failed + +.got_enemy_move + pop hl + ld a, c + ld [CurEnemyMoveNum], a + ld a, b + ld [CurEnemyMove], a + dec a + ld de, wEnemyMoveStruct + call GetMoveData + +.finish_move + call AnimateCurrentMove + ld hl, GotAnEncoreText + jp StdBattleTextBox + +.failed + jp PrintDidntAffect2 + +; 35926 diff --git a/engine/battle/effect_commands/endure.asm b/engine/battle/move_effects/endure.asm index ed4329ff5..ed4329ff5 100644 --- a/engine/battle/effect_commands/endure.asm +++ b/engine/battle/move_effects/endure.asm diff --git a/engine/battle/move_effects/false_swipe.asm b/engine/battle/move_effects/false_swipe.asm new file mode 100644 index 000000000..ae8bcedb3 --- /dev/null +++ b/engine/battle/move_effects/false_swipe.asm @@ -0,0 +1,44 @@ +BattleCommand_FalseSwipe: ; 35c94 +; falseswipe + + ld hl, EnemyMonHP + ld a, [hBattleTurn] + and a + jr z, .got_hp + ld hl, BattleMonHP +.got_hp + ld de, CurDamage + ld c, 2 + push hl + push de + call StringCmp + pop de + pop hl + jr c, .done + ld a, [hli] + ld [de], a + inc de + ld a, [hl] + dec a + ld [de], a + inc a + jr nz, .okay + dec de + ld a, [de] + dec a + ld [de], a +.okay + ld a, [CriticalHit] + cp 2 + jr nz, .carry + xor a + ld [CriticalHit], a +.carry + scf + ret + +.done + and a + ret + +; 35cc9 diff --git a/engine/battle/move_effects/focus_energy.asm b/engine/battle/move_effects/focus_energy.asm new file mode 100644 index 000000000..2a3726c53 --- /dev/null +++ b/engine/battle/move_effects/focus_energy.asm @@ -0,0 +1,17 @@ +BattleCommand_FocusEnergy: ; 36c98 +; focusenergy + + ld a, BATTLE_VARS_SUBSTATUS4 + call GetBattleVarAddr + bit SUBSTATUS_FOCUS_ENERGY, [hl] + jr nz, .already_pumped + set SUBSTATUS_FOCUS_ENERGY, [hl] + call AnimateCurrentMove + ld hl, GettingPumpedText + jp StdBattleTextBox + +.already_pumped + call AnimateFailedMove + jp PrintButItFailed + +; 36cb2 diff --git a/engine/battle/effect_commands/foresight.asm b/engine/battle/move_effects/foresight.asm index 6f4f97cd2..0e6b1dd4e 100644 --- a/engine/battle/effect_commands/foresight.asm +++ b/engine/battle/move_effects/foresight.asm @@ -19,5 +19,5 @@ BattleCommand_Foresight: ; 376a0 jp StdBattleTextBox .failed - jp FailForesight + jp FailMove ; 376c2 diff --git a/engine/battle/move_effects/frustration.asm b/engine/battle/move_effects/frustration.asm new file mode 100644 index 000000000..ddf09afb1 --- /dev/null +++ b/engine/battle/move_effects/frustration.asm @@ -0,0 +1,29 @@ +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 diff --git a/engine/battle/move_effects/fury_cutter.asm b/engine/battle/move_effects/fury_cutter.asm new file mode 100644 index 000000000..9a667552a --- /dev/null +++ b/engine/battle/move_effects/fury_cutter.asm @@ -0,0 +1,61 @@ +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 diff --git a/engine/battle/move_effects/future_sight.asm b/engine/battle/move_effects/future_sight.asm new file mode 100644 index 000000000..cd01db838 --- /dev/null +++ b/engine/battle/move_effects/future_sight.asm @@ -0,0 +1,85 @@ +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 diff --git a/engine/battle/move_effects/heal_bell.asm b/engine/battle/move_effects/heal_bell.asm new file mode 100644 index 000000000..b4f6ccecb --- /dev/null +++ b/engine/battle/move_effects/heal_bell.asm @@ -0,0 +1,36 @@ +BattleCommand_HealBell: ; 35cc9 +; healbell + + ld a, BATTLE_VARS_SUBSTATUS1 + call GetBattleVarAddr + res SUBSTATUS_NIGHTMARE, [hl] + ld de, PartyMon1Status + ld a, [hBattleTurn] + and a + jr z, .got_status + ld de, OTPartyMon1Status +.got_status + ld a, BATTLE_VARS_STATUS + call GetBattleVarAddr + xor a + ld [hl], a + ld h, d + ld l, e + ld bc, PARTYMON_STRUCT_LENGTH + ld d, PARTY_LENGTH +.loop + ld [hl], a + add hl, bc + dec d + jr nz, .loop + call AnimateCurrentMove + + ld hl, BellChimedText + call StdBattleTextBox + + ld a, [hBattleTurn] + and a + jp z, CalcPlayerStats + jp CalcEnemyStats + +; 35d00 diff --git a/engine/battle/move_effects/hidden_power.asm b/engine/battle/move_effects/hidden_power.asm new file mode 100644 index 000000000..8fbdba42d --- /dev/null +++ b/engine/battle/move_effects/hidden_power.asm @@ -0,0 +1,10 @@ +BattleCommand_HiddenPower: ; 37be8 +; hiddenpower + + ld a, [AttackMissed] + and a + ret nz + farcall HiddenPowerDamage + ret + +; 37bf4 diff --git a/engine/battle/move_effects/leech_seed.asm b/engine/battle/move_effects/leech_seed.asm new file mode 100644 index 000000000..25f7a9a18 --- /dev/null +++ b/engine/battle/move_effects/leech_seed.asm @@ -0,0 +1,42 @@ +BattleCommand_LeechSeed: ; 36f9d +; leechseed + ld a, [AttackMissed] + and a + jr nz, .evaded + call CheckSubstituteOpp + jr nz, .evaded + + ld de, EnemyMonType1 + ld a, [hBattleTurn] + and a + jr z, .ok + ld de, BattleMonType1 +.ok + + ld a, [de] + cp GRASS + jr z, .grass + inc de + ld a, [de] + cp GRASS + jr z, .grass + + ld a, BATTLE_VARS_SUBSTATUS4_OPP + call GetBattleVarAddr + bit SUBSTATUS_LEECH_SEED, [hl] + jr nz, .evaded + set SUBSTATUS_LEECH_SEED, [hl] + call AnimateCurrentMove + ld hl, WasSeededText + jp StdBattleTextBox + +.grass + call AnimateFailedMove + jp PrintDoesntAffect + +.evaded + call AnimateFailedMove + ld hl, EvadedText + jp StdBattleTextBox + +; 36fe1 diff --git a/engine/battle/move_effects/lock_on.asm b/engine/battle/move_effects/lock_on.asm new file mode 100644 index 000000000..de92e0751 --- /dev/null +++ b/engine/battle/move_effects/lock_on.asm @@ -0,0 +1,23 @@ +BattleCommand_LockOn: ; 35a53 +; lockon + + call CheckSubstituteOpp + jr nz, .fail + + ld a, [AttackMissed] + and a + jr nz, .fail + + ld a, BATTLE_VARS_SUBSTATUS5_OPP + call GetBattleVarAddr + set SUBSTATUS_LOCK_ON, [hl] + call AnimateCurrentMove + + ld hl, TookAimText + jp StdBattleTextBox + +.fail + call AnimateFailedMove + jp PrintDidntAffect + +; 35a74 diff --git a/engine/battle/move_effects/magnitude.asm b/engine/battle/move_effects/magnitude.asm new file mode 100644 index 000000000..f56ec5c1b --- /dev/null +++ b/engine/battle/move_effects/magnitude.asm @@ -0,0 +1,29 @@ +BattleCommand_GetMagnitude: ; 37991 +; getmagnitude + + push bc + call BattleRandom + ld b, a + ld hl, MagnitudePower +.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 + +INCLUDE "data/moves/magnitude_power.asm" diff --git a/engine/battle/effect_commands/metronome.asm b/engine/battle/move_effects/metronome.asm index 6835ab569..6835ab569 100644 --- a/engine/battle/effect_commands/metronome.asm +++ b/engine/battle/move_effects/metronome.asm diff --git a/engine/battle/move_effects/mimic.asm b/engine/battle/move_effects/mimic.asm new file mode 100644 index 000000000..c1a3bc592 --- /dev/null +++ b/engine/battle/move_effects/mimic.asm @@ -0,0 +1,52 @@ +BattleCommand_Mimic: ; 36f46 +; mimic + + call ClearLastMove + call BattleCommand_MoveDelay + ld a, [AttackMissed] + and a + jr nz, .fail + ld hl, BattleMonMoves + ld a, [hBattleTurn] + and a + jr z, .player_turn + ld hl, EnemyMonMoves +.player_turn + call CheckHiddenOpponent + jr nz, .fail + ld a, BATTLE_VARS_LAST_COUNTER_MOVE_OPP + call GetBattleVar + and a + jr z, .fail + cp STRUGGLE + jr z, .fail + ld b, a + ld c, NUM_MOVES +.check_already_knows_move + ld a, [hli] + cp b + jr z, .fail + dec c + jr nz, .check_already_knows_move + dec hl +.find_mimic + ld a, [hld] + cp MIMIC + jr nz, .find_mimic + inc hl + ld a, BATTLE_VARS_LAST_COUNTER_MOVE_OPP + call GetBattleVar + ld [hl], a + ld [wNamedObjectIndexBuffer], a + ld bc, BattleMonPP - BattleMonMoves + add hl, bc + ld [hl], 5 + call GetMoveName + call AnimateCurrentMove + ld hl, LearnedMoveText + jp StdBattleTextBox + +.fail + jp FailMimic + +; 36f9d diff --git a/engine/battle/move_effects/mirror_coat.asm b/engine/battle/move_effects/mirror_coat.asm new file mode 100644 index 000000000..8e9c7c1b4 --- /dev/null +++ b/engine/battle/move_effects/mirror_coat.asm @@ -0,0 +1,61 @@ +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 diff --git a/engine/battle/effect_commands/mirror_move.asm b/engine/battle/move_effects/mirror_move.asm index c4f208d77..c4f208d77 100644 --- a/engine/battle/effect_commands/mirror_move.asm +++ b/engine/battle/move_effects/mirror_move.asm diff --git a/engine/battle/move_effects/mist.asm b/engine/battle/move_effects/mist.asm new file mode 100644 index 000000000..9ffd86c8e --- /dev/null +++ b/engine/battle/move_effects/mist.asm @@ -0,0 +1,17 @@ +BattleCommand_Mist: ; 36c7e +; mist + + ld a, BATTLE_VARS_SUBSTATUS4 + call GetBattleVarAddr + bit SUBSTATUS_MIST, [hl] + jr nz, .already_mist + set SUBSTATUS_MIST, [hl] + call AnimateCurrentMove + ld hl, MistText + jp StdBattleTextBox + +.already_mist + call AnimateFailedMove + jp PrintButItFailed + +; 36c98 diff --git a/engine/battle/effect_commands/nightmare.asm b/engine/battle/move_effects/nightmare.asm index 788e3de41..788e3de41 100644 --- a/engine/battle/effect_commands/nightmare.asm +++ b/engine/battle/move_effects/nightmare.asm diff --git a/engine/battle/move_effects/pain_split.asm b/engine/battle/move_effects/pain_split.asm new file mode 100644 index 000000000..5a6b72686 --- /dev/null +++ b/engine/battle/move_effects/pain_split.asm @@ -0,0 +1,97 @@ +BattleCommand_PainSplit: ; 35926 +; painsplit + + ld a, [AttackMissed] + and a + jp nz, .ButItFailed + call CheckSubstituteOpp + jp nz, .ButItFailed + call AnimateCurrentMove + ld hl, BattleMonMaxHP + 1 + ld de, EnemyMonMaxHP + 1 + call .PlayerShareHP + ld a, $1 + ld [wWhichHPBar], a + hlcoord 10, 9 + predef AnimateHPBar + ld hl, EnemyMonHP + ld a, [hli] + ld [Buffer4], a + ld a, [hli] + ld [Buffer3], a + ld a, [hli] + ld [Buffer2], a + ld a, [hl] + ld [Buffer1], a + call .EnemyShareHP + xor a + ld [wWhichHPBar], a + call ResetDamage + hlcoord 2, 2 + predef AnimateHPBar + farcall _UpdateBattleHUDs + + ld hl, SharedPainText + jp StdBattleTextBox + +.PlayerShareHP: + ld a, [hld] + ld [Buffer1], a + ld a, [hld] + ld [Buffer2], a + ld a, [hld] + ld b, a + ld [Buffer3], a + ld a, [hl] + ld [Buffer4], a + dec de + dec de + ld a, [de] + dec de + add b + ld [CurDamage + 1], a + ld b, [hl] + ld a, [de] + adc b + srl a + ld [CurDamage], a + ld a, [CurDamage + 1] + rr a + ld [CurDamage + 1], a + inc hl + inc hl + inc hl + inc de + inc de + inc de + +.EnemyShareHP: ; 359ac + ld c, [hl] + dec hl + ld a, [CurDamage + 1] + sub c + ld b, [hl] + dec hl + ld a, [CurDamage] + sbc b + jr nc, .skip + + ld a, [CurDamage] + ld b, a + ld a, [CurDamage + 1] + ld c, a +.skip + ld a, c + ld [hld], a + ld [Buffer5], a + ld a, b + ld [hli], a + ld [Buffer6], a + ret + +; 359cd + +.ButItFailed: + jp PrintDidntAffect2 + +; 359d0 diff --git a/engine/battle/move_effects/pay_day.asm b/engine/battle/move_effects/pay_day.asm new file mode 100644 index 000000000..05231fc1a --- /dev/null +++ b/engine/battle/move_effects/pay_day.asm @@ -0,0 +1,28 @@ +BattleCommand_PayDay: ; 3705c +; payday + + xor a + ld hl, StringBuffer1 + ld [hli], a + + ld a, [hBattleTurn] + and a + ld a, [BattleMonLevel] + jr z, .ok + ld a, [EnemyMonLevel] +.ok + + add a + ld hl, wPayDayMoney + 2 + add [hl] + ld [hld], a + jr nc, .done + inc [hl] + dec hl + jr nz, .done + inc [hl] +.done + ld hl, CoinsScatteredText + jp StdBattleTextBox + +; 3707f diff --git a/engine/battle/effect_commands/perish_song.asm b/engine/battle/move_effects/perish_song.asm index ac491ef6b..ac491ef6b 100644 --- a/engine/battle/effect_commands/perish_song.asm +++ b/engine/battle/move_effects/perish_song.asm diff --git a/engine/battle/effect_commands/present.asm b/engine/battle/move_effects/present.asm index 24db2a7fb..24db2a7fb 100755 --- a/engine/battle/effect_commands/present.asm +++ b/engine/battle/move_effects/present.asm diff --git a/engine/battle/effect_commands/protect.asm b/engine/battle/move_effects/protect.asm index 568ac00f8..568ac00f8 100644 --- a/engine/battle/effect_commands/protect.asm +++ b/engine/battle/move_effects/protect.asm diff --git a/engine/battle/move_effects/psych_up.asm b/engine/battle/move_effects/psych_up.asm new file mode 100644 index 000000000..c7e7e59b6 --- /dev/null +++ b/engine/battle/move_effects/psych_up.asm @@ -0,0 +1,51 @@ +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 diff --git a/engine/battle/move_effects/pursuit.asm b/engine/battle/move_effects/pursuit.asm new file mode 100644 index 000000000..c75204fb3 --- /dev/null +++ b/engine/battle/move_effects/pursuit.asm @@ -0,0 +1,26 @@ +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 diff --git a/engine/battle/move_effects/rage.asm b/engine/battle/move_effects/rage.asm new file mode 100644 index 000000000..ac01f8137 --- /dev/null +++ b/engine/battle/move_effects/rage.asm @@ -0,0 +1,8 @@ +BattleCommand_Rage: ; 36f1d +; rage + ld a, BATTLE_VARS_SUBSTATUS4 + call GetBattleVarAddr + set SUBSTATUS_RAGE, [hl] + ret + +; 36f25 diff --git a/engine/battle/move_effects/rain_dance.asm b/engine/battle/move_effects/rain_dance.asm new file mode 100644 index 000000000..8448ccb57 --- /dev/null +++ b/engine/battle/move_effects/rain_dance.asm @@ -0,0 +1,11 @@ +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 diff --git a/engine/battle/move_effects/rapid_spin.asm b/engine/battle/move_effects/rapid_spin.asm new file mode 100644 index 000000000..e429d9cb2 --- /dev/null +++ b/engine/battle/move_effects/rapid_spin.asm @@ -0,0 +1,38 @@ +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 diff --git a/engine/battle/move_effects/return.asm b/engine/battle/move_effects/return.asm new file mode 100644 index 000000000..8d8046385 --- /dev/null +++ b/engine/battle/move_effects/return.asm @@ -0,0 +1,27 @@ +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 diff --git a/engine/battle/effect_commands/rollout.asm b/engine/battle/move_effects/rollout.asm index 4ce9ab3d8..4ce9ab3d8 100644 --- a/engine/battle/effect_commands/rollout.asm +++ b/engine/battle/move_effects/rollout.asm diff --git a/engine/battle/move_effects/safeguard.asm b/engine/battle/move_effects/safeguard.asm new file mode 100644 index 000000000..cdf5bf7dc --- /dev/null +++ b/engine/battle/move_effects/safeguard.asm @@ -0,0 +1,25 @@ +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 diff --git a/engine/battle/effect_commands/sandstorm.asm b/engine/battle/move_effects/sandstorm.asm index 27b8e8e2c..27b8e8e2c 100644 --- a/engine/battle/effect_commands/sandstorm.asm +++ b/engine/battle/move_effects/sandstorm.asm diff --git a/engine/battle/move_effects/selfdestruct.asm b/engine/battle/move_effects/selfdestruct.asm new file mode 100644 index 000000000..6f6b0966f --- /dev/null +++ b/engine/battle/move_effects/selfdestruct.asm @@ -0,0 +1,31 @@ +BattleCommand_Selfdestruct: ; 37380 + farcall StubbedTrainerRankings_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 diff --git a/engine/battle/move_effects/sketch.asm b/engine/battle/move_effects/sketch.asm new file mode 100644 index 000000000..af6f8cc8c --- /dev/null +++ b/engine/battle/move_effects/sketch.asm @@ -0,0 +1,119 @@ +BattleCommand_Sketch: ; 35a74 +; sketch + + call ClearLastMove +; Don't sketch during a link battle + ld a, [wLinkMode] + and a + jr z, .not_linked + call AnimateFailedMove + jp PrintNothingHappened + +.not_linked +; If the opponent has a substitute up, fail. + call CheckSubstituteOpp + jp nz, .fail +; If the opponent is transformed, fail. + ld a, BATTLE_VARS_SUBSTATUS5_OPP + call GetBattleVarAddr + bit SUBSTATUS_TRANSFORMED, [hl] + jp nz, .fail +; Get the user's moveset in its party struct. +; This move replacement shall be permanent. +; Pointer will be in de. + ld a, MON_MOVES + call UserPartyAttr + ld d, h + ld e, l +; Get the battle move structs. + ld hl, BattleMonMoves + ld a, [hBattleTurn] + and a + jr z, .get_last_move + ld hl, EnemyMonMoves +.get_last_move + ld a, BATTLE_VARS_LAST_COUNTER_MOVE_OPP + call GetBattleVar + ld [wTypeMatchup], a + ld b, a +; Fail if move is invalid or is Struggle. + and a + jr z, .fail + cp STRUGGLE + jr z, .fail +; Fail if user already knows that move + ld c, NUM_MOVES +.does_user_already_know_move + ld a, [hli] + cp b + jr z, .fail + dec c + jr nz, .does_user_already_know_move +; Find Sketch in the user's moveset. +; Pointer in hl, and index in c. + dec hl + ld c, NUM_MOVES +.find_sketch + dec c + ld a, [hld] + cp SKETCH + jr nz, .find_sketch + inc hl +; The Sketched move is loaded to that slot. + ld a, b + ld [hl], a +; Copy the base PP from that move. + push bc + push hl + dec a + ld hl, Moves + MOVE_PP + call GetMoveAttr + pop hl + ld bc, BattleMonPP - BattleMonMoves + add hl, bc + ld [hl], a + pop bc + + ld a, [hBattleTurn] + and a + jr z, .user_trainer + ld a, [wBattleMode] + dec a + jr nz, .user_trainer +; wildmon + ld a, [hl] + push bc + ld hl, wWildMonPP + ld b, 0 + add hl, bc + ld [hl], a + ld hl, wWildMonMoves + add hl, bc + pop bc + ld [hl], b + jr .done_copy + +.user_trainer + ld a, [hl] + push af + ld l, c + ld h, 0 + add hl, de + ld a, b + ld [hl], a + pop af + ld de, MON_PP - MON_MOVES + add hl, de + ld [hl], a +.done_copy + call GetMoveName + call AnimateCurrentMove + + ld hl, SketchedText + jp StdBattleTextBox + +.fail + call AnimateFailedMove + jp PrintDidntAffect + +; 35b16 diff --git a/engine/battle/move_effects/sleep_talk.asm b/engine/battle/move_effects/sleep_talk.asm new file mode 100644 index 000000000..254b13814 --- /dev/null +++ b/engine/battle/move_effects/sleep_talk.asm @@ -0,0 +1,145 @@ +BattleCommand_SleepTalk: ; 35b33 +; sleeptalk + + call ClearLastMove + ld a, [AttackMissed] + and a + jr nz, .fail + ld a, [hBattleTurn] + and a + ld hl, BattleMonMoves + 1 + ld a, [DisabledMove] + ld d, a + jr z, .got_moves + ld hl, EnemyMonMoves + 1 + ld a, [EnemyDisabledMove] + ld d, a +.got_moves + ld a, BATTLE_VARS_STATUS + call GetBattleVar + and SLP + jr z, .fail + ld a, [hl] + and a + jr z, .fail + call .safely_check_has_usable_move + jr c, .fail + dec hl +.sample_move + push hl + call BattleRandom + maskbits NUM_MOVES + ld c, a + ld b, 0 + add hl, bc + ld a, [hl] + pop hl + and a + jr z, .sample_move + ld e, a + ld a, BATTLE_VARS_MOVE_ANIM + call GetBattleVar + cp e + jr z, .sample_move + ld a, e + cp d + jr z, .sample_move + call .check_two_turn_move + jr z, .sample_move + ld a, BATTLE_VARS_MOVE + call GetBattleVarAddr + ld a, e + ld [hl], a + call CheckUserIsCharging + jr nz, .charging + ld a, [wKickCounter] + push af + call BattleCommand_LowerSub + pop af + ld [wKickCounter], a +.charging + call LoadMoveAnim + call UpdateMoveData + jp ResetTurn + +.fail + call AnimateFailedMove + jp TryPrintButItFailed + +.safely_check_has_usable_move + push hl + push de + push bc + call .check_has_usable_move + pop bc + pop de + pop hl + ret + +.check_has_usable_move + ld a, [hBattleTurn] + and a + ld a, [DisabledMove] + jr z, .got_move_2 + + ld a, [EnemyDisabledMove] +.got_move_2 + ld b, a + ld a, BATTLE_VARS_MOVE + call GetBattleVar + ld c, a + dec hl + ld d, NUM_MOVES +.loop2 + ld a, [hl] + and a + jr z, .carry + + cp c + jr z, .nope + cp b + jr z, .nope + + call .check_two_turn_move + jr nz, .no_carry + +.nope + inc hl + dec d + jr nz, .loop2 + +.carry + scf + ret + +.no_carry + and a + ret + +.check_two_turn_move + push hl + push de + push bc + + ld b, a + callfar GetMoveEffect + ld a, b + + pop bc + pop de + pop hl + + cp EFFECT_SKULL_BASH + ret z + cp EFFECT_RAZOR_WIND + ret z + cp EFFECT_SKY_ATTACK + ret z + cp EFFECT_SOLARBEAM + ret z + cp EFFECT_FLY + ret z + cp EFFECT_BIDE + ret + +; 35bff diff --git a/engine/battle/move_effects/snore.asm b/engine/battle/move_effects/snore.asm new file mode 100644 index 000000000..926ee462d --- /dev/null +++ b/engine/battle/move_effects/snore.asm @@ -0,0 +1,13 @@ +BattleCommand_Snore: ; 359d0 +; snore + ld a, BATTLE_VARS_STATUS + call GetBattleVar + and SLP + ret nz + call ResetDamage + ld a, $1 + ld [AttackMissed], a + call FailMove + jp EndMoveEffect + +; 359e6 diff --git a/engine/battle/effect_commands/spikes.asm b/engine/battle/move_effects/spikes.asm index 3d15e4cfd..bc23d6559 100644 --- a/engine/battle/effect_commands/spikes.asm +++ b/engine/battle/move_effects/spikes.asm @@ -23,5 +23,5 @@ BattleCommand_Spikes: ; 37683 jp StdBattleTextBox .failed - jp FailSpikes + jp FailMove ; 376a0 diff --git a/engine/battle/move_effects/spite.asm b/engine/battle/move_effects/spite.asm new file mode 100644 index 000000000..96058de60 --- /dev/null +++ b/engine/battle/move_effects/spite.asm @@ -0,0 +1,88 @@ +BattleCommand_Spite: ; 35c0f +; spite + + ld a, [AttackMissed] + and a + jp nz, .failed + ld bc, PARTYMON_STRUCT_LENGTH ; ???? + ld hl, EnemyMonMoves + ld a, [hBattleTurn] + and a + jr z, .got_moves + ld hl, BattleMonMoves +.got_moves + ld a, BATTLE_VARS_LAST_COUNTER_MOVE_OPP + call GetBattleVar + and a + jr z, .failed + cp STRUGGLE + jr z, .failed + ld b, a + ld c, -1 +.loop + inc c + ld a, [hli] + cp b + jr nz, .loop + ld [wTypeMatchup], a + dec hl + ld b, 0 + push bc + ld c, BattleMonPP - BattleMonMoves + add hl, bc + pop bc + ld a, [hl] + and PP_MASK + jr z, .failed + push bc + call GetMoveName + ; lose 2-5 PP + call BattleRandom + and %11 + inc a + inc a + ld b, a + ld a, [hl] + and PP_MASK + cp b + jr nc, .deplete_pp + ld b, a +.deplete_pp + ld a, [hl] + sub b + ld [hl], a + push af + ld a, MON_PP + call OpponentPartyAttr + ld d, b + pop af + pop bc + add hl, bc + ld e, a + ld a, BATTLE_VARS_SUBSTATUS5_OPP + call GetBattleVar + bit SUBSTATUS_TRANSFORMED, a + jr nz, .transformed + ld a, [hBattleTurn] + and a + jr nz, .not_wildmon + ld a, [wBattleMode] + dec a + jr nz, .not_wildmon + ld hl, wWildMonPP + add hl, bc +.not_wildmon + ld [hl], e +.transformed + push de + call AnimateCurrentMove + pop de + ld a, d + ld [wTypeMatchup], a + ld hl, SpiteEffectText + jp StdBattleTextBox + +.failed + jp PrintDidntAffect2 + +; 35c94 diff --git a/engine/battle/move_effects/splash.asm b/engine/battle/move_effects/splash.asm new file mode 100644 index 000000000..5b5e504b8 --- /dev/null +++ b/engine/battle/move_effects/splash.asm @@ -0,0 +1,6 @@ +BattleCommand_Splash: ; 36fe1 + call AnimateCurrentMove + farcall StubbedTrainerRankings_Splash + jp PrintNothingHappened + +; 36fed diff --git a/engine/battle/move_effects/substitute.asm b/engine/battle/move_effects/substitute.asm new file mode 100644 index 000000000..c761f88e1 --- /dev/null +++ b/engine/battle/move_effects/substitute.asm @@ -0,0 +1,90 @@ +BattleCommand_Substitute: ; 36e7c +; substitute + + call BattleCommand_MoveDelay + ld hl, BattleMonMaxHP + ld de, PlayerSubstituteHP + ld a, [hBattleTurn] + and a + jr z, .got_hp + ld hl, EnemyMonMaxHP + ld de, EnemySubstituteHP +.got_hp + + ld a, BATTLE_VARS_SUBSTATUS4 + call GetBattleVar + bit SUBSTATUS_SUBSTITUTE, a + jr nz, .already_has_sub + + ld a, [hli] + ld b, [hl] + srl a + rr b + srl a + rr b + dec hl + dec hl + ld a, b + ld [de], a + ld a, [hld] + sub b + ld e, a + ld a, [hl] + sbc 0 + ld d, a + jr c, .too_weak_to_sub + ld a, d + or e + jr z, .too_weak_to_sub + ld [hl], d + inc hl + ld [hl], e + + ld a, BATTLE_VARS_SUBSTATUS4 + call GetBattleVarAddr + set SUBSTATUS_SUBSTITUTE, [hl] + + ld hl, wPlayerWrapCount + ld de, wPlayerTrappingMove + ld a, [hBattleTurn] + and a + jr z, .player + ld hl, wEnemyWrapCount + ld de, wEnemyTrappingMove +.player + + xor a + ld [hl], a + ld [de], a + call _CheckBattleScene + jr c, .no_anim + + xor a + ld [wNumHits], a + ld [FXAnimID + 1], a + ld [wKickCounter], a + ld a, SUBSTITUTE + call LoadAnim + jr .finish + +.no_anim + call BattleCommand_RaiseSubNoAnim +.finish + ld hl, MadeSubstituteText + call StdBattleTextBox + jp RefreshBattleHuds + +.already_has_sub + call CheckUserIsCharging + call nz, BattleCommand_RaiseSub + ld hl, HasSubstituteText + jr .jp_stdbattletextbox + +.too_weak_to_sub + call CheckUserIsCharging + call nz, BattleCommand_RaiseSub + ld hl, TooWeakSubText +.jp_stdbattletextbox + jp StdBattleTextBox + +; 36f0b diff --git a/engine/battle/move_effects/sunny_day.asm b/engine/battle/move_effects/sunny_day.asm new file mode 100644 index 000000000..7d8a9cef1 --- /dev/null +++ b/engine/battle/move_effects/sunny_day.asm @@ -0,0 +1,11 @@ +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 diff --git a/engine/battle/move_effects/teleport.asm b/engine/battle/move_effects/teleport.asm new file mode 100644 index 000000000..e3a0535ca --- /dev/null +++ b/engine/battle/move_effects/teleport.asm @@ -0,0 +1,91 @@ +BattleCommand_Teleport: ; 36778 +; teleport + + ld a, [BattleType] + cp BATTLETYPE_SHINY + jr z, .failed + cp BATTLETYPE_TRAP + jr z, .failed + cp BATTLETYPE_CELEBI + jr z, .failed + cp BATTLETYPE_SUICUNE + jr z, .failed + + ld a, BATTLE_VARS_SUBSTATUS5_OPP + call GetBattleVar + bit SUBSTATUS_CANT_RUN, a + jr nz, .failed +; Only need to check these next things if it's your turn + ld a, [hBattleTurn] + and a + jr nz, .enemy_turn +; Can't teleport from a trainer battle + ld a, [wBattleMode] + dec a + jr nz, .failed +; If your level is greater than the opponent's, you run without fail. + ld a, [CurPartyLevel] + ld b, a + ld a, [BattleMonLevel] + cp b + jr nc, .run_away +; Generate a number between 0 and (YourLevel + TheirLevel). + add b + ld c, a + inc c +.loop_player + call BattleRandom + cp c + jr nc, .loop_player +; If that number is greater than 4 times your level, run away. + srl b + srl b + cp b + jr nc, .run_away + +.failed + call AnimateFailedMove + jp PrintButItFailed + +.enemy_turn + ld a, [wBattleMode] + dec a + jr nz, .failed + ld a, [BattleMonLevel] + ld b, a + ld a, [CurPartyLevel] + cp b + jr nc, .run_away + add b + ld c, a + inc c +.loop_enemy + call BattleRandom + cp c + jr nc, .loop_enemy + srl b + srl b + cp b + ; This does the wrong thing. What was + ; probably intended was jr c, .failed + ; The way this is made makes enemy use + ; of Teleport always succeed if able + jr nc, .run_away +.run_away + call UpdateBattleMonInParty + xor a + ld [wNumHits], a + inc a + ld [wForcedSwitch], a + ld [wKickCounter], a + call SetBattleDraw + call BattleCommand_LowerSub + call LoadMoveAnim + ld c, 20 + call DelayFrames + call SetBattleDraw + + ld hl, FledFromBattleText + jp StdBattleTextBox + +; 36804 diff --git a/engine/battle/effect_commands/thief.asm b/engine/battle/move_effects/thief.asm index 6d32d68d4..6d32d68d4 100644 --- a/engine/battle/effect_commands/thief.asm +++ b/engine/battle/move_effects/thief.asm diff --git a/engine/battle/move_effects/thunder.asm b/engine/battle/move_effects/thunder.asm new file mode 100644 index 000000000..adfb4dd33 --- /dev/null +++ b/engine/battle/move_effects/thunder.asm @@ -0,0 +1,20 @@ +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 diff --git a/engine/battle/effect_commands/transform.asm b/engine/battle/move_effects/transform.asm index 65c3f3e60..65c3f3e60 100755 --- a/engine/battle/effect_commands/transform.asm +++ b/engine/battle/move_effects/transform.asm diff --git a/engine/battle/move_effects/triple_kick.asm b/engine/battle/move_effects/triple_kick.asm new file mode 100644 index 000000000..e66e5a9a7 --- /dev/null +++ b/engine/battle/move_effects/triple_kick.asm @@ -0,0 +1,39 @@ +BattleCommand_TripleKick: ; 346b2 +; triplekick + + ld a, [wKickCounter] + ld b, a + inc b + ld hl, CurDamage + 1 + ld a, [hld] + ld e, a + ld a, [hli] + ld d, a +.next_kick + dec b + ret z + ld a, [hl] + add e + ld [hld], a + ld a, [hl] + adc d + ld [hli], a + +; No overflow. + jr nc, .next_kick + ld a, $ff + ld [hld], a + ld [hl], a + ret + +; 346cd + + +BattleCommand_KickCounter: ; 346cd +; kickcounter + + ld hl, wKickCounter + inc [hl] + ret + +; 346d2 |