diff --git a/data/battle_anim_scripts.s b/data/battle_anim_scripts.s index 4cf77642d..98e445087 100644 --- a/data/battle_anim_scripts.s +++ b/data/battle_anim_scripts.s @@ -1023,6 +1023,7 @@ gBattleAnims_Special:: .4byte Special_BallThrowWithTrainer @ B_ANIM_BALL_THROW_WITH_TRAINER .4byte Special_SubstituteToMon @ B_ANIM_SUBSTITUTE_TO_MON .4byte Special_MonToSubstitute @ B_ANIM_MON_TO_SUBSTITUTE + .4byte Special_CriticalCaptureBallThrow @ B_ANIM_CRITICAL_CAPTURE_THROW Move_NONE: Move_MIRROR_MOVE: @@ -12271,6 +12272,15 @@ Special_MonToSubstitute: createvisualtask AnimTask_SwapMonSpriteToFromSubstitute, 2, FALSE end +Special_CriticalCaptureBallThrow: + createvisualtask AnimTask_LoadBallGfx, 2 + delay 0 + playsewithpan SE_FALL, 0 + createvisualtask AnimTask_ThrowBall, 2 + createvisualtask AnimTask_IsBallBlockedByTrainerOrDodged, 2 + jumpreteq -1, BallThrowTrainerBlock + goto BallThrowEnd + General_RestoreBg: restorebg waitbgfadein diff --git a/data/battle_scripts_2.s b/data/battle_scripts_2.s index 6b81c09f9..457ce9a4d 100644 --- a/data/battle_scripts_2.s +++ b/data/battle_scripts_2.s @@ -18,59 +18,101 @@ .section script_data, "aw", %progbits .align 2 -gBattlescriptsForBallThrow:: - .4byte BattleScript_ThrowBall - .4byte BattleScript_ThrowBall - .4byte BattleScript_ThrowBall - .4byte BattleScript_ThrowBall - .4byte BattleScript_ThrowBall - .4byte BattleScript_ThrowBall - .4byte BattleScript_ThrowBall - .4byte BattleScript_ThrowBall - .4byte BattleScript_ThrowBall - .4byte BattleScript_ThrowBall - .4byte BattleScript_ThrowBall - .4byte BattleScript_ThrowBall - .4byte BattleScript_ThrowBall +@ pokefirered leftovers +BattleScript_OldMan_Pokedude_CaughtMessage:: + printstring STRINGID_GOTCHAPKMNCAUGHT2 + setbyte gBattleOutcome, B_OUTCOME_CAUGHT + endlinkbattle + finishturn +BattleScript_GhostBallDodge:: + waitmessage B_WAIT_TIME_LONG + printstring STRINGID_ITDODGEDBALL + waitmessage B_WAIT_TIME_LONG + finishaction + +BattleScript_UsePokeFlute:: + checkpokeflute BS_ATTACKER + jumpifbyte CMP_EQUAL, cMULTISTRING_CHOOSER, 1, BattleScript_PokeFluteWakeUp + printstring STRINGID_POKEFLUTECATCHY + waitmessage B_WAIT_TIME_LONG + goto BattleScript_PokeFluteEnd + +BattleScript_PokeFluteWakeUp:: + printstring STRINGID_POKEFLUTE + waitmessage B_WAIT_TIME_LONG + fanfare MUS_POKE_FLUTE + waitfanfare BS_ATTACKER + printstring STRINGID_MONHEARINGFLUTEAWOKE + waitmessage B_WAIT_TIME_LONG + updatestatusicon BS_PLAYER2 + waitstate +BattleScript_PokeFluteEnd:: + finishaction + +@ pokemerald + .align 2 gBattlescriptsForUsingItem:: - .4byte BattleScript_PlayerUseItem - .4byte BattleScript_ItemRestoreHP @ EFFECT_ITEM_RESTORE_HP (e.g. Potion) - .4byte BattleScript_ItemCureStatus @ EFFECT_ITEM_CURE_STATUS (e.g. Antidote, Pecha Berry) - .4byte BattleScript_ItemHealAndCureStatus @ EFFECT_ITEM_HEAL_AND_CURE_STATUS (e.g. Full Restore) - .4byte BattleScript_ItemIncreaseStat @ EFFECT_ITEM_INCREASE_STAT (e.g. X Attack) - .4byte BattleScript_ItemSetMist @ EFFECT_ITEM_SET_MIST (e.g. Guard Spec) - .4byte BattleScript_ItemSetFocusEnergy @ EFFECT_ITEM_SET_FOCUS_ENERGY (e.g. Dire Hit) - .4byte BattleScript_RunByUsingItem @ EFFECT_ITEM_ESCAPE (e.g. Poké Doll) - .4byte BattleScript_BallThrow @ EFFECT_ITEM_THROW_BALL (e.g. Pokéball) - .4byte BattleScript_ItemRestoreHP @ EFFECT_ITEM_REVIVE (e.g. Revive) - .4byte BattleScript_ItemRestorePP @ EFFECT_ITEM_RESTORE_PP (e.g. Ether) - .4byte BattleScript_ItemIncreaseAllStats @ EFFECT_ITEM_INCREASE_ALL_STATS (e.g. Max Mushrooms) + .4byte BattleScript_ItemRestoreHP @ EFFECT_ITEM_RESTORE_HP + .4byte BattleScript_ItemCureStatus @ EFFECT_ITEM_CURE_STATUS + .4byte BattleScript_ItemHealAndCureStatus @ EFFECT_ITEM_HEAL_AND_CURE_STATUS + .4byte BattleScript_ItemIncreaseStat @ EFFECT_ITEM_INCREASE_STAT + .4byte BattleScript_ItemSetMist @ EFFECT_ITEM_SET_MIST + .4byte BattleScript_ItemSetFocusEnergy @ EFFECT_ITEM_SET_FOCUS_ENERGY + .4byte BattleScript_RunByUsingItem @ EFFECT_ITEM_ESCAPE + .4byte BattleScript_BallThrow @ EFFECT_ITEM_THROW_BALL + .4byte BattleScript_ItemRestoreHP @ EFFECT_ITEM_REVIVE + .4byte BattleScript_ItemRestorePP @ EFFECT_ITEM_RESTORE_PP + .4byte BattleScript_ItemIncreaseAllStats @ EFFECT_ITEM_INCREASE_ALL_STATS -gBattleScriptsForAIUsingItems:: - .4byte BattleScript_AIUseFullRestoreOrHpHeal - .4byte BattleScript_AIUseFullRestoreOrHpHeal - .4byte BattleScript_AIUseStatRestore - .4byte BattleScript_AIUseXstat - .4byte BattleScript_AIUseGuardSpec + .align 2 +gBattlescriptsForSafariActions:: + .4byte BattleScript_WatchesCarefully + .4byte BattleScript_ThrowRock + .4byte BattleScript_ThrowBait + .4byte BattleScript_LeftoverWallyPrepToThrow -gBattlescriptsForRunningByItem:: - .4byte BattleScript_UseFluffyTail - .4byte BattleScript_UsePokeFlute +BattleScript_WatchesCarefully:: + printfromtable gSafariReactionStringIds + waitmessage B_WAIT_TIME_LONG + playanimation BS_OPPONENT1, B_ANIM_SAFARI_REACTION + end2 + +BattleScript_ThrowRock:: + printstring STRINGID_THREWROCK + waitmessage B_WAIT_TIME_LONG + playanimation BS_ATTACKER, B_ANIM_ROCK_THROW + end2 + +BattleScript_ThrowBait:: + printstring STRINGID_THREWBAIT + waitmessage B_WAIT_TIME_LONG + playanimation BS_ATTACKER, B_ANIM_BAIT_THROW + end2 + +BattleScript_LeftoverWallyPrepToThrow:: + printstring STRINGID_RETURNMON + waitmessage B_WAIT_TIME_LONG + returnatktoball + waitstate + trainerslidein BS_TARGET + waitstate + printstring STRINGID_YOUTHROWABALLNOWRIGHT + waitmessage B_WAIT_TIME_LONG + end2 BattleScript_ItemEnd: - end + end BattleScript_UseItemMessage: - printstring STRINGID_EMPTYSTRING3 - pause B_WAIT_TIME_MED - playse SE_USE_ITEM - getbattlerside BS_ATTACKER - copybyte cMULTISTRING_CHOOSER, gBattleCommunication - printfromtable gTrainerUsedItemStringIds - waitmessage B_WAIT_TIME_LONG - moveendcase 15 - return + printstring STRINGID_EMPTYSTRING3 + pause B_WAIT_TIME_MED + playse SE_USE_ITEM + getbattlerside BS_ATTACKER + copybyte cMULTISTRING_CHOOSER, gBattleCommunication + printfromtable gTrainerUsedItemStringIds + waitmessage B_WAIT_TIME_LONG + return BattleScript_ItemRestoreHPRet: bichalfword gMoveResultFlags, MOVE_RESULT_NO_EFFECT @@ -119,69 +161,47 @@ BattleScript_ItemHealAndCureStatus:: BattleScript_ItemIncreaseStat:: call BattleScript_UseItemMessage - itemincreasestat + itemincreasestat statbuffchange MOVE_EFFECT_AFFECTS_USER | STAT_CHANGE_NOT_PROTECT_AFFECTED | STAT_CHANGE_ALLOW_PTR, BattleScript_ItemEnd setgraphicalstatchangevalues playanimation BS_ATTACKER, B_ANIM_STATS_CHANGE, sB_ANIM_ARG1 printfromtable gStatUpStringIds waitmessage B_WAIT_TIME_LONG - moveendcase 15 - end + end BattleScript_ItemSetMist:: - call BattleScript_UseItemMessage - setmist - playmoveanimation BS_ATTACKER, MOVE_MIST - waitanimation - printfromtable gMistUsedStringIds - waitmessage B_WAIT_TIME_LONG - moveendcase 15 - end + call BattleScript_UseItemMessage + setmist + playmoveanimation BS_ATTACKER, MOVE_MIST + waitanimation + printfromtable gMistUsedStringIds + waitmessage B_WAIT_TIME_LONG + end BattleScript_ItemSetFocusEnergy:: - call BattleScript_UseItemMessage - jumpifstatus2 BS_ATTACKER, STATUS2_FOCUS_ENERGY, BattleScript_ButItFailed - setfocusenergy - playmoveanimation BS_ATTACKER, MOVE_FOCUS_ENERGY - waitanimation + call BattleScript_UseItemMessage + jumpifstatus2 BS_ATTACKER, STATUS2_FOCUS_ENERGY_ANY, BattleScript_ButItFailed + setfocusenergy + playmoveanimation BS_ATTACKER, MOVE_FOCUS_ENERGY + waitanimation copybyte sBATTLER, gBattlerAttacker - printstring STRINGID_PKMNUSEDXTOGETPUMPED - waitmessage B_WAIT_TIME_LONG - moveendcase 15 - end - -BattleScript_RunByUsingItem:: - playse SE_FLEE - setbyte gBattleOutcome, B_OUTCOME_RAN - finishturn - -BattleScript_BallThrow:: - jumpifbattletype BATTLE_TYPE_OLD_MAN_TUTORIAL, BattleScript_OldManThrowBall - jumpifbattletype BATTLE_TYPE_POKEDUDE, BattleScript_PokedudeThrowBall - printstring STRINGID_PLAYERUSEDITEM - handleballthrow + printstring STRINGID_PKMNUSEDXTOGETPUMPED + waitmessage B_WAIT_TIME_LONG + end BattleScript_ItemRestorePP:: - call BattleScript_UseItemMessage - itemrestorepp - printstring STRINGID_ITEMRESTOREDSPECIESPP - waitmessage B_WAIT_TIME_LONG - moveendcase 15 - end + call BattleScript_UseItemMessage + itemrestorepp + printstring STRINGID_ITEMRESTOREDSPECIESPP + waitmessage B_WAIT_TIME_LONG + end BattleScript_ItemIncreaseAllStats:: call BattleScript_UseItemMessage call BattleScript_AllStatsUp - moveendcase 15 - end + end -gBattlescriptsForSafariActions:: - .4byte BattleScript_WatchesCarefully - .4byte BattleScript_ThrowRock - .4byte BattleScript_ThrowBait - .4byte BattleScript_LeftoverWallyPrepToThrow - -BattleScript_ThrowBall:: +BattleScript_BallThrow:: jumpifbattletype BATTLE_TYPE_OLD_MAN_TUTORIAL, BattleScript_OldManThrowBall jumpifbattletype BATTLE_TYPE_POKEDUDE, BattleScript_PokedudeThrowBall printstring STRINGID_PLAYERUSEDITEM @@ -230,21 +250,20 @@ BattleScript_SuccessBallThrowEnd:: setbyte gBattleOutcome, B_OUTCOME_CAUGHT finishturn -BattleScript_OldMan_Pokedude_CaughtMessage:: - printstring STRINGID_GOTCHAPKMNCAUGHT2 +BattleScript_WallyBallThrow:: + printstring STRINGID_GOTCHAPKMNCAUGHTWALLY setbyte gBattleOutcome, B_OUTCOME_CAUGHT - endlinkbattle finishturn BattleScript_ShakeBallThrow:: printfromtable gBallEscapeStringIds waitmessage B_WAIT_TIME_LONG - jumpifnotbattletype BATTLE_TYPE_SAFARI, BattleScript_CatchFailEnd - jumpifbyte CMP_NOT_EQUAL, gNumSafariBalls, 0, BattleScript_CatchFailEnd + jumpifword CMP_NO_COMMON_BITS, gBattleTypeFlags, BATTLE_TYPE_SAFARI, BattleScript_ShakeBallThrowEnd + jumpifbyte CMP_NOT_EQUAL, gNumSafariBalls, 0, BattleScript_ShakeBallThrowEnd printstring STRINGID_OUTOFSAFARIBALLS waitmessage B_WAIT_TIME_LONG setbyte gBattleOutcome, B_OUTCOME_NO_SAFARI_BALLS -BattleScript_CatchFailEnd:: +BattleScript_ShakeBallThrowEnd:: finishaction BattleScript_TrainerBallBlock:: @@ -255,118 +274,35 @@ BattleScript_TrainerBallBlock:: waitmessage B_WAIT_TIME_LONG finishaction -BattleScript_GhostBallDodge:: - waitmessage B_WAIT_TIME_LONG - printstring STRINGID_ITDODGEDBALL - waitmessage B_WAIT_TIME_LONG - finishaction - -BattleScript_PlayerUseItem:: - moveendcase 15 - end - -BattleScript_AIUseFullRestoreOrHpHeal:: - printstring STRINGID_EMPTYSTRING3 - pause B_WAIT_TIME_MED - playse SE_USE_ITEM - printstring STRINGID_TRAINER1USEDITEM - waitmessage B_WAIT_TIME_LONG - useitemonopponent - orword gHitMarker, HITMARKER_IGNORE_SUBSTITUTE - healthbarupdate BS_ATTACKER - datahpupdate BS_ATTACKER - printstring STRINGID_PKMNSITEMRESTOREDHEALTH - waitmessage B_WAIT_TIME_LONG - updatestatusicon BS_ATTACKER - moveendcase 15 - finishaction - -BattleScript_AIUseStatRestore:: - printstring STRINGID_EMPTYSTRING3 - pause B_WAIT_TIME_MED - playse SE_USE_ITEM - printstring STRINGID_TRAINER1USEDITEM - waitmessage B_WAIT_TIME_LONG - useitemonopponent - printfromtable gTrainerItemCuredStatusStringIds - waitmessage B_WAIT_TIME_LONG - updatestatusicon BS_ATTACKER - moveendcase 15 - finishaction - -BattleScript_AIUseXstat:: - printstring STRINGID_EMPTYSTRING3 - pause B_WAIT_TIME_MED - playse SE_USE_ITEM - printstring STRINGID_TRAINER1USEDITEM - waitmessage B_WAIT_TIME_LONG - useitemonopponent - printfromtable gStatUpStringIds - waitmessage B_WAIT_TIME_LONG - moveendcase 15 - finishaction - -BattleScript_AIUseGuardSpec:: - printstring STRINGID_EMPTYSTRING3 - pause B_WAIT_TIME_MED - playse SE_USE_ITEM - printstring STRINGID_TRAINER1USEDITEM - waitmessage B_WAIT_TIME_LONG - useitemonopponent - printfromtable gMistUsedStringIds - waitmessage B_WAIT_TIME_LONG - moveendcase 15 - finishaction - -BattleScript_UseFluffyTail:: +BattleScript_RunByUsingItem:: playse SE_FLEE setbyte gBattleOutcome, B_OUTCOME_RAN finishturn -BattleScript_UsePokeFlute:: - checkpokeflute BS_ATTACKER - jumpifbyte CMP_EQUAL, cMULTISTRING_CHOOSER, 1, BattleScript_PokeFluteWakeUp - printstring STRINGID_POKEFLUTECATCHY - waitmessage B_WAIT_TIME_LONG - goto BattleScript_PokeFluteEnd - -BattleScript_PokeFluteWakeUp:: - printstring STRINGID_POKEFLUTE - waitmessage B_WAIT_TIME_LONG - fanfare MUS_POKE_FLUTE - waitfanfare BS_ATTACKER - printstring STRINGID_MONHEARINGFLUTEAWOKE - waitmessage B_WAIT_TIME_LONG - updatestatusicon BS_PLAYER2 +BattleScript_TrainerASlideMsgRet:: + handletrainerslidemsg BS_SCRIPTING, 0 + trainerslidein B_POSITION_OPPONENT_LEFT + handletrainerslidemsg BS_SCRIPTING, 1 waitstate -BattleScript_PokeFluteEnd:: - finishaction - -BattleScript_WatchesCarefully:: - printfromtable gSafariReactionStringIds - waitmessage B_WAIT_TIME_LONG - playanimation BS_OPPONENT1, B_ANIM_SAFARI_REACTION - end2 - -BattleScript_ThrowRock:: - printstring STRINGID_THREWROCK - waitmessage B_WAIT_TIME_LONG - playanimation BS_ATTACKER, B_ANIM_ROCK_THROW - end2 - -BattleScript_ThrowBait:: - printstring STRINGID_THREWBAIT - waitmessage B_WAIT_TIME_LONG - playanimation BS_ATTACKER, B_ANIM_BAIT_THROW - end2 - -BattleScript_LeftoverWallyPrepToThrow:: - printstring STRINGID_RETURNMON - waitmessage B_WAIT_TIME_LONG - returnatktoball + trainerslideout B_POSITION_OPPONENT_LEFT waitstate - trainerslidein BS_TARGET - waitstate - printstring STRINGID_YOUTHROWABALLNOWRIGHT - waitmessage B_WAIT_TIME_LONG + handletrainerslidemsg BS_SCRIPTING, 2 + return + +BattleScript_TrainerASlideMsgEnd2:: + call BattleScript_TrainerASlideMsgRet + end2 + +BattleScript_TrainerBSlideMsgRet:: + handletrainerslidemsg BS_SCRIPTING, 0 + trainerslidein B_POSITION_OPPONENT_RIGHT + handletrainerslidemsg BS_SCRIPTING, 1 + waitstate + trainerslideout B_POSITION_OPPONENT_RIGHT + waitstate + handletrainerslidemsg BS_SCRIPTING, 2 + return + +BattleScript_TrainerBSlideMsgEnd2:: + call BattleScript_TrainerBSlideMsgRet end2 diff --git a/include/battle.h b/include/battle.h index 776e760b6..b8e43a1db 100644 --- a/include/battle.h +++ b/include/battle.h @@ -922,6 +922,7 @@ extern u16 gBattlerPartyIndexes[MAX_BATTLERS_COUNT]; extern s32 gBattleMoveDamage; extern u16 gIntroSlideFlags; extern u32 gTransformedPersonalities[MAX_BATTLERS_COUNT]; +extern bool8 gTransformedShininess[MAX_BATTLERS_COUNT]; extern u8 gBattlerPositions[MAX_BATTLERS_COUNT]; extern u8 gHealthboxSpriteIds[MAX_BATTLERS_COUNT]; extern u8 gBattleOutcome; diff --git a/include/battle_controllers.h b/include/battle_controllers.h index 89afd6346..59729206d 100644 --- a/include/battle_controllers.h +++ b/include/battle_controllers.h @@ -261,6 +261,7 @@ void BtlController_EmitEndLinkBattle(u32 battler, u32 bufferId, u8 battleOutcome void BtlController_Empty(u32 battler); // Empty command, does nothing, only completes the execution. void StartSendOutAnim(u32 battler, bool32 dontClearSubstituteBit); +void Controller_WaitForString(u32 battler); // handlers void BtlController_HandleGetMonData(u32 battler); @@ -272,6 +273,13 @@ void BtlController_HandleReturnMonToBall(u32 battler); void BtlController_HandleDrawTrainerPic(u32 battlerId, u32 trainerPicId, bool32 isFrontPic, s16 xPos, s16 yPos, s32 subpriority); void BtlController_HandleTrainerSlide(u32 battler, u32 trainerPicId); void BtlController_HandleTrainerSlideBack(u32 battlerId, s16 data0, bool32 startAnim); +void BtlController_HandleFaintAnimation(u32 battler); +void BtlController_HandleSuccessBallThrowAnim(u32 battler, u32 target, u32 animId, bool32 allowCriticalCapture); +void BtlController_HandleBallThrowAnim(u32 battler, u32 target, u32 animId, bool32 allowCriticalCapture); +void BtlController_HandleMoveAnimation(u32 battler); +void BtlController_HandlePrintString(u32 battler); +void BtlController_HandleHealthBarUpdate(u32 battler, bool32 updateHpText); +void BtlController_HandleStatusIconUpdate(u32 battler); // player controller void BattleControllerDummy(u32 battler); diff --git a/include/battle_interface.h b/include/battle_interface.h index d4ab7a593..7de67517d 100644 --- a/include/battle_interface.h +++ b/include/battle_interface.h @@ -83,6 +83,7 @@ enum HEALTHBOX_SAFARI_BALLS_TEXT }; +u32 WhichBattleCoords(u32 battlerId); void Task_HidePartyStatusSummary(u8 taskId); u8 CreateBattlerHealthboxSprites(u8 battlerId); u8 CreateSafariPlayerHealthboxSprites(void); diff --git a/include/battle_scripts.h b/include/battle_scripts.h index 836d9f7be..24c91de38 100644 --- a/include/battle_scripts.h +++ b/include/battle_scripts.h @@ -199,9 +199,6 @@ extern const u8 BattleScript_WallyBallThrow[]; extern const u8 BattleScript_ShakeBallThrow[]; extern const u8 BattleScript_TrainerBallBlock[]; extern const u8 BattleScript_RunByUsingItem[]; -extern const u8 BattleScript_ActionWatchesCarefully[]; -extern const u8 BattleScript_ActionGetNear[]; -extern const u8 BattleScript_ActionThrowPokeblock[]; extern const u8 BattleScript_GhostGetOutGetOut[]; extern const u8 BattleScript_TooScaredToMove[]; extern const u8 BattleScript_IntimidateActivates[]; @@ -213,10 +210,7 @@ extern const u8 BattleScript_GhostBallDodge[]; extern const u8 BattleScript_OldMan_Pokedude_CaughtMessage[]; extern const u8 BattleScript_SilphScopeUnveiled[]; -extern const u8 *const gBattlescriptsForBallThrow[]; -extern const u8 *const gBattlescriptsForRunningByItem[]; extern const u8 *const gBattlescriptsForUsingItem[]; -extern const u8 *const gBattleScriptsForAIUsingItems[]; extern const u8 *const gBattlescriptsForSafariActions[]; extern const u8 BattleScript_ItemRestoreHP_Party[]; @@ -702,9 +696,6 @@ extern const u8 BattleScript_WallyBallThrow[]; extern const u8 BattleScript_ShakeBallThrow[]; extern const u8 BattleScript_TrainerBallBlock[]; extern const u8 BattleScript_RunByUsingItem[]; -extern const u8 BattleScript_ActionWatchesCarefully[]; -extern const u8 BattleScript_ActionGetNear[]; -extern const u8 BattleScript_ActionThrowPokeblock[]; extern const u8 BattleScript_EmbargoEndTurn[]; extern const u8 BattleScript_TelekinesisEndTurn[]; extern const u8 BattleScript_BufferEndTurn[]; diff --git a/include/battle_util.h b/include/battle_util.h index 7cb4dc1be..9fa8996bb 100644 --- a/include/battle_util.h +++ b/include/battle_util.h @@ -146,7 +146,7 @@ u32 AbilityBattleEffects(u32 caseID, u32 battler, u32 ability, u32 special, u32 void BattleScriptExecute(const u8 *BS_ptr); void BattleScriptPushCursorAndCallback(const u8 *BS_ptr); u8 ItemBattleEffects(u8 caseID, u32 battler, bool32 moveTurn); -void ClearFuryCutterDestinyBondGrudge(u8 battlerId); +void ClearVariousBattlerFlags(u32 battler); void HandleAction_RunBattleScript(void); u8 GetMoveTarget(u16 move, u8 setTarget); u8 IsMonDisobedient(void); diff --git a/include/constants/battle_anim.h b/include/constants/battle_anim.h index 64f873d7f..31e21298e 100644 --- a/include/constants/battle_anim.h +++ b/include/constants/battle_anim.h @@ -399,6 +399,7 @@ #define B_ANIM_BALL_THROW_WITH_TRAINER 4 #define B_ANIM_SUBSTITUTE_TO_MON 5 #define B_ANIM_MON_TO_SUBSTITUTE 6 +#define B_ANIM_CRITICAL_CAPTURE_THROW 7 // status animation table (gBattleAnims_StatusConditions) #define B_ANIM_STATUS_PSN 0 diff --git a/src/battle_controller_player.c b/src/battle_controller_player.c index 59398b456..59e979e8a 100644 --- a/src/battle_controller_player.c +++ b/src/battle_controller_player.c @@ -1,4 +1,5 @@ #include "global.h" +#include "battle_controllers.h" #include "gflib.h" #include "data.h" #include "item.h" @@ -13,7 +14,6 @@ #include "util.h" #include "battle.h" #include "battle_anim.h" -#include "battle_controllers.h" #include "battle_interface.h" #include "battle_message.h" #include "battle_setup.h" @@ -32,13 +32,10 @@ static void PlayerHandleSwitchInAnim(u32 battler); static void PlayerHandleDrawTrainerPic(u32 battler); static void PlayerHandleTrainerSlide(u32 battler); static void PlayerHandleTrainerSlideBack(u32 battler); -static void PlayerHandleFaintAnimation(u32 battler); static void PlayerHandlePaletteFade(u32 battler); static void PlayerHandleSuccessBallThrowAnim(u32 battler); static void PlayerHandleBallThrowAnim(u32 battler); static void PlayerHandlePause(u32 battler); -static void PlayerHandleMoveAnimation(u32 battler); -static void PlayerHandlePrintString(u32 battler); static void PlayerHandlePrintSelectionString(u32 battler); static void PlayerHandleChooseAction(u32 battler); static void PlayerHandleUnknownYesNoBox(u32 battler); @@ -48,7 +45,6 @@ static void PlayerHandleChoosePokemon(u32 battler); static void PlayerHandleCmd23(u32 battler); static void PlayerHandleHealthBarUpdate(u32 battler); static void PlayerHandleExpUpdate(u32 battler); -static void PlayerHandleStatusIconUpdate(u32 battler); static void PlayerHandleStatusAnimation(u32 battler); static void PlayerHandleStatusXor(u32 battler); static void PlayerHandleDataTransfer(u32 battler); @@ -94,7 +90,6 @@ static void Task_PrepareToGiveExpWithExpBar(u8 taskId); static void DestroyExpTaskAndCompleteOnInactiveTextPrinter(u8 taskId); static void Task_UpdateLvlInHealthbox(u8 taskId); static void PrintLinkStandbyMsg(void); -static void PlayerDoMoveAnimation(u32 battler); static void Task_StartSendOutAnim(u8 taskId); static void PreviewDeterminativeMoveTargets(u32 battler); static void SwitchIn_HandleSoundAndEnd(u32 battler); @@ -116,23 +111,23 @@ static void (*const sPlayerBufferCommands[CONTROLLER_CMDS_COUNT])(u32 battler) = [CONTROLLER_DRAWTRAINERPIC] = PlayerHandleDrawTrainerPic, // done [CONTROLLER_TRAINERSLIDE] = PlayerHandleTrainerSlide, // done [CONTROLLER_TRAINERSLIDEBACK] = PlayerHandleTrainerSlideBack, // done - [CONTROLLER_FAINTANIMATION] = PlayerHandleFaintAnimation, - [CONTROLLER_PALETTEFADE] = PlayerHandlePaletteFade, - [CONTROLLER_SUCCESSBALLTHROWANIM] = PlayerHandleSuccessBallThrowAnim, - [CONTROLLER_BALLTHROWANIM] = PlayerHandleBallThrowAnim, - [CONTROLLER_PAUSE] = PlayerHandlePause, - [CONTROLLER_MOVEANIMATION] = PlayerHandleMoveAnimation, - [CONTROLLER_PRINTSTRING] = PlayerHandlePrintString, - [CONTROLLER_PRINTSTRINGPLAYERONLY] = PlayerHandlePrintSelectionString, - [CONTROLLER_CHOOSEACTION] = PlayerHandleChooseAction, - [CONTROLLER_UNKNOWNYESNOBOX] = PlayerHandleUnknownYesNoBox, - [CONTROLLER_CHOOSEMOVE] = PlayerHandleChooseMove, - [CONTROLLER_OPENBAG] = PlayerHandleChooseItem, - [CONTROLLER_CHOOSEPOKEMON] = PlayerHandleChoosePokemon, - [CONTROLLER_23] = PlayerHandleCmd23, - [CONTROLLER_HEALTHBARUPDATE] = PlayerHandleHealthBarUpdate, - [CONTROLLER_EXPUPDATE] = PlayerHandleExpUpdate, - [CONTROLLER_STATUSICONUPDATE] = PlayerHandleStatusIconUpdate, + [CONTROLLER_FAINTANIMATION] = BtlController_HandleFaintAnimation, // done + [CONTROLLER_PALETTEFADE] = PlayerHandlePaletteFade, // done + [CONTROLLER_SUCCESSBALLTHROWANIM] = PlayerHandleSuccessBallThrowAnim, // done + [CONTROLLER_BALLTHROWANIM] = PlayerHandleBallThrowAnim, // done + [CONTROLLER_PAUSE] = PlayerHandlePause, // done + [CONTROLLER_MOVEANIMATION] = BtlController_HandleMoveAnimation, // done + [CONTROLLER_PRINTSTRING] = BtlController_HandlePrintString, // done + [CONTROLLER_PRINTSTRINGPLAYERONLY] = PlayerHandlePrintSelectionString, // done + [CONTROLLER_CHOOSEACTION] = PlayerHandleChooseAction, // done + [CONTROLLER_UNKNOWNYESNOBOX] = BtlController_Empty, // done + [CONTROLLER_CHOOSEMOVE] = PlayerHandleChooseMove, // done + [CONTROLLER_OPENBAG] = PlayerHandleChooseItem, // done + [CONTROLLER_CHOOSEPOKEMON] = PlayerHandleChoosePokemon, // done + [CONTROLLER_23] = PlayerHandleCmd23, // done + [CONTROLLER_HEALTHBARUPDATE] = PlayerHandleHealthBarUpdate, // done + [CONTROLLER_EXPUPDATE] = PlayerHandleExpUpdate, // done + [CONTROLLER_STATUSICONUPDATE] = BtlController_HandleStatusIconUpdate, // done [CONTROLLER_STATUSANIMATION] = PlayerHandleStatusAnimation, [CONTROLLER_STATUSXOR] = PlayerHandleStatusXor, [CONTROLLER_DATATRANSFER] = PlayerHandleDataTransfer, @@ -758,10 +753,8 @@ void HandleInputChooseMove(u32 battler) } else if (JOY_NEW(START_BUTTON)) { - DebugPrintfLevel(MGBA_LOG_ERROR, "start"); if (CanMegaEvolve(battler)) { - DebugPrintfLevel(MGBA_LOG_ERROR, "canmegaevolve"); gBattleStruct->mega.playerSelect ^= 1; ChangeMegaTriggerSprite(gBattleStruct->mega.triggerSpriteId, gBattleStruct->mega.playerSelect); PlaySE(SE_SELECT); @@ -1169,22 +1162,6 @@ void Task_PlayerController_RestoreBgmAfterCry(u8 taskId) } } -static void CompleteOnHealthbarDone(u32 battler) -{ - s16 hpValue = MoveBattleBar(battler, gHealthboxSpriteIds[battler], HEALTH_BAR, 0); - - SetHealthboxSpriteVisible(gHealthboxSpriteIds[battler]); - if (hpValue != -1) - { - UpdateHpTextInHealthbox(gHealthboxSpriteIds[battler], HP_CURRENT, hpValue, gBattleMons[battler].maxHP); - } - else - { - HandleLowHpMusicChange(&gPlayerParty[gBattlerPartyIndexes[battler]], battler); - PlayerBufferExecCompleted(battler); - } -} - void CompleteOnInactiveTextPrinter(u32 battler) { if (!IsTextPrinterActive(0)) @@ -1205,10 +1182,10 @@ static s32 GetTaskExpValue(u8 taskId) static void Task_GiveExpToMon(u8 taskId) { u32 monId = (u8)(gTasks[taskId].tExpTask_monId); - u32 battler = gTasks[taskId].tExpTask_battler; + u8 battler = gTasks[taskId].tExpTask_battler; s32 gainedExp = GetTaskExpValue(taskId); - if (IsDoubleBattle() == TRUE || monId != gBattlerPartyIndexes[battler]) // Give exp without moving the expbar. + if (WhichBattleCoords(battler) == 1 || monId != gBattlerPartyIndexes[battler]) // Give exp without moving the expbar. { struct Pokemon *mon = &gPlayerParty[monId]; u16 species = GetMonData(mon, MON_DATA_SPECIES); @@ -1219,11 +1196,23 @@ static void Task_GiveExpToMon(u8 taskId) if (currExp + gainedExp >= nextLvlExp) { SetMonData(mon, MON_DATA_EXP, &nextLvlExp); + gBattleStruct->dynamax.levelUpHP = GetMonData(mon, MON_DATA_HP) \ + + UQ_4_12_TO_INT((gBattleScripting.levelUpHP * UQ_4_12(1.5)) + UQ_4_12_ROUND); CalculateMonStats(mon); + + // Reapply Dynamax HP multiplier after stats are recalculated. + if (IsDynamaxed(battler) && monId == gBattlerPartyIndexes[battler]) + { + ApplyDynamaxHPMultiplier(battler, mon); + gBattleMons[battler].hp = gBattleStruct->dynamax.levelUpHP; + SetMonData(mon, MON_DATA_HP, &gBattleMons[battler].hp); + } + gainedExp -= nextLvlExp - currExp; - BtlController_EmitTwoReturnValues(battler, 1, RET_VALUE_LEVELED_UP, gainedExp); + BtlController_EmitTwoReturnValues(battler, BUFFER_B, RET_VALUE_LEVELED_UP, gainedExp); + if (IsDoubleBattle() == TRUE - && ((u16)(monId) == gBattlerPartyIndexes[battler] || (u16)(monId) == gBattlerPartyIndexes[BATTLE_PARTNER(battler)])) + && (monId == gBattlerPartyIndexes[battler] || monId == gBattlerPartyIndexes[BATTLE_PARTNER(battler)])) gTasks[taskId].func = Task_LaunchLvlUpAnim; else gTasks[taskId].func = DestroyExpTaskAndCompleteOnInactiveTextPrinter; @@ -1232,7 +1221,7 @@ static void Task_GiveExpToMon(u8 taskId) { currExp += gainedExp; SetMonData(mon, MON_DATA_EXP, &currExp); - gBattlerControllerFuncs[battler] = CompleteOnInactiveTextPrinter; + gBattlerControllerFuncs[battler] = Controller_WaitForString; DestroyTask(taskId); } } @@ -1288,7 +1277,18 @@ static void Task_GiveExpWithExpBar(u8 taskId) if (currExp + gainedExp >= expOnNextLvl) { SetMonData(&gPlayerParty[monId], MON_DATA_EXP, &expOnNextLvl); + gBattleStruct->dynamax.levelUpHP = GetMonData(&gPlayerParty[monId], MON_DATA_HP) \ + + UQ_4_12_TO_INT((gBattleScripting.levelUpHP * UQ_4_12(1.5)) + UQ_4_12_ROUND); CalculateMonStats(&gPlayerParty[monId]); + + // Reapply Dynamax HP multiplier after stats are recalculated. + if (IsDynamaxed(battler) && monId == gBattlerPartyIndexes[battler]) + { + ApplyDynamaxHPMultiplier(battler, &gPlayerParty[monId]); + gBattleMons[battler].hp = gBattleStruct->dynamax.levelUpHP; + SetMonData(&gPlayerParty[monId], MON_DATA_HP, &gBattleMons[battler].hp); + } + gainedExp -= expOnNextLvl - currExp; BtlController_EmitTwoReturnValues(battler, 1, RET_VALUE_LEVELED_UP, gainedExp); gTasks[taskId].func = Task_LaunchLvlUpAnim; @@ -1297,7 +1297,7 @@ static void Task_GiveExpWithExpBar(u8 taskId) { currExp += gainedExp; SetMonData(&gPlayerParty[monId], MON_DATA_EXP, &currExp); - gBattlerControllerFuncs[battler] = CompleteOnInactiveTextPrinter; + gBattlerControllerFuncs[battler] = Controller_WaitForString; DestroyTask(taskId); } } @@ -1343,7 +1343,7 @@ static void DestroyExpTaskAndCompleteOnInactiveTextPrinter(u8 taskId) } else { - gBattlerControllerFuncs[battlerId] = CompleteOnInactiveTextPrinter; + gBattlerControllerFuncs[battlerId] = Controller_WaitForString; DestroyTask(taskId); } } @@ -1423,29 +1423,12 @@ static void Task_CreateLevelUpVerticalStripes(u8 taskId) gBattle_BG2_X = data[14]; gBattle_BG2_Y = data[13]; } - gBattlerControllerFuncs[battlerId] = CompleteOnInactiveTextPrinter; + gBattlerControllerFuncs[battlerId] = Controller_WaitForString; DestroyTask(taskId); break; } } -static void FreeMonSpriteAfterFaintAnim(u32 battler) -{ - if (gSprites[gBattlerSpriteIds[battler]].y + gSprites[gBattlerSpriteIds[battler]].y2 > DISPLAY_HEIGHT) - { - FreeOamMatrix(gSprites[gBattlerSpriteIds[battler]].oam.matrixNum); - DestroySprite(&gSprites[gBattlerSpriteIds[battler]]); - SetHealthboxSpriteInvisible(gHealthboxSpriteIds[battler]); - PlayerBufferExecCompleted(battler); - } -} - -static void CompleteOnInactiveTextPrinter2(u32 battler) -{ - if (!IsTextPrinterActive(0)) - PlayerBufferExecCompleted(battler); -} - static void OpenPartyMenuToChooseMon(u32 battler) { if (!gPaletteFade.active) @@ -1740,29 +1723,6 @@ static void PlayerHandleTrainerSlideBack(u32 battler) BtlController_HandleTrainerSlideBack(battler, 50, TRUE); } -static void PlayerHandleFaintAnimation(u32 battler) -{ - if (gBattleSpritesDataPtr->healthBoxesData[battler].animationState == 0) - { - if (gBattleSpritesDataPtr->battlerData[battler].behindSubstitute) - InitAndLaunchSpecialAnimation(battler, battler, battler, B_ANIM_SUBSTITUTE_TO_MON); - ++gBattleSpritesDataPtr->healthBoxesData[battler].animationState; - } - else - { - if (!gBattleSpritesDataPtr->healthBoxesData[battler].specialAnimActive) - { - gBattleSpritesDataPtr->healthBoxesData[battler].animationState = 0; - HandleLowHpMusicChange(&gPlayerParty[gBattlerPartyIndexes[battler]], battler); - PlaySE12WithPanning(SE_FAINT, SOUND_PAN_ATTACKER); - gSprites[gBattlerSpriteIds[battler]].data[1] = 0; - gSprites[gBattlerSpriteIds[battler]].data[2] = 5; - gSprites[gBattlerSpriteIds[battler]].callback = SpriteCB_FaintSlideAnim; - gBattlerControllerFuncs[battler] = FreeMonSpriteAfterFaintAnim; - } - } -} - static void PlayerHandlePaletteFade(u32 battler) { BeginNormalPaletteFade(PALETTES_ALL, 2, 0, 16, RGB_BLACK); @@ -1771,20 +1731,12 @@ static void PlayerHandlePaletteFade(u32 battler) static void PlayerHandleSuccessBallThrowAnim(u32 battler) { - gBattleSpritesDataPtr->animationData->ballThrowCaseId = BALL_3_SHAKES_SUCCESS; - gDoingBattleAnim = TRUE; - InitAndLaunchSpecialAnimation(battler, battler, GetBattlerAtPosition(B_POSITION_OPPONENT_LEFT), B_ANIM_BALL_THROW); - gBattlerControllerFuncs[battler] = CompleteOnSpecialAnimDone; + BtlController_HandleSuccessBallThrowAnim(battler, gBattlerTarget, B_ANIM_BALL_THROW, TRUE); } static void PlayerHandleBallThrowAnim(u32 battler) { - u8 ballThrowCaseId = gBattleResources->bufferA[battler][1]; - - gBattleSpritesDataPtr->animationData->ballThrowCaseId = ballThrowCaseId; - gDoingBattleAnim = TRUE; - InitAndLaunchSpecialAnimation(battler, battler, GetBattlerAtPosition(B_POSITION_OPPONENT_LEFT), B_ANIM_BALL_THROW); - gBattlerControllerFuncs[battler] = CompleteOnSpecialAnimDone; + BtlController_HandleBallThrowAnim(battler, gBattlerTarget, B_ANIM_BALL_THROW, TRUE); } static void PlayerHandlePause(u32 battler) @@ -1796,99 +1748,10 @@ static void PlayerHandlePause(u32 battler) PlayerBufferExecCompleted(battler); } -static void PlayerHandleMoveAnimation(u32 battler) -{ - if (!IsBattleSEPlaying(battler)) - { - u16 move = gBattleResources->bufferA[battler][1] | (gBattleResources->bufferA[battler][2] << 8); - - gAnimMoveTurn = gBattleResources->bufferA[battler][3]; - gAnimMovePower = gBattleResources->bufferA[battler][4] | (gBattleResources->bufferA[battler][5] << 8); - gAnimMoveDmg = gBattleResources->bufferA[battler][6] | (gBattleResources->bufferA[battler][7] << 8) | (gBattleResources->bufferA[battler][8] << 16) | (gBattleResources->bufferA[battler][9] << 24); - gAnimFriendship = gBattleResources->bufferA[battler][10]; - gWeatherMoveAnim = gBattleResources->bufferA[battler][12] | (gBattleResources->bufferA[battler][13] << 8); - gAnimDisableStructPtr = (struct DisableStruct *)&gBattleResources->bufferA[battler][16]; - gTransformedPersonalities[battler] = gAnimDisableStructPtr->transformedMonPersonality; - if (IsMoveWithoutAnimation(move, gAnimMoveTurn)) // Always returns FALSE. - { - PlayerBufferExecCompleted(battler); - } - else - { - gBattleSpritesDataPtr->healthBoxesData[battler].animationState = 0; - gBattlerControllerFuncs[battler] = PlayerDoMoveAnimation; - } - } -} - -static void PlayerDoMoveAnimation(u32 battler) -{ - u16 move = gBattleResources->bufferA[battler][1] | (gBattleResources->bufferA[battler][2] << 8); - u8 multihit = gBattleResources->bufferA[battler][11]; - - switch (gBattleSpritesDataPtr->healthBoxesData[battler].animationState) - { - case 0: - if (gBattleSpritesDataPtr->battlerData[battler].behindSubstitute - && !gBattleSpritesDataPtr->battlerData[battler].flag_x8) - { - gBattleSpritesDataPtr->battlerData[battler].flag_x8 = 1; - InitAndLaunchSpecialAnimation(battler, battler, battler, B_ANIM_SUBSTITUTE_TO_MON); - } - gBattleSpritesDataPtr->healthBoxesData[battler].animationState = 1; - break; - case 1: - if (!gBattleSpritesDataPtr->healthBoxesData[battler].specialAnimActive) - { - SetBattlerSpriteAffineMode(ST_OAM_AFFINE_OFF); - DoMoveAnim(move); - gBattleSpritesDataPtr->healthBoxesData[battler].animationState = 2; - } - break; - case 2: - gAnimScriptCallback(); - if (!gAnimScriptActive) - { - SetBattlerSpriteAffineMode(ST_OAM_AFFINE_NORMAL); - if (gBattleSpritesDataPtr->battlerData[battler].behindSubstitute && multihit < 2) - { - InitAndLaunchSpecialAnimation(battler, battler, battler, B_ANIM_MON_TO_SUBSTITUTE); - gBattleSpritesDataPtr->battlerData[battler].flag_x8 = 0; - } - gBattleSpritesDataPtr->healthBoxesData[battler].animationState = 3; - } - break; - case 3: - if (!gBattleSpritesDataPtr->healthBoxesData[battler].specialAnimActive) - { - CopyAllBattleSpritesInvisibilities(); - TrySetBehindSubstituteSpriteBit(battler, gBattleResources->bufferA[battler][1] | (gBattleResources->bufferA[battler][2] << 8)); - gBattleSpritesDataPtr->healthBoxesData[battler].animationState = 0; - PlayerBufferExecCompleted(battler); - } - break; - } -} - -static void PlayerHandlePrintString(u32 battler) -{ - u16 *stringId; - - gBattle_BG0_X = 0; - gBattle_BG0_Y = 0; - stringId = (u16 *)(&gBattleResources->bufferA[battler][2]); - BufferStringBattle(battler, *stringId); - if (BattleStringShouldBeColored(*stringId)) - BattlePutTextOnWindow(gDisplayedStringBattle, (B_WIN_MSG | B_TEXT_FLAG_NPC_CONTEXT_FONT)); - else - BattlePutTextOnWindow(gDisplayedStringBattle, B_WIN_MSG); - gBattlerControllerFuncs[battler] = CompleteOnInactiveTextPrinter2; -} - static void PlayerHandlePrintSelectionString(u32 battler) { if (GetBattlerSide(battler) == B_SIDE_PLAYER) - PlayerHandlePrintString(battler); + BtlController_HandlePrintString(battler); else PlayerBufferExecCompleted(battler); } @@ -1908,9 +1771,8 @@ static void PlayerHandleChooseAction(u32 battler) s32 i; gBattlerControllerFuncs[battler] = HandleChooseActionAfterDma3; - BattlePutTextOnWindow(gText_EmptyString3, B_WIN_MSG); BattlePutTextOnWindow(gText_BattleMenu, B_WIN_ACTION_MENU); - for (i = 0; i < 4; ++i) + for (i = 0; i < 4; i++) ActionSelectionDestroyCursorAt(i); ActionSelectionCreateCursorAt(gActionSelectionCursor[battler], 0); PREPARE_MON_NICK_BUFFER(gBattleTextBuff1, battler, gBattlerPartyIndexes[battler]); @@ -1935,6 +1797,7 @@ static void HandleChooseMoveAfterDma3(u32 battler) static void PlayerHandleChooseMove(u32 battler) { struct ChooseMoveStruct *moveInfo = (struct ChooseMoveStruct *)(&gBattleResources->bufferA[battler][4]); + InitMoveSelectionsVarsAndStrings(battler); gBattleStruct->mega.playerSelect = FALSE; gBattleStruct->burst.playerSelect = FALSE; @@ -1947,11 +1810,10 @@ static void PlayerHandleChooseMove(u32 battler) gBattleStruct->burst.triggerSpriteId = 0xFF; if (CanUltraBurst(battler)) CreateBurstTriggerSprite(battler, 0); - // TODO: Dynamax - // if (!IsDynamaxTriggerSpriteActive()) - // gBattleStruct->dynamax.triggerSpriteId = 0xFF; - // if (CanDynamax(battler)) - // CreateDynamaxTriggerSprite(battler, 0); + if (!IsDynamaxTriggerSpriteActive()) + gBattleStruct->dynamax.triggerSpriteId = 0xFF; + if (CanDynamax(battler)) + CreateDynamaxTriggerSprite(battler, 0); // TODO: Z-Move // if (!IsZMoveTriggerSpriteActive()) // gBattleStruct->zmove.triggerSpriteId = 0xFF; @@ -1979,7 +1841,8 @@ static void PlayerHandleChooseItem(u32 battler) BeginNormalPaletteFade(PALETTES_ALL, 0, 0, 0x10, RGB_BLACK); gBattlerControllerFuncs[battler] = OpenBagAndChooseItem; gBattlerInMenuId = battler; - for (i = 0; i < 3; ++i) + + for (i = 0; i < ARRAY_COUNT(gBattlePartyCurrentOrder); i++) gBattlePartyCurrentOrder[i] = gBattleResources->bufferA[battler][1 + i]; } @@ -1987,13 +1850,14 @@ static void PlayerHandleChoosePokemon(u32 battler) { s32 i; + for (i = 0; i < ARRAY_COUNT(gBattlePartyCurrentOrder); i++) + gBattlePartyCurrentOrder[i] = gBattleResources->bufferA[battler][4 + i]; + gBattleControllerData[battler] = CreateTask(TaskDummy, 0xFF); gTasks[gBattleControllerData[battler]].data[0] = gBattleResources->bufferA[battler][1] & 0xF; *(&gBattleStruct->battlerPreventingSwitchout) = gBattleResources->bufferA[battler][1] >> 4; *(&gBattleStruct->playerPartyIdx) = gBattleResources->bufferA[battler][2]; *(&gBattleStruct->abilityPreventingSwitchout) = (gBattleResources->bufferA[battler][3] & 0xFF) | (gBattleResources->bufferA[battler][7] << 8); - for (i = 0; i < 3; ++i) - gBattlePartyCurrentOrder[i] = gBattleResources->bufferA[battler][4 + i]; BeginNormalPaletteFade(PALETTES_ALL, 0, 0, 0x10, RGB_BLACK); gBattlerControllerFuncs[battler] = OpenPartyMenuToChooseMon; gBattlerInMenuId = battler; @@ -2008,31 +1872,13 @@ static void PlayerHandleCmd23(u32 battler) static void PlayerHandleHealthBarUpdate(u32 battler) { - s16 hpVal; - - LoadBattleBarGfx(0); - hpVal = gBattleResources->bufferA[battler][2] | (gBattleResources->bufferA[battler][3] << 8); - if (hpVal != INSTANT_HP_BAR_DROP) - { - u32 maxHP = GetMonData(&gPlayerParty[gBattlerPartyIndexes[battler]], MON_DATA_MAX_HP); - u32 curHP = GetMonData(&gPlayerParty[gBattlerPartyIndexes[battler]], MON_DATA_HP); - - SetBattleBarStruct(battler, gHealthboxSpriteIds[battler], maxHP, curHP, hpVal); - } - else - { - u32 maxHP = GetMonData(&gPlayerParty[gBattlerPartyIndexes[battler]], MON_DATA_MAX_HP); - - SetBattleBarStruct(battler, gHealthboxSpriteIds[battler], maxHP, 0, hpVal); - UpdateHpTextInHealthbox(gHealthboxSpriteIds[battler], HP_CURRENT, 0, maxHP); - } - gBattlerControllerFuncs[battler] = CompleteOnHealthbarDone; + BtlController_HandleHealthBarUpdate(battler, TRUE); } static void PlayerHandleExpUpdate(u32 battler) { u8 monId = gBattleResources->bufferA[battler][1]; - s32 expPointsToGive, taskId; + s32 taskId, expPointsToGive; if (GetMonData(&gPlayerParty[monId], MON_DATA_LEVEL) >= MAX_LEVEL) { @@ -2051,19 +1897,6 @@ static void PlayerHandleExpUpdate(u32 battler) } } -static void PlayerHandleStatusIconUpdate(u32 battler) -{ - if (!IsBattleSEPlaying(battler)) - { - u8 battlerId; - - UpdateHealthboxAttribute(gHealthboxSpriteIds[battler], &gPlayerParty[gBattlerPartyIndexes[battler]], HEALTHBOX_STATUS_ICON); - battlerId = battler; - gBattleSpritesDataPtr->healthBoxesData[battlerId].statusAnimActive = FALSE; - gBattlerControllerFuncs[battler] = CompleteOnFinishedStatusAnimation; - } -} - static void PlayerHandleStatusAnimation(u32 battler) { if (!IsBattleSEPlaying(battler)) diff --git a/src/battle_controllers.c b/src/battle_controllers.c index a66785b3a..568ec2171 100644 --- a/src/battle_controllers.c +++ b/src/battle_controllers.c @@ -10,10 +10,12 @@ #include "link_rfu.h" #include "party_menu.h" #include "pokeball.h" +#include "sound.h" #include "string_util.h" #include "task.h" #include "text.h" #include "util.h" +#include "constants/songs.h" #include "constants/abilities.h" static EWRAM_DATA u8 sLinkSendTaskId = 0; @@ -1749,6 +1751,77 @@ static void Controller_ReturnMonToBall(u32 battler) } } +static void Controller_FaintPlayerMon(u32 battler) +{ + u32 spriteId = gBattlerSpriteIds[battler]; + if (gSprites[spriteId].y + gSprites[spriteId].y2 > DISPLAY_HEIGHT) + { + FreeOamMatrix(gSprites[spriteId].oam.matrixNum); + DestroySprite(&gSprites[spriteId]); + SetHealthboxSpriteInvisible(gHealthboxSpriteIds[battler]); + BattleControllerComplete(battler); + } +} + +static void Controller_FaintOpponentMon(u32 battler) +{ + if (!gSprites[gBattlerSpriteIds[battler]].inUse) + { + SetHealthboxSpriteInvisible(gHealthboxSpriteIds[battler]); + BattleControllerComplete(battler); + } +} + +static void Controller_DoMoveAnimation(u32 battler) +{ + u16 move = gBattleResources->bufferA[battler][1] | (gBattleResources->bufferA[battler][2] << 8); + + switch (gBattleSpritesDataPtr->healthBoxesData[battler].animationState) + { + case 0: + if (gBattleSpritesDataPtr->battlerData[battler].behindSubstitute + && !gBattleSpritesDataPtr->battlerData[battler].flag_x8) + { + gBattleSpritesDataPtr->battlerData[battler].flag_x8 = 1; + InitAndLaunchSpecialAnimation(battler, battler, battler, B_ANIM_SUBSTITUTE_TO_MON); + } + gBattleSpritesDataPtr->healthBoxesData[battler].animationState = 1; + break; + case 1: + if (!gBattleSpritesDataPtr->healthBoxesData[battler].specialAnimActive) + { + SetBattlerSpriteAffineMode(ST_OAM_AFFINE_OFF); + DoMoveAnim(move); + gBattleSpritesDataPtr->healthBoxesData[battler].animationState = 2; + } + break; + case 2: + gAnimScriptCallback(); + if (!gAnimScriptActive) + { + u8 multihit = gBattleResources->bufferA[battler][11]; + + SetBattlerSpriteAffineMode(ST_OAM_AFFINE_NORMAL); + if (gBattleSpritesDataPtr->battlerData[battler].behindSubstitute && multihit < 2) + { + InitAndLaunchSpecialAnimation(battler, battler, battler, B_ANIM_MON_TO_SUBSTITUTE); + gBattleSpritesDataPtr->battlerData[battler].flag_x8 = 0; + } + gBattleSpritesDataPtr->healthBoxesData[battler].animationState = 3; + } + break; + case 3: + if (!gBattleSpritesDataPtr->healthBoxesData[battler].specialAnimActive) + { + CopyAllBattleSpritesInvisibilities(); + TrySetBehindSubstituteSpriteBit(battler, gBattleResources->bufferA[battler][1] | (gBattleResources->bufferA[battler][2] << 8)); + gBattleSpritesDataPtr->healthBoxesData[battler].animationState = 0; + BattleControllerComplete(battler); + } + break; + } +} + static void Controller_HandleTrainerSlideBack(u32 battler) { if (gSprites[gBattlerSpriteIds[battler]].callback == SpriteCallbackDummy) @@ -1761,12 +1834,47 @@ static void Controller_HandleTrainerSlideBack(u32 battler) } } +void Controller_WaitForHealthBar(u32 battler) +{ + s16 hpValue = MoveBattleBar(battler, gHealthboxSpriteIds[battler], HEALTH_BAR, 0); + + SetHealthboxSpriteVisible(gHealthboxSpriteIds[battler]); + if (hpValue != -1) + { + UpdateHpTextInHealthbox(gHealthboxSpriteIds[battler], HP_CURRENT, hpValue, gBattleMons[battler].maxHP); + } + else + { + if (GetBattlerSide(battler) == B_SIDE_PLAYER) + HandleLowHpMusicChange(&gPlayerParty[gBattlerPartyIndexes[battler]], battler); + BattleControllerComplete(battler); + } +} + +static void Controller_WaitForBallThrow(u32 battler) +{ + if (!gDoingBattleAnim || !gBattleSpritesDataPtr->healthBoxesData[battler].specialAnimActive) + BattleControllerComplete(battler); +} + +static void Controller_WaitForStatusAnimation(u32 battler) +{ + if (!gBattleSpritesDataPtr->healthBoxesData[battler].statusAnimActive) + BattleControllerComplete(battler); +} + static void Controller_WaitForTrainerPic(u32 battler) { if (gSprites[gBattlerSpriteIds[battler]].callback == SpriteCallbackDummy) BattleControllerComplete(battler); } +void Controller_WaitForString(u32 battler) +{ + if (!IsTextPrinterActive(B_WIN_MSG)) + BattleControllerComplete(battler); +} + // Used for all the commands which do nothing. void BtlController_Empty(u32 battler) { @@ -1994,5 +2102,141 @@ void BtlController_HandleTrainerSlideBack(u32 battler, s16 data0, bool32 startAn gBattlerControllerFuncs[battler] = Controller_HandleTrainerSlideBack; } +#define sSpeedX data[1] +#define sSpeedY data[2] + +void BtlController_HandleFaintAnimation(u32 battler) +{ + if (gBattleSpritesDataPtr->healthBoxesData[battler].animationState == 0) + { + if (gBattleSpritesDataPtr->battlerData[battler].behindSubstitute) + InitAndLaunchSpecialAnimation(battler, battler, battler, B_ANIM_SUBSTITUTE_TO_MON); + gBattleSpritesDataPtr->healthBoxesData[battler].animationState++; + } + else + { + if (!gBattleSpritesDataPtr->healthBoxesData[battler].specialAnimActive) + { + gBattleSpritesDataPtr->healthBoxesData[battler].animationState = 0; + if (GetBattlerSide(battler) == B_SIDE_PLAYER) + { + HandleLowHpMusicChange(&gPlayerParty[gBattlerPartyIndexes[battler]], battler); + gSprites[gBattlerSpriteIds[battler]].sSpeedX = 0; + gSprites[gBattlerSpriteIds[battler]].sSpeedY = 5; + PlaySE12WithPanning(SE_FAINT, SOUND_PAN_ATTACKER); + gSprites[gBattlerSpriteIds[battler]].callback = SpriteCB_FaintSlideAnim; + gBattlerControllerFuncs[battler] = Controller_FaintPlayerMon; + } + else + { + PlaySE12WithPanning(SE_FAINT, SOUND_PAN_TARGET); + gSprites[gBattlerSpriteIds[battler]].callback = SpriteCB_FaintOpponentMon; + gBattlerControllerFuncs[battler] = Controller_FaintOpponentMon; + } + // The player's sprite callback just slides the mon, the opponent's removes the sprite. + // The player's sprite is removed in Controller_FaintPlayerMon. Controller_FaintOpponentMon only removes the healthbox once the sprite is removed by SpriteCB_FaintOpponentMon. + } + } +} + +#undef sSpeedX +#undef sSpeedY + +static void HandleBallThrow(u32 battler, u32 target, u32 animId, bool32 allowCriticalCapture) +{ + gDoingBattleAnim = TRUE; + if (allowCriticalCapture && IsCriticalCapture()) + animId = B_ANIM_CRITICAL_CAPTURE_THROW; + InitAndLaunchSpecialAnimation(battler, battler, target, animId); + + gBattlerControllerFuncs[battler] = Controller_WaitForBallThrow; +} + +void BtlController_HandleSuccessBallThrowAnim(u32 battler, u32 target, u32 animId, bool32 allowCriticalCapture) +{ + gBattleSpritesDataPtr->animationData->ballThrowCaseId = BALL_3_SHAKES_SUCCESS; + HandleBallThrow(battler, target, animId, allowCriticalCapture); +} + +void BtlController_HandleBallThrowAnim(u32 battler, u32 target, u32 animId, bool32 allowCriticalCapture) +{ + gBattleSpritesDataPtr->animationData->ballThrowCaseId = gBattleResources->bufferA[battler][1]; + HandleBallThrow(battler, target, animId, allowCriticalCapture); +} + +void BtlController_HandleMoveAnimation(u32 battler) +{ + if (!IsBattleSEPlaying(battler)) + { + u16 move = gBattleResources->bufferA[battler][1] | (gBattleResources->bufferA[battler][2] << 8); + + gAnimMoveTurn = gBattleResources->bufferA[battler][3]; + gAnimMovePower = gBattleResources->bufferA[battler][4] | (gBattleResources->bufferA[battler][5] << 8); + gAnimMoveDmg = gBattleResources->bufferA[battler][6] | (gBattleResources->bufferA[battler][7] << 8) | (gBattleResources->bufferA[battler][8] << 16) | (gBattleResources->bufferA[battler][9] << 24); + gAnimFriendship = gBattleResources->bufferA[battler][10]; + gWeatherMoveAnim = gBattleResources->bufferA[battler][12] | (gBattleResources->bufferA[battler][13] << 8); + gAnimDisableStructPtr = (struct DisableStruct *)&gBattleResources->bufferA[battler][16]; + gTransformedPersonalities[battler] = gAnimDisableStructPtr->transformedMonPersonality; + gTransformedShininess[battler] = gAnimDisableStructPtr->transformedMonShininess; + gBattleSpritesDataPtr->healthBoxesData[battler].animationState = 0; + gBattlerControllerFuncs[battler] = Controller_DoMoveAnimation; + } +} + +void BtlController_HandlePrintString(u32 battler) +{ + u16 *stringId; + + gBattle_BG0_X = 0; + gBattle_BG0_Y = 0; + stringId = (u16 *)(&gBattleResources->bufferA[battler][2]); + BufferStringBattle(battler, *stringId); + + BattlePutTextOnWindow(gDisplayedStringBattle, B_WIN_MSG); + gBattlerControllerFuncs[battler] = Controller_WaitForString; +} + +void BtlController_HandleHealthBarUpdate(u32 battler, bool32 updateHpText) +{ + s32 maxHP, curHP; + s16 hpVal; + struct Pokemon *party = GetBattlerParty(battler); + + LoadBattleBarGfx(0); + hpVal = gBattleResources->bufferA[battler][2] | (gBattleResources->bufferA[battler][3] << 8); + maxHP = GetMonData(&party[gBattlerPartyIndexes[battler]], MON_DATA_MAX_HP); + curHP = GetMonData(&party[gBattlerPartyIndexes[battler]], MON_DATA_HP); + + if (hpVal != INSTANT_HP_BAR_DROP) + { + SetBattleBarStruct(battler, gHealthboxSpriteIds[battler], maxHP, curHP, hpVal); + } + else + { + SetBattleBarStruct(battler, gHealthboxSpriteIds[battler], maxHP, 0, hpVal); + if (updateHpText) + UpdateHpTextInHealthbox(gHealthboxSpriteIds[battler], HP_CURRENT, 0, maxHP); + } + + gBattlerControllerFuncs[battler] = Controller_WaitForHealthBar; +} + +void DoStatusIconUpdate(u32 battler) +{ + struct Pokemon *party = GetBattlerParty(battler); + + UpdateHealthboxAttribute(gHealthboxSpriteIds[battler], &party[gBattlerPartyIndexes[battler]], HEALTHBOX_STATUS_ICON); + gBattleSpritesDataPtr->healthBoxesData[battler].statusAnimActive = FALSE; + gBattlerControllerFuncs[battler] = Controller_WaitForStatusAnimation; +} + +void BtlController_HandleStatusIconUpdate(u32 battler) +{ + if (!IsBattleSEPlaying(battler)) + { + DoStatusIconUpdate(battler); + } +} + diff --git a/src/battle_interface.c b/src/battle_interface.c index afc2f3a8c..d17b31e2e 100644 --- a/src/battle_interface.c +++ b/src/battle_interface.c @@ -658,6 +658,22 @@ enum HEALTHBAR_TYPE_OPPONENT, }; +// This function is here to cover a specific case - one player's mon in a 2 vs 1 double battle. In this scenario - display singles layout. +// The same goes for a 2 vs 1 where opponent has only one pokemon. +u32 WhichBattleCoords(u32 battlerId) // 0 - singles, 1 - doubles +{ + if (GetBattlerPosition(battlerId) == B_POSITION_PLAYER_LEFT + && gPlayerPartyCount == 1 + && !(gBattleTypeFlags & BATTLE_TYPE_MULTI)) + return 0; + else if (GetBattlerPosition(battlerId) == B_POSITION_OPPONENT_LEFT + && gEnemyPartyCount == 1 + && !(gBattleTypeFlags & BATTLE_TYPE_TWO_OPPONENTS)) + return 0; + else + return IsDoubleBattle(); +} + u8 CreateBattlerHealthboxSprites(u8 battlerId) { s16 healthbarType = HEALTHBAR_TYPE_PLAYER_SINGLE; diff --git a/src/battle_main.c b/src/battle_main.c index 6137e7efd..a3f6c424e 100644 --- a/src/battle_main.c +++ b/src/battle_main.c @@ -213,6 +213,7 @@ EWRAM_DATA u8 gBattlerStatusSummaryTaskId[MAX_BATTLERS_COUNT] = {0}; EWRAM_DATA u8 gBattlerInMenuId = 0; EWRAM_DATA bool8 gDoingBattleAnim = FALSE; EWRAM_DATA u32 gTransformedPersonalities[MAX_BATTLERS_COUNT] = {0}; +EWRAM_DATA bool8 gTransformedShininess[MAX_BATTLERS_COUNT] = {0}; EWRAM_DATA u8 gPlayerDpadHoldFrames = 0; EWRAM_DATA struct BattleSpriteData *gBattleSpritesDataPtr = NULL; EWRAM_DATA struct MonSpritesGfx *gMonSpritesGfxPtr = NULL; @@ -4788,85 +4789,13 @@ static void HandleAction_Switch(void) static void HandleAction_UseItem(void) { - gBattlerAttacker = gBattlerTarget = gBattlerByTurnOrder[gCurrentTurnActionNumber]; + gBattlerAttacker = gBattlerByTurnOrder[gCurrentTurnActionNumber]; gBattle_BG0_X = 0; gBattle_BG0_Y = 0; - ClearFuryCutterDestinyBondGrudge(gBattlerAttacker); - gLastUsedItem = gBattleResources->bufferB[gBattlerAttacker][1] | (gBattleResources->bufferB[gBattlerAttacker][2] << 8); - if (GetBattlerSide(gBattlerAttacker) == B_SIDE_PLAYER) { - // change to index minus 1 - DebugPrintfLevel(MGBA_LOG_ERROR, "BattleUsage: %d", ItemId_GetBattleUsage(gLastUsedItem)); - gBattlescriptCurrInstr = gBattlescriptsForUsingItem[ItemId_GetBattleUsage(gLastUsedItem)]; - } - // if (gLastUsedItem <= ITEM_PREMIER_BALL) // is ball - // { - // gBattlescriptCurrInstr = gBattlescriptsForBallThrow[gLastUsedItem]; - // } - // else if (gLastUsedItem == ITEM_POKE_DOLL || gLastUsedItem == ITEM_FLUFFY_TAIL) - // { - // gBattlescriptCurrInstr = gBattlescriptsForRunningByItem[0]; - // } - // else if (gLastUsedItem == ITEM_POKE_FLUTE) - // { - // gBattlescriptCurrInstr = gBattlescriptsForRunningByItem[1]; - // } - // else if (GetBattlerSide(gBattlerAttacker) == B_SIDE_PLAYER) - // { - // gBattlescriptCurrInstr = gBattlescriptsForUsingItem[0]; - // } - else - { - gBattleScripting.battler = gBattlerAttacker; - switch (*(gBattleStruct->AI_itemType + (gBattlerAttacker >> 1))) - { - case AI_ITEM_FULL_RESTORE: - case AI_ITEM_HEAL_HP: - break; - case AI_ITEM_CURE_CONDITION: - gBattleCommunication[MULTISTRING_CHOOSER] = 0; - if (*(gBattleStruct->AI_itemFlags + gBattlerAttacker / 2) & 1) - { - if (*(gBattleStruct->AI_itemFlags + gBattlerAttacker / 2) & 0x3E) - gBattleCommunication[MULTISTRING_CHOOSER] = 5; - } - else - { - while (!(*(gBattleStruct->AI_itemFlags + gBattlerAttacker / 2) & 1)) - { - *(gBattleStruct->AI_itemFlags + gBattlerAttacker / 2) >>= 1; - gBattleCommunication[MULTISTRING_CHOOSER]++; - } - } - break; - case AI_ITEM_X_STAT: - gBattleCommunication[MULTISTRING_CHOOSER] = 4; - if (*(gBattleStruct->AI_itemFlags + (gBattlerAttacker >> 1)) & 0x80) - { - gBattleCommunication[MULTISTRING_CHOOSER] = 5; - } - else - { - PREPARE_STAT_BUFFER(gBattleTextBuff1, STAT_ATK); - PREPARE_STRING_BUFFER(gBattleTextBuff2, CHAR_X); - while (!((*(gBattleStruct->AI_itemFlags + (gBattlerAttacker >> 1))) & 1)) - { - *(gBattleStruct->AI_itemFlags + gBattlerAttacker / 2) >>= 1; - ++gBattleTextBuff1[2]; - } - gBattleScripting.animArg1 = gBattleTextBuff1[2] + 14; - gBattleScripting.animArg2 = 0; - } - break; - case AI_ITEM_GUARD_SPECS: - if (gBattleTypeFlags & BATTLE_TYPE_DOUBLE) - gBattleCommunication[MULTISTRING_CHOOSER] = 2; - else - gBattleCommunication[MULTISTRING_CHOOSER] = 0; - break; - } + ClearVariousBattlerFlags(gBattlerAttacker); - gBattlescriptCurrInstr = gBattleScriptsForAIUsingItems[*(gBattleStruct->AI_itemType + gBattlerAttacker / 2) - 1]; - } + gLastUsedItem = gBattleResources->bufferB[gBattlerAttacker][1] | (gBattleResources->bufferB[gBattlerAttacker][2] << 8); + gBattlescriptCurrInstr = gBattlescriptsForUsingItem[ItemId_GetBattleUsage(gLastUsedItem) - 1]; gCurrentActionFuncId = B_ACTION_EXEC_SCRIPT; } @@ -4953,7 +4882,7 @@ static void HandleAction_Run(void) { if (!TryRunFromBattle(gBattlerAttacker)) // failed to run away { - ClearFuryCutterDestinyBondGrudge(gBattlerAttacker); + ClearVariousBattlerFlags(gBattlerAttacker); gBattleCommunication[MULTISTRING_CHOOSER] = 3; gBattlescriptCurrInstr = BattleScript_PrintFailedToRunString; gCurrentActionFuncId = B_ACTION_EXEC_SCRIPT; diff --git a/src/battle_script_commands.c b/src/battle_script_commands.c index 61e5b36bc..ff7913cc8 100644 --- a/src/battle_script_commands.c +++ b/src/battle_script_commands.c @@ -27,6 +27,7 @@ #include "reshow_battle_screen.h" #include "battle_controllers.h" #include "battle_interface.h" +#include "rtc.h" #include "constants/battle_anim.h" #include "constants/battle_move_effects.h" #include "constants/battle_script_commands.h" @@ -15206,10 +15207,9 @@ static void Cmd_handleballthrow(void) ballMultiplier = 400; break; case ITEM_DUSK_BALL: - // TODO: RTC - // i = GetTimeOfDay(); - // if (i == TIME_EVENING || i == TIME_NIGHT || gMapHeader.cave || gMapHeader.mapType == MAP_TYPE_UNDERGROUND) - // ballMultiplier = (B_DUSK_BALL_MODIFIER >= GEN_7 ? 300 : 350); + i = GetTimeOfDay(); + if (i == TIME_EVENING || i == TIME_NIGHT || gMapHeader.cave || gMapHeader.mapType == MAP_TYPE_UNDERGROUND) + ballMultiplier = (B_DUSK_BALL_MODIFIER >= GEN_7 ? 300 : 350); break; case ITEM_QUICK_BALL: if (gBattleResults.battleTurnCounter == 0) @@ -15358,7 +15358,7 @@ static void Cmd_handleballthrow(void) gBattleSpritesDataPtr->animationData->isCriticalCapture = FALSE; gBattleSpritesDataPtr->animationData->criticalCaptureSuccess = FALSE; - if (CriticalCapture(odds)) + if (TRUE || CriticalCapture(odds)) { maxShakes = BALL_1_SHAKE; // critical capture doesn't guarantee capture gBattleSpritesDataPtr->animationData->isCriticalCapture = TRUE; @@ -16472,7 +16472,7 @@ void BS_RunStatChangeItems(void) // Change instruction before calling ItemBattleEffects. gBattlescriptCurrInstr = cmd->nextInstr; - ItemBattleEffects(ITEMEFFECT_STATS_CHANGED, GetBattlerForBattleScript(cmd->battler), FALSE); // TODO: update + ItemBattleEffects(ITEMEFFECT_STATS_CHANGED, GetBattlerForBattleScript(cmd->battler), FALSE); } void BS_ItemRestorePP(void) diff --git a/src/battle_util.c b/src/battle_util.c index 1bca14552..bd4095489 100644 --- a/src/battle_util.c +++ b/src/battle_util.c @@ -6680,11 +6680,12 @@ u8 ItemBattleEffects(u8 caseID, u32 battler, bool32 moveTurn) return effect; } -void ClearFuryCutterDestinyBondGrudge(u8 battlerId) +void ClearVariousBattlerFlags(u32 battler) { - gDisableStructs[battlerId].furyCutterCounter = 0; - gBattleMons[battlerId].status2 &= ~STATUS2_DESTINY_BOND; - gStatuses3[battlerId] &= ~STATUS3_GRUDGE; + gDisableStructs[battler].furyCutterCounter = 0; + gBattleMons[battler].status2 &= ~STATUS2_DESTINY_BOND; + gStatuses3[battler] &= ~STATUS3_GRUDGE; + gStatuses4[battler] &= ~ STATUS4_GLAIVE_RUSH; } void HandleAction_RunBattleScript(void) // identical to RunBattleScriptCommands diff --git a/src/data/wild_encounters.json b/src/data/wild_encounters.json index c5963d0c8..2f38921c6 100644 --- a/src/data/wild_encounters.json +++ b/src/data/wild_encounters.json @@ -10499,24 +10499,24 @@ "encounter_rate": 21, "mons": [ { - "min_level": 3, - "max_level": 3, - "species": "SPECIES_RATTATA" + "min_level": 6, + "max_level": 6, + "species": "SPECIES_PARAS" }, { - "min_level": 3, - "max_level": 3, - "species": "SPECIES_MANKEY" + "min_level": 6, + "max_level": 6, + "species": "SPECIES_PARAS" }, { - "min_level": 4, - "max_level": 4, - "species": "SPECIES_RATTATA" + "min_level": 6, + "max_level": 6, + "species": "SPECIES_PARAS" }, { - "min_level": 4, - "max_level": 4, - "species": "SPECIES_MANKEY" + "min_level": 6, + "max_level": 6, + "species": "SPECIES_PARAS" }, { "min_level": 2, diff --git a/src/pokemon.c b/src/pokemon.c index ac7cea3d0..0a9a86db2 100644 --- a/src/pokemon.c +++ b/src/pokemon.c @@ -3370,61 +3370,6 @@ void RemoveBattleMonPPBonus(struct BattlePokemon *mon, u8 moveIndex) mon->ppBonuses &= gPPUpClearMask[moveIndex]; } -static void CopyPlayerPartyMonToBattleData(u8 battlerId, u8 partyIndex) -{ - u16 *hpSwitchout; - s32 i; - u8 nickname[POKEMON_NAME_LENGTH * 2]; // Why is the nickname array here longer in FR/LG? - - gBattleMons[battlerId].species = GetMonData(&gPlayerParty[partyIndex], MON_DATA_SPECIES, NULL); - gBattleMons[battlerId].item = GetMonData(&gPlayerParty[partyIndex], MON_DATA_HELD_ITEM, NULL); - - for (i = 0; i < MAX_MON_MOVES; i++) - { - gBattleMons[battlerId].moves[i] = GetMonData(&gPlayerParty[partyIndex], MON_DATA_MOVE1 + i, NULL); - gBattleMons[battlerId].pp[i] = GetMonData(&gPlayerParty[partyIndex], MON_DATA_PP1 + i, NULL); - } - - gBattleMons[battlerId].ppBonuses = GetMonData(&gPlayerParty[partyIndex], MON_DATA_PP_BONUSES, NULL); - gBattleMons[battlerId].friendship = GetMonData(&gPlayerParty[partyIndex], MON_DATA_FRIENDSHIP, NULL); - gBattleMons[battlerId].experience = GetMonData(&gPlayerParty[partyIndex], MON_DATA_EXP, NULL); - gBattleMons[battlerId].hpIV = GetMonData(&gPlayerParty[partyIndex], MON_DATA_HP_IV, NULL); - gBattleMons[battlerId].attackIV = GetMonData(&gPlayerParty[partyIndex], MON_DATA_ATK_IV, NULL); - gBattleMons[battlerId].defenseIV = GetMonData(&gPlayerParty[partyIndex], MON_DATA_DEF_IV, NULL); - gBattleMons[battlerId].speedIV = GetMonData(&gPlayerParty[partyIndex], MON_DATA_SPEED_IV, NULL); - gBattleMons[battlerId].spAttackIV = GetMonData(&gPlayerParty[partyIndex], MON_DATA_SPATK_IV, NULL); - gBattleMons[battlerId].spDefenseIV = GetMonData(&gPlayerParty[partyIndex], MON_DATA_SPDEF_IV, NULL); - gBattleMons[battlerId].personality = GetMonData(&gPlayerParty[partyIndex], MON_DATA_PERSONALITY, NULL); - gBattleMons[battlerId].status1 = GetMonData(&gPlayerParty[partyIndex], MON_DATA_STATUS, NULL); - gBattleMons[battlerId].level = GetMonData(&gPlayerParty[partyIndex], MON_DATA_LEVEL, NULL); - gBattleMons[battlerId].hp = GetMonData(&gPlayerParty[partyIndex], MON_DATA_HP, NULL); - gBattleMons[battlerId].maxHP = GetMonData(&gPlayerParty[partyIndex], MON_DATA_MAX_HP, NULL); - gBattleMons[battlerId].attack = GetMonData(&gPlayerParty[partyIndex], MON_DATA_ATK, NULL); - gBattleMons[battlerId].defense = GetMonData(&gPlayerParty[partyIndex], MON_DATA_DEF, NULL); - gBattleMons[battlerId].speed = GetMonData(&gPlayerParty[partyIndex], MON_DATA_SPEED, NULL); - gBattleMons[battlerId].spAttack = GetMonData(&gPlayerParty[partyIndex], MON_DATA_SPATK, NULL); - gBattleMons[battlerId].spDefense = GetMonData(&gPlayerParty[partyIndex], MON_DATA_SPDEF, NULL); - // gBattleMons[battlerId].isEgg = GetMonData(&gPlayerParty[partyIndex], MON_DATA_IS_EGG, NULL); - gBattleMons[battlerId].abilityNum = GetMonData(&gPlayerParty[partyIndex], MON_DATA_ABILITY_NUM, NULL); - gBattleMons[battlerId].otId = GetMonData(&gPlayerParty[partyIndex], MON_DATA_OT_ID, NULL); - gBattleMons[battlerId].type1 = gSpeciesInfo[gBattleMons[battlerId].species].types[0]; - gBattleMons[battlerId].type2 = gSpeciesInfo[gBattleMons[battlerId].species].types[1]; - gBattleMons[battlerId].ability = GetAbilityBySpecies(gBattleMons[battlerId].species, gBattleMons[battlerId].abilityNum); - GetMonData(&gPlayerParty[partyIndex], MON_DATA_NICKNAME, nickname); - StringCopy_Nickname(gBattleMons[battlerId].nickname, nickname); - GetMonData(&gPlayerParty[partyIndex], MON_DATA_OT_NAME, gBattleMons[battlerId].otName); - - hpSwitchout = &gBattleStruct->hpOnSwitchout[GetBattlerSide(battlerId)]; - *hpSwitchout = gBattleMons[battlerId].hp; - - for (i = 0; i < NUM_BATTLE_STATS; i++) - gBattleMons[battlerId].statStages[i] = DEFAULT_STAT_STAGE; - - gBattleMons[battlerId].status2 = 0; - UpdateSentPokesToOpponentValue(battlerId); - ClearTemporarySpeciesSpriteData(battlerId, FALSE); -} - bool8 ExecuteTableBasedItemEffect(struct Pokemon *mon, u16 item, u8 partyIndex, u8 moveIndex) { return PokemonUseItemEffects(mon, item, partyIndex, moveIndex, FALSE); diff --git a/sym_ewram.txt b/sym_ewram.txt index cee4e8281..7e7fc424d 100644 --- a/sym_ewram.txt +++ b/sym_ewram.txt @@ -135,3 +135,4 @@ .include "src/digit_obj_util.o" .include "src/trainer_tower.o" .include "src/berry_powder.o" + .include "src/battle_controller_player.o"