diff --git a/asm/macros/battle_script.inc b/asm/macros/battle_script.inc index ba4b4619aa..c906938b93 100644 --- a/asm/macros/battle_script.inc +++ b/asm/macros/battle_script.inc @@ -1806,499 +1806,6 @@ .4byte \jumpInstr .endm -@ various command changed to more readable macros - .macro cancelmultiturnmoves battler:req - various \battler, VARIOUS_CANCEL_MULTI_TURN_MOVES - .endm - - .macro getifcantrunfrombattle battler:req - various \battler, VARIOUS_IS_RUNNING_IMPOSSIBLE - .endm - - .macro getmovetarget battler:req - various \battler, VARIOUS_GET_MOVE_TARGET - .endm - - .macro getbattlerfainted battler:req - various \battler, VARIOUS_GET_BATTLER_FAINTED - .endm - - .macro resetswitchinabilitybits battler:req - various \battler, VARIOUS_RESET_SWITCH_IN_ABILITY_BITS - .endm - - .macro updatechoicemoveonlvlup battler:req - various \battler, VARIOUS_UPDATE_CHOICE_MOVE_ON_LVL_UP - .endm - - .macro resetplayerfainted - various BS_ATTACKER, VARIOUS_RESET_PLAYER_FAINTED - .endm - - .macro palaceflavortext battler:req - various \battler, VARIOUS_PALACE_FLAVOR_TEXT - .endm - - .macro arenajudgmentwindow - various BS_ATTACKER, VARIOUS_ARENA_JUDGMENT_WINDOW - .endm - - .macro arenaopponentmonlost - various BS_ATTACKER, VARIOUS_ARENA_OPPONENT_MON_LOST - .endm - - .macro arenaplayermonlost - various BS_ATTACKER, VARIOUS_ARENA_PLAYER_MON_LOST - .endm - - .macro arenabothmonlost - various BS_ATTACKER, VARIOUS_ARENA_BOTH_MONS_LOST - .endm - - .macro forfeityesnobox battler:req - various \battler, VARIOUS_EMIT_YESNOBOX - .endm - - .macro arenadrawreftextbox - various BS_ATTACKER, VARIOUS_DRAW_ARENA_REF_TEXT_BOX - .endm - - .macro arenaerasereftextbox - various BS_ATTACKER, VARIOUS_ERASE_ARENA_REF_TEXT_BOX - .endm - - .macro arenajudgmentstring id:req - various \id, VARIOUS_ARENA_JUDGMENT_STRING - .endm - - .macro arenawaitmessage id:req - various \id, VARIOUS_ARENA_WAIT_STRING - .endm - - .macro waitcry battler:req - various \battler, VARIOUS_WAIT_CRY - .endm - - .macro returnopponentmon1toball battler:req - various \battler, VARIOUS_RETURN_OPPONENT_MON1 - .endm - - .macro returnopponentmon2toball battler:req - various \battler, VARIOUS_RETURN_OPPONENT_MON2 - .endm - - .macro volumedown - various BS_ATTACKER, VARIOUS_VOLUME_DOWN - .endm - - .macro volumeup - various BS_ATTACKER, VARIOUS_VOLUME_UP - .endm - - .macro setalreadystatusedmoveattempt battler:req - various \battler, VARIOUS_SET_ALREADY_STATUS_MOVE_ATTEMPT - .endm - - .macro palacetryescapestatus battler:req - various \battler, VARIOUS_PALACE_TRY_ESCAPE_STATUS - .endm - - .macro setoutcomeonteleport battler:req - various \battler, VARIOUS_SET_TELEPORT_OUTCOME - .endm - - .macro playtrainerdefeatbgm battler:req - various \battler, VARIOUS_PLAY_TRAINER_DEFEATED_MUSIC - .endm - - .macro stattextbuffer battler:req - various \battler, VARIOUS_STAT_TEXT_BUFFER - .endm - - .macro switchinabilities battler:req - various \battler, VARIOUS_SWITCHIN_ABILITIES - .endm - - .macro instanthpdrop battler:req - various \battler, VARIOUS_INSTANT_HP_DROP - .endm - - .macro clearstatus battler:req - various \battler, VARIOUS_CLEAR_STATUS - .endm - - .macro restorepp battler:req - various \battler, VARIOUS_RESTORE_PP - .endm - - .macro tryactivatereceiver battler:req - various \battler, VARIOUS_TRY_ACTIVATE_RECEIVER - .endm - - .macro tryactivatesoulheart - various BS_ATTACKER, VARIOUS_TRY_ACTIVATE_SOULHEART - .endm - - .macro playmoveanimation battler:req, move:req - various \battler, VARIOUS_PLAY_MOVE_ANIMATION - .2byte \move - .endm - - .macro setluckychant battler:req, failInstr:req - various \battler VARIOUS_SET_LUCKY_CHANT - .4byte \failInstr - .endm - - .macro suckerpunchcheck failInstr:req - various BS_ATTACKER, VARIOUS_SUCKER_PUNCH_CHECK - .4byte \failInstr - .endm - - .macro setabilitysimple battler:req, failInstr:req - various \battler VARIOUS_SET_SIMPLE_BEAM - .4byte \failInstr - .endm - - .macro tryentrainment failInstr:req - various BS_ATTACKER, VARIOUS_TRY_ENTRAINMENT - .4byte \failInstr - .endm - - .macro setlastusedability battler:req - various \battler, VARIOUS_SET_LAST_USED_ABILITY - .endm - - .macro tryafteryou failInstr:req - various BS_ATTACKER, VARIOUS_AFTER_YOU - .4byte \failInstr - .endm - - .macro trybestow failInstr:req - various BS_ATTACKER, VARIOUS_BESTOW - .4byte \failInstr - .endm - - .macro invertstatstages battler:req - various \battler, VARIOUS_INVERT_STAT_STAGES - .endm - - .macro trymefirst failInstr:req - various BS_ATTACKER, VARIOUS_TRY_ME_FIRST - .4byte \failInstr - .endm - - .macro jumpifbattleend jumpInstr:req - various BS_ATTACKER, VARIOUS_JUMP_IF_BATTLE_END - .4byte \jumpInstr - .endm - - .macro tryelectrify failInstr:req - various BS_ATTACKER, VARIOUS_TRY_ELECTRIFY - .4byte \failInstr - .endm - - .macro trysoak failInstr:req - various BS_ATTACKER, VARIOUS_TRY_SOAK - .4byte \failInstr - .endm - - .macro handleformchange battler:req, case:req - various \battler, VARIOUS_HANDLE_FORM_CHANGE - .byte \case - .endm - - .macro jumpifcantuselastresort battler:req, jumpInstr:req - various \battler, VARIOUS_TRY_LAST_RESORT - .4byte \jumpInstr - .endm - - .macro tryautotomize battler:req, failInstr:req - various \battler, VARIOUS_TRY_AUTOTOMIZE - .4byte \failInstr - .endm - - .macro jumpifcantusesynchronoise jumpInstr:req - various BS_ATTACKER, VARIOUS_TRY_SYNCHRONOISE - .4byte \jumpInstr - .endm - - .macro showabilitypopup battler:req - various \battler, VARIOUS_ABILITY_POPUP - .endm - - .macro updateabilitypopup battler:req - various \battler, VARIOUS_UPDATE_ABILITY_POPUP - .endm - - .macro jumpiftargetally jumpInstr:req - various BS_ATTACKER, VARIOUS_JUMP_IF_TARGET_ALLY - .4byte \jumpInstr - .endm - - .macro trypsychoshift failInstr:req sleepClauseFailInstr:req - various BS_ATTACKER, VARIOUS_PSYCHO_SHIFT - .4byte \failInstr - .4byte \sleepClauseFailInstr - .endm - - .macro curestatus battler:req - various \battler, VARIOUS_CURE_STATUS - .endm - - .macro powertrick battler:req - various \battler, VARIOUS_POWER_TRICK - .endm - - .macro jumpifnotgrounded battler:req, jumpInstr:req - various \battler, VARIOUS_JUMP_IF_NOT_GROUNDED - .4byte \jumpInstr - .endm - - .macro handletrainerslidemsg battler:req, case:req - various \battler, VARIOUS_HANDLE_TRAINER_SLIDE_MSG - .byte \case - .endm - - .macro trytrainerslidefirstdownmsg battler:req - various \battler, VARIOUS_TRY_TRAINER_SLIDE_MSG_FIRST_OFF - .endm - - .macro trytrainerslidelastonmsg battler:req - various \battler, VARIOUS_TRY_TRAINER_SLIDE_MSG_LAST_ON - .endm - - .macro setauroraveil battler:req - various \battler, VARIOUS_SET_AURORA_VEIL - .endm - - .macro trysetthirdtype battler:req, failInstr:req - various \battler, VARIOUS_TRY_THIRD_TYPE - .4byte \failInstr - .endm - - .macro tryaccupressure battler:req, failInstr:req - various \battler, VARIOUS_ACUPRESSURE - .4byte \failInstr - .endm - - .macro bringdownairbornebattler battler:req - various \battler, VARIOUS_GRAVITY_ON_AIRBORNE_MONS - .endm - - .macro checkgrassyterrainheal battler:req, failInstr:req - various \battler, VARIOUS_CHECK_IF_GRASSY_TERRAIN_HEALS - .4byte \failInstr - .endm - - .macro jumpifnotberry battler:req, jumpInstr:req - various \battler, VARIOUS_JUMP_IF_NOT_BERRY - .4byte \jumpInstr - .endm - - .macro jumpifroarfails jumpInstr:req - various BS_ATTACKER, VARIOUS_JUMP_IF_ROAR_FAILS - .4byte \jumpInstr - .endm - - .macro tryinstruct failInstr:req - various BS_ATTACKER, VARIOUS_TRY_INSTRUCT - .4byte \failInstr - .endm - - .macro settracedability battler:req - various \battler, VARIOUS_TRACE_ABILITY - .endm - - .macro updatenick battler:req - various \battler, VARIOUS_UPDATE_NICK - .endm - - .macro tryillusionoff battler:req - various \battler, VARIOUS_TRY_ILLUSION_OFF - .endm - - .macro spriteignore0hp value:req - various BS_ATTACKER, VARIOUS_SET_SPRITEIGNORE0HP - .byte \value - .endm - - .macro getstatvalue battler:req, stat:req - various \battler, VARIOUS_GET_STAT_VALUE - .byte \stat - .endm - - .macro jumpiffullhp battler:req, jumpInstr:req - various \battler, VARIOUS_JUMP_IF_FULL_HP - .4byte \jumpInstr - .endm - - .macro losetype battler:req, type:req - various \battler, VARIOUS_LOSE_TYPE - .byte \type - .endm - - .macro tryfriskmsg battler:req - various \battler, VARIOUS_TRY_FRISK - .endm - - .macro jumpifshieldsdown battler:req, jumpInstr:req - various \battler, VARIOUS_JUMP_IF_SHIELDS_DOWN_PROTECTED - .4byte \jumpInstr - .endm - - .macro trysetfairylock failInstr:req - various BS_ATTACKER, VARIOUS_TRY_FAIRY_LOCK - .4byte \failInstr - .endm - - .macro jumpifnoally battler:req, jumpInstr:req - various \battler, VARIOUS_JUMP_IF_NO_ALLY - .4byte \jumpInstr - .endm - - .macro jumpifholdeffect battler:req, holdEffect:req, jumpInstr:req, equal=TRUE - various \battler, VARIOUS_JUMP_IF_HOLD_EFFECT - .byte \holdEffect - .4byte \jumpInstr - .byte \equal - .endm - - .macro jumpifnoholdeffect battler:req, holdEffect:req, jumpInstr:req - jumpifholdeffect \battler, \holdEffect, \jumpInstr, FALSE - .endm - - .macro infatuatewithbattler battler:req, infatuateWith:req - various \battler, VARIOUS_INFATUATE_WITH_BATTLER - .byte \infatuateWith - .endm - - .macro setlastuseditem battler:req - various \battler, VARIOUS_SET_LAST_USED_ITEM - .endm - - .macro jumpifabsent battler:req, jumpInstr:req - various \battler, VARIOUS_JUMP_IF_ABSENT - .4byte \jumpInstr - .endm - - .macro destroyabilitypopup - various BS_ABILITY_BATTLER, VARIOUS_DESTROY_ABILITY_POPUP - .endm - - .macro gettotemboost jumpInstr:req - various BS_ATTACKER, VARIOUS_TOTEM_BOOST - .4byte \jumpInstr - .endm - - .macro consumeberry battler:req, fromBattler:req - various \battler, VARIOUS_CONSUME_BERRY - .byte \fromBattler - .endm - - .macro activateitemeffects battler:req - various \battler, VARIOUS_MOVEEND_ITEM_EFFECTS - .endm - - .macro pickpocketsteal - various 0, VARIOUS_PICKPOCKET - .endm - - .macro doterrainseed battler:req, failInstr:req - various \battler, VARIOUS_TERRAIN_SEED - .4byte \failInstr - .endm - - .macro makeinvisible battler:req - various \battler, VARIOUS_MAKE_INVISIBLE - .endm - - .macro tryroomservice battler:req, failInstr:req - various \battler, VARIOUS_ROOM_SERVICE - .4byte \failInstr - .endm - - .macro jumpifpranksterblocked battler:req, jumpInstr:req - various \battler, VARIOUS_JUMP_IF_PRANKSTER_BLOCKED - .4byte \jumpInstr - .endm - - .macro jumpifteamhealthy battler:req, jumpInstr:req - various \battler, VARIOUS_JUMP_IF_TEAM_HEALTHY - .4byte \jumpInstr - .endm - - .macro tryhealquarterhealth battler:req, failInstr:req - various \battler, VARIOUS_TRY_HEAL_QUARTER_HP - .4byte \failInstr - .endm - - .macro trytoclearprimalweather - various BS_ATTACKER, VARIOUS_TRY_TO_CLEAR_PRIMAL_WEATHER - .endm - - .macro setattackertostickywebuser - various BS_TARGET, VARIOUS_SET_ATTACKER_STICKY_WEB_USER - .endm - - .macro getrototillertargets failInstr:req - various BS_ATTACKER, VARIOUS_GET_ROTOTILLER_TARGETS - .4byte \failInstr - .endm - - .macro jumpifnotrototilleraffected battler:req, jumpInstr:req - various \battler, VARIOUS_JUMP_IF_NOT_ROTOTILLER_AFFECTED - .4byte \jumpInstr - .endm - - .macro jumpifcantreverttoprimal jumpInstr:req - various BS_ATTACKER, VARIOUS_JUMP_IF_CANT_REVERT_TO_PRIMAL - .4byte \jumpInstr - .endm - - .macro jumpifweatheraffected battler:req, flags:req, jumpInstr:req - various \battler, VARIOUS_JUMP_IF_WEATHER_AFFECTED - .4byte \flags - .4byte \jumpInstr - .endm - - .macro jumpifspecies battler:req, species:req, jumpInstr:req - various \battler, VARIOUS_JUMP_IF_SPECIES - .2byte \species - .4byte \jumpInstr - .endm - - .macro tryendneutralizinggas battler:req - various \battler, VARIOUS_TRY_END_NEUTRALIZING_GAS - .endm - - .macro trynoretreat battler:req, failInstr:req - various \battler, VARIOUS_TRY_NO_RETREAT - .4byte \failInstr - .endm - - .macro checkpoltergeist battler:req, failInstr:req - various \battler, VARIOUS_CHECK_POLTERGEIST - .4byte \failInstr - .endm - - .macro cutonethirdhpraisestats failInstr:req - various BS_ATTACKER, VARIOUS_CUT_1_3_HP_RAISE_STATS - .4byte \failInstr - .endm - - .macro curecertainstatuses battler:req - various \battler, VARIOUS_CURE_CERTAIN_STATUSES - .endm - - .macro tryresetnegativestatstages battler:req - various \battler, VARIOUS_TRY_RESET_NEGATIVE_STAT_STAGES - .endm - - .macro jumpiflastuseditemberry jumpInstr:req - various BS_ATTACKER, VARIOUS_JUMP_IF_LAST_USED_ITEM_BERRY - .4byte \jumpInstr - .endm - .macro jumpiflastuseditemholdeffect holdEffect:req, secondaryId:req, jumpInstr:req callnative BS_JumpIfLastUsedItemHoldEffect .byte \holdEffect @@ -2306,18 +1813,6 @@ .4byte \jumpInstr .endm - .macro savebattleritem battler:req - various \battler, VARIOUS_SAVE_BATTLER_ITEM - .endm - - .macro restorebattleritem battler:req - various \battler, VARIOUS_RESTORE_BATTLER_ITEM - .endm - - .macro battleritemtolastuseditem battler:req - various \battler, VARIOUS_BATTLER_ITEM_TO_LAST_USED_ITEM - .endm - .macro swapsidestatuses callnative BS_CourtChangeSwapSideStatuses .endm @@ -2446,6 +1941,526 @@ .4byte \jumpInstr .endm + .macro jumpifroarfails jumpInstr:req + callnative BS_JumpIfRoarFails + .4byte \jumpInstr + .endm + + .macro jumpifabsent battler:req, jumpInstr:req + callnative BS_JumpIfAbsent + .byte \battler + .4byte \jumpInstr + .endm + + .macro jumpifnoholdeffect battler:req, holdEffect:req, jumpInstr:req + jumpifholdeffect \battler, \holdEffect, \jumpInstr, FALSE + .endm + + .macro jumpifholdeffect battler:req, holdEffect:req, jumpInstr:req, equal:req + callnative BS_JumpIfHoldEffect + .byte \battler + .byte \holdEffect + .4byte \jumpInstr + .byte \equal + .endm + + .macro jumpifnoally battler:req, jumpInstr:req + callnative BS_JumpIfNoAlly + .byte \battler + .4byte \jumpInstr + .endm + + .macro infatuatewithbattler battler:req, infatuateWith:req + callnative BS_InfatuateWithBattler + .byte \battler + .byte \infatuateWith + .endm + + .macro setlastuseditem battler:req + callnative BS_SetLastUsedItem + .byte \battler + .endm + + .macro trysetfairylock failInstr:req + callnative BS_TrySetFairyLock + .4byte \failInstr + .endm + + .macro getstatvalue stat:req + callnative BS_GetStatValue + .byte \stat + .endm + + .macro jumpiffullhp battler:req, jumpInstr:req + callnative BS_JumpIfFullHp + .byte \battler + .4byte \jumpInstr + .endm + + .macro tryfriskmessage + callnative BS_TryFriskMessage + .endm + + .macro settracedability battler:req + callnative BS_SetTracedAbility + .byte \battler + .endm + + .macro tryillusionoff battler:req + callnative BS_TryIllusionOff + .byte \battler + .endm + + .macro setspriteignore0hp ignore0HP:req + callnative BS_SetSpriteIgnore0Hp + .byte \ignore0HP + .endm + + .macro updatenick + callnative BS_UpdateNick + .endm + + .macro jumpifnotberry battler:req, jumpInstr:req + callnative BS_JumpIfNotBerry + .byte \battler + .4byte \jumpInstr + .endm + + .macro gravityonairbornemons + callnative BS_GravityOnAirborneMons + .endm + + .macro tryacupressure failInstr:req + callnative BS_TryAcupressure + .4byte \failInstr + .endm + + .macro cancelmultiturnmoves + callnative BS_CancelMultiTurnMoves + .endm + + .macro isrunningimpossible + callnative BS_IsRunningImpossible + .endm + + .macro getmovetarget + callnative BS_GetMoveTarget + .endm + + @ Will jump to script pointer if the specified battler has or has not fainted. + .macro jumpiffainted battler:req, value:req, ptr:req + getbattlerfainted \battler + jumpifbyte CMP_EQUAL, gBattleCommunication, \value, \ptr + .endm + + .macro getbattlerfainted battler:req + callnative BS_GetBattlerFainted + .byte \battler + .endm + + .macro resetswitchinabilitybits + callnative BS_ResetSwitchInAbilityBits + .endm + + .macro updatechoicemoveonlvlup + callnative BS_UpdateChoiceMoveOnLvlUp + .endm + + .macro resetplayerfainted + callnative BS_ResetPlayerFainted + .endm + + .macro palaceflavortext + callnative BS_PalaceFlavorText + .endm + + .macro arenajudgmentwindow + callnative BS_ArenaJudgmentWindow + .endm + + .macro arenaopponentmonlost + callnative BS_ArenaOpponentMonLost + .endm + + .macro arenaplayermonlost + callnative BS_ArenaPlayerMonLost + .endm + + .macro arenabothmonslost + callnative BS_ArenaBothMonsLost + .endm + + .macro forfeityesnobox + callnative BS_ForfeitYesNoBox + .endm + + .macro drawarenareftextbox + callnative BS_DrawArenaRefTextBox + .endm + + .macro erasearenareftextbox + callnative BS_EraseArenaRefTextBox + .endm + + .macro arenajudgmentstring id:req + callnative BS_ArenaJudgmentString + .byte \id + .endm + + .macro arenawaitmessage id:req + callnative BS_ArenaWaitMessage + .byte \id + .endm + + .macro waitcry + callnative BS_WaitCry + .endm + + .macro returnopponentmon1toball + callnative BS_ReturnOpponentMon1ToBall + .endm + + .macro returnopponentmon2toball + callnative BS_ReturnOpponentMon2ToBall + .endm + + .macro volumedown + callnative BS_VolumeDown + .endm + + .macro volumeup + callnative BS_VolumeUp + .endm + + .macro setalreadystatusedmoveattempt + callnative BS_SetAlreadyStatusedMoveAttempt + .endm + + .macro palacetryescapestatus + callnative BS_PalaceTryEscapeStatus + .endm + + .macro setteleportoutcome battler:req + callnative BS_SetTeleportOutcome + .byte \battler + .endm + + .macro playtrainerdefeatedmusic + callnative BS_PlayTrainerDefeatedMusic + .endm + + .macro stattextbuffer + callnative BS_StatTextBuffer + .endm + + .macro switchinabilities battler:req + callnative BS_SwitchinAbilities + .byte \battler + .endm + + .macro instanthpdrop + callnative BS_InstantHpDrop + .endm + + .macro clearstatus + callnative BS_ClearStatus + .endm + + .macro restoremovepp + callnative BS_RestoreMovePp + .endm + + .macro tryactivatereceiver battler:req + callnative BS_TryActivateReceiver + .byte \battler + .endm + + .macro tryactivatesoulheart + callnative BS_TryActivateSoulheart + .endm + + .macro playmoveanimation move:req + callnative BS_PlayMoveAnimation + .2byte \move + .endm + + .macro setluckychant failInstr:req + callnative BS_SetLuckyChant + .4byte \failInstr + .endm + + .macro suckerpunchcheck failInstr:req + callnative BS_SuckerPunchCheck + .4byte \failInstr + .endm + + .macro setsimplebeam failInstr:req + callnative BS_SetSimpleBeam + .4byte \failInstr + .endm + + .macro tryentrainment failInstr:req + callnative BS_TryEntrainment + .4byte \failInstr + .endm + + .macro setlastusedability + callnative BS_SetLastUsedAbility + .endm + + .macro invertstatstages + callnative BS_InvertStatStages + .endm + + .macro trymefirst failInstr:req + callnative BS_TryMeFirst + .4byte \failInstr + .endm + + .macro tryelectrify failInstr:req + callnative BS_TryElectrify + .4byte \failInstr + .endm + + .macro trysoak failInstr:req + callnative BS_TrySoak + .4byte \failInstr + .endm + + .macro handleformchange battler:req, case_:req + callnative BS_HandleFormChange + .byte \battler + .byte \case_ + .endm + + .macro trylastresort failInstr:req + callnative BS_TryLastResort + .4byte \failInstr + .endm + + .macro tryautotomize failInstr:req + callnative BS_TryAutotomize + .4byte \failInstr + .endm + + .macro tryinstruct failInstr:req + callnative BS_TryInstruct + .4byte \failInstr + .endm + + .macro showabilitypopup + callnative BS_ShowAbilityPopup + .endm + + .macro updateabilitypopup + callnative BS_UpdateAbilityPopup + .endm + + .macro jumpiftargetally jumpInstr:req + callnative BS_JumpIfTargetAlly + .4byte \jumpInstr + .endm + + .macro trypsychoshift failInstr:req sleepClauseFailInstr:req + callnative BS_TryPsychoShift + .4byte \failInstr + .4byte \sleepClauseFailInstr + .endm + + .macro curestatus battler:req + callnative BS_CureStatus + .byte \battler + .endm + + .macro powertrick + callnative BS_PowerTrick + .endm + + .macro tryafteryou failInstr:req + callnative BS_TryAfterYou + .4byte \failInstr + .endm + + .macro trybestow failInstr:req + callnative BS_TryBestow + .4byte \failInstr + .endm + + .macro handletrainerslidemsg battler:req, case_:req + callnative BS_HandleTrainerSlideMsg + .byte \battler + .byte \case_ + .endm + + .macro trytrainerslidemsgfirstoff battler:req + callnative BS_TryTrainerSlideMsgFirstOff + .byte \battler + .endm + + .macro trytrainerslidemsglaston battler:req + callnative BS_TryTrainerSlideMsgLastOn + .byte \battler + .endm + + .macro setauroraveil + callnative BS_SetAuroraVeil + .endm + + .macro trythirdtype failInstr:req + callnative BS_TryThirdType + .4byte \failInstr + .endm + + .macro destroyabilitypopup + callnative BS_DestroyAbilityPopup + .endm + + .macro gettotemboost jumpInstr:req + callnative BS_GetTotemBoost + .4byte \jumpInstr + .endm + + .macro activateitemeffects + callnative BS_ActivateItemEffects + .endm + + .macro tryroomservice battler:req, failInstr:req + callnative BS_TryRoomService + .byte \battler + .4byte \failInstr + .endm + + .macro tryterrainseed battler:req, failInstr:req + callnative BS_TryTerrainSeed + .byte \battler + .4byte \failInstr + .endm + + .macro makeinvisible battler:req + callnative BS_MakeInvisible + .byte \battler + .endm + + .macro jumpifteamhealthy jumpInstr:req + callnative BS_JumpIfTeamHealthy + .4byte \jumpInstr + .endm + + .macro tryhealquarterhealth battler:req, failInstr:req + callnative BS_TryHealQuarterHealth + .byte \battler + .4byte \failInstr + .endm + + .macro jumpifunder200 jumpInstr:req + callnative BS_JumpIfUnder200 + .4byte \jumpInstr + .endm + + .macro setskydrop + callnative BS_SetSkyDrop + .endm + + .macro clearskydrop failInstr:req + callnative BS_ClearSkyDrop + .4byte \failInstr + .endm + + .macro skydropyawn + callnative BS_SkyDropYawn + .endm + + .macro jumpifpranksterblocked jumpInstr:req + callnative BS_JumpIfPranksterBlocked + .4byte \jumpInstr + .endm + + .macro trytoclearprimalweather + callnative BS_TryToClearPrimalWeather + .endm + + .macro tryendneutralizinggas + callnative BS_TryEndNeutralizingGas + .endm + + .macro getrototillertargets failInstr:req + callnative BS_GetRototillerTargets + .4byte \failInstr + .endm + + .macro jumpifnotrototilleraffected jumpInstr:req + callnative BS_JumpIfNotRototillerAffected + .4byte \jumpInstr + .endm + + .macro consumeberry battler:req, fromBattler:req + callnative BS_ConsumeBerry + .byte \battler + .byte \fromBattler + .endm + + .macro jumpifweatheraffected flags:req, jumpInstr:req + callnative BS_JumpIfWeatherAffected + .2byte \flags + .4byte \jumpInstr + .endm + + .macro jumpifspecies species:req, jumpInstr:req + callnative BS_JumpIfSpecies + .2byte \species + .4byte \jumpInstr + .endm + + .macro jumpifleafguardprotected battler:req, jumpInstr:req + callnative BS_JumpIfLeafGuardProtected + .byte \battler + .4byte \jumpInstr + .endm + + .macro setattackertostickywebuser + callnative BS_SetAttackerToStickyWebUser + .endm + + .macro cutonethirdhpandraisestats failInstr:req + callnative BS_CutOneThirdHpAndRaiseStats + .4byte \failInstr + .endm + + .macro checkpoltergeist failInstr:req + callnative BS_CheckPoltergeist + .4byte \failInstr + .endm + + .macro trynoretreat failInstr:req + callnative BS_TryNoRetreat + .4byte \failInstr + .endm + + .macro curecertainstatuses + callnative BS_CureCertainStatuses + .endm + + .macro tryresetnegativestatstages + callnative BS_TryResetNegativeStatStages + .endm + + .macro jumpiflastuseditemberry jumpInstr:req + callnative BS_JumpIfLastUsedItemBerry + .4byte \jumpInstr + .endm + + .macro savebattleritem + callnative BS_SaveBattlerItem + .endm + + .macro restorebattleritem + callnative BS_RestoreBattlerItem + .endm + + .macro battleritemtolastuseditem + callnative BS_BattlerItemToLastUsedItem + .endm + .macro setallytonexttarget jumpInstr:req jumpifbyte CMP_GREATER_THAN, gBattlerTarget, 0x1, 1f addbyte gBattlerTarget, 0x2 @@ -2464,40 +2479,12 @@ goto \jumpInstr .endm - .macro jumpifleafguardprotected battler:req, jumpInstr:req - various \battler, VARIOUS_JUMP_IF_LEAF_GUARD_PROTECTED - .4byte \jumpInstr - .endm - .macro jumpifsafeguard jumpInstr:req jumpifability BS_ATTACKER, ABILITY_INFILTRATOR, 1f jumpifsideaffecting BS_TARGET, SIDE_STATUS_SAFEGUARD, \jumpInstr 1: .endm - @ Will jump to script pointer if the target weighs less than 200 kg, or 441 lbs. - .macro jumpifunder200 battler:req, failInstr:req - various \battler, VARIOUS_JUMP_IF_UNDER_200 - .4byte \failInstr - .endm - - @ Sets the sky drop status and does all other necessary operations - .macro setskydrop - various 0, VARIOUS_SET_SKY_DROP - .endm - - @ Clears the sky drop status and does all other necessary operations. - @ If the target fainted in before this script is called, it goes to the given script. - .macro clearskydrop failInstr:req - various 0, VARIOUS_CLEAR_SKY_DROP - .4byte \failInstr - .endm - - @ Accounts for if the target of Sky Drop was in confuse_lock when the attacker falls asleep due to Yawn. - .macro skydropyawn - various 0, VARIOUS_SKY_DROP_YAWN - .endm - @ Tries to increase or decrease a battler's stat's stat stage by a specified amount. If impossible, jumps to \script. .macro modifybattlerstatstage battler:req, stat:req, mode:req, amount:req, script:req, animation:req, customString @@ -2528,12 +2515,6 @@ waitmessage B_WAIT_TIME_LONG .endm - @ Will jump to script pointer if the specified battler has or has not fainted. - .macro jumpiffainted battler:req, value:req, ptr:req - getbattlerfainted \battler - jumpifbyte CMP_EQUAL, gBattleCommunication, \value, \ptr - .endm - .macro flushtextbox printstring STRINGID_EMPTYSTRING3 waitmessage 1 diff --git a/data/battle_scripts_1.s b/data/battle_scripts_1.s index 695535ab4f..d0a8d640ef 100644 --- a/data/battle_scripts_1.s +++ b/data/battle_scripts_1.s @@ -621,7 +621,7 @@ BattleScript_AffectionBasedStatus_HealFrostbiteString: printstring STRINGID_ATTACKERHEALEDITSFROSTBITE BattleScript_AffectionBasedStatusHeal_Continue: waitmessage B_WAIT_TIME_LONG - clearstatus BS_ATTACKER + clearstatus waitstate updatestatusicon BS_ATTACKER waitstate @@ -677,7 +677,7 @@ BattleScript_EffectSkyDrop:: attackstring jumpifsubstituteblocks BattleScript_ButItFailed jumpiftargetally BattleScript_ButItFailed - jumpifunder200 BS_TARGET, BattleScript_SkyDropWork + jumpifunder200 BattleScript_SkyDropWork pause B_WAIT_TIME_SHORT printstring STRINGID_TARGETTOOHEAVY waitmessage B_WAIT_TIME_LONG @@ -753,14 +753,14 @@ BattleScript_EffectFling:: jumpiflastuseditemholdeffect HOLD_EFFECT_WHITE_HERB, 0, BattleScript_FlingWhiteHerb goto BattleScript_FlingEnd BattleScript_EffectFlingConsumeBerry: - savebattleritem BS_TARGET - battleritemtolastuseditem BS_TARGET + savebattleritem + battleritemtolastuseditem setbyte sBERRY_OVERRIDE, 1 @ override the requirements for eating berries orword gHitMarker, HITMARKER_DISABLE_ANIMATION consumeberry BS_TARGET, TRUE bicword gHitMarker, HITMARKER_DISABLE_ANIMATION setbyte sBERRY_OVERRIDE, 0 - restorebattleritem BS_TARGET + restorebattleritem BattleScript_FlingEnd: tryfaintmon BS_TARGET trysymbiosis BS_ATTACKER @@ -785,7 +785,7 @@ BattleScript_FlingLightBall: seteffectsecondary BS_ATTACKER, BS_TARGET, MOVE_EFFECT_PARALYSIS goto BattleScript_FlingEnd BattleScript_FlingMentalHerb: - curecertainstatuses BS_TARGET + curecertainstatuses savetarget copybyte gBattlerAttacker, gBattlerTarget playanimation BS_ATTACKER, B_ANIM_HELD_ITEM_EFFECT, NULL @@ -801,7 +801,7 @@ BattleScript_FlingToxicOrb: seteffectsecondary BS_ATTACKER, BS_TARGET, MOVE_EFFECT_TOXIC goto BattleScript_FlingEnd BattleScript_FlingWhiteHerb: - tryresetnegativestatstages BS_TARGET + tryresetnegativestatstages swapattackerwithtarget printstring STRINGID_PKMNSTATUSNORMAL waitmessage B_WAIT_TIME_MED @@ -815,15 +815,15 @@ BattleScript_FlingMissed: goto BattleScript_MoveMissedPause BattleScript_EffectAuraWheel:: @ Aura Wheel can only be used by Morpeko - jumpifspecies BS_ATTACKER, SPECIES_MORPEKO_FULL_BELLY, BattleScript_EffectHit - jumpifspecies BS_ATTACKER, SPECIES_MORPEKO_HANGRY, BattleScript_EffectHit + jumpifspecies SPECIES_MORPEKO_FULL_BELLY, BattleScript_EffectHit + jumpifspecies SPECIES_MORPEKO_HANGRY, BattleScript_EffectHit goto BattleScript_PokemonCantUseTheMove BattleScript_EffectClangorousSoul:: attackcanceler attackstring ppreduce - cutonethirdhpraisestats BattleScript_ButItFailed + cutonethirdhpandraisestats BattleScript_ButItFailed orword gHitMarker, HITMARKER_IGNORE_SUBSTITUTE | HITMARKER_IGNORE_BIDE | HITMARKER_PASSIVE_DAMAGE | HITMARKER_IGNORE_DISGUISE attackanimation waitanimation @@ -863,7 +863,7 @@ BattleScript_EffectPoltergeist:: accuracycheck BattleScript_PrintMoveMissed, ACC_CURR_MOVE attackstring ppreduce - checkpoltergeist BS_TARGET, BattleScript_ButItFailed + checkpoltergeist BattleScript_ButItFailed printstring STRINGID_ABOUTTOUSEPOLTERGEIST waitmessage B_WAIT_TIME_LONG goto BattleScript_HitFromCritCalc @@ -892,7 +892,7 @@ BattleScript_EffectNoRetreat:: accuracycheck BattleScript_PrintMoveMissed, ACC_CURR_MOVE attackstring ppreduce - trynoretreat BS_TARGET, BattleScript_ButItFailed + trynoretreat BattleScript_ButItFailed attackanimation waitanimation call BattleScript_AllStatsUp @@ -908,8 +908,8 @@ BattleScript_BothCanNoLongerEscape:: return BattleScript_EffectHyperspaceFury:: - jumpifspecies BS_ATTACKER, SPECIES_HOOPA_UNBOUND, BattleScript_EffectHit - jumpifspecies BS_ATTACKER, SPECIES_HOOPA_CONFINED, BattleScript_ButHoopaCantUseIt + jumpifspecies SPECIES_HOOPA_UNBOUND, BattleScript_EffectHit + jumpifspecies SPECIES_HOOPA_CONFINED, BattleScript_ButHoopaCantUseIt goto BattleScript_PokemonCantUseTheMove BattleScript_ButHoopaCantUseIt: @@ -1024,7 +1024,7 @@ BattleScript_EffectJungleHealing:: attackcanceler attackstring ppreduce - jumpifteamhealthy BS_ATTACKER, BattleScript_ButItFailed + jumpifteamhealthy BattleScript_ButItFailed attackanimation waitanimation copybyte gBattlerTarget, gBattlerAttacker @@ -1170,7 +1170,7 @@ BattleScript_EffectStrengthSap:: waitmessage B_WAIT_TIME_LONG goto BattleScript_MoveEnd BattleScript_StrengthSapTryLower: - getstatvalue BS_TARGET, STAT_ATK + getstatvalue STAT_ATK jumpiffullhp BS_ATTACKER, BattleScript_StrengthSapMustLower BattleScript_StrengthSapAnimation: attackanimation @@ -1274,7 +1274,7 @@ BattleScript_VCreateStatLossRet: BattleScript_SpectralThiefSteal:: setbyte sB_ANIM_TURN, 1 - playmoveanimation BS_ATTACKER, MOVE_SPECTRAL_THIEF + playmoveanimation MOVE_SPECTRAL_THIEF waitanimation setbyte sB_ANIM_TURN, 0 printstring STRINGID_SPECTRALTHIEFSTEAL @@ -1440,7 +1440,7 @@ BattleScript_EffectAcupressure:: BattleScript_EffectAcupressureTry: attackstring ppreduce - tryaccupressure BS_TARGET, BattleScript_ButItFailed + tryacupressure BattleScript_ButItFailed attackanimation waitanimation statbuffchange BS_TARGET, STAT_CHANGE_CERTAIN, BattleScript_MoveEnd @@ -1458,7 +1458,7 @@ BattleScript_EffectThirdType:: accuracycheck BattleScript_PrintMoveMissed, ACC_CURR_MOVE attackstring ppreduce - trysetthirdtype BS_TARGET, BattleScript_ButItFailed + trythirdtype BattleScript_ButItFailed attackanimation waitanimation printstring STRINGID_THIRDTYPEADDED @@ -1516,7 +1516,7 @@ BattleScript_RototillerLoop: jumpifstat BS_TARGET, CMP_LESS_THAN, STAT_ATK, MAX_STAT_STAGE, BattleScript_RototillerCheckAffected jumpifstat BS_TARGET, CMP_EQUAL, STAT_SPATK, MAX_STAT_STAGE, BattleScript_RototillerCantRaiseMultipleStats BattleScript_RototillerCheckAffected: - jumpifnotrototilleraffected BS_TARGET, BattleScript_RototillerNoEffect + jumpifnotrototilleraffected BattleScript_RototillerNoEffect setstatchanger STAT_ATK, 1, FALSE statbuffchange BS_TARGET, STAT_CHANGE_ALLOW_PTR, BattleScript_RototillerTrySpAtk, BIT_SPATK jumpifbyte CMP_EQUAL, cMULTISTRING_CHOOSER, B_MSG_STAT_WONT_INCREASE, BattleScript_RototillerTrySpAtk @@ -1588,7 +1588,7 @@ BattleScript_EffectPowerTrick:: accuracycheck BattleScript_PrintMoveMissed, ACC_CURR_MOVE attackstring ppreduce - powertrick BS_ATTACKER + powertrick attackanimation waitanimation printstring STRINGID_PKMNSWITCHEDATKANDDEF @@ -1723,7 +1723,7 @@ BattleScript_AutotomizePrintString:: waitmessage B_WAIT_TIME_LONG BattleScript_AutotomizeWeightLoss:: jumpifmovehadnoeffect BattleScript_MoveEnd - tryautotomize BS_ATTACKER, BattleScript_MoveEnd + tryautotomize BattleScript_MoveEnd printstring STRINGID_BECAMENIMBLE waitmessage B_WAIT_TIME_LONG goto BattleScript_MoveEnd @@ -1877,7 +1877,7 @@ BattleScript_EffectLastResort:: attackcanceler attackstring ppreduce - jumpifcantuselastresort BS_ATTACKER, BattleScript_ButItFailed + trylastresort BattleScript_ButItFailed accuracycheck BattleScript_PrintMoveMissed, ACC_CURR_MOVE goto BattleScript_HitFromCritCalc @@ -1890,7 +1890,7 @@ BattleScript_EffectGrowth:: BattleScript_GrowthDoMoveAnim:: attackanimation waitanimation - jumpifweatheraffected BS_ATTACKER, B_WEATHER_SUN, BattleScript_GrowthAtk2 + jumpifweatheraffected B_WEATHER_SUN, BattleScript_GrowthAtk2 setstatchanger STAT_ATK, 1, FALSE goto BattleScript_GrowthAtk BattleScript_GrowthAtk2: @@ -1901,7 +1901,7 @@ BattleScript_GrowthAtk: printfromtable gStatUpStringIds waitmessage B_WAIT_TIME_LONG BattleScript_GrowthTrySpAtk:: - jumpifweatheraffected BS_ATTACKER, B_WEATHER_SUN, BattleScript_GrowthSpAtk2 + jumpifweatheraffected B_WEATHER_SUN, BattleScript_GrowthSpAtk2 setstatchanger STAT_SPATK, 1, FALSE goto BattleScript_GrowthSpAtk BattleScript_GrowthSpAtk2: @@ -2156,7 +2156,7 @@ BattleScript_EffectTopsyTurvy:: BattleScript_EffectTopsyTurvyWorks: attackanimation waitanimation - invertstatstages BS_TARGET + invertstatstages printstring STRINGID_TOPSYTURVYSWITCHEDSTATS waitmessage B_WAIT_TIME_LONG goto BattleScript_MoveEnd @@ -2210,7 +2210,7 @@ BattleScript_EffectEntrainment:: tryentrainment BattleScript_ButItFailed attackanimation waitanimation - setlastusedability BS_TARGET + setlastusedability printstring STRINGID_PKMNACQUIREDABILITY waitmessage B_WAIT_TIME_LONG goto BattleScript_MoveEnd @@ -2220,7 +2220,7 @@ BattleScript_EffectSimpleBeam:: accuracycheck BattleScript_PrintMoveMissed, ACC_CURR_MOVE attackstring ppreduce - setabilitysimple BS_TARGET, BattleScript_ButItFailed + setsimplebeam BattleScript_ButItFailed attackanimation waitanimation .if B_ABILITY_POP_UP == TRUE @@ -2233,7 +2233,7 @@ BattleScript_EffectSimpleBeam:: trytoclearprimalweather tryrevertweatherform flushtextbox - tryendneutralizinggas BS_TARGET + tryendneutralizinggas goto BattleScript_MoveEnd BattleScript_EffectSuckerPunch:: @@ -2246,7 +2246,7 @@ BattleScript_EffectLuckyChant:: attackcanceler attackstring ppreduce - setluckychant BS_ATTACKER, BattleScript_ButItFailed + setluckychant BattleScript_ButItFailed attackanimation waitanimation printstring STRINGID_SHIELDEDFROMCRITICALHITS @@ -2271,7 +2271,7 @@ BattleScript_EffectHealingWish:: ppreduce attackanimation waitanimation - instanthpdrop BS_ATTACKER + instanthpdrop setatkhptozero tryfaintmon BS_ATTACKER storehealingwish BS_ATTACKER @@ -2299,7 +2299,7 @@ BattleScript_HealingWishActivates:: goto BattleScript_EffectHealingWishRestore BattleScript_LunarDanceActivates:: setbyte cMULTISTRING_CHOOSER, 1 - restorepp BS_ATTACKER + restoremovepp BattleScript_EffectHealingWishRestore: printfromtable gHealingWishStringIds waitmessage B_WAIT_TIME_LONG @@ -2309,7 +2309,7 @@ BattleScript_EffectHealingWishRestore: manipulatedamage DMG_CHANGE_SIGN healthbarupdate BS_ATTACKER datahpupdate BS_ATTACKER - clearstatus BS_ATTACKER + clearstatus waitstate updatestatusicon BS_ATTACKER waitstate @@ -2335,7 +2335,7 @@ BattleScript_EffectWorrySeed:: trytoclearprimalweather tryrevertweatherform flushtextbox - tryendneutralizinggas BS_TARGET + tryendneutralizinggas goto BattleScript_MoveEnd BattleScript_EffectPowerSplit:: @@ -2467,7 +2467,7 @@ BattleScript_EffectGastroAcid:: trytoclearprimalweather tryrevertweatherform flushtextbox - tryendneutralizinggas BS_TARGET + tryendneutralizinggas goto BattleScript_MoveEnd BattleScript_EffectToxicSpikes:: @@ -2614,7 +2614,7 @@ BattleScript_GravityLoop: jumpifstatus3 BS_TARGET, STATUS3_ON_AIR | STATUS3_MAGNET_RISE | STATUS3_TELEKINESIS, BattleScript_GravityLoopDrop goto BattleScript_GravityLoopEnd BattleScript_GravityLoopDrop: - bringdownairbornebattler BS_TARGET + gravityonairbornemons printstring STRINGID_GRAVITYGROUNDING waitmessage B_WAIT_TIME_LONG BattleScript_GravityLoopEnd: @@ -2742,7 +2742,7 @@ BattleScript_MoveMissed:: BattleScript_EffectDarkVoid:: .if B_DARK_VOID_FAIL >= GEN_7 - jumpifspecies BS_ATTACKER, SPECIES_DARKRAI, BattleScript_EffectNonVolatileStatus + jumpifspecies SPECIES_DARKRAI, BattleScript_EffectNonVolatileStatus goto BattleScript_PokemonCantUseTheMove .endif @@ -2831,7 +2831,7 @@ BattleScript_InsomniaProtects: goto BattleScript_MoveEnd BattleScript_AlreadyAsleep:: - setalreadystatusedmoveattempt BS_ATTACKER + setalreadystatusedmoveattempt pause B_WAIT_TIME_SHORT printstring STRINGID_PKMNALREADYASLEEP waitmessage B_WAIT_TIME_LONG @@ -3158,7 +3158,7 @@ BattleScript_RestoreHp: goto BattleScript_MoveEnd BattleScript_AlreadyPoisoned:: - setalreadystatusedmoveattempt BS_ATTACKER + setalreadystatusedmoveattempt pause B_WAIT_TIME_LONG printstring STRINGID_PKMNALREADYPOISONED waitmessage B_WAIT_TIME_LONG @@ -3175,7 +3175,7 @@ BattleScript_EffectAuroraVeil:: attackcanceler attackstring ppreduce - setauroraveil BS_ATTACKER + setauroraveil goto BattleScript_PrintReflectLightScreenSafeguardString BattleScript_EffectLightScreen:: @@ -3213,7 +3213,7 @@ BattleScript_RestCantSleep:: goto BattleScript_MoveEnd BattleScript_RestIsAlreadyAsleep:: - setalreadystatusedmoveattempt BS_ATTACKER + setalreadystatusedmoveattempt pause B_WAIT_TIME_SHORT printstring STRINGID_PKMNALREADYASLEEP2 waitmessage B_WAIT_TIME_LONG @@ -3293,7 +3293,7 @@ BattleScript_EffectConfuse:: goto BattleScript_MoveEnd BattleScript_AlreadyConfused:: - setalreadystatusedmoveattempt BS_ATTACKER + setalreadystatusedmoveattempt pause B_WAIT_TIME_SHORT printstring STRINGID_PKMNALREADYCONFUSED waitmessage B_WAIT_TIME_LONG @@ -3395,7 +3395,7 @@ BattleScript_VoltAbsorbHeal: goto BattleScript_MoveHPDrain BattleScript_AlreadyParalyzed:: - setalreadystatusedmoveattempt BS_ATTACKER + setalreadystatusedmoveattempt pause B_WAIT_TIME_SHORT printstring STRINGID_PKMNISALREADYPARALYZED waitmessage B_WAIT_TIME_LONG @@ -3414,7 +3414,7 @@ BattleScript_EffectTwoTurnsAttack:: tryfiretwoturnmovewithoutcharging BS_ATTACKER, BattleScript_EffectHit @ e.g. Solar Beam call BattleScript_FirstChargingTurn tryfiretwoturnmoveaftercharging BS_ATTACKER, BattleScript_TwoTurnMovesSecondTurn @ e.g. Electro Shot - jumpifholdeffect BS_ATTACKER, HOLD_EFFECT_POWER_HERB, BattleScript_TwoTurnMovesSecondPowerHerbActivates + jumpifholdeffect BS_ATTACKER, HOLD_EFFECT_POWER_HERB, BattleScript_TwoTurnMovesSecondPowerHerbActivates, TRUE goto BattleScript_MoveEnd BattleScript_EffectGeomancy:: @@ -3515,7 +3515,7 @@ BattleScript_SubstituteString:: waitmessage B_WAIT_TIME_LONG goto BattleScript_MoveEnd BattleScript_AlreadyHasSubstitute:: - setalreadystatusedmoveattempt BS_ATTACKER + setalreadystatusedmoveattempt pause B_WAIT_TIME_SHORT printstring STRINGID_PKMNHASSUBSTITUTE waitmessage B_WAIT_TIME_LONG @@ -3870,7 +3870,7 @@ BattleScript_CurseEnd:: goto BattleScript_MoveEnd BattleScript_GhostCurse:: jumpifbytenotequal gBattlerAttacker, gBattlerTarget, BattleScript_DoGhostCurse - getmovetarget BS_ATTACKER + getmovetarget BattleScript_DoGhostCurse:: attackcanceler attackstring @@ -3944,7 +3944,7 @@ BattleScript_EffectPerishSong:: setbyte gBattlerTarget, 0 BattleScript_PerishSongLoop:: jumpifblockedbysoundproof BS_TARGET, BattleScript_PerishSongBlocked - jumpifpranksterblocked BS_TARGET, BattleScript_PerishSongNotAffected + jumpifpranksterblocked BattleScript_PerishSongNotAffected BattleScript_PerishSongLoopIncrement:: addbyte gBattlerTarget, 1 jumpifbytenotequal gBattlerTarget, gBattlersCount, BattleScript_PerishSongLoop @@ -4269,14 +4269,14 @@ BattleScript_EffectTeleport:: attackcanceler attackstring ppreduce - getifcantrunfrombattle BS_ATTACKER + isrunningimpossible jumpifbyte CMP_EQUAL, gBattleCommunication, BATTLE_RUN_FORBIDDEN, BattleScript_ButItFailed jumpifbyte CMP_EQUAL, gBattleCommunication, BATTLE_RUN_FAILURE, BattleScript_PrintAbilityMadeIneffective attackanimation waitanimation printstring STRINGID_PKMNFLEDFROMBATTLE waitmessage B_WAIT_TIME_LONG - setoutcomeonteleport BS_ATTACKER + setteleportoutcome BS_ATTACKER goto BattleScript_MoveEnd BattleScript_EffectBeatUp:: @@ -4557,7 +4557,7 @@ BattleScript_EffectNonVolatileStatus:: goto BattleScript_MoveEnd BattleScript_AlreadyBurned:: - setalreadystatusedmoveattempt BS_ATTACKER + setalreadystatusedmoveattempt pause B_WAIT_TIME_SHORT printstring STRINGID_PKMNALREADYHASBURN waitmessage B_WAIT_TIME_LONG @@ -5074,7 +5074,7 @@ BattleScript_FaintAttacker:: cleareffectsonfaint BS_ATTACKER tryactivatesoulheart tryactivatereceiver BS_ATTACKER - trytrainerslidefirstdownmsg BS_ATTACKER + trytrainerslidemsgfirstoff BS_ATTACKER return BattleScript_FaintTarget:: @@ -5088,7 +5088,7 @@ BattleScript_FaintTarget:: cleareffectsonfaint BS_TARGET tryactivatesoulheart tryactivatereceiver BS_TARGET - trytrainerslidefirstdownmsg BS_TARGET + trytrainerslidemsgfirstoff BS_TARGET return BattleScript_GiveExp:: @@ -5134,7 +5134,7 @@ BattleScript_FaintedMonTryChoose: jumpifbyte CMP_EQUAL, gBattleCommunication, PARTY_SIZE, BattleScript_FaintedMonSendOutNew @ Switch Pokémon before opponent atknameinbuff1 - resetswitchinabilitybits BS_ATTACKER + resetswitchinabilitybits hpthresholds2 BS_ATTACKER printstring STRINGID_RETURNMON switchoutabilities BS_ATTACKER @@ -5164,7 +5164,7 @@ BattleScript_FaintedMonSendOutNew: switchinanim BS_FAINTED, FALSE, FALSE waitstate resetplayerfainted - trytrainerslidelastonmsg BS_FAINTED + trytrainerslidemsglaston BS_FAINTED jumpifbytenotequal sSHIFT_SWITCHED, sZero, BattleScript_FaintedMonShiftSwitched BattleScript_FaintedMonSendOutNewEnd: switchineffects BS_FAINTED @@ -5264,9 +5264,9 @@ BattleScript_CheckDomeDrew:: jumpifbyte CMP_EQUAL, gBattleOutcome, B_OUTCOME_DREW, BattleScript_LocalBattleLostEnd_ BattleScript_LocalBattleLostPrintTrainersWinText:: jumpifnotbattletype BATTLE_TYPE_TRAINER, BattleScript_LocalBattleLostPrintWhiteOut - returnopponentmon1toball BS_ATTACKER + returnopponentmon1toball waitstate - returnopponentmon2toball BS_ATTACKER + returnopponentmon2toball waitstate trainerslidein BS_OPPONENT1 waitstate @@ -5283,9 +5283,9 @@ BattleScript_LocalBattleLostEnd_:: end2 BattleScript_FrontierLinkBattleLost:: - returnopponentmon1toball BS_ATTACKER + returnopponentmon1toball waitstate - returnopponentmon2toball BS_ATTACKER + returnopponentmon2toball waitstate trainerslidein BS_OPPONENT1 waitstate @@ -5312,7 +5312,7 @@ BattleScript_LinkBattleWonOrLostWaitEnd:: end2 BattleScript_TowerLinkBattleWon:: - playtrainerdefeatbgm BS_ATTACKER + playtrainerdefeatedmusic printstring STRINGID_BATTLEEND waitmessage B_WAIT_TIME_LONG trainerslidein BS_OPPONENT1 @@ -5456,7 +5456,7 @@ BattleScript_LearnedNewMove:: fanfare MUS_LEVEL_UP printstring STRINGID_PKMNLEARNEDMOVE waitmessage B_WAIT_TIME_LONG - updatechoicemoveonlvlup BS_ATTACKER + updatechoicemoveonlvlup goto BattleScript_TryLearnMoveLoop BattleScript_LearnMoveReturn:: return @@ -5691,7 +5691,7 @@ BattleScript_RoarSuccessSwitch_Ret: BattleScript_RoarSuccessEndBattle:: call BattleScript_RoarSuccessRet setbyte sSWITCH_CASE, B_SWITCH_NORMAL - setoutcomeonteleport BS_ATTACKER + setteleportoutcome BS_ATTACKER finishaction BattleScript_RoarSuccessRet: @@ -6661,12 +6661,12 @@ BattleScript_IllusionOffEnd3:: end3 BattleScript_IllusionOff:: - spriteignore0hp TRUE + setspriteignore0hp TRUE playanimation BS_SCRIPTING, B_ANIM_ILLUSION_OFF waitanimation - updatenick BS_SCRIPTING + updatenick waitstate - spriteignore0hp FALSE + setspriteignore0hp FALSE printstring STRINGID_ILLUSIONWOREOFF waitmessage B_WAIT_TIME_LONG return @@ -6814,7 +6814,7 @@ BattleScript_MoveUsedIsParalyzed:: printstring STRINGID_PKMNISPARALYZED waitmessage B_WAIT_TIME_LONG statusanimation BS_ATTACKER - cancelmultiturnmoves BS_ATTACKER + cancelmultiturnmoves goto BattleScript_MoveEnd BattleScript_PowderMoveNoEffect:: @@ -6831,7 +6831,7 @@ BattleScript_PowderMoveNoEffectPrint: printstring STRINGID_ITDOESNTAFFECT BattleScript_PowderMoveNoEffectWaitMsg: waitmessage B_WAIT_TIME_LONG - cancelmultiturnmoves BS_ATTACKER + cancelmultiturnmoves setmoveresultflags MOVE_RESULT_FAILED goto BattleScript_MoveEnd @@ -6849,7 +6849,7 @@ BattleScript_TryActivateSteadFast: call BattleScript_AbilityPopUp statbuffchange BS_ATTACKER, STAT_CHANGE_ALLOW_PTR, BattleScript_MoveUsedFlinchedEnd setbyte gBattleCommunication STAT_SPEED - stattextbuffer BS_ATTACKER + stattextbuffer printstring STRINGID_ATTACKERABILITYSTATRAISE waitmessage B_WAIT_TIME_LONG goto BattleScript_MoveUsedFlinchedEnd @@ -6871,7 +6871,7 @@ BattleScript_MoveUsedIsConfused:: volatileanimation BS_ATTACKER, VOLATILE_CONFUSION jumpifbyte CMP_EQUAL, cMULTISTRING_CHOOSER, FALSE, BattleScript_MoveUsedIsConfusedRet BattleScript_DoSelfConfusionDmg:: - cancelmultiturnmoves BS_ATTACKER + cancelmultiturnmoves adjustdamage printstring STRINGID_ITHURTCONFUSION waitmessage B_WAIT_TIME_LONG @@ -6893,7 +6893,7 @@ BattleScript_MoveUsedPowder:: attackstring ppreduce pause B_WAIT_TIME_SHORT - cancelmultiturnmoves BS_ATTACKER + cancelmultiturnmoves volatileanimation BS_ATTACKER, VOLATILE_POWDER waitanimation effectivenesssound @@ -7146,7 +7146,7 @@ BattleScript_AbilityPopUpTarget:: BattleScript_AbilityPopUp:: tryactivateabilityshield BS_ABILITY_BATTLER .if B_ABILITY_POP_UP == TRUE - showabilitypopup BS_ABILITY_BATTLER + showabilitypopup pause B_WAIT_TIME_SHORT .endif recordability BS_ABILITY_BATTLER @@ -7159,10 +7159,10 @@ BattleScript_AbilityPopUpScripting: BattleScript_AbilityPopUpOverwriteThenNormal: setbyte sFIXED_ABILITY_POPUP, TRUE - showabilitypopup BS_ABILITY_BATTLER + showabilitypopup pause B_WAIT_TIME_SHORT sethword sABILITY_OVERWRITE, 0 - updateabilitypopup BS_ABILITY_BATTLER + updateabilitypopup pause B_WAIT_TIME_SHORT recordability BS_ABILITY_BATTLER destroyabilitypopup @@ -7229,7 +7229,7 @@ BattleScript_EmergencyExitWild:: .endif playanimation BS_SCRIPTING, B_ANIM_SLIDE_OFFSCREEN waitanimation - setoutcomeonteleport BS_SCRIPTING + setteleportoutcome BS_SCRIPTING finishaction return @@ -7260,7 +7260,7 @@ BattleScript_EmergencyExitWildEnd2:: pause B_WAIT_TIME_LONG playanimation BS_ATTACKER, B_ANIM_SLIDE_OFFSCREEN waitanimation - setoutcomeonteleport BS_ATTACKER + setteleportoutcome BS_ATTACKER finishaction end2 @@ -7667,7 +7667,7 @@ BattleScript_ActivateTerrainEffects: setbyte gBattlerAttacker, 0 BattleScript_ActivateTerrainSeed: copyarraywithindex gBattlerTarget, gBattlerByTurnOrder, gBattlerAttacker, 1 - doterrainseed BS_TARGET, BattleScript_ActivateTerrainAbility + tryterrainseed BS_TARGET, BattleScript_ActivateTerrainAbility removeitem BS_TARGET BattleScript_ActivateTerrainAbility: activateterrainchangeabilities BS_TARGET @@ -8118,7 +8118,7 @@ BattleScript_FriskActivates:: saveattacker savetarget copybyte gBattlerAttacker, sBATTLER - tryfriskmsg BS_SCRIPTING + tryfriskmessage restoreattacker restoretarget end3 @@ -8126,7 +8126,7 @@ BattleScript_FriskActivates:: BattleScript_ImposterActivates:: call BattleScript_AbilityPopUp transformdataexecution - playmoveanimation BS_ATTACKER, MOVE_TRANSFORM + playmoveanimation MOVE_TRANSFORM waitanimation printstring STRINGID_IMPOSTERTRANSFORM waitmessage B_WAIT_TIME_LONG @@ -8298,7 +8298,7 @@ BattleScript_MoveUsedLoafingAround:: @ Skip ahead if not the Battle Palace message jumpifbyte CMP_NOT_EQUAL, cMULTISTRING_CHOOSER, B_MSG_INCAPABLE_OF_POWER, BattleScript_MoveUsedLoafingAroundMsg setbyte gBattleCommunication, 0 - palacetryescapestatus BS_ATTACKER + palacetryescapestatus setbyte cMULTISTRING_CHOOSER, B_MSG_INCAPABLE_OF_POWER BattleScript_MoveUsedLoafingAroundMsg:: printfromtable gInobedientStringIds @@ -8669,7 +8669,7 @@ BattleScript_FlushMessageBox:: BattleScript_PalacePrintFlavorText:: setbyte gBattleCommunication + 1, 0 BattleScript_PalaceTryBattlerFlavorText:: - palaceflavortext BS_ATTACKER @ BS_ATTACKER here overwritten by gBattleCommunication + 1 + palaceflavortext jumpifbyte CMP_NOT_EQUAL, gBattleCommunication, TRUE, BattleScript_PalaceEndFlavorText printfromtable gBattlePalaceFlavorTextTable waitmessage B_WAIT_TIME_LONG @@ -8681,16 +8681,16 @@ BattleScript_PalaceEndFlavorText:: end2 BattleScript_ArenaTurnBeginning:: - waitcry BS_ATTACKER + waitcry volumedown playse SE_ARENA_TIMEUP1 pause 8 playse SE_ARENA_TIMEUP1 - arenadrawreftextbox + drawarenareftextbox arenajudgmentstring B_MSG_REF_COMMENCE_BATTLE arenawaitmessage B_MSG_REF_COMMENCE_BATTLE pause B_WAIT_TIME_LONG - arenaerasereftextbox + erasearenareftextbox volumeup end2 @@ -8704,7 +8704,7 @@ BattleScript_ArenaDoJudgment:: pause 8 playse SE_ARENA_TIMEUP1 pause B_WAIT_TIME_LONG - arenadrawreftextbox + drawarenareftextbox arenajudgmentstring B_MSG_REF_THATS_IT arenawaitmessage B_MSG_REF_THATS_IT pause B_WAIT_TIME_LONG @@ -8727,11 +8727,11 @@ BattleScript_ArenaDoJudgment:: arenajudgmentstring B_MSG_REF_PLAYER_WON arenawaitmessage B_MSG_REF_PLAYER_WON arenajudgmentwindow - arenaerasereftextbox + erasearenareftextbox printstring STRINGID_DEFEATEDOPPONENTBYREFEREE waitmessage B_WAIT_TIME_LONG playfaintcry BS_OPPONENT1 - waitcry BS_ATTACKER + waitcry dofaintanimation BS_OPPONENT1 cleareffectsonfaint BS_OPPONENT1 arenaopponentmonlost @@ -8741,11 +8741,11 @@ BattleScript_ArenaJudgmentPlayerLoses: arenajudgmentstring B_MSG_REF_OPPONENT_WON arenawaitmessage B_MSG_REF_OPPONENT_WON arenajudgmentwindow - arenaerasereftextbox + erasearenareftextbox printstring STRINGID_LOSTTOOPPONENTBYREFEREE waitmessage B_WAIT_TIME_LONG playfaintcry BS_PLAYER1 - waitcry BS_ATTACKER + waitcry dofaintanimation BS_PLAYER1 cleareffectsonfaint BS_PLAYER1 arenaplayermonlost @@ -8755,23 +8755,23 @@ BattleScript_ArenaJudgmentDraw: arenajudgmentstring B_MSG_REF_DRAW arenawaitmessage B_MSG_REF_DRAW arenajudgmentwindow - arenaerasereftextbox + erasearenareftextbox printstring STRINGID_TIEDOPPONENTBYREFEREE waitmessage B_WAIT_TIME_LONG playfaintcry BS_PLAYER1 - waitcry BS_ATTACKER + waitcry dofaintanimation BS_PLAYER1 cleareffectsonfaint BS_PLAYER1 playfaintcry BS_OPPONENT1 - waitcry BS_ATTACKER + waitcry dofaintanimation BS_OPPONENT1 cleareffectsonfaint BS_OPPONENT1 - arenabothmonlost + arenabothmonslost end2 BattleScript_AskIfWantsToForfeitMatch:: printselectionstring STRINGID_QUESTIONFORFEITMATCH - forfeityesnobox BS_ATTACKER + forfeityesnobox endselectionscript BattleScript_PrintPlayerForfeited:: @@ -9074,7 +9074,7 @@ BattleScript_Pickpocket:: swapattackerwithtarget call BattleScript_ItemSteal swapattackerwithtarget - activateitemeffects BS_TARGET + activateitemeffects return BattleScript_PickpocketPrevented: @@ -9536,7 +9536,7 @@ BattleScript_RaiseCritAlliesEnd: goto BattleScript_MoveEnd BattleScript_EffectHealOneSixthAllies:: - jumpifteamhealthy BS_ATTACKER, BattleScript_MoveEnd + jumpifteamhealthy BattleScript_MoveEnd savetarget copybyte gBattlerTarget, gBattlerAttacker BattleScript_HealOneSixthAlliesLoop: @@ -9617,11 +9617,11 @@ BattleScript_DynamaxEnds:: BattleScript_DynamaxEnds_Ret:: flushtextbox - spriteignore0hp TRUE + setspriteignore0hp TRUE updatedynamax playanimation BS_SCRIPTING, B_ANIM_FORM_CHANGE waitanimation - spriteignore0hp FALSE + setspriteignore0hp FALSE pause B_WAIT_TIME_SHORT return @@ -9720,7 +9720,7 @@ BattleScript_SleepClausePreventsEnd:: BattleScript_QuestionForfeitBattle:: printselectionstring STRINGID_QUESTIONFORFEITBATTLE - forfeityesnobox BS_ATTACKER + forfeityesnobox endselectionscript BattleScript_ForfeitBattleGaveMoney:: diff --git a/data/battle_scripts_2.s b/data/battle_scripts_2.s index 004b4ca8ab..0e0f43893e 100644 --- a/data/battle_scripts_2.s +++ b/data/battle_scripts_2.s @@ -131,7 +131,7 @@ BattleScript_PokeFluteEnd:: BattleScript_ItemSetMist:: call BattleScript_UseItemMessage setmist - playmoveanimation BS_ATTACKER, MOVE_MIST + playmoveanimation MOVE_MIST waitanimation printfromtable gMistUsedStringIds waitmessage B_WAIT_TIME_LONG @@ -142,7 +142,7 @@ BattleScript_ItemSetFocusEnergy:: jumpifvolatile BS_ATTACKER, VOLATILE_DRAGON_CHEER, BattleScript_ButItFailed jumpifvolatile BS_ATTACKER, VOLATILE_FOCUS_ENERGY, BattleScript_ButItFailed setfocusenergy BS_ATTACKER - playmoveanimation BS_ATTACKER, MOVE_FOCUS_ENERGY + playmoveanimation MOVE_FOCUS_ENERGY waitanimation copybyte sBATTLER, gBattlerAttacker printstring STRINGID_PKMNUSEDXTOGETPUMPED diff --git a/include/constants/battle_script_commands.h b/include/constants/battle_script_commands.h index 02f0bc2813..2d50ec1e4f 100644 --- a/include/constants/battle_script_commands.h +++ b/include/constants/battle_script_commands.h @@ -88,123 +88,10 @@ #define CMP_COMMON_BITS 4 #define CMP_NO_COMMON_BITS 5 +// Veriouses have been deprecated but the enum and function will be supported for one more release cycle enum CmdVarious { - VARIOUS_CANCEL_MULTI_TURN_MOVES, - VARIOUS_IS_RUNNING_IMPOSSIBLE, - VARIOUS_GET_MOVE_TARGET, - VARIOUS_GET_BATTLER_FAINTED, - VARIOUS_RESET_SWITCH_IN_ABILITY_BITS, - VARIOUS_UPDATE_CHOICE_MOVE_ON_LVL_UP, - VARIOUS_RESET_PLAYER_FAINTED, - VARIOUS_PALACE_FLAVOR_TEXT, - VARIOUS_ARENA_JUDGMENT_WINDOW, - VARIOUS_ARENA_OPPONENT_MON_LOST, - VARIOUS_ARENA_PLAYER_MON_LOST, - VARIOUS_ARENA_BOTH_MONS_LOST, - VARIOUS_EMIT_YESNOBOX, - VARIOUS_DRAW_ARENA_REF_TEXT_BOX, - VARIOUS_ERASE_ARENA_REF_TEXT_BOX, - VARIOUS_ARENA_JUDGMENT_STRING, - VARIOUS_ARENA_WAIT_STRING, - VARIOUS_WAIT_CRY, - VARIOUS_RETURN_OPPONENT_MON1, - VARIOUS_RETURN_OPPONENT_MON2, - VARIOUS_VOLUME_DOWN, - VARIOUS_VOLUME_UP, - VARIOUS_SET_ALREADY_STATUS_MOVE_ATTEMPT, - VARIOUS_PALACE_TRY_ESCAPE_STATUS, - VARIOUS_SET_TELEPORT_OUTCOME, - VARIOUS_PLAY_TRAINER_DEFEATED_MUSIC, - VARIOUS_STAT_TEXT_BUFFER, - VARIOUS_SWITCHIN_ABILITIES, - VARIOUS_INSTANT_HP_DROP, - VARIOUS_CLEAR_STATUS, - VARIOUS_RESTORE_PP, - VARIOUS_PLAY_MOVE_ANIMATION, - VARIOUS_SET_LUCKY_CHANT, - VARIOUS_SUCKER_PUNCH_CHECK, - VARIOUS_SET_SIMPLE_BEAM, - VARIOUS_TRY_ENTRAINMENT, - VARIOUS_SET_LAST_USED_ABILITY, - VARIOUS_INVERT_STAT_STAGES, - VARIOUS_TRY_ME_FIRST, - VARIOUS_JUMP_IF_BATTLE_END, - VARIOUS_TRY_ELECTRIFY, - VARIOUS_TRY_SOAK, - VARIOUS_TRY_LAST_RESORT, - VARIOUS_TRY_AUTOTOMIZE, - VARIOUS_ABILITY_POPUP, - VARIOUS_JUMP_IF_TARGET_ALLY, - VARIOUS_TRY_SYNCHRONOISE, - VARIOUS_PSYCHO_SHIFT, - VARIOUS_CURE_STATUS, - VARIOUS_POWER_TRICK, - VARIOUS_AFTER_YOU, - VARIOUS_BESTOW, - VARIOUS_JUMP_IF_NOT_GROUNDED, - VARIOUS_HANDLE_TRAINER_SLIDE_MSG, - VARIOUS_TRY_TRAINER_SLIDE_MSG_FIRST_OFF, - VARIOUS_TRY_TRAINER_SLIDE_MSG_LAST_ON, - VARIOUS_SET_AURORA_VEIL, - VARIOUS_TRY_THIRD_TYPE, - VARIOUS_ACUPRESSURE, - VARIOUS_GRAVITY_ON_AIRBORNE_MONS, - VARIOUS_CHECK_IF_GRASSY_TERRAIN_HEALS, - VARIOUS_JUMP_IF_ROAR_FAILS, - VARIOUS_TRY_INSTRUCT, - VARIOUS_JUMP_IF_NOT_BERRY, - VARIOUS_TRACE_ABILITY, - VARIOUS_UPDATE_NICK, - VARIOUS_TRY_ILLUSION_OFF, - VARIOUS_SET_SPRITEIGNORE0HP, - VARIOUS_HANDLE_FORM_CHANGE, - VARIOUS_GET_STAT_VALUE, - VARIOUS_JUMP_IF_FULL_HP, - VARIOUS_LOSE_TYPE, - VARIOUS_TRY_ACTIVATE_SOULHEART, - VARIOUS_TRY_ACTIVATE_RECEIVER, - VARIOUS_TRY_FRISK, - VARIOUS_JUMP_IF_SHIELDS_DOWN_PROTECTED, - VARIOUS_TRY_FAIRY_LOCK, - VARIOUS_JUMP_IF_NO_ALLY, - VARIOUS_JUMP_IF_HOLD_EFFECT, - VARIOUS_INFATUATE_WITH_BATTLER, - VARIOUS_SET_LAST_USED_ITEM, - VARIOUS_JUMP_IF_ABSENT, - VARIOUS_DESTROY_ABILITY_POPUP, - VARIOUS_TOTEM_BOOST, - VARIOUS_MOVEEND_ITEM_EFFECTS, - VARIOUS_TERRAIN_SEED, - VARIOUS_MAKE_INVISIBLE, - VARIOUS_ROOM_SERVICE, - VARIOUS_JUMP_IF_TEAM_HEALTHY, - VARIOUS_TRY_HEAL_QUARTER_HP, - VARIOUS_JUMP_IF_PRANKSTER_BLOCKED, - VARIOUS_TRY_TO_CLEAR_PRIMAL_WEATHER, - VARIOUS_GET_ROTOTILLER_TARGETS, - VARIOUS_JUMP_IF_NOT_ROTOTILLER_AFFECTED, - VARIOUS_CONSUME_BERRY, - VARIOUS_JUMP_IF_CANT_REVERT_TO_PRIMAL, - VARIOUS_JUMP_IF_SPECIES, - VARIOUS_UPDATE_ABILITY_POPUP, - VARIOUS_JUMP_IF_WEATHER_AFFECTED, - VARIOUS_JUMP_IF_LEAF_GUARD_PROTECTED, - VARIOUS_SET_ATTACKER_STICKY_WEB_USER, - VARIOUS_TRY_NO_RETREAT, - VARIOUS_CHECK_POLTERGEIST, - VARIOUS_CUT_1_3_HP_RAISE_STATS, - VARIOUS_TRY_END_NEUTRALIZING_GAS, - VARIOUS_JUMP_IF_UNDER_200, - VARIOUS_SET_SKY_DROP, - VARIOUS_CLEAR_SKY_DROP, - VARIOUS_SKY_DROP_YAWN, - VARIOUS_CURE_CERTAIN_STATUSES, - VARIOUS_TRY_RESET_NEGATIVE_STAT_STAGES, - VARIOUS_JUMP_IF_LAST_USED_ITEM_BERRY, - VARIOUS_SAVE_BATTLER_ITEM, - VARIOUS_RESTORE_BATTLER_ITEM, - VARIOUS_BATTLER_ITEM_TO_LAST_USED_ITEM, + VARIOUS_NONE, }; // Cmd_manipulatedamage diff --git a/src/battle_script_commands.c b/src/battle_script_commands.c index 533c25171f..7f816f1f37 100644 --- a/src/battle_script_commands.c +++ b/src/battle_script_commands.c @@ -6716,7 +6716,7 @@ static void Cmd_moveend(void) effect = TRUE; gBattleScripting.battler = battler; - + if (gBattleTypeFlags & BATTLE_TYPE_TRAINER || IsOnPlayerSide(battler)) BattleScriptCall(BattleScript_EmergencyExit); else @@ -9562,1608 +9562,14 @@ static bool32 ChangeOrderTargetAfterAttacker(void) return TRUE; } +// will be deprecated next release cycle static void Cmd_various(void) { CMD_ARGS(u8 battler, u8 id); - struct Pokemon *mon; - s32 i; - u8 data[10]; - u32 battler, bits; - enum CmdVarious variousId = cmd->id; - if (gBattleControllerExecFlags) return; - battler = GetBattlerForBattleScript(cmd->battler); - - switch (variousId) - { - // Roar will fail in a double wild battle when used by the player against one of the two alive wild mons. - // Also when an opposing wild mon uses it againt its partner. - // Also when B_FLAG_NO_RUNNING is enabled. - case VARIOUS_JUMP_IF_ROAR_FAILS: - { - VARIOUS_ARGS(const u8 *jumpInstr); - if (WILD_DOUBLE_BATTLE - && IsOnPlayerSide(gBattlerAttacker) - && !IsOnPlayerSide(gBattlerTarget) - && IS_WHOLE_SIDE_ALIVE(gBattlerTarget)) - gBattlescriptCurrInstr = cmd->jumpInstr; - else if (WILD_DOUBLE_BATTLE - && !IsOnPlayerSide(gBattlerAttacker) - && !IsOnPlayerSide(gBattlerTarget)) - gBattlescriptCurrInstr = cmd->jumpInstr; - else if (FlagGet(B_FLAG_NO_RUNNING)) - gBattlescriptCurrInstr = cmd->jumpInstr; - else - gBattlescriptCurrInstr = cmd->nextInstr; - return; - } - case VARIOUS_JUMP_IF_ABSENT: - { - VARIOUS_ARGS(const u8 *jumpInstr); - if (!IsBattlerAlive(battler)) - gBattlescriptCurrInstr = cmd->jumpInstr; - else - gBattlescriptCurrInstr = cmd->nextInstr; - return; - } - case VARIOUS_JUMP_IF_SHIELDS_DOWN_PROTECTED: - { - VARIOUS_ARGS(const u8 *jumpInstr); - if (IsShieldsDownProtected(battler, GetBattlerAbility(battler))) - { - gBattlerAbility = battler; - gBattlescriptCurrInstr = cmd->jumpInstr; - } - else - { - gBattlescriptCurrInstr = cmd->nextInstr; - } - return; - } - case VARIOUS_JUMP_IF_HOLD_EFFECT: - { - VARIOUS_ARGS(u8 holdEffect, const u8 *jumpInstr, u8 equal); - if ((GetBattlerHoldEffect(battler, TRUE) == cmd->holdEffect) == cmd->equal) - { - if (cmd->equal) - gLastUsedItem = gBattleMons[battler].item; // For B_LAST_USED_ITEM - gBattlescriptCurrInstr = cmd->jumpInstr; - } - else - { - if (!cmd->equal) - gLastUsedItem = gBattleMons[battler].item; // For B_LAST_USED_ITEM - gBattlescriptCurrInstr = cmd->nextInstr; - } - return; - } - case VARIOUS_JUMP_IF_NO_ALLY: - { - VARIOUS_ARGS(const u8 *jumpInstr); - if (!IsBattlerAlive(BATTLE_PARTNER(battler))) - gBattlescriptCurrInstr = cmd->jumpInstr; - else - gBattlescriptCurrInstr = cmd->nextInstr; - return; - } - case VARIOUS_INFATUATE_WITH_BATTLER: - { - VARIOUS_ARGS(u8 infatuateWith); - gBattleScripting.battler = battler; - gBattleMons[battler].volatiles.infatuation = INFATUATED_WITH(GetBattlerForBattleScript(cmd->infatuateWith)); - gBattlescriptCurrInstr = cmd->nextInstr; - return; - } - case VARIOUS_SET_LAST_USED_ITEM: - { - VARIOUS_ARGS(); - gLastUsedItem = gBattleMons[battler].item; - break; - } - case VARIOUS_TRY_FAIRY_LOCK: - { - VARIOUS_ARGS(const u8 *failInstr); - if (gFieldStatuses & STATUS_FIELD_FAIRY_LOCK) - { - gBattlescriptCurrInstr = cmd->failInstr; - } - else - { - gFieldStatuses |= STATUS_FIELD_FAIRY_LOCK; - gFieldTimers.fairyLockTimer = gBattleTurnCounter + 2; - gBattlescriptCurrInstr = cmd->nextInstr; - } - return; - } - case VARIOUS_GET_STAT_VALUE: - { - VARIOUS_ARGS(u8 stat); - i = cmd->stat; - gBattleStruct->moveDamage[gBattlerAttacker] = *(u16 *)(&gBattleMons[battler].attack) + (i - 1); - gBattleStruct->moveDamage[gBattlerAttacker] *= gStatStageRatios[gBattleMons[battler].statStages[i]][0]; - gBattleStruct->moveDamage[gBattlerAttacker] /= gStatStageRatios[gBattleMons[battler].statStages[i]][1]; - gBattlescriptCurrInstr = cmd->nextInstr; - return; - } - case VARIOUS_JUMP_IF_FULL_HP: - { - VARIOUS_ARGS(const u8 *jumpInstr); - if (IsBattlerAtMaxHp(battler)) - gBattlescriptCurrInstr = cmd->jumpInstr; - else - gBattlescriptCurrInstr = cmd->nextInstr; - return; - } - case VARIOUS_TRY_FRISK: - { - VARIOUS_ARGS(); - while (gBattleStruct->friskedBattler < gBattlersCount) - { - gBattlerTarget = gBattleStruct->friskedBattler++; - if (!IsBattlerAlly(battler, gBattlerTarget) - && IsBattlerAlive(gBattlerTarget) - && gBattleMons[gBattlerTarget].item != ITEM_NONE) - { - gLastUsedItem = gBattleMons[gBattlerTarget].item; - RecordItemEffectBattle(gBattlerTarget, GetBattlerHoldEffect(gBattlerTarget, FALSE)); - // If Frisk identifies two mons' items, show the pop-up only once. - if (gBattleStruct->friskedAbility) - { - BattleScriptCall(BattleScript_FriskMsg); - } - else - { - gBattleStruct->friskedAbility = TRUE; - BattleScriptCall(BattleScript_FriskMsgWithPopup); - } - return; - } - } - gBattleStruct->friskedBattler = 0; - gBattleStruct->friskedAbility = FALSE; - break; - } - case VARIOUS_TRACE_ABILITY: - { - VARIOUS_ARGS(); - gBattleMons[battler].ability = gDisableStructs[battler].overwrittenAbility = gBattleStruct->tracedAbility[battler]; - break; - } - case VARIOUS_TRY_ILLUSION_OFF: - { - VARIOUS_ARGS(); - if (TryClearIllusion(battler, ABILITYEFFECT_MOVE_END)) - return; - break; - } - case VARIOUS_SET_SPRITEIGNORE0HP: - { - VARIOUS_ARGS(bool8 ignore0HP); - gBattleStruct->spriteIgnore0Hp = cmd->ignore0HP; - gBattlescriptCurrInstr = cmd->nextInstr; - return; - } - case VARIOUS_UPDATE_NICK: - { - VARIOUS_ARGS(); - mon = GetBattlerMon(battler); - UpdateHealthboxAttribute(gHealthboxSpriteIds[battler], mon, HEALTHBOX_NICK); - break; - } - case VARIOUS_JUMP_IF_NOT_BERRY: - { - VARIOUS_ARGS(const u8 *jumpInstr); - if (GetItemPocket(gBattleMons[battler].item) == POCKET_BERRIES) - gBattlescriptCurrInstr = cmd->nextInstr; - else - gBattlescriptCurrInstr = cmd->jumpInstr; - return; - } - case VARIOUS_CHECK_IF_GRASSY_TERRAIN_HEALS: - { - VARIOUS_ARGS(const u8 *failInstr); - if ((gStatuses3[battler] & (STATUS3_SEMI_INVULNERABLE | STATUS3_HEAL_BLOCK)) - || IsBattlerAtMaxHp(battler) - || !gBattleMons[battler].hp - || !(IsBattlerGrounded(battler))) - { - gBattlescriptCurrInstr = cmd->failInstr; - } - else - { - gBattleStruct->moveDamage[battler] = GetNonDynamaxMaxHP(battler) / 16; - if (gBattleStruct->moveDamage[battler] == 0) - gBattleStruct->moveDamage[battler] = 1; - gBattleStruct->moveDamage[battler] *= -1; - - gBattlescriptCurrInstr = cmd->nextInstr; - } - return; - } - case VARIOUS_GRAVITY_ON_AIRBORNE_MONS: - { - VARIOUS_ARGS(); - // Cancel all multiturn moves of IN_AIR Pokemon except those being targeted by Sky Drop. - if (gStatuses3[battler] & STATUS3_ON_AIR && !(gStatuses3[battler] & STATUS3_SKY_DROPPED)) - CancelMultiTurnMoves(battler, SKY_DROP_GRAVITY_ON_AIRBORNE); - - gStatuses3[battler] &= ~(STATUS3_MAGNET_RISE | STATUS3_TELEKINESIS | STATUS3_ON_AIR | STATUS3_SKY_DROPPED); - break; - } - case VARIOUS_ACUPRESSURE: - { - VARIOUS_ARGS(const u8 *failInstr); - bits = 0; - for (i = STAT_ATK; i < NUM_BATTLE_STATS; i++) - { - if (CompareStat(battler, i, MAX_STAT_STAGE, CMP_LESS_THAN)) - bits |= 1u << i; - } - if (bits) - { - u32 statId; - do - { - statId = (Random() % (NUM_BATTLE_STATS - 1)) + 1; - } while (!(bits & (1u << statId))); - - SET_STATCHANGER(statId, 2, FALSE); - gBattlescriptCurrInstr = cmd->nextInstr; - } - else - { - gBattlescriptCurrInstr = cmd->failInstr; - } - return; - } - case VARIOUS_CANCEL_MULTI_TURN_MOVES: - { - VARIOUS_ARGS(); - const u8 *result; - result = CancelMultiTurnMoves(battler, SKY_DROP_CANCEL_MULTI_TURN_MOVES); - if (result) - { - gBattlescriptCurrInstr = result; - return; - } - break; - } - case VARIOUS_IS_RUNNING_IMPOSSIBLE: - { - VARIOUS_ARGS(); - gBattleCommunication[0] = IsRunningFromBattleImpossible(battler); - break; - } - case VARIOUS_GET_MOVE_TARGET: - { - VARIOUS_ARGS(); - gBattlerTarget = GetBattleMoveTarget(gCurrentMove, NO_TARGET_OVERRIDE); - break; - } - case VARIOUS_GET_BATTLER_FAINTED: - { - VARIOUS_ARGS(); - if (gHitMarker & HITMARKER_FAINTED(battler)) - gBattleCommunication[0] = TRUE; - else - gBattleCommunication[0] = FALSE; - break; - } - case VARIOUS_RESET_SWITCH_IN_ABILITY_BITS: - { - VARIOUS_ARGS(); - gSpecialStatuses[battler].switchInAbilityDone = FALSE; - break; - } - case VARIOUS_UPDATE_CHOICE_MOVE_ON_LVL_UP: - { - VARIOUS_ARGS(); - if (gBattlerPartyIndexes[0] == gBattleStruct->expGetterMonId || gBattlerPartyIndexes[2] == gBattleStruct->expGetterMonId) - { - if (gBattlerPartyIndexes[0] == gBattleStruct->expGetterMonId) - battler = 0; - else - battler = 2; - - for (i = 0; i < MAX_MON_MOVES; i++) - { - if (gBattleMons[battler].moves[i] == gBattleStruct->choicedMove[battler]) - break; - } - if (i == MAX_MON_MOVES) - gBattleStruct->choicedMove[battler] = MOVE_NONE; - } - break; - } - case VARIOUS_RESET_PLAYER_FAINTED: - { - VARIOUS_ARGS(); - if (!(gBattleTypeFlags & (BATTLE_TYPE_LINK | BATTLE_TYPE_DOUBLE)) - && gBattleTypeFlags & BATTLE_TYPE_TRAINER - && IsBattlerAlive(B_POSITION_PLAYER_LEFT) - && IsBattlerAlive(B_POSITION_OPPONENT_LEFT)) - { - gHitMarker &= ~HITMARKER_PLAYER_FAINTED; - } - break; - } - case VARIOUS_PALACE_FLAVOR_TEXT: - { - VARIOUS_ARGS(); - // Try and print end-of-turn Battle Palace flavor text (e.g. "A glint appears in mon's eyes") - gBattleCommunication[0] = FALSE; // whether or not msg should be printed - gBattleScripting.battler = battler = gBattleCommunication[1]; - if (!(gBattleStruct->palaceFlags & (1u << battler)) - && gBattleMons[battler].maxHP / 2 >= gBattleMons[battler].hp - && IsBattlerAlive(battler) - && !(gBattleMons[battler].status1 & STATUS1_SLEEP)) - { - gBattleStruct->palaceFlags |= 1u << battler; - gBattleCommunication[0] = TRUE; - gBattleCommunication[MULTISTRING_CHOOSER] = gNaturesInfo[GetNatureFromPersonality(gBattleMons[battler].personality)].battlePalaceFlavorText; - } - break; - } - case VARIOUS_ARENA_JUDGMENT_WINDOW: - { - VARIOUS_ARGS(); - - i = BattleArena_ShowJudgmentWindow(&gBattleCommunication[0]); - - // BattleArena_ShowJudgmentWindow's last state was an intermediate step. - // Return without advancing the current instruction so that it will be called again. - if (i == ARENA_RESULT_RUNNING) - return; - - gBattleCommunication[1] = i; - break; - } - case VARIOUS_ARENA_OPPONENT_MON_LOST: - { - VARIOUS_ARGS(); - gBattleMons[1].hp = 0; - gHitMarker |= HITMARKER_FAINTED(1); - gBattleStruct->arenaLostOpponentMons |= 1u << gBattlerPartyIndexes[1]; - gDisableStructs[1].truantSwitchInHack = 1; - break; - } - case VARIOUS_ARENA_PLAYER_MON_LOST: - { - VARIOUS_ARGS(); - gBattleMons[0].hp = 0; - gHitMarker |= HITMARKER_FAINTED(0); - gHitMarker |= HITMARKER_PLAYER_FAINTED; - gBattleStruct->arenaLostPlayerMons |= 1u << gBattlerPartyIndexes[0]; - gDisableStructs[0].truantSwitchInHack = 1; - break; - } - case VARIOUS_ARENA_BOTH_MONS_LOST: - { - VARIOUS_ARGS(); - gBattleMons[0].hp = 0; - gBattleMons[1].hp = 0; - gHitMarker |= HITMARKER_FAINTED(0); - gHitMarker |= HITMARKER_FAINTED(1); - gHitMarker |= HITMARKER_PLAYER_FAINTED; - gBattleStruct->arenaLostPlayerMons |= 1u << gBattlerPartyIndexes[0]; - gBattleStruct->arenaLostOpponentMons |= 1u << gBattlerPartyIndexes[1]; - gDisableStructs[0].truantSwitchInHack = 1; - gDisableStructs[1].truantSwitchInHack = 1; - break; - } - case VARIOUS_EMIT_YESNOBOX: - { - VARIOUS_ARGS(); - BtlController_EmitYesNoBox(battler, B_COMM_TO_CONTROLLER); - MarkBattlerForControllerExec(battler); - break; - } - case VARIOUS_DRAW_ARENA_REF_TEXT_BOX: - { - VARIOUS_ARGS(); - DrawArenaRefereeTextBox(); - break; - } - case VARIOUS_ERASE_ARENA_REF_TEXT_BOX: - { - VARIOUS_ARGS(); - EraseArenaRefereeTextBox(); - break; - } - case VARIOUS_ARENA_JUDGMENT_STRING: - { - CMD_ARGS(u8 id, u8 _); - BattleStringExpandPlaceholdersToDisplayedString(gRefereeStringsTable[cmd->id]); - BattlePutTextOnWindow(gDisplayedStringBattle, ARENA_WIN_JUDGMENT_TEXT); - break; - } - case VARIOUS_ARENA_WAIT_STRING: - { - VARIOUS_ARGS(); - if (IsTextPrinterActive(ARENA_WIN_JUDGMENT_TEXT)) - return; - break; - } - case VARIOUS_WAIT_CRY: - { - VARIOUS_ARGS(); - if (!IsCryFinished()) - return; - break; - } - case VARIOUS_RETURN_OPPONENT_MON1: - { - VARIOUS_ARGS(); - battler = 1; - if (IsBattlerAlive(battler)) - { - BtlController_EmitReturnMonToBall(battler, B_COMM_TO_CONTROLLER, FALSE); - MarkBattlerForControllerExec(battler); - } - break; - } - case VARIOUS_RETURN_OPPONENT_MON2: - { - VARIOUS_ARGS(); - if (gBattlersCount > 3) - { - battler = 3; - if (IsBattlerAlive(battler)) - { - BtlController_EmitReturnMonToBall(battler, B_COMM_TO_CONTROLLER, FALSE); - MarkBattlerForControllerExec(battler); - } - } - break; - } - case VARIOUS_VOLUME_DOWN: - { - VARIOUS_ARGS(); - m4aMPlayVolumeControl(&gMPlayInfo_BGM, TRACKS_ALL, 0x55); - break; - } - case VARIOUS_VOLUME_UP: - { - VARIOUS_ARGS(); - m4aMPlayVolumeControl(&gMPlayInfo_BGM, TRACKS_ALL, 0x100); - break; - } - case VARIOUS_SET_ALREADY_STATUS_MOVE_ATTEMPT: - { - VARIOUS_ARGS(); - gBattleStruct->battlerState[battler].alreadyStatusedMoveAttempt = TRUE; - break; - } - case VARIOUS_PALACE_TRY_ESCAPE_STATUS: - { - VARIOUS_ARGS(); - if (BattlePalace_TryEscapeStatus(battler)) - return; - break; - } - case VARIOUS_SET_TELEPORT_OUTCOME: - { - VARIOUS_ARGS(); - // Don't end the battle if one of the wild mons teleported from the wild double battle - // and its partner is still alive. - if (!IsOnPlayerSide(battler) && IsBattlerAlive(BATTLE_PARTNER(battler))) - { - gAbsentBattlerFlags |= 1u << battler; - gHitMarker |= HITMARKER_FAINTED(battler); - gBattleMons[battler].hp = 0; - SetMonData(GetBattlerMon(battler), MON_DATA_HP, &gBattleMons[battler].hp); - SetHealthboxSpriteInvisible(gHealthboxSpriteIds[battler]); - FaintClearSetData(battler); - } - else if (IsOnPlayerSide(battler)) - { - gBattleOutcome = B_OUTCOME_PLAYER_TELEPORTED; - } - else - { - gBattleOutcome = B_OUTCOME_MON_TELEPORTED; - } - break; - } - case VARIOUS_PLAY_TRAINER_DEFEATED_MUSIC: - { - VARIOUS_ARGS(); - BtlController_EmitPlayFanfareOrBGM(battler, B_COMM_TO_CONTROLLER, MUS_VICTORY_TRAINER, TRUE); - MarkBattlerForControllerExec(battler); - break; - } - case VARIOUS_STAT_TEXT_BUFFER: - { - VARIOUS_ARGS(); - PREPARE_STAT_BUFFER(gBattleTextBuff1, gBattleCommunication[0]); - break; - } - case VARIOUS_SWITCHIN_ABILITIES: - { - VARIOUS_ARGS(); - gBattlescriptCurrInstr = cmd->nextInstr; - AbilityBattleEffects(ABILITYEFFECT_NEUTRALIZINGGAS, battler, 0, 0, 0); - AbilityBattleEffects(ABILITYEFFECT_ON_SWITCHIN, battler, 0, 0, 0); - AbilityBattleEffects(ABILITYEFFECT_OPPORTUNIST, battler, 0, 0, 0); - return; - } - case VARIOUS_INSTANT_HP_DROP: - { - VARIOUS_ARGS(); - BtlController_EmitHealthBarUpdate(battler, B_COMM_TO_CONTROLLER, INSTANT_HP_BAR_DROP); - MarkBattlerForControllerExec(battler); - break; - } - case VARIOUS_CLEAR_STATUS: - { - VARIOUS_ARGS(); - gBattleMons[battler].status1 = 0; - BtlController_EmitSetMonData(battler, B_COMM_TO_CONTROLLER, REQUEST_STATUS_BATTLE, 0, sizeof(gBattleMons[battler].status1), &gBattleMons[battler].status1); - MarkBattlerForControllerExec(battler); - break; - } - case VARIOUS_RESTORE_PP: - { - VARIOUS_ARGS(); - for (i = 0; i < 4; i++) - { - gBattleMons[battler].pp[i] = CalculatePPWithBonus(gBattleMons[battler].moves[i], gBattleMons[battler].ppBonuses, i); - data[i] = gBattleMons[battler].pp[i]; - } - data[i] = gBattleMons[battler].ppBonuses; - BtlController_EmitSetMonData(battler, B_COMM_TO_CONTROLLER, REQUEST_PP_DATA_BATTLE, 0, 5, data); - MarkBattlerForControllerExec(battler); - break; - } - case VARIOUS_TRY_ACTIVATE_RECEIVER: // Partner gets fainted's ally ability - { - VARIOUS_ARGS(); - gBattlerAbility = BATTLE_PARTNER(battler); - i = GetBattlerAbility(gBattlerAbility); - if (IsBattlerAlive(gBattlerAbility) - && (i == ABILITY_RECEIVER || i == ABILITY_POWER_OF_ALCHEMY) - && GetBattlerHoldEffect(battler, TRUE) != HOLD_EFFECT_ABILITY_SHIELD - && !gAbilitiesInfo[gBattleMons[battler].ability].cantBeCopied) - { - gBattleStruct->tracedAbility[gBattlerAbility] = gBattleMons[battler].ability; // re-using the variable for trace - gBattleScripting.battler = battler; - BattleScriptPush(cmd->nextInstr); - gBattlescriptCurrInstr = BattleScript_ReceiverActivates; - return; - } - break; - } - case VARIOUS_TRY_ACTIVATE_SOULHEART: - { - VARIOUS_ARGS(); - while (gBattleStruct->soulheartBattlerId < gBattlersCount) - { - gBattleScripting.battler = gBattleStruct->soulheartBattlerId++; - if (GetBattlerAbility(gBattleScripting.battler) == ABILITY_SOUL_HEART - && IsBattlerAlive(gBattleScripting.battler) - && !NoAliveMonsForEitherParty() - && CompareStat(gBattleScripting.battler, STAT_SPATK, MAX_STAT_STAGE, CMP_LESS_THAN)) - { - SET_STATCHANGER(STAT_SPATK, 1, FALSE); - PREPARE_STAT_BUFFER(gBattleTextBuff1, STAT_SPATK); - BattleScriptCall(BattleScript_ScriptingAbilityStatRaise); - return; - } - } - gBattleStruct->soulheartBattlerId = 0; - break; - } - case VARIOUS_PLAY_MOVE_ANIMATION: - { - VARIOUS_ARGS(u16 move); - BtlController_EmitMoveAnimation(battler, B_COMM_TO_CONTROLLER, cmd->move, gBattleScripting.animTurn, 0, 0, gBattleMons[battler].friendship, &gDisableStructs[battler], gMultiHitCounter); - MarkBattlerForControllerExec(battler); - gBattlescriptCurrInstr = cmd->nextInstr; - return; - } - case VARIOUS_SET_LUCKY_CHANT: - { - VARIOUS_ARGS(const u8 *failInstr); - if (!(gSideStatuses[GetBattlerSide(battler)] & SIDE_STATUS_LUCKY_CHANT)) - { - gSideStatuses[GetBattlerSide(battler)] |= SIDE_STATUS_LUCKY_CHANT; - gSideTimers[GetBattlerSide(battler)].luckyChantTimer = gBattleTurnCounter + 5; - gBattlescriptCurrInstr = cmd->nextInstr; - } - else - { - gBattlescriptCurrInstr = cmd->failInstr; - } - return; - } - case VARIOUS_SUCKER_PUNCH_CHECK: - { - VARIOUS_ARGS(const u8 *failInstr); - if (gProtectStructs[gBattlerTarget].protected == PROTECT_OBSTRUCT) - gBattlescriptCurrInstr = cmd->failInstr; - else if (GetBattlerTurnOrderNum(gBattlerAttacker) > GetBattlerTurnOrderNum(gBattlerTarget)) - gBattlescriptCurrInstr = cmd->failInstr; - else if (IsBattleMoveStatus(gBattleMons[gBattlerTarget].moves[gBattleStruct->chosenMovePositions[gBattlerTarget]]) && !gProtectStructs[gBattlerTarget].noValidMoves) - gBattlescriptCurrInstr = cmd->failInstr; - else - gBattlescriptCurrInstr = cmd->nextInstr; - return; - } - case VARIOUS_SET_SIMPLE_BEAM: - { - VARIOUS_ARGS(const u8 *failInstr); - if (gAbilitiesInfo[gBattleMons[gBattlerTarget].ability].cantBeOverwritten - || gBattleMons[gBattlerTarget].ability == ABILITY_SIMPLE) - { - RecordAbilityBattle(gBattlerTarget, gBattleMons[gBattlerTarget].ability); - gBattlescriptCurrInstr = cmd->failInstr; - } - else if (GetBattlerHoldEffect(gBattlerTarget, TRUE) == HOLD_EFFECT_ABILITY_SHIELD) - { - RecordItemEffectBattle(gBattlerTarget, HOLD_EFFECT_ABILITY_SHIELD); - gBattlescriptCurrInstr = cmd->failInstr; - } - else - { - if (gBattleMons[gBattlerTarget].ability == ABILITY_NEUTRALIZING_GAS) - gSpecialStatuses[gBattlerTarget].neutralizingGasRemoved = TRUE; - - gBattleScripting.abilityPopupOverwrite = gBattleMons[gBattlerTarget].ability; - gBattleMons[gBattlerTarget].ability = gDisableStructs[gBattlerTarget].overwrittenAbility = ABILITY_SIMPLE; - gBattlescriptCurrInstr = cmd->nextInstr; - } - return; - } - case VARIOUS_TRY_ENTRAINMENT: - { - VARIOUS_ARGS(const u8 *failInstr); - if (gAbilitiesInfo[gBattleMons[gBattlerAttacker].ability].cantBeCopied - || gAbilitiesInfo[gBattleMons[gBattlerTarget].ability].cantBeOverwritten) - { - RecordAbilityBattle(gBattlerTarget, gBattleMons[gBattlerTarget].ability); - gBattlescriptCurrInstr = cmd->failInstr; - } - else if (GetBattlerHoldEffect(gBattlerTarget, TRUE) == HOLD_EFFECT_ABILITY_SHIELD) - { - RecordItemEffectBattle(gBattlerTarget, HOLD_EFFECT_ABILITY_SHIELD); - gBattlescriptCurrInstr = cmd->failInstr; - } - else - { - if (gBattleMons[gBattlerTarget].ability == gBattleMons[gBattlerAttacker].ability - || (GetActiveGimmick(gBattlerTarget) == GIMMICK_DYNAMAX)) - { - gBattlescriptCurrInstr = cmd->failInstr; - } - else - { - gBattleMons[gBattlerTarget].ability = gDisableStructs[gBattlerTarget].overwrittenAbility = gBattleMons[gBattlerAttacker].ability; - gBattlescriptCurrInstr = cmd->nextInstr; - } - } - return; - } - case VARIOUS_SET_LAST_USED_ABILITY: - { - VARIOUS_ARGS(); - gLastUsedAbility = gBattleMons[battler].ability; - break; - } - case VARIOUS_INVERT_STAT_STAGES: - { - VARIOUS_ARGS(); - for (i = 0; i < NUM_BATTLE_STATS; i++) - { - if (gBattleMons[battler].statStages[i] < DEFAULT_STAT_STAGE) // Negative becomes positive. - gBattleMons[battler].statStages[i] = DEFAULT_STAT_STAGE + (DEFAULT_STAT_STAGE - gBattleMons[battler].statStages[i]); - else if (gBattleMons[battler].statStages[i] > DEFAULT_STAT_STAGE) // Positive becomes negative. - gBattleMons[battler].statStages[i] = DEFAULT_STAT_STAGE - (gBattleMons[battler].statStages[i] - DEFAULT_STAT_STAGE); - } - break; - } - case VARIOUS_TRY_ME_FIRST: - { - VARIOUS_ARGS(const u8 *failInstr); - u16 move = gBattleMons[gBattlerTarget].moves[gBattleStruct->chosenMovePositions[gBattlerTarget]]; - if (IsBattleMoveStatus(move) || IsMoveMeFirstBanned(move) - || GetBattlerTurnOrderNum(gBattlerAttacker) > GetBattlerTurnOrderNum(gBattlerTarget)) - gBattlescriptCurrInstr = cmd->failInstr; - else - { - if (GetActiveGimmick(gBattlerAttacker) == GIMMICK_Z_MOVE && !IsBattleMoveStatus(move)) - { - gBattleStruct->zmove.baseMoves[gBattlerAttacker] = move; - gCalledMove = GetTypeBasedZMove(move); - } - else - { - gCalledMove = move; - } - gHitMarker &= ~HITMARKER_ATTACKSTRING_PRINTED; - gBattlerTarget = GetBattleMoveTarget(gCalledMove, NO_TARGET_OVERRIDE); - gBattlescriptCurrInstr = cmd->nextInstr; - } - return; - } - case VARIOUS_JUMP_IF_BATTLE_END: - { - VARIOUS_ARGS(const u8 *jumpInstr); - if (NoAliveMonsForEitherParty()) - gBattlescriptCurrInstr = cmd->jumpInstr; - else - gBattlescriptCurrInstr = cmd->nextInstr; - return; - } - case VARIOUS_TRY_ELECTRIFY: - { - VARIOUS_ARGS(const u8 *failInstr); - if (GetBattlerTurnOrderNum(gBattlerAttacker) > GetBattlerTurnOrderNum(gBattlerTarget)) - { - gBattlescriptCurrInstr = cmd->failInstr; - } - else - { - gStatuses4[gBattlerTarget] |= STATUS4_ELECTRIFIED; - gBattlescriptCurrInstr = cmd->nextInstr; - } - return; - } - case VARIOUS_TRY_SOAK: - { - VARIOUS_ARGS(const u8 *failInstr); - u32 types[3]; - GetBattlerTypes(gBattlerTarget, FALSE, types); - u32 typeToSet = GetMoveArgType(gCurrentMove); - if ((types[0] == typeToSet && types[1] == typeToSet) - || GetActiveGimmick(gBattlerTarget) == GIMMICK_TERA) - { - gBattlescriptCurrInstr = cmd->failInstr; - } - else - { - SET_BATTLER_TYPE(gBattlerTarget, typeToSet); - PREPARE_TYPE_BUFFER(gBattleTextBuff1, typeToSet); - gBattlescriptCurrInstr = cmd->nextInstr; - } - return; - } - case VARIOUS_HANDLE_FORM_CHANGE: - { - VARIOUS_ARGS(u8 case_); - mon = GetBattlerMon(battler); - - // Change species. - if (cmd->case_ == 0) - { - /* What was the idea here? - if (!gBattleTextBuff1) - PREPARE_SPECIES_BUFFER(gBattleTextBuff1, gBattleMons[battler].species); - */ - BtlController_EmitSetMonData(battler, B_COMM_TO_CONTROLLER, REQUEST_SPECIES_BATTLE, 1u << gBattlerPartyIndexes[battler], sizeof(gBattleMons[battler].species), &gBattleMons[battler].species); - MarkBattlerForControllerExec(battler); - } - // Change stats. - else if (cmd->case_ == 1) - { - RecalcBattlerStats(battler, mon, FALSE); - } - // Update healthbox. - else - { - UpdateHealthboxAttribute(gHealthboxSpriteIds[battler], mon, HEALTHBOX_ALL); - } - gBattlescriptCurrInstr = cmd->nextInstr; - return; - } - case VARIOUS_TRY_LAST_RESORT: - { - VARIOUS_ARGS(const u8 *failInstr); - if (CanUseLastResort(battler)) - gBattlescriptCurrInstr = cmd->nextInstr; - else - gBattlescriptCurrInstr = cmd->failInstr; - return; - } - case VARIOUS_TRY_AUTOTOMIZE: - { - VARIOUS_ARGS(const u8 *failInstr); - if (GetBattlerWeight(battler) > 1) - { - gDisableStructs[battler].autotomizeCount++; - gBattlescriptCurrInstr = cmd->nextInstr; - } - else - { - gBattlescriptCurrInstr = cmd->failInstr; - } - return; - } - case VARIOUS_TRY_INSTRUCT: - { - VARIOUS_ARGS(const u8 *failInstr); - u16 move = gLastPrintedMoves[gBattlerTarget]; - if (move == MOVE_NONE || move == MOVE_UNAVAILABLE || MoveHasAdditionalEffectSelf(move, MOVE_EFFECT_RECHARGE) - || IsMoveInstructBanned(move) - || gBattleMoveEffects[GetMoveEffect(move)].twoTurnEffect - || (GetActiveGimmick(gBattlerTarget) == GIMMICK_DYNAMAX) - || IsZMove(move) - || IsMaxMove(move)) - { - gBattlescriptCurrInstr = cmd->failInstr; - } - else - { - gSpecialStatuses[gBattlerTarget].instructedChosenTarget = gBattleStruct->moveTarget[gBattlerTarget] | 0x4; - gCalledMove = move; - for (i = 0; i < MAX_MON_MOVES; i++) - { - if (gBattleMons[gBattlerTarget].moves[i] == gCalledMove) - { - gCurrMovePos = i; - i = 4; - break; - } - } - if (i != 4 || gBattleMons[gBattlerTarget].pp[gCurrMovePos] == 0) - gBattlescriptCurrInstr = cmd->failInstr; - else - { - gEffectBattler = gBattleStruct->lastMoveTarget[gBattlerTarget]; - gHitMarker &= ~HITMARKER_ATTACKSTRING_PRINTED; - PREPARE_MON_NICK_WITH_PREFIX_BUFFER(gBattleTextBuff1, battler, gBattlerPartyIndexes[battler]); - gBattlescriptCurrInstr = cmd->nextInstr; - } - } - return; - } - case VARIOUS_ABILITY_POPUP: - { - VARIOUS_ARGS(); - CreateAbilityPopUp(battler, gBattleMons[battler].ability, (IsDoubleBattle()) != 0); - break; - } - case VARIOUS_UPDATE_ABILITY_POPUP: - { - VARIOUS_ARGS(); - UpdateAbilityPopup(battler); - break; - } - case VARIOUS_JUMP_IF_TARGET_ALLY: - { - VARIOUS_ARGS(const u8 *jumpInstr); - if (!IsBattlerAlly(gBattlerAttacker, gBattlerTarget)) - gBattlescriptCurrInstr = cmd->nextInstr; - else - gBattlescriptCurrInstr = cmd->jumpInstr; - return; - } - case VARIOUS_TRY_SYNCHRONOISE: - { - VARIOUS_ARGS(const u8 *failInstr); - if (!DoBattlersShareType(gBattlerAttacker, gBattlerTarget)) - gBattlescriptCurrInstr = cmd->failInstr; - else - gBattlescriptCurrInstr = cmd->nextInstr; - return; - } - case VARIOUS_LOSE_TYPE: - { - VARIOUS_ARGS(u8 type); - RemoveBattlerType(battler, cmd->type); - gBattlescriptCurrInstr = cmd->nextInstr; - return; - } - case VARIOUS_PSYCHO_SHIFT: - { - VARIOUS_ARGS(const u8 *failInstr, const u8 *sleepClauseFailInstr); - u32 targetAbility = GetBattlerAbility(gBattlerTarget); - // Psycho shift works - if ((gBattleMons[gBattlerAttacker].status1 & STATUS1_POISON) && CanBePoisoned(gBattlerAttacker, gBattlerTarget, GetBattlerAbility(gBattlerAttacker), targetAbility)) - gBattleCommunication[MULTISTRING_CHOOSER] = 0; - else if ((gBattleMons[gBattlerAttacker].status1 & STATUS1_TOXIC_POISON) && CanBePoisoned(gBattlerAttacker, gBattlerTarget, GetBattlerAbility(gBattlerAttacker), targetAbility)) - gBattleCommunication[MULTISTRING_CHOOSER] = 1; - else if ((gBattleMons[gBattlerAttacker].status1 & STATUS1_BURN) && CanBeBurned(gBattlerAttacker, gBattlerTarget, targetAbility)) - gBattleCommunication[MULTISTRING_CHOOSER] = 2; - else if ((gBattleMons[gBattlerAttacker].status1 & STATUS1_PARALYSIS) && CanBeParalyzed(gBattlerAttacker, gBattlerTarget, targetAbility)) - gBattleCommunication[MULTISTRING_CHOOSER] = 3; - else if ((gBattleMons[gBattlerAttacker].status1 & STATUS1_SLEEP) && CanBeSlept(gBattlerAttacker, gBattlerTarget, targetAbility, BLOCKED_BY_SLEEP_CLAUSE)) - gBattleCommunication[MULTISTRING_CHOOSER] = 4; - else if ((gBattleMons[gBattlerAttacker].status1 & STATUS1_FROSTBITE) && CanBeFrozen(gBattlerAttacker, gBattlerTarget, targetAbility)) - gBattleCommunication[MULTISTRING_CHOOSER] = 5; - else if (IsSleepClauseActiveForSide(GetBattlerSide(battler))) - { - gBattlescriptCurrInstr = cmd->sleepClauseFailInstr; - return; - } - else - { - gBattlescriptCurrInstr = cmd->failInstr; - return; - } - gBattleMons[gBattlerTarget].status1 = gBattleMons[gBattlerAttacker].status1 & STATUS1_ANY; - battler = gBattlerTarget; - BtlController_EmitSetMonData(battler, B_COMM_TO_CONTROLLER, REQUEST_STATUS_BATTLE, 0, sizeof(gBattleMons[battler].status1), &gBattleMons[battler].status1); - MarkBattlerForControllerExec(battler); - gBattlescriptCurrInstr = cmd->nextInstr; - TryActivateSleepClause(battler, gBattlerPartyIndexes[battler]); - return; - } - case VARIOUS_CURE_STATUS: - { - VARIOUS_ARGS(); - - if (gBattleMons[battler].status1 & STATUS1_SLEEP) - TryDeactivateSleepClause(GetBattlerSide(battler), gBattlerPartyIndexes[battler]); - - gBattleMons[battler].status1 = 0; - BtlController_EmitSetMonData(battler, B_COMM_TO_CONTROLLER, REQUEST_STATUS_BATTLE, 0, sizeof(gBattleMons[battler].status1), &gBattleMons[battler].status1); - MarkBattlerForControllerExec(battler); - break; - } - case VARIOUS_POWER_TRICK: - { - VARIOUS_ARGS(); - gStatuses3[battler] ^= STATUS3_POWER_TRICK; - SWAP(gBattleMons[battler].attack, gBattleMons[battler].defense, i); - break; - } - case VARIOUS_AFTER_YOU: - { - VARIOUS_ARGS(const u8 *failInstr); - if (ChangeOrderTargetAfterAttacker()) - { - gSpecialStatuses[gBattlerTarget].afterYou = 1; - gBattlescriptCurrInstr = cmd->nextInstr; - } - else - { - gBattlescriptCurrInstr = cmd->failInstr; - } - return; - } - case VARIOUS_BESTOW: - { - VARIOUS_ARGS(const u8 *failInstr); - if (gBattleMons[gBattlerAttacker].item == ITEM_NONE - || gBattleMons[gBattlerTarget].item != ITEM_NONE - || !CanBattlerGetOrLoseItem(gBattlerAttacker, gBattleMons[gBattlerAttacker].item) - || !CanBattlerGetOrLoseItem(gBattlerTarget, gBattleMons[gBattlerAttacker].item) - || gWishFutureKnock.knockedOffMons[GetBattlerSide(gBattlerTarget)] & (1u << gBattlerPartyIndexes[gBattlerTarget])) - { - gBattlescriptCurrInstr = cmd->failInstr; - } - else - { - BestowItem(gBattlerAttacker, gBattlerTarget); - gBattlescriptCurrInstr = cmd->nextInstr; - } - return; - } - case VARIOUS_JUMP_IF_NOT_GROUNDED: - { - VARIOUS_ARGS(const u8 *jumpInstr); - if (!IsBattlerGrounded(battler)) - gBattlescriptCurrInstr = cmd->jumpInstr; - else - gBattlescriptCurrInstr = cmd->nextInstr; - return; - } - case VARIOUS_HANDLE_TRAINER_SLIDE_MSG: - { - VARIOUS_ARGS(u8 case_); - if (cmd->case_ == PRINT_SLIDE_MESSAGE) - { - BtlController_EmitPrintString(battler, B_COMM_TO_CONTROLLER, STRINGID_TRAINERSLIDE); - MarkBattlerForControllerExec(battler); - } - else if (cmd->case_ == RESTORE_BATTLER_SLIDE_CONTROL) - { - if (IsBattlerAlive(battler)) - { - SetBattlerShadowSpriteCallback(battler, gBattleMons[battler].species); - BattleLoadMonSpriteGfx(GetBattlerMon(battler), battler); - } - i = BATTLE_PARTNER(battler); - if (IsBattlerAlive(i)) - { - SetBattlerShadowSpriteCallback(i, gBattleMons[i].species); - BattleLoadMonSpriteGfx(GetBattlerMon(i), i); - } - } - gBattlescriptCurrInstr = cmd->nextInstr; - return; - } - case VARIOUS_TRY_TRAINER_SLIDE_MSG_FIRST_OFF: - { - VARIOUS_ARGS(); - if ((i = ShouldDoTrainerSlide(battler, TRAINER_SLIDE_PLAYER_LANDS_FIRST_DOWN))) - { - gBattleScripting.battler = battler; - BattleScriptPush(cmd->nextInstr); - gBattlescriptCurrInstr = (i == 1 ? BattleScript_TrainerASlideMsgRet : BattleScript_TrainerBSlideMsgRet); - return; - } - break; - } - case VARIOUS_TRY_TRAINER_SLIDE_MSG_LAST_ON: - { - VARIOUS_ARGS(); - if ((i = ShouldDoTrainerSlide(battler, TRAINER_SLIDE_LAST_SWITCHIN))) - { - gBattleScripting.battler = battler; - BattleScriptPush(cmd->nextInstr); - gBattlescriptCurrInstr = (i == 1 ? BattleScript_TrainerASlideMsgRet : BattleScript_TrainerBSlideMsgRet); - return; - } - break; - } - case VARIOUS_SET_AURORA_VEIL: - { - VARIOUS_ARGS(); - if (gSideStatuses[GetBattlerSide(battler)] & SIDE_STATUS_AURORA_VEIL - || !(HasWeatherEffect() && gBattleWeather & (B_WEATHER_HAIL | B_WEATHER_SNOW))) - { - gBattleStruct->moveResultFlags[gBattlerTarget] |= MOVE_RESULT_MISSED; - gBattleCommunication[MULTISTRING_CHOOSER] = 0; - } - else - { - gSideStatuses[GetBattlerSide(battler)] |= SIDE_STATUS_AURORA_VEIL; - if (GetBattlerHoldEffect(battler, TRUE) == HOLD_EFFECT_LIGHT_CLAY) - gSideTimers[GetBattlerSide(battler)].auroraVeilTimer = gBattleTurnCounter + 8; - else - gSideTimers[GetBattlerSide(battler)].auroraVeilTimer = gBattleTurnCounter + 5; - - if (IsDoubleBattle() && CountAliveMonsInBattle(BATTLE_ALIVE_SIDE, gBattlerAttacker) == 2) - gBattleCommunication[MULTISTRING_CHOOSER] = 5; - else - gBattleCommunication[MULTISTRING_CHOOSER] = 5; - } - break; - } - case VARIOUS_TRY_THIRD_TYPE: - { - VARIOUS_ARGS(const u8 *failInstr); - u32 type = GetMoveArgType(gCurrentMove); - if (IS_BATTLER_OF_TYPE(battler, type) || GetActiveGimmick(battler) == GIMMICK_TERA) - { - gBattlescriptCurrInstr = cmd->failInstr; - } - else - { - gBattleMons[battler].types[2] = type; - PREPARE_TYPE_BUFFER(gBattleTextBuff1, type); - gBattlescriptCurrInstr = cmd->nextInstr; - } - return; - } - case VARIOUS_DESTROY_ABILITY_POPUP: - { - VARIOUS_ARGS(); - for (u32 i = 0; i < gBattlersCount; i++) - { - DestroyAbilityPopUp(i); - } - break; - } - case VARIOUS_TOTEM_BOOST: - { - VARIOUS_ARGS(const u8 *jumpInstr); - battler = gBattlerAttacker; - if (gQueuedStatBoosts[battler].stats == 0) - { - gBattlescriptCurrInstr = cmd->nextInstr; // stats done, exit - } - else - { - for (i = 0; i < (NUM_BATTLE_STATS - 1); i++) - { - if (gQueuedStatBoosts[battler].stats & (1 << i)) - { - if (gQueuedStatBoosts[battler].statChanges[i] <= -1) - SET_STATCHANGER(i + 1, abs(gQueuedStatBoosts[battler].statChanges[i]), TRUE); - else - SET_STATCHANGER(i + 1, gQueuedStatBoosts[battler].statChanges[i], FALSE); - - gQueuedStatBoosts[battler].stats &= ~(1 << i); - gBattleScripting.battler = battler; - gBattlerTarget = battler; - if (gQueuedStatBoosts[battler].stats & 0x80) - { - gQueuedStatBoosts[battler].stats &= ~0x80; // set 'aura flared to life' flag - gBattlescriptCurrInstr = BattleScript_TotemFlaredToLife; - } - else - { - gBattlescriptCurrInstr = cmd->jumpInstr; // do boost - } - return; - } - } - gBattlescriptCurrInstr = cmd->nextInstr; // exit if loop failed (failsafe) - } - return; - } - case VARIOUS_MOVEEND_ITEM_EFFECTS: - { - VARIOUS_ARGS(); - if (ItemBattleEffects(ITEMEFFECT_NORMAL, battler)) - return; - break; - } - case VARIOUS_ROOM_SERVICE: - { - VARIOUS_ARGS(const u8 *failInstr); - if (GetBattlerHoldEffect(battler, TRUE) == HOLD_EFFECT_ROOM_SERVICE && TryRoomService(battler)) - { - BattleScriptCall(BattleScript_ConsumableStatRaiseRet); - } - else - { - gBattlescriptCurrInstr = cmd->failInstr; - } - return; - } - case VARIOUS_TERRAIN_SEED: - { - VARIOUS_ARGS(const u8 *failInstr); - if (GetBattlerHoldEffect(battler, TRUE) == HOLD_EFFECT_SEEDS) - { - enum ItemEffect effect = ITEM_NO_EFFECT; - u16 item = gBattleMons[battler].item; - switch (GetBattlerHoldEffectParam(battler)) - { - case HOLD_EFFECT_PARAM_ELECTRIC_TERRAIN: - effect = TryHandleSeed(battler, STATUS_FIELD_ELECTRIC_TERRAIN, STAT_DEF, item, ITEMEFFECT_NONE); - break; - case HOLD_EFFECT_PARAM_GRASSY_TERRAIN: - effect = TryHandleSeed(battler, STATUS_FIELD_GRASSY_TERRAIN, STAT_DEF, item, ITEMEFFECT_NONE); - break; - case HOLD_EFFECT_PARAM_MISTY_TERRAIN: - effect = TryHandleSeed(battler, STATUS_FIELD_MISTY_TERRAIN, STAT_SPDEF, item, ITEMEFFECT_NONE); - break; - case HOLD_EFFECT_PARAM_PSYCHIC_TERRAIN: - effect = TryHandleSeed(battler, STATUS_FIELD_PSYCHIC_TERRAIN, STAT_SPDEF, item, ITEMEFFECT_NONE); - break; - } - - if (effect != ITEM_NO_EFFECT) - return; - } - gBattlescriptCurrInstr = cmd->failInstr; - return; - } - case VARIOUS_MAKE_INVISIBLE: - { - VARIOUS_ARGS(); - if (gBattleControllerExecFlags) - break; - - BtlController_EmitSpriteInvisibility(battler, B_COMM_TO_CONTROLLER, TRUE); - MarkBattlerForControllerExec(battler); - break; - } - case VARIOUS_JUMP_IF_TEAM_HEALTHY: - { - VARIOUS_ARGS(const u8 *jumpInstr); - if ((IsDoubleBattle()) && IsBattlerAlive(BATTLE_PARTNER(battler))) - { - u8 partner = BATTLE_PARTNER(battler); - if ((gBattleMons[battler].hp == gBattleMons[battler].maxHP && !(gBattleMons[battler].status1 & STATUS1_ANY)) - && (gBattleMons[partner].hp == gBattleMons[partner].maxHP && !(gBattleMons[partner].status1 & STATUS1_ANY))) - gBattlescriptCurrInstr = cmd->jumpInstr; - else - gBattlescriptCurrInstr = cmd->nextInstr; - } - else // single battle - { - if (gBattleMons[battler].hp == gBattleMons[battler].maxHP && !(gBattleMons[battler].status1 & STATUS1_ANY)) - gBattlescriptCurrInstr = cmd->jumpInstr; - else - gBattlescriptCurrInstr = cmd->nextInstr; - } - return; - } - case VARIOUS_TRY_HEAL_QUARTER_HP: - { - VARIOUS_ARGS(const u8 *failInstr); - gBattleStruct->moveDamage[battler] = GetNonDynamaxMaxHP(battler) / 4; - if (gBattleStruct->moveDamage[battler] == 0) - gBattleStruct->moveDamage[battler] = 1; - gBattleStruct->moveDamage[battler] *= -1; - - if (gBattleMons[battler].hp == gBattleMons[battler].maxHP) - gBattlescriptCurrInstr = cmd->failInstr; // fail - else - gBattlescriptCurrInstr = cmd->nextInstr; // can heal - return; - } - case VARIOUS_JUMP_IF_UNDER_200: - { - VARIOUS_ARGS(const u8 *jumpInstr); - // If the Pokemon is less than 200 kg, or weighing less than 441 lbs, then Sky Drop will work. Otherwise, it will fail. - if (GetBattlerWeight(gBattlerTarget) < 2000) - gBattlescriptCurrInstr = cmd->jumpInstr; - else - gBattlescriptCurrInstr = cmd->nextInstr; - return; - } - case VARIOUS_SET_SKY_DROP: - { - VARIOUS_ARGS(); - gStatuses3[gBattlerTarget] |= (STATUS3_SKY_DROPPED | STATUS3_ON_AIR); - /* skyDropTargets holds the information of who is in a particular instance of Sky Drop. - This is needed in the case that multiple Pokemon use Sky Drop in the same turn or if - the target of a Sky Drop faints while in the air.*/ - gBattleStruct->skyDropTargets[gBattlerAttacker] = gBattlerTarget; - gBattleStruct->skyDropTargets[gBattlerTarget] = gBattlerAttacker; - - // End any multiturn effects caused by the target except VOLATILE_LOCK_CONFUSE - gBattleMons[gBattlerTarget].volatiles.multipleTurns = 0; - gBattleMons[gBattlerTarget].volatiles.uproarTurns= 0; - gBattleMons[gBattlerTarget].volatiles.bideTurns = 0; - gDisableStructs[gBattlerTarget].rolloutTimer = 0; - gDisableStructs[gBattlerTarget].furyCutterCounter = 0; - - // End any Follow Me/Rage Powder effects caused by the target - if (gSideTimers[GetBattlerSide(gBattlerTarget)].followmeTimer != 0 && gSideTimers[GetBattlerSide(gBattlerTarget)].followmeTarget == gBattlerTarget) - gSideTimers[GetBattlerSide(gBattlerTarget)].followmeTimer = 0; - - break; - } - case VARIOUS_CLEAR_SKY_DROP: - { - VARIOUS_ARGS(const u8 *failInstr); - // Check to see if the initial target of this Sky Drop fainted before the 2nd turn of Sky Drop. - // If so, make the move fail. If not, clear all of the statuses and continue the move. - if (gBattleStruct->skyDropTargets[gBattlerAttacker] == SKY_DROP_NO_TARGET) - gBattlescriptCurrInstr = cmd->failInstr; - else - { - gBattleStruct->skyDropTargets[gBattlerAttacker] = SKY_DROP_NO_TARGET; - gBattleStruct->skyDropTargets[gBattlerTarget] = SKY_DROP_NO_TARGET; - gStatuses3[gBattlerTarget] &= ~(STATUS3_SKY_DROPPED | STATUS3_ON_AIR); - gBattlescriptCurrInstr = cmd->nextInstr; - } - - // Confuse target if they were in the middle of Petal Dance/Outrage/Thrash when targeted. - if (gBattleMons[gBattlerTarget].volatiles.lockConfusionTurns) - gBattleScripting.moveEffect = MOVE_EFFECT_CONFUSION; - return; - } - case VARIOUS_SKY_DROP_YAWN: // If the mon that's sleeping due to Yawn was holding a Pokemon in Sky Drop, release the target and clear Sky Drop data. - { - VARIOUS_ARGS(); - if (gBattleStruct->skyDropTargets[gEffectBattler] != SKY_DROP_NO_TARGET && !(gStatuses3[gEffectBattler] & STATUS3_SKY_DROPPED)) - { - // Set the target of Sky Drop as gEffectBattler - gEffectBattler = gBattleStruct->skyDropTargets[gEffectBattler]; - - // Clear skyDropTargets data - gBattleStruct->skyDropTargets[gBattleStruct->skyDropTargets[gEffectBattler]] = SKY_DROP_NO_TARGET; - gBattleStruct->skyDropTargets[gEffectBattler] = SKY_DROP_NO_TARGET; - - // If the target was in the middle of Outrage/Thrash/etc. when targeted by Sky Drop, confuse them on release and do proper animation - if (gBattleMons[gEffectBattler].volatiles.lockConfusionTurns && CanBeConfused(gEffectBattler)) - { - gBattleMons[gEffectBattler].volatiles.lockConfusionTurns = 0; - gBattlerAttacker = gEffectBattler; - gBattleMons[gBattlerTarget].volatiles.confusionTurns = ((Random()) % 4) + 2; - gBattlescriptCurrInstr = BattleScript_ThrashConfuses; - return; - } - } - break; - } - case VARIOUS_JUMP_IF_PRANKSTER_BLOCKED: - { - VARIOUS_ARGS(const u8 *jumpInstr); - if (BlocksPrankster(gCurrentMove, gBattlerAttacker, battler, TRUE)) - gBattlescriptCurrInstr = cmd->jumpInstr; - else - gBattlescriptCurrInstr = cmd->nextInstr; - return; - } - case VARIOUS_TRY_TO_CLEAR_PRIMAL_WEATHER: - { - bool8 shouldNotClear = FALSE; - - for (i = 0; i < gBattlersCount; i++) - { - u32 ability = GetBattlerAbility(i); - if (((ability == ABILITY_DESOLATE_LAND && gBattleWeather & B_WEATHER_SUN_PRIMAL) - || (ability == ABILITY_PRIMORDIAL_SEA && gBattleWeather & B_WEATHER_RAIN_PRIMAL) - || (ability == ABILITY_DELTA_STREAM && gBattleWeather & B_WEATHER_STRONG_WINDS)) - && IsBattlerAlive(i)) - shouldNotClear = TRUE; - } - if (gBattleWeather & B_WEATHER_SUN_PRIMAL && !shouldNotClear) - { - gBattleWeather &= ~B_WEATHER_SUN_PRIMAL; - PrepareStringBattle(STRINGID_EXTREMESUNLIGHTFADED, battler); - gBattleCommunication[MSG_DISPLAY] = 1; - } - else if (gBattleWeather & B_WEATHER_RAIN_PRIMAL && !shouldNotClear) - { - gBattleWeather &= ~B_WEATHER_RAIN_PRIMAL; - PrepareStringBattle(STRINGID_HEAVYRAINLIFTED, battler); - gBattleCommunication[MSG_DISPLAY] = 1; - } - else if (gBattleWeather & B_WEATHER_STRONG_WINDS && !shouldNotClear) - { - gBattleWeather &= ~B_WEATHER_STRONG_WINDS; - PrepareStringBattle(STRINGID_STRONGWINDSDISSIPATED, battler); - gBattleCommunication[MSG_DISPLAY] = 1; - } - break; - } - case VARIOUS_TRY_END_NEUTRALIZING_GAS: - { - VARIOUS_ARGS(); - if (gSpecialStatuses[battler].neutralizingGasRemoved) - { - gSpecialStatuses[battler].neutralizingGasRemoved = FALSE; - BattleScriptPush(cmd->nextInstr); - gBattlescriptCurrInstr = BattleScript_NeutralizingGasExits; - return; - } - break; - } - case VARIOUS_GET_ROTOTILLER_TARGETS: - { - VARIOUS_ARGS(const u8 *failInstr); - // Gets the battlers to be affected by rototiller. If there are none, print 'But it failed!' - { - u32 count = 0; - for (i = 0; i < gBattlersCount; i++) - { - gSpecialStatuses[i].rototillerAffected = FALSE; - if (IsRototillerAffected(i)) - { - gSpecialStatuses[i].rototillerAffected = TRUE; - count++; - } - } - - if (count == 0) - gBattlescriptCurrInstr = cmd->failInstr; // Rototiller fails - else - gBattlescriptCurrInstr = cmd->nextInstr; - } - return; - } - case VARIOUS_JUMP_IF_NOT_ROTOTILLER_AFFECTED: - { - VARIOUS_ARGS(const u8 *jumpInstr); - if (gSpecialStatuses[battler].rototillerAffected) - { - gSpecialStatuses[battler].rototillerAffected = FALSE; - gBattlescriptCurrInstr = cmd->nextInstr; - } - else - { - gBattlescriptCurrInstr = cmd->jumpInstr; // Unaffected by rototiller - print STRINGID_NOEFFECTONTARGET - } - return; - } - case VARIOUS_CONSUME_BERRY: - { - VARIOUS_ARGS(bool8 fromBattler); - if (gBattleScripting.overrideBerryRequirements == 2) - { - gBattlescriptCurrInstr = cmd->nextInstr; - return; - } - - if (cmd->fromBattler) - gLastUsedItem = gBattleMons[battler].item; - - gBattleStruct->partyState[GetBattlerSide(battler)][gBattlerPartyIndexes[battler]].ateBerry = TRUE; - gBattleScripting.battler = gEffectBattler = gBattlerTarget = battler; // Cover all berry effect battler cases. e.g. ChangeStatBuffs uses target ID - if (ItemBattleEffects(ITEMEFFECT_USE_LAST_ITEM, battler)) - return; - gBattlescriptCurrInstr = cmd->nextInstr; - return; - } - case VARIOUS_JUMP_IF_CANT_REVERT_TO_PRIMAL: - { - VARIOUS_ARGS(const u8 *jumpInstr); - if (GetBattleFormChangeTargetSpecies(battler, FORM_CHANGE_BATTLE_PRIMAL_REVERSION) == gBattleMons[battler].species) - gBattlescriptCurrInstr = cmd->jumpInstr; - else - gBattlescriptCurrInstr = cmd->nextInstr; - return; - } - case VARIOUS_JUMP_IF_WEATHER_AFFECTED: - { - VARIOUS_ARGS(u32 flags, const u8 *jumpInstr); - u32 flags = cmd->flags; - if (IsBattlerWeatherAffected(battler, flags)) - gBattlescriptCurrInstr = cmd->jumpInstr; - else - gBattlescriptCurrInstr = cmd->nextInstr; - return; - } - case VARIOUS_JUMP_IF_SPECIES: - { - VARIOUS_ARGS(u16 species, const u8 *jumpInstr); - if (gBattleMons[battler].species == cmd->species) - gBattlescriptCurrInstr = cmd->jumpInstr; - else - gBattlescriptCurrInstr = cmd->nextInstr; - return; - } - case VARIOUS_JUMP_IF_LEAF_GUARD_PROTECTED: - { - VARIOUS_ARGS(const u8 *jumpInstr); - if (IsLeafGuardProtected(battler, GetBattlerAbility(battler))) - { - gBattlerAbility = battler; - gBattlescriptCurrInstr = cmd->jumpInstr; - } - else - { - gBattlescriptCurrInstr = cmd->nextInstr; - } - return; - } - case VARIOUS_SET_ATTACKER_STICKY_WEB_USER: - { - VARIOUS_ARGS(); - // For Mirror Armor: "If the Pokémon with this Ability is affected by Sticky Web, the effect is reflected back to the Pokémon which set it up. - // If Pokémon which set up Sticky Web is not on the field, no Pokémon have their Speed lowered." - gBattlerAttacker = gBattlerTarget; // Initialize 'fail' condition - SET_STATCHANGER(STAT_SPEED, 1, TRUE); - if (gSideTimers[GetBattlerSide(battler)].stickyWebBattlerId != 0xFF) - gBattlerAttacker = gSideTimers[GetBattlerSide(battler)].stickyWebBattlerId; - break; - } - case VARIOUS_CUT_1_3_HP_RAISE_STATS: - { - VARIOUS_ARGS(const u8 *failInstr); - - bool8 atLeastOneStatBoosted = FALSE; - u16 hpFraction = max(1, GetNonDynamaxMaxHP(gBattlerAttacker) / 3); - - for (i = 1; i < NUM_STATS; i++) - { - if (CompareStat(gBattlerAttacker, i, MAX_STAT_STAGE, CMP_LESS_THAN)) - { - atLeastOneStatBoosted = TRUE; - break; - } - } - if (atLeastOneStatBoosted && gBattleMons[gBattlerAttacker].hp > hpFraction) - { - gBattleStruct->moveDamage[gBattlerAttacker] = hpFraction; - gBattlescriptCurrInstr = cmd->nextInstr; - } - else - { - gBattlescriptCurrInstr = cmd->failInstr; - } - return; - } - case VARIOUS_CHECK_POLTERGEIST: - { - VARIOUS_ARGS(const u8 *failInstr); - if (gBattleMons[battler].item == ITEM_NONE - || gFieldStatuses & STATUS_FIELD_MAGIC_ROOM - || GetBattlerAbility(battler) == ABILITY_KLUTZ) - { - gBattlescriptCurrInstr = cmd->failInstr; - } - else - { - PREPARE_ITEM_BUFFER(gBattleTextBuff1, gBattleMons[battler].item); - gLastUsedItem = gBattleMons[battler].item; - gBattlescriptCurrInstr = cmd->nextInstr; - } - return; - } - case VARIOUS_TRY_NO_RETREAT: - { - VARIOUS_ARGS(const u8 *failInstr); - if (gDisableStructs[battler].noRetreat) - { - gBattlescriptCurrInstr = cmd->failInstr; - } - else - { - if (!gBattleMons[battler].volatiles.escapePrevention) - gDisableStructs[battler].noRetreat = TRUE; - gBattlescriptCurrInstr = cmd->nextInstr; - } - return; - } - case VARIOUS_CURE_CERTAIN_STATUSES: - { - VARIOUS_ARGS(); - // Check infatuation - if (gBattleMons[battler].volatiles.infatuation) - { - gBattleMons[battler].volatiles.infatuation = 0; - gBattleCommunication[MULTISTRING_CHOOSER] = B_MSG_MENTALHERBCURE_INFATUATION; // STRINGID_TARGETGOTOVERINFATUATION - StringCopy(gBattleTextBuff1, gStatusConditionString_LoveJpn); - } - // Check taunt - if (gDisableStructs[battler].tauntTimer != 0) - { - gDisableStructs[battler].tauntTimer = 0; - gBattleCommunication[MULTISTRING_CHOOSER] = B_MSG_MENTALHERBCURE_TAUNT; - PREPARE_MOVE_BUFFER(gBattleTextBuff1, MOVE_TAUNT); - } - // Check encore - if (gDisableStructs[battler].encoreTimer != 0) - { - gDisableStructs[battler].encoredMove = 0; - gDisableStructs[battler].encoreTimer = 0; - gBattleCommunication[MULTISTRING_CHOOSER] = B_MSG_MENTALHERBCURE_ENCORE; // STRINGID_PKMNENCOREENDED - } - // Check torment - if (gBattleMons[battler].volatiles.torment == TRUE) - { - gBattleMons[battler].volatiles.torment = FALSE; - gBattleCommunication[MULTISTRING_CHOOSER] = B_MSG_MENTALHERBCURE_TORMENT; - } - // Check heal block - if (gStatuses3[battler] & STATUS3_HEAL_BLOCK) - { - gStatuses3[battler] &= ~(STATUS3_HEAL_BLOCK); - gBattleCommunication[MULTISTRING_CHOOSER] = B_MSG_MENTALHERBCURE_HEALBLOCK; - } - // Check disable - if (gDisableStructs[battler].disableTimer != 0) - { - gDisableStructs[battler].disableTimer = 0; - gDisableStructs[battler].disabledMove = 0; - gBattleCommunication[MULTISTRING_CHOOSER] = B_MSG_MENTALHERBCURE_DISABLE; - } - gBattlescriptCurrInstr = cmd->nextInstr; - return; - } - case VARIOUS_TRY_RESET_NEGATIVE_STAT_STAGES: - { - VARIOUS_ARGS(); - battler = gBattlerTarget; - for (i = 0; i < NUM_BATTLE_STATS; i++) - if (gBattleMons[battler].statStages[i] < DEFAULT_STAT_STAGE) - gBattleMons[battler].statStages[i] = DEFAULT_STAT_STAGE; - gBattlescriptCurrInstr = cmd->nextInstr; - return; - } - case VARIOUS_JUMP_IF_LAST_USED_ITEM_BERRY: - { - VARIOUS_ARGS(const u8 *jumpInstr); - if (GetItemPocket(gLastUsedItem) == POCKET_BERRIES) - gBattlescriptCurrInstr = cmd->jumpInstr; - else - gBattlescriptCurrInstr = cmd->nextInstr; - return; - } - case VARIOUS_SAVE_BATTLER_ITEM: - { - VARIOUS_ARGS(); - gBattleHistory->heldItems[battler] = gBattleMons[battler].item; - break; - } - case VARIOUS_RESTORE_BATTLER_ITEM: - { - VARIOUS_ARGS(); - gBattleMons[battler].item = gBattleHistory->heldItems[battler]; - break; - } - case VARIOUS_BATTLER_ITEM_TO_LAST_USED_ITEM: - { - VARIOUS_ARGS(); - gBattleMons[battler].item = gLastUsedItem; - break; - } - } // End of switch (cmd->id) - gBattlescriptCurrInstr = cmd->nextInstr; } @@ -18351,3 +16757,1636 @@ void BS_TrySynchronoise(void) else gBattlescriptCurrInstr = cmd->jumpInstr; } + +void BS_JumpIfRoarFails(void) +{ + NATIVE_ARGS(const u8 *jumpInstr); + + if (WILD_DOUBLE_BATTLE + && IsOnPlayerSide(gBattlerAttacker) + && !IsOnPlayerSide(gBattlerTarget) + && IS_WHOLE_SIDE_ALIVE(gBattlerTarget)) + gBattlescriptCurrInstr = cmd->jumpInstr; + else if (WILD_DOUBLE_BATTLE + && !IsOnPlayerSide(gBattlerAttacker) + && !IsOnPlayerSide(gBattlerTarget)) + gBattlescriptCurrInstr = cmd->jumpInstr; + else if (FlagGet(B_FLAG_NO_RUNNING)) + gBattlescriptCurrInstr = cmd->jumpInstr; + else + gBattlescriptCurrInstr = cmd->nextInstr; +} + +void BS_JumpIfAbsent(void) +{ + NATIVE_ARGS(u8 battler, const u8 *jumpInstr); + if (!IsBattlerAlive(GetBattlerForBattleScript(cmd->battler))) + gBattlescriptCurrInstr = cmd->jumpInstr; + else + gBattlescriptCurrInstr = cmd->nextInstr; +} + +void BS_JumpIfHoldEffect(void) +{ + NATIVE_ARGS(u8 battler, u8 holdEffect, const u8 *jumpInstr, u8 equal); + u32 battler = GetBattlerForBattleScript(cmd->battler); + if ((GetBattlerHoldEffect(battler, TRUE) == cmd->holdEffect) == cmd->equal) + { + if (cmd->equal) + gLastUsedItem = gBattleMons[battler].item; // For B_LAST_USED_ITEM + gBattlescriptCurrInstr = cmd->jumpInstr; + } + else + { + if (!cmd->equal) + gLastUsedItem = gBattleMons[battler].item; // For B_LAST_USED_ITEM + gBattlescriptCurrInstr = cmd->nextInstr; + } +} + +void BS_JumpIfNoAlly(void) +{ + NATIVE_ARGS(u8 battler, const u8 *jumpInstr); + u32 partner = BATTLE_PARTNER(GetBattlerForBattleScript(cmd->battler)); + if (!IsBattlerAlive(partner)) + gBattlescriptCurrInstr = cmd->jumpInstr; + else + gBattlescriptCurrInstr = cmd->nextInstr; +} + +void BS_InfatuateWithBattler(void) +{ + NATIVE_ARGS(u8 battler, u8 infatuateWith); + u32 battler = GetBattlerForBattleScript(cmd->battler); + gBattleScripting.battler = battler; + gBattleMons[battler].volatiles.infatuation = INFATUATED_WITH(GetBattlerForBattleScript(cmd->infatuateWith)); + gBattlescriptCurrInstr = cmd->nextInstr; +} + +void BS_SetLastUsedItem(void) +{ + NATIVE_ARGS(u8 battler); + gLastUsedItem = gBattleMons[GetBattlerForBattleScript(cmd->battler)].item; + gBattlescriptCurrInstr = cmd->nextInstr; +} + +void BS_TrySetFairyLock(void) +{ + NATIVE_ARGS(const u8 *failInstr); + if (gFieldStatuses & STATUS_FIELD_FAIRY_LOCK) + { + gBattlescriptCurrInstr = cmd->failInstr; + } + else + { + gFieldStatuses |= STATUS_FIELD_FAIRY_LOCK; + gFieldTimers.fairyLockTimer = gBattleTurnCounter + 2; + gBattlescriptCurrInstr = cmd->nextInstr; + } +} + +void BS_GetStatValue(void) +{ + NATIVE_ARGS(u8 stat); + u32 stat = cmd->stat; + gBattleStruct->moveDamage[gBattlerAttacker] = *(u16 *)(&gBattleMons[gBattlerTarget].attack) + (stat - 1); + gBattleStruct->moveDamage[gBattlerAttacker] *= gStatStageRatios[gBattleMons[gBattlerTarget].statStages[stat]][0]; + gBattleStruct->moveDamage[gBattlerAttacker] /= gStatStageRatios[gBattleMons[gBattlerTarget].statStages[stat]][1]; + gBattlescriptCurrInstr = cmd->nextInstr; +} + +void BS_JumpIfFullHp(void) +{ + NATIVE_ARGS(u8 battler, const u8 *jumpInstr); + if (IsBattlerAtMaxHp(GetBattlerForBattleScript(cmd->battler))) + gBattlescriptCurrInstr = cmd->jumpInstr; + else + gBattlescriptCurrInstr = cmd->nextInstr; +} + +void BS_TryFriskMessage(void) +{ + NATIVE_ARGS(); + while (gBattleStruct->friskedBattler < gBattlersCount) + { + gBattlerTarget = gBattleStruct->friskedBattler++; + if (!IsBattlerAlly(gBattlerAttacker, gBattlerTarget) + && IsBattlerAlive(gBattlerTarget) + && gBattleMons[gBattlerTarget].item != ITEM_NONE) + { + gLastUsedItem = gBattleMons[gBattlerTarget].item; + RecordItemEffectBattle(gBattlerTarget, GetBattlerHoldEffect(gBattlerTarget, FALSE)); + // If Frisk identifies two mons' items, show the pop-up only once. + if (gBattleStruct->friskedAbility) + { + BattleScriptCall(BattleScript_FriskMsg); + } + else + { + gBattleStruct->friskedAbility = TRUE; + BattleScriptCall(BattleScript_FriskMsgWithPopup); + } + return; + } + } + gBattleStruct->friskedBattler = 0; + gBattleStruct->friskedAbility = FALSE; + gBattlescriptCurrInstr = cmd->nextInstr; +} + +void BS_SetTracedAbility(void) +{ + NATIVE_ARGS(u8 battler); + u32 battler = GetBattlerForBattleScript(cmd->battler); + gBattleMons[battler].ability = gDisableStructs[battler].overwrittenAbility = gBattleStruct->tracedAbility[battler]; + gBattlescriptCurrInstr = cmd->nextInstr; +} + +void BS_TryIllusionOff(void) +{ + NATIVE_ARGS(u8 battler); + if (TryClearIllusion(GetBattlerForBattleScript(cmd->battler), ABILITYEFFECT_MOVE_END)) + return; + gBattlescriptCurrInstr = cmd->nextInstr; +} + +void BS_SetSpriteIgnore0Hp(void) +{ + NATIVE_ARGS(bool8 ignore0HP); + gBattleStruct->spriteIgnore0Hp = cmd->ignore0HP; + gBattlescriptCurrInstr = cmd->nextInstr; +} + +void BS_UpdateNick(void) +{ + NATIVE_ARGS(); + u32 battler = gBattleScripting.battler; + UpdateHealthboxAttribute(gHealthboxSpriteIds[battler], GetBattlerMon(battler), HEALTHBOX_NICK); + gBattlescriptCurrInstr = cmd->nextInstr; +} + +void BS_JumpIfNotBerry(void) +{ + NATIVE_ARGS(u8 battler, const u8 *jumpInstr); + if (GetItemPocket(gBattleMons[GetBattlerForBattleScript(cmd->battler)].item) == POCKET_BERRIES) + gBattlescriptCurrInstr = cmd->nextInstr; + else + gBattlescriptCurrInstr = cmd->jumpInstr; +} + +void BS_GravityOnAirborneMons(void) +{ + NATIVE_ARGS(); + // Cancel all multiturn moves of IN_AIR Pokemon except those being targeted by Sky Drop. + if (gStatuses3[gBattlerTarget] & STATUS3_ON_AIR && !(gStatuses3[gBattlerTarget] & STATUS3_SKY_DROPPED)) + CancelMultiTurnMoves(gBattlerTarget, SKY_DROP_GRAVITY_ON_AIRBORNE); + + gStatuses3[gBattlerTarget] &= ~(STATUS3_MAGNET_RISE | STATUS3_TELEKINESIS | STATUS3_ON_AIR | STATUS3_SKY_DROPPED); + gBattlescriptCurrInstr = cmd->nextInstr; +} + +void BS_TryAcupressure(void) +{ + NATIVE_ARGS(const u8 *failInstr); + u32 bits = 0; + for (u32 stat = STAT_ATK; stat < NUM_BATTLE_STATS; stat++) + { + if (CompareStat(gBattlerTarget, stat, MAX_STAT_STAGE, CMP_LESS_THAN)) + bits |= 1u << stat; + } + if (bits) + { + u32 statId; + do + { + statId = (Random() % (NUM_BATTLE_STATS - 1)) + 1; + } while (!(bits & (1u << statId))); + + SET_STATCHANGER(statId, 2, FALSE); + gBattlescriptCurrInstr = cmd->nextInstr; + } + else + { + gBattlescriptCurrInstr = cmd->failInstr; + } +} + +void BS_CancelMultiTurnMoves(void) +{ + NATIVE_ARGS(); + const u8 *result = CancelMultiTurnMoves(gBattlerAttacker, SKY_DROP_CANCEL_MULTI_TURN_MOVES); + if (result) + gBattlescriptCurrInstr = result; + else + gBattlescriptCurrInstr = cmd->nextInstr; +} + +void BS_IsRunningImpossible(void) +{ + NATIVE_ARGS(); + gBattleCommunication[0] = IsRunningFromBattleImpossible(gBattlerAttacker); + gBattlescriptCurrInstr = cmd->nextInstr; +} + +void BS_GetMoveTarget(void) +{ + NATIVE_ARGS(); + gBattlerTarget = GetBattleMoveTarget(gCurrentMove, NO_TARGET_OVERRIDE); + gBattlescriptCurrInstr = cmd->nextInstr; +} + +void BS_GetBattlerFainted(void) +{ + NATIVE_ARGS(u8 battler); + if (gHitMarker & HITMARKER_FAINTED(GetBattlerForBattleScript(cmd->battler))) + gBattleCommunication[0] = TRUE; + else + gBattleCommunication[0] = FALSE; + gBattlescriptCurrInstr = cmd->nextInstr; +} + +void BS_ResetSwitchInAbilityBits(void) +{ + NATIVE_ARGS(); + gSpecialStatuses[gBattlerAttacker].switchInAbilityDone = FALSE; + gBattlescriptCurrInstr = cmd->nextInstr; +} + +void BS_UpdateChoiceMoveOnLvlUp(void) +{ + NATIVE_ARGS(); + if (gBattlerPartyIndexes[0] == gBattleStruct->expGetterMonId || gBattlerPartyIndexes[2] == gBattleStruct->expGetterMonId) + { + u32 battler; + if (gBattlerPartyIndexes[0] == gBattleStruct->expGetterMonId) + battler = 0; + else + battler = 2; + + u32 moveIndex; + for (moveIndex = 0; moveIndex < MAX_MON_MOVES; moveIndex++) + { + if (gBattleMons[battler].moves[moveIndex] == gBattleStruct->choicedMove[battler]) + break; + } + if (moveIndex == MAX_MON_MOVES) + gBattleStruct->choicedMove[battler] = MOVE_NONE; + } + gBattlescriptCurrInstr = cmd->nextInstr; +} + +void BS_ResetPlayerFainted(void) +{ + NATIVE_ARGS(); + if (!(gBattleTypeFlags & (BATTLE_TYPE_LINK | BATTLE_TYPE_DOUBLE)) + && gBattleTypeFlags & BATTLE_TYPE_TRAINER + && IsBattlerAlive(B_POSITION_PLAYER_LEFT) + && IsBattlerAlive(B_POSITION_OPPONENT_LEFT)) + { + gHitMarker &= ~HITMARKER_PLAYER_FAINTED; + } + gBattlescriptCurrInstr = cmd->nextInstr; +} + +void BS_PalaceFlavorText(void) +{ + NATIVE_ARGS(); + // Try and print end-of-turn Battle Palace flavor text (e.g. "A glint appears in mon's eyes") + u32 battler; + gBattleCommunication[0] = FALSE; // whether or not msg should be printed + gBattleScripting.battler = battler = gBattleCommunication[1]; + if (!(gBattleStruct->palaceFlags & (1u << battler)) + && gBattleMons[battler].maxHP / 2 >= gBattleMons[battler].hp + && IsBattlerAlive(battler) + && !(gBattleMons[battler].status1 & STATUS1_SLEEP)) + { + gBattleStruct->palaceFlags |= 1u << battler; + gBattleCommunication[0] = TRUE; + gBattleCommunication[MULTISTRING_CHOOSER] = gNaturesInfo[GetNatureFromPersonality(gBattleMons[battler].personality)].battlePalaceFlavorText; + } + gBattlescriptCurrInstr = cmd->nextInstr; +} + +void BS_ArenaJudgmentWindow(void) +{ + NATIVE_ARGS(); + u32 judgmentWindow = BattleArena_ShowJudgmentWindow(&gBattleCommunication[0]); + + // BattleArena_ShowJudgmentWindow's last state was an intermediate step. + // Return without advancing the current instruction so that it will be called again. + if (judgmentWindow == ARENA_RESULT_RUNNING) + return; + + gBattleCommunication[1] = judgmentWindow; + gBattlescriptCurrInstr = cmd->nextInstr; +} + +static void SetArenMonLostValues(u32 battler) +{ + gBattleMons[battler].hp = 0; + gHitMarker |= HITMARKER_FAINTED(battler); + gBattleStruct->arenaLostOpponentMons |= 1u << gBattlerPartyIndexes[battler]; + gDisableStructs[battler].truantSwitchInHack = TRUE; +} + +#define playerMon 0 +#define opponentMon 1 +void BS_ArenaOpponentMonLost(void) +{ + NATIVE_ARGS(); + SetArenMonLostValues(opponentMon); + gBattlescriptCurrInstr = cmd->nextInstr; +} + +void BS_ArenaPlayerMonLost(void) +{ + NATIVE_ARGS(); + SetArenMonLostValues(playerMon); + gBattlescriptCurrInstr = cmd->nextInstr; +} + +void BS_ArenaBothMonsLost(void) +{ + NATIVE_ARGS(); + SetArenMonLostValues(playerMon); + SetArenMonLostValues(opponentMon); + gBattlescriptCurrInstr = cmd->nextInstr; +} +#undef playerMon +#undef opponentMon + +void BS_ForfeitYesNoBox(void) +{ + NATIVE_ARGS(); + BtlController_EmitYesNoBox(gBattlerAttacker, B_COMM_TO_CONTROLLER); + MarkBattlerForControllerExec(gBattlerAttacker); + gBattlescriptCurrInstr = cmd->nextInstr; +} + +void BS_DrawArenaRefTextBox(void) +{ + NATIVE_ARGS(); + DrawArenaRefereeTextBox(); + gBattlescriptCurrInstr = cmd->nextInstr; +} + +void BS_EraseArenaRefTextBox(void) +{ + NATIVE_ARGS(); + EraseArenaRefereeTextBox(); + gBattlescriptCurrInstr = cmd->nextInstr; +} + +void BS_ArenaJudgmentString(void) +{ + CMD_ARGS(u8 id); + BattleStringExpandPlaceholdersToDisplayedString(gRefereeStringsTable[cmd->id]); + BattlePutTextOnWindow(gDisplayedStringBattle, ARENA_WIN_JUDGMENT_TEXT); + gBattlescriptCurrInstr = cmd->nextInstr; +} + +// Argument passed but no use +void BS_ArenaWaitMessage(void) +{ + NATIVE_ARGS(); + if (IsTextPrinterActive(ARENA_WIN_JUDGMENT_TEXT)) + return; + gBattlescriptCurrInstr = cmd->nextInstr; +} + +void BS_WaitCry(void) +{ + NATIVE_ARGS(); + if (!IsCryFinished()) + return; + gBattlescriptCurrInstr = cmd->nextInstr; +} + +#define opponentFirstBattler 1 +#define opponentSecondBattler 3 +void BS_ReturnOpponentMon1ToBall(void) +{ + NATIVE_ARGS(); + if (IsBattlerAlive(opponentFirstBattler)) + { + BtlController_EmitReturnMonToBall(opponentFirstBattler, B_COMM_TO_CONTROLLER, FALSE); + MarkBattlerForControllerExec(opponentFirstBattler); + } + gBattlescriptCurrInstr = cmd->nextInstr; +} + +void BS_ReturnOpponentMon2ToBall(void) +{ + NATIVE_ARGS(); + if (gBattlersCount > opponentSecondBattler) + { + if (IsBattlerAlive(opponentSecondBattler)) + { + BtlController_EmitReturnMonToBall(opponentSecondBattler, B_COMM_TO_CONTROLLER, FALSE); + MarkBattlerForControllerExec(opponentSecondBattler); + } + } + gBattlescriptCurrInstr = cmd->nextInstr; +} +#undef opponentFirstBattler +#undef opponentSecondBattler + +void BS_VolumeDown(void) +{ + NATIVE_ARGS(); + m4aMPlayVolumeControl(&gMPlayInfo_BGM, TRACKS_ALL, 0x55); + gBattlescriptCurrInstr = cmd->nextInstr; +} + +void BS_VolumeUp(void) +{ + NATIVE_ARGS(); + m4aMPlayVolumeControl(&gMPlayInfo_BGM, TRACKS_ALL, 0x100); + gBattlescriptCurrInstr = cmd->nextInstr; +} + +void BS_SetAlreadyStatusedMoveAttempt(void) +{ + NATIVE_ARGS(); + gBattleStruct->battlerState[gBattlerAttacker].alreadyStatusedMoveAttempt = TRUE; + gBattlescriptCurrInstr = cmd->nextInstr; +} + +void BS_PalaceTryEscapeStatus(void) +{ + NATIVE_ARGS(); + if (BattlePalace_TryEscapeStatus(gBattlerAttacker)) + return; + gBattlescriptCurrInstr = cmd->nextInstr; +} + +void BS_SetTeleportOutcome(void) +{ + NATIVE_ARGS(u8 battler); + u32 battler = GetBattlerForBattleScript(cmd->battler); + + // Don't end the battle if one of the wild mons teleported from the wild double battle + // and its partner is still alive. + if (!IsOnPlayerSide(battler) && IsBattlerAlive(BATTLE_PARTNER(battler))) + { + gAbsentBattlerFlags |= 1u << battler; + gHitMarker |= HITMARKER_FAINTED(battler); + gBattleMons[battler].hp = 0; + SetMonData(GetBattlerMon(battler), MON_DATA_HP, &gBattleMons[battler].hp); + SetHealthboxSpriteInvisible(gHealthboxSpriteIds[battler]); + FaintClearSetData(battler); + } + else if (IsOnPlayerSide(battler)) + { + gBattleOutcome = B_OUTCOME_PLAYER_TELEPORTED; + } + else + { + gBattleOutcome = B_OUTCOME_MON_TELEPORTED; + } + gBattlescriptCurrInstr = cmd->nextInstr; +} + +void BS_PlayTrainerDefeatedMusic(void) +{ + NATIVE_ARGS(); + BtlController_EmitPlayFanfareOrBGM(gBattlerAttacker, B_COMM_TO_CONTROLLER, MUS_VICTORY_TRAINER, TRUE); + MarkBattlerForControllerExec(gBattlerAttacker); + gBattlescriptCurrInstr = cmd->nextInstr; +} + +void BS_StatTextBuffer(void) +{ + NATIVE_ARGS(); + PREPARE_STAT_BUFFER(gBattleTextBuff1, gBattleCommunication[0]); + gBattlescriptCurrInstr = cmd->nextInstr; +} + +void BS_SwitchinAbilities(void) +{ + NATIVE_ARGS(u8 battler); + u32 battler = GetBattlerForBattleScript(cmd->battler); + gBattlescriptCurrInstr = cmd->nextInstr; + AbilityBattleEffects(ABILITYEFFECT_NEUTRALIZINGGAS, battler, 0, 0, 0); + AbilityBattleEffects(ABILITYEFFECT_ON_SWITCHIN, battler, 0, 0, 0); + AbilityBattleEffects(ABILITYEFFECT_OPPORTUNIST, battler, 0, 0, 0); +} + +void BS_InstantHpDrop(void) +{ + NATIVE_ARGS(); + BtlController_EmitHealthBarUpdate(gBattlerAttacker, B_COMM_TO_CONTROLLER, INSTANT_HP_BAR_DROP); + MarkBattlerForControllerExec(gBattlerAttacker); + gBattlescriptCurrInstr = cmd->nextInstr; +} + +void BS_ClearStatus(void) +{ + NATIVE_ARGS(); + gBattleMons[gBattlerAttacker].status1 = 0; + BtlController_EmitSetMonData( + gBattlerAttacker, + B_COMM_TO_CONTROLLER, + REQUEST_STATUS_BATTLE, + 0, + sizeof(gBattleMons[gBattlerAttacker].status1), + &gBattleMons[gBattlerAttacker].status1); + MarkBattlerForControllerExec(gBattlerAttacker); + gBattlescriptCurrInstr = cmd->nextInstr; +} + +// NEW BATCH + +void BS_RestoreMovePp(void) +{ + NATIVE_ARGS(); + u32 moveIndex; + u32 data[MAX_MON_MOVES + 1]; + for (moveIndex = 0; moveIndex < MAX_MON_MOVES; moveIndex++) + { + gBattleMons[gBattlerAttacker].pp[moveIndex] = CalculatePPWithBonus(gBattleMons[gBattlerAttacker].moves[moveIndex], gBattleMons[gBattlerAttacker].ppBonuses, moveIndex); + data[moveIndex] = gBattleMons[gBattlerAttacker].pp[moveIndex]; + } + data[moveIndex] = gBattleMons[gBattlerAttacker].ppBonuses; + BtlController_EmitSetMonData(gBattlerAttacker, B_COMM_TO_CONTROLLER, REQUEST_PP_DATA_BATTLE, 0, 5, data); + MarkBattlerForControllerExec(gBattlerAttacker); + gBattlescriptCurrInstr = cmd->nextInstr; +} + +void BS_TryActivateReceiver(void) +{ + NATIVE_ARGS(u8 battler); + u32 battler = GetBattlerForBattleScript(cmd->battler); + gBattlerAbility = BATTLE_PARTNER(battler); + u32 partnerAbility = GetBattlerAbility(gBattlerAbility); + if (IsBattlerAlive(gBattlerAbility) + && (partnerAbility == ABILITY_RECEIVER || partnerAbility == ABILITY_POWER_OF_ALCHEMY) + && GetBattlerHoldEffect(battler, TRUE) != HOLD_EFFECT_ABILITY_SHIELD + && !gAbilitiesInfo[gBattleMons[battler].ability].cantBeCopied) + { + gBattleStruct->tracedAbility[gBattlerAbility] = gBattleMons[battler].ability; // re-using the variable for trace + gBattleScripting.battler = battler; + BattleScriptPush(cmd->nextInstr); + gBattlescriptCurrInstr = BattleScript_ReceiverActivates; + } + else + { + gBattlescriptCurrInstr = cmd->nextInstr; + } +} + +void BS_TryActivateSoulheart(void) +{ + NATIVE_ARGS(); + while (gBattleStruct->soulheartBattlerId < gBattlersCount) + { + gBattleScripting.battler = gBattleStruct->soulheartBattlerId++; + if (GetBattlerAbility(gBattleScripting.battler) == ABILITY_SOUL_HEART + && IsBattlerAlive(gBattleScripting.battler) + && !NoAliveMonsForEitherParty() + && CompareStat(gBattleScripting.battler, STAT_SPATK, MAX_STAT_STAGE, CMP_LESS_THAN)) + { + SET_STATCHANGER(STAT_SPATK, 1, FALSE); + PREPARE_STAT_BUFFER(gBattleTextBuff1, STAT_SPATK); + BattleScriptCall(BattleScript_ScriptingAbilityStatRaise); + return; + } + } + gBattleStruct->soulheartBattlerId = 0; + gBattlescriptCurrInstr = cmd->nextInstr; +} + +void BS_PlayMoveAnimation(void) +{ + NATIVE_ARGS(u16 move); + BtlController_EmitMoveAnimation( + gBattlerAttacker, + B_COMM_TO_CONTROLLER, + cmd->move, + gBattleScripting.animTurn, + 0, + 0, + gBattleMons[gBattlerAttacker].friendship, + &gDisableStructs[gBattlerAttacker], + gMultiHitCounter); + MarkBattlerForControllerExec(gBattlerAttacker); + gBattlescriptCurrInstr = cmd->nextInstr; +} + +void BS_SetLuckyChant(void) +{ + NATIVE_ARGS(const u8 *failInstr); + u32 side = GetBattlerSide(gBattlerAttacker); + if (!(gSideStatuses[side] & SIDE_STATUS_LUCKY_CHANT)) + { + gSideStatuses[side] |= SIDE_STATUS_LUCKY_CHANT; + gSideTimers[side].luckyChantTimer = gBattleTurnCounter + 5; + gBattlescriptCurrInstr = cmd->nextInstr; + } + else + { + gBattlescriptCurrInstr = cmd->failInstr; + } +} + +void BS_SuckerPunchCheck(void) +{ + NATIVE_ARGS(const u8 *failInstr); + if (gProtectStructs[gBattlerTarget].protected == PROTECT_OBSTRUCT) + gBattlescriptCurrInstr = cmd->failInstr; + else if (GetBattlerTurnOrderNum(gBattlerAttacker) > GetBattlerTurnOrderNum(gBattlerTarget)) + gBattlescriptCurrInstr = cmd->failInstr; + else if (IsBattleMoveStatus(gBattleMons[gBattlerTarget].moves[gBattleStruct->chosenMovePositions[gBattlerTarget]]) && !gProtectStructs[gBattlerTarget].noValidMoves) + gBattlescriptCurrInstr = cmd->failInstr; + else + gBattlescriptCurrInstr = cmd->nextInstr; +} + +void BS_SetSimpleBeam(void) +{ + NATIVE_ARGS(const u8 *failInstr); + if (gAbilitiesInfo[gBattleMons[gBattlerTarget].ability].cantBeOverwritten + || gBattleMons[gBattlerTarget].ability == ABILITY_SIMPLE) + { + RecordAbilityBattle(gBattlerTarget, gBattleMons[gBattlerTarget].ability); + gBattlescriptCurrInstr = cmd->failInstr; + } + else if (GetBattlerHoldEffect(gBattlerTarget, TRUE) == HOLD_EFFECT_ABILITY_SHIELD) + { + RecordItemEffectBattle(gBattlerTarget, HOLD_EFFECT_ABILITY_SHIELD); + gBattlescriptCurrInstr = cmd->failInstr; + } + else + { + if (gBattleMons[gBattlerTarget].ability == ABILITY_NEUTRALIZING_GAS) + gSpecialStatuses[gBattlerTarget].neutralizingGasRemoved = TRUE; + + gBattleScripting.abilityPopupOverwrite = gBattleMons[gBattlerTarget].ability; + gBattleMons[gBattlerTarget].ability = gDisableStructs[gBattlerTarget].overwrittenAbility = ABILITY_SIMPLE; + gBattlescriptCurrInstr = cmd->nextInstr; + } +} + +void BS_TryEntrainment(void) +{ + NATIVE_ARGS(const u8 *failInstr); + if (gAbilitiesInfo[gBattleMons[gBattlerAttacker].ability].cantBeCopied + || gAbilitiesInfo[gBattleMons[gBattlerTarget].ability].cantBeOverwritten) + { + RecordAbilityBattle(gBattlerTarget, gBattleMons[gBattlerTarget].ability); + gBattlescriptCurrInstr = cmd->failInstr; + } + else if (GetBattlerHoldEffect(gBattlerTarget, TRUE) == HOLD_EFFECT_ABILITY_SHIELD) + { + RecordItemEffectBattle(gBattlerTarget, HOLD_EFFECT_ABILITY_SHIELD); + gBattlescriptCurrInstr = cmd->failInstr; + } + else + { + if (gBattleMons[gBattlerTarget].ability == gBattleMons[gBattlerAttacker].ability + || (GetActiveGimmick(gBattlerTarget) == GIMMICK_DYNAMAX)) + { + gBattlescriptCurrInstr = cmd->failInstr; + } + else + { + gBattleMons[gBattlerTarget].ability = gDisableStructs[gBattlerTarget].overwrittenAbility = gBattleMons[gBattlerAttacker].ability; + gBattlescriptCurrInstr = cmd->nextInstr; + } + } +} + +void BS_SetLastUsedAbility(void) +{ + NATIVE_ARGS(); + gLastUsedAbility = gBattleMons[gBattlerTarget].ability; + gBattlescriptCurrInstr = cmd->nextInstr; +} + +void BS_InvertStatStages(void) +{ + NATIVE_ARGS(); + for (u32 i = 0; i < NUM_BATTLE_STATS; i++) + { + if (gBattleMons[gBattlerTarget].statStages[i] < DEFAULT_STAT_STAGE) // Negative becomes positive. + gBattleMons[gBattlerTarget].statStages[i] = DEFAULT_STAT_STAGE + (DEFAULT_STAT_STAGE - gBattleMons[gBattlerTarget].statStages[i]); + else if (gBattleMons[gBattlerTarget].statStages[i] > DEFAULT_STAT_STAGE) // Positive becomes negative. + gBattleMons[gBattlerTarget].statStages[i] = DEFAULT_STAT_STAGE - (gBattleMons[gBattlerTarget].statStages[i] - DEFAULT_STAT_STAGE); + } + gBattlescriptCurrInstr = cmd->nextInstr; +} + +void BS_TryMeFirst(void) +{ + NATIVE_ARGS(const u8 *failInstr); + u16 move = gBattleMons[gBattlerTarget].moves[gBattleStruct->chosenMovePositions[gBattlerTarget]]; + if (IsBattleMoveStatus(move) || IsMoveMeFirstBanned(move) + || GetBattlerTurnOrderNum(gBattlerAttacker) > GetBattlerTurnOrderNum(gBattlerTarget)) + { + gBattlescriptCurrInstr = cmd->failInstr; + } + else + { + if (GetActiveGimmick(gBattlerAttacker) == GIMMICK_Z_MOVE && !IsBattleMoveStatus(move)) + { + gBattleStruct->zmove.baseMoves[gBattlerAttacker] = move; + gCalledMove = GetTypeBasedZMove(move); + } + else + { + gCalledMove = move; + } + gHitMarker &= ~HITMARKER_ATTACKSTRING_PRINTED; + gBattlerTarget = GetBattleMoveTarget(gCalledMove, NO_TARGET_OVERRIDE); + gBattlescriptCurrInstr = cmd->nextInstr; + } +} + +void BS_TryElectrify(void) +{ + NATIVE_ARGS(const u8 *failInstr); + if (GetBattlerTurnOrderNum(gBattlerAttacker) > GetBattlerTurnOrderNum(gBattlerTarget)) + { + gBattlescriptCurrInstr = cmd->failInstr; + } + else + { + gStatuses4[gBattlerTarget] |= STATUS4_ELECTRIFIED; + gBattlescriptCurrInstr = cmd->nextInstr; + } +} + +void BS_TrySoak(void) +{ + NATIVE_ARGS(const u8 *failInstr); + u32 types[3]; + GetBattlerTypes(gBattlerTarget, FALSE, types); + u32 typeToSet = GetMoveArgType(gCurrentMove); + if ((types[0] == typeToSet && types[1] == typeToSet) + || GetActiveGimmick(gBattlerTarget) == GIMMICK_TERA) + { + gBattlescriptCurrInstr = cmd->failInstr; + } + else + { + SET_BATTLER_TYPE(gBattlerTarget, typeToSet); + PREPARE_TYPE_BUFFER(gBattleTextBuff1, typeToSet); + gBattlescriptCurrInstr = cmd->nextInstr; + } +} + +void BS_HandleFormChange(void) +{ + NATIVE_ARGS(u8 battler, u8 case_); + u32 battler = GetBattlerForBattleScript(cmd->battler); + struct Pokemon *mon = GetBattlerMon(battler); + + if (cmd->case_ == 0) // Change species. + { + BtlController_EmitSetMonData(battler, B_COMM_TO_CONTROLLER, REQUEST_SPECIES_BATTLE, 1u << gBattlerPartyIndexes[battler], sizeof(gBattleMons[battler].species), &gBattleMons[battler].species); + MarkBattlerForControllerExec(battler); + } + else if (cmd->case_ == 1) // Change stats. + { + RecalcBattlerStats(battler, mon, FALSE); + } + else // Update healthbox. + { + UpdateHealthboxAttribute(gHealthboxSpriteIds[battler], mon, HEALTHBOX_ALL); + } + gBattlescriptCurrInstr = cmd->nextInstr; +} + +void BS_TryLastResort(void) +{ + NATIVE_ARGS(const u8 *failInstr); + if (CanUseLastResort(gBattlerAttacker)) + gBattlescriptCurrInstr = cmd->nextInstr; + else + gBattlescriptCurrInstr = cmd->failInstr; +} + +void BS_TryAutotomize(void) +{ + NATIVE_ARGS(const u8 *failInstr); + if (GetBattlerWeight(gBattlerAttacker) > 1) + { + gDisableStructs[gBattlerAttacker].autotomizeCount++; + gBattlescriptCurrInstr = cmd->nextInstr; + } + else + { + gBattlescriptCurrInstr = cmd->failInstr; + } +} + +void BS_TryInstruct(void) +{ + NATIVE_ARGS(const u8 *failInstr); + u16 move = gLastPrintedMoves[gBattlerTarget]; + if (move == MOVE_NONE || move == MOVE_UNAVAILABLE || MoveHasAdditionalEffectSelf(move, MOVE_EFFECT_RECHARGE) + || IsMoveInstructBanned(move) + || gBattleMoveEffects[GetMoveEffect(move)].twoTurnEffect + || (GetActiveGimmick(gBattlerTarget) == GIMMICK_DYNAMAX) + || IsZMove(move) + || IsMaxMove(move)) + { + gBattlescriptCurrInstr = cmd->failInstr; + } + else + { + gSpecialStatuses[gBattlerTarget].instructedChosenTarget = gBattleStruct->moveTarget[gBattlerTarget] | 0x4; + gCalledMove = move; + u32 moveIndex; + for (moveIndex = 0; moveIndex < MAX_MON_MOVES; moveIndex++) + { + if (gBattleMons[gBattlerTarget].moves[moveIndex] == gCalledMove) + { + gCurrMovePos = moveIndex; + moveIndex = 4; + break; + } + } + if (moveIndex != 4 || gBattleMons[gBattlerTarget].pp[gCurrMovePos] == 0) + { + gBattlescriptCurrInstr = cmd->failInstr; + } + else + { + gEffectBattler = gBattleStruct->lastMoveTarget[gBattlerTarget]; + gHitMarker &= ~HITMARKER_ATTACKSTRING_PRINTED; + PREPARE_MON_NICK_WITH_PREFIX_BUFFER(gBattleTextBuff1, gBattlerTarget, gBattlerPartyIndexes[gBattlerTarget]); + gBattlescriptCurrInstr = cmd->nextInstr; + } + } +} + +void BS_ShowAbilityPopup(void) +{ + NATIVE_ARGS(); + CreateAbilityPopUp(gBattlerAbility, gBattleMons[gBattlerAbility].ability, (IsDoubleBattle()) != 0); + gBattlescriptCurrInstr = cmd->nextInstr; +} + +void BS_UpdateAbilityPopup(void) +{ + NATIVE_ARGS(); + UpdateAbilityPopup(gBattlerAbility); + gBattlescriptCurrInstr = cmd->nextInstr; +} + +void BS_JumpIfTargetAlly(void) +{ + NATIVE_ARGS(const u8 *jumpInstr); + if (!IsBattlerAlly(gBattlerAttacker, gBattlerTarget)) + gBattlescriptCurrInstr = cmd->nextInstr; + else + gBattlescriptCurrInstr = cmd->jumpInstr; +} + +void BS_TryPsychoShift(void) +{ + NATIVE_ARGS(const u8 *failInstr, const u8 *sleepClauseFailInstr); + u32 targetAbility = GetBattlerAbility(gBattlerTarget); + // Psycho shift works + if ((gBattleMons[gBattlerAttacker].status1 & STATUS1_POISON) && CanBePoisoned(gBattlerAttacker, gBattlerTarget, GetBattlerAbility(gBattlerAttacker), targetAbility)) + { + gBattleCommunication[MULTISTRING_CHOOSER] = 0; + } + else if ((gBattleMons[gBattlerAttacker].status1 & STATUS1_TOXIC_POISON) && CanBePoisoned(gBattlerAttacker, gBattlerTarget, GetBattlerAbility(gBattlerAttacker), targetAbility)) + { + gBattleCommunication[MULTISTRING_CHOOSER] = 1; + } + else if ((gBattleMons[gBattlerAttacker].status1 & STATUS1_BURN) && CanBeBurned(gBattlerAttacker, gBattlerTarget, targetAbility)) + { + gBattleCommunication[MULTISTRING_CHOOSER] = 2; + } + else if ((gBattleMons[gBattlerAttacker].status1 & STATUS1_PARALYSIS) && CanBeParalyzed(gBattlerAttacker, gBattlerTarget, targetAbility)) + { + gBattleCommunication[MULTISTRING_CHOOSER] = 3; + } + else if ((gBattleMons[gBattlerAttacker].status1 & STATUS1_SLEEP) && CanBeSlept(gBattlerAttacker, gBattlerTarget, targetAbility, BLOCKED_BY_SLEEP_CLAUSE)) + { + gBattleCommunication[MULTISTRING_CHOOSER] = 4; + } + else if ((gBattleMons[gBattlerAttacker].status1 & STATUS1_FROSTBITE) && CanBeFrozen(gBattlerAttacker, gBattlerTarget, targetAbility)) + { + gBattleCommunication[MULTISTRING_CHOOSER] = 5; + } + else if (IsSleepClauseActiveForSide(GetBattlerSide(gBattlerTarget))) + { + gBattlescriptCurrInstr = cmd->sleepClauseFailInstr; + return; + } + else + { + gBattlescriptCurrInstr = cmd->failInstr; + return; + } + gBattleMons[gBattlerTarget].status1 = gBattleMons[gBattlerAttacker].status1 & STATUS1_ANY; + BtlController_EmitSetMonData( + gBattlerTarget, + B_COMM_TO_CONTROLLER, + REQUEST_STATUS_BATTLE, + 0, + sizeof(gBattleMons[gBattlerTarget].status1), + &gBattleMons[gBattlerTarget].status1); + MarkBattlerForControllerExec(gBattlerTarget); + TryActivateSleepClause(gBattlerTarget, gBattlerPartyIndexes[gBattlerTarget]); + gBattlescriptCurrInstr = cmd->nextInstr; +} + +void BS_CureStatus(void) +{ + NATIVE_ARGS(u8 battler); + u32 battler = GetBattlerForBattleScript(cmd->battler); + + if (gBattleMons[battler].status1 & STATUS1_SLEEP) + TryDeactivateSleepClause(GetBattlerSide(battler), gBattlerPartyIndexes[battler]); + + gBattleMons[battler].status1 = 0; + BtlController_EmitSetMonData(battler, B_COMM_TO_CONTROLLER, REQUEST_STATUS_BATTLE, 0, sizeof(gBattleMons[battler].status1), &gBattleMons[battler].status1); + MarkBattlerForControllerExec(battler); + gBattlescriptCurrInstr = cmd->nextInstr; +} + +void BS_PowerTrick(void) +{ + NATIVE_ARGS(); + u32 temp; + gStatuses3[gBattlerAttacker] ^= STATUS3_POWER_TRICK; + SWAP(gBattleMons[gBattlerAttacker].attack, gBattleMons[gBattlerAttacker].defense, temp); + gBattlescriptCurrInstr = cmd->nextInstr; +} + +void BS_TryAfterYou(void) +{ + NATIVE_ARGS(const u8 *failInstr); + if (ChangeOrderTargetAfterAttacker()) + { + gSpecialStatuses[gBattlerTarget].afterYou = 1; + gBattlescriptCurrInstr = cmd->nextInstr; + } + else + { + gBattlescriptCurrInstr = cmd->failInstr; + } +} + +void BS_TryBestow(void) +{ + NATIVE_ARGS(const u8 *failInstr); + if (gBattleMons[gBattlerAttacker].item == ITEM_NONE + || gBattleMons[gBattlerTarget].item != ITEM_NONE + || !CanBattlerGetOrLoseItem(gBattlerAttacker, gBattleMons[gBattlerAttacker].item) + || !CanBattlerGetOrLoseItem(gBattlerTarget, gBattleMons[gBattlerAttacker].item) + || gWishFutureKnock.knockedOffMons[GetBattlerSide(gBattlerTarget)] & (1u << gBattlerPartyIndexes[gBattlerTarget])) + { + gBattlescriptCurrInstr = cmd->failInstr; + } + else + { + BestowItem(gBattlerAttacker, gBattlerTarget); + gBattlescriptCurrInstr = cmd->nextInstr; + } +} + +void BS_HandleTrainerSlideMsg(void) +{ + NATIVE_ARGS(u8 battler, u8 case_); + u32 battler = GetBattlerForBattleScript(cmd->battler); + if (cmd->case_ == PRINT_SLIDE_MESSAGE) + { + BtlController_EmitPrintString(battler, B_COMM_TO_CONTROLLER, STRINGID_TRAINERSLIDE); + MarkBattlerForControllerExec(battler); + } + else if (cmd->case_ == RESTORE_BATTLER_SLIDE_CONTROL) + { + if (IsBattlerAlive(battler)) + { + SetBattlerShadowSpriteCallback(battler, gBattleMons[battler].species); + BattleLoadMonSpriteGfx(GetBattlerMon(battler), battler); + } + u32 partner = BATTLE_PARTNER(battler); + if (IsBattlerAlive(partner)) + { + SetBattlerShadowSpriteCallback(partner, gBattleMons[partner].species); + BattleLoadMonSpriteGfx(GetBattlerMon(partner), partner); + } + } + gBattlescriptCurrInstr = cmd->nextInstr; +} + +void BS_TryTrainerSlideMsgFirstOff(void) +{ + NATIVE_ARGS(u8 battler); + u32 battler = GetBattlerForBattleScript(cmd->battler); + u32 shouldDoTrainerSlide = 0; + if ((shouldDoTrainerSlide = ShouldDoTrainerSlide(battler, TRAINER_SLIDE_PLAYER_LANDS_FIRST_DOWN))) + { + gBattleScripting.battler = battler; + BattleScriptPush(cmd->nextInstr); + gBattlescriptCurrInstr = (shouldDoTrainerSlide == 1 ? BattleScript_TrainerASlideMsgRet : BattleScript_TrainerBSlideMsgRet); + } + else + { + gBattlescriptCurrInstr = cmd->nextInstr; + } +} + +void BS_TryTrainerSlideMsgLastOn(void) +{ + NATIVE_ARGS(u8 battler); + u32 shouldDoTrainerSlide = 0; + u32 battler = GetBattlerForBattleScript(cmd->battler); + if ((shouldDoTrainerSlide = ShouldDoTrainerSlide(battler, TRAINER_SLIDE_LAST_SWITCHIN))) + { + gBattleScripting.battler = battler; + BattleScriptPush(cmd->nextInstr); + gBattlescriptCurrInstr = (shouldDoTrainerSlide == 1 ? BattleScript_TrainerASlideMsgRet : BattleScript_TrainerBSlideMsgRet); + } + else + { + gBattlescriptCurrInstr = cmd->nextInstr; + } +} + +// Potential bug with failing message and missed result on wrong battler +void BS_SetAuroraVeil(void) +{ + NATIVE_ARGS(); + u32 side = GetBattlerSide(gBattlerAttacker); + if (gSideStatuses[side] & SIDE_STATUS_AURORA_VEIL + || !(HasWeatherEffect() && gBattleWeather & (B_WEATHER_HAIL | B_WEATHER_SNOW))) + { + gBattleStruct->moveResultFlags[gBattlerTarget] |= MOVE_RESULT_MISSED; + gBattleCommunication[MULTISTRING_CHOOSER] = 0; + } + else + { + gSideStatuses[side] |= SIDE_STATUS_AURORA_VEIL; + if (GetBattlerHoldEffect(gBattlerAttacker, TRUE) == HOLD_EFFECT_LIGHT_CLAY) + gSideTimers[GetBattlerSide(gBattlerAttacker)].auroraVeilTimer = gBattleTurnCounter + 8; + else + gSideTimers[GetBattlerSide(gBattlerAttacker)].auroraVeilTimer = gBattleTurnCounter + 5; + + if (IsDoubleBattle() && CountAliveMonsInBattle(BATTLE_ALIVE_SIDE, gBattlerAttacker) == 2) + gBattleCommunication[MULTISTRING_CHOOSER] = 5; + else + gBattleCommunication[MULTISTRING_CHOOSER] = 5; + } + gBattlescriptCurrInstr = cmd->nextInstr; +} + +void BS_TryThirdType(void) +{ + NATIVE_ARGS(const u8 *failInstr); + u32 type = GetMoveArgType(gCurrentMove); + if (IS_BATTLER_OF_TYPE(gBattlerTarget, type) || GetActiveGimmick(gBattlerTarget) == GIMMICK_TERA) + { + gBattlescriptCurrInstr = cmd->failInstr; + } + else + { + gBattleMons[gBattlerTarget].types[2] = type; + PREPARE_TYPE_BUFFER(gBattleTextBuff1, type); + gBattlescriptCurrInstr = cmd->nextInstr; + } +} + +void BS_DestroyAbilityPopup(void) +{ + NATIVE_ARGS(); + for (u32 battler = 0; battler < gBattlersCount; battler++) + DestroyAbilityPopUp(battler); + gBattlescriptCurrInstr = cmd->nextInstr; +} + +void BS_GetTotemBoost(void) +{ + NATIVE_ARGS(const u8 *jumpInstr); + u32 battler = gBattlerAttacker; + if (gQueuedStatBoosts[battler].stats == 0) + { + gBattlescriptCurrInstr = cmd->nextInstr; // stats done, exit + } + else + { + for (u32 i = 0; i < (NUM_BATTLE_STATS - 1); i++) + { + if (gQueuedStatBoosts[battler].stats & (1 << i)) + { + if (gQueuedStatBoosts[battler].statChanges[i] <= -1) + SET_STATCHANGER(i + 1, abs(gQueuedStatBoosts[battler].statChanges[i]), TRUE); + else + SET_STATCHANGER(i + 1, gQueuedStatBoosts[battler].statChanges[i], FALSE); + + gQueuedStatBoosts[battler].stats &= ~(1 << i); + gBattleScripting.battler = battler; + gBattlerTarget = battler; + if (gQueuedStatBoosts[battler].stats & 0x80) + { + gQueuedStatBoosts[battler].stats &= ~0x80; // set 'aura flared to life' flag + gBattlescriptCurrInstr = BattleScript_TotemFlaredToLife; + } + else + { + gBattlescriptCurrInstr = cmd->jumpInstr; // do boost + } + return; + } + } + gBattlescriptCurrInstr = cmd->nextInstr; // exit if loop failed (failsafe) + } +} + +void BS_ActivateItemEffects(void) +{ + NATIVE_ARGS(); + if (ItemBattleEffects(ITEMEFFECT_NORMAL, gBattlerTarget)) + return; + gBattlescriptCurrInstr = cmd->nextInstr; +} + +void BS_TryRoomService(void) +{ + NATIVE_ARGS(u8 battler, const u8 *failInstr); + u32 battler = GetBattlerForBattleScript(cmd->battler); + if (GetBattlerHoldEffect(battler, TRUE) == HOLD_EFFECT_ROOM_SERVICE && TryRoomService(battler)) + { + BattleScriptCall(BattleScript_ConsumableStatRaiseRet); + } + else + { + gBattlescriptCurrInstr = cmd->failInstr; + } +} + +void BS_TryTerrainSeed(void) +{ + NATIVE_ARGS(u8 battler, const u8 *failInstr); + u32 battler = GetBattlerForBattleScript(cmd->battler); + if (GetBattlerHoldEffect(battler, TRUE) == HOLD_EFFECT_SEEDS) + { + enum ItemEffect effect = ITEM_NO_EFFECT; + u16 item = gBattleMons[battler].item; + switch (GetBattlerHoldEffectParam(battler)) + { + case HOLD_EFFECT_PARAM_ELECTRIC_TERRAIN: + effect = TryHandleSeed(battler, STATUS_FIELD_ELECTRIC_TERRAIN, STAT_DEF, item, ITEMEFFECT_NONE); + break; + case HOLD_EFFECT_PARAM_GRASSY_TERRAIN: + effect = TryHandleSeed(battler, STATUS_FIELD_GRASSY_TERRAIN, STAT_DEF, item, ITEMEFFECT_NONE); + break; + case HOLD_EFFECT_PARAM_MISTY_TERRAIN: + effect = TryHandleSeed(battler, STATUS_FIELD_MISTY_TERRAIN, STAT_SPDEF, item, ITEMEFFECT_NONE); + break; + case HOLD_EFFECT_PARAM_PSYCHIC_TERRAIN: + effect = TryHandleSeed(battler, STATUS_FIELD_PSYCHIC_TERRAIN, STAT_SPDEF, item, ITEMEFFECT_NONE); + break; + } + + if (effect != ITEM_NO_EFFECT) + return; + } + gBattlescriptCurrInstr = cmd->failInstr; +} + +void BS_MakeInvisible(void) +{ + NATIVE_ARGS(u8 battler); + u32 battler = GetBattlerForBattleScript(cmd->battler); + + if (gBattleControllerExecFlags) + return; + + BtlController_EmitSpriteInvisibility(battler, B_COMM_TO_CONTROLLER, TRUE); + MarkBattlerForControllerExec(battler); + gBattlescriptCurrInstr = cmd->nextInstr; +} + +void BS_JumpIfTeamHealthy(void) +{ + NATIVE_ARGS(const u8 *jumpInstr); + u32 battler = gBattlerAttacker; + if ((IsDoubleBattle()) && IsBattlerAlive(BATTLE_PARTNER(battler))) + { + u8 partner = BATTLE_PARTNER(battler); + if ((gBattleMons[battler].hp == gBattleMons[battler].maxHP && !(gBattleMons[battler].status1 & STATUS1_ANY)) + && (gBattleMons[partner].hp == gBattleMons[partner].maxHP && !(gBattleMons[partner].status1 & STATUS1_ANY))) + gBattlescriptCurrInstr = cmd->jumpInstr; + else + gBattlescriptCurrInstr = cmd->nextInstr; + } + else // single battle + { + if (gBattleMons[battler].hp == gBattleMons[battler].maxHP && !(gBattleMons[battler].status1 & STATUS1_ANY)) + gBattlescriptCurrInstr = cmd->jumpInstr; + else + gBattlescriptCurrInstr = cmd->nextInstr; + } +} + +void BS_TryHealQuarterHealth(void) +{ + NATIVE_ARGS(u8 battler, const u8 *failInstr); + u32 battler = GetBattlerForBattleScript(cmd->battler); + gBattleStruct->moveDamage[battler] = GetNonDynamaxMaxHP(battler) / 4; + if (gBattleStruct->moveDamage[battler] == 0) + gBattleStruct->moveDamage[battler] = 1; + gBattleStruct->moveDamage[battler] *= -1; + + if (gBattleMons[battler].hp == gBattleMons[battler].maxHP) + gBattlescriptCurrInstr = cmd->failInstr; // fail + else + gBattlescriptCurrInstr = cmd->nextInstr; // can heal +} + +void BS_JumpIfUnder200(void) +{ + NATIVE_ARGS(const u8 *jumpInstr); + // If the Pokemon is less than 200 kg, or weighing less than 441 lbs, then Sky Drop will work. Otherwise, it will fail. + if (GetBattlerWeight(gBattlerTarget) < 2000) + gBattlescriptCurrInstr = cmd->jumpInstr; + else + gBattlescriptCurrInstr = cmd->nextInstr; +} + +void BS_SetSkyDrop(void) +{ + NATIVE_ARGS(); + gStatuses3[gBattlerTarget] |= (STATUS3_SKY_DROPPED | STATUS3_ON_AIR); + /* skyDropTargets holds the information of who is in a particular instance of Sky Drop. + This is needed in the case that multiple Pokemon use Sky Drop in the same turn or if + the target of a Sky Drop faints while in the air.*/ + gBattleStruct->skyDropTargets[gBattlerAttacker] = gBattlerTarget; + gBattleStruct->skyDropTargets[gBattlerTarget] = gBattlerAttacker; + + // End any multiturn effects caused by the target except VOLATILE_LOCK_CONFUSE + gBattleMons[gBattlerTarget].volatiles.multipleTurns = 0; + gBattleMons[gBattlerTarget].volatiles.uproarTurns = 0; + gBattleMons[gBattlerTarget].volatiles.bideTurns = 0; + gDisableStructs[gBattlerTarget].rolloutTimer = 0; + gDisableStructs[gBattlerTarget].furyCutterCounter = 0; + + // End any Follow Me/Rage Powder effects caused by the target + if (gSideTimers[GetBattlerSide(gBattlerTarget)].followmeTimer != 0 && gSideTimers[GetBattlerSide(gBattlerTarget)].followmeTarget == gBattlerTarget) + gSideTimers[GetBattlerSide(gBattlerTarget)].followmeTimer = 0; + + gBattlescriptCurrInstr = cmd->nextInstr; +} + +void BS_ClearSkyDrop(void) +{ + NATIVE_ARGS(const u8 *failInstr); + // Check to see if the initial target of this Sky Drop fainted before the 2nd turn of Sky Drop. + // If so, make the move fail. If not, clear all of the statuses and continue the move. + if (gBattleStruct->skyDropTargets[gBattlerAttacker] == SKY_DROP_NO_TARGET) + { + gBattlescriptCurrInstr = cmd->failInstr; + } + else + { + gBattleStruct->skyDropTargets[gBattlerAttacker] = SKY_DROP_NO_TARGET; + gBattleStruct->skyDropTargets[gBattlerTarget] = SKY_DROP_NO_TARGET; + gStatuses3[gBattlerTarget] &= ~(STATUS3_SKY_DROPPED | STATUS3_ON_AIR); + gBattlescriptCurrInstr = cmd->nextInstr; + } + + // Confuse target if they were in the middle of Petal Dance/Outrage/Thrash when targeted. + if (gBattleMons[gBattlerTarget].volatiles.lockConfusionTurns) + gBattleScripting.moveEffect = MOVE_EFFECT_CONFUSION; +} + +void BS_SkyDropYawn(void) +{ + NATIVE_ARGS(); + if (gBattleStruct->skyDropTargets[gEffectBattler] != SKY_DROP_NO_TARGET && !(gStatuses3[gEffectBattler] & STATUS3_SKY_DROPPED)) + { + // Set the target of Sky Drop as gEffectBattler + gEffectBattler = gBattleStruct->skyDropTargets[gEffectBattler]; + + // Clear skyDropTargets data + gBattleStruct->skyDropTargets[gBattleStruct->skyDropTargets[gEffectBattler]] = SKY_DROP_NO_TARGET; + gBattleStruct->skyDropTargets[gEffectBattler] = SKY_DROP_NO_TARGET; + + // If the target was in the middle of Outrage/Thrash/etc. when targeted by Sky Drop, confuse them on release and do proper animation + if (gBattleMons[gEffectBattler].volatiles.lockConfusionTurns && CanBeConfused(gEffectBattler)) + { + gBattleMons[gEffectBattler].volatiles.lockConfusionTurns = 0; + gBattlerAttacker = gEffectBattler; + gBattleMons[gBattlerTarget].volatiles.confusionTurns = ((Random()) % 4) + 2; + gBattlescriptCurrInstr = BattleScript_ThrashConfuses; + } + else + { + gBattlescriptCurrInstr = cmd->nextInstr; + } + } + else + { + gBattlescriptCurrInstr = cmd->nextInstr; + } +} + +void BS_JumpIfPranksterBlocked(void) +{ + NATIVE_ARGS(const u8 *jumpInstr); + if (BlocksPrankster(gCurrentMove, gBattlerAttacker, gBattlerTarget, TRUE)) + gBattlescriptCurrInstr = cmd->jumpInstr; + else + gBattlescriptCurrInstr = cmd->nextInstr; +} + +void BS_TryToClearPrimalWeather(void) +{ + NATIVE_ARGS(); + bool32 shouldNotClear = FALSE; + + for (u32 i = 0; i < gBattlersCount; i++) + { + u32 ability = GetBattlerAbility(i); + if (((ability == ABILITY_DESOLATE_LAND && gBattleWeather & B_WEATHER_SUN_PRIMAL) + || (ability == ABILITY_PRIMORDIAL_SEA && gBattleWeather & B_WEATHER_RAIN_PRIMAL) + || (ability == ABILITY_DELTA_STREAM && gBattleWeather & B_WEATHER_STRONG_WINDS)) + && IsBattlerAlive(i)) + shouldNotClear = TRUE; + } + if (gBattleWeather & B_WEATHER_SUN_PRIMAL && !shouldNotClear) + { + gBattleWeather &= ~B_WEATHER_SUN_PRIMAL; + PrepareStringBattle(STRINGID_EXTREMESUNLIGHTFADED, gBattlerAttacker); + gBattleCommunication[MSG_DISPLAY] = 1; + } + else if (gBattleWeather & B_WEATHER_RAIN_PRIMAL && !shouldNotClear) + { + gBattleWeather &= ~B_WEATHER_RAIN_PRIMAL; + PrepareStringBattle(STRINGID_HEAVYRAINLIFTED, gBattlerAttacker); + gBattleCommunication[MSG_DISPLAY] = 1; + } + else if (gBattleWeather & B_WEATHER_STRONG_WINDS && !shouldNotClear) + { + gBattleWeather &= ~B_WEATHER_STRONG_WINDS; + PrepareStringBattle(STRINGID_STRONGWINDSDISSIPATED, gBattlerAttacker); + gBattleCommunication[MSG_DISPLAY] = 1; + } + gBattlescriptCurrInstr = cmd->nextInstr; +} + +void BS_TryEndNeutralizingGas(void) +{ + NATIVE_ARGS(); + if (gSpecialStatuses[gBattlerTarget].neutralizingGasRemoved) + { + gSpecialStatuses[gBattlerTarget].neutralizingGasRemoved = FALSE; + BattleScriptPush(cmd->nextInstr); + gBattlescriptCurrInstr = BattleScript_NeutralizingGasExits; + } + else + { + gBattlescriptCurrInstr = cmd->nextInstr; + } +} + +void BS_GetRototillerTargets(void) +{ + NATIVE_ARGS(const u8 *failInstr); + u32 count = 0; + for (u32 battler = 0; battler < gBattlersCount; battler++) + { + gSpecialStatuses[battler].rototillerAffected = FALSE; + if (IsRototillerAffected(battler)) + { + gSpecialStatuses[battler].rototillerAffected = TRUE; + count++; + } + } + + if (count == 0) + gBattlescriptCurrInstr = cmd->failInstr; // Rototiller fails + else + gBattlescriptCurrInstr = cmd->nextInstr; +} + +void BS_JumpIfNotRototillerAffected(void) +{ + NATIVE_ARGS(const u8 *jumpInstr); + if (gSpecialStatuses[gBattlerTarget].rototillerAffected) + { + gSpecialStatuses[gBattlerTarget].rototillerAffected = FALSE; + gBattlescriptCurrInstr = cmd->nextInstr; + } + else + { + gBattlescriptCurrInstr = cmd->jumpInstr; // Unaffected by rototiller - print STRINGID_NOEFFECTONTARGET + } +} + +void BS_ConsumeBerry(void) +{ + NATIVE_ARGS(u8 battler, bool8 fromBattler); + u32 battler = GetBattlerForBattleScript(cmd->battler); + if (gBattleScripting.overrideBerryRequirements == 2) + { + gBattlescriptCurrInstr = cmd->nextInstr; + return; + } + + if (cmd->fromBattler) + gLastUsedItem = gBattleMons[battler].item; + + gBattleStruct->partyState[GetBattlerSide(battler)][gBattlerPartyIndexes[battler]].ateBerry = TRUE; + gBattleScripting.battler = gEffectBattler = gBattlerTarget = battler; // Cover all berry effect battler cases. e.g. ChangeStatBuffs uses target ID + if (ItemBattleEffects(ITEMEFFECT_USE_LAST_ITEM, battler)) + return; + gBattlescriptCurrInstr = cmd->nextInstr; +} + +void BS_JumpIfWeatherAffected(void) +{ + NATIVE_ARGS(u16 flags, const u8 *jumpInstr); + u32 weather = cmd->flags; + if (IsBattlerWeatherAffected(gBattlerAttacker, weather)) + gBattlescriptCurrInstr = cmd->jumpInstr; + else + gBattlescriptCurrInstr = cmd->nextInstr; +} + +void BS_JumpIfSpecies(void) +{ + NATIVE_ARGS(u16 species, const u8 *jumpInstr); + if (gBattleMons[gBattlerAttacker].species == cmd->species) + gBattlescriptCurrInstr = cmd->jumpInstr; + else + gBattlescriptCurrInstr = cmd->nextInstr; +} + +void BS_JumpIfLeafGuardProtected(void) +{ + NATIVE_ARGS(u8 battler, const u8 *jumpInstr); + u32 battler = GetBattlerForBattleScript(cmd->battler); + if (IsLeafGuardProtected(battler, GetBattlerAbility(battler))) + { + gBattlerAbility = battler; + gBattlescriptCurrInstr = cmd->jumpInstr; + } + else + { + gBattlescriptCurrInstr = cmd->nextInstr; + } +} + +void BS_SetAttackerToStickyWebUser(void) +{ + NATIVE_ARGS(); + // For Mirror Armor: "If the Pokémon with this Ability is affected by Sticky Web, the effect is reflected back to the Pokémon which set it up. + // If Pokémon which set up Sticky Web is not on the field, no Pokémon have their Speed lowered." + gBattlerAttacker = gBattlerTarget; // Initialize 'fail' condition + SET_STATCHANGER(STAT_SPEED, 1, TRUE); + if (gSideTimers[GetBattlerSide(gBattlerTarget)].stickyWebBattlerId != 0xFF) + gBattlerAttacker = gSideTimers[GetBattlerSide(gBattlerTarget)].stickyWebBattlerId; + gBattlescriptCurrInstr = cmd->nextInstr; +} + +void BS_CutOneThirdHpAndRaiseStats(void) +{ + NATIVE_ARGS(const u8 *failInstr); + + bool8 atLeastOneStatBoosted = FALSE; + u16 hpFraction = max(1, GetNonDynamaxMaxHP(gBattlerAttacker) / 3); + + for (u32 stat = 1; stat < NUM_STATS; stat++) + { + if (CompareStat(gBattlerAttacker, stat, MAX_STAT_STAGE, CMP_LESS_THAN)) + { + atLeastOneStatBoosted = TRUE; + break; + } + } + if (atLeastOneStatBoosted && gBattleMons[gBattlerAttacker].hp > hpFraction) + { + gBattleStruct->moveDamage[gBattlerAttacker] = hpFraction; + gBattlescriptCurrInstr = cmd->nextInstr; + } + else + { + gBattlescriptCurrInstr = cmd->failInstr; + } +} + +void BS_CheckPoltergeist(void) +{ + NATIVE_ARGS(const u8 *failInstr); + if (gBattleMons[gBattlerTarget].item == ITEM_NONE + || gFieldStatuses & STATUS_FIELD_MAGIC_ROOM + || GetBattlerAbility(gBattlerTarget) == ABILITY_KLUTZ) + { + gBattlescriptCurrInstr = cmd->failInstr; + } + else + { + PREPARE_ITEM_BUFFER(gBattleTextBuff1, gBattleMons[gBattlerTarget].item); + gLastUsedItem = gBattleMons[gBattlerTarget].item; + gBattlescriptCurrInstr = cmd->nextInstr; + } +} + +void BS_TryNoRetreat(void) +{ + NATIVE_ARGS(const u8 *failInstr); + if (gDisableStructs[gBattlerTarget].noRetreat) + { + gBattlescriptCurrInstr = cmd->failInstr; + } + else + { + if (!gBattleMons[gBattlerTarget].volatiles.escapePrevention) + gDisableStructs[gBattlerTarget].noRetreat = TRUE; + gBattlescriptCurrInstr = cmd->nextInstr; + } +} + +void BS_CureCertainStatuses(void) +{ + NATIVE_ARGS(); + // Check infatuation + if (gBattleMons[gBattlerTarget].volatiles.infatuation) + { + gBattleMons[gBattlerTarget].volatiles.infatuation = 0; + gBattleCommunication[MULTISTRING_CHOOSER] = B_MSG_MENTALHERBCURE_INFATUATION; // STRINGID_TARGETGOTOVERINFATUATION + StringCopy(gBattleTextBuff1, gStatusConditionString_LoveJpn); + } + // Check taunt + if (gDisableStructs[gBattlerTarget].tauntTimer != 0) + { + gDisableStructs[gBattlerTarget].tauntTimer = 0; + gBattleCommunication[MULTISTRING_CHOOSER] = B_MSG_MENTALHERBCURE_TAUNT; + PREPARE_MOVE_BUFFER(gBattleTextBuff1, MOVE_TAUNT); + } + // Check encore + if (gDisableStructs[gBattlerTarget].encoreTimer != 0) + { + gDisableStructs[gBattlerTarget].encoredMove = 0; + gDisableStructs[gBattlerTarget].encoreTimer = 0; + gBattleCommunication[MULTISTRING_CHOOSER] = B_MSG_MENTALHERBCURE_ENCORE; // STRINGID_PKMNENCOREENDED + } + // Check torment + if (gBattleMons[gBattlerTarget].volatiles.torment == TRUE) + { + gBattleMons[gBattlerTarget].volatiles.torment = FALSE; + gBattleCommunication[MULTISTRING_CHOOSER] = B_MSG_MENTALHERBCURE_TORMENT; + } + // Check heal block + if (gStatuses3[gBattlerTarget] & STATUS3_HEAL_BLOCK) + { + gStatuses3[gBattlerTarget] &= ~(STATUS3_HEAL_BLOCK); + gBattleCommunication[MULTISTRING_CHOOSER] = B_MSG_MENTALHERBCURE_HEALBLOCK; + } + // Check disable + if (gDisableStructs[gBattlerTarget].disableTimer != 0) + { + gDisableStructs[gBattlerTarget].disableTimer = 0; + gDisableStructs[gBattlerTarget].disabledMove = 0; + gBattleCommunication[MULTISTRING_CHOOSER] = B_MSG_MENTALHERBCURE_DISABLE; + } + gBattlescriptCurrInstr = cmd->nextInstr; +} + +void BS_TryResetNegativeStatStages(void) +{ + NATIVE_ARGS(); + for (u32 stat = 0; stat < NUM_BATTLE_STATS; stat++) + if (gBattleMons[gBattlerTarget].statStages[stat] < DEFAULT_STAT_STAGE) + gBattleMons[gBattlerTarget].statStages[stat] = DEFAULT_STAT_STAGE; + gBattlescriptCurrInstr = cmd->nextInstr; +} + +void BS_JumpIfLastUsedItemBerry(void) +{ + NATIVE_ARGS(const u8 *jumpInstr); + if (GetItemPocket(gLastUsedItem) == POCKET_BERRIES) + gBattlescriptCurrInstr = cmd->jumpInstr; + else + gBattlescriptCurrInstr = cmd->nextInstr; +} + +void BS_SaveBattlerItem(void) +{ + NATIVE_ARGS(); + gBattleHistory->heldItems[gBattlerTarget] = gBattleMons[gBattlerTarget].item; + gBattlescriptCurrInstr = cmd->nextInstr; +} + +void BS_RestoreBattlerItem(void) +{ + NATIVE_ARGS(); + gBattleMons[gBattlerTarget].item = gBattleHistory->heldItems[gBattlerTarget]; + gBattlescriptCurrInstr = cmd->nextInstr; +} + +void BS_BattlerItemToLastUsedItem(void) +{ + NATIVE_ARGS(); + gBattleMons[gBattlerTarget].item = gLastUsedItem; + gBattlescriptCurrInstr = cmd->nextInstr; +}