2017-10-01 01:12:42 +02:00
|
|
|
#include "global.h"
|
|
|
|
#include "battle.h"
|
2019-03-31 19:15:39 +02:00
|
|
|
#include "battle_anim.h"
|
2018-11-13 23:28:46 +01:00
|
|
|
#include "battle_ai_script_commands.h"
|
|
|
|
#include "battle_arena.h"
|
|
|
|
#include "battle_controllers.h"
|
2018-02-09 01:09:02 +01:00
|
|
|
#include "battle_interface.h"
|
2018-12-07 20:47:20 +01:00
|
|
|
#include "battle_main.h"
|
2018-11-13 23:28:46 +01:00
|
|
|
#include "battle_message.h"
|
2018-11-18 17:52:22 +01:00
|
|
|
#include "battle_pyramid.h"
|
2018-11-13 23:28:46 +01:00
|
|
|
#include "battle_scripts.h"
|
|
|
|
#include "battle_setup.h"
|
|
|
|
#include "battle_tower.h"
|
2017-10-01 01:12:42 +02:00
|
|
|
#include "berry.h"
|
2018-11-13 23:28:46 +01:00
|
|
|
#include "bg.h"
|
2019-04-04 23:53:06 +02:00
|
|
|
#include "data.h"
|
2018-11-13 23:28:46 +01:00
|
|
|
#include "decompress.h"
|
2018-11-14 01:01:50 +01:00
|
|
|
#include "dma3.h"
|
2018-11-13 23:28:46 +01:00
|
|
|
#include "event_data.h"
|
|
|
|
#include "evolution_scene.h"
|
2018-12-19 03:15:59 +01:00
|
|
|
#include "graphics.h"
|
2018-11-13 23:28:46 +01:00
|
|
|
#include "gpu_regs.h"
|
|
|
|
#include "international_string_util.h"
|
2017-10-02 23:32:39 +02:00
|
|
|
#include "item.h"
|
2017-10-01 01:12:42 +02:00
|
|
|
#include "link.h"
|
2017-11-11 04:08:17 +01:00
|
|
|
#include "link_rfu.h"
|
2018-11-13 23:28:46 +01:00
|
|
|
#include "load_save.h"
|
|
|
|
#include "main.h"
|
2018-11-29 12:24:28 +01:00
|
|
|
#include "alloc.h"
|
2017-10-01 18:54:01 +02:00
|
|
|
#include "m4a.h"
|
2018-11-13 23:28:46 +01:00
|
|
|
#include "palette.h"
|
|
|
|
#include "party_menu.h"
|
|
|
|
#include "pokeball.h"
|
|
|
|
#include "pokedex.h"
|
|
|
|
#include "pokemon.h"
|
2017-12-05 19:27:33 +01:00
|
|
|
#include "random.h"
|
2018-11-13 23:28:46 +01:00
|
|
|
#include "recorded_battle.h"
|
|
|
|
#include "roamer.h"
|
|
|
|
#include "safari_zone.h"
|
|
|
|
#include "scanline_effect.h"
|
2017-10-01 18:54:01 +02:00
|
|
|
#include "sound.h"
|
|
|
|
#include "sprite.h"
|
2018-11-13 23:28:46 +01:00
|
|
|
#include "string_util.h"
|
2018-12-24 00:02:29 +01:00
|
|
|
#include "strings.h"
|
2018-11-13 23:28:46 +01:00
|
|
|
#include "task.h"
|
|
|
|
#include "text.h"
|
2017-10-02 23:32:39 +02:00
|
|
|
#include "trig.h"
|
2018-11-13 23:28:46 +01:00
|
|
|
#include "tv.h"
|
|
|
|
#include "util.h"
|
|
|
|
#include "window.h"
|
2017-12-05 18:55:48 +01:00
|
|
|
#include "constants/abilities.h"
|
2018-11-15 21:53:32 +01:00
|
|
|
#include "constants/battle_config.h"
|
2018-11-13 23:28:46 +01:00
|
|
|
#include "constants/battle_move_effects.h"
|
|
|
|
#include "constants/battle_string_ids.h"
|
|
|
|
#include "constants/hold_effects.h"
|
|
|
|
#include "constants/items.h"
|
2017-12-11 19:27:51 +01:00
|
|
|
#include "constants/moves.h"
|
2018-06-20 23:07:51 +02:00
|
|
|
#include "constants/rgb.h"
|
2018-11-13 23:28:46 +01:00
|
|
|
#include "constants/songs.h"
|
|
|
|
#include "constants/species.h"
|
2018-11-14 01:01:50 +01:00
|
|
|
#include "constants/trainers.h"
|
2019-03-02 04:32:50 +01:00
|
|
|
#include "cable_club.h"
|
2017-10-01 01:12:42 +02:00
|
|
|
|
2018-01-10 04:30:54 +01:00
|
|
|
extern struct MusicPlayerInfo gMPlayInfo_SE1;
|
|
|
|
extern struct MusicPlayerInfo gMPlayInfo_SE2;
|
2017-10-01 18:54:01 +02:00
|
|
|
|
2018-06-17 16:48:58 +02:00
|
|
|
extern const struct BgTemplate gBattleBgTemplates[];
|
2018-06-28 21:06:32 +02:00
|
|
|
extern const struct WindowTemplate *const gBattleWindowTemplates[];
|
|
|
|
extern const u8 *const gBattleScriptsForMoveEffects[];
|
|
|
|
extern const u8 *const gBattlescriptsForBallThrow[];
|
|
|
|
extern const u8 *const gBattlescriptsForRunningByItem[];
|
|
|
|
extern const u8 *const gBattlescriptsForUsingItem[];
|
|
|
|
extern const u8 *const gBattlescriptsForSafariActions[];
|
2017-10-02 23:32:39 +02:00
|
|
|
|
2017-10-01 01:12:42 +02:00
|
|
|
// this file's functions
|
|
|
|
static void CB2_InitBattleInternal(void);
|
|
|
|
static void CB2_PreInitMultiBattle(void);
|
|
|
|
static void CB2_PreInitIngamePlayerPartnerBattle(void);
|
|
|
|
static void CB2_HandleStartMultiPartnerBattle(void);
|
|
|
|
static void CB2_HandleStartMultiBattle(void);
|
|
|
|
static void CB2_HandleStartBattle(void);
|
2017-10-01 18:54:01 +02:00
|
|
|
static void TryCorrectShedinjaLanguage(struct Pokemon *mon);
|
|
|
|
static u8 CreateNPCTrainerParty(struct Pokemon *party, u16 trainerNum, bool8 firstTrainer);
|
2017-10-06 19:09:37 +02:00
|
|
|
static void BattleMainCB1(void);
|
2017-10-01 18:54:01 +02:00
|
|
|
static void sub_8038538(struct Sprite *sprite);
|
|
|
|
static void sub_8038F14(void);
|
|
|
|
static void sub_8038F34(void);
|
|
|
|
static void sub_80392A8(void);
|
|
|
|
static void sub_803937C(void);
|
|
|
|
static void sub_803939C(void);
|
2018-12-23 14:52:47 +01:00
|
|
|
static void SpriteCb_MoveWildMonToRight(struct Sprite *sprite);
|
|
|
|
static void SpriteCb_WildMonShowHealthbox(struct Sprite *sprite);
|
|
|
|
static void SpriteCb_WildMonAnimate(struct Sprite *sprite);
|
2017-10-01 18:54:01 +02:00
|
|
|
static void sub_80398D0(struct Sprite *sprite);
|
2018-06-20 23:07:51 +02:00
|
|
|
static void SpriteCB_AnimFaintOpponent(struct Sprite *sprite);
|
2017-10-06 19:09:37 +02:00
|
|
|
static void sub_8039AF4(struct Sprite *sprite);
|
|
|
|
static void SpriteCallbackDummy_3(struct Sprite *sprite);
|
|
|
|
static void oac_poke_ally_(struct Sprite *sprite);
|
|
|
|
static void SpecialStatusesClear(void);
|
|
|
|
static void TurnValuesCleanUp(bool8 var0);
|
2018-06-20 23:07:51 +02:00
|
|
|
static void SpriteCB_BounceEffect(struct Sprite *sprite);
|
2017-10-02 23:32:39 +02:00
|
|
|
static void BattleStartClearSetData(void);
|
2018-12-23 18:47:00 +01:00
|
|
|
static void DoBattleIntro(void);
|
2017-10-02 23:32:39 +02:00
|
|
|
static void TryDoEventsBeforeFirstTurn(void);
|
2017-10-06 19:09:37 +02:00
|
|
|
static void HandleTurnActionSelectionState(void);
|
2017-10-06 00:12:01 +02:00
|
|
|
static void RunTurnActionsFunctions(void);
|
2018-02-08 11:17:41 +01:00
|
|
|
static void SetActionsAndBattlersTurnOrder(void);
|
2017-10-06 19:09:37 +02:00
|
|
|
static void sub_803CDF8(void);
|
2018-07-07 21:14:41 +02:00
|
|
|
static bool8 AllAtActionConfirmed(void);
|
2017-10-06 00:12:01 +02:00
|
|
|
static void CheckFocusPunch_ClearVarsBeforeTurnStarts(void);
|
2018-09-16 18:55:32 +02:00
|
|
|
static void CheckMegaEvolutionBeforeTurn(void);
|
2017-10-06 00:12:01 +02:00
|
|
|
static void FreeResetData_ReturnToOvOrDoEvolutions(void);
|
|
|
|
static void ReturnFromBattleToOverworld(void);
|
|
|
|
static void TryEvolvePokemon(void);
|
|
|
|
static void WaitForEvoSceneToFinish(void);
|
2017-10-06 19:09:37 +02:00
|
|
|
static void HandleEndTurn_ContinueBattle(void);
|
|
|
|
static void HandleEndTurn_BattleWon(void);
|
|
|
|
static void HandleEndTurn_BattleLost(void);
|
|
|
|
static void HandleEndTurn_RanFromBattle(void);
|
|
|
|
static void HandleEndTurn_MonFled(void);
|
|
|
|
static void HandleEndTurn_FinishBattle(void);
|
|
|
|
static void HandleAction_UseMove(void);
|
|
|
|
static void HandleAction_Switch(void);
|
|
|
|
static void HandleAction_UseItem(void);
|
|
|
|
static void HandleAction_Run(void);
|
|
|
|
static void HandleAction_WatchesCarefully(void);
|
|
|
|
static void HandleAction_SafariZoneBallThrow(void);
|
|
|
|
static void HandleAction_ThrowPokeblock(void);
|
|
|
|
static void HandleAction_GoNear(void);
|
2018-11-22 02:10:50 +01:00
|
|
|
static void HandleAction_SafariZoneRun(void);
|
2018-06-20 23:07:51 +02:00
|
|
|
static void HandleAction_WallyBallThrow(void);
|
2019-02-02 11:32:00 +01:00
|
|
|
static void HandleAction_TryFinish(void);
|
2017-10-06 19:09:37 +02:00
|
|
|
static void HandleAction_NothingIsFainted(void);
|
|
|
|
static void HandleAction_ActionFinished(void);
|
|
|
|
|
2018-02-07 22:53:40 +01:00
|
|
|
// EWRAM vars
|
2018-11-19 17:36:39 +01:00
|
|
|
EWRAM_DATA u16 gBattle_BG0_X = 0;
|
|
|
|
EWRAM_DATA u16 gBattle_BG0_Y = 0;
|
|
|
|
EWRAM_DATA u16 gBattle_BG1_X = 0;
|
|
|
|
EWRAM_DATA u16 gBattle_BG1_Y = 0;
|
|
|
|
EWRAM_DATA u16 gBattle_BG2_X = 0;
|
|
|
|
EWRAM_DATA u16 gBattle_BG2_Y = 0;
|
|
|
|
EWRAM_DATA u16 gBattle_BG3_X = 0;
|
|
|
|
EWRAM_DATA u16 gBattle_BG3_Y = 0;
|
|
|
|
EWRAM_DATA u16 gBattle_WIN0H = 0;
|
|
|
|
EWRAM_DATA u16 gBattle_WIN0V = 0;
|
|
|
|
EWRAM_DATA u16 gBattle_WIN1H = 0;
|
|
|
|
EWRAM_DATA u16 gBattle_WIN1V = 0;
|
2018-12-01 11:12:31 +01:00
|
|
|
EWRAM_DATA u8 gDisplayedStringBattle[400] = {0};
|
2018-06-30 15:35:54 +02:00
|
|
|
EWRAM_DATA u8 gBattleTextBuff1[TEXT_BUFF_ARRAY_COUNT] = {0};
|
|
|
|
EWRAM_DATA u8 gBattleTextBuff2[TEXT_BUFF_ARRAY_COUNT] = {0};
|
|
|
|
EWRAM_DATA u8 gBattleTextBuff3[TEXT_BUFF_ARRAY_COUNT] = {0};
|
2018-02-07 22:53:40 +01:00
|
|
|
EWRAM_DATA u32 gBattleTypeFlags = 0;
|
|
|
|
EWRAM_DATA u8 gBattleTerrain = 0;
|
|
|
|
EWRAM_DATA u32 gUnknown_02022FF4 = 0;
|
2018-02-11 23:46:50 +01:00
|
|
|
EWRAM_DATA struct UnknownPokemonStruct4 gUnknown_02022FF8[3] = {0}; // what is it used for?
|
|
|
|
EWRAM_DATA struct UnknownPokemonStruct4* gUnknown_02023058 = NULL; // what is it used for?
|
2018-02-07 22:53:40 +01:00
|
|
|
EWRAM_DATA u8 *gUnknown_0202305C = NULL;
|
|
|
|
EWRAM_DATA u8 *gUnknown_02023060 = NULL;
|
|
|
|
EWRAM_DATA u8 gActiveBattler = 0;
|
|
|
|
EWRAM_DATA u32 gBattleControllerExecFlags = 0;
|
|
|
|
EWRAM_DATA u8 gBattlersCount = 0;
|
|
|
|
EWRAM_DATA u16 gBattlerPartyIndexes[MAX_BATTLERS_COUNT] = {0};
|
|
|
|
EWRAM_DATA u8 gBattlerPositions[MAX_BATTLERS_COUNT] = {0};
|
|
|
|
EWRAM_DATA u8 gActionsByTurnOrder[MAX_BATTLERS_COUNT] = {0};
|
2018-06-28 21:06:32 +02:00
|
|
|
EWRAM_DATA u8 gBattlerByTurnOrder[MAX_BATTLERS_COUNT] = {0};
|
2018-02-07 22:53:40 +01:00
|
|
|
EWRAM_DATA u8 gCurrentTurnActionNumber = 0;
|
|
|
|
EWRAM_DATA u8 gCurrentActionFuncId = 0;
|
|
|
|
EWRAM_DATA struct BattlePokemon gBattleMons[MAX_BATTLERS_COUNT] = {0};
|
|
|
|
EWRAM_DATA u8 gBattlerSpriteIds[MAX_BATTLERS_COUNT] = {0};
|
|
|
|
EWRAM_DATA u8 gCurrMovePos = 0;
|
2018-02-08 11:17:41 +01:00
|
|
|
EWRAM_DATA u8 gChosenMovePos = 0;
|
2018-02-07 22:53:40 +01:00
|
|
|
EWRAM_DATA u16 gCurrentMove = 0;
|
|
|
|
EWRAM_DATA u16 gChosenMove = 0;
|
2018-09-22 18:41:00 +02:00
|
|
|
EWRAM_DATA u16 gCalledMove = 0;
|
2018-02-07 22:53:40 +01:00
|
|
|
EWRAM_DATA s32 gBattleMoveDamage = 0;
|
|
|
|
EWRAM_DATA s32 gHpDealt = 0;
|
|
|
|
EWRAM_DATA s32 gTakenDmg[MAX_BATTLERS_COUNT] = {0};
|
|
|
|
EWRAM_DATA u16 gLastUsedItem = 0;
|
|
|
|
EWRAM_DATA u8 gLastUsedAbility = 0;
|
|
|
|
EWRAM_DATA u8 gBattlerAttacker = 0;
|
|
|
|
EWRAM_DATA u8 gBattlerTarget = 0;
|
2018-02-08 11:17:41 +01:00
|
|
|
EWRAM_DATA u8 gBattlerFainted = 0;
|
|
|
|
EWRAM_DATA u8 gEffectBattler = 0;
|
2018-02-08 12:13:29 +01:00
|
|
|
EWRAM_DATA u8 gPotentialItemEffectBattler = 0;
|
2018-02-07 22:53:40 +01:00
|
|
|
EWRAM_DATA u8 gAbsentBattlerFlags = 0;
|
2018-07-14 22:56:03 +02:00
|
|
|
EWRAM_DATA u8 gIsCriticalHit = FALSE;
|
2018-02-07 22:53:40 +01:00
|
|
|
EWRAM_DATA u8 gMultiHitCounter = 0;
|
|
|
|
EWRAM_DATA const u8 *gBattlescriptCurrInstr = NULL;
|
|
|
|
EWRAM_DATA u8 gChosenActionByBattler[MAX_BATTLERS_COUNT] = {0};
|
|
|
|
EWRAM_DATA const u8 *gSelectionBattleScripts[MAX_BATTLERS_COUNT] = {NULL};
|
|
|
|
EWRAM_DATA const u8 *gPalaceSelectionBattleScripts[MAX_BATTLERS_COUNT] = {NULL};
|
|
|
|
EWRAM_DATA u16 gLastPrintedMoves[MAX_BATTLERS_COUNT] = {0};
|
|
|
|
EWRAM_DATA u16 gLastMoves[MAX_BATTLERS_COUNT] = {0};
|
|
|
|
EWRAM_DATA u16 gLastLandedMoves[MAX_BATTLERS_COUNT] = {0};
|
|
|
|
EWRAM_DATA u16 gLastHitByType[MAX_BATTLERS_COUNT] = {0};
|
|
|
|
EWRAM_DATA u16 gLastResultingMoves[MAX_BATTLERS_COUNT] = {0};
|
|
|
|
EWRAM_DATA u16 gLockedMoves[MAX_BATTLERS_COUNT] = {0};
|
2018-09-22 18:37:03 +02:00
|
|
|
EWRAM_DATA u16 gLastUsedMove = 0;
|
2018-02-07 22:53:40 +01:00
|
|
|
EWRAM_DATA u8 gLastHitBy[MAX_BATTLERS_COUNT] = {0};
|
|
|
|
EWRAM_DATA u16 gChosenMoveByBattler[MAX_BATTLERS_COUNT] = {0};
|
2018-07-21 15:11:13 +02:00
|
|
|
EWRAM_DATA u16 gMoveResultFlags = 0;
|
2018-02-07 22:53:40 +01:00
|
|
|
EWRAM_DATA u32 gHitMarker = 0;
|
|
|
|
EWRAM_DATA u8 gTakenDmgByBattler[MAX_BATTLERS_COUNT] = {0};
|
|
|
|
EWRAM_DATA u8 gUnknown_0202428C = 0;
|
2018-07-24 20:13:02 +02:00
|
|
|
EWRAM_DATA u32 gSideStatuses[2] = {0};
|
2018-02-07 22:53:40 +01:00
|
|
|
EWRAM_DATA struct SideTimer gSideTimers[2] = {0};
|
|
|
|
EWRAM_DATA u32 gStatuses3[MAX_BATTLERS_COUNT] = {0};
|
|
|
|
EWRAM_DATA struct DisableStruct gDisableStructs[MAX_BATTLERS_COUNT] = {0};
|
|
|
|
EWRAM_DATA u16 gPauseCounterBattle = 0;
|
|
|
|
EWRAM_DATA u16 gPaydayMoney = 0;
|
|
|
|
EWRAM_DATA u16 gRandomTurnNumber = 0;
|
|
|
|
EWRAM_DATA u8 gBattleCommunication[BATTLE_COMMUNICATION_ENTRIES_COUNT] = {0};
|
|
|
|
EWRAM_DATA u8 gBattleOutcome = 0;
|
|
|
|
EWRAM_DATA struct ProtectStruct gProtectStructs[MAX_BATTLERS_COUNT] = {0};
|
|
|
|
EWRAM_DATA struct SpecialStatus gSpecialStatuses[MAX_BATTLERS_COUNT] = {0};
|
|
|
|
EWRAM_DATA u16 gBattleWeather = 0;
|
|
|
|
EWRAM_DATA struct WishFutureKnock gWishFutureKnock = {0};
|
2018-02-08 11:17:41 +01:00
|
|
|
EWRAM_DATA u16 gIntroSlideFlags = 0;
|
2018-02-07 22:53:40 +01:00
|
|
|
EWRAM_DATA u8 gSentPokesToOpponent[2] = {0};
|
|
|
|
EWRAM_DATA u16 gExpShareExp = 0;
|
|
|
|
EWRAM_DATA struct BattleEnigmaBerry gEnigmaBerries[MAX_BATTLERS_COUNT] = {0};
|
|
|
|
EWRAM_DATA struct BattleScripting gBattleScripting = {0};
|
|
|
|
EWRAM_DATA struct BattleStruct *gBattleStruct = NULL;
|
|
|
|
EWRAM_DATA u8 *gLinkBattleSendBuffer = NULL;
|
|
|
|
EWRAM_DATA u8 *gLinkBattleRecvBuffer = NULL;
|
|
|
|
EWRAM_DATA struct BattleResources *gBattleResources = NULL;
|
|
|
|
EWRAM_DATA u8 gActionSelectionCursor[MAX_BATTLERS_COUNT] = {0};
|
|
|
|
EWRAM_DATA u8 gMoveSelectionCursor[MAX_BATTLERS_COUNT] = {0};
|
2018-02-08 11:17:41 +01:00
|
|
|
EWRAM_DATA u8 gBattlerStatusSummaryTaskId[MAX_BATTLERS_COUNT] = {0};
|
2018-02-07 22:53:40 +01:00
|
|
|
EWRAM_DATA u8 gBattlerInMenuId = 0;
|
|
|
|
EWRAM_DATA bool8 gDoingBattleAnim = FALSE;
|
|
|
|
EWRAM_DATA u32 gTransformedPersonalities[MAX_BATTLERS_COUNT] = {0};
|
|
|
|
EWRAM_DATA u8 gPlayerDpadHoldFrames = 0;
|
|
|
|
EWRAM_DATA struct BattleSpriteData *gBattleSpritesDataPtr = NULL;
|
|
|
|
EWRAM_DATA struct MonSpritesGfx *gMonSpritesGfxPtr = NULL;
|
2018-02-08 00:00:25 +01:00
|
|
|
EWRAM_DATA struct BattleHealthboxInfo *gUnknown_020244D8 = NULL;
|
|
|
|
EWRAM_DATA struct BattleHealthboxInfo *gUnknown_020244DC = NULL;
|
2018-02-07 22:53:40 +01:00
|
|
|
EWRAM_DATA u16 gBattleMovePower = 0;
|
|
|
|
EWRAM_DATA u16 gMoveToLearn = 0;
|
|
|
|
EWRAM_DATA u8 gBattleMonForms[MAX_BATTLERS_COUNT] = {0};
|
2018-07-14 13:17:10 +02:00
|
|
|
EWRAM_DATA u32 gFieldStatuses = 0;
|
|
|
|
EWRAM_DATA struct FieldTimer gFieldTimers = {0};
|
2018-09-29 13:36:33 +02:00
|
|
|
EWRAM_DATA u8 gBattlerAbility = 0;
|
2018-11-24 01:02:02 +01:00
|
|
|
EWRAM_DATA u16 gPartnerSpriteId = 0;
|
2018-02-07 22:53:40 +01:00
|
|
|
|
2018-02-07 23:21:51 +01:00
|
|
|
// IWRAM common vars
|
|
|
|
void (*gPreBattleCallback1)(void);
|
|
|
|
void (*gBattleMainFunc)(void);
|
|
|
|
struct BattleResults gBattleResults;
|
|
|
|
u8 gLeveledUpInBattle;
|
|
|
|
void (*gBattlerControllerFuncs[MAX_BATTLERS_COUNT])(void);
|
|
|
|
u8 gHealthboxSpriteIds[MAX_BATTLERS_COUNT];
|
|
|
|
u8 gMultiUsePlayerCursor;
|
|
|
|
u8 gNumberOfMovesToChoose;
|
|
|
|
u8 gUnknown_03005D7C[MAX_BATTLERS_COUNT];
|
|
|
|
|
2017-10-06 19:09:37 +02:00
|
|
|
// rom const data
|
2018-12-23 14:52:47 +01:00
|
|
|
static const struct ScanlineEffectParams sIntroScanlineParams16Bit =
|
|
|
|
{
|
|
|
|
(void *)REG_ADDR_BG3HOFS, SCANLINE_EFFECT_DMACNT_16BIT, 1
|
|
|
|
};
|
|
|
|
|
|
|
|
// unused
|
|
|
|
static const struct ScanlineEffectParams sIntroScanlineParams32Bit =
|
|
|
|
{
|
|
|
|
(void *)REG_ADDR_BG3HOFS, SCANLINE_EFFECT_DMACNT_32BIT, 1
|
|
|
|
};
|
|
|
|
|
|
|
|
const struct SpriteTemplate gUnknown_0831AC88 =
|
|
|
|
{
|
|
|
|
.tileTag = 0,
|
|
|
|
.paletteTag = 0,
|
|
|
|
.oam = &gDummyOamData,
|
|
|
|
.anims = gDummySpriteAnimTable,
|
|
|
|
.images = NULL,
|
|
|
|
.affineAnims = gDummySpriteAffineAnimTable,
|
|
|
|
.callback = sub_8038528,
|
|
|
|
};
|
|
|
|
|
|
|
|
static const u8 sText_ShedinjaJpnName[] = _("ヌケニン"); // Nukenin
|
|
|
|
|
|
|
|
const struct OamData gOamData_831ACA8 =
|
|
|
|
{
|
|
|
|
.y = 0,
|
2019-04-02 00:31:10 +02:00
|
|
|
.affineMode = ST_OAM_AFFINE_NORMAL,
|
|
|
|
.objMode = ST_OAM_OBJ_NORMAL,
|
|
|
|
.bpp = ST_OAM_4BPP,
|
2019-03-11 08:12:15 +01:00
|
|
|
.shape = SPRITE_SHAPE(64x64),
|
2018-12-23 14:52:47 +01:00
|
|
|
.x = 0,
|
2019-03-11 08:12:15 +01:00
|
|
|
.size = SPRITE_SIZE(64x64),
|
2018-12-23 14:52:47 +01:00
|
|
|
.tileNum = 0,
|
|
|
|
.priority = 2,
|
|
|
|
.paletteNum = 0,
|
2019-04-02 00:31:10 +02:00
|
|
|
.affineParam = 0,
|
2018-12-23 14:52:47 +01:00
|
|
|
};
|
|
|
|
|
|
|
|
const struct OamData gOamData_831ACB0 =
|
|
|
|
{
|
|
|
|
.y = 0,
|
2019-04-02 00:31:10 +02:00
|
|
|
.affineMode = ST_OAM_AFFINE_NORMAL,
|
|
|
|
.objMode = ST_OAM_OBJ_NORMAL,
|
|
|
|
.bpp = ST_OAM_4BPP,
|
2019-03-11 08:12:15 +01:00
|
|
|
.shape = SPRITE_SHAPE(64x64),
|
2018-12-23 14:52:47 +01:00
|
|
|
.x = 0,
|
2019-03-11 08:12:15 +01:00
|
|
|
.size = SPRITE_SIZE(64x64),
|
2018-12-23 14:52:47 +01:00
|
|
|
.tileNum = 0,
|
|
|
|
.priority = 2,
|
|
|
|
.paletteNum = 2,
|
2019-04-02 00:31:10 +02:00
|
|
|
.affineParam = 0,
|
2018-12-23 14:52:47 +01:00
|
|
|
};
|
2018-12-23 13:52:53 +01:00
|
|
|
|
2018-07-01 15:28:57 +02:00
|
|
|
static const s8 gUnknown_0831ACE0[] ={-32, -16, -16, -32, -32, 0, 0, 0};
|
2018-02-26 14:29:17 +01:00
|
|
|
|
|
|
|
const u8 gTypeNames[][TYPE_NAME_LENGTH + 1] =
|
|
|
|
{
|
|
|
|
_("NORMAL"),
|
|
|
|
_("FIGHT"),
|
|
|
|
_("FLYING"),
|
|
|
|
_("POISON"),
|
|
|
|
_("GROUND"),
|
|
|
|
_("ROCK"),
|
|
|
|
_("BUG"),
|
|
|
|
_("GHOST"),
|
|
|
|
_("STEEL"),
|
|
|
|
_("???"),
|
|
|
|
_("FIRE"),
|
|
|
|
_("WATER"),
|
|
|
|
_("GRASS"),
|
|
|
|
_("ELECTR"),
|
|
|
|
_("PSYCHC"),
|
|
|
|
_("ICE"),
|
|
|
|
_("DRAGON"),
|
|
|
|
_("DARK"),
|
2018-07-14 10:57:34 +02:00
|
|
|
_("FAIRY"),
|
2018-02-26 14:29:17 +01:00
|
|
|
};
|
|
|
|
|
|
|
|
// This is a factor in how much money you get for beating a trainer.
|
|
|
|
const struct TrainerMoney gTrainerMoneyTable[] =
|
|
|
|
{
|
|
|
|
{TRAINER_CLASS_TEAM_AQUA, 5},
|
|
|
|
{TRAINER_CLASS_AQUA_ADMIN, 10},
|
|
|
|
{TRAINER_CLASS_AQUA_LEADER, 20},
|
|
|
|
{TRAINER_CLASS_AROMA_LADY, 10},
|
|
|
|
{TRAINER_CLASS_RUIN_MANIAC, 15},
|
|
|
|
{TRAINER_CLASS_INTERVIEWER, 12},
|
2018-12-03 04:35:11 +01:00
|
|
|
{TRAINER_CLASS_TUBER_F, 1},
|
|
|
|
{TRAINER_CLASS_TUBER_M, 1},
|
2018-02-26 14:29:17 +01:00
|
|
|
{TRAINER_CLASS_SIS_AND_BRO, 3},
|
2018-12-03 04:35:11 +01:00
|
|
|
{TRAINER_CLASS_COOLTRAINER, 12},
|
2018-02-26 14:29:17 +01:00
|
|
|
{TRAINER_CLASS_HEX_MANIAC, 6},
|
|
|
|
{TRAINER_CLASS_LADY, 50},
|
|
|
|
{TRAINER_CLASS_BEAUTY, 20},
|
|
|
|
{TRAINER_CLASS_RICH_BOY, 50},
|
|
|
|
{TRAINER_CLASS_POKEMANIAC, 15},
|
|
|
|
{TRAINER_CLASS_SWIMMER_M, 2},
|
|
|
|
{TRAINER_CLASS_BLACK_BELT, 8},
|
|
|
|
{TRAINER_CLASS_GUITARIST, 8},
|
|
|
|
{TRAINER_CLASS_KINDLER, 8},
|
|
|
|
{TRAINER_CLASS_CAMPER, 4},
|
|
|
|
{TRAINER_CLASS_OLD_COUPLE, 10},
|
|
|
|
{TRAINER_CLASS_BUG_MANIAC, 15},
|
|
|
|
{TRAINER_CLASS_PSYCHIC, 6},
|
|
|
|
{TRAINER_CLASS_GENTLEMAN, 20},
|
|
|
|
{TRAINER_CLASS_ELITE_FOUR, 25},
|
|
|
|
{TRAINER_CLASS_LEADER, 25},
|
|
|
|
{TRAINER_CLASS_SCHOOL_KID, 5},
|
|
|
|
{TRAINER_CLASS_SR_AND_JR, 4},
|
|
|
|
{TRAINER_CLASS_POKEFAN, 20},
|
|
|
|
{TRAINER_CLASS_EXPERT, 10},
|
|
|
|
{TRAINER_CLASS_YOUNGSTER, 4},
|
|
|
|
{TRAINER_CLASS_CHAMPION, 50},
|
|
|
|
{TRAINER_CLASS_FISHERMAN, 10},
|
|
|
|
{TRAINER_CLASS_TRIATHLETE, 10},
|
|
|
|
{TRAINER_CLASS_DRAGON_TAMER, 12},
|
|
|
|
{TRAINER_CLASS_BIRD_KEEPER, 8},
|
|
|
|
{TRAINER_CLASS_NINJA_BOY, 3},
|
|
|
|
{TRAINER_CLASS_BATTLE_GIRL, 6},
|
|
|
|
{TRAINER_CLASS_PARASOL_LADY, 10},
|
|
|
|
{TRAINER_CLASS_SWIMMER_F, 2},
|
|
|
|
{TRAINER_CLASS_PICNICKER, 4},
|
|
|
|
{TRAINER_CLASS_TWINS, 3},
|
|
|
|
{TRAINER_CLASS_SAILOR, 8},
|
|
|
|
{TRAINER_CLASS_COLLECTOR, 15},
|
|
|
|
{TRAINER_CLASS_PKMN_TRAINER_3, 15},
|
|
|
|
{TRAINER_CLASS_PKMN_BREEDER, 10},
|
|
|
|
{TRAINER_CLASS_PKMN_RANGER, 12},
|
|
|
|
{TRAINER_CLASS_TEAM_MAGMA, 5},
|
|
|
|
{TRAINER_CLASS_MAGMA_ADMIN, 10},
|
|
|
|
{TRAINER_CLASS_MAGMA_LEADER, 20},
|
|
|
|
{TRAINER_CLASS_LASS, 4},
|
|
|
|
{TRAINER_CLASS_BUG_CATCHER, 4},
|
|
|
|
{TRAINER_CLASS_HIKER, 10},
|
|
|
|
{TRAINER_CLASS_YOUNG_COUPLE, 8},
|
|
|
|
{TRAINER_CLASS_WINSTRATE, 10},
|
|
|
|
{0xFF, 5},
|
|
|
|
};
|
|
|
|
|
|
|
|
#include "data/text/abilities.h"
|
|
|
|
|
2017-10-06 19:09:37 +02:00
|
|
|
static void (* const sTurnActionsFuncsTable[])(void) =
|
|
|
|
{
|
2018-12-08 07:10:30 +01:00
|
|
|
[B_ACTION_USE_MOVE] = HandleAction_UseMove,
|
|
|
|
[B_ACTION_USE_ITEM] = HandleAction_UseItem,
|
|
|
|
[B_ACTION_SWITCH] = HandleAction_Switch,
|
|
|
|
[B_ACTION_RUN] = HandleAction_Run,
|
|
|
|
[B_ACTION_SAFARI_WATCH_CAREFULLY] = HandleAction_WatchesCarefully,
|
|
|
|
[B_ACTION_SAFARI_BALL] = HandleAction_SafariZoneBallThrow,
|
|
|
|
[B_ACTION_SAFARI_POKEBLOCK] = HandleAction_ThrowPokeblock,
|
|
|
|
[B_ACTION_SAFARI_GO_NEAR] = HandleAction_GoNear,
|
|
|
|
[B_ACTION_SAFARI_RUN] = HandleAction_SafariZoneRun,
|
|
|
|
[B_ACTION_WALLY_THROW] = HandleAction_WallyBallThrow,
|
|
|
|
[B_ACTION_EXEC_SCRIPT] = HandleAction_RunBattleScript,
|
2019-02-02 11:32:00 +01:00
|
|
|
[B_ACTION_TRY_FINISH] = HandleAction_TryFinish,
|
2018-12-08 07:10:30 +01:00
|
|
|
[B_ACTION_FINISHED] = HandleAction_ActionFinished,
|
|
|
|
[B_ACTION_NOTHING_FAINTED] = HandleAction_NothingIsFainted,
|
2017-10-06 19:09:37 +02:00
|
|
|
};
|
|
|
|
|
|
|
|
static void (* const sEndTurnFuncsTable[])(void) =
|
|
|
|
{
|
2018-12-08 07:10:30 +01:00
|
|
|
[0] = HandleEndTurn_ContinueBattle, //B_OUTCOME_NONE?
|
|
|
|
[B_OUTCOME_WON] = HandleEndTurn_BattleWon,
|
|
|
|
[B_OUTCOME_LOST] = HandleEndTurn_BattleLost,
|
|
|
|
[B_OUTCOME_DREW] = HandleEndTurn_BattleLost,
|
|
|
|
[B_OUTCOME_RAN] = HandleEndTurn_RanFromBattle,
|
|
|
|
[B_OUTCOME_PLAYER_TELEPORTED] = HandleEndTurn_FinishBattle,
|
|
|
|
[B_OUTCOME_MON_FLED] = HandleEndTurn_MonFled,
|
|
|
|
[B_OUTCOME_CAUGHT] = HandleEndTurn_FinishBattle,
|
|
|
|
[B_OUTCOME_NO_SAFARI_BALLS] = HandleEndTurn_FinishBattle,
|
|
|
|
[B_OUTCOME_FORFEITED] = HandleEndTurn_FinishBattle,
|
|
|
|
[B_OUTCOME_MON_TELEPORTED] = HandleEndTurn_FinishBattle,
|
2017-10-06 19:09:37 +02:00
|
|
|
};
|
|
|
|
|
|
|
|
const u8 gStatusConditionString_PoisonJpn[8] = _("どく$$$$$");
|
|
|
|
const u8 gStatusConditionString_SleepJpn[8] = _("ねむり$$$$");
|
|
|
|
const u8 gStatusConditionString_ParalysisJpn[8] = _("まひ$$$$$");
|
|
|
|
const u8 gStatusConditionString_BurnJpn[8] = _("やけど$$$$");
|
|
|
|
const u8 gStatusConditionString_IceJpn[8] = _("こおり$$$$");
|
|
|
|
const u8 gStatusConditionString_ConfusionJpn[8] = _("こんらん$$$");
|
|
|
|
const u8 gStatusConditionString_LoveJpn[8] = _("メロメロ$$$");
|
|
|
|
|
2017-10-07 19:59:41 +02:00
|
|
|
const u8 * const gStatusConditionStringsTable[7][2] =
|
2017-10-06 19:09:37 +02:00
|
|
|
{
|
|
|
|
{gStatusConditionString_PoisonJpn, gText_Poison},
|
|
|
|
{gStatusConditionString_SleepJpn, gText_Sleep},
|
|
|
|
{gStatusConditionString_ParalysisJpn, gText_Paralysis},
|
|
|
|
{gStatusConditionString_BurnJpn, gText_Burn},
|
|
|
|
{gStatusConditionString_IceJpn, gText_Ice},
|
|
|
|
{gStatusConditionString_ConfusionJpn, gText_Confusion},
|
|
|
|
{gStatusConditionString_LoveJpn, gText_Love}
|
|
|
|
};
|
|
|
|
|
2018-07-01 11:15:42 +02:00
|
|
|
static const u8 sPkblToEscapeFactor[][3] = {{0, 0, 0}, {3, 5, 0}, {2, 3, 0}, {1, 2, 0}, {1, 1, 0}};
|
|
|
|
static const u8 sGoNearCounterToCatchFactor[] = {4, 3, 2, 1};
|
|
|
|
static const u8 sGoNearCounterToEscapeFactor[] = {4, 4, 4, 4};
|
2017-10-01 01:12:42 +02:00
|
|
|
|
2018-06-30 14:12:17 +02:00
|
|
|
// code
|
2017-10-01 01:12:42 +02:00
|
|
|
void CB2_InitBattle(void)
|
|
|
|
{
|
|
|
|
MoveSaveBlocks_ResetHeap();
|
2017-11-12 16:39:21 +01:00
|
|
|
AllocateBattleResources();
|
2017-10-01 01:12:42 +02:00
|
|
|
AllocateBattleSpritesData();
|
|
|
|
AllocateMonSpritesGfx();
|
|
|
|
sub_8185F84();
|
|
|
|
|
|
|
|
if (gBattleTypeFlags & BATTLE_TYPE_MULTI)
|
|
|
|
{
|
|
|
|
if (gBattleTypeFlags & BATTLE_TYPE_RECORDED)
|
|
|
|
{
|
|
|
|
CB2_InitBattleInternal();
|
|
|
|
}
|
|
|
|
else if (!(gBattleTypeFlags & BATTLE_TYPE_INGAME_PARTNER))
|
|
|
|
{
|
|
|
|
HandleLinkBattleSetup();
|
|
|
|
SetMainCallback2(CB2_PreInitMultiBattle);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
SetMainCallback2(CB2_PreInitIngamePlayerPartnerBattle);
|
|
|
|
}
|
|
|
|
gBattleCommunication[MULTIUSE_STATE] = 0;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
CB2_InitBattleInternal();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static void CB2_InitBattleInternal(void)
|
|
|
|
{
|
|
|
|
s32 i;
|
|
|
|
|
|
|
|
SetHBlankCallback(NULL);
|
|
|
|
SetVBlankCallback(NULL);
|
|
|
|
|
2017-10-01 18:54:01 +02:00
|
|
|
CpuFill32(0, (void*)(VRAM), VRAM_SIZE);
|
2017-10-01 01:12:42 +02:00
|
|
|
|
|
|
|
SetGpuReg(REG_OFFSET_MOSAIC, 0);
|
|
|
|
SetGpuReg(REG_OFFSET_WIN0H, 240);
|
|
|
|
SetGpuReg(REG_OFFSET_WIN0V, 0x5051);
|
|
|
|
SetGpuReg(REG_OFFSET_WININ, 0);
|
|
|
|
SetGpuReg(REG_OFFSET_WINOUT, 0);
|
|
|
|
|
|
|
|
gBattle_WIN0H = 240;
|
|
|
|
|
2018-11-24 01:02:02 +01:00
|
|
|
if (gBattleTypeFlags & BATTLE_TYPE_INGAME_PARTNER && gPartnerTrainerId != TRAINER_STEVEN_PARTNER && gPartnerTrainerId < TRAINER_CUSTOM_PARTNER)
|
2017-10-01 01:12:42 +02:00
|
|
|
{
|
|
|
|
gBattle_WIN0V = 159;
|
|
|
|
gBattle_WIN1H = 240;
|
|
|
|
gBattle_WIN1V = 32;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
gBattle_WIN0V = 0x5051;
|
2018-01-29 17:47:12 +01:00
|
|
|
ScanlineEffect_Clear();
|
2017-10-01 01:12:42 +02:00
|
|
|
|
2019-01-05 19:25:46 +01:00
|
|
|
i = 0;
|
|
|
|
while (i < 80)
|
2017-10-01 01:12:42 +02:00
|
|
|
{
|
2018-01-29 17:47:12 +01:00
|
|
|
gScanlineEffectRegBuffers[0][i] = 0xF0;
|
|
|
|
gScanlineEffectRegBuffers[1][i] = 0xF0;
|
2019-01-05 19:25:46 +01:00
|
|
|
i++;
|
2017-10-01 01:12:42 +02:00
|
|
|
}
|
2019-01-05 19:25:46 +01:00
|
|
|
|
|
|
|
while (i < 160)
|
2017-10-01 01:12:42 +02:00
|
|
|
{
|
2018-01-29 17:47:12 +01:00
|
|
|
gScanlineEffectRegBuffers[0][i] = 0xFF10;
|
|
|
|
gScanlineEffectRegBuffers[1][i] = 0xFF10;
|
2019-01-05 19:25:46 +01:00
|
|
|
i++;
|
2017-10-01 01:12:42 +02:00
|
|
|
}
|
|
|
|
|
2018-12-23 14:52:47 +01:00
|
|
|
ScanlineEffect_SetParams(sIntroScanlineParams16Bit);
|
2017-10-01 01:12:42 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
ResetPaletteFade();
|
|
|
|
gBattle_BG0_X = 0;
|
|
|
|
gBattle_BG0_Y = 0;
|
|
|
|
gBattle_BG1_X = 0;
|
|
|
|
gBattle_BG1_Y = 0;
|
|
|
|
gBattle_BG2_X = 0;
|
|
|
|
gBattle_BG2_Y = 0;
|
|
|
|
gBattle_BG3_X = 0;
|
|
|
|
gBattle_BG3_Y = 0;
|
|
|
|
|
|
|
|
gBattleTerrain = BattleSetup_GetTerrainId();
|
|
|
|
if (gBattleTypeFlags & BATTLE_TYPE_RECORDED)
|
2017-12-16 01:08:55 +01:00
|
|
|
gBattleTerrain = BATTLE_TERRAIN_BUILDING;
|
2017-10-01 01:12:42 +02:00
|
|
|
|
2017-10-01 18:54:01 +02:00
|
|
|
sub_80356D0();
|
2017-10-01 01:12:42 +02:00
|
|
|
LoadBattleTextboxAndBackground();
|
|
|
|
ResetSpriteData();
|
|
|
|
ResetTasks();
|
2018-06-17 16:48:58 +02:00
|
|
|
DrawBattleEntryBackground();
|
2017-10-01 01:12:42 +02:00
|
|
|
FreeAllSpritePalettes();
|
|
|
|
gReservedSpritePaletteCount = 4;
|
|
|
|
SetVBlankCallback(VBlankCB_Battle);
|
|
|
|
SetUpBattleVarsAndBirchZigzagoon();
|
|
|
|
|
|
|
|
if (gBattleTypeFlags & BATTLE_TYPE_MULTI && gBattleTypeFlags & BATTLE_TYPE_BATTLE_TOWER)
|
|
|
|
SetMainCallback2(CB2_HandleStartMultiPartnerBattle);
|
|
|
|
else if (gBattleTypeFlags & BATTLE_TYPE_MULTI && gBattleTypeFlags & BATTLE_TYPE_INGAME_PARTNER)
|
|
|
|
SetMainCallback2(CB2_HandleStartMultiPartnerBattle);
|
|
|
|
else if (gBattleTypeFlags & BATTLE_TYPE_MULTI)
|
|
|
|
SetMainCallback2(CB2_HandleStartMultiBattle);
|
|
|
|
else
|
|
|
|
SetMainCallback2(CB2_HandleStartBattle);
|
|
|
|
|
|
|
|
if (!(gBattleTypeFlags & (BATTLE_TYPE_LINK | BATTLE_TYPE_RECORDED)))
|
|
|
|
{
|
|
|
|
CreateNPCTrainerParty(&gEnemyParty[0], gTrainerBattleOpponent_A, TRUE);
|
2019-01-27 20:54:34 +01:00
|
|
|
if (gBattleTypeFlags & BATTLE_TYPE_TWO_OPPONENTS && !BATTLE_TWO_VS_ONE_OPPONENT)
|
2017-10-01 01:12:42 +02:00
|
|
|
CreateNPCTrainerParty(&gEnemyParty[3], gTrainerBattleOpponent_B, FALSE);
|
|
|
|
SetWildMonHeldItem();
|
|
|
|
}
|
|
|
|
|
|
|
|
gMain.inBattle = TRUE;
|
2018-06-17 12:30:09 +02:00
|
|
|
gSaveBlock2Ptr->frontier.field_CA9_b = 0;
|
2017-10-01 01:12:42 +02:00
|
|
|
|
2018-06-20 23:07:51 +02:00
|
|
|
for (i = 0; i < PARTY_SIZE; i++)
|
2017-10-01 01:12:42 +02:00
|
|
|
AdjustFriendship(&gPlayerParty[i], 3);
|
|
|
|
|
|
|
|
gBattleCommunication[MULTIUSE_STATE] = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void sub_8036A5C(void)
|
|
|
|
{
|
|
|
|
u16 r6 = 0;
|
|
|
|
u16 species = 0;
|
|
|
|
u16 hp = 0;
|
|
|
|
u32 status = 0;
|
|
|
|
s32 i;
|
|
|
|
|
2017-11-26 13:26:58 +01:00
|
|
|
for (i = 0; i < PARTY_SIZE; i++)
|
2017-10-01 01:12:42 +02:00
|
|
|
{
|
|
|
|
species = GetMonData(&gPlayerParty[i], MON_DATA_SPECIES2);
|
|
|
|
hp = GetMonData(&gPlayerParty[i], MON_DATA_HP);
|
|
|
|
status = GetMonData(&gPlayerParty[i], MON_DATA_STATUS);
|
|
|
|
|
|
|
|
if (species == SPECIES_NONE)
|
|
|
|
continue;
|
|
|
|
if (species != SPECIES_EGG && hp != 0 && status == 0)
|
|
|
|
r6 |= 1 << i * 2;
|
|
|
|
|
|
|
|
if (species == SPECIES_NONE)
|
|
|
|
continue;
|
|
|
|
if (hp != 0 && (species == SPECIES_EGG || status != 0))
|
|
|
|
r6 |= 2 << i * 2;
|
|
|
|
|
|
|
|
if (species == SPECIES_NONE)
|
|
|
|
continue;
|
|
|
|
if (species != SPECIES_EGG && hp == 0)
|
|
|
|
r6 |= 3 << i * 2;
|
|
|
|
}
|
|
|
|
|
|
|
|
gBattleStruct->field_182 = r6;
|
|
|
|
*(&gBattleStruct->field_183) = r6 >> 8;
|
2017-11-08 22:20:10 +01:00
|
|
|
gBattleStruct->field_183 |= FlagGet(FLAG_SYS_FRONTIER_PASS) << 7;
|
2017-10-01 01:12:42 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
static void SetPlayerBerryDataInBattleStruct(void)
|
|
|
|
{
|
|
|
|
s32 i;
|
|
|
|
struct BattleStruct *battleStruct = gBattleStruct;
|
|
|
|
struct BattleEnigmaBerry *battleBerry = &battleStruct->battleEnigmaBerry;
|
|
|
|
|
|
|
|
if (IsEnigmaBerryValid() == TRUE)
|
|
|
|
{
|
2018-09-01 22:03:21 +02:00
|
|
|
for (i = 0; i < BERRY_NAME_LENGTH; i++)
|
2017-10-01 01:12:42 +02:00
|
|
|
battleBerry->name[i] = gSaveBlock1Ptr->enigmaBerry.berry.name[i];
|
|
|
|
battleBerry->name[i] = EOS;
|
|
|
|
|
|
|
|
for (i = 0; i < BERRY_ITEM_EFFECT_COUNT; i++)
|
|
|
|
battleBerry->itemEffect[i] = gSaveBlock1Ptr->enigmaBerry.itemEffect[i];
|
|
|
|
|
|
|
|
battleBerry->holdEffect = gSaveBlock1Ptr->enigmaBerry.holdEffect;
|
|
|
|
battleBerry->holdEffectParam = gSaveBlock1Ptr->enigmaBerry.holdEffectParam;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2018-06-20 23:07:51 +02:00
|
|
|
const struct Berry *berryData = GetBerryInfo(ItemIdToBerryType(ITEM_ENIGMA_BERRY));
|
2017-10-01 01:12:42 +02:00
|
|
|
|
2018-09-01 22:03:21 +02:00
|
|
|
for (i = 0; i < BERRY_NAME_LENGTH; i++)
|
2017-10-01 01:12:42 +02:00
|
|
|
battleBerry->name[i] = berryData->name[i];
|
|
|
|
battleBerry->name[i] = EOS;
|
|
|
|
|
|
|
|
for (i = 0; i < BERRY_ITEM_EFFECT_COUNT; i++)
|
|
|
|
battleBerry->itemEffect[i] = 0;
|
|
|
|
|
|
|
|
battleBerry->holdEffect = HOLD_EFFECT_NONE;
|
|
|
|
battleBerry->holdEffectParam = 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static void SetAllPlayersBerryData(void)
|
|
|
|
{
|
|
|
|
s32 i;
|
|
|
|
s32 j;
|
|
|
|
|
|
|
|
if (!(gBattleTypeFlags & BATTLE_TYPE_LINK))
|
|
|
|
{
|
|
|
|
if (IsEnigmaBerryValid() == TRUE)
|
|
|
|
{
|
2018-09-01 22:03:21 +02:00
|
|
|
for (i = 0; i < BERRY_NAME_LENGTH; i++)
|
2017-10-01 01:12:42 +02:00
|
|
|
{
|
|
|
|
gEnigmaBerries[0].name[i] = gSaveBlock1Ptr->enigmaBerry.berry.name[i];
|
|
|
|
gEnigmaBerries[2].name[i] = gSaveBlock1Ptr->enigmaBerry.berry.name[i];
|
|
|
|
}
|
|
|
|
gEnigmaBerries[0].name[i] = EOS;
|
|
|
|
gEnigmaBerries[2].name[i] = EOS;
|
|
|
|
|
|
|
|
for (i = 0; i < BERRY_ITEM_EFFECT_COUNT; i++)
|
|
|
|
{
|
|
|
|
gEnigmaBerries[0].itemEffect[i] = gSaveBlock1Ptr->enigmaBerry.itemEffect[i];
|
|
|
|
gEnigmaBerries[2].itemEffect[i] = gSaveBlock1Ptr->enigmaBerry.itemEffect[i];
|
|
|
|
}
|
|
|
|
|
|
|
|
gEnigmaBerries[0].holdEffect = gSaveBlock1Ptr->enigmaBerry.holdEffect;
|
|
|
|
gEnigmaBerries[2].holdEffect = gSaveBlock1Ptr->enigmaBerry.holdEffect;
|
|
|
|
gEnigmaBerries[0].holdEffectParam = gSaveBlock1Ptr->enigmaBerry.holdEffectParam;
|
|
|
|
gEnigmaBerries[2].holdEffectParam = gSaveBlock1Ptr->enigmaBerry.holdEffectParam;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2018-06-20 23:07:51 +02:00
|
|
|
const struct Berry *berryData = GetBerryInfo(ItemIdToBerryType(ITEM_ENIGMA_BERRY));
|
2017-10-01 01:12:42 +02:00
|
|
|
|
2018-09-01 22:03:21 +02:00
|
|
|
for (i = 0; i < BERRY_NAME_LENGTH; i++)
|
2017-10-01 01:12:42 +02:00
|
|
|
{
|
|
|
|
gEnigmaBerries[0].name[i] = berryData->name[i];
|
|
|
|
gEnigmaBerries[2].name[i] = berryData->name[i];
|
|
|
|
}
|
|
|
|
gEnigmaBerries[0].name[i] = EOS;
|
|
|
|
gEnigmaBerries[2].name[i] = EOS;
|
|
|
|
|
|
|
|
for (i = 0; i < BERRY_ITEM_EFFECT_COUNT; i++)
|
|
|
|
{
|
|
|
|
gEnigmaBerries[0].itemEffect[i] = 0;
|
|
|
|
gEnigmaBerries[2].itemEffect[i] = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
gEnigmaBerries[0].holdEffect = 0;
|
|
|
|
gEnigmaBerries[2].holdEffect = 0;
|
|
|
|
gEnigmaBerries[0].holdEffectParam = 0;
|
|
|
|
gEnigmaBerries[2].holdEffectParam = 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
s32 numPlayers;
|
|
|
|
struct BattleEnigmaBerry *src;
|
2018-06-20 23:07:51 +02:00
|
|
|
u8 battlerId;
|
2017-10-01 01:12:42 +02:00
|
|
|
|
|
|
|
if (gBattleTypeFlags & BATTLE_TYPE_MULTI)
|
|
|
|
{
|
|
|
|
if (gBattleTypeFlags & BATTLE_TYPE_BATTLE_TOWER)
|
|
|
|
numPlayers = 2;
|
|
|
|
else
|
|
|
|
numPlayers = 4;
|
|
|
|
|
|
|
|
for (i = 0; i < numPlayers; i++)
|
|
|
|
{
|
|
|
|
src = (struct BattleEnigmaBerry *)(gBlockRecvBuffer[i] + 2);
|
2018-07-22 13:14:58 +02:00
|
|
|
battlerId = gLinkPlayers[i].id;
|
2017-10-01 01:12:42 +02:00
|
|
|
|
2018-09-01 22:03:21 +02:00
|
|
|
for (j = 0; j < BERRY_NAME_LENGTH; j++)
|
2018-06-20 23:07:51 +02:00
|
|
|
gEnigmaBerries[battlerId].name[j] = src->name[j];
|
|
|
|
gEnigmaBerries[battlerId].name[j] = EOS;
|
2017-10-01 01:12:42 +02:00
|
|
|
|
|
|
|
for (j = 0; j < BERRY_ITEM_EFFECT_COUNT; j++)
|
2018-06-20 23:07:51 +02:00
|
|
|
gEnigmaBerries[battlerId].itemEffect[j] = src->itemEffect[j];
|
2017-10-01 01:12:42 +02:00
|
|
|
|
2018-06-20 23:07:51 +02:00
|
|
|
gEnigmaBerries[battlerId].holdEffect = src->holdEffect;
|
|
|
|
gEnigmaBerries[battlerId].holdEffectParam = src->holdEffectParam;
|
2017-10-01 01:12:42 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
for (i = 0; i < 2; i++)
|
|
|
|
{
|
|
|
|
src = (struct BattleEnigmaBerry *)(gBlockRecvBuffer[i] + 2);
|
|
|
|
|
2018-09-01 22:03:21 +02:00
|
|
|
for (j = 0; j < BERRY_NAME_LENGTH; j++)
|
2017-10-01 01:12:42 +02:00
|
|
|
{
|
|
|
|
gEnigmaBerries[i].name[j] = src->name[j];
|
|
|
|
gEnigmaBerries[i + 2].name[j] = src->name[j];
|
|
|
|
}
|
|
|
|
gEnigmaBerries[i].name[j] = EOS;
|
|
|
|
gEnigmaBerries[i + 2].name[j] = EOS;
|
|
|
|
|
|
|
|
for (j = 0; j < BERRY_ITEM_EFFECT_COUNT; j++)
|
|
|
|
{
|
|
|
|
gEnigmaBerries[i].itemEffect[j] = src->itemEffect[j];
|
|
|
|
gEnigmaBerries[i + 2].itemEffect[j] = src->itemEffect[j];
|
|
|
|
}
|
|
|
|
|
|
|
|
gEnigmaBerries[i].holdEffect = src->holdEffect;
|
|
|
|
gEnigmaBerries[i + 2].holdEffect = src->holdEffect;
|
|
|
|
gEnigmaBerries[i].holdEffectParam = src->holdEffectParam;
|
|
|
|
gEnigmaBerries[i + 2].holdEffectParam = src->holdEffectParam;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static void sub_8036EB8(u8 arg0, u8 arg1)
|
|
|
|
{
|
|
|
|
u8 var = 0;
|
|
|
|
|
|
|
|
if (gBlockRecvBuffer[0][0] == 256)
|
|
|
|
{
|
|
|
|
if (arg1 == 0)
|
2018-09-20 11:55:35 +02:00
|
|
|
gBattleTypeFlags |= BATTLE_TYPE_IS_MASTER | BATTLE_TYPE_TRAINER;
|
2017-10-01 01:12:42 +02:00
|
|
|
else
|
|
|
|
gBattleTypeFlags |= BATTLE_TYPE_TRAINER;
|
|
|
|
var++;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (var == 0)
|
|
|
|
{
|
|
|
|
s32 i;
|
|
|
|
|
|
|
|
for (i = 0; i < arg0; i++)
|
|
|
|
{
|
|
|
|
if (gBlockRecvBuffer[0][0] != gBlockRecvBuffer[i][0])
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (i == arg0)
|
|
|
|
{
|
|
|
|
if (arg1 == 0)
|
2018-09-20 11:55:35 +02:00
|
|
|
gBattleTypeFlags |= BATTLE_TYPE_IS_MASTER | BATTLE_TYPE_TRAINER;
|
2017-10-01 01:12:42 +02:00
|
|
|
else
|
|
|
|
gBattleTypeFlags |= BATTLE_TYPE_TRAINER;
|
|
|
|
var++;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (var == 0)
|
|
|
|
{
|
|
|
|
for (i = 0; i < arg0; i++)
|
|
|
|
{
|
|
|
|
if (gBlockRecvBuffer[i][0] == 0x300)
|
|
|
|
{
|
|
|
|
if (i != arg1 && i < arg1)
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
if (gBlockRecvBuffer[i][0] > 0x300 && i != arg1)
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (i == arg0)
|
2018-09-20 11:55:35 +02:00
|
|
|
gBattleTypeFlags |= BATTLE_TYPE_IS_MASTER | BATTLE_TYPE_TRAINER;
|
2017-10-01 01:12:42 +02:00
|
|
|
else
|
|
|
|
gBattleTypeFlags |= BATTLE_TYPE_TRAINER;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static void CB2_HandleStartBattle(void)
|
|
|
|
{
|
|
|
|
u8 playerMultiplayerId;
|
|
|
|
u8 enemyMultiplayerId;
|
|
|
|
|
|
|
|
RunTasks();
|
|
|
|
AnimateSprites();
|
|
|
|
BuildOamBuffer();
|
|
|
|
|
|
|
|
playerMultiplayerId = GetMultiplayerId();
|
|
|
|
gBattleScripting.multiplayerId = playerMultiplayerId;
|
|
|
|
enemyMultiplayerId = playerMultiplayerId ^ BIT_SIDE;
|
|
|
|
|
|
|
|
switch (gBattleCommunication[MULTIUSE_STATE])
|
|
|
|
{
|
|
|
|
case 0:
|
|
|
|
if (!IsDma3ManagerBusyWithBgCopy())
|
|
|
|
{
|
|
|
|
ShowBg(0);
|
|
|
|
ShowBg(1);
|
|
|
|
ShowBg(2);
|
|
|
|
ShowBg(3);
|
|
|
|
sub_805EF14();
|
|
|
|
gBattleCommunication[MULTIUSE_STATE] = 1;
|
|
|
|
}
|
2017-11-13 05:58:05 +01:00
|
|
|
if (gWirelessCommType)
|
2019-04-04 23:05:46 +02:00
|
|
|
LoadWirelessStatusIndicatorSpriteGfx();
|
2017-10-01 01:12:42 +02:00
|
|
|
break;
|
|
|
|
case 1:
|
|
|
|
if (gBattleTypeFlags & BATTLE_TYPE_LINK)
|
|
|
|
{
|
|
|
|
if (gReceivedRemoteLinkPlayers != 0)
|
|
|
|
{
|
2018-12-31 09:22:21 +01:00
|
|
|
if (IsLinkTaskFinished())
|
2017-10-01 01:12:42 +02:00
|
|
|
{
|
|
|
|
*(&gBattleStruct->field_180) = 0;
|
|
|
|
*(&gBattleStruct->field_181) = 3;
|
|
|
|
sub_8036A5C();
|
|
|
|
SetPlayerBerryDataInBattleStruct();
|
|
|
|
|
|
|
|
if (gTrainerBattleOpponent_A == TRAINER_OPPONENT_C00)
|
|
|
|
{
|
2018-07-22 12:49:49 +02:00
|
|
|
gLinkPlayers[0].id = 0;
|
|
|
|
gLinkPlayers[1].id = 1;
|
2017-10-01 01:12:42 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
SendBlock(bitmask_all_link_players_but_self(), &gBattleStruct->field_180, 32);
|
|
|
|
gBattleCommunication[MULTIUSE_STATE] = 2;
|
|
|
|
}
|
2017-11-13 05:58:05 +01:00
|
|
|
if (gWirelessCommType)
|
2017-12-04 04:01:06 +01:00
|
|
|
CreateWirelessStatusIndicatorSprite(0, 0);
|
2017-10-01 01:12:42 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
if (!(gBattleTypeFlags & BATTLE_TYPE_RECORDED))
|
2018-09-20 11:55:35 +02:00
|
|
|
gBattleTypeFlags |= BATTLE_TYPE_IS_MASTER;
|
2017-10-01 01:12:42 +02:00
|
|
|
gBattleCommunication[MULTIUSE_STATE] = 15;
|
|
|
|
SetAllPlayersBerryData();
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case 2:
|
|
|
|
if ((GetBlockReceivedStatus() & 3) == 3)
|
|
|
|
{
|
|
|
|
u8 taskId;
|
|
|
|
|
|
|
|
ResetBlockReceivedFlags();
|
|
|
|
sub_8036EB8(2, playerMultiplayerId);
|
|
|
|
SetAllPlayersBerryData();
|
2017-12-17 20:10:57 +01:00
|
|
|
taskId = CreateTask(sub_8035D74, 0);
|
2017-10-01 01:12:42 +02:00
|
|
|
gTasks[taskId].data[1] = 0x10E;
|
|
|
|
gTasks[taskId].data[2] = 0x5A;
|
|
|
|
gTasks[taskId].data[5] = 0;
|
|
|
|
gTasks[taskId].data[3] = gBattleStruct->field_182 | (gBattleStruct->field_183 << 8);
|
|
|
|
gTasks[taskId].data[4] = gBlockRecvBuffer[enemyMultiplayerId][1];
|
|
|
|
sub_8185F90(gBlockRecvBuffer[playerMultiplayerId][1]);
|
|
|
|
sub_8185F90(gBlockRecvBuffer[enemyMultiplayerId][1]);
|
2018-02-09 15:55:12 +01:00
|
|
|
SetDeoxysStats();
|
2017-10-01 01:12:42 +02:00
|
|
|
gBattleCommunication[MULTIUSE_STATE]++;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case 3:
|
2018-12-31 09:22:21 +01:00
|
|
|
if (IsLinkTaskFinished())
|
2017-10-01 01:12:42 +02:00
|
|
|
{
|
|
|
|
SendBlock(bitmask_all_link_players_but_self(), gPlayerParty, sizeof(struct Pokemon) * 2);
|
|
|
|
gBattleCommunication[MULTIUSE_STATE]++;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case 4:
|
|
|
|
if ((GetBlockReceivedStatus() & 3) == 3)
|
|
|
|
{
|
|
|
|
ResetBlockReceivedFlags();
|
|
|
|
memcpy(gEnemyParty, gBlockRecvBuffer[enemyMultiplayerId], sizeof(struct Pokemon) * 2);
|
|
|
|
gBattleCommunication[MULTIUSE_STATE]++;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case 7:
|
2018-12-31 09:22:21 +01:00
|
|
|
if (IsLinkTaskFinished())
|
2017-10-01 01:12:42 +02:00
|
|
|
{
|
|
|
|
SendBlock(bitmask_all_link_players_but_self(), gPlayerParty + 2, sizeof(struct Pokemon) * 2);
|
|
|
|
gBattleCommunication[MULTIUSE_STATE]++;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case 8:
|
|
|
|
if ((GetBlockReceivedStatus() & 3) == 3)
|
|
|
|
{
|
|
|
|
ResetBlockReceivedFlags();
|
|
|
|
memcpy(gEnemyParty + 2, gBlockRecvBuffer[enemyMultiplayerId], sizeof(struct Pokemon) * 2);
|
|
|
|
gBattleCommunication[MULTIUSE_STATE]++;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case 11:
|
2018-12-31 09:22:21 +01:00
|
|
|
if (IsLinkTaskFinished())
|
2017-10-01 01:12:42 +02:00
|
|
|
{
|
|
|
|
SendBlock(bitmask_all_link_players_but_self(), gPlayerParty + 4, sizeof(struct Pokemon) * 2);
|
|
|
|
gBattleCommunication[MULTIUSE_STATE]++;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case 12:
|
|
|
|
if ((GetBlockReceivedStatus() & 3) == 3)
|
|
|
|
{
|
|
|
|
ResetBlockReceivedFlags();
|
|
|
|
memcpy(gEnemyParty + 4, gBlockRecvBuffer[enemyMultiplayerId], sizeof(struct Pokemon) * 2);
|
2017-10-01 18:54:01 +02:00
|
|
|
TryCorrectShedinjaLanguage(&gEnemyParty[0]);
|
|
|
|
TryCorrectShedinjaLanguage(&gEnemyParty[1]);
|
|
|
|
TryCorrectShedinjaLanguage(&gEnemyParty[2]);
|
|
|
|
TryCorrectShedinjaLanguage(&gEnemyParty[3]);
|
|
|
|
TryCorrectShedinjaLanguage(&gEnemyParty[4]);
|
|
|
|
TryCorrectShedinjaLanguage(&gEnemyParty[5]);
|
2017-10-01 01:12:42 +02:00
|
|
|
gBattleCommunication[MULTIUSE_STATE]++;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case 15:
|
|
|
|
sub_8032768();
|
|
|
|
sub_8184E58();
|
|
|
|
gBattleCommunication[SPRITES_INIT_STATE1] = 0;
|
|
|
|
gBattleCommunication[SPRITES_INIT_STATE2] = 0;
|
|
|
|
if (gBattleTypeFlags & BATTLE_TYPE_LINK)
|
|
|
|
{
|
|
|
|
s32 i;
|
|
|
|
|
2017-10-13 17:09:36 +02:00
|
|
|
for (i = 0; i < 2 && (gLinkPlayers[i].version & 0xFF) == VERSION_EMERALD; i++);
|
2017-10-01 01:12:42 +02:00
|
|
|
|
|
|
|
if (i == 2)
|
|
|
|
gBattleCommunication[MULTIUSE_STATE] = 16;
|
|
|
|
else
|
|
|
|
gBattleCommunication[MULTIUSE_STATE] = 18;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
gBattleCommunication[MULTIUSE_STATE] = 18;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case 16:
|
2018-12-31 09:22:21 +01:00
|
|
|
if (IsLinkTaskFinished())
|
2017-10-01 01:12:42 +02:00
|
|
|
{
|
|
|
|
SendBlock(bitmask_all_link_players_but_self(), &gRecordedBattleRngSeed, sizeof(gRecordedBattleRngSeed));
|
|
|
|
gBattleCommunication[MULTIUSE_STATE]++;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case 17:
|
|
|
|
if ((GetBlockReceivedStatus() & 3) == 3)
|
|
|
|
{
|
|
|
|
ResetBlockReceivedFlags();
|
2018-09-20 11:55:35 +02:00
|
|
|
if (!(gBattleTypeFlags & BATTLE_TYPE_IS_MASTER))
|
2017-10-01 01:12:42 +02:00
|
|
|
memcpy(&gRecordedBattleRngSeed, gBlockRecvBuffer[enemyMultiplayerId], sizeof(gRecordedBattleRngSeed));
|
|
|
|
gBattleCommunication[MULTIUSE_STATE]++;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case 18:
|
|
|
|
if (BattleInitAllSprites(&gBattleCommunication[SPRITES_INIT_STATE1], &gBattleCommunication[SPRITES_INIT_STATE2]))
|
|
|
|
{
|
|
|
|
gPreBattleCallback1 = gMain.callback1;
|
|
|
|
gMain.callback1 = BattleMainCB1;
|
|
|
|
SetMainCallback2(BattleMainCB2);
|
|
|
|
if (gBattleTypeFlags & BATTLE_TYPE_LINK)
|
|
|
|
{
|
|
|
|
gBattleTypeFlags |= BATTLE_TYPE_20;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case 5:
|
|
|
|
case 9:
|
|
|
|
case 13:
|
|
|
|
gBattleCommunication[MULTIUSE_STATE]++;
|
|
|
|
gBattleCommunication[1] = 1;
|
|
|
|
case 6:
|
|
|
|
case 10:
|
|
|
|
case 14:
|
|
|
|
if (--gBattleCommunication[1] == 0)
|
|
|
|
gBattleCommunication[MULTIUSE_STATE]++;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static void CB2_HandleStartMultiPartnerBattle(void)
|
|
|
|
{
|
|
|
|
u8 playerMultiplayerId;
|
|
|
|
u8 enemyMultiplayerId;
|
|
|
|
|
|
|
|
RunTasks();
|
|
|
|
AnimateSprites();
|
|
|
|
BuildOamBuffer();
|
|
|
|
|
|
|
|
playerMultiplayerId = GetMultiplayerId();
|
|
|
|
gBattleScripting.multiplayerId = playerMultiplayerId;
|
|
|
|
enemyMultiplayerId = playerMultiplayerId ^ BIT_SIDE;
|
|
|
|
|
|
|
|
switch (gBattleCommunication[MULTIUSE_STATE])
|
|
|
|
{
|
|
|
|
case 0:
|
|
|
|
if (!IsDma3ManagerBusyWithBgCopy())
|
|
|
|
{
|
|
|
|
ShowBg(0);
|
|
|
|
ShowBg(1);
|
|
|
|
ShowBg(2);
|
|
|
|
ShowBg(3);
|
|
|
|
sub_805EF14();
|
|
|
|
gBattleCommunication[MULTIUSE_STATE] = 1;
|
|
|
|
}
|
2017-11-13 05:58:05 +01:00
|
|
|
if (gWirelessCommType)
|
2019-04-04 23:05:46 +02:00
|
|
|
LoadWirelessStatusIndicatorSpriteGfx();
|
2017-10-01 01:12:42 +02:00
|
|
|
// fall through
|
|
|
|
case 1:
|
|
|
|
if (gBattleTypeFlags & BATTLE_TYPE_LINK)
|
|
|
|
{
|
|
|
|
if (gReceivedRemoteLinkPlayers != 0)
|
|
|
|
{
|
|
|
|
u8 language;
|
|
|
|
|
2018-07-22 12:49:49 +02:00
|
|
|
gLinkPlayers[0].id = 0;
|
|
|
|
gLinkPlayers[1].id = 2;
|
|
|
|
gLinkPlayers[2].id = 1;
|
|
|
|
gLinkPlayers[3].id = 3;
|
2017-10-01 01:12:42 +02:00
|
|
|
GetFrontierTrainerName(gLinkPlayers[2].name, gTrainerBattleOpponent_A);
|
|
|
|
GetFrontierTrainerName(gLinkPlayers[3].name, gTrainerBattleOpponent_B);
|
2018-10-24 23:14:45 +02:00
|
|
|
GetBattleTowerTrainerLanguage(&language, gTrainerBattleOpponent_A);
|
2017-10-01 01:12:42 +02:00
|
|
|
gLinkPlayers[2].language = language;
|
2018-10-24 23:14:45 +02:00
|
|
|
GetBattleTowerTrainerLanguage(&language, gTrainerBattleOpponent_B);
|
2017-10-01 01:12:42 +02:00
|
|
|
gLinkPlayers[3].language = language;
|
|
|
|
|
2018-12-31 09:22:21 +01:00
|
|
|
if (IsLinkTaskFinished())
|
2017-10-01 01:12:42 +02:00
|
|
|
{
|
|
|
|
*(&gBattleStruct->field_180) = 0;
|
|
|
|
*(&gBattleStruct->field_181) = 3;
|
|
|
|
sub_8036A5C();
|
|
|
|
SetPlayerBerryDataInBattleStruct();
|
|
|
|
SendBlock(bitmask_all_link_players_but_self(), &gBattleStruct->field_180, 32);
|
|
|
|
gBattleCommunication[MULTIUSE_STATE] = 2;
|
|
|
|
}
|
|
|
|
|
2017-11-13 05:58:05 +01:00
|
|
|
if (gWirelessCommType)
|
2017-12-04 04:01:06 +01:00
|
|
|
CreateWirelessStatusIndicatorSprite(0, 0);
|
2017-10-01 01:12:42 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
if (!(gBattleTypeFlags & BATTLE_TYPE_RECORDED))
|
2018-09-20 11:55:35 +02:00
|
|
|
gBattleTypeFlags |= BATTLE_TYPE_IS_MASTER;
|
2017-10-01 01:12:42 +02:00
|
|
|
gBattleCommunication[MULTIUSE_STATE] = 13;
|
|
|
|
SetAllPlayersBerryData();
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case 2:
|
|
|
|
if ((GetBlockReceivedStatus() & 3) == 3)
|
|
|
|
{
|
|
|
|
u8 taskId;
|
|
|
|
|
|
|
|
ResetBlockReceivedFlags();
|
|
|
|
sub_8036EB8(2, playerMultiplayerId);
|
|
|
|
SetAllPlayersBerryData();
|
2017-12-17 20:10:57 +01:00
|
|
|
taskId = CreateTask(sub_8035D74, 0);
|
2017-10-01 01:12:42 +02:00
|
|
|
gTasks[taskId].data[1] = 0x10E;
|
|
|
|
gTasks[taskId].data[2] = 0x5A;
|
|
|
|
gTasks[taskId].data[5] = 0;
|
|
|
|
gTasks[taskId].data[3] = 0x145;
|
|
|
|
gTasks[taskId].data[4] = 0x145;
|
|
|
|
gBattleCommunication[MULTIUSE_STATE]++;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case 3:
|
2018-12-31 09:22:21 +01:00
|
|
|
if (IsLinkTaskFinished())
|
2017-10-01 01:12:42 +02:00
|
|
|
{
|
|
|
|
SendBlock(bitmask_all_link_players_but_self(), gPlayerParty, sizeof(struct Pokemon) * 2);
|
|
|
|
gBattleCommunication[MULTIUSE_STATE]++;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case 4:
|
|
|
|
if ((GetBlockReceivedStatus() & 3) == 3)
|
|
|
|
{
|
|
|
|
ResetBlockReceivedFlags();
|
2018-07-22 12:49:49 +02:00
|
|
|
if (gLinkPlayers[playerMultiplayerId].id != 0)
|
2017-10-01 01:12:42 +02:00
|
|
|
{
|
|
|
|
memcpy(gPlayerParty, gBlockRecvBuffer[enemyMultiplayerId], sizeof(struct Pokemon) * 2);
|
|
|
|
memcpy(gPlayerParty + 3, gBlockRecvBuffer[playerMultiplayerId], sizeof(struct Pokemon) * 2);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
memcpy(gPlayerParty, gBlockRecvBuffer[playerMultiplayerId], sizeof(struct Pokemon) * 2);
|
|
|
|
memcpy(gPlayerParty + 3, gBlockRecvBuffer[enemyMultiplayerId], sizeof(struct Pokemon) * 2);
|
|
|
|
}
|
|
|
|
gBattleCommunication[MULTIUSE_STATE]++;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case 5:
|
2018-12-31 09:22:21 +01:00
|
|
|
if (IsLinkTaskFinished())
|
2017-10-01 01:12:42 +02:00
|
|
|
{
|
|
|
|
SendBlock(bitmask_all_link_players_but_self(), gPlayerParty + 2, sizeof(struct Pokemon));
|
|
|
|
gBattleCommunication[MULTIUSE_STATE]++;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case 6:
|
|
|
|
if ((GetBlockReceivedStatus() & 3) == 3)
|
|
|
|
{
|
|
|
|
ResetBlockReceivedFlags();
|
2018-07-22 12:49:49 +02:00
|
|
|
if (gLinkPlayers[playerMultiplayerId].id != 0)
|
2017-10-01 01:12:42 +02:00
|
|
|
{
|
|
|
|
memcpy(gPlayerParty + 2, gBlockRecvBuffer[enemyMultiplayerId], sizeof(struct Pokemon));
|
|
|
|
memcpy(gPlayerParty + 5, gBlockRecvBuffer[playerMultiplayerId], sizeof(struct Pokemon));
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
memcpy(gPlayerParty + 2, gBlockRecvBuffer[playerMultiplayerId], sizeof(struct Pokemon));
|
|
|
|
memcpy(gPlayerParty + 5, gBlockRecvBuffer[enemyMultiplayerId], sizeof(struct Pokemon));
|
|
|
|
}
|
|
|
|
gBattleCommunication[MULTIUSE_STATE]++;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case 7:
|
2018-12-31 09:22:21 +01:00
|
|
|
if (IsLinkTaskFinished())
|
2017-10-01 01:12:42 +02:00
|
|
|
{
|
|
|
|
SendBlock(bitmask_all_link_players_but_self(), gEnemyParty, sizeof(struct Pokemon) * 2);
|
|
|
|
gBattleCommunication[MULTIUSE_STATE]++;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case 8:
|
|
|
|
if ((GetBlockReceivedStatus() & 3) == 3)
|
|
|
|
{
|
|
|
|
ResetBlockReceivedFlags();
|
|
|
|
if (GetMultiplayerId() != 0)
|
|
|
|
{
|
|
|
|
memcpy(gEnemyParty, gBlockRecvBuffer[0], sizeof(struct Pokemon) * 2);
|
|
|
|
}
|
|
|
|
gBattleCommunication[MULTIUSE_STATE]++;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case 9:
|
2018-12-31 09:22:21 +01:00
|
|
|
if (IsLinkTaskFinished())
|
2017-10-01 01:12:42 +02:00
|
|
|
{
|
|
|
|
SendBlock(bitmask_all_link_players_but_self(), gEnemyParty + 2, sizeof(struct Pokemon) * 2);
|
|
|
|
gBattleCommunication[MULTIUSE_STATE]++;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case 10:
|
|
|
|
if ((GetBlockReceivedStatus() & 3) == 3)
|
|
|
|
{
|
|
|
|
ResetBlockReceivedFlags();
|
|
|
|
if (GetMultiplayerId() != 0)
|
|
|
|
{
|
|
|
|
memcpy(gEnemyParty + 2, gBlockRecvBuffer[0], sizeof(struct Pokemon) * 2);
|
|
|
|
}
|
|
|
|
gBattleCommunication[MULTIUSE_STATE]++;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case 11:
|
2018-12-31 09:22:21 +01:00
|
|
|
if (IsLinkTaskFinished())
|
2017-10-01 01:12:42 +02:00
|
|
|
{
|
|
|
|
SendBlock(bitmask_all_link_players_but_self(), gEnemyParty + 4, sizeof(struct Pokemon) * 2);
|
|
|
|
gBattleCommunication[MULTIUSE_STATE]++;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case 12:
|
|
|
|
if ((GetBlockReceivedStatus() & 3) == 3)
|
|
|
|
{
|
|
|
|
ResetBlockReceivedFlags();
|
|
|
|
if (GetMultiplayerId() != 0)
|
|
|
|
memcpy(gEnemyParty + 4, gBlockRecvBuffer[0], sizeof(struct Pokemon) * 2);
|
2017-10-01 18:54:01 +02:00
|
|
|
TryCorrectShedinjaLanguage(&gPlayerParty[0]);
|
|
|
|
TryCorrectShedinjaLanguage(&gPlayerParty[1]);
|
|
|
|
TryCorrectShedinjaLanguage(&gPlayerParty[2]);
|
|
|
|
TryCorrectShedinjaLanguage(&gPlayerParty[3]);
|
|
|
|
TryCorrectShedinjaLanguage(&gPlayerParty[4]);
|
|
|
|
TryCorrectShedinjaLanguage(&gPlayerParty[5]);
|
|
|
|
TryCorrectShedinjaLanguage(&gEnemyParty[0]);
|
|
|
|
TryCorrectShedinjaLanguage(&gEnemyParty[1]);
|
|
|
|
TryCorrectShedinjaLanguage(&gEnemyParty[2]);
|
|
|
|
TryCorrectShedinjaLanguage(&gEnemyParty[3]);
|
|
|
|
TryCorrectShedinjaLanguage(&gEnemyParty[4]);
|
|
|
|
TryCorrectShedinjaLanguage(&gEnemyParty[5]);
|
2017-10-01 01:12:42 +02:00
|
|
|
gBattleCommunication[MULTIUSE_STATE]++;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case 13:
|
|
|
|
sub_8032768();
|
|
|
|
sub_8184E58();
|
|
|
|
gBattleCommunication[SPRITES_INIT_STATE1] = 0;
|
|
|
|
gBattleCommunication[SPRITES_INIT_STATE2] = 0;
|
|
|
|
if (gBattleTypeFlags & BATTLE_TYPE_LINK)
|
|
|
|
{
|
|
|
|
gBattleCommunication[MULTIUSE_STATE] = 14;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
gBattleCommunication[MULTIUSE_STATE] = 16;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case 14:
|
2018-12-31 09:22:21 +01:00
|
|
|
if (IsLinkTaskFinished())
|
2017-10-01 01:12:42 +02:00
|
|
|
{
|
|
|
|
SendBlock(bitmask_all_link_players_but_self(), &gRecordedBattleRngSeed, sizeof(gRecordedBattleRngSeed));
|
|
|
|
gBattleCommunication[MULTIUSE_STATE]++;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case 15:
|
|
|
|
if ((GetBlockReceivedStatus() & 3) == 3)
|
|
|
|
{
|
|
|
|
ResetBlockReceivedFlags();
|
2018-09-20 11:55:35 +02:00
|
|
|
if (!(gBattleTypeFlags & BATTLE_TYPE_IS_MASTER))
|
2017-10-01 01:12:42 +02:00
|
|
|
memcpy(&gRecordedBattleRngSeed, gBlockRecvBuffer[enemyMultiplayerId], sizeof(gRecordedBattleRngSeed));
|
|
|
|
gBattleCommunication[MULTIUSE_STATE]++;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case 16:
|
|
|
|
if (BattleInitAllSprites(&gBattleCommunication[SPRITES_INIT_STATE1], &gBattleCommunication[SPRITES_INIT_STATE2]))
|
|
|
|
{
|
|
|
|
sub_8166188();
|
|
|
|
gPreBattleCallback1 = gMain.callback1;
|
|
|
|
gMain.callback1 = BattleMainCB1;
|
|
|
|
SetMainCallback2(BattleMainCB2);
|
|
|
|
if (gBattleTypeFlags & BATTLE_TYPE_LINK)
|
|
|
|
{
|
|
|
|
gBattleTypeFlags |= BATTLE_TYPE_20;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static void sub_80379F8(u8 arrayIdPlus)
|
|
|
|
{
|
|
|
|
s32 i;
|
|
|
|
|
|
|
|
for (i = 0; i < 3; i++)
|
|
|
|
{
|
|
|
|
gUnknown_02022FF8[i].species = GetMonData(&gPlayerParty[arrayIdPlus + i], MON_DATA_SPECIES);
|
|
|
|
gUnknown_02022FF8[i].heldItem = GetMonData(&gPlayerParty[arrayIdPlus + i], MON_DATA_HELD_ITEM);
|
|
|
|
GetMonData(&gPlayerParty[arrayIdPlus + i], MON_DATA_NICKNAME, gUnknown_02022FF8[i].nickname);
|
|
|
|
gUnknown_02022FF8[i].level = GetMonData(&gPlayerParty[arrayIdPlus + i], MON_DATA_LEVEL);
|
|
|
|
gUnknown_02022FF8[i].hp = GetMonData(&gPlayerParty[arrayIdPlus + i], MON_DATA_HP);
|
|
|
|
gUnknown_02022FF8[i].maxhp = GetMonData(&gPlayerParty[arrayIdPlus + i], MON_DATA_MAX_HP);
|
|
|
|
gUnknown_02022FF8[i].status = GetMonData(&gPlayerParty[arrayIdPlus + i], MON_DATA_STATUS);
|
|
|
|
gUnknown_02022FF8[i].personality = GetMonData(&gPlayerParty[arrayIdPlus + i], MON_DATA_PERSONALITY);
|
|
|
|
gUnknown_02022FF8[i].gender = GetMonGender(&gPlayerParty[arrayIdPlus + i]);
|
|
|
|
StripExtCtrlCodes(gUnknown_02022FF8[i].nickname);
|
|
|
|
if (GetMonData(&gPlayerParty[arrayIdPlus + i], MON_DATA_LANGUAGE) != LANGUAGE_JAPANESE)
|
2017-12-16 01:18:31 +01:00
|
|
|
PadNameString(gUnknown_02022FF8[i].nickname, CHAR_SPACE);
|
2017-10-01 01:12:42 +02:00
|
|
|
}
|
|
|
|
memcpy(gUnknown_02023058, gUnknown_02022FF8, sizeof(gUnknown_02022FF8));
|
|
|
|
}
|
|
|
|
|
|
|
|
static void CB2_PreInitMultiBattle(void)
|
|
|
|
{
|
|
|
|
s32 i;
|
|
|
|
u8 playerMultiplierId;
|
|
|
|
s32 numPlayers = 4;
|
|
|
|
u8 r4 = 0xF;
|
2018-06-20 23:07:51 +02:00
|
|
|
u32 *savedBattleTypeFlags;
|
2017-10-01 01:12:42 +02:00
|
|
|
void (**savedCallback)(void);
|
|
|
|
|
|
|
|
if (gBattleTypeFlags & BATTLE_TYPE_BATTLE_TOWER)
|
|
|
|
{
|
|
|
|
numPlayers = 2;
|
|
|
|
r4 = 3;
|
|
|
|
}
|
|
|
|
|
|
|
|
playerMultiplierId = GetMultiplayerId();
|
|
|
|
gBattleScripting.multiplayerId = playerMultiplierId;
|
|
|
|
savedCallback = &gBattleStruct->savedCallback;
|
|
|
|
savedBattleTypeFlags = &gBattleStruct->savedBattleTypeFlags;
|
|
|
|
|
|
|
|
RunTasks();
|
|
|
|
AnimateSprites();
|
|
|
|
BuildOamBuffer();
|
|
|
|
|
|
|
|
switch (gBattleCommunication[MULTIUSE_STATE])
|
|
|
|
{
|
|
|
|
case 0:
|
2018-12-31 09:22:21 +01:00
|
|
|
if (gReceivedRemoteLinkPlayers != 0 && IsLinkTaskFinished())
|
2017-10-01 01:12:42 +02:00
|
|
|
{
|
2018-02-09 15:55:12 +01:00
|
|
|
gUnknown_02023058 = Alloc(sizeof(struct UnknownPokemonStruct4) * 3);
|
2017-10-01 01:12:42 +02:00
|
|
|
sub_80379F8(0);
|
2018-02-09 15:55:12 +01:00
|
|
|
SendBlock(bitmask_all_link_players_but_self(), gUnknown_02023058, sizeof(struct UnknownPokemonStruct4) * 3);
|
2017-10-01 01:12:42 +02:00
|
|
|
gBattleCommunication[MULTIUSE_STATE]++;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case 1:
|
|
|
|
if ((GetBlockReceivedStatus() & r4) == r4)
|
|
|
|
{
|
|
|
|
ResetBlockReceivedFlags();
|
|
|
|
for (i = 0; i < numPlayers; i++)
|
|
|
|
{
|
|
|
|
if (i == playerMultiplierId)
|
|
|
|
continue;
|
|
|
|
|
|
|
|
if (numPlayers == 4)
|
|
|
|
{
|
2018-07-22 12:49:49 +02:00
|
|
|
if ((!(gLinkPlayers[i].id & 1) && !(gLinkPlayers[playerMultiplierId].id & 1))
|
|
|
|
|| (gLinkPlayers[i].id & 1 && gLinkPlayers[playerMultiplierId].id & 1))
|
2017-10-01 01:12:42 +02:00
|
|
|
{
|
2018-02-09 15:55:12 +01:00
|
|
|
memcpy(gUnknown_02022FF8, gBlockRecvBuffer[i], sizeof(struct UnknownPokemonStruct4) * 3);
|
2017-10-01 01:12:42 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2018-02-09 15:55:12 +01:00
|
|
|
memcpy(gUnknown_02022FF8, gBlockRecvBuffer[i], sizeof(struct UnknownPokemonStruct4) * 3);
|
2017-10-01 01:12:42 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
gBattleCommunication[MULTIUSE_STATE]++;
|
|
|
|
*savedCallback = gMain.savedCallback;
|
|
|
|
*savedBattleTypeFlags = gBattleTypeFlags;
|
|
|
|
gMain.savedCallback = CB2_PreInitMultiBattle;
|
|
|
|
sub_81B9150();
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case 2:
|
2018-12-31 09:22:21 +01:00
|
|
|
if (IsLinkTaskFinished() && !gPaletteFade.active)
|
2017-10-01 01:12:42 +02:00
|
|
|
{
|
|
|
|
gBattleCommunication[MULTIUSE_STATE]++;
|
2017-11-13 05:58:05 +01:00
|
|
|
if (gWirelessCommType)
|
2017-10-01 01:12:42 +02:00
|
|
|
sub_800ADF8();
|
|
|
|
else
|
|
|
|
sub_800AC34();
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case 3:
|
2017-11-13 05:58:05 +01:00
|
|
|
if (gWirelessCommType)
|
2017-10-01 01:12:42 +02:00
|
|
|
{
|
|
|
|
if (sub_8010500())
|
|
|
|
{
|
|
|
|
gBattleTypeFlags = *savedBattleTypeFlags;
|
|
|
|
gMain.savedCallback = *savedCallback;
|
|
|
|
SetMainCallback2(CB2_InitBattleInternal);
|
|
|
|
Free(gUnknown_02023058);
|
|
|
|
gUnknown_02023058 = NULL;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else if (gReceivedRemoteLinkPlayers == 0)
|
|
|
|
{
|
|
|
|
gBattleTypeFlags = *savedBattleTypeFlags;
|
|
|
|
gMain.savedCallback = *savedCallback;
|
|
|
|
SetMainCallback2(CB2_InitBattleInternal);
|
|
|
|
Free(gUnknown_02023058);
|
|
|
|
gUnknown_02023058 = NULL;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static void CB2_PreInitIngamePlayerPartnerBattle(void)
|
|
|
|
{
|
2018-06-20 23:07:51 +02:00
|
|
|
u32 *savedBattleTypeFlags;
|
2017-10-01 01:12:42 +02:00
|
|
|
void (**savedCallback)(void);
|
|
|
|
|
|
|
|
savedCallback = &gBattleStruct->savedCallback;
|
|
|
|
savedBattleTypeFlags = &gBattleStruct->savedBattleTypeFlags;
|
|
|
|
|
|
|
|
RunTasks();
|
|
|
|
AnimateSprites();
|
|
|
|
BuildOamBuffer();
|
|
|
|
|
|
|
|
switch (gBattleCommunication[MULTIUSE_STATE])
|
|
|
|
{
|
|
|
|
case 0:
|
2018-02-09 15:55:12 +01:00
|
|
|
gUnknown_02023058 = Alloc(sizeof(struct UnknownPokemonStruct4) * 3);
|
2017-10-01 01:12:42 +02:00
|
|
|
sub_80379F8(3);
|
|
|
|
gBattleCommunication[MULTIUSE_STATE]++;
|
|
|
|
*savedCallback = gMain.savedCallback;
|
|
|
|
*savedBattleTypeFlags = gBattleTypeFlags;
|
|
|
|
gMain.savedCallback = CB2_PreInitIngamePlayerPartnerBattle;
|
|
|
|
sub_81B9150();
|
|
|
|
break;
|
|
|
|
case 1:
|
|
|
|
if (!gPaletteFade.active)
|
|
|
|
{
|
|
|
|
gBattleCommunication[MULTIUSE_STATE] = 2;
|
|
|
|
gBattleTypeFlags = *savedBattleTypeFlags;
|
|
|
|
gMain.savedCallback = *savedCallback;
|
|
|
|
SetMainCallback2(CB2_InitBattleInternal);
|
|
|
|
Free(gUnknown_02023058);
|
|
|
|
gUnknown_02023058 = NULL;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static void CB2_HandleStartMultiBattle(void)
|
|
|
|
{
|
|
|
|
u8 playerMultiplayerId;
|
|
|
|
s32 id;
|
|
|
|
u8 var;
|
|
|
|
|
|
|
|
playerMultiplayerId = GetMultiplayerId();
|
|
|
|
gBattleScripting.multiplayerId = playerMultiplayerId;
|
|
|
|
|
|
|
|
RunTasks();
|
|
|
|
AnimateSprites();
|
|
|
|
BuildOamBuffer();
|
|
|
|
|
|
|
|
switch (gBattleCommunication[MULTIUSE_STATE])
|
|
|
|
{
|
|
|
|
case 0:
|
|
|
|
if (!IsDma3ManagerBusyWithBgCopy())
|
|
|
|
{
|
|
|
|
ShowBg(0);
|
|
|
|
ShowBg(1);
|
|
|
|
ShowBg(2);
|
|
|
|
ShowBg(3);
|
|
|
|
sub_805EF14();
|
|
|
|
gBattleCommunication[MULTIUSE_STATE] = 1;
|
|
|
|
}
|
2017-11-13 05:58:05 +01:00
|
|
|
if (gWirelessCommType)
|
2019-04-04 23:05:46 +02:00
|
|
|
LoadWirelessStatusIndicatorSpriteGfx();
|
2017-10-01 01:12:42 +02:00
|
|
|
break;
|
|
|
|
case 1:
|
|
|
|
if (gBattleTypeFlags & BATTLE_TYPE_LINK)
|
|
|
|
{
|
|
|
|
if (gReceivedRemoteLinkPlayers != 0)
|
|
|
|
{
|
2018-12-31 09:22:21 +01:00
|
|
|
if (IsLinkTaskFinished())
|
2017-10-01 01:12:42 +02:00
|
|
|
{
|
|
|
|
*(&gBattleStruct->field_180) = 0;
|
|
|
|
*(&gBattleStruct->field_181) = 3;
|
|
|
|
sub_8036A5C();
|
|
|
|
SetPlayerBerryDataInBattleStruct();
|
|
|
|
|
|
|
|
SendBlock(bitmask_all_link_players_but_self(), &gBattleStruct->field_180, 32);
|
|
|
|
gBattleCommunication[MULTIUSE_STATE]++;
|
|
|
|
}
|
2017-11-13 05:58:05 +01:00
|
|
|
if (gWirelessCommType)
|
2017-12-04 04:01:06 +01:00
|
|
|
CreateWirelessStatusIndicatorSprite(0, 0);
|
2017-10-01 01:12:42 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
if (!(gBattleTypeFlags & BATTLE_TYPE_RECORDED))
|
2018-09-20 11:55:35 +02:00
|
|
|
gBattleTypeFlags |= BATTLE_TYPE_IS_MASTER;
|
2017-10-01 01:12:42 +02:00
|
|
|
gBattleCommunication[MULTIUSE_STATE] = 7;
|
|
|
|
SetAllPlayersBerryData();
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case 2:
|
|
|
|
if ((GetBlockReceivedStatus() & 0xF) == 0xF)
|
|
|
|
{
|
|
|
|
ResetBlockReceivedFlags();
|
|
|
|
sub_8036EB8(4, playerMultiplayerId);
|
|
|
|
SetAllPlayersBerryData();
|
2018-02-09 15:55:12 +01:00
|
|
|
SetDeoxysStats();
|
2017-12-17 20:10:57 +01:00
|
|
|
var = CreateTask(sub_8035D74, 0);
|
2017-10-01 01:12:42 +02:00
|
|
|
gTasks[var].data[1] = 0x10E;
|
|
|
|
gTasks[var].data[2] = 0x5A;
|
|
|
|
gTasks[var].data[5] = 0;
|
|
|
|
gTasks[var].data[3] = 0;
|
|
|
|
gTasks[var].data[4] = 0;
|
|
|
|
|
|
|
|
for (id = 0; id < MAX_LINK_PLAYERS; id++)
|
|
|
|
{
|
|
|
|
sub_8185F90(gBlockRecvBuffer[id][1]);
|
2018-07-22 12:49:49 +02:00
|
|
|
switch (gLinkPlayers[id].id)
|
2017-10-01 01:12:42 +02:00
|
|
|
{
|
|
|
|
case 0:
|
|
|
|
gTasks[var].data[3] |= gBlockRecvBuffer[id][1] & 0x3F;
|
|
|
|
break;
|
|
|
|
case 1:
|
|
|
|
gTasks[var].data[4] |= gBlockRecvBuffer[id][1] & 0x3F;
|
|
|
|
break;
|
|
|
|
case 2:
|
|
|
|
gTasks[var].data[3] |= (gBlockRecvBuffer[id][1] & 0x3F) << 6;
|
|
|
|
break;
|
|
|
|
case 3:
|
|
|
|
gTasks[var].data[4] |= (gBlockRecvBuffer[id][1] & 0x3F) << 6;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
ZeroEnemyPartyMons();
|
|
|
|
gBattleCommunication[MULTIUSE_STATE]++;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
break;
|
|
|
|
// fall through
|
|
|
|
case 3:
|
2018-12-31 09:22:21 +01:00
|
|
|
if (IsLinkTaskFinished())
|
2017-10-01 01:12:42 +02:00
|
|
|
{
|
|
|
|
SendBlock(bitmask_all_link_players_but_self(), gPlayerParty, sizeof(struct Pokemon) * 2);
|
|
|
|
gBattleCommunication[MULTIUSE_STATE]++;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case 4:
|
|
|
|
if ((GetBlockReceivedStatus() & 0xF) == 0xF)
|
|
|
|
{
|
|
|
|
ResetBlockReceivedFlags();
|
|
|
|
for (id = 0; id < MAX_LINK_PLAYERS; id++)
|
|
|
|
{
|
|
|
|
if (id == playerMultiplayerId)
|
|
|
|
{
|
2018-07-22 12:49:49 +02:00
|
|
|
switch (gLinkPlayers[id].id)
|
2017-10-01 01:12:42 +02:00
|
|
|
{
|
|
|
|
case 0:
|
|
|
|
case 3:
|
|
|
|
memcpy(gPlayerParty, gBlockRecvBuffer[id], sizeof(struct Pokemon) * 2);
|
|
|
|
break;
|
|
|
|
case 1:
|
|
|
|
case 2:
|
|
|
|
memcpy(gPlayerParty + 3, gBlockRecvBuffer[id], sizeof(struct Pokemon) * 2);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2018-07-22 12:49:49 +02:00
|
|
|
if ((!(gLinkPlayers[id].id & 1) && !(gLinkPlayers[playerMultiplayerId].id & 1))
|
|
|
|
|| ((gLinkPlayers[id].id & 1) && (gLinkPlayers[playerMultiplayerId].id & 1)))
|
2017-10-01 01:12:42 +02:00
|
|
|
{
|
2018-07-22 12:49:49 +02:00
|
|
|
switch (gLinkPlayers[id].id)
|
2017-10-01 01:12:42 +02:00
|
|
|
{
|
|
|
|
case 0:
|
|
|
|
case 3:
|
|
|
|
memcpy(gPlayerParty, gBlockRecvBuffer[id], sizeof(struct Pokemon) * 2);
|
|
|
|
break;
|
|
|
|
case 1:
|
|
|
|
case 2:
|
|
|
|
memcpy(gPlayerParty + 3, gBlockRecvBuffer[id], sizeof(struct Pokemon) * 2);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2018-07-22 12:49:49 +02:00
|
|
|
switch (gLinkPlayers[id].id)
|
2017-10-01 01:12:42 +02:00
|
|
|
{
|
|
|
|
case 0:
|
|
|
|
case 3:
|
|
|
|
memcpy(gEnemyParty, gBlockRecvBuffer[id], sizeof(struct Pokemon) * 2);
|
|
|
|
break;
|
|
|
|
case 1:
|
|
|
|
case 2:
|
|
|
|
memcpy(gEnemyParty + 3, gBlockRecvBuffer[id], sizeof(struct Pokemon) * 2);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
gBattleCommunication[MULTIUSE_STATE]++;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case 5:
|
2018-12-31 09:22:21 +01:00
|
|
|
if (IsLinkTaskFinished())
|
2017-10-01 01:12:42 +02:00
|
|
|
{
|
|
|
|
SendBlock(bitmask_all_link_players_but_self(), gPlayerParty + 2, sizeof(struct Pokemon));
|
|
|
|
gBattleCommunication[MULTIUSE_STATE]++;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case 6:
|
|
|
|
if ((GetBlockReceivedStatus() & 0xF) == 0xF)
|
|
|
|
{
|
|
|
|
ResetBlockReceivedFlags();
|
|
|
|
for (id = 0; id < MAX_LINK_PLAYERS; id++)
|
|
|
|
{
|
|
|
|
if (id == playerMultiplayerId)
|
|
|
|
{
|
2018-07-22 12:49:49 +02:00
|
|
|
switch (gLinkPlayers[id].id)
|
2017-10-01 01:12:42 +02:00
|
|
|
{
|
|
|
|
case 0:
|
|
|
|
case 3:
|
|
|
|
memcpy(gPlayerParty + 2, gBlockRecvBuffer[id], sizeof(struct Pokemon));
|
|
|
|
break;
|
|
|
|
case 1:
|
|
|
|
case 2:
|
|
|
|
memcpy(gPlayerParty + 5, gBlockRecvBuffer[id], sizeof(struct Pokemon));
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2018-07-22 12:49:49 +02:00
|
|
|
if ((!(gLinkPlayers[id].id & 1) && !(gLinkPlayers[playerMultiplayerId].id & 1))
|
|
|
|
|| ((gLinkPlayers[id].id & 1) && (gLinkPlayers[playerMultiplayerId].id & 1)))
|
2017-10-01 01:12:42 +02:00
|
|
|
{
|
2018-07-22 12:49:49 +02:00
|
|
|
switch (gLinkPlayers[id].id)
|
2017-10-01 01:12:42 +02:00
|
|
|
{
|
|
|
|
case 0:
|
|
|
|
case 3:
|
|
|
|
memcpy(gPlayerParty + 2, gBlockRecvBuffer[id], sizeof(struct Pokemon));
|
|
|
|
break;
|
|
|
|
case 1:
|
|
|
|
case 2:
|
|
|
|
memcpy(gPlayerParty + 5, gBlockRecvBuffer[id], sizeof(struct Pokemon));
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2018-07-22 12:49:49 +02:00
|
|
|
switch (gLinkPlayers[id].id)
|
2017-10-01 01:12:42 +02:00
|
|
|
{
|
|
|
|
case 0:
|
|
|
|
case 3:
|
|
|
|
memcpy(gEnemyParty + 2, gBlockRecvBuffer[id], sizeof(struct Pokemon));
|
|
|
|
break;
|
|
|
|
case 1:
|
|
|
|
case 2:
|
|
|
|
memcpy(gEnemyParty + 5, gBlockRecvBuffer[id], sizeof(struct Pokemon));
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2017-10-01 18:54:01 +02:00
|
|
|
TryCorrectShedinjaLanguage(&gPlayerParty[0]);
|
|
|
|
TryCorrectShedinjaLanguage(&gPlayerParty[1]);
|
|
|
|
TryCorrectShedinjaLanguage(&gPlayerParty[2]);
|
|
|
|
TryCorrectShedinjaLanguage(&gPlayerParty[3]);
|
|
|
|
TryCorrectShedinjaLanguage(&gPlayerParty[4]);
|
|
|
|
TryCorrectShedinjaLanguage(&gPlayerParty[5]);
|
|
|
|
|
|
|
|
TryCorrectShedinjaLanguage(&gEnemyParty[0]);
|
|
|
|
TryCorrectShedinjaLanguage(&gEnemyParty[1]);
|
|
|
|
TryCorrectShedinjaLanguage(&gEnemyParty[2]);
|
|
|
|
TryCorrectShedinjaLanguage(&gEnemyParty[3]);
|
|
|
|
TryCorrectShedinjaLanguage(&gEnemyParty[4]);
|
|
|
|
TryCorrectShedinjaLanguage(&gEnemyParty[5]);
|
2017-10-01 01:12:42 +02:00
|
|
|
|
|
|
|
gBattleCommunication[MULTIUSE_STATE]++;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case 7:
|
|
|
|
sub_8032768();
|
|
|
|
sub_8184E58();
|
|
|
|
gBattleCommunication[SPRITES_INIT_STATE1] = 0;
|
|
|
|
gBattleCommunication[SPRITES_INIT_STATE2] = 0;
|
|
|
|
if (gBattleTypeFlags & BATTLE_TYPE_LINK)
|
|
|
|
{
|
|
|
|
for (id = 0; id < 4 && (gLinkPlayers[id].version & 0xFF) == 3; id++);
|
|
|
|
|
|
|
|
if (id == 4)
|
|
|
|
gBattleCommunication[MULTIUSE_STATE] = 8;
|
|
|
|
else
|
|
|
|
gBattleCommunication[MULTIUSE_STATE] = 10;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
gBattleCommunication[MULTIUSE_STATE] = 10;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case 8:
|
2018-12-31 09:22:21 +01:00
|
|
|
if (IsLinkTaskFinished())
|
2017-10-01 01:12:42 +02:00
|
|
|
{
|
|
|
|
u32* ptr = (u32*)(&gBattleStruct->field_180);
|
|
|
|
ptr[0] = gBattleTypeFlags;
|
|
|
|
ptr[1] = gRecordedBattleRngSeed; // UB: overwrites berry data
|
|
|
|
SendBlock(bitmask_all_link_players_but_self(), ptr, 8);
|
|
|
|
gBattleCommunication[MULTIUSE_STATE]++;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case 9:
|
|
|
|
if ((GetBlockReceivedStatus() & 0xF) == 0xF)
|
|
|
|
{
|
|
|
|
ResetBlockReceivedFlags();
|
|
|
|
for (var = 0; var < 4; var++)
|
|
|
|
{
|
|
|
|
u32 blockValue = gBlockRecvBuffer[var][0];
|
|
|
|
if (blockValue & 4)
|
|
|
|
{
|
|
|
|
memcpy(&gRecordedBattleRngSeed, &gBlockRecvBuffer[var][2], sizeof(gRecordedBattleRngSeed));
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
gBattleCommunication[MULTIUSE_STATE]++;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case 10:
|
|
|
|
if (BattleInitAllSprites(&gBattleCommunication[SPRITES_INIT_STATE1], &gBattleCommunication[SPRITES_INIT_STATE2]))
|
|
|
|
{
|
|
|
|
gPreBattleCallback1 = gMain.callback1;
|
|
|
|
gMain.callback1 = BattleMainCB1;
|
|
|
|
SetMainCallback2(BattleMainCB2);
|
|
|
|
if (gBattleTypeFlags & BATTLE_TYPE_LINK)
|
|
|
|
{
|
2018-07-01 11:15:42 +02:00
|
|
|
gTrainerBattleOpponent_A = TRAINER_LINK_OPPONENT;
|
2017-10-01 01:12:42 +02:00
|
|
|
gBattleTypeFlags |= BATTLE_TYPE_20;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-10-01 18:54:01 +02:00
|
|
|
void BattleMainCB2(void)
|
|
|
|
{
|
|
|
|
AnimateSprites();
|
|
|
|
BuildOamBuffer();
|
|
|
|
RunTextPrinters();
|
|
|
|
UpdatePaletteFade();
|
|
|
|
RunTasks();
|
|
|
|
|
|
|
|
if (gMain.heldKeys & B_BUTTON && gBattleTypeFlags & BATTLE_TYPE_RECORDED && sub_8186450())
|
|
|
|
{
|
2018-01-16 22:12:38 +01:00
|
|
|
gSpecialVar_Result = gBattleOutcome = B_OUTCOME_PLAYER_TELEPORTED;
|
2017-10-01 18:54:01 +02:00
|
|
|
ResetPaletteFadeControl();
|
2018-07-16 20:23:05 +02:00
|
|
|
BeginNormalPaletteFade(0xFFFFFFFF, 0, 0, 0x10, RGB_BLACK);
|
2017-10-01 18:54:01 +02:00
|
|
|
SetMainCallback2(CB2_QuitRecordedBattle);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static void FreeRestoreBattleData(void)
|
|
|
|
{
|
|
|
|
gMain.callback1 = gPreBattleCallback1;
|
2018-01-29 17:47:12 +01:00
|
|
|
gScanlineEffect.state = 3;
|
2017-10-01 18:54:01 +02:00
|
|
|
gMain.inBattle = 0;
|
|
|
|
ZeroEnemyPartyMons();
|
2018-05-11 07:33:32 +02:00
|
|
|
m4aSongNumStop(SE_HINSI);
|
2017-10-01 18:54:01 +02:00
|
|
|
FreeMonSpritesGfx();
|
|
|
|
FreeBattleSpritesData();
|
|
|
|
FreeBattleResources();
|
|
|
|
}
|
|
|
|
|
|
|
|
void CB2_QuitRecordedBattle(void)
|
|
|
|
{
|
|
|
|
UpdatePaletteFade();
|
|
|
|
if (!gPaletteFade.active)
|
|
|
|
{
|
2018-01-10 04:30:54 +01:00
|
|
|
m4aMPlayStop(&gMPlayInfo_SE1);
|
|
|
|
m4aMPlayStop(&gMPlayInfo_SE2);
|
2017-10-01 18:54:01 +02:00
|
|
|
FreeRestoreBattleData();
|
|
|
|
FreeAllWindowBuffers();
|
|
|
|
SetMainCallback2(gMain.savedCallback);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-10-09 20:32:26 +02:00
|
|
|
void sub_8038528(struct Sprite* sprite)
|
2017-10-01 18:54:01 +02:00
|
|
|
{
|
2017-12-02 21:44:50 +01:00
|
|
|
sprite->data[0] = 0;
|
2017-10-01 18:54:01 +02:00
|
|
|
sprite->callback = sub_8038538;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void sub_8038538(struct Sprite *sprite)
|
|
|
|
{
|
|
|
|
u16 *arr = (u16*)(gDecompressionBuffer);
|
|
|
|
|
2017-12-02 21:44:50 +01:00
|
|
|
switch (sprite->data[0])
|
2017-10-01 18:54:01 +02:00
|
|
|
{
|
|
|
|
case 0:
|
2017-12-02 21:44:50 +01:00
|
|
|
sprite->data[0]++;
|
|
|
|
sprite->data[1] = 0;
|
|
|
|
sprite->data[2] = 0x281;
|
|
|
|
sprite->data[3] = 0;
|
|
|
|
sprite->data[4] = 1;
|
2017-10-01 18:54:01 +02:00
|
|
|
// fall through
|
|
|
|
case 1:
|
2017-12-02 21:44:50 +01:00
|
|
|
sprite->data[4]--;
|
|
|
|
if (sprite->data[4] == 0)
|
2017-10-01 18:54:01 +02:00
|
|
|
{
|
|
|
|
s32 i;
|
|
|
|
s32 r2;
|
|
|
|
s32 r0;
|
|
|
|
|
2017-12-02 21:44:50 +01:00
|
|
|
sprite->data[4] = 2;
|
|
|
|
r2 = sprite->data[1] + sprite->data[3] * 32;
|
|
|
|
r0 = sprite->data[2] - sprite->data[3] * 32;
|
2017-10-01 18:54:01 +02:00
|
|
|
for (i = 0; i < 29; i += 2)
|
|
|
|
{
|
|
|
|
arr[r2 + i] = 0x3D;
|
|
|
|
arr[r0 + i] = 0x3D;
|
|
|
|
}
|
2017-12-02 21:44:50 +01:00
|
|
|
sprite->data[3]++;
|
|
|
|
if (sprite->data[3] == 21)
|
2017-10-01 18:54:01 +02:00
|
|
|
{
|
2017-12-02 21:44:50 +01:00
|
|
|
sprite->data[0]++;
|
|
|
|
sprite->data[1] = 32;
|
2017-10-01 18:54:01 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case 2:
|
2017-12-02 21:44:50 +01:00
|
|
|
sprite->data[1]--;
|
|
|
|
if (sprite->data[1] == 20)
|
2017-10-01 18:54:01 +02:00
|
|
|
SetMainCallback2(CB2_InitBattle);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static u8 CreateNPCTrainerParty(struct Pokemon *party, u16 trainerNum, bool8 firstTrainer)
|
|
|
|
{
|
|
|
|
u32 nameHash = 0;
|
|
|
|
u32 personalityValue;
|
|
|
|
u8 fixedIV;
|
|
|
|
s32 i, j;
|
|
|
|
u8 monsCount;
|
|
|
|
|
2018-06-30 18:55:34 +02:00
|
|
|
if (trainerNum == TRAINER_SECRET_BASE)
|
2017-10-01 18:54:01 +02:00
|
|
|
return 0;
|
|
|
|
|
|
|
|
if (gBattleTypeFlags & BATTLE_TYPE_TRAINER && !(gBattleTypeFlags & (BATTLE_TYPE_FRONTIER
|
|
|
|
| BATTLE_TYPE_EREADER_TRAINER
|
2018-09-20 22:00:00 +02:00
|
|
|
| BATTLE_TYPE_TRAINER_HILL)))
|
2017-10-01 18:54:01 +02:00
|
|
|
{
|
|
|
|
if (firstTrainer == TRUE)
|
|
|
|
ZeroEnemyPartyMons();
|
|
|
|
|
|
|
|
if (gBattleTypeFlags & BATTLE_TYPE_TWO_OPPONENTS)
|
|
|
|
{
|
|
|
|
if (gTrainers[trainerNum].partySize > 3)
|
|
|
|
monsCount = 3;
|
|
|
|
else
|
|
|
|
monsCount = gTrainers[trainerNum].partySize;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
monsCount = gTrainers[trainerNum].partySize;
|
|
|
|
}
|
|
|
|
|
|
|
|
for (i = 0; i < monsCount; i++)
|
|
|
|
{
|
|
|
|
|
|
|
|
if (gTrainers[trainerNum].doubleBattle == TRUE)
|
|
|
|
personalityValue = 0x80;
|
|
|
|
else if (gTrainers[trainerNum].encounterMusic_gender & 0x80)
|
|
|
|
personalityValue = 0x78;
|
|
|
|
else
|
|
|
|
personalityValue = 0x88;
|
|
|
|
|
2018-02-08 11:17:41 +01:00
|
|
|
for (j = 0; gTrainers[trainerNum].trainerName[j] != EOS; j++)
|
2017-10-01 18:54:01 +02:00
|
|
|
nameHash += gTrainers[trainerNum].trainerName[j];
|
|
|
|
|
|
|
|
switch (gTrainers[trainerNum].partyFlags)
|
|
|
|
{
|
|
|
|
case 0:
|
|
|
|
{
|
|
|
|
const struct TrainerMonNoItemDefaultMoves *partyData = gTrainers[trainerNum].party.NoItemDefaultMoves;
|
|
|
|
|
2017-12-17 21:19:08 +01:00
|
|
|
for (j = 0; gSpeciesNames[partyData[i].species][j] != EOS; j++)
|
2017-10-01 18:54:01 +02:00
|
|
|
nameHash += gSpeciesNames[partyData[i].species][j];
|
|
|
|
|
|
|
|
personalityValue += nameHash << 8;
|
|
|
|
fixedIV = partyData[i].iv * 31 / 255;
|
|
|
|
CreateMon(&party[i], partyData[i].species, partyData[i].lvl, fixedIV, TRUE, personalityValue, OT_ID_RANDOM_NO_SHINY, 0);
|
|
|
|
break;
|
|
|
|
}
|
2017-12-17 21:19:08 +01:00
|
|
|
case F_TRAINER_PARTY_CUSTOM_MOVESET:
|
2017-10-01 18:54:01 +02:00
|
|
|
{
|
|
|
|
const struct TrainerMonNoItemCustomMoves *partyData = gTrainers[trainerNum].party.NoItemCustomMoves;
|
|
|
|
|
2017-12-17 21:19:08 +01:00
|
|
|
for (j = 0; gSpeciesNames[partyData[i].species][j] != EOS; j++)
|
2017-10-01 18:54:01 +02:00
|
|
|
nameHash += gSpeciesNames[partyData[i].species][j];
|
|
|
|
|
|
|
|
personalityValue += nameHash << 8;
|
|
|
|
fixedIV = partyData[i].iv * 31 / 255;
|
|
|
|
CreateMon(&party[i], partyData[i].species, partyData[i].lvl, fixedIV, TRUE, personalityValue, 2, 0);
|
|
|
|
|
2018-12-25 18:50:15 +01:00
|
|
|
for (j = 0; j < MAX_MON_MOVES; j++)
|
2017-10-01 18:54:01 +02:00
|
|
|
{
|
|
|
|
SetMonData(&party[i], MON_DATA_MOVE1 + j, &partyData[i].moves[j]);
|
|
|
|
SetMonData(&party[i], MON_DATA_PP1 + j, &gBattleMoves[partyData[i].moves[j]].pp);
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
2017-12-17 21:19:08 +01:00
|
|
|
case F_TRAINER_PARTY_HELD_ITEM:
|
2017-10-01 18:54:01 +02:00
|
|
|
{
|
|
|
|
const struct TrainerMonItemDefaultMoves *partyData = gTrainers[trainerNum].party.ItemDefaultMoves;
|
|
|
|
|
2017-12-17 21:19:08 +01:00
|
|
|
for (j = 0; gSpeciesNames[partyData[i].species][j] != EOS; j++)
|
2017-10-01 18:54:01 +02:00
|
|
|
nameHash += gSpeciesNames[partyData[i].species][j];
|
|
|
|
|
|
|
|
personalityValue += nameHash << 8;
|
|
|
|
fixedIV = partyData[i].iv * 31 / 255;
|
|
|
|
CreateMon(&party[i], partyData[i].species, partyData[i].lvl, fixedIV, TRUE, personalityValue, 2, 0);
|
|
|
|
|
|
|
|
SetMonData(&party[i], MON_DATA_HELD_ITEM, &partyData[i].heldItem);
|
|
|
|
break;
|
|
|
|
}
|
2017-12-17 21:19:08 +01:00
|
|
|
case F_TRAINER_PARTY_CUSTOM_MOVESET | F_TRAINER_PARTY_HELD_ITEM:
|
2017-10-01 18:54:01 +02:00
|
|
|
{
|
|
|
|
const struct TrainerMonItemCustomMoves *partyData = gTrainers[trainerNum].party.ItemCustomMoves;
|
|
|
|
|
2017-12-17 21:19:08 +01:00
|
|
|
for (j = 0; gSpeciesNames[partyData[i].species][j] != EOS; j++)
|
2017-10-01 18:54:01 +02:00
|
|
|
nameHash += gSpeciesNames[partyData[i].species][j];
|
|
|
|
|
|
|
|
personalityValue += nameHash << 8;
|
|
|
|
fixedIV = partyData[i].iv * 31 / 255;
|
|
|
|
CreateMon(&party[i], partyData[i].species, partyData[i].lvl, fixedIV, TRUE, personalityValue, 2, 0);
|
|
|
|
|
|
|
|
SetMonData(&party[i], MON_DATA_HELD_ITEM, &partyData[i].heldItem);
|
|
|
|
|
2018-12-25 18:50:15 +01:00
|
|
|
for (j = 0; j < MAX_MON_MOVES; j++)
|
2017-10-01 18:54:01 +02:00
|
|
|
{
|
|
|
|
SetMonData(&party[i], MON_DATA_MOVE1 + j, &partyData[i].moves[j]);
|
|
|
|
SetMonData(&party[i], MON_DATA_PP1 + j, &gBattleMoves[partyData[i].moves[j]].pp);
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
gBattleTypeFlags |= gTrainers[trainerNum].doubleBattle;
|
|
|
|
}
|
|
|
|
|
|
|
|
return gTrainers[trainerNum].partySize;
|
|
|
|
}
|
|
|
|
|
|
|
|
void VBlankCB_Battle(void)
|
|
|
|
{
|
2018-06-20 23:07:51 +02:00
|
|
|
// Change gRngSeed every vblank unless the battle could be recorded.
|
2017-10-01 18:54:01 +02:00
|
|
|
if (!(gBattleTypeFlags & (BATTLE_TYPE_LINK | BATTLE_TYPE_FRONTIER | BATTLE_TYPE_RECORDED)))
|
|
|
|
Random();
|
|
|
|
|
|
|
|
SetGpuReg(REG_OFFSET_BG0HOFS, gBattle_BG0_X);
|
|
|
|
SetGpuReg(REG_OFFSET_BG0VOFS, gBattle_BG0_Y);
|
|
|
|
SetGpuReg(REG_OFFSET_BG1HOFS, gBattle_BG1_X);
|
|
|
|
SetGpuReg(REG_OFFSET_BG1VOFS, gBattle_BG1_Y);
|
|
|
|
SetGpuReg(REG_OFFSET_BG2HOFS, gBattle_BG2_X);
|
|
|
|
SetGpuReg(REG_OFFSET_BG2VOFS, gBattle_BG2_Y);
|
|
|
|
SetGpuReg(REG_OFFSET_BG3HOFS, gBattle_BG3_X);
|
|
|
|
SetGpuReg(REG_OFFSET_BG3VOFS, gBattle_BG3_Y);
|
|
|
|
SetGpuReg(REG_OFFSET_WIN0H, gBattle_WIN0H);
|
|
|
|
SetGpuReg(REG_OFFSET_WIN0V, gBattle_WIN0V);
|
|
|
|
SetGpuReg(REG_OFFSET_WIN1H, gBattle_WIN1H);
|
|
|
|
SetGpuReg(REG_OFFSET_WIN1V, gBattle_WIN1V);
|
|
|
|
LoadOam();
|
|
|
|
ProcessSpriteCopyRequests();
|
|
|
|
TransferPlttBuffer();
|
2018-01-29 17:47:12 +01:00
|
|
|
ScanlineEffect_InitHBlankDmaTransfer();
|
2017-10-01 18:54:01 +02:00
|
|
|
}
|
|
|
|
|
2018-09-12 00:37:47 +02:00
|
|
|
void nullsub_17(struct Sprite *sprite)
|
2017-10-01 18:54:01 +02:00
|
|
|
{
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
static void sub_8038B04(struct Sprite *sprite)
|
|
|
|
{
|
2017-12-02 21:44:50 +01:00
|
|
|
if (sprite->data[0] != 0)
|
|
|
|
sprite->pos1.x = sprite->data[1] + ((sprite->data[2] & 0xFF00) >> 8);
|
2017-10-01 18:54:01 +02:00
|
|
|
else
|
2017-12-02 21:44:50 +01:00
|
|
|
sprite->pos1.x = sprite->data[1] - ((sprite->data[2] & 0xFF00) >> 8);
|
2017-10-01 18:54:01 +02:00
|
|
|
|
2017-12-02 21:44:50 +01:00
|
|
|
sprite->data[2] += 0x180;
|
2017-10-01 18:54:01 +02:00
|
|
|
|
|
|
|
if (sprite->affineAnimEnded)
|
|
|
|
{
|
|
|
|
FreeSpriteTilesByTag(0x2710);
|
|
|
|
FreeSpritePaletteByTag(0x2710);
|
|
|
|
FreeSpriteOamMatrix(sprite);
|
|
|
|
DestroySprite(sprite);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void sub_8038B74(struct Sprite *sprite)
|
|
|
|
{
|
|
|
|
StartSpriteAffineAnim(sprite, 1);
|
|
|
|
sprite->callback = sub_8038B04;
|
|
|
|
PlaySE(SE_BT_START);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void sub_8038B94(u8 taskId)
|
|
|
|
{
|
|
|
|
struct Pokemon *sp4 = NULL;
|
|
|
|
struct Pokemon *sp8 = NULL;
|
|
|
|
u8 r2 = gBattleScripting.multiplayerId;
|
|
|
|
u32 r7;
|
|
|
|
s32 i;
|
|
|
|
|
|
|
|
if (gBattleTypeFlags & BATTLE_TYPE_MULTI)
|
|
|
|
{
|
2018-07-22 12:49:49 +02:00
|
|
|
switch (gLinkPlayers[r2].id)
|
2017-10-01 18:54:01 +02:00
|
|
|
{
|
|
|
|
case 0:
|
|
|
|
case 2:
|
|
|
|
sp4 = gPlayerParty;
|
|
|
|
sp8 = gEnemyParty;
|
|
|
|
break;
|
|
|
|
case 1:
|
|
|
|
case 3:
|
|
|
|
sp4 = gEnemyParty;
|
|
|
|
sp8 = gPlayerParty;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
sp4 = gPlayerParty;
|
|
|
|
sp8 = gEnemyParty;
|
|
|
|
}
|
|
|
|
|
|
|
|
r7 = 0;
|
2017-11-26 13:26:58 +01:00
|
|
|
for (i = 0; i < PARTY_SIZE; i++)
|
2017-10-01 18:54:01 +02:00
|
|
|
{
|
|
|
|
u16 species = GetMonData(&sp4[i], MON_DATA_SPECIES2);
|
|
|
|
u16 hp = GetMonData(&sp4[i], MON_DATA_HP);
|
|
|
|
u32 status = GetMonData(&sp4[i], MON_DATA_STATUS);
|
|
|
|
|
|
|
|
if (species == SPECIES_NONE)
|
|
|
|
continue;
|
|
|
|
if (species != SPECIES_EGG && hp != 0 && status == 0)
|
|
|
|
r7 |= 1 << i * 2;
|
|
|
|
|
2018-12-18 15:35:31 +01:00
|
|
|
if (species == SPECIES_NONE)
|
2017-10-01 18:54:01 +02:00
|
|
|
continue;
|
|
|
|
if (hp != 0 && (species == SPECIES_EGG || status != 0))
|
|
|
|
r7 |= 2 << i * 2;
|
|
|
|
|
2018-12-18 15:35:31 +01:00
|
|
|
if (species == SPECIES_NONE)
|
2017-10-01 18:54:01 +02:00
|
|
|
continue;
|
|
|
|
if (species != SPECIES_EGG && hp == 0)
|
|
|
|
r7 |= 3 << i * 2;
|
|
|
|
}
|
|
|
|
gTasks[taskId].data[3] = r7;
|
|
|
|
|
|
|
|
r7 = 0;
|
2017-11-26 13:26:58 +01:00
|
|
|
for (i = 0; i < PARTY_SIZE; i++)
|
2017-10-01 18:54:01 +02:00
|
|
|
{
|
|
|
|
u16 species = GetMonData(&sp8[i], MON_DATA_SPECIES2);
|
|
|
|
u16 hp = GetMonData(&sp8[i], MON_DATA_HP);
|
|
|
|
u32 status = GetMonData(&sp8[i], MON_DATA_STATUS);
|
|
|
|
|
|
|
|
if (species == SPECIES_NONE)
|
|
|
|
continue;
|
|
|
|
if (species != SPECIES_EGG && hp != 0 && status == 0)
|
|
|
|
r7 |= 1 << i * 2;
|
|
|
|
|
|
|
|
if (species == SPECIES_NONE)
|
|
|
|
continue;
|
|
|
|
if (hp != 0 && (species == SPECIES_EGG || status != 0))
|
|
|
|
r7 |= 2 << i * 2;
|
|
|
|
|
|
|
|
if (species == SPECIES_NONE)
|
|
|
|
continue;
|
|
|
|
if (species != SPECIES_EGG && hp == 0)
|
|
|
|
r7 |= 3 << i * 2;
|
|
|
|
}
|
|
|
|
gTasks[taskId].data[4] = r7;
|
|
|
|
}
|
|
|
|
|
|
|
|
void sub_8038D64(void)
|
|
|
|
{
|
|
|
|
s32 i;
|
|
|
|
u8 taskId;
|
|
|
|
|
|
|
|
SetHBlankCallback(NULL);
|
|
|
|
SetVBlankCallback(NULL);
|
|
|
|
gBattleTypeFlags &= ~(BATTLE_TYPE_20);
|
|
|
|
|
|
|
|
if (gBattleTypeFlags & BATTLE_TYPE_FRONTIER)
|
|
|
|
{
|
|
|
|
SetMainCallback2(gMain.savedCallback);
|
|
|
|
FreeBattleResources();
|
|
|
|
FreeBattleSpritesData();
|
|
|
|
FreeMonSpritesGfx();
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
CpuFill32(0, (void*)(VRAM), VRAM_SIZE);
|
|
|
|
SetGpuReg(REG_OFFSET_MOSAIC, 0);
|
|
|
|
SetGpuReg(REG_OFFSET_WIN0H, 0xF0);
|
|
|
|
SetGpuReg(REG_OFFSET_WIN0V, 0x5051);
|
|
|
|
SetGpuReg(REG_OFFSET_WININ, 0);
|
|
|
|
SetGpuReg(REG_OFFSET_WINOUT, 0);
|
|
|
|
gBattle_WIN0H = 0xF0;
|
|
|
|
gBattle_WIN0V = 0x5051;
|
2018-01-29 17:47:12 +01:00
|
|
|
ScanlineEffect_Clear();
|
2017-10-01 18:54:01 +02:00
|
|
|
|
2019-01-05 19:25:46 +01:00
|
|
|
i = 0;
|
|
|
|
while (i < 80)
|
2017-10-01 18:54:01 +02:00
|
|
|
{
|
2018-01-29 17:47:12 +01:00
|
|
|
gScanlineEffectRegBuffers[0][i] = 0xF0;
|
|
|
|
gScanlineEffectRegBuffers[1][i] = 0xF0;
|
2019-01-05 19:25:46 +01:00
|
|
|
i++;
|
2017-10-01 18:54:01 +02:00
|
|
|
}
|
2019-01-05 19:25:46 +01:00
|
|
|
|
|
|
|
while (i < 160)
|
2017-10-01 18:54:01 +02:00
|
|
|
{
|
2018-01-29 17:47:12 +01:00
|
|
|
gScanlineEffectRegBuffers[0][i] = 0xFF10;
|
|
|
|
gScanlineEffectRegBuffers[1][i] = 0xFF10;
|
2019-01-05 19:25:46 +01:00
|
|
|
i++;
|
2017-10-01 18:54:01 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
ResetPaletteFade();
|
|
|
|
|
|
|
|
gBattle_BG0_X = 0;
|
|
|
|
gBattle_BG0_Y = 0;
|
|
|
|
gBattle_BG1_X = 0;
|
|
|
|
gBattle_BG1_Y = 0;
|
|
|
|
gBattle_BG2_X = 0;
|
|
|
|
gBattle_BG2_Y = 0;
|
|
|
|
gBattle_BG3_X = 0;
|
|
|
|
gBattle_BG3_Y = 0;
|
|
|
|
|
|
|
|
sub_80356D0();
|
2017-12-17 20:10:57 +01:00
|
|
|
LoadCompressedPalette(gBattleTextboxPalette, 0, 64);
|
2018-06-17 16:48:58 +02:00
|
|
|
LoadBattleMenuWindowGfx();
|
2017-10-01 18:54:01 +02:00
|
|
|
ResetSpriteData();
|
|
|
|
ResetTasks();
|
2018-06-17 16:48:58 +02:00
|
|
|
DrawBattleEntryBackground();
|
2017-10-01 18:54:01 +02:00
|
|
|
SetGpuReg(REG_OFFSET_WINOUT, 0x37);
|
|
|
|
FreeAllSpritePalettes();
|
|
|
|
gReservedSpritePaletteCount = 4;
|
|
|
|
SetVBlankCallback(VBlankCB_Battle);
|
|
|
|
|
2017-12-17 20:10:57 +01:00
|
|
|
taskId = CreateTask(sub_8035D74, 0);
|
2017-10-01 18:54:01 +02:00
|
|
|
gTasks[taskId].data[1] = 0x10E;
|
|
|
|
gTasks[taskId].data[2] = 0x5A;
|
|
|
|
gTasks[taskId].data[5] = 1;
|
|
|
|
sub_8038B94(taskId);
|
|
|
|
SetMainCallback2(sub_8038F14);
|
|
|
|
gBattleCommunication[MULTIUSE_STATE] = 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static void sub_8038F14(void)
|
|
|
|
{
|
|
|
|
sub_8038F34();
|
|
|
|
AnimateSprites();
|
|
|
|
BuildOamBuffer();
|
|
|
|
RunTextPrinters();
|
|
|
|
UpdatePaletteFade();
|
|
|
|
RunTasks();
|
|
|
|
}
|
|
|
|
|
|
|
|
static void sub_8038F34(void)
|
|
|
|
{
|
|
|
|
s32 i;
|
|
|
|
|
|
|
|
switch (gBattleCommunication[MULTIUSE_STATE])
|
|
|
|
{
|
|
|
|
case 0:
|
|
|
|
ShowBg(0);
|
|
|
|
ShowBg(1);
|
|
|
|
ShowBg(2);
|
|
|
|
gBattleCommunication[1] = 0xFF;
|
|
|
|
gBattleCommunication[MULTIUSE_STATE]++;
|
|
|
|
break;
|
|
|
|
case 1:
|
|
|
|
if (--gBattleCommunication[1] == 0)
|
|
|
|
{
|
2018-07-16 20:23:05 +02:00
|
|
|
BeginNormalPaletteFade(0xFFFFFFFF, 0, 0, 0x10, RGB_BLACK);
|
2017-10-01 18:54:01 +02:00
|
|
|
gBattleCommunication[MULTIUSE_STATE]++;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case 2:
|
|
|
|
if (!gPaletteFade.active)
|
|
|
|
{
|
|
|
|
u8 monsCount;
|
|
|
|
|
|
|
|
gMain.field_439_x4 = sub_8185FAC();
|
|
|
|
|
|
|
|
if (gBattleTypeFlags & BATTLE_TYPE_MULTI)
|
|
|
|
monsCount = 4;
|
|
|
|
else
|
|
|
|
monsCount = 2;
|
|
|
|
|
2017-10-13 17:09:36 +02:00
|
|
|
for (i = 0; i < monsCount && (gLinkPlayers[i].version & 0xFF) == VERSION_EMERALD; i++);
|
2017-10-01 18:54:01 +02:00
|
|
|
|
2018-06-17 12:30:09 +02:00
|
|
|
if (!gSaveBlock2Ptr->frontier.field_CA9_b && i == monsCount)
|
2017-10-01 18:54:01 +02:00
|
|
|
{
|
2017-11-08 22:20:10 +01:00
|
|
|
if (FlagGet(FLAG_SYS_FRONTIER_PASS))
|
2017-10-01 18:54:01 +02:00
|
|
|
{
|
|
|
|
FreeAllWindowBuffers();
|
|
|
|
SetMainCallback2(sub_80392A8);
|
|
|
|
}
|
|
|
|
else if (!gMain.field_439_x4)
|
|
|
|
{
|
|
|
|
SetMainCallback2(gMain.savedCallback);
|
|
|
|
FreeBattleResources();
|
|
|
|
FreeBattleSpritesData();
|
|
|
|
FreeMonSpritesGfx();
|
|
|
|
}
|
|
|
|
else if (gReceivedRemoteLinkPlayers == 0)
|
|
|
|
{
|
|
|
|
CreateTask(sub_80B3AF8, 5);
|
|
|
|
gBattleCommunication[MULTIUSE_STATE]++;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
gBattleCommunication[MULTIUSE_STATE]++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
SetMainCallback2(gMain.savedCallback);
|
|
|
|
FreeBattleResources();
|
|
|
|
FreeBattleSpritesData();
|
|
|
|
FreeMonSpritesGfx();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case 3:
|
|
|
|
CpuFill32(0, (void*)(VRAM), VRAM_SIZE);
|
|
|
|
|
|
|
|
for (i = 0; i < 2; i++)
|
|
|
|
LoadChosenBattleElement(i);
|
|
|
|
|
2018-07-16 20:23:05 +02:00
|
|
|
BeginNormalPaletteFade(0xFFFFFFFF, 0, 0x10, 0, RGB_BLACK);
|
2017-10-01 18:54:01 +02:00
|
|
|
gBattleCommunication[MULTIUSE_STATE]++;
|
|
|
|
break;
|
|
|
|
case 4:
|
|
|
|
if (!gPaletteFade.active)
|
|
|
|
gBattleCommunication[MULTIUSE_STATE]++;
|
|
|
|
break;
|
|
|
|
case 5:
|
|
|
|
if (!FuncIsActiveTask(sub_80B3AF8))
|
|
|
|
gBattleCommunication[MULTIUSE_STATE]++;
|
|
|
|
break;
|
|
|
|
case 6:
|
2018-12-31 09:22:21 +01:00
|
|
|
if (IsLinkTaskFinished() == TRUE)
|
2017-10-01 18:54:01 +02:00
|
|
|
{
|
|
|
|
sub_800ADF8();
|
2018-06-17 16:48:58 +02:00
|
|
|
BattlePutTextOnWindow(gText_LinkStandby3, 0);
|
2017-10-01 18:54:01 +02:00
|
|
|
gBattleCommunication[MULTIUSE_STATE]++;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case 7:
|
|
|
|
if (!IsTextPrinterActive(0))
|
|
|
|
{
|
2018-12-31 09:22:21 +01:00
|
|
|
if (IsLinkTaskFinished() == TRUE)
|
2017-10-01 18:54:01 +02:00
|
|
|
gBattleCommunication[MULTIUSE_STATE]++;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case 8:
|
2017-11-13 05:58:05 +01:00
|
|
|
if (!gWirelessCommType)
|
2017-10-01 18:54:01 +02:00
|
|
|
sub_800AC34();
|
|
|
|
gBattleCommunication[MULTIUSE_STATE]++;
|
|
|
|
break;
|
|
|
|
case 9:
|
2017-11-13 05:58:05 +01:00
|
|
|
if (!gMain.field_439_x4 || gWirelessCommType || gReceivedRemoteLinkPlayers != 1)
|
2017-10-01 18:54:01 +02:00
|
|
|
{
|
|
|
|
gMain.field_439_x4 = 0;
|
|
|
|
SetMainCallback2(gMain.savedCallback);
|
|
|
|
FreeBattleResources();
|
|
|
|
FreeBattleSpritesData();
|
|
|
|
FreeMonSpritesGfx();
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
u32 sub_80391E0(u8 arrayId, u8 caseId)
|
|
|
|
{
|
|
|
|
u32 ret = 0;
|
|
|
|
|
|
|
|
switch (caseId)
|
|
|
|
{
|
|
|
|
case 0:
|
2018-06-17 16:48:58 +02:00
|
|
|
ret = gBattleBgTemplates[arrayId].bg;
|
2017-10-01 18:54:01 +02:00
|
|
|
break;
|
|
|
|
case 1:
|
2018-06-17 16:48:58 +02:00
|
|
|
ret = gBattleBgTemplates[arrayId].charBaseIndex;
|
2017-10-01 18:54:01 +02:00
|
|
|
break;
|
|
|
|
case 2:
|
2018-06-17 16:48:58 +02:00
|
|
|
ret = gBattleBgTemplates[arrayId].mapBaseIndex;
|
2017-10-01 18:54:01 +02:00
|
|
|
break;
|
|
|
|
case 3:
|
2018-06-17 16:48:58 +02:00
|
|
|
ret = gBattleBgTemplates[arrayId].screenSize;
|
2017-10-01 18:54:01 +02:00
|
|
|
break;
|
|
|
|
case 4:
|
2018-06-17 16:48:58 +02:00
|
|
|
ret = gBattleBgTemplates[arrayId].paletteMode;
|
2017-10-01 18:54:01 +02:00
|
|
|
break;
|
|
|
|
case 5:
|
2018-06-17 16:48:58 +02:00
|
|
|
ret = gBattleBgTemplates[arrayId].priority;
|
2017-10-01 18:54:01 +02:00
|
|
|
break;
|
|
|
|
case 6:
|
2018-06-17 16:48:58 +02:00
|
|
|
ret = gBattleBgTemplates[arrayId].baseTile;
|
2017-10-01 18:54:01 +02:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void sub_80392A8(void)
|
|
|
|
{
|
|
|
|
s32 i;
|
|
|
|
|
|
|
|
SetHBlankCallback(NULL);
|
|
|
|
SetVBlankCallback(NULL);
|
|
|
|
CpuFill32(0, (void*)(VRAM), VRAM_SIZE);
|
|
|
|
ResetPaletteFade();
|
|
|
|
gBattle_BG0_X = 0;
|
|
|
|
gBattle_BG0_Y = 0;
|
|
|
|
gBattle_BG1_X = 0;
|
|
|
|
gBattle_BG1_Y = 0;
|
|
|
|
gBattle_BG2_X = 0;
|
|
|
|
gBattle_BG2_Y = 0;
|
|
|
|
gBattle_BG3_X = 0;
|
|
|
|
gBattle_BG3_Y = 0;
|
|
|
|
sub_80356D0();
|
|
|
|
SetGpuReg(REG_OFFSET_DISPCNT, DISPCNT_OBJ_ON | DISPCNT_OBJ_1D_MAP);
|
2018-06-17 16:48:58 +02:00
|
|
|
LoadBattleMenuWindowGfx();
|
2017-10-01 18:54:01 +02:00
|
|
|
|
|
|
|
for (i = 0; i < 2; i++)
|
|
|
|
LoadChosenBattleElement(i);
|
|
|
|
|
|
|
|
ResetSpriteData();
|
|
|
|
ResetTasks();
|
|
|
|
FreeAllSpritePalettes();
|
|
|
|
gReservedSpritePaletteCount = 4;
|
|
|
|
SetVBlankCallback(VBlankCB_Battle);
|
|
|
|
SetMainCallback2(sub_803937C);
|
2018-07-16 20:23:05 +02:00
|
|
|
BeginNormalPaletteFade(0xFFFFFFFF, 0, 0x10, 0, RGB_BLACK);
|
2017-10-01 18:54:01 +02:00
|
|
|
gBattleCommunication[MULTIUSE_STATE] = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void sub_803937C(void)
|
|
|
|
{
|
|
|
|
sub_803939C();
|
|
|
|
AnimateSprites();
|
|
|
|
BuildOamBuffer();
|
|
|
|
RunTextPrinters();
|
|
|
|
UpdatePaletteFade();
|
|
|
|
RunTasks();
|
|
|
|
}
|
|
|
|
|
|
|
|
static void sub_803939C(void)
|
|
|
|
{
|
|
|
|
switch (gBattleCommunication[MULTIUSE_STATE])
|
|
|
|
{
|
|
|
|
case 0:
|
|
|
|
ShowBg(0);
|
|
|
|
ShowBg(1);
|
|
|
|
ShowBg(2);
|
|
|
|
gBattleCommunication[MULTIUSE_STATE]++;
|
|
|
|
break;
|
|
|
|
case 1:
|
|
|
|
if (gMain.field_439_x4 && gReceivedRemoteLinkPlayers == 0)
|
|
|
|
CreateTask(sub_80B3AF8, 5);
|
|
|
|
gBattleCommunication[MULTIUSE_STATE]++;
|
|
|
|
break;
|
|
|
|
case 2:
|
|
|
|
if (!FuncIsActiveTask(sub_80B3AF8))
|
|
|
|
gBattleCommunication[MULTIUSE_STATE]++;
|
|
|
|
break;
|
|
|
|
case 3:
|
|
|
|
if (!gPaletteFade.active)
|
|
|
|
{
|
2018-06-17 16:48:58 +02:00
|
|
|
BattlePutTextOnWindow(gText_RecordBattleToPass, 0);
|
2017-10-01 18:54:01 +02:00
|
|
|
gBattleCommunication[MULTIUSE_STATE]++;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case 4:
|
|
|
|
if (!IsTextPrinterActive(0))
|
|
|
|
{
|
2017-10-29 16:15:23 +01:00
|
|
|
HandleBattleWindow(0x18, 8, 0x1D, 0xD, 0);
|
2018-06-17 16:48:58 +02:00
|
|
|
BattlePutTextOnWindow(gText_BattleYesNoChoice, 0xC);
|
2017-10-01 18:54:01 +02:00
|
|
|
gBattleCommunication[CURSOR_POSITION] = 1;
|
2017-10-29 16:15:23 +01:00
|
|
|
BattleCreateYesNoCursorAt(1);
|
2017-10-01 18:54:01 +02:00
|
|
|
gBattleCommunication[MULTIUSE_STATE]++;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case 5:
|
|
|
|
if (gMain.newKeys & DPAD_UP)
|
|
|
|
{
|
|
|
|
if (gBattleCommunication[CURSOR_POSITION] != 0)
|
|
|
|
{
|
|
|
|
PlaySE(SE_SELECT);
|
2017-10-29 16:15:23 +01:00
|
|
|
BattleDestroyYesNoCursorAt(gBattleCommunication[CURSOR_POSITION]);
|
2017-10-01 18:54:01 +02:00
|
|
|
gBattleCommunication[CURSOR_POSITION] = 0;
|
2017-10-29 16:15:23 +01:00
|
|
|
BattleCreateYesNoCursorAt(0);
|
2017-10-01 18:54:01 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
else if (gMain.newKeys & DPAD_DOWN)
|
|
|
|
{
|
|
|
|
if (gBattleCommunication[CURSOR_POSITION] == 0)
|
|
|
|
{
|
|
|
|
PlaySE(SE_SELECT);
|
2017-10-29 16:15:23 +01:00
|
|
|
BattleDestroyYesNoCursorAt(gBattleCommunication[CURSOR_POSITION]);
|
2017-10-01 18:54:01 +02:00
|
|
|
gBattleCommunication[CURSOR_POSITION] = 1;
|
2017-10-29 16:15:23 +01:00
|
|
|
BattleCreateYesNoCursorAt(1);
|
2017-10-01 18:54:01 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
else if (gMain.newKeys & A_BUTTON)
|
|
|
|
{
|
|
|
|
PlaySE(SE_SELECT);
|
|
|
|
if (gBattleCommunication[CURSOR_POSITION] == 0)
|
|
|
|
{
|
2017-10-22 01:04:02 +02:00
|
|
|
HandleBattleWindow(0x18, 8, 0x1D, 0xD, WINDOW_CLEAR);
|
2017-10-01 18:54:01 +02:00
|
|
|
gBattleCommunication[1] = MoveRecordedBattleToSaveData();
|
|
|
|
gBattleCommunication[MULTIUSE_STATE] = 10;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
gBattleCommunication[MULTIUSE_STATE]++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else if (gMain.newKeys & B_BUTTON)
|
|
|
|
{
|
|
|
|
PlaySE(SE_SELECT);
|
|
|
|
gBattleCommunication[MULTIUSE_STATE]++;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case 6:
|
2018-12-31 09:22:21 +01:00
|
|
|
if (IsLinkTaskFinished() == TRUE)
|
2017-10-01 18:54:01 +02:00
|
|
|
{
|
2017-10-22 01:04:02 +02:00
|
|
|
HandleBattleWindow(0x18, 8, 0x1D, 0xD, WINDOW_CLEAR);
|
2017-10-01 18:54:01 +02:00
|
|
|
if (gMain.field_439_x4)
|
|
|
|
{
|
|
|
|
sub_800ADF8();
|
2018-06-17 16:48:58 +02:00
|
|
|
BattlePutTextOnWindow(gText_LinkStandby3, 0);
|
2017-10-01 18:54:01 +02:00
|
|
|
}
|
|
|
|
gBattleCommunication[MULTIUSE_STATE]++;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case 8:
|
|
|
|
if (--gBattleCommunication[1] == 0)
|
|
|
|
{
|
2017-11-13 05:58:05 +01:00
|
|
|
if (gMain.field_439_x4 && !gWirelessCommType)
|
2017-10-01 18:54:01 +02:00
|
|
|
sub_800AC34();
|
|
|
|
gBattleCommunication[MULTIUSE_STATE]++;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case 9:
|
2017-11-13 05:58:05 +01:00
|
|
|
if (!gMain.field_439_x4 || gWirelessCommType || gReceivedRemoteLinkPlayers != 1)
|
2017-10-01 18:54:01 +02:00
|
|
|
{
|
|
|
|
gMain.field_439_x4 = 0;
|
|
|
|
if (!gPaletteFade.active)
|
|
|
|
{
|
|
|
|
SetMainCallback2(gMain.savedCallback);
|
|
|
|
FreeBattleResources();
|
|
|
|
FreeBattleSpritesData();
|
|
|
|
FreeMonSpritesGfx();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case 10:
|
|
|
|
if (gBattleCommunication[1] == 1)
|
|
|
|
{
|
|
|
|
PlaySE(SE_SAVE);
|
|
|
|
BattleStringExpandPlaceholdersToDisplayedString(gText_BattleRecordedOnPass);
|
2018-06-17 16:48:58 +02:00
|
|
|
BattlePutTextOnWindow(gDisplayedStringBattle, 0);
|
2017-10-01 18:54:01 +02:00
|
|
|
gBattleCommunication[1] = 0x80;
|
|
|
|
gBattleCommunication[MULTIUSE_STATE]++;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
BattleStringExpandPlaceholdersToDisplayedString(gText_BattleRecordCouldntBeSaved);
|
2018-06-17 16:48:58 +02:00
|
|
|
BattlePutTextOnWindow(gDisplayedStringBattle, 0);
|
2017-10-01 18:54:01 +02:00
|
|
|
gBattleCommunication[1] = 0x80;
|
|
|
|
gBattleCommunication[MULTIUSE_STATE]++;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case 11:
|
2018-12-31 09:22:21 +01:00
|
|
|
if (IsLinkTaskFinished() == TRUE && !IsTextPrinterActive(0) && --gBattleCommunication[1] == 0)
|
2017-10-01 18:54:01 +02:00
|
|
|
{
|
|
|
|
if (gMain.field_439_x4)
|
|
|
|
{
|
|
|
|
sub_800ADF8();
|
2018-06-17 16:48:58 +02:00
|
|
|
BattlePutTextOnWindow(gText_LinkStandby3, 0);
|
2017-10-01 18:54:01 +02:00
|
|
|
}
|
|
|
|
gBattleCommunication[MULTIUSE_STATE]++;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case 12:
|
|
|
|
case 7:
|
|
|
|
if (!IsTextPrinterActive(0))
|
|
|
|
{
|
|
|
|
if (gMain.field_439_x4)
|
|
|
|
{
|
2018-12-31 09:22:21 +01:00
|
|
|
if (IsLinkTaskFinished() == TRUE)
|
2017-10-01 18:54:01 +02:00
|
|
|
{
|
2018-07-16 20:23:05 +02:00
|
|
|
BeginNormalPaletteFade(0xFFFFFFFF, 0, 0, 0x10, RGB_BLACK);
|
2017-10-01 18:54:01 +02:00
|
|
|
gBattleCommunication[1] = 0x20;
|
|
|
|
gBattleCommunication[MULTIUSE_STATE] = 8;
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2018-07-16 20:23:05 +02:00
|
|
|
BeginNormalPaletteFade(0xFFFFFFFF, 0, 0, 0x10, RGB_BLACK);
|
2017-10-01 18:54:01 +02:00
|
|
|
gBattleCommunication[1] = 0x20;
|
|
|
|
gBattleCommunication[MULTIUSE_STATE] = 8;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static void TryCorrectShedinjaLanguage(struct Pokemon *mon)
|
|
|
|
{
|
|
|
|
u8 nickname[POKEMON_NAME_LENGTH + 1];
|
|
|
|
u8 language = LANGUAGE_JAPANESE;
|
|
|
|
|
|
|
|
if (GetMonData(mon, MON_DATA_SPECIES) == SPECIES_SHEDINJA
|
|
|
|
&& GetMonData(mon, MON_DATA_LANGUAGE) != language)
|
|
|
|
{
|
|
|
|
GetMonData(mon, MON_DATA_NICKNAME, nickname);
|
2018-12-23 14:52:47 +01:00
|
|
|
if (StringCompareWithoutExtCtrlCodes(nickname, sText_ShedinjaJpnName) == 0)
|
2017-10-01 18:54:01 +02:00
|
|
|
SetMonData(mon, MON_DATA_LANGUAGE, &language);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
u32 sub_80397C4(u32 setId, u32 tableId)
|
|
|
|
{
|
2018-06-17 16:48:58 +02:00
|
|
|
return gBattleWindowTemplates[setId][tableId].width * 8;
|
2017-10-01 18:54:01 +02:00
|
|
|
}
|
|
|
|
|
2018-02-06 23:09:39 +01:00
|
|
|
#define sBattler data[0]
|
|
|
|
#define sSpeciesId data[2]
|
2017-10-01 18:54:01 +02:00
|
|
|
|
2018-12-23 14:52:47 +01:00
|
|
|
void SpriteCb_WildMon(struct Sprite *sprite)
|
2017-10-01 18:54:01 +02:00
|
|
|
{
|
2018-12-23 14:52:47 +01:00
|
|
|
sprite->callback = SpriteCb_MoveWildMonToRight;
|
2017-10-01 18:54:01 +02:00
|
|
|
StartSpriteAnimIfDifferent(sprite, 0);
|
2018-10-16 22:19:53 +02:00
|
|
|
if (WILD_DOUBLE_BATTLE)
|
|
|
|
BeginNormalPaletteFade((0x10000 << sprite->sBattler) | (0x10000 << BATTLE_PARTNER(sprite->sBattler)), 0, 10, 10, RGB(8, 8, 8));
|
|
|
|
else
|
|
|
|
BeginNormalPaletteFade((0x10000 << sprite->sBattler), 0, 10, 10, RGB(8, 8, 8));
|
2017-10-01 18:54:01 +02:00
|
|
|
}
|
|
|
|
|
2018-12-23 14:52:47 +01:00
|
|
|
static void SpriteCb_MoveWildMonToRight(struct Sprite *sprite)
|
2017-10-01 18:54:01 +02:00
|
|
|
{
|
2018-02-08 11:17:41 +01:00
|
|
|
if ((gIntroSlideFlags & 1) == 0)
|
2017-10-01 18:54:01 +02:00
|
|
|
{
|
|
|
|
sprite->pos2.x += 2;
|
|
|
|
if (sprite->pos2.x == 0)
|
|
|
|
{
|
2018-12-23 14:52:47 +01:00
|
|
|
sprite->callback = SpriteCb_WildMonShowHealthbox;
|
2017-10-01 18:54:01 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-12-23 14:52:47 +01:00
|
|
|
static void SpriteCb_WildMonShowHealthbox(struct Sprite *sprite)
|
2017-10-01 18:54:01 +02:00
|
|
|
{
|
|
|
|
if (sprite->animEnded)
|
|
|
|
{
|
2018-02-06 23:09:39 +01:00
|
|
|
sub_8076918(sprite->sBattler);
|
|
|
|
SetHealthboxSpriteVisible(gHealthboxSpriteIds[sprite->sBattler]);
|
2018-12-23 14:52:47 +01:00
|
|
|
sprite->callback = SpriteCb_WildMonAnimate;
|
2017-10-01 18:54:01 +02:00
|
|
|
StartSpriteAnimIfDifferent(sprite, 0);
|
2018-10-16 22:19:53 +02:00
|
|
|
if (WILD_DOUBLE_BATTLE)
|
|
|
|
BeginNormalPaletteFade((0x10000 << sprite->sBattler) | (0x10000 << BATTLE_PARTNER(sprite->sBattler)), 0, 10, 0, RGB(8, 8, 8));
|
|
|
|
else
|
|
|
|
BeginNormalPaletteFade((0x10000 << sprite->sBattler), 0, 10, 0, RGB(8, 8, 8));
|
2017-10-01 18:54:01 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-12-23 14:52:47 +01:00
|
|
|
static void SpriteCb_WildMonAnimate(struct Sprite *sprite)
|
2017-10-01 18:54:01 +02:00
|
|
|
{
|
|
|
|
if (!gPaletteFade.active)
|
|
|
|
{
|
2018-02-06 23:09:39 +01:00
|
|
|
BattleAnimateFrontSprite(sprite, sprite->sSpeciesId, FALSE, 1);
|
2017-10-01 18:54:01 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void SpriteCallbackDummy_2(struct Sprite *sprite)
|
|
|
|
{
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
static void sub_80398D0(struct Sprite *sprite)
|
|
|
|
{
|
2017-12-02 21:44:50 +01:00
|
|
|
sprite->data[4]--;
|
|
|
|
if (sprite->data[4] == 0)
|
2017-10-01 18:54:01 +02:00
|
|
|
{
|
2017-12-02 21:44:50 +01:00
|
|
|
sprite->data[4] = 8;
|
2017-10-01 18:54:01 +02:00
|
|
|
sprite->invisible ^= 1;
|
2017-12-02 21:44:50 +01:00
|
|
|
sprite->data[3]--;
|
|
|
|
if (sprite->data[3] == 0)
|
2017-10-01 18:54:01 +02:00
|
|
|
{
|
|
|
|
sprite->invisible = FALSE;
|
|
|
|
sprite->callback = SpriteCallbackDummy_2;
|
2018-11-24 01:02:02 +01:00
|
|
|
// sUnusedUnknownArray[0] = 0;
|
2017-10-01 18:54:01 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
extern const struct MonCoords gMonFrontPicCoords[];
|
|
|
|
extern const struct MonCoords gCastformFrontSpriteCoords[];
|
|
|
|
|
2018-06-20 23:07:51 +02:00
|
|
|
void SpriteCB_FaintOpponentMon(struct Sprite *sprite)
|
2017-10-01 18:54:01 +02:00
|
|
|
{
|
2018-02-06 23:09:39 +01:00
|
|
|
u8 battler = sprite->sBattler;
|
2017-10-01 18:54:01 +02:00
|
|
|
u16 species;
|
|
|
|
u8 yOffset;
|
|
|
|
|
2018-02-06 23:09:39 +01:00
|
|
|
if (gBattleSpritesDataPtr->battlerData[battler].transformSpecies != 0)
|
|
|
|
species = gBattleSpritesDataPtr->battlerData[battler].transformSpecies;
|
2017-10-01 18:54:01 +02:00
|
|
|
else
|
2018-02-06 23:09:39 +01:00
|
|
|
species = sprite->sSpeciesId;
|
2017-10-01 18:54:01 +02:00
|
|
|
|
2018-06-20 23:07:51 +02:00
|
|
|
GetMonData(&gEnemyParty[gBattlerPartyIndexes[battler]], MON_DATA_PERSONALITY); // Unused return value.
|
2017-10-01 18:54:01 +02:00
|
|
|
|
|
|
|
if (species == SPECIES_UNOWN)
|
|
|
|
{
|
2018-02-06 23:09:39 +01:00
|
|
|
u32 personalityValue = GetMonData(&gEnemyParty[gBattlerPartyIndexes[battler]], MON_DATA_PERSONALITY);
|
2017-10-01 18:54:01 +02:00
|
|
|
u16 unownForm = ((((personalityValue & 0x3000000) >> 18) | ((personalityValue & 0x30000) >> 12) | ((personalityValue & 0x300) >> 6) | (personalityValue & 3)) % 0x1C);
|
|
|
|
u16 unownSpecies;
|
|
|
|
|
|
|
|
if (unownForm == 0)
|
2018-06-20 23:07:51 +02:00
|
|
|
unownSpecies = SPECIES_UNOWN; // Use the A Unown form.
|
2017-10-01 18:54:01 +02:00
|
|
|
else
|
2018-06-20 23:07:51 +02:00
|
|
|
unownSpecies = NUM_SPECIES + unownForm; // Use one of the other Unown letters.
|
2017-10-01 18:54:01 +02:00
|
|
|
|
|
|
|
yOffset = gMonFrontPicCoords[unownSpecies].y_offset;
|
|
|
|
}
|
|
|
|
else if (species == SPECIES_CASTFORM)
|
|
|
|
{
|
2018-02-06 23:09:39 +01:00
|
|
|
yOffset = gCastformFrontSpriteCoords[gBattleMonForms[battler]].y_offset;
|
2017-10-01 18:54:01 +02:00
|
|
|
}
|
|
|
|
else if (species > NUM_SPECIES)
|
|
|
|
{
|
|
|
|
yOffset = gMonFrontPicCoords[SPECIES_NONE].y_offset;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
yOffset = gMonFrontPicCoords[species].y_offset;
|
|
|
|
}
|
|
|
|
|
2017-12-02 21:44:50 +01:00
|
|
|
sprite->data[3] = 8 - yOffset / 8;
|
|
|
|
sprite->data[4] = 1;
|
2018-06-20 23:07:51 +02:00
|
|
|
sprite->callback = SpriteCB_AnimFaintOpponent;
|
2017-10-01 18:54:01 +02:00
|
|
|
}
|
|
|
|
|
2018-06-20 23:07:51 +02:00
|
|
|
static void SpriteCB_AnimFaintOpponent(struct Sprite *sprite)
|
2017-10-01 18:54:01 +02:00
|
|
|
{
|
|
|
|
s32 i;
|
|
|
|
|
2018-06-20 23:07:51 +02:00
|
|
|
if (--sprite->data[4] == 0)
|
2017-10-01 18:54:01 +02:00
|
|
|
{
|
2017-12-02 21:44:50 +01:00
|
|
|
sprite->data[4] = 2;
|
2018-06-20 23:07:51 +02:00
|
|
|
sprite->pos2.y += 8; // Move the sprite down.
|
|
|
|
if (--sprite->data[3] < 0)
|
2017-10-01 18:54:01 +02:00
|
|
|
{
|
|
|
|
FreeSpriteOamMatrix(sprite);
|
|
|
|
DestroySprite(sprite);
|
|
|
|
}
|
2018-06-20 23:07:51 +02:00
|
|
|
else // Erase bottom part of the sprite to create a smooth illusion of mon falling down.
|
2017-10-01 18:54:01 +02:00
|
|
|
{
|
2018-02-06 23:09:39 +01:00
|
|
|
u8 *dst = (u8 *)gMonSpritesGfxPtr->sprites[GetBattlerPosition(sprite->sBattler)] + (gBattleMonForms[sprite->sBattler] << 11) + (sprite->data[3] << 8);
|
2017-10-01 18:54:01 +02:00
|
|
|
|
|
|
|
for (i = 0; i < 0x100; i++)
|
|
|
|
*(dst++) = 0;
|
|
|
|
|
2018-02-06 23:09:39 +01:00
|
|
|
StartSpriteAnim(sprite, gBattleMonForms[sprite->sBattler]);
|
2017-10-01 18:54:01 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void sub_8039AD8(struct Sprite *sprite)
|
|
|
|
{
|
2017-12-02 21:44:50 +01:00
|
|
|
sprite->data[3] = 8;
|
|
|
|
sprite->data[4] = sprite->invisible;
|
2017-10-01 18:54:01 +02:00
|
|
|
sprite->callback = sub_8039AF4;
|
|
|
|
}
|
|
|
|
|
2017-10-06 19:09:37 +02:00
|
|
|
static void sub_8039AF4(struct Sprite *sprite)
|
2017-10-01 18:54:01 +02:00
|
|
|
{
|
2017-12-02 21:44:50 +01:00
|
|
|
sprite->data[3]--;
|
|
|
|
if (sprite->data[3] == 0)
|
2017-10-01 18:54:01 +02:00
|
|
|
{
|
|
|
|
sprite->invisible ^= 1;
|
2017-12-02 21:44:50 +01:00
|
|
|
sprite->data[3] = 8;
|
2017-10-01 18:54:01 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void sub_8039B2C(struct Sprite *sprite)
|
|
|
|
{
|
2017-12-02 21:44:50 +01:00
|
|
|
sprite->invisible = sprite->data[4];
|
|
|
|
sprite->data[4] = FALSE;
|
2017-10-01 18:54:01 +02:00
|
|
|
sprite->callback = SpriteCallbackDummy_2;
|
|
|
|
}
|
|
|
|
|
2017-10-02 23:32:39 +02:00
|
|
|
void sub_8039B58(struct Sprite *sprite)
|
|
|
|
{
|
|
|
|
if (sprite->affineAnimEnded)
|
|
|
|
{
|
|
|
|
if (!(gHitMarker & HITMARKER_NO_ANIMATIONS) || gBattleTypeFlags & (BATTLE_TYPE_LINK | BATTLE_TYPE_x2000000))
|
|
|
|
{
|
2018-02-06 23:09:39 +01:00
|
|
|
if (HasTwoFramesAnimation(sprite->sSpeciesId))
|
2017-10-02 23:32:39 +02:00
|
|
|
StartSpriteAnim(sprite, 1);
|
|
|
|
}
|
2018-02-06 23:09:39 +01:00
|
|
|
BattleAnimateFrontSprite(sprite, sprite->sSpeciesId, TRUE, 1);
|
2017-10-02 23:32:39 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void sub_8039BB4(struct Sprite *sprite)
|
|
|
|
{
|
|
|
|
sprite->callback = oac_poke_ally_;
|
|
|
|
}
|
|
|
|
|
2017-10-06 19:09:37 +02:00
|
|
|
static void oac_poke_ally_(struct Sprite *sprite)
|
2017-10-02 23:32:39 +02:00
|
|
|
{
|
2018-07-01 15:28:57 +02:00
|
|
|
if (!(gIntroSlideFlags & 1))
|
2017-10-02 23:32:39 +02:00
|
|
|
{
|
|
|
|
sprite->pos2.x -= 2;
|
|
|
|
if (sprite->pos2.x == 0)
|
|
|
|
{
|
|
|
|
sprite->callback = SpriteCallbackDummy_3;
|
2017-12-02 21:44:50 +01:00
|
|
|
sprite->data[1] = 0;
|
2017-10-02 23:32:39 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void sub_80105DC(struct Sprite *sprite)
|
|
|
|
{
|
|
|
|
sprite->callback = SpriteCallbackDummy_3;
|
|
|
|
}
|
|
|
|
|
2017-10-06 19:09:37 +02:00
|
|
|
static void SpriteCallbackDummy_3(struct Sprite *sprite)
|
2017-10-02 23:32:39 +02:00
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
void sub_8039C00(struct Sprite *sprite)
|
|
|
|
{
|
2018-02-08 11:17:41 +01:00
|
|
|
if (!(gIntroSlideFlags & 1))
|
2017-10-02 23:32:39 +02:00
|
|
|
{
|
2017-12-02 21:44:50 +01:00
|
|
|
sprite->pos2.x += sprite->data[1];
|
|
|
|
sprite->pos2.y += sprite->data[2];
|
2017-10-02 23:32:39 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-05-02 23:10:01 +02:00
|
|
|
#define sSinIndex data[3]
|
|
|
|
#define sDelta data[4]
|
|
|
|
#define sAmplitude data[5]
|
|
|
|
#define sBouncerSpriteId data[6]
|
|
|
|
#define sWhich data[7]
|
2018-06-20 23:07:51 +02:00
|
|
|
|
|
|
|
void DoBounceEffect(u8 battler, u8 which, s8 delta, s8 amplitude)
|
2017-10-02 23:32:39 +02:00
|
|
|
{
|
2018-06-20 23:07:51 +02:00
|
|
|
u8 invisibleSpriteId;
|
|
|
|
u8 bouncerSpriteId;
|
2017-10-02 23:32:39 +02:00
|
|
|
|
2018-06-20 23:07:51 +02:00
|
|
|
switch (which)
|
2017-10-02 23:32:39 +02:00
|
|
|
{
|
2018-06-20 23:07:51 +02:00
|
|
|
case BOUNCE_HEALTHBOX:
|
|
|
|
default:
|
|
|
|
if (gBattleSpritesDataPtr->healthBoxesData[battler].healthboxIsBouncing)
|
2017-10-02 23:32:39 +02:00
|
|
|
return;
|
2018-06-20 23:07:51 +02:00
|
|
|
break;
|
|
|
|
case BOUNCE_MON:
|
|
|
|
if (gBattleSpritesDataPtr->healthBoxesData[battler].battlerIsBouncing)
|
2017-10-02 23:32:39 +02:00
|
|
|
return;
|
2018-06-20 23:07:51 +02:00
|
|
|
break;
|
2017-10-02 23:32:39 +02:00
|
|
|
}
|
|
|
|
|
2018-06-20 23:07:51 +02:00
|
|
|
invisibleSpriteId = CreateInvisibleSpriteWithCallback(SpriteCB_BounceEffect);
|
|
|
|
if (which == BOUNCE_HEALTHBOX)
|
2017-10-02 23:32:39 +02:00
|
|
|
{
|
2018-06-20 23:07:51 +02:00
|
|
|
bouncerSpriteId = gHealthboxSpriteIds[battler];
|
|
|
|
gBattleSpritesDataPtr->healthBoxesData[battler].healthboxBounceSpriteId = invisibleSpriteId;
|
|
|
|
gBattleSpritesDataPtr->healthBoxesData[battler].healthboxIsBouncing = 1;
|
|
|
|
gSprites[invisibleSpriteId].sSinIndex = 128; // 0
|
2017-10-02 23:32:39 +02:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2018-06-20 23:07:51 +02:00
|
|
|
bouncerSpriteId = gBattlerSpriteIds[battler];
|
|
|
|
gBattleSpritesDataPtr->healthBoxesData[battler].battlerBounceSpriteId = invisibleSpriteId;
|
|
|
|
gBattleSpritesDataPtr->healthBoxesData[battler].battlerIsBouncing = 1;
|
|
|
|
gSprites[invisibleSpriteId].sSinIndex = 192; // -1
|
|
|
|
}
|
|
|
|
gSprites[invisibleSpriteId].sDelta = delta;
|
|
|
|
gSprites[invisibleSpriteId].sAmplitude = amplitude;
|
|
|
|
gSprites[invisibleSpriteId].sBouncerSpriteId = bouncerSpriteId;
|
|
|
|
gSprites[invisibleSpriteId].sWhich = which;
|
2019-05-02 23:10:01 +02:00
|
|
|
gSprites[invisibleSpriteId].sBattler = battler;
|
2018-06-20 23:07:51 +02:00
|
|
|
gSprites[bouncerSpriteId].pos2.x = 0;
|
|
|
|
gSprites[bouncerSpriteId].pos2.y = 0;
|
2017-10-02 23:32:39 +02:00
|
|
|
}
|
|
|
|
|
2018-06-20 23:07:51 +02:00
|
|
|
void EndBounceEffect(u8 battler, u8 which)
|
2017-10-02 23:32:39 +02:00
|
|
|
{
|
2018-06-20 23:07:51 +02:00
|
|
|
u8 bouncerSpriteId;
|
2017-10-02 23:32:39 +02:00
|
|
|
|
2018-06-20 23:07:51 +02:00
|
|
|
if (which == BOUNCE_HEALTHBOX)
|
2017-10-02 23:32:39 +02:00
|
|
|
{
|
2018-06-20 23:07:51 +02:00
|
|
|
if (!gBattleSpritesDataPtr->healthBoxesData[battler].healthboxIsBouncing)
|
2017-10-02 23:32:39 +02:00
|
|
|
return;
|
|
|
|
|
2018-06-20 23:07:51 +02:00
|
|
|
bouncerSpriteId = gSprites[gBattleSpritesDataPtr->healthBoxesData[battler].healthboxBounceSpriteId].sBouncerSpriteId;
|
|
|
|
DestroySprite(&gSprites[gBattleSpritesDataPtr->healthBoxesData[battler].healthboxBounceSpriteId]);
|
|
|
|
gBattleSpritesDataPtr->healthBoxesData[battler].healthboxIsBouncing = 0;
|
2017-10-02 23:32:39 +02:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2018-06-20 23:07:51 +02:00
|
|
|
if (!gBattleSpritesDataPtr->healthBoxesData[battler].battlerIsBouncing)
|
2017-10-02 23:32:39 +02:00
|
|
|
return;
|
|
|
|
|
2018-06-20 23:07:51 +02:00
|
|
|
bouncerSpriteId = gSprites[gBattleSpritesDataPtr->healthBoxesData[battler].battlerBounceSpriteId].sBouncerSpriteId;
|
|
|
|
DestroySprite(&gSprites[gBattleSpritesDataPtr->healthBoxesData[battler].battlerBounceSpriteId]);
|
|
|
|
gBattleSpritesDataPtr->healthBoxesData[battler].battlerIsBouncing = 0;
|
2017-10-02 23:32:39 +02:00
|
|
|
}
|
2018-06-20 23:07:51 +02:00
|
|
|
|
|
|
|
gSprites[bouncerSpriteId].pos2.x = 0;
|
|
|
|
gSprites[bouncerSpriteId].pos2.y = 0;
|
2017-10-02 23:32:39 +02:00
|
|
|
}
|
|
|
|
|
2018-06-20 23:07:51 +02:00
|
|
|
static void SpriteCB_BounceEffect(struct Sprite *sprite)
|
2017-10-02 23:32:39 +02:00
|
|
|
{
|
2018-06-20 23:07:51 +02:00
|
|
|
u8 bouncerSpriteId = sprite->sBouncerSpriteId;
|
2019-05-02 23:10:01 +02:00
|
|
|
s32 index = sprite->sSinIndex;
|
|
|
|
s32 y = Sin(index, sprite->sAmplitude) + sprite->sAmplitude;
|
2017-10-02 23:32:39 +02:00
|
|
|
|
2019-05-02 23:10:01 +02:00
|
|
|
gSprites[bouncerSpriteId].pos2.y = y;
|
2018-06-20 23:07:51 +02:00
|
|
|
sprite->sSinIndex = (sprite->sSinIndex + sprite->sDelta) & 0xFF;
|
2019-05-02 23:10:01 +02:00
|
|
|
|
|
|
|
bouncerSpriteId = gBattleStruct->mega.indicatorSpriteIds[sprite->sBattler];
|
|
|
|
if (sprite->sWhich == BOUNCE_HEALTHBOX && bouncerSpriteId != 0xFF)
|
|
|
|
gSprites[bouncerSpriteId].pos2.y = y;
|
2017-10-02 23:32:39 +02:00
|
|
|
}
|
|
|
|
|
2018-06-20 23:07:51 +02:00
|
|
|
#undef sSinIndex
|
|
|
|
#undef sDelta
|
|
|
|
#undef sAmplitude
|
|
|
|
#undef sBouncerSpriteId
|
|
|
|
#undef sWhich
|
|
|
|
|
2017-10-02 23:32:39 +02:00
|
|
|
void sub_8039E44(struct Sprite *sprite)
|
|
|
|
{
|
|
|
|
if (sprite->affineAnimEnded)
|
2018-02-06 23:09:39 +01:00
|
|
|
BattleAnimateBackSprite(sprite, sprite->sSpeciesId);
|
2017-10-02 23:32:39 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
void sub_8039E60(struct Sprite *sprite)
|
|
|
|
{
|
|
|
|
sub_8039E9C(sprite);
|
|
|
|
if (sprite->animEnded)
|
|
|
|
sprite->callback = SpriteCallbackDummy_3;
|
|
|
|
}
|
|
|
|
|
|
|
|
void sub_8039E84(struct Sprite *sprite)
|
|
|
|
{
|
|
|
|
StartSpriteAnim(sprite, 1);
|
|
|
|
sprite->callback = sub_8039E60;
|
|
|
|
}
|
|
|
|
|
|
|
|
void sub_8039E9C(struct Sprite *sprite)
|
|
|
|
{
|
|
|
|
if (sprite->animDelayCounter == 0)
|
|
|
|
sprite->centerToCornerVecX = gUnknown_0831ACE0[sprite->animCmdIndex];
|
|
|
|
}
|
|
|
|
|
|
|
|
void nullsub_20(void)
|
|
|
|
{
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
void BeginBattleIntro(void)
|
|
|
|
{
|
|
|
|
BattleStartClearSetData();
|
|
|
|
gBattleCommunication[1] = 0;
|
2018-12-23 18:47:00 +01:00
|
|
|
gBattleStruct->introState = 0;
|
|
|
|
gBattleMainFunc = DoBattleIntro;
|
2017-10-02 23:32:39 +02:00
|
|
|
}
|
|
|
|
|
2017-10-06 19:09:37 +02:00
|
|
|
static void BattleMainCB1(void)
|
2017-10-02 23:32:39 +02:00
|
|
|
{
|
|
|
|
gBattleMainFunc();
|
|
|
|
|
2018-02-06 02:46:59 +01:00
|
|
|
for (gActiveBattler = 0; gActiveBattler < gBattlersCount; gActiveBattler++)
|
2018-02-06 20:48:02 +01:00
|
|
|
gBattlerControllerFuncs[gActiveBattler]();
|
2017-10-02 23:32:39 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
static void BattleStartClearSetData(void)
|
|
|
|
{
|
|
|
|
s32 i;
|
|
|
|
|
2017-10-06 00:12:01 +02:00
|
|
|
TurnValuesCleanUp(FALSE);
|
2017-10-02 23:32:39 +02:00
|
|
|
SpecialStatusesClear();
|
|
|
|
|
2019-01-27 13:52:02 +01:00
|
|
|
memset(&gDisableStructs, 0, sizeof(gDisableStructs));
|
|
|
|
memset(&gFieldTimers, 0, sizeof(gFieldTimers));
|
|
|
|
memset(&gSideStatuses, 0, sizeof(gSideStatuses));
|
|
|
|
memset(&gSideTimers, 0, sizeof(gSideTimers));
|
|
|
|
memset(&gWishFutureKnock, 0, sizeof(gWishFutureKnock));
|
|
|
|
memset(&gBattleResults, 0, sizeof(gBattleResults));
|
|
|
|
|
2018-02-06 02:46:59 +01:00
|
|
|
for (i = 0; i < MAX_BATTLERS_COUNT; i++)
|
2017-10-02 23:32:39 +02:00
|
|
|
{
|
|
|
|
gStatuses3[i] = 0;
|
2017-11-26 13:26:58 +01:00
|
|
|
gDisableStructs[i].isFirstTurn = 2;
|
2017-11-26 18:07:00 +01:00
|
|
|
gLastMoves[i] = 0;
|
2017-11-26 14:17:02 +01:00
|
|
|
gLastLandedMoves[i] = 0;
|
|
|
|
gLastHitByType[i] = 0;
|
2017-11-26 18:07:00 +01:00
|
|
|
gLastResultingMoves[i] = 0;
|
2017-11-26 14:17:02 +01:00
|
|
|
gLastHitBy[i] = 0xFF;
|
2017-10-02 23:32:39 +02:00
|
|
|
gLockedMoves[i] = 0;
|
2017-11-26 18:07:00 +01:00
|
|
|
gLastPrintedMoves[i] = 0;
|
2017-10-02 23:32:39 +02:00
|
|
|
gBattleResources->flags->flags[i] = 0;
|
2017-11-26 17:15:28 +01:00
|
|
|
gPalaceSelectionBattleScripts[i] = 0;
|
2019-01-27 13:52:02 +01:00
|
|
|
gBattleStruct->lastTakenMove[i] = 0;
|
|
|
|
gBattleStruct->usedHeldItems[i] = 0;
|
|
|
|
gBattleStruct->choicedMove[i] = 0;
|
|
|
|
gBattleStruct->changedItems[i] = 0;
|
|
|
|
gBattleStruct->lastTakenMoveFrom[i][0] = 0;
|
|
|
|
gBattleStruct->lastTakenMoveFrom[i][1] = 0;
|
|
|
|
gBattleStruct->lastTakenMoveFrom[i][2] = 0;
|
|
|
|
gBattleStruct->lastTakenMoveFrom[i][3] = 0;
|
|
|
|
gBattleStruct->AI_monToSwitchIntoId[i] = PARTY_SIZE;
|
2017-10-02 23:32:39 +02:00
|
|
|
}
|
|
|
|
|
2018-09-22 18:37:03 +02:00
|
|
|
gLastUsedMove = 0;
|
2018-08-11 12:16:00 +02:00
|
|
|
gFieldStatuses = 0;
|
2017-10-02 23:32:39 +02:00
|
|
|
|
2018-02-06 23:09:39 +01:00
|
|
|
gBattlerAttacker = 0;
|
|
|
|
gBattlerTarget = 0;
|
2017-10-02 23:32:39 +02:00
|
|
|
gBattleWeather = 0;
|
|
|
|
gHitMarker = 0;
|
|
|
|
|
|
|
|
if (!(gBattleTypeFlags & BATTLE_TYPE_RECORDED))
|
|
|
|
{
|
|
|
|
if (!(gBattleTypeFlags & BATTLE_TYPE_LINK) && gSaveBlock2Ptr->optionsBattleSceneOff == TRUE)
|
|
|
|
gHitMarker |= HITMARKER_NO_ANIMATIONS;
|
|
|
|
}
|
2018-11-01 15:06:50 +01:00
|
|
|
else if (!(gBattleTypeFlags & (BATTLE_TYPE_LINK | BATTLE_TYPE_x2000000)) && GetBattleSceneInRecordedBattle())
|
2019-01-27 13:52:02 +01:00
|
|
|
{
|
2017-10-02 23:32:39 +02:00
|
|
|
gHitMarker |= HITMARKER_NO_ANIMATIONS;
|
2019-01-27 13:52:02 +01:00
|
|
|
}
|
2017-10-02 23:32:39 +02:00
|
|
|
|
|
|
|
gBattleScripting.battleStyle = gSaveBlock2Ptr->optionsBattleStyle;
|
2018-08-03 18:01:14 +02:00
|
|
|
gBattleScripting.expOnCatch = (B_EXP_CATCH >= GEN_6);
|
|
|
|
gBattleScripting.monCaught = FALSE;
|
2017-10-02 23:32:39 +02:00
|
|
|
|
|
|
|
gMultiHitCounter = 0;
|
|
|
|
gBattleOutcome = 0;
|
2018-02-06 20:48:02 +01:00
|
|
|
gBattleControllerExecFlags = 0;
|
2017-10-02 23:32:39 +02:00
|
|
|
gPaydayMoney = 0;
|
|
|
|
gBattleResources->battleScriptsStack->size = 0;
|
|
|
|
gBattleResources->battleCallbackStack->size = 0;
|
|
|
|
|
|
|
|
for (i = 0; i < BATTLE_COMMUNICATION_ENTRIES_COUNT; i++)
|
|
|
|
gBattleCommunication[i] = 0;
|
|
|
|
|
|
|
|
gPauseCounterBattle = 0;
|
|
|
|
gBattleMoveDamage = 0;
|
2018-02-08 11:17:41 +01:00
|
|
|
gIntroSlideFlags = 0;
|
2017-10-02 23:32:39 +02:00
|
|
|
gBattleScripting.animTurn = 0;
|
|
|
|
gBattleScripting.animTargetsHit = 0;
|
|
|
|
gLeveledUpInBattle = 0;
|
2018-02-06 02:46:59 +01:00
|
|
|
gAbsentBattlerFlags = 0;
|
2017-10-06 00:12:01 +02:00
|
|
|
gBattleStruct->runTries = 0;
|
2018-07-01 11:15:42 +02:00
|
|
|
gBattleStruct->safariGoNearCounter = 0;
|
|
|
|
gBattleStruct->safariPkblThrowCounter = 0;
|
2019-01-27 13:52:02 +01:00
|
|
|
gBattleStruct->safariCatchFactor = gBaseStats[GetMonData(&gEnemyParty[0], MON_DATA_SPECIES)].catchRate * 100 / 1275;
|
2018-07-01 11:15:42 +02:00
|
|
|
gBattleStruct->safariEscapeFactor = 3;
|
2017-10-02 23:32:39 +02:00
|
|
|
gBattleStruct->wildVictorySong = 0;
|
|
|
|
gBattleStruct->moneyMultiplier = 1;
|
|
|
|
|
2018-12-07 23:50:56 +01:00
|
|
|
gBattleStruct->givenExpMons = 0;
|
2017-10-02 23:32:39 +02:00
|
|
|
gBattleStruct->field_92 = 0;
|
|
|
|
|
|
|
|
gRandomTurnNumber = Random();
|
|
|
|
|
2018-06-28 21:06:32 +02:00
|
|
|
gBattleResults.shinyWildMon = IsMonShiny(&gEnemyParty[0]);
|
2017-10-02 23:32:39 +02:00
|
|
|
|
2018-11-11 18:33:16 +01:00
|
|
|
gBattleStruct->arenaLostPlayerMons = 0;
|
|
|
|
gBattleStruct->arenaLostOpponentMons = 0;
|
2018-09-16 21:08:49 +02:00
|
|
|
|
2018-09-20 17:33:27 +02:00
|
|
|
gBattleStruct->mega.triggerSpriteId = 0xFF;
|
2018-09-16 21:08:49 +02:00
|
|
|
for (i = 0; i < MAX_BATTLERS_COUNT; i++)
|
2018-09-20 17:33:27 +02:00
|
|
|
gBattleStruct->mega.indicatorSpriteIds[i] = 0xFF;
|
2017-10-02 23:32:39 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
void SwitchInClearSetData(void)
|
|
|
|
{
|
|
|
|
s32 i;
|
2019-01-27 13:52:02 +01:00
|
|
|
struct DisableStruct disableStructCopy = gDisableStructs[gActiveBattler];
|
2017-10-02 23:32:39 +02:00
|
|
|
|
|
|
|
if (gBattleMoves[gCurrentMove].effect != EFFECT_BATON_PASS)
|
|
|
|
{
|
2018-11-18 20:00:36 +01:00
|
|
|
for (i = 0; i < NUM_BATTLE_STATS; i++)
|
2018-02-06 02:46:59 +01:00
|
|
|
gBattleMons[gActiveBattler].statStages[i] = 6;
|
|
|
|
for (i = 0; i < gBattlersCount; i++)
|
2017-10-02 23:32:39 +02:00
|
|
|
{
|
2018-02-06 23:09:39 +01:00
|
|
|
if ((gBattleMons[i].status2 & STATUS2_ESCAPE_PREVENTION) && gDisableStructs[i].battlerPreventingEscape == gActiveBattler)
|
2017-10-02 23:32:39 +02:00
|
|
|
gBattleMons[i].status2 &= ~STATUS2_ESCAPE_PREVENTION;
|
2018-02-06 23:09:39 +01:00
|
|
|
if ((gStatuses3[i] & STATUS3_ALWAYS_HITS) && gDisableStructs[i].battlerWithSureHit == gActiveBattler)
|
2017-10-02 23:32:39 +02:00
|
|
|
{
|
|
|
|
gStatuses3[i] &= ~STATUS3_ALWAYS_HITS;
|
2018-02-06 23:09:39 +01:00
|
|
|
gDisableStructs[i].battlerWithSureHit = 0;
|
2017-10-02 23:32:39 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (gBattleMoves[gCurrentMove].effect == EFFECT_BATON_PASS)
|
|
|
|
{
|
2018-02-06 02:46:59 +01:00
|
|
|
gBattleMons[gActiveBattler].status2 &= (STATUS2_CONFUSION | STATUS2_FOCUS_ENERGY | STATUS2_SUBSTITUTE | STATUS2_ESCAPE_PREVENTION | STATUS2_CURSED);
|
2018-07-14 13:17:10 +02:00
|
|
|
gStatuses3[gActiveBattler] &= (STATUS3_LEECHSEED_BATTLER | STATUS3_LEECHSEED | STATUS3_ALWAYS_HITS | STATUS3_PERISH_SONG | STATUS3_ROOTED);
|
2017-10-02 23:32:39 +02:00
|
|
|
|
2018-02-06 02:46:59 +01:00
|
|
|
for (i = 0; i < gBattlersCount; i++)
|
2017-10-02 23:32:39 +02:00
|
|
|
{
|
2018-02-06 02:46:59 +01:00
|
|
|
if (GetBattlerSide(gActiveBattler) != GetBattlerSide(i)
|
2017-10-02 23:32:39 +02:00
|
|
|
&& (gStatuses3[i] & STATUS3_ALWAYS_HITS) != 0
|
2018-02-06 23:09:39 +01:00
|
|
|
&& (gDisableStructs[i].battlerWithSureHit == gActiveBattler))
|
2017-10-02 23:32:39 +02:00
|
|
|
{
|
2017-12-03 00:47:21 +01:00
|
|
|
gStatuses3[i] &= ~(STATUS3_ALWAYS_HITS);
|
2017-10-02 23:32:39 +02:00
|
|
|
gStatuses3[i] |= 0x10;
|
|
|
|
}
|
|
|
|
}
|
2018-09-29 18:40:14 +02:00
|
|
|
if (gStatuses3[gActiveBattler] & STATUS3_POWER_TRICK)
|
|
|
|
SWAP(gBattleMons[gActiveBattler].attack, gBattleMons[gActiveBattler].defense, i);
|
2017-10-02 23:32:39 +02:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2018-02-06 02:46:59 +01:00
|
|
|
gBattleMons[gActiveBattler].status2 = 0;
|
|
|
|
gStatuses3[gActiveBattler] = 0;
|
2017-10-02 23:32:39 +02:00
|
|
|
}
|
|
|
|
|
2018-02-06 02:46:59 +01:00
|
|
|
for (i = 0; i < gBattlersCount; i++)
|
2017-10-02 23:32:39 +02:00
|
|
|
{
|
2018-02-06 02:46:59 +01:00
|
|
|
if (gBattleMons[i].status2 & STATUS2_INFATUATED_WITH(gActiveBattler))
|
|
|
|
gBattleMons[i].status2 &= ~(STATUS2_INFATUATED_WITH(gActiveBattler));
|
|
|
|
if ((gBattleMons[i].status2 & STATUS2_WRAPPED) && *(gBattleStruct->wrappedBy + i) == gActiveBattler)
|
2017-10-02 23:32:39 +02:00
|
|
|
gBattleMons[i].status2 &= ~(STATUS2_WRAPPED);
|
|
|
|
}
|
|
|
|
|
2018-02-06 02:46:59 +01:00
|
|
|
gActionSelectionCursor[gActiveBattler] = 0;
|
|
|
|
gMoveSelectionCursor[gActiveBattler] = 0;
|
2017-10-02 23:32:39 +02:00
|
|
|
|
2019-01-27 13:52:02 +01:00
|
|
|
memset(&gDisableStructs[gActiveBattler], 0, sizeof(struct DisableStruct));
|
2017-10-02 23:32:39 +02:00
|
|
|
|
|
|
|
if (gBattleMoves[gCurrentMove].effect == EFFECT_BATON_PASS)
|
|
|
|
{
|
2018-02-06 02:46:59 +01:00
|
|
|
gDisableStructs[gActiveBattler].substituteHP = disableStructCopy.substituteHP;
|
2018-02-06 23:09:39 +01:00
|
|
|
gDisableStructs[gActiveBattler].battlerWithSureHit = disableStructCopy.battlerWithSureHit;
|
2018-10-14 18:10:54 +02:00
|
|
|
gDisableStructs[gActiveBattler].perishSongTimer = disableStructCopy.perishSongTimer;
|
|
|
|
gDisableStructs[gActiveBattler].perishSongTimerStartValue = disableStructCopy.perishSongTimerStartValue;
|
2018-02-06 23:09:39 +01:00
|
|
|
gDisableStructs[gActiveBattler].battlerPreventingEscape = disableStructCopy.battlerPreventingEscape;
|
2017-10-02 23:32:39 +02:00
|
|
|
}
|
|
|
|
|
2018-01-16 22:12:38 +01:00
|
|
|
gMoveResultFlags = 0;
|
2018-02-06 02:46:59 +01:00
|
|
|
gDisableStructs[gActiveBattler].isFirstTurn = 2;
|
2019-01-19 22:32:25 +01:00
|
|
|
gDisableStructs[gActiveBattler].truantSwitchInHack = disableStructCopy.truantSwitchInHack;
|
2018-02-06 02:46:59 +01:00
|
|
|
gLastMoves[gActiveBattler] = 0;
|
|
|
|
gLastLandedMoves[gActiveBattler] = 0;
|
|
|
|
gLastHitByType[gActiveBattler] = 0;
|
|
|
|
gLastResultingMoves[gActiveBattler] = 0;
|
|
|
|
gLastPrintedMoves[gActiveBattler] = 0;
|
|
|
|
gLastHitBy[gActiveBattler] = 0xFF;
|
2017-10-02 23:32:39 +02:00
|
|
|
|
2019-01-27 13:52:02 +01:00
|
|
|
gBattleStruct->lastTakenMove[gActiveBattler] = 0;
|
|
|
|
gBattleStruct->lastTakenMoveFrom[gActiveBattler][0] = 0;
|
|
|
|
gBattleStruct->lastTakenMoveFrom[gActiveBattler][1] = 0;
|
|
|
|
gBattleStruct->lastTakenMoveFrom[gActiveBattler][2] = 0;
|
|
|
|
gBattleStruct->lastTakenMoveFrom[gActiveBattler][3] = 0;
|
2019-04-13 14:36:08 +02:00
|
|
|
gBattleStruct->lastMoveFailed &= ~(gBitTable[gActiveBattler]);
|
2018-02-06 02:46:59 +01:00
|
|
|
gBattleStruct->field_92 &= ~(gBitTable[gActiveBattler]);
|
2017-10-02 23:32:39 +02:00
|
|
|
|
2018-02-06 02:46:59 +01:00
|
|
|
for (i = 0; i < gBattlersCount; i++)
|
2017-10-02 23:32:39 +02:00
|
|
|
{
|
2018-02-06 02:46:59 +01:00
|
|
|
if (i != gActiveBattler && GetBattlerSide(i) != GetBattlerSide(gActiveBattler))
|
2019-01-27 13:52:02 +01:00
|
|
|
gBattleStruct->lastTakenMove[i] = 0;
|
2017-10-02 23:32:39 +02:00
|
|
|
|
2019-01-27 13:52:02 +01:00
|
|
|
gBattleStruct->lastTakenMoveFrom[i][gActiveBattler] = 0;
|
|
|
|
}
|
2017-10-02 23:32:39 +02:00
|
|
|
|
2019-01-27 13:52:02 +01:00
|
|
|
gBattleStruct->choicedMove[gActiveBattler] = 0;
|
2018-02-06 02:46:59 +01:00
|
|
|
gBattleResources->flags->flags[gActiveBattler] = 0;
|
2017-10-02 23:32:39 +02:00
|
|
|
gCurrentMove = 0;
|
2018-12-07 23:50:56 +01:00
|
|
|
gBattleStruct->arenaTurnCounter = 0xFF;
|
2017-10-02 23:32:39 +02:00
|
|
|
|
2018-02-06 23:09:39 +01:00
|
|
|
ClearBattlerMoveHistory(gActiveBattler);
|
|
|
|
ClearBattlerAbilityHistory(gActiveBattler);
|
2017-10-02 23:32:39 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
void FaintClearSetData(void)
|
|
|
|
{
|
|
|
|
s32 i;
|
|
|
|
|
2018-11-18 20:00:36 +01:00
|
|
|
for (i = 0; i < NUM_BATTLE_STATS; i++)
|
2018-02-06 02:46:59 +01:00
|
|
|
gBattleMons[gActiveBattler].statStages[i] = 6;
|
2017-10-02 23:32:39 +02:00
|
|
|
|
2018-02-06 02:46:59 +01:00
|
|
|
gBattleMons[gActiveBattler].status2 = 0;
|
|
|
|
gStatuses3[gActiveBattler] = 0;
|
2017-10-02 23:32:39 +02:00
|
|
|
|
2018-02-06 02:46:59 +01:00
|
|
|
for (i = 0; i < gBattlersCount; i++)
|
2017-10-02 23:32:39 +02:00
|
|
|
{
|
2018-02-06 23:09:39 +01:00
|
|
|
if ((gBattleMons[i].status2 & STATUS2_ESCAPE_PREVENTION) && gDisableStructs[i].battlerPreventingEscape == gActiveBattler)
|
2017-10-02 23:32:39 +02:00
|
|
|
gBattleMons[i].status2 &= ~STATUS2_ESCAPE_PREVENTION;
|
2018-02-06 02:46:59 +01:00
|
|
|
if (gBattleMons[i].status2 & STATUS2_INFATUATED_WITH(gActiveBattler))
|
|
|
|
gBattleMons[i].status2 &= ~(STATUS2_INFATUATED_WITH(gActiveBattler));
|
|
|
|
if ((gBattleMons[i].status2 & STATUS2_WRAPPED) && *(gBattleStruct->wrappedBy + i) == gActiveBattler)
|
2017-10-02 23:32:39 +02:00
|
|
|
gBattleMons[i].status2 &= ~(STATUS2_WRAPPED);
|
|
|
|
}
|
|
|
|
|
2018-02-06 02:46:59 +01:00
|
|
|
gActionSelectionCursor[gActiveBattler] = 0;
|
|
|
|
gMoveSelectionCursor[gActiveBattler] = 0;
|
2017-10-02 23:32:39 +02:00
|
|
|
|
2019-01-27 13:52:02 +01:00
|
|
|
memset(&gDisableStructs[gActiveBattler], 0, sizeof(struct DisableStruct));
|
2017-10-02 23:32:39 +02:00
|
|
|
|
2018-02-06 02:46:59 +01:00
|
|
|
gProtectStructs[gActiveBattler].protected = 0;
|
2018-10-06 15:50:35 +02:00
|
|
|
gProtectStructs[gActiveBattler].spikyShielded = 0;
|
|
|
|
gProtectStructs[gActiveBattler].kingsShielded = 0;
|
|
|
|
gProtectStructs[gActiveBattler].banefulBunkered = 0;
|
2018-02-06 02:46:59 +01:00
|
|
|
gProtectStructs[gActiveBattler].endured = 0;
|
2018-07-07 19:57:09 +02:00
|
|
|
gProtectStructs[gActiveBattler].noValidMoves = 0;
|
2018-02-06 02:46:59 +01:00
|
|
|
gProtectStructs[gActiveBattler].helpingHand = 0;
|
|
|
|
gProtectStructs[gActiveBattler].bounceMove = 0;
|
|
|
|
gProtectStructs[gActiveBattler].stealMove = 0;
|
|
|
|
gProtectStructs[gActiveBattler].prlzImmobility = 0;
|
|
|
|
gProtectStructs[gActiveBattler].confusionSelfDmg = 0;
|
|
|
|
gProtectStructs[gActiveBattler].targetNotAffected = 0;
|
|
|
|
gProtectStructs[gActiveBattler].chargingTurn = 0;
|
|
|
|
gProtectStructs[gActiveBattler].fleeFlag = 0;
|
2019-03-02 23:40:38 +01:00
|
|
|
gProtectStructs[gActiveBattler].usedImprisonedMove = 0;
|
2018-02-06 02:46:59 +01:00
|
|
|
gProtectStructs[gActiveBattler].loveImmobility = 0;
|
|
|
|
gProtectStructs[gActiveBattler].usedDisabledMove = 0;
|
|
|
|
gProtectStructs[gActiveBattler].usedTauntedMove = 0;
|
|
|
|
gProtectStructs[gActiveBattler].flag2Unknown = 0;
|
|
|
|
gProtectStructs[gActiveBattler].flinchImmobility = 0;
|
|
|
|
gProtectStructs[gActiveBattler].notFirstStrike = 0;
|
2018-08-02 21:27:28 +02:00
|
|
|
gProtectStructs[gActiveBattler].usedHealBlockedMove = 0;
|
|
|
|
gProtectStructs[gActiveBattler].usesBouncedMove = 0;
|
|
|
|
gProtectStructs[gActiveBattler].usedGravityPreventedMove = 0;
|
2019-04-16 15:01:48 +02:00
|
|
|
gProtectStructs[gActiveBattler].usedThroatChopPreventedMove = 0;
|
2018-02-06 02:46:59 +01:00
|
|
|
|
|
|
|
gDisableStructs[gActiveBattler].isFirstTurn = 2;
|
|
|
|
|
|
|
|
gLastMoves[gActiveBattler] = 0;
|
|
|
|
gLastLandedMoves[gActiveBattler] = 0;
|
|
|
|
gLastHitByType[gActiveBattler] = 0;
|
|
|
|
gLastResultingMoves[gActiveBattler] = 0;
|
|
|
|
gLastPrintedMoves[gActiveBattler] = 0;
|
|
|
|
gLastHitBy[gActiveBattler] = 0xFF;
|
|
|
|
|
2019-01-27 13:52:02 +01:00
|
|
|
gBattleStruct->choicedMove[gActiveBattler] = 0;
|
|
|
|
gBattleStruct->lastTakenMove[gActiveBattler] = 0;
|
|
|
|
gBattleStruct->lastTakenMoveFrom[gActiveBattler][0] = 0;
|
|
|
|
gBattleStruct->lastTakenMoveFrom[gActiveBattler][1] = 0;
|
|
|
|
gBattleStruct->lastTakenMoveFrom[gActiveBattler][2] = 0;
|
|
|
|
gBattleStruct->lastTakenMoveFrom[gActiveBattler][3] = 0;
|
2018-02-06 02:46:59 +01:00
|
|
|
|
|
|
|
gBattleStruct->field_92 &= ~(gBitTable[gActiveBattler]);
|
|
|
|
|
|
|
|
for (i = 0; i < gBattlersCount; i++)
|
|
|
|
{
|
|
|
|
if (i != gActiveBattler && GetBattlerSide(i) != GetBattlerSide(gActiveBattler))
|
2019-01-27 13:52:02 +01:00
|
|
|
gBattleStruct->lastTakenMove[i] = 0;
|
|
|
|
|
|
|
|
gBattleStruct->lastTakenMoveFrom[i][gActiveBattler] = 0;
|
2017-10-02 23:32:39 +02:00
|
|
|
}
|
|
|
|
|
2018-02-06 02:46:59 +01:00
|
|
|
gBattleResources->flags->flags[gActiveBattler] = 0;
|
2017-10-02 23:32:39 +02:00
|
|
|
|
2018-02-06 02:46:59 +01:00
|
|
|
gBattleMons[gActiveBattler].type1 = gBaseStats[gBattleMons[gActiveBattler].species].type1;
|
|
|
|
gBattleMons[gActiveBattler].type2 = gBaseStats[gBattleMons[gActiveBattler].species].type2;
|
2018-11-17 12:10:24 +01:00
|
|
|
gBattleMons[gActiveBattler].type3 = TYPE_MYSTERY;
|
2017-10-02 23:32:39 +02:00
|
|
|
|
2018-02-06 23:09:39 +01:00
|
|
|
ClearBattlerMoveHistory(gActiveBattler);
|
|
|
|
ClearBattlerAbilityHistory(gActiveBattler);
|
2018-09-16 21:08:49 +02:00
|
|
|
if (GetBattlerSide(gActiveBattler) == B_SIDE_PLAYER)
|
|
|
|
UndoMegaEvolution(gBattlerPartyIndexes[gActiveBattler]);
|
2017-10-02 23:32:39 +02:00
|
|
|
}
|
|
|
|
|
2018-12-23 18:47:00 +01:00
|
|
|
static void DoBattleIntro(void)
|
2017-10-02 23:32:39 +02:00
|
|
|
{
|
2018-12-23 18:47:00 +01:00
|
|
|
s32 i;
|
|
|
|
u8 *state = &gBattleStruct->introState;
|
|
|
|
|
|
|
|
switch (*state)
|
2017-10-02 23:32:39 +02:00
|
|
|
{
|
2018-12-23 18:47:00 +01:00
|
|
|
case 0: // Get Data of all battlers.
|
2018-02-06 02:46:59 +01:00
|
|
|
gActiveBattler = gBattleCommunication[1];
|
2018-09-20 11:55:35 +02:00
|
|
|
BtlController_EmitGetMonData(0, REQUEST_ALL_BATTLE, 0);
|
2018-02-06 20:48:02 +01:00
|
|
|
MarkBattlerForControllerExec(gActiveBattler);
|
2018-12-23 18:47:00 +01:00
|
|
|
(*state)++;
|
2017-10-02 23:32:39 +02:00
|
|
|
break;
|
2018-12-23 18:47:00 +01:00
|
|
|
case 1: // Loop through all battlers.
|
|
|
|
if (!gBattleControllerExecFlags)
|
2017-10-02 23:32:39 +02:00
|
|
|
{
|
2018-12-23 18:47:00 +01:00
|
|
|
if (++gBattleCommunication[1] == gBattlersCount)
|
|
|
|
(*state)++;
|
2017-10-02 23:32:39 +02:00
|
|
|
else
|
2018-12-23 18:47:00 +01:00
|
|
|
*state = 0;
|
2017-10-02 23:32:39 +02:00
|
|
|
}
|
|
|
|
break;
|
2018-12-23 18:47:00 +01:00
|
|
|
case 2: // Start graphical intro slide.
|
|
|
|
if (!gBattleControllerExecFlags)
|
2017-10-02 23:32:39 +02:00
|
|
|
{
|
2018-12-23 18:47:00 +01:00
|
|
|
gActiveBattler = GetBattlerAtPosition(0);
|
|
|
|
BtlController_EmitIntroSlide(0, gBattleTerrain);
|
2018-02-06 20:48:02 +01:00
|
|
|
MarkBattlerForControllerExec(gActiveBattler);
|
2018-12-23 18:47:00 +01:00
|
|
|
gBattleCommunication[0] = 0;
|
|
|
|
gBattleCommunication[1] = 0;
|
|
|
|
(*state)++;
|
2017-10-02 23:32:39 +02:00
|
|
|
}
|
2018-12-23 18:47:00 +01:00
|
|
|
break;
|
|
|
|
case 3: // Wait for intro slide.
|
|
|
|
if (!gBattleControllerExecFlags)
|
|
|
|
(*state)++;
|
|
|
|
break;
|
|
|
|
case 4: // Copy battler data gotten in cases 0 and 1. Draw trainer/mon sprite.
|
|
|
|
for (gActiveBattler = 0; gActiveBattler < gBattlersCount; gActiveBattler++)
|
2017-10-02 23:32:39 +02:00
|
|
|
{
|
2018-12-23 18:47:00 +01:00
|
|
|
if ((gBattleTypeFlags & BATTLE_TYPE_SAFARI) && GetBattlerSide(gActiveBattler) == B_SIDE_PLAYER)
|
2017-10-02 23:32:39 +02:00
|
|
|
{
|
2018-12-23 18:47:00 +01:00
|
|
|
memset(&gBattleMons[gActiveBattler], 0, sizeof(struct BattlePokemon));
|
2017-10-02 23:32:39 +02:00
|
|
|
}
|
2018-12-23 18:47:00 +01:00
|
|
|
else
|
2017-10-02 23:32:39 +02:00
|
|
|
{
|
2019-01-05 16:00:57 +01:00
|
|
|
memcpy(&gBattleMons[gActiveBattler], &gBattleResources->bufferB[gActiveBattler][4], sizeof(struct BattlePokemon));
|
2018-12-23 18:47:00 +01:00
|
|
|
gBattleMons[gActiveBattler].type1 = gBaseStats[gBattleMons[gActiveBattler].species].type1;
|
|
|
|
gBattleMons[gActiveBattler].type2 = gBaseStats[gBattleMons[gActiveBattler].species].type2;
|
|
|
|
gBattleMons[gActiveBattler].type3 = TYPE_MYSTERY;
|
|
|
|
gBattleMons[gActiveBattler].ability = GetAbilityBySpecies(gBattleMons[gActiveBattler].species, gBattleMons[gActiveBattler].altAbility);
|
|
|
|
gBattleStruct->hpOnSwitchout[GetBattlerSide(gActiveBattler)] = gBattleMons[gActiveBattler].hp;
|
|
|
|
gBattleMons[gActiveBattler].status2 = 0;
|
|
|
|
for (i = 0; i < NUM_BATTLE_STATS; i++)
|
|
|
|
gBattleMons[gActiveBattler].statStages[i] = 6;
|
2017-10-02 23:32:39 +02:00
|
|
|
}
|
|
|
|
|
2018-12-23 18:47:00 +01:00
|
|
|
// Draw sprite.
|
|
|
|
switch (GetBattlerPosition(gActiveBattler))
|
2017-10-02 23:32:39 +02:00
|
|
|
{
|
2018-12-23 18:47:00 +01:00
|
|
|
case B_POSITION_PLAYER_LEFT: // player sprite
|
2018-02-06 20:48:02 +01:00
|
|
|
BtlController_EmitDrawTrainerPic(0);
|
|
|
|
MarkBattlerForControllerExec(gActiveBattler);
|
2018-12-23 18:47:00 +01:00
|
|
|
break;
|
|
|
|
case B_POSITION_OPPONENT_LEFT:
|
|
|
|
if (gBattleTypeFlags & BATTLE_TYPE_TRAINER) // opponent 1 sprite
|
|
|
|
{
|
|
|
|
BtlController_EmitDrawTrainerPic(0);
|
|
|
|
MarkBattlerForControllerExec(gActiveBattler);
|
|
|
|
}
|
|
|
|
else // wild mon 1
|
|
|
|
{
|
|
|
|
BtlController_EmitLoadMonSprite(0);
|
|
|
|
MarkBattlerForControllerExec(gActiveBattler);
|
|
|
|
gBattleResults.lastOpponentSpecies = GetMonData(&gEnemyParty[gBattlerPartyIndexes[gActiveBattler]], MON_DATA_SPECIES, NULL);
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case B_POSITION_PLAYER_RIGHT:
|
|
|
|
if (gBattleTypeFlags & (BATTLE_TYPE_MULTI | BATTLE_TYPE_INGAME_PARTNER)) // partner sprite
|
|
|
|
{
|
|
|
|
BtlController_EmitDrawTrainerPic(0);
|
|
|
|
MarkBattlerForControllerExec(gActiveBattler);
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case B_POSITION_OPPONENT_RIGHT:
|
|
|
|
if (gBattleTypeFlags & BATTLE_TYPE_TRAINER)
|
|
|
|
{
|
2019-01-27 20:54:34 +01:00
|
|
|
if (gBattleTypeFlags & (BATTLE_TYPE_MULTI | BATTLE_TYPE_TWO_OPPONENTS) && !BATTLE_TWO_VS_ONE_OPPONENT) // opponent 2 if exists
|
2018-12-23 18:47:00 +01:00
|
|
|
{
|
|
|
|
BtlController_EmitDrawTrainerPic(0);
|
|
|
|
MarkBattlerForControllerExec(gActiveBattler);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else // wild mon 2
|
|
|
|
{
|
|
|
|
BtlController_EmitLoadMonSprite(0);
|
|
|
|
MarkBattlerForControllerExec(gActiveBattler);
|
|
|
|
gBattleResults.lastOpponentSpecies = GetMonData(&gEnemyParty[gBattlerPartyIndexes[gActiveBattler]], MON_DATA_SPECIES, NULL);
|
|
|
|
}
|
|
|
|
break;
|
2017-10-02 23:32:39 +02:00
|
|
|
}
|
2018-12-23 18:47:00 +01:00
|
|
|
|
|
|
|
if (gBattleTypeFlags & BATTLE_TYPE_ARENA)
|
|
|
|
BattleArena_InitPoints();
|
2017-10-02 23:32:39 +02:00
|
|
|
}
|
|
|
|
|
2018-12-23 18:47:00 +01:00
|
|
|
if (gBattleTypeFlags & BATTLE_TYPE_TRAINER)
|
2017-10-02 23:32:39 +02:00
|
|
|
{
|
2018-12-23 18:47:00 +01:00
|
|
|
(*state)++;
|
2017-10-02 23:32:39 +02:00
|
|
|
}
|
2018-12-23 18:47:00 +01:00
|
|
|
else // Skip party summary since it is a wild battle.
|
2017-10-02 23:32:39 +02:00
|
|
|
{
|
2018-12-23 18:47:00 +01:00
|
|
|
if (B_FAST_INTRO)
|
|
|
|
*state = 7; // Don't wait for sprite, print message at the same time.
|
2017-10-02 23:32:39 +02:00
|
|
|
else
|
2018-12-23 18:47:00 +01:00
|
|
|
*state = 6; // Wait for sprite to load.
|
2017-10-02 23:32:39 +02:00
|
|
|
}
|
2018-12-23 18:47:00 +01:00
|
|
|
break;
|
|
|
|
case 5: // draw party summary in trainer battles
|
|
|
|
if (!gBattleControllerExecFlags)
|
2017-10-02 23:32:39 +02:00
|
|
|
{
|
2018-12-23 18:47:00 +01:00
|
|
|
struct HpAndStatus hpStatus[PARTY_SIZE];
|
|
|
|
|
|
|
|
for (i = 0; i < PARTY_SIZE; i++)
|
2017-10-02 23:32:39 +02:00
|
|
|
{
|
2018-12-23 18:47:00 +01:00
|
|
|
if (GetMonData(&gEnemyParty[i], MON_DATA_SPECIES2) == SPECIES_NONE
|
|
|
|
|| GetMonData(&gEnemyParty[i], MON_DATA_SPECIES2) == SPECIES_EGG)
|
|
|
|
{
|
|
|
|
hpStatus[i].hp = 0xFFFF;
|
|
|
|
hpStatus[i].status = 0;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
hpStatus[i].hp = GetMonData(&gEnemyParty[i], MON_DATA_HP);
|
|
|
|
hpStatus[i].status = GetMonData(&gEnemyParty[i], MON_DATA_STATUS);
|
|
|
|
}
|
2017-10-02 23:32:39 +02:00
|
|
|
}
|
2018-12-23 18:47:00 +01:00
|
|
|
|
|
|
|
gActiveBattler = GetBattlerAtPosition(B_POSITION_OPPONENT_LEFT);
|
|
|
|
BtlController_EmitDrawPartyStatusSummary(0, hpStatus, 0x80);
|
|
|
|
MarkBattlerForControllerExec(gActiveBattler);
|
|
|
|
|
|
|
|
for (i = 0; i < PARTY_SIZE; i++)
|
2017-10-02 23:32:39 +02:00
|
|
|
{
|
2018-12-23 18:47:00 +01:00
|
|
|
if (GetMonData(&gPlayerParty[i], MON_DATA_SPECIES2) == SPECIES_NONE
|
|
|
|
|| GetMonData(&gPlayerParty[i], MON_DATA_SPECIES2) == SPECIES_EGG)
|
|
|
|
{
|
|
|
|
hpStatus[i].hp = 0xFFFF;
|
|
|
|
hpStatus[i].status = 0;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
hpStatus[i].hp = GetMonData(&gPlayerParty[i], MON_DATA_HP);
|
|
|
|
hpStatus[i].status = GetMonData(&gPlayerParty[i], MON_DATA_STATUS);
|
|
|
|
}
|
2017-10-02 23:32:39 +02:00
|
|
|
}
|
|
|
|
|
2018-12-23 18:47:00 +01:00
|
|
|
gActiveBattler = GetBattlerAtPosition(B_POSITION_PLAYER_LEFT);
|
|
|
|
BtlController_EmitDrawPartyStatusSummary(0, hpStatus, 0x80);
|
|
|
|
MarkBattlerForControllerExec(gActiveBattler);
|
2017-10-02 23:32:39 +02:00
|
|
|
|
2018-12-23 18:47:00 +01:00
|
|
|
(*state)++;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case 6: // wait for previous action to complete
|
|
|
|
if (!gBattleControllerExecFlags)
|
|
|
|
(*state)++;
|
|
|
|
break;
|
|
|
|
case 7: // print battle intro message
|
|
|
|
if (!IsBattlerMarkedForControllerExec(GetBattlerAtPosition(B_POSITION_PLAYER_LEFT)))
|
2017-10-02 23:32:39 +02:00
|
|
|
{
|
2018-12-23 18:47:00 +01:00
|
|
|
PrepareStringBattle(STRINGID_INTROMSG, GetBattlerAtPosition(B_POSITION_PLAYER_LEFT));
|
|
|
|
(*state)++;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case 8: // wait for intro message to be printed
|
|
|
|
if (!IsBattlerMarkedForControllerExec(GetBattlerAtPosition(B_POSITION_PLAYER_LEFT)))
|
|
|
|
{
|
|
|
|
if (gBattleTypeFlags & BATTLE_TYPE_TRAINER)
|
2017-10-02 23:32:39 +02:00
|
|
|
{
|
2018-12-23 18:47:00 +01:00
|
|
|
(*state)++;
|
2017-10-02 23:32:39 +02:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2018-12-23 18:47:00 +01:00
|
|
|
if (B_FAST_INTRO)
|
|
|
|
*state = 15; // Wait for text to be printed.
|
|
|
|
else
|
|
|
|
*state = 14; // Wait for text and sprite.
|
2017-10-02 23:32:39 +02:00
|
|
|
}
|
|
|
|
}
|
2018-12-23 18:47:00 +01:00
|
|
|
break;
|
|
|
|
case 9: // print opponent sends out
|
|
|
|
if (gBattleTypeFlags & BATTLE_TYPE_x2000000 && !(gBattleTypeFlags & BATTLE_TYPE_x80000000))
|
|
|
|
PrepareStringBattle(STRINGID_INTROSENDOUT, GetBattlerAtPosition(B_POSITION_PLAYER_LEFT));
|
2017-10-02 23:32:39 +02:00
|
|
|
else
|
2018-12-23 18:47:00 +01:00
|
|
|
PrepareStringBattle(STRINGID_INTROSENDOUT, GetBattlerAtPosition(B_POSITION_OPPONENT_LEFT));
|
|
|
|
(*state)++;
|
|
|
|
break;
|
|
|
|
case 10: // wait for opponent sends out text
|
|
|
|
if (!gBattleControllerExecFlags)
|
|
|
|
(*state)++;
|
|
|
|
break;
|
|
|
|
case 11: // first opponent's mon send out animation
|
|
|
|
if (gBattleTypeFlags & BATTLE_TYPE_x2000000 && !(gBattleTypeFlags & BATTLE_TYPE_x80000000))
|
|
|
|
gActiveBattler = GetBattlerAtPosition(B_POSITION_PLAYER_LEFT);
|
2017-10-02 23:32:39 +02:00
|
|
|
else
|
2018-12-23 18:47:00 +01:00
|
|
|
gActiveBattler = GetBattlerAtPosition(B_POSITION_OPPONENT_LEFT);
|
2017-10-02 23:32:39 +02:00
|
|
|
|
2018-12-23 18:47:00 +01:00
|
|
|
BtlController_EmitIntroTrainerBallThrow(0);
|
|
|
|
MarkBattlerForControllerExec(gActiveBattler);
|
|
|
|
(*state)++;
|
|
|
|
break;
|
|
|
|
case 12: // nothing
|
|
|
|
(*state)++;
|
|
|
|
case 13: // second opponent's mon send out
|
2019-01-27 20:54:34 +01:00
|
|
|
if (gBattleTypeFlags & (BATTLE_TYPE_MULTI | BATTLE_TYPE_TWO_OPPONENTS) && !BATTLE_TWO_VS_ONE_OPPONENT)
|
2017-10-02 23:32:39 +02:00
|
|
|
{
|
2018-12-23 18:47:00 +01:00
|
|
|
if (gBattleTypeFlags & BATTLE_TYPE_x2000000 && !(gBattleTypeFlags & BATTLE_TYPE_x80000000))
|
|
|
|
gActiveBattler = GetBattlerAtPosition(B_POSITION_PLAYER_RIGHT);
|
|
|
|
else
|
|
|
|
gActiveBattler = GetBattlerAtPosition(B_POSITION_OPPONENT_RIGHT);
|
|
|
|
|
2018-02-06 20:48:02 +01:00
|
|
|
BtlController_EmitIntroTrainerBallThrow(0);
|
|
|
|
MarkBattlerForControllerExec(gActiveBattler);
|
2017-10-02 23:32:39 +02:00
|
|
|
}
|
2018-12-23 18:47:00 +01:00
|
|
|
if (B_FAST_INTRO && !(gBattleTypeFlags & (BATTLE_TYPE_RECORDED | BATTLE_TYPE_x2000000 | BATTLE_TYPE_x80000000 | BATTLE_TYPE_LINK)))
|
|
|
|
*state = 15; // Print at the same time as trainer sends out second mon.
|
2017-10-02 23:32:39 +02:00
|
|
|
else
|
2018-12-23 18:47:00 +01:00
|
|
|
(*state)++;
|
|
|
|
break;
|
|
|
|
case 14: // wait for opponent 2 send out
|
|
|
|
if (!gBattleControllerExecFlags)
|
|
|
|
(*state)++;
|
|
|
|
break;
|
|
|
|
case 15: // wait for wild battle message
|
|
|
|
if (!IsBattlerMarkedForControllerExec(GetBattlerAtPosition(B_POSITION_PLAYER_LEFT)))
|
|
|
|
(*state)++;
|
|
|
|
break;
|
|
|
|
case 16: // print player sends out
|
|
|
|
if (!(gBattleTypeFlags & BATTLE_TYPE_SAFARI))
|
2017-10-02 23:32:39 +02:00
|
|
|
{
|
2018-12-23 18:47:00 +01:00
|
|
|
if (gBattleTypeFlags & BATTLE_TYPE_x2000000 && !(gBattleTypeFlags & BATTLE_TYPE_x80000000))
|
|
|
|
gActiveBattler = GetBattlerAtPosition(B_POSITION_OPPONENT_LEFT);
|
|
|
|
else
|
|
|
|
gActiveBattler = GetBattlerAtPosition(B_POSITION_PLAYER_LEFT);
|
|
|
|
|
|
|
|
// A hack that makes fast intro work in trainer battles too.
|
|
|
|
if (B_FAST_INTRO
|
|
|
|
&& gBattleTypeFlags & BATTLE_TYPE_TRAINER
|
|
|
|
&& !(gBattleTypeFlags & (BATTLE_TYPE_RECORDED | BATTLE_TYPE_x2000000 | BATTLE_TYPE_x80000000 | BATTLE_TYPE_LINK))
|
|
|
|
&& gSprites[gHealthboxSpriteIds[gActiveBattler ^ BIT_SIDE]].callback == SpriteCallbackDummy)
|
2017-10-02 23:32:39 +02:00
|
|
|
{
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2018-12-23 18:47:00 +01:00
|
|
|
PrepareStringBattle(STRINGID_INTROSENDOUT, gActiveBattler);
|
2017-10-02 23:32:39 +02:00
|
|
|
}
|
2018-12-23 18:47:00 +01:00
|
|
|
(*state)++;
|
|
|
|
break;
|
|
|
|
case 17: // wait for player send out message
|
|
|
|
if (!(gBattleTypeFlags & BATTLE_TYPE_LINK && gBattleControllerExecFlags))
|
2017-10-02 23:32:39 +02:00
|
|
|
{
|
2018-12-23 18:47:00 +01:00
|
|
|
if (gBattleTypeFlags & BATTLE_TYPE_x2000000 && !(gBattleTypeFlags & BATTLE_TYPE_x80000000))
|
|
|
|
gActiveBattler = GetBattlerAtPosition(B_POSITION_OPPONENT_LEFT);
|
2017-10-02 23:32:39 +02:00
|
|
|
else
|
2018-12-23 18:47:00 +01:00
|
|
|
gActiveBattler = GetBattlerAtPosition(B_POSITION_PLAYER_LEFT);
|
2017-10-02 23:32:39 +02:00
|
|
|
|
2018-12-23 18:47:00 +01:00
|
|
|
if (!IsBattlerMarkedForControllerExec(gActiveBattler))
|
|
|
|
(*state)++;
|
2017-10-02 23:32:39 +02:00
|
|
|
}
|
2018-12-23 18:47:00 +01:00
|
|
|
break;
|
|
|
|
case 18: // player 1 send out
|
|
|
|
if (gBattleTypeFlags & BATTLE_TYPE_x2000000 && !(gBattleTypeFlags & BATTLE_TYPE_x80000000))
|
|
|
|
gActiveBattler = GetBattlerAtPosition(B_POSITION_OPPONENT_LEFT);
|
2017-10-02 23:32:39 +02:00
|
|
|
else
|
2018-12-23 18:47:00 +01:00
|
|
|
gActiveBattler = GetBattlerAtPosition(B_POSITION_PLAYER_LEFT);
|
2017-10-02 23:32:39 +02:00
|
|
|
|
2018-12-23 18:47:00 +01:00
|
|
|
BtlController_EmitIntroTrainerBallThrow(0);
|
|
|
|
MarkBattlerForControllerExec(gActiveBattler);
|
|
|
|
(*state)++;
|
|
|
|
break;
|
|
|
|
case 19: // player 2 send out
|
|
|
|
if (gBattleTypeFlags & (BATTLE_TYPE_MULTI | BATTLE_TYPE_INGAME_PARTNER))
|
2017-10-02 23:32:39 +02:00
|
|
|
{
|
2018-12-23 18:47:00 +01:00
|
|
|
if (gBattleTypeFlags & BATTLE_TYPE_x2000000 && !(gBattleTypeFlags & BATTLE_TYPE_x80000000))
|
|
|
|
gActiveBattler = GetBattlerAtPosition(B_POSITION_OPPONENT_RIGHT);
|
|
|
|
else
|
|
|
|
gActiveBattler = GetBattlerAtPosition(B_POSITION_PLAYER_RIGHT);
|
|
|
|
|
2018-02-06 20:48:02 +01:00
|
|
|
BtlController_EmitIntroTrainerBallThrow(0);
|
|
|
|
MarkBattlerForControllerExec(gActiveBattler);
|
2017-10-02 23:32:39 +02:00
|
|
|
}
|
2018-12-23 18:47:00 +01:00
|
|
|
(*state)++;
|
|
|
|
break;
|
|
|
|
case 20: // set dex and battle vars
|
|
|
|
if (!gBattleControllerExecFlags)
|
2017-10-02 23:32:39 +02:00
|
|
|
{
|
2018-12-23 18:47:00 +01:00
|
|
|
for (gActiveBattler = 0; gActiveBattler < gBattlersCount; gActiveBattler++)
|
2017-10-02 23:32:39 +02:00
|
|
|
{
|
2018-12-23 18:47:00 +01:00
|
|
|
if (GetBattlerSide(gActiveBattler) == B_SIDE_OPPONENT
|
|
|
|
&& !(gBattleTypeFlags & (BATTLE_TYPE_EREADER_TRAINER
|
|
|
|
| BATTLE_TYPE_FRONTIER
|
|
|
|
| BATTLE_TYPE_LINK
|
|
|
|
| BATTLE_TYPE_x2000000
|
|
|
|
| BATTLE_TYPE_TRAINER_HILL)))
|
|
|
|
{
|
|
|
|
HandleSetPokedexFlag(SpeciesToNationalPokedexNum(gBattleMons[gActiveBattler].species), FLAG_SET_SEEN, gBattleMons[gActiveBattler].personality);
|
|
|
|
}
|
2017-10-02 23:32:39 +02:00
|
|
|
}
|
|
|
|
|
2018-12-23 18:47:00 +01:00
|
|
|
gBattleStruct->switchInAbilitiesCounter = 0;
|
|
|
|
gBattleStruct->switchInItemsCounter = 0;
|
|
|
|
gBattleStruct->overworldWeatherDone = FALSE;
|
2017-10-02 23:32:39 +02:00
|
|
|
|
2018-12-23 18:47:00 +01:00
|
|
|
gBattleMainFunc = TryDoEventsBeforeFirstTurn;
|
|
|
|
}
|
|
|
|
break;
|
2017-10-02 23:32:39 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static void TryDoEventsBeforeFirstTurn(void)
|
|
|
|
{
|
|
|
|
s32 i;
|
|
|
|
s32 j;
|
|
|
|
u8 effect = 0;
|
|
|
|
|
2018-02-06 20:48:02 +01:00
|
|
|
if (gBattleControllerExecFlags)
|
2017-10-02 23:32:39 +02:00
|
|
|
return;
|
|
|
|
|
|
|
|
if (gBattleStruct->switchInAbilitiesCounter == 0)
|
|
|
|
{
|
2018-02-06 02:46:59 +01:00
|
|
|
for (i = 0; i < gBattlersCount; i++)
|
2018-06-28 21:06:32 +02:00
|
|
|
gBattlerByTurnOrder[i] = i;
|
2018-02-06 02:46:59 +01:00
|
|
|
for (i = 0; i < gBattlersCount - 1; i++)
|
2017-10-02 23:32:39 +02:00
|
|
|
{
|
2018-02-06 02:46:59 +01:00
|
|
|
for (j = i + 1; j < gBattlersCount; j++)
|
2017-10-02 23:32:39 +02:00
|
|
|
{
|
2018-06-28 21:06:32 +02:00
|
|
|
if (GetWhoStrikesFirst(gBattlerByTurnOrder[i], gBattlerByTurnOrder[j], TRUE) != 0)
|
2017-10-04 19:25:14 +02:00
|
|
|
SwapTurnOrder(i, j);
|
2017-10-02 23:32:39 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (!gBattleStruct->overworldWeatherDone
|
|
|
|
&& AbilityBattleEffects(0, 0, 0, ABILITYEFFECT_SWITCH_IN_WEATHER, 0) != 0)
|
|
|
|
{
|
|
|
|
gBattleStruct->overworldWeatherDone = TRUE;
|
|
|
|
return;
|
|
|
|
}
|
2018-06-28 21:06:32 +02:00
|
|
|
// Check all switch in abilities happening from the fastest mon to slowest.
|
2018-02-06 02:46:59 +01:00
|
|
|
while (gBattleStruct->switchInAbilitiesCounter < gBattlersCount)
|
2017-10-02 23:32:39 +02:00
|
|
|
{
|
2018-06-28 21:06:32 +02:00
|
|
|
if (AbilityBattleEffects(ABILITYEFFECT_ON_SWITCHIN, gBattlerByTurnOrder[gBattleStruct->switchInAbilitiesCounter], 0, 0, 0) != 0)
|
2017-10-02 23:32:39 +02:00
|
|
|
effect++;
|
|
|
|
|
|
|
|
gBattleStruct->switchInAbilitiesCounter++;
|
|
|
|
|
|
|
|
if (effect)
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
if (AbilityBattleEffects(ABILITYEFFECT_INTIMIDATE1, 0, 0, 0, 0) != 0)
|
|
|
|
return;
|
|
|
|
if (AbilityBattleEffects(ABILITYEFFECT_TRACE, 0, 0, 0, 0) != 0)
|
|
|
|
return;
|
2018-06-28 21:06:32 +02:00
|
|
|
// Check all switch in items having effect from the fastest mon to slowest.
|
2018-02-06 02:46:59 +01:00
|
|
|
while (gBattleStruct->switchInItemsCounter < gBattlersCount)
|
2017-10-02 23:32:39 +02:00
|
|
|
{
|
2018-09-01 20:00:13 +02:00
|
|
|
if (ItemBattleEffects(ITEMEFFECT_ON_SWITCH_IN, gBattlerByTurnOrder[gBattleStruct->switchInItemsCounter], FALSE))
|
2017-10-02 23:32:39 +02:00
|
|
|
effect++;
|
|
|
|
|
|
|
|
gBattleStruct->switchInItemsCounter++;
|
|
|
|
|
|
|
|
if (effect)
|
|
|
|
return;
|
|
|
|
}
|
2018-02-06 02:46:59 +01:00
|
|
|
for (i = 0; i < MAX_BATTLERS_COUNT; i++)
|
2017-10-02 23:32:39 +02:00
|
|
|
{
|
2018-06-28 21:06:32 +02:00
|
|
|
*(gBattleStruct->monToSwitchIntoId + i) = PARTY_SIZE;
|
2018-02-06 23:09:39 +01:00
|
|
|
gChosenActionByBattler[i] = B_ACTION_NONE;
|
|
|
|
gChosenMoveByBattler[i] = MOVE_NONE;
|
2017-10-02 23:32:39 +02:00
|
|
|
}
|
2017-10-06 00:12:01 +02:00
|
|
|
TurnValuesCleanUp(FALSE);
|
2017-10-02 23:32:39 +02:00
|
|
|
SpecialStatusesClear();
|
2018-02-06 02:46:59 +01:00
|
|
|
*(&gBattleStruct->field_91) = gAbsentBattlerFlags;
|
2018-06-17 16:48:58 +02:00
|
|
|
BattlePutTextOnWindow(gText_EmptyString3, 0);
|
2017-10-04 19:25:14 +02:00
|
|
|
gBattleMainFunc = HandleTurnActionSelectionState;
|
2017-10-02 23:32:39 +02:00
|
|
|
ResetSentPokesToOpponentValue();
|
|
|
|
|
|
|
|
for (i = 0; i < BATTLE_COMMUNICATION_ENTRIES_COUNT; i++)
|
|
|
|
gBattleCommunication[i] = 0;
|
|
|
|
|
2018-02-06 02:46:59 +01:00
|
|
|
for (i = 0; i < gBattlersCount; i++)
|
2017-10-02 23:32:39 +02:00
|
|
|
gBattleMons[i].status2 &= ~(STATUS2_FLINCHED);
|
|
|
|
|
|
|
|
*(&gBattleStruct->turnEffectsTracker) = 0;
|
2018-02-07 22:53:40 +01:00
|
|
|
*(&gBattleStruct->turnEffectsBattlerId) = 0;
|
2017-12-02 14:08:55 +01:00
|
|
|
*(&gBattleStruct->wishPerishSongState) = 0;
|
2018-02-07 22:53:40 +01:00
|
|
|
*(&gBattleStruct->wishPerishSongBattlerId) = 0;
|
2017-10-02 23:32:39 +02:00
|
|
|
gBattleScripting.atk49_state = 0;
|
2017-12-02 14:08:55 +01:00
|
|
|
gBattleStruct->faintedActionsState = 0;
|
2018-02-07 22:53:40 +01:00
|
|
|
gBattleStruct->turnCountersTracker = 0;
|
2018-01-16 22:12:38 +01:00
|
|
|
gMoveResultFlags = 0;
|
2017-10-02 23:32:39 +02:00
|
|
|
|
|
|
|
gRandomTurnNumber = Random();
|
|
|
|
|
|
|
|
if (gBattleTypeFlags & BATTLE_TYPE_ARENA)
|
|
|
|
{
|
|
|
|
StopCryAndClearCrySongs();
|
2018-08-25 21:04:12 +02:00
|
|
|
BattleScriptExecute(BattleScript_ArenaTurnBeginning);
|
2017-10-02 23:32:39 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-10-06 19:09:37 +02:00
|
|
|
static void HandleEndTurn_ContinueBattle(void)
|
2017-10-02 23:32:39 +02:00
|
|
|
{
|
|
|
|
s32 i;
|
|
|
|
|
2018-02-06 20:48:02 +01:00
|
|
|
if (gBattleControllerExecFlags == 0)
|
2017-10-02 23:32:39 +02:00
|
|
|
{
|
|
|
|
gBattleMainFunc = BattleTurnPassed;
|
|
|
|
for (i = 0; i < BATTLE_COMMUNICATION_ENTRIES_COUNT; i++)
|
|
|
|
gBattleCommunication[i] = 0;
|
2018-02-06 02:46:59 +01:00
|
|
|
for (i = 0; i < gBattlersCount; i++)
|
2017-10-02 23:32:39 +02:00
|
|
|
{
|
|
|
|
gBattleMons[i].status2 &= ~(STATUS2_FLINCHED);
|
2018-01-16 22:12:38 +01:00
|
|
|
if ((gBattleMons[i].status1 & STATUS1_SLEEP) && (gBattleMons[i].status2 & STATUS2_MULTIPLETURNS))
|
2017-10-02 23:32:39 +02:00
|
|
|
CancelMultiTurnMoves(i);
|
|
|
|
}
|
|
|
|
gBattleStruct->turnEffectsTracker = 0;
|
2018-02-07 22:53:40 +01:00
|
|
|
gBattleStruct->turnEffectsBattlerId = 0;
|
2017-12-02 14:08:55 +01:00
|
|
|
gBattleStruct->wishPerishSongState = 0;
|
2018-02-07 22:53:40 +01:00
|
|
|
gBattleStruct->wishPerishSongBattlerId = 0;
|
|
|
|
gBattleStruct->turnCountersTracker = 0;
|
2018-01-16 22:12:38 +01:00
|
|
|
gMoveResultFlags = 0;
|
2017-10-02 23:32:39 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void BattleTurnPassed(void)
|
|
|
|
{
|
|
|
|
s32 i;
|
|
|
|
|
2017-10-06 00:12:01 +02:00
|
|
|
TurnValuesCleanUp(TRUE);
|
2017-10-02 23:32:39 +02:00
|
|
|
if (gBattleOutcome == 0)
|
|
|
|
{
|
2018-07-21 12:10:08 +02:00
|
|
|
if (DoFieldEndTurnEffects())
|
2017-10-02 23:32:39 +02:00
|
|
|
return;
|
2018-07-18 22:07:48 +02:00
|
|
|
if (DoBattlerEndTurnEffects())
|
2017-10-02 23:32:39 +02:00
|
|
|
return;
|
|
|
|
}
|
2018-06-28 21:06:32 +02:00
|
|
|
if (HandleFaintedMonActions())
|
2017-10-02 23:32:39 +02:00
|
|
|
return;
|
2017-12-02 14:08:55 +01:00
|
|
|
gBattleStruct->faintedActionsState = 0;
|
2018-06-28 21:06:32 +02:00
|
|
|
if (HandleWishPerishSongOnTurnEnd())
|
2017-10-02 23:32:39 +02:00
|
|
|
return;
|
|
|
|
|
2017-10-06 00:12:01 +02:00
|
|
|
TurnValuesCleanUp(FALSE);
|
2017-10-02 23:32:39 +02:00
|
|
|
gHitMarker &= ~(HITMARKER_NO_ATTACKSTRING);
|
|
|
|
gHitMarker &= ~(HITMARKER_UNABLE_TO_USE_MOVE);
|
|
|
|
gHitMarker &= ~(HITMARKER_x400000);
|
|
|
|
gHitMarker &= ~(HITMARKER_x100000);
|
|
|
|
gBattleScripting.animTurn = 0;
|
|
|
|
gBattleScripting.animTargetsHit = 0;
|
|
|
|
gBattleScripting.atk49_state = 0;
|
|
|
|
gBattleMoveDamage = 0;
|
2018-01-16 22:12:38 +01:00
|
|
|
gMoveResultFlags = 0;
|
2017-10-02 23:32:39 +02:00
|
|
|
|
|
|
|
for (i = 0; i < 5; i++)
|
|
|
|
gBattleCommunication[i] = 0;
|
|
|
|
|
|
|
|
if (gBattleOutcome != 0)
|
|
|
|
{
|
2017-10-06 00:12:01 +02:00
|
|
|
gCurrentActionFuncId = 12;
|
|
|
|
gBattleMainFunc = RunTurnActionsFunctions;
|
2017-10-02 23:32:39 +02:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (gBattleResults.battleTurnCounter < 0xFF)
|
|
|
|
{
|
|
|
|
gBattleResults.battleTurnCounter++;
|
2018-12-07 23:50:56 +01:00
|
|
|
gBattleStruct->arenaTurnCounter++;
|
2017-10-02 23:32:39 +02:00
|
|
|
}
|
|
|
|
|
2018-02-06 02:46:59 +01:00
|
|
|
for (i = 0; i < gBattlersCount; i++)
|
2017-10-02 23:32:39 +02:00
|
|
|
{
|
2018-02-06 23:09:39 +01:00
|
|
|
gChosenActionByBattler[i] = B_ACTION_NONE;
|
|
|
|
gChosenMoveByBattler[i] = MOVE_NONE;
|
2017-10-02 23:32:39 +02:00
|
|
|
}
|
|
|
|
|
2018-07-21 12:10:08 +02:00
|
|
|
for (i = 0; i < MAX_BATTLERS_COUNT; i++)
|
2018-06-28 21:06:32 +02:00
|
|
|
*(gBattleStruct->monToSwitchIntoId + i) = PARTY_SIZE;
|
2017-10-02 23:32:39 +02:00
|
|
|
|
2018-02-06 02:46:59 +01:00
|
|
|
*(&gBattleStruct->field_91) = gAbsentBattlerFlags;
|
2018-06-17 16:48:58 +02:00
|
|
|
BattlePutTextOnWindow(gText_EmptyString3, 0);
|
2017-10-04 19:25:14 +02:00
|
|
|
gBattleMainFunc = HandleTurnActionSelectionState;
|
2017-10-02 23:32:39 +02:00
|
|
|
gRandomTurnNumber = Random();
|
|
|
|
|
|
|
|
if (gBattleTypeFlags & BATTLE_TYPE_PALACE)
|
2017-11-25 18:42:31 +01:00
|
|
|
BattleScriptExecute(BattleScript_82DB881);
|
2018-12-07 23:50:56 +01:00
|
|
|
else if (gBattleTypeFlags & BATTLE_TYPE_ARENA && gBattleStruct->arenaTurnCounter == 0)
|
2018-08-25 21:04:12 +02:00
|
|
|
BattleScriptExecute(BattleScript_ArenaTurnBeginning);
|
2018-11-03 01:17:16 +01:00
|
|
|
else if (ShouldDoTrainerSlide(GetBattlerAtPosition(B_POSITION_OPPONENT_LEFT), gTrainerBattleOpponent_A, TRAINER_SLIDE_LAST_LOW_HP))
|
|
|
|
BattleScriptExecute(BattleScript_TrainerSlideMsgEnd2);
|
2017-10-02 23:32:39 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
u8 IsRunningFromBattleImpossible(void)
|
|
|
|
{
|
|
|
|
u8 holdEffect;
|
|
|
|
u8 side;
|
|
|
|
s32 i;
|
|
|
|
|
2018-02-06 02:46:59 +01:00
|
|
|
if (gBattleMons[gActiveBattler].item == ITEM_ENIGMA_BERRY)
|
|
|
|
holdEffect = gEnigmaBerries[gActiveBattler].holdEffect;
|
2017-10-02 23:32:39 +02:00
|
|
|
else
|
2018-02-06 02:46:59 +01:00
|
|
|
holdEffect = ItemId_GetHoldEffect(gBattleMons[gActiveBattler].item);
|
2017-10-02 23:32:39 +02:00
|
|
|
|
2018-02-08 12:13:29 +01:00
|
|
|
gPotentialItemEffectBattler = gActiveBattler;
|
2017-10-02 23:32:39 +02:00
|
|
|
|
2018-10-15 21:19:52 +02:00
|
|
|
if (gBattleTypeFlags & BATTLE_TYPE_FIRST_BATTLE) // Cannot ever run from saving Birch's battle.
|
|
|
|
{
|
|
|
|
gBattleCommunication[MULTISTRING_CHOOSER] = 1;
|
|
|
|
return 1;
|
|
|
|
}
|
2018-10-16 22:19:53 +02:00
|
|
|
if (GetBattlerPosition(gActiveBattler) == B_POSITION_PLAYER_RIGHT && WILD_DOUBLE_BATTLE) // The second pokemon cannot run from a double wild battle.
|
2018-10-15 21:19:52 +02:00
|
|
|
{
|
|
|
|
gBattleCommunication[MULTISTRING_CHOOSER] = 0;
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
2017-10-02 23:32:39 +02:00
|
|
|
if (holdEffect == HOLD_EFFECT_CAN_ALWAYS_RUN)
|
|
|
|
return 0;
|
|
|
|
if (gBattleTypeFlags & BATTLE_TYPE_LINK)
|
|
|
|
return 0;
|
2018-02-06 02:46:59 +01:00
|
|
|
if (gBattleMons[gActiveBattler].ability == ABILITY_RUN_AWAY)
|
2017-10-02 23:32:39 +02:00
|
|
|
return 0;
|
|
|
|
|
2018-02-06 02:46:59 +01:00
|
|
|
side = GetBattlerSide(gActiveBattler);
|
2017-10-02 23:32:39 +02:00
|
|
|
|
2018-02-06 02:46:59 +01:00
|
|
|
for (i = 0; i < gBattlersCount; i++)
|
2017-10-02 23:32:39 +02:00
|
|
|
{
|
2018-02-06 02:46:59 +01:00
|
|
|
if (side != GetBattlerSide(i)
|
2017-10-02 23:32:39 +02:00
|
|
|
&& gBattleMons[i].ability == ABILITY_SHADOW_TAG)
|
|
|
|
{
|
2018-02-06 02:46:59 +01:00
|
|
|
gBattleScripting.battler = i;
|
2017-10-02 23:32:39 +02:00
|
|
|
gLastUsedAbility = gBattleMons[i].ability;
|
|
|
|
gBattleCommunication[MULTISTRING_CHOOSER] = 2;
|
|
|
|
return 2;
|
|
|
|
}
|
2018-02-06 02:46:59 +01:00
|
|
|
if (side != GetBattlerSide(i)
|
|
|
|
&& gBattleMons[gActiveBattler].ability != ABILITY_LEVITATE
|
2018-03-01 00:59:52 +01:00
|
|
|
&& !IS_BATTLER_OF_TYPE(gActiveBattler, TYPE_FLYING)
|
2017-10-02 23:32:39 +02:00
|
|
|
&& gBattleMons[i].ability == ABILITY_ARENA_TRAP)
|
|
|
|
{
|
2018-02-06 02:46:59 +01:00
|
|
|
gBattleScripting.battler = i;
|
2017-10-02 23:32:39 +02:00
|
|
|
gLastUsedAbility = gBattleMons[i].ability;
|
|
|
|
gBattleCommunication[MULTISTRING_CHOOSER] = 2;
|
|
|
|
return 2;
|
|
|
|
}
|
|
|
|
}
|
2019-03-31 21:38:58 +02:00
|
|
|
i = IsAbilityOnFieldExcept(gActiveBattler, ABILITY_MAGNET_PULL);
|
2018-03-01 00:59:52 +01:00
|
|
|
if (i != 0 && IS_BATTLER_OF_TYPE(gActiveBattler, TYPE_STEEL))
|
2017-10-02 23:32:39 +02:00
|
|
|
{
|
2018-02-06 02:46:59 +01:00
|
|
|
gBattleScripting.battler = i - 1;
|
2017-10-02 23:32:39 +02:00
|
|
|
gLastUsedAbility = gBattleMons[i - 1].ability;
|
|
|
|
gBattleCommunication[MULTISTRING_CHOOSER] = 2;
|
|
|
|
return 2;
|
|
|
|
}
|
2018-02-06 02:46:59 +01:00
|
|
|
if ((gBattleMons[gActiveBattler].status2 & (STATUS2_ESCAPE_PREVENTION | STATUS2_WRAPPED))
|
|
|
|
|| (gStatuses3[gActiveBattler] & STATUS3_ROOTED))
|
2017-10-02 23:32:39 +02:00
|
|
|
{
|
|
|
|
gBattleCommunication[MULTISTRING_CHOOSER] = 0;
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
}
|
2017-10-03 21:35:27 +02:00
|
|
|
|
2018-02-06 23:09:39 +01:00
|
|
|
void sub_803BDA0(u8 battler)
|
2017-10-03 21:35:27 +02:00
|
|
|
{
|
|
|
|
s32 i;
|
|
|
|
u8 r4;
|
|
|
|
u8 r1;
|
|
|
|
|
2018-02-06 23:09:39 +01:00
|
|
|
// gBattleStruct->field_60[battler][i]
|
2017-10-03 21:35:27 +02:00
|
|
|
|
|
|
|
for (i = 0; i < 3; i++)
|
2018-02-06 23:09:39 +01:00
|
|
|
gUnknown_0203CF00[i] = *(battler * 3 + i + (u8*)(gBattleStruct->field_60));
|
2017-10-03 21:35:27 +02:00
|
|
|
|
2018-02-06 23:09:39 +01:00
|
|
|
r4 = pokemon_order_func(gBattlerPartyIndexes[battler]);
|
|
|
|
r1 = pokemon_order_func(*(gBattleStruct->monToSwitchIntoId + battler));
|
2017-10-03 21:35:27 +02:00
|
|
|
sub_81B8FB0(r4, r1);
|
|
|
|
|
|
|
|
if (gBattleTypeFlags & BATTLE_TYPE_DOUBLE)
|
|
|
|
{
|
|
|
|
for (i = 0; i < 3; i++)
|
|
|
|
{
|
2018-02-06 23:09:39 +01:00
|
|
|
*(battler * 3 + i + (u8*)(gBattleStruct->field_60)) = gUnknown_0203CF00[i];
|
|
|
|
*(BATTLE_PARTNER(battler) * 3 + i + (u8*)(gBattleStruct->field_60)) = gUnknown_0203CF00[i];
|
2017-10-03 21:35:27 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
for (i = 0; i < 3; i++)
|
|
|
|
{
|
2018-02-06 23:09:39 +01:00
|
|
|
*(battler * 3 + i + (u8*)(gBattleStruct->field_60)) = gUnknown_0203CF00[i];
|
2017-10-03 21:35:27 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-10-06 17:06:45 +02:00
|
|
|
enum
|
|
|
|
{
|
|
|
|
STATE_TURN_START_RECORD,
|
|
|
|
STATE_BEFORE_ACTION_CHOSEN,
|
|
|
|
STATE_WAIT_ACTION_CHOSEN,
|
|
|
|
STATE_WAIT_ACTION_CASE_CHOSEN,
|
|
|
|
STATE_WAIT_ACTION_CONFIRMED_STANDBY,
|
|
|
|
STATE_WAIT_ACTION_CONFIRMED,
|
|
|
|
STATE_SELECTION_SCRIPT,
|
|
|
|
STATE_WAIT_SET_BEFORE_ACTION,
|
|
|
|
STATE_SELECTION_SCRIPT_MAY_RUN
|
|
|
|
};
|
2017-10-04 19:25:14 +02:00
|
|
|
|
2017-10-06 19:09:37 +02:00
|
|
|
static void HandleTurnActionSelectionState(void)
|
2017-10-03 21:35:27 +02:00
|
|
|
{
|
|
|
|
s32 i;
|
|
|
|
|
2017-10-04 19:25:14 +02:00
|
|
|
gBattleCommunication[ACTIONS_CONFIRMED_COUNT] = 0;
|
2018-02-06 02:46:59 +01:00
|
|
|
for (gActiveBattler = 0; gActiveBattler < gBattlersCount; gActiveBattler++)
|
2017-10-03 21:35:27 +02:00
|
|
|
{
|
2018-02-06 02:46:59 +01:00
|
|
|
u8 position = GetBattlerPosition(gActiveBattler);
|
|
|
|
switch (gBattleCommunication[gActiveBattler])
|
2017-10-03 21:35:27 +02:00
|
|
|
{
|
2018-07-07 19:57:09 +02:00
|
|
|
case STATE_TURN_START_RECORD: // Recorded battle related action on start of every turn.
|
2018-02-08 11:17:41 +01:00
|
|
|
RecordedBattle_CopyBattlerMoves();
|
2018-02-06 02:46:59 +01:00
|
|
|
gBattleCommunication[gActiveBattler] = STATE_BEFORE_ACTION_CHOSEN;
|
2017-10-03 21:35:27 +02:00
|
|
|
break;
|
2018-07-07 19:57:09 +02:00
|
|
|
case STATE_BEFORE_ACTION_CHOSEN: // Choose an action.
|
2018-06-28 21:06:32 +02:00
|
|
|
*(gBattleStruct->monToSwitchIntoId + gActiveBattler) = PARTY_SIZE;
|
2017-10-03 21:35:27 +02:00
|
|
|
if (gBattleTypeFlags & BATTLE_TYPE_MULTI
|
2018-06-28 21:06:32 +02:00
|
|
|
|| (position & BIT_FLANK) == B_FLANK_LEFT
|
2018-02-06 23:09:39 +01:00
|
|
|
|| gBattleStruct->field_91 & gBitTable[GetBattlerAtPosition(BATTLE_PARTNER(position))]
|
2018-06-28 21:06:32 +02:00
|
|
|
|| gBattleCommunication[GetBattlerAtPosition(BATTLE_PARTNER(position))] == STATE_WAIT_ACTION_CONFIRMED)
|
2017-10-03 21:35:27 +02:00
|
|
|
{
|
2018-02-06 02:46:59 +01:00
|
|
|
if (gBattleStruct->field_91 & gBitTable[gActiveBattler])
|
2017-10-03 21:35:27 +02:00
|
|
|
{
|
2018-02-06 23:09:39 +01:00
|
|
|
gChosenActionByBattler[gActiveBattler] = B_ACTION_NOTHING_FAINTED;
|
2017-10-03 21:35:27 +02:00
|
|
|
if (!(gBattleTypeFlags & BATTLE_TYPE_MULTI))
|
2018-02-06 02:46:59 +01:00
|
|
|
gBattleCommunication[gActiveBattler] = STATE_WAIT_ACTION_CONFIRMED;
|
2017-10-03 21:35:27 +02:00
|
|
|
else
|
2018-02-06 02:46:59 +01:00
|
|
|
gBattleCommunication[gActiveBattler] = STATE_WAIT_ACTION_CONFIRMED_STANDBY;
|
2017-10-03 21:35:27 +02:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2018-02-06 02:46:59 +01:00
|
|
|
if (gBattleMons[gActiveBattler].status2 & STATUS2_MULTIPLETURNS
|
|
|
|
|| gBattleMons[gActiveBattler].status2 & STATUS2_RECHARGE)
|
2017-10-03 21:35:27 +02:00
|
|
|
{
|
2018-02-06 23:09:39 +01:00
|
|
|
gChosenActionByBattler[gActiveBattler] = B_ACTION_USE_MOVE;
|
2018-02-06 02:46:59 +01:00
|
|
|
gBattleCommunication[gActiveBattler] = STATE_WAIT_ACTION_CONFIRMED_STANDBY;
|
2017-10-03 21:35:27 +02:00
|
|
|
}
|
2018-10-16 22:19:53 +02:00
|
|
|
else if (WILD_DOUBLE_BATTLE
|
|
|
|
&& position == B_POSITION_PLAYER_RIGHT
|
2018-10-15 21:19:52 +02:00
|
|
|
&& (gBattleStruct->throwingPokeBall || gChosenActionByBattler[GetBattlerAtPosition(B_POSITION_PLAYER_LEFT)] == B_ACTION_RUN))
|
|
|
|
{
|
|
|
|
gBattleStruct->throwingPokeBall = FALSE;
|
|
|
|
gChosenActionByBattler[gActiveBattler] = B_ACTION_NOTHING_FAINTED; // Not fainted, but it cannot move, because of the throwing ball.
|
|
|
|
gBattleCommunication[gActiveBattler] = STATE_WAIT_ACTION_CONFIRMED_STANDBY;
|
|
|
|
}
|
2017-10-03 21:35:27 +02:00
|
|
|
else
|
|
|
|
{
|
2019-01-05 16:00:57 +01:00
|
|
|
BtlController_EmitChooseAction(0, gChosenActionByBattler[0], gBattleResources->bufferB[0][1] | (gBattleResources->bufferB[0][2] << 8));
|
2018-02-06 20:48:02 +01:00
|
|
|
MarkBattlerForControllerExec(gActiveBattler);
|
2018-02-06 02:46:59 +01:00
|
|
|
gBattleCommunication[gActiveBattler]++;
|
2017-10-03 21:35:27 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
break;
|
2018-07-07 19:57:09 +02:00
|
|
|
case STATE_WAIT_ACTION_CHOSEN: // Try to perform an action.
|
2018-02-06 20:48:02 +01:00
|
|
|
if (!(gBattleControllerExecFlags & ((gBitTable[gActiveBattler]) | (0xF0000000) | (gBitTable[gActiveBattler] << 4) | (gBitTable[gActiveBattler] << 8) | (gBitTable[gActiveBattler] << 0xC))))
|
2017-10-03 21:35:27 +02:00
|
|
|
{
|
2019-01-05 16:00:57 +01:00
|
|
|
RecordedBattle_SetBattlerAction(gActiveBattler, gBattleResources->bufferB[gActiveBattler][1]);
|
|
|
|
gChosenActionByBattler[gActiveBattler] = gBattleResources->bufferB[gActiveBattler][1];
|
2017-10-03 21:35:27 +02:00
|
|
|
|
2019-01-05 16:00:57 +01:00
|
|
|
switch (gBattleResources->bufferB[gActiveBattler][1])
|
2017-10-03 21:35:27 +02:00
|
|
|
{
|
2018-02-06 23:09:39 +01:00
|
|
|
case B_ACTION_USE_MOVE:
|
2017-10-03 21:35:27 +02:00
|
|
|
if (AreAllMovesUnusable())
|
|
|
|
{
|
2018-02-06 02:46:59 +01:00
|
|
|
gBattleCommunication[gActiveBattler] = STATE_SELECTION_SCRIPT;
|
|
|
|
*(gBattleStruct->selectionScriptFinished + gActiveBattler) = FALSE;
|
|
|
|
*(gBattleStruct->stateIdAfterSelScript + gActiveBattler) = STATE_WAIT_ACTION_CONFIRMED_STANDBY;
|
2019-01-05 16:00:57 +01:00
|
|
|
*(gBattleStruct->moveTarget + gActiveBattler) = gBattleResources->bufferB[gActiveBattler][3];
|
2017-10-03 21:35:27 +02:00
|
|
|
return;
|
|
|
|
}
|
2018-02-06 02:46:59 +01:00
|
|
|
else if (gDisableStructs[gActiveBattler].encoredMove != 0)
|
2017-10-03 21:35:27 +02:00
|
|
|
{
|
2018-02-06 23:09:39 +01:00
|
|
|
gChosenMoveByBattler[gActiveBattler] = gDisableStructs[gActiveBattler].encoredMove;
|
2018-02-06 02:46:59 +01:00
|
|
|
*(gBattleStruct->chosenMovePositions + gActiveBattler) = gDisableStructs[gActiveBattler].encoredMovePos;
|
|
|
|
gBattleCommunication[gActiveBattler] = STATE_WAIT_ACTION_CONFIRMED_STANDBY;
|
2017-10-03 21:35:27 +02:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
struct ChooseMoveStruct moveInfo;
|
|
|
|
|
2018-09-20 17:59:17 +02:00
|
|
|
moveInfo.mega = gBattleStruct->mega;
|
2018-02-06 02:46:59 +01:00
|
|
|
moveInfo.species = gBattleMons[gActiveBattler].species;
|
|
|
|
moveInfo.monType1 = gBattleMons[gActiveBattler].type1;
|
|
|
|
moveInfo.monType2 = gBattleMons[gActiveBattler].type2;
|
2018-11-17 12:10:24 +01:00
|
|
|
moveInfo.monType3 = gBattleMons[gActiveBattler].type3;
|
2017-10-03 21:35:27 +02:00
|
|
|
|
|
|
|
for (i = 0; i < 4; i++)
|
|
|
|
{
|
2018-02-06 02:46:59 +01:00
|
|
|
moveInfo.moves[i] = gBattleMons[gActiveBattler].moves[i];
|
|
|
|
moveInfo.currentPp[i] = gBattleMons[gActiveBattler].pp[i];
|
2017-10-08 14:54:51 +02:00
|
|
|
moveInfo.maxPp[i] = CalculatePPWithBonus(
|
2018-02-06 02:46:59 +01:00
|
|
|
gBattleMons[gActiveBattler].moves[i],
|
|
|
|
gBattleMons[gActiveBattler].ppBonuses,
|
2017-10-03 21:35:27 +02:00
|
|
|
i);
|
|
|
|
}
|
|
|
|
|
2018-02-06 20:48:02 +01:00
|
|
|
BtlController_EmitChooseMove(0, (gBattleTypeFlags & BATTLE_TYPE_DOUBLE) != 0, FALSE, &moveInfo);
|
|
|
|
MarkBattlerForControllerExec(gActiveBattler);
|
2017-10-03 21:35:27 +02:00
|
|
|
}
|
|
|
|
break;
|
2018-02-06 23:09:39 +01:00
|
|
|
case B_ACTION_USE_ITEM:
|
2017-10-03 21:35:27 +02:00
|
|
|
if (gBattleTypeFlags & (BATTLE_TYPE_LINK
|
|
|
|
| BATTLE_TYPE_FRONTIER_NO_PYRAMID
|
|
|
|
| BATTLE_TYPE_EREADER_TRAINER
|
|
|
|
| BATTLE_TYPE_x2000000))
|
|
|
|
{
|
2018-02-06 20:48:02 +01:00
|
|
|
RecordedBattle_ClearBattlerAction(gActiveBattler, 1);
|
2018-02-06 02:46:59 +01:00
|
|
|
gSelectionBattleScripts[gActiveBattler] = BattleScript_ActionSelectionItemsCantBeUsed;
|
|
|
|
gBattleCommunication[gActiveBattler] = STATE_SELECTION_SCRIPT;
|
|
|
|
*(gBattleStruct->selectionScriptFinished + gActiveBattler) = FALSE;
|
|
|
|
*(gBattleStruct->stateIdAfterSelScript + gActiveBattler) = STATE_BEFORE_ACTION_CHOSEN;
|
2017-10-03 21:35:27 +02:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2018-02-06 20:48:02 +01:00
|
|
|
BtlController_EmitChooseItem(0, gBattleStruct->field_60[gActiveBattler]);
|
|
|
|
MarkBattlerForControllerExec(gActiveBattler);
|
2017-10-03 21:35:27 +02:00
|
|
|
}
|
|
|
|
break;
|
2018-02-06 23:09:39 +01:00
|
|
|
case B_ACTION_SWITCH:
|
2018-02-06 20:48:02 +01:00
|
|
|
*(gBattleStruct->field_58 + gActiveBattler) = gBattlerPartyIndexes[gActiveBattler];
|
2018-02-06 02:46:59 +01:00
|
|
|
if (gBattleMons[gActiveBattler].status2 & (STATUS2_WRAPPED | STATUS2_ESCAPE_PREVENTION)
|
2017-10-03 21:35:27 +02:00
|
|
|
|| gBattleTypeFlags & BATTLE_TYPE_ARENA
|
2018-02-06 02:46:59 +01:00
|
|
|
|| gStatuses3[gActiveBattler] & STATUS3_ROOTED)
|
2017-10-03 21:35:27 +02:00
|
|
|
{
|
2018-07-07 19:57:09 +02:00
|
|
|
BtlController_EmitChoosePokemon(0, PARTY_CANT_SWITCH, 6, ABILITY_NONE, gBattleStruct->field_60[gActiveBattler]);
|
2017-10-03 21:35:27 +02:00
|
|
|
}
|
2019-03-31 21:38:58 +02:00
|
|
|
else if ((i = IsAbilityOnOpposingSide(gActiveBattler, ABILITY_SHADOW_TAG))
|
|
|
|
|| ((i = IsAbilityOnOpposingSide(gActiveBattler, ABILITY_ARENA_TRAP))
|
2018-03-01 00:59:52 +01:00
|
|
|
&& !IS_BATTLER_OF_TYPE(gActiveBattler, TYPE_FLYING)
|
2018-02-06 02:46:59 +01:00
|
|
|
&& gBattleMons[gActiveBattler].ability != ABILITY_LEVITATE)
|
2019-03-31 21:38:58 +02:00
|
|
|
|| ((i = IsAbilityOnFieldExcept(gActiveBattler, ABILITY_MAGNET_PULL))
|
2018-03-01 00:59:52 +01:00
|
|
|
&& IS_BATTLER_OF_TYPE(gActiveBattler, TYPE_STEEL)))
|
2017-10-03 21:35:27 +02:00
|
|
|
{
|
2018-07-07 19:57:09 +02:00
|
|
|
BtlController_EmitChoosePokemon(0, ((i - 1) << 4) | PARTY_ABILITY_PREVENTS, 6, gLastUsedAbility, gBattleStruct->field_60[gActiveBattler]);
|
2017-10-03 21:35:27 +02:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2018-02-06 23:09:39 +01:00
|
|
|
if (gActiveBattler == 2 && gChosenActionByBattler[0] == B_ACTION_SWITCH)
|
2018-07-07 19:57:09 +02:00
|
|
|
BtlController_EmitChoosePokemon(0, PARTY_CHOOSE_MON, *(gBattleStruct->monToSwitchIntoId + 0), ABILITY_NONE, gBattleStruct->field_60[gActiveBattler]);
|
2018-02-06 23:09:39 +01:00
|
|
|
else if (gActiveBattler == 3 && gChosenActionByBattler[1] == B_ACTION_SWITCH)
|
2018-07-07 19:57:09 +02:00
|
|
|
BtlController_EmitChoosePokemon(0, PARTY_CHOOSE_MON, *(gBattleStruct->monToSwitchIntoId + 1), ABILITY_NONE, gBattleStruct->field_60[gActiveBattler]);
|
2017-10-03 21:35:27 +02:00
|
|
|
else
|
2018-07-07 19:57:09 +02:00
|
|
|
BtlController_EmitChoosePokemon(0, PARTY_CHOOSE_MON, 6, ABILITY_NONE, gBattleStruct->field_60[gActiveBattler]);
|
2017-10-03 21:35:27 +02:00
|
|
|
}
|
2018-02-06 20:48:02 +01:00
|
|
|
MarkBattlerForControllerExec(gActiveBattler);
|
2017-10-03 21:35:27 +02:00
|
|
|
break;
|
2018-02-06 23:09:39 +01:00
|
|
|
case B_ACTION_SAFARI_BALL:
|
2017-10-03 21:35:27 +02:00
|
|
|
if (IsPlayerPartyAndPokemonStorageFull())
|
|
|
|
{
|
2018-02-06 02:46:59 +01:00
|
|
|
gSelectionBattleScripts[gActiveBattler] = BattleScript_PrintFullBox;
|
|
|
|
gBattleCommunication[gActiveBattler] = STATE_SELECTION_SCRIPT;
|
|
|
|
*(gBattleStruct->selectionScriptFinished + gActiveBattler) = FALSE;
|
|
|
|
*(gBattleStruct->stateIdAfterSelScript + gActiveBattler) = STATE_BEFORE_ACTION_CHOSEN;
|
2017-10-03 21:35:27 +02:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
break;
|
2018-02-06 23:09:39 +01:00
|
|
|
case B_ACTION_SAFARI_POKEBLOCK:
|
2018-02-06 20:48:02 +01:00
|
|
|
BtlController_EmitChooseItem(0, gBattleStruct->field_60[gActiveBattler]);
|
|
|
|
MarkBattlerForControllerExec(gActiveBattler);
|
2017-10-03 21:35:27 +02:00
|
|
|
break;
|
2018-02-06 23:09:39 +01:00
|
|
|
case B_ACTION_CANCEL_PARTNER:
|
2018-07-07 21:14:41 +02:00
|
|
|
gBattleCommunication[gActiveBattler] = STATE_WAIT_SET_BEFORE_ACTION;
|
|
|
|
gBattleCommunication[GetBattlerAtPosition(BATTLE_PARTNER(GetBattlerPosition(gActiveBattler)))] = STATE_BEFORE_ACTION_CHOSEN;
|
2018-02-06 20:48:02 +01:00
|
|
|
RecordedBattle_ClearBattlerAction(gActiveBattler, 1);
|
2018-02-06 23:09:39 +01:00
|
|
|
if (gBattleMons[GetBattlerAtPosition(BATTLE_PARTNER(GetBattlerPosition(gActiveBattler)))].status2 & STATUS2_MULTIPLETURNS
|
|
|
|
|| gBattleMons[GetBattlerAtPosition(BATTLE_PARTNER(GetBattlerPosition(gActiveBattler)))].status2 & STATUS2_RECHARGE)
|
2017-10-03 21:35:27 +02:00
|
|
|
{
|
2018-06-20 23:07:51 +02:00
|
|
|
BtlController_EmitEndBounceEffect(0);
|
2018-02-06 20:48:02 +01:00
|
|
|
MarkBattlerForControllerExec(gActiveBattler);
|
2017-10-03 21:35:27 +02:00
|
|
|
return;
|
|
|
|
}
|
2018-02-06 23:09:39 +01:00
|
|
|
else if (gChosenActionByBattler[GetBattlerAtPosition(BATTLE_PARTNER(GetBattlerPosition(gActiveBattler)))] == B_ACTION_SWITCH)
|
2017-10-03 21:35:27 +02:00
|
|
|
{
|
2018-02-06 23:09:39 +01:00
|
|
|
RecordedBattle_ClearBattlerAction(GetBattlerAtPosition(BATTLE_PARTNER(GetBattlerPosition(gActiveBattler))), 2);
|
2017-10-03 21:35:27 +02:00
|
|
|
}
|
2018-02-06 23:09:39 +01:00
|
|
|
else if (gChosenActionByBattler[GetBattlerAtPosition(BATTLE_PARTNER(GetBattlerPosition(gActiveBattler)))] == B_ACTION_RUN)
|
2017-10-03 21:35:27 +02:00
|
|
|
{
|
2018-02-06 23:09:39 +01:00
|
|
|
RecordedBattle_ClearBattlerAction(GetBattlerAtPosition(BATTLE_PARTNER(GetBattlerPosition(gActiveBattler))), 1);
|
2017-10-03 21:35:27 +02:00
|
|
|
}
|
2018-02-06 23:09:39 +01:00
|
|
|
else if (gChosenActionByBattler[GetBattlerAtPosition(BATTLE_PARTNER(GetBattlerPosition(gActiveBattler)))] == B_ACTION_USE_MOVE
|
2018-07-07 19:57:09 +02:00
|
|
|
&& (gProtectStructs[GetBattlerAtPosition(BATTLE_PARTNER(GetBattlerPosition(gActiveBattler)))].noValidMoves
|
2018-02-06 23:09:39 +01:00
|
|
|
|| gDisableStructs[GetBattlerAtPosition(BATTLE_PARTNER(GetBattlerPosition(gActiveBattler)))].encoredMove))
|
2017-10-03 21:35:27 +02:00
|
|
|
{
|
2018-02-06 23:09:39 +01:00
|
|
|
RecordedBattle_ClearBattlerAction(GetBattlerAtPosition(BATTLE_PARTNER(GetBattlerPosition(gActiveBattler))), 1);
|
2017-10-03 21:35:27 +02:00
|
|
|
}
|
|
|
|
else if (gBattleTypeFlags & BATTLE_TYPE_PALACE
|
2018-02-06 23:09:39 +01:00
|
|
|
&& gChosenActionByBattler[GetBattlerAtPosition(BATTLE_PARTNER(GetBattlerPosition(gActiveBattler)))] == B_ACTION_USE_MOVE)
|
2017-10-03 21:35:27 +02:00
|
|
|
{
|
|
|
|
gRngValue = gBattlePalaceMoveSelectionRngValue;
|
2018-02-06 23:09:39 +01:00
|
|
|
RecordedBattle_ClearBattlerAction(GetBattlerAtPosition(BATTLE_PARTNER(GetBattlerPosition(gActiveBattler))), 1);
|
2017-10-03 21:35:27 +02:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2018-02-06 23:09:39 +01:00
|
|
|
RecordedBattle_ClearBattlerAction(GetBattlerAtPosition(BATTLE_PARTNER(GetBattlerPosition(gActiveBattler))), 3);
|
2017-10-03 21:35:27 +02:00
|
|
|
}
|
2018-09-20 12:55:12 +02:00
|
|
|
|
2018-09-20 17:33:27 +02:00
|
|
|
gBattleStruct->mega.toEvolve &= ~(gBitTable[BATTLE_PARTNER(GetBattlerPosition(gActiveBattler))]);
|
2018-06-20 23:07:51 +02:00
|
|
|
BtlController_EmitEndBounceEffect(0);
|
2018-02-06 20:48:02 +01:00
|
|
|
MarkBattlerForControllerExec(gActiveBattler);
|
2017-10-03 21:35:27 +02:00
|
|
|
return;
|
2018-07-13 23:00:56 +02:00
|
|
|
case B_ACTION_DEBUG:
|
|
|
|
BtlController_EmitDebugMenu(0);
|
|
|
|
MarkBattlerForControllerExec(gActiveBattler);
|
|
|
|
break;
|
2017-10-03 21:35:27 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
if (gBattleTypeFlags & BATTLE_TYPE_TRAINER
|
2018-09-20 22:00:00 +02:00
|
|
|
&& gBattleTypeFlags & (BATTLE_TYPE_FRONTIER | BATTLE_TYPE_TRAINER_HILL)
|
2019-01-05 16:00:57 +01:00
|
|
|
&& gBattleResources->bufferB[gActiveBattler][1] == B_ACTION_RUN)
|
2017-10-03 21:35:27 +02:00
|
|
|
{
|
2018-02-06 02:46:59 +01:00
|
|
|
gSelectionBattleScripts[gActiveBattler] = BattleScript_AskIfWantsToForfeitMatch;
|
2018-07-07 21:14:41 +02:00
|
|
|
gBattleCommunication[gActiveBattler] = STATE_SELECTION_SCRIPT_MAY_RUN;
|
2018-02-06 02:46:59 +01:00
|
|
|
*(gBattleStruct->selectionScriptFinished + gActiveBattler) = FALSE;
|
|
|
|
*(gBattleStruct->stateIdAfterSelScript + gActiveBattler) = STATE_BEFORE_ACTION_CHOSEN;
|
2017-10-03 21:35:27 +02:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
else if (gBattleTypeFlags & BATTLE_TYPE_TRAINER
|
|
|
|
&& !(gBattleTypeFlags & (BATTLE_TYPE_LINK | BATTLE_TYPE_x2000000))
|
2019-01-05 16:00:57 +01:00
|
|
|
&& gBattleResources->bufferB[gActiveBattler][1] == B_ACTION_RUN)
|
2017-10-03 21:35:27 +02:00
|
|
|
{
|
2017-11-26 17:26:11 +01:00
|
|
|
BattleScriptExecute(BattleScript_PrintCantRunFromTrainer);
|
2018-07-07 21:14:41 +02:00
|
|
|
gBattleCommunication[gActiveBattler] = STATE_BEFORE_ACTION_CHOSEN;
|
2017-10-03 21:35:27 +02:00
|
|
|
}
|
2017-11-26 17:26:11 +01:00
|
|
|
else if (IsRunningFromBattleImpossible()
|
2019-01-05 16:00:57 +01:00
|
|
|
&& gBattleResources->bufferB[gActiveBattler][1] == B_ACTION_RUN)
|
2017-10-03 21:35:27 +02:00
|
|
|
{
|
2018-02-06 02:46:59 +01:00
|
|
|
gSelectionBattleScripts[gActiveBattler] = BattleScript_PrintCantEscapeFromBattle;
|
|
|
|
gBattleCommunication[gActiveBattler] = STATE_SELECTION_SCRIPT;
|
|
|
|
*(gBattleStruct->selectionScriptFinished + gActiveBattler) = FALSE;
|
|
|
|
*(gBattleStruct->stateIdAfterSelScript + gActiveBattler) = STATE_BEFORE_ACTION_CHOSEN;
|
2017-10-03 21:35:27 +02:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2018-02-06 02:46:59 +01:00
|
|
|
gBattleCommunication[gActiveBattler]++;
|
2017-10-03 21:35:27 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
break;
|
2017-10-04 19:25:14 +02:00
|
|
|
case STATE_WAIT_ACTION_CASE_CHOSEN:
|
2018-02-06 20:48:02 +01:00
|
|
|
if (!(gBattleControllerExecFlags & ((gBitTable[gActiveBattler]) | (0xF0000000) | (gBitTable[gActiveBattler] << 4) | (gBitTable[gActiveBattler] << 8) | (gBitTable[gActiveBattler] << 0xC))))
|
2017-10-03 21:35:27 +02:00
|
|
|
{
|
2018-02-06 23:09:39 +01:00
|
|
|
switch (gChosenActionByBattler[gActiveBattler])
|
2017-10-03 21:35:27 +02:00
|
|
|
{
|
2018-02-06 23:09:39 +01:00
|
|
|
case B_ACTION_USE_MOVE:
|
2019-01-05 16:00:57 +01:00
|
|
|
switch (gBattleResources->bufferB[gActiveBattler][1])
|
2017-10-03 21:35:27 +02:00
|
|
|
{
|
|
|
|
case 3:
|
|
|
|
case 4:
|
|
|
|
case 5:
|
|
|
|
case 6:
|
|
|
|
case 7:
|
|
|
|
case 8:
|
|
|
|
case 9:
|
2019-01-05 16:00:57 +01:00
|
|
|
gChosenActionByBattler[gActiveBattler] = gBattleResources->bufferB[gActiveBattler][1];
|
2017-10-03 21:35:27 +02:00
|
|
|
return;
|
|
|
|
case 15:
|
2018-02-06 23:09:39 +01:00
|
|
|
gChosenActionByBattler[gActiveBattler] = B_ACTION_SWITCH;
|
2017-10-03 21:35:27 +02:00
|
|
|
sub_803CDF8();
|
|
|
|
return;
|
|
|
|
default:
|
|
|
|
sub_818603C(2);
|
2019-01-05 16:00:57 +01:00
|
|
|
if ((gBattleResources->bufferB[gActiveBattler][2] | (gBattleResources->bufferB[gActiveBattler][3] << 8)) == 0xFFFF)
|
2017-10-03 21:35:27 +02:00
|
|
|
{
|
2018-07-07 21:14:41 +02:00
|
|
|
gBattleCommunication[gActiveBattler] = STATE_BEFORE_ACTION_CHOSEN;
|
2018-02-06 20:48:02 +01:00
|
|
|
RecordedBattle_ClearBattlerAction(gActiveBattler, 1);
|
2017-10-03 21:35:27 +02:00
|
|
|
}
|
|
|
|
else if (TrySetCantSelectMoveBattleScript())
|
|
|
|
{
|
2018-02-06 20:48:02 +01:00
|
|
|
RecordedBattle_ClearBattlerAction(gActiveBattler, 1);
|
2018-02-06 02:46:59 +01:00
|
|
|
gBattleCommunication[gActiveBattler] = STATE_SELECTION_SCRIPT;
|
|
|
|
*(gBattleStruct->selectionScriptFinished + gActiveBattler) = FALSE;
|
2019-01-05 16:00:57 +01:00
|
|
|
gBattleResources->bufferB[gActiveBattler][1] = 0;
|
2018-02-06 02:46:59 +01:00
|
|
|
*(gBattleStruct->stateIdAfterSelScript + gActiveBattler) = STATE_WAIT_ACTION_CHOSEN;
|
2017-10-03 21:35:27 +02:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
if (!(gBattleTypeFlags & BATTLE_TYPE_PALACE))
|
|
|
|
{
|
2019-01-05 16:00:57 +01:00
|
|
|
RecordedBattle_SetBattlerAction(gActiveBattler, gBattleResources->bufferB[gActiveBattler][2]);
|
|
|
|
RecordedBattle_SetBattlerAction(gActiveBattler, gBattleResources->bufferB[gActiveBattler][3]);
|
2017-10-03 21:35:27 +02:00
|
|
|
}
|
2019-01-05 16:00:57 +01:00
|
|
|
*(gBattleStruct->chosenMovePositions + gActiveBattler) = gBattleResources->bufferB[gActiveBattler][2] & ~(RET_MEGA_EVOLUTION);
|
2018-02-06 23:09:39 +01:00
|
|
|
gChosenMoveByBattler[gActiveBattler] = gBattleMons[gActiveBattler].moves[*(gBattleStruct->chosenMovePositions + gActiveBattler)];
|
2019-01-05 16:00:57 +01:00
|
|
|
*(gBattleStruct->moveTarget + gActiveBattler) = gBattleResources->bufferB[gActiveBattler][3];
|
|
|
|
if (gBattleResources->bufferB[gActiveBattler][2] & RET_MEGA_EVOLUTION)
|
2018-09-20 17:33:27 +02:00
|
|
|
gBattleStruct->mega.toEvolve |= gBitTable[gActiveBattler];
|
2018-02-06 02:46:59 +01:00
|
|
|
gBattleCommunication[gActiveBattler]++;
|
2017-10-03 21:35:27 +02:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
break;
|
2018-02-06 23:09:39 +01:00
|
|
|
case B_ACTION_USE_ITEM:
|
2019-01-05 16:00:57 +01:00
|
|
|
if ((gBattleResources->bufferB[gActiveBattler][1] | (gBattleResources->bufferB[gActiveBattler][2] << 8)) == 0)
|
2017-10-03 21:35:27 +02:00
|
|
|
{
|
2018-07-07 21:14:41 +02:00
|
|
|
gBattleCommunication[gActiveBattler] = STATE_BEFORE_ACTION_CHOSEN;
|
2017-10-03 21:35:27 +02:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2019-01-05 16:00:57 +01:00
|
|
|
gLastUsedItem = (gBattleResources->bufferB[gActiveBattler][1] | (gBattleResources->bufferB[gActiveBattler][2] << 8));
|
2018-10-15 21:19:52 +02:00
|
|
|
if (ItemId_GetPocket(gLastUsedItem) == POCKET_POKE_BALLS)
|
|
|
|
gBattleStruct->throwingPokeBall = TRUE;
|
2018-02-06 02:46:59 +01:00
|
|
|
gBattleCommunication[gActiveBattler]++;
|
2017-10-03 21:35:27 +02:00
|
|
|
}
|
|
|
|
break;
|
2018-02-06 23:09:39 +01:00
|
|
|
case B_ACTION_SWITCH:
|
2019-01-05 16:00:57 +01:00
|
|
|
if (gBattleResources->bufferB[gActiveBattler][1] == PARTY_SIZE)
|
2017-10-03 21:35:27 +02:00
|
|
|
{
|
2018-07-07 21:14:41 +02:00
|
|
|
gBattleCommunication[gActiveBattler] = STATE_BEFORE_ACTION_CHOSEN;
|
2018-02-06 20:48:02 +01:00
|
|
|
RecordedBattle_ClearBattlerAction(gActiveBattler, 1);
|
2017-10-03 21:35:27 +02:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
sub_803CDF8();
|
2018-02-06 02:46:59 +01:00
|
|
|
gBattleCommunication[gActiveBattler]++;
|
2017-10-03 21:35:27 +02:00
|
|
|
}
|
|
|
|
break;
|
2018-02-06 23:09:39 +01:00
|
|
|
case B_ACTION_RUN:
|
2017-10-06 17:06:45 +02:00
|
|
|
gHitMarker |= HITMARKER_RUN;
|
2018-02-06 02:46:59 +01:00
|
|
|
gBattleCommunication[gActiveBattler]++;
|
2017-10-03 21:35:27 +02:00
|
|
|
break;
|
2018-02-06 23:09:39 +01:00
|
|
|
case B_ACTION_SAFARI_WATCH_CAREFULLY:
|
2018-02-06 02:46:59 +01:00
|
|
|
gBattleCommunication[gActiveBattler]++;
|
2017-10-03 21:35:27 +02:00
|
|
|
break;
|
2018-02-06 23:09:39 +01:00
|
|
|
case B_ACTION_SAFARI_BALL:
|
2018-02-06 02:46:59 +01:00
|
|
|
gBattleCommunication[gActiveBattler]++;
|
2017-10-03 21:35:27 +02:00
|
|
|
break;
|
2018-02-06 23:09:39 +01:00
|
|
|
case B_ACTION_SAFARI_POKEBLOCK:
|
2019-01-05 16:00:57 +01:00
|
|
|
if ((gBattleResources->bufferB[gActiveBattler][1] | (gBattleResources->bufferB[gActiveBattler][2] << 8)) != 0)
|
2017-10-03 21:35:27 +02:00
|
|
|
{
|
2018-02-06 02:46:59 +01:00
|
|
|
gBattleCommunication[gActiveBattler]++;
|
2017-10-03 21:35:27 +02:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2018-02-06 02:46:59 +01:00
|
|
|
gBattleCommunication[gActiveBattler] = STATE_BEFORE_ACTION_CHOSEN;
|
2017-10-03 21:35:27 +02:00
|
|
|
}
|
|
|
|
break;
|
2018-02-06 23:09:39 +01:00
|
|
|
case B_ACTION_SAFARI_GO_NEAR:
|
2018-02-06 02:46:59 +01:00
|
|
|
gBattleCommunication[gActiveBattler]++;
|
2017-10-03 21:35:27 +02:00
|
|
|
break;
|
2018-02-06 23:09:39 +01:00
|
|
|
case B_ACTION_SAFARI_RUN:
|
2017-10-06 17:06:45 +02:00
|
|
|
gHitMarker |= HITMARKER_RUN;
|
2018-02-06 02:46:59 +01:00
|
|
|
gBattleCommunication[gActiveBattler]++;
|
2017-10-03 21:35:27 +02:00
|
|
|
break;
|
2018-06-20 23:07:51 +02:00
|
|
|
case B_ACTION_WALLY_THROW:
|
2018-02-06 02:46:59 +01:00
|
|
|
gBattleCommunication[gActiveBattler]++;
|
2017-10-03 21:35:27 +02:00
|
|
|
break;
|
2018-07-13 23:00:56 +02:00
|
|
|
case B_ACTION_DEBUG:
|
|
|
|
gBattleCommunication[gActiveBattler] = STATE_BEFORE_ACTION_CHOSEN;
|
|
|
|
break;
|
2017-10-03 21:35:27 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
break;
|
2017-10-04 19:25:14 +02:00
|
|
|
case STATE_WAIT_ACTION_CONFIRMED_STANDBY:
|
2018-02-06 20:48:02 +01:00
|
|
|
if (!(gBattleControllerExecFlags & ((gBitTable[gActiveBattler]) | (0xF0000000) | (gBitTable[gActiveBattler] << 4) | (gBitTable[gActiveBattler] << 8) | (gBitTable[gActiveBattler] << 0xC))))
|
2017-10-03 21:35:27 +02:00
|
|
|
{
|
2018-07-07 21:14:41 +02:00
|
|
|
if (AllAtActionConfirmed())
|
|
|
|
i = TRUE;
|
|
|
|
else
|
|
|
|
i = FALSE;
|
2017-10-03 21:35:27 +02:00
|
|
|
|
|
|
|
if (((gBattleTypeFlags & (BATTLE_TYPE_MULTI | BATTLE_TYPE_DOUBLE)) != BATTLE_TYPE_DOUBLE)
|
2018-07-07 21:14:41 +02:00
|
|
|
|| (position & BIT_FLANK) != B_FLANK_LEFT
|
2018-02-06 02:46:59 +01:00
|
|
|
|| (*(&gBattleStruct->field_91) & gBitTable[GetBattlerAtPosition(position ^ BIT_FLANK)]))
|
2017-10-03 21:35:27 +02:00
|
|
|
{
|
2018-02-06 20:48:02 +01:00
|
|
|
BtlController_EmitLinkStandbyMsg(0, 0, i);
|
2017-10-03 21:35:27 +02:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2018-02-06 20:48:02 +01:00
|
|
|
BtlController_EmitLinkStandbyMsg(0, 1, i);
|
2017-10-03 21:35:27 +02:00
|
|
|
}
|
2018-02-06 20:48:02 +01:00
|
|
|
MarkBattlerForControllerExec(gActiveBattler);
|
2018-02-06 02:46:59 +01:00
|
|
|
gBattleCommunication[gActiveBattler]++;
|
2017-10-03 21:35:27 +02:00
|
|
|
}
|
|
|
|
break;
|
2017-10-04 19:25:14 +02:00
|
|
|
case STATE_WAIT_ACTION_CONFIRMED:
|
2018-02-06 20:48:02 +01:00
|
|
|
if (!(gBattleControllerExecFlags & ((gBitTable[gActiveBattler]) | (0xF0000000) | (gBitTable[gActiveBattler] << 4) | (gBitTable[gActiveBattler] << 8) | (gBitTable[gActiveBattler] << 0xC))))
|
2017-10-03 21:35:27 +02:00
|
|
|
{
|
2017-10-04 19:25:14 +02:00
|
|
|
gBattleCommunication[ACTIONS_CONFIRMED_COUNT]++;
|
2017-10-03 21:35:27 +02:00
|
|
|
}
|
|
|
|
break;
|
2017-10-04 19:25:14 +02:00
|
|
|
case STATE_SELECTION_SCRIPT:
|
2018-02-06 02:46:59 +01:00
|
|
|
if (*(gBattleStruct->selectionScriptFinished + gActiveBattler))
|
2017-10-03 21:35:27 +02:00
|
|
|
{
|
2018-02-06 02:46:59 +01:00
|
|
|
gBattleCommunication[gActiveBattler] = *(gBattleStruct->stateIdAfterSelScript + gActiveBattler);
|
2017-10-03 21:35:27 +02:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2018-02-06 23:09:39 +01:00
|
|
|
gBattlerAttacker = gActiveBattler;
|
2018-02-06 02:46:59 +01:00
|
|
|
gBattlescriptCurrInstr = gSelectionBattleScripts[gActiveBattler];
|
2018-02-06 20:48:02 +01:00
|
|
|
if (!(gBattleControllerExecFlags & ((gBitTable[gActiveBattler]) | (0xF0000000) | (gBitTable[gActiveBattler] << 4) | (gBitTable[gActiveBattler] << 8) | (gBitTable[gActiveBattler] << 0xC))))
|
2017-10-03 21:35:27 +02:00
|
|
|
{
|
|
|
|
gBattleScriptingCommandsTable[gBattlescriptCurrInstr[0]]();
|
|
|
|
}
|
2018-02-06 02:46:59 +01:00
|
|
|
gSelectionBattleScripts[gActiveBattler] = gBattlescriptCurrInstr;
|
2017-10-03 21:35:27 +02:00
|
|
|
}
|
|
|
|
break;
|
2017-10-04 19:25:14 +02:00
|
|
|
case STATE_WAIT_SET_BEFORE_ACTION:
|
2018-02-06 20:48:02 +01:00
|
|
|
if (!(gBattleControllerExecFlags & ((gBitTable[gActiveBattler]) | (0xF0000000) | (gBitTable[gActiveBattler] << 4) | (gBitTable[gActiveBattler] << 8) | (gBitTable[gActiveBattler] << 0xC))))
|
2017-10-03 21:35:27 +02:00
|
|
|
{
|
2018-07-07 21:14:41 +02:00
|
|
|
gBattleCommunication[gActiveBattler] = STATE_BEFORE_ACTION_CHOSEN;
|
2017-10-03 21:35:27 +02:00
|
|
|
}
|
|
|
|
break;
|
2017-10-04 19:25:14 +02:00
|
|
|
case STATE_SELECTION_SCRIPT_MAY_RUN:
|
2018-02-06 02:46:59 +01:00
|
|
|
if (*(gBattleStruct->selectionScriptFinished + gActiveBattler))
|
2017-10-03 21:35:27 +02:00
|
|
|
{
|
2019-01-05 16:00:57 +01:00
|
|
|
if (gBattleResources->bufferB[gActiveBattler][1] == 13)
|
2017-10-03 21:35:27 +02:00
|
|
|
{
|
2017-10-06 17:06:45 +02:00
|
|
|
gHitMarker |= HITMARKER_RUN;
|
2018-02-06 23:09:39 +01:00
|
|
|
gChosenActionByBattler[gActiveBattler] = B_ACTION_RUN;
|
2018-02-06 02:46:59 +01:00
|
|
|
gBattleCommunication[gActiveBattler] = STATE_WAIT_ACTION_CONFIRMED_STANDBY;
|
2017-10-03 21:35:27 +02:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2018-02-06 20:48:02 +01:00
|
|
|
RecordedBattle_ClearBattlerAction(gActiveBattler, 1);
|
2018-02-06 02:46:59 +01:00
|
|
|
gBattleCommunication[gActiveBattler] = *(gBattleStruct->stateIdAfterSelScript + gActiveBattler);
|
2017-10-03 21:35:27 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2018-02-06 23:09:39 +01:00
|
|
|
gBattlerAttacker = gActiveBattler;
|
2018-02-06 02:46:59 +01:00
|
|
|
gBattlescriptCurrInstr = gSelectionBattleScripts[gActiveBattler];
|
2018-02-06 20:48:02 +01:00
|
|
|
if (!(gBattleControllerExecFlags & ((gBitTable[gActiveBattler]) | (0xF0000000) | (gBitTable[gActiveBattler] << 4) | (gBitTable[gActiveBattler] << 8) | (gBitTable[gActiveBattler] << 0xC))))
|
2017-10-03 21:35:27 +02:00
|
|
|
{
|
|
|
|
gBattleScriptingCommandsTable[gBattlescriptCurrInstr[0]]();
|
|
|
|
}
|
2018-02-06 02:46:59 +01:00
|
|
|
gSelectionBattleScripts[gActiveBattler] = gBattlescriptCurrInstr;
|
2017-10-03 21:35:27 +02:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-07-07 21:14:41 +02:00
|
|
|
// Check if everyone chose actions.
|
2018-02-06 02:46:59 +01:00
|
|
|
if (gBattleCommunication[ACTIONS_CONFIRMED_COUNT] == gBattlersCount)
|
2017-10-03 21:35:27 +02:00
|
|
|
{
|
|
|
|
sub_818603C(1);
|
2018-02-08 11:17:41 +01:00
|
|
|
gBattleMainFunc = SetActionsAndBattlersTurnOrder;
|
2017-10-03 21:35:27 +02:00
|
|
|
|
|
|
|
if (gBattleTypeFlags & BATTLE_TYPE_INGAME_PARTNER)
|
|
|
|
{
|
2018-02-06 02:46:59 +01:00
|
|
|
for (i = 0; i < gBattlersCount; i++)
|
2017-10-03 21:35:27 +02:00
|
|
|
{
|
2018-02-06 23:09:39 +01:00
|
|
|
if (gChosenActionByBattler[i] == B_ACTION_SWITCH)
|
2017-11-12 17:06:31 +01:00
|
|
|
sub_80571DC(i, *(gBattleStruct->monToSwitchIntoId + i));
|
2017-10-03 21:35:27 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2017-10-04 19:25:14 +02:00
|
|
|
|
2018-07-07 21:14:41 +02:00
|
|
|
static bool8 AllAtActionConfirmed(void)
|
2017-10-04 19:25:14 +02:00
|
|
|
{
|
2018-07-07 21:14:41 +02:00
|
|
|
s32 i, count;
|
2017-10-04 19:25:14 +02:00
|
|
|
|
2018-07-07 21:14:41 +02:00
|
|
|
for (count = 0, i = 0; i < gBattlersCount; i++)
|
2017-10-04 19:25:14 +02:00
|
|
|
{
|
2018-07-07 21:14:41 +02:00
|
|
|
if (gBattleCommunication[i] == STATE_WAIT_ACTION_CONFIRMED)
|
|
|
|
count++;
|
2017-10-04 19:25:14 +02:00
|
|
|
}
|
|
|
|
|
2018-07-07 21:14:41 +02:00
|
|
|
if (count + 1 == gBattlersCount)
|
2017-10-04 19:25:14 +02:00
|
|
|
return TRUE;
|
|
|
|
else
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
2017-10-06 19:09:37 +02:00
|
|
|
static void sub_803CDF8(void)
|
2017-10-04 19:25:14 +02:00
|
|
|
{
|
2019-01-05 16:00:57 +01:00
|
|
|
*(gBattleStruct->monToSwitchIntoId + gActiveBattler) = gBattleResources->bufferB[gActiveBattler][1];
|
|
|
|
RecordedBattle_SetBattlerAction(gActiveBattler, gBattleResources->bufferB[gActiveBattler][1]);
|
2017-10-04 19:25:14 +02:00
|
|
|
|
|
|
|
if (gBattleTypeFlags & BATTLE_TYPE_LINK && gBattleTypeFlags & BATTLE_TYPE_MULTI)
|
|
|
|
{
|
2018-02-06 02:46:59 +01:00
|
|
|
*(gActiveBattler * 3 + (u8*)(gBattleStruct->field_60) + 0) &= 0xF;
|
2019-01-05 16:00:57 +01:00
|
|
|
*(gActiveBattler * 3 + (u8*)(gBattleStruct->field_60) + 0) |= (gBattleResources->bufferB[gActiveBattler][2] & 0xF0);
|
|
|
|
*(gActiveBattler * 3 + (u8*)(gBattleStruct->field_60) + 1) = gBattleResources->bufferB[gActiveBattler][3];
|
2017-10-04 19:25:14 +02:00
|
|
|
|
2018-02-06 02:46:59 +01:00
|
|
|
*((gActiveBattler ^ BIT_FLANK) * 3 + (u8*)(gBattleStruct->field_60) + 0) &= (0xF0);
|
2019-01-05 16:00:57 +01:00
|
|
|
*((gActiveBattler ^ BIT_FLANK) * 3 + (u8*)(gBattleStruct->field_60) + 0) |= (gBattleResources->bufferB[gActiveBattler][2] & 0xF0) >> 4;
|
|
|
|
*((gActiveBattler ^ BIT_FLANK) * 3 + (u8*)(gBattleStruct->field_60) + 2) = gBattleResources->bufferB[gActiveBattler][3];
|
2017-10-04 19:25:14 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void SwapTurnOrder(u8 id1, u8 id2)
|
|
|
|
{
|
2018-12-05 15:31:01 +01:00
|
|
|
u32 temp;
|
2018-09-16 10:18:35 +02:00
|
|
|
|
2018-12-05 15:31:01 +01:00
|
|
|
SWAP(gActionsByTurnOrder[id1], gActionsByTurnOrder[id2], temp);
|
|
|
|
SWAP(gBattlerByTurnOrder[id1], gBattlerByTurnOrder[id2], temp);
|
2017-10-04 19:25:14 +02:00
|
|
|
}
|
|
|
|
|
2018-07-14 22:56:03 +02:00
|
|
|
u32 GetBattlerTotalSpeedStat(u8 battlerId)
|
2017-10-04 19:25:14 +02:00
|
|
|
{
|
2018-07-14 22:56:03 +02:00
|
|
|
u32 speed = gBattleMons[battlerId].speed;
|
|
|
|
u32 ability = GetBattlerAbility(battlerId);
|
|
|
|
u32 holdEffect = GetBattlerHoldEffect(battlerId, TRUE);
|
2017-10-04 19:25:14 +02:00
|
|
|
|
2018-07-14 22:56:03 +02:00
|
|
|
// weather abilities
|
2017-10-04 19:25:14 +02:00
|
|
|
if (WEATHER_HAS_EFFECT)
|
|
|
|
{
|
2018-07-14 22:56:03 +02:00
|
|
|
if (ability == ABILITY_SWIFT_SWIM && gBattleWeather & WEATHER_RAIN_ANY)
|
|
|
|
speed *= 2;
|
|
|
|
else if (ability == ABILITY_CHLOROPHYLL && gBattleWeather & WEATHER_SUN_ANY)
|
|
|
|
speed *= 2;
|
|
|
|
else if (ability == ABILITY_SAND_RUSH && gBattleWeather & WEATHER_SANDSTORM_ANY)
|
|
|
|
speed *= 2;
|
|
|
|
else if (ability == ABILITY_SLUSH_RUSH && gBattleWeather & WEATHER_HAIL_ANY)
|
|
|
|
speed *= 2;
|
2017-10-04 19:25:14 +02:00
|
|
|
}
|
|
|
|
|
2018-07-14 22:56:03 +02:00
|
|
|
// other abilities
|
|
|
|
if (ability == ABILITY_QUICK_FEET && gBattleMons[battlerId].status1 & STATUS1_ANY)
|
|
|
|
speed = (speed * 150) / 100;
|
|
|
|
else if (ability == ABILITY_SURGE_SURFER && gFieldStatuses & STATUS_FIELD_ELECTRIC_TERRAIN)
|
|
|
|
speed *= 2;
|
2017-10-04 19:25:14 +02:00
|
|
|
|
2018-07-14 22:56:03 +02:00
|
|
|
// stat stages
|
|
|
|
speed *= gStatStageRatios[gBattleMons[battlerId].statStages[STAT_SPEED]][0];
|
|
|
|
speed /= gStatStageRatios[gBattleMons[battlerId].statStages[STAT_SPEED]][1];
|
2017-10-04 19:25:14 +02:00
|
|
|
|
2018-07-14 22:56:03 +02:00
|
|
|
// player's badge boost
|
2017-10-04 19:25:14 +02:00
|
|
|
if (!(gBattleTypeFlags & (BATTLE_TYPE_LINK | BATTLE_TYPE_x2000000 | BATTLE_TYPE_FRONTIER))
|
2017-11-08 22:20:10 +01:00
|
|
|
&& FlagGet(FLAG_BADGE03_GET)
|
2018-07-14 22:56:03 +02:00
|
|
|
&& GetBattlerSide(battlerId) == B_SIDE_PLAYER)
|
2017-10-04 19:25:14 +02:00
|
|
|
{
|
2018-07-14 22:56:03 +02:00
|
|
|
speed = (speed * 110) / 100;
|
2017-10-04 19:25:14 +02:00
|
|
|
}
|
|
|
|
|
2018-07-14 22:56:03 +02:00
|
|
|
// item effects
|
2017-10-04 19:25:14 +02:00
|
|
|
if (holdEffect == HOLD_EFFECT_MACHO_BRACE)
|
2018-07-14 22:56:03 +02:00
|
|
|
speed /= 2;
|
|
|
|
else if (holdEffect == HOLD_EFFECT_IRON_BALL)
|
|
|
|
speed /= 2;
|
|
|
|
else if (holdEffect == HOLD_EFFECT_CHOICE_SCARF)
|
|
|
|
speed = (speed * 150) / 100;
|
|
|
|
else if (holdEffect == HOLD_EFFECT_QUICK_POWDER && gBattleMons[battlerId].species == SPECIES_DITTO && !(gBattleMons[battlerId].status2 & STATUS2_TRANSFORMED))
|
|
|
|
speed *= 2;
|
|
|
|
|
|
|
|
// various effects
|
|
|
|
if (gSideStatuses[GET_BATTLER_SIDE(battlerId)] & SIDE_STATUS_TAILWIND)
|
|
|
|
speed *= 2;
|
2018-12-08 16:19:50 +01:00
|
|
|
if (gBattleResources->flags->flags[battlerId] & RESOURCE_FLAG_UNBURDEN)
|
2018-07-14 22:56:03 +02:00
|
|
|
speed *= 2;
|
|
|
|
|
|
|
|
// paralysis drop
|
|
|
|
if (gBattleMons[battlerId].status1 & STATUS1_PARALYSIS && ability != ABILITY_QUICK_FEET)
|
|
|
|
speed /= 4;
|
|
|
|
|
|
|
|
return speed;
|
|
|
|
}
|
2017-10-04 19:25:14 +02:00
|
|
|
|
2019-02-16 14:54:17 +01:00
|
|
|
s8 GetChosenMovePriority(u32 battlerId)
|
2018-07-28 00:25:02 +02:00
|
|
|
{
|
|
|
|
u16 move;
|
|
|
|
|
|
|
|
if (gProtectStructs[battlerId].noValidMoves)
|
|
|
|
move = MOVE_STRUGGLE;
|
|
|
|
else
|
|
|
|
move = gBattleMons[battlerId].moves[*(gBattleStruct->chosenMovePositions + battlerId)];
|
|
|
|
|
2019-02-16 14:54:17 +01:00
|
|
|
return GetMovePriority(battlerId, move);
|
|
|
|
}
|
|
|
|
|
|
|
|
s8 GetMovePriority(u32 battlerId, u16 move)
|
|
|
|
{
|
|
|
|
s8 priority;
|
|
|
|
|
2018-12-22 15:10:24 +01:00
|
|
|
priority = gBattleMoves[move].priority;
|
2018-07-28 00:25:02 +02:00
|
|
|
if (GetBattlerAbility(battlerId) == ABILITY_GALE_WINGS
|
|
|
|
&& gBattleMoves[move].type == TYPE_FLYING
|
|
|
|
&& (B_GALE_WINGS == GEN_6 || BATTLER_MAX_HP(battlerId)))
|
|
|
|
{
|
2018-12-22 15:10:24 +01:00
|
|
|
priority++;
|
2018-07-28 00:25:02 +02:00
|
|
|
}
|
|
|
|
else if (GetBattlerAbility(battlerId) == ABILITY_PRANKSTER
|
|
|
|
&& gBattleMoves[move].split == SPLIT_STATUS)
|
|
|
|
{
|
2018-12-22 15:10:24 +01:00
|
|
|
priority++;
|
2018-07-28 00:25:02 +02:00
|
|
|
}
|
2018-11-30 21:42:30 +01:00
|
|
|
else if (GetBattlerAbility(battlerId) == ABILITY_TRIAGE)
|
|
|
|
{
|
|
|
|
switch (gBattleMoves[move].effect)
|
|
|
|
{
|
|
|
|
case EFFECT_RESTORE_HP:
|
|
|
|
case EFFECT_REST:
|
|
|
|
case EFFECT_MORNING_SUN:
|
|
|
|
case EFFECT_MOONLIGHT:
|
|
|
|
case EFFECT_SYNTHESIS:
|
|
|
|
case EFFECT_HEAL_PULSE:
|
|
|
|
case EFFECT_HEALING_WISH:
|
|
|
|
case EFFECT_SWALLOW:
|
|
|
|
case EFFECT_WISH:
|
|
|
|
case EFFECT_SOFTBOILED:
|
|
|
|
case EFFECT_ABSORB:
|
|
|
|
case EFFECT_ROOST:
|
2018-12-22 15:10:24 +01:00
|
|
|
priority += 3;
|
2018-11-30 21:42:30 +01:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
2018-07-28 00:25:02 +02:00
|
|
|
|
2018-12-22 15:10:24 +01:00
|
|
|
return priority;
|
2018-07-28 00:25:02 +02:00
|
|
|
}
|
|
|
|
|
2018-07-14 22:56:03 +02:00
|
|
|
u8 GetWhoStrikesFirst(u8 battler1, u8 battler2, bool8 ignoreChosenMoves)
|
|
|
|
{
|
|
|
|
u8 strikesFirst = 0;
|
|
|
|
u32 speedBattler1 = 0, speedBattler2 = 0;
|
2018-07-22 19:02:41 +02:00
|
|
|
u32 holdEffectBattler1 = 0, holdEffectBattler2 = 0;
|
|
|
|
bool32 quickClawBattler1 = FALSE, quickClawBattler2 = FALSE;
|
2018-07-28 00:25:02 +02:00
|
|
|
s8 priority1 = 0, priority2 = 0;
|
2017-10-04 19:25:14 +02:00
|
|
|
|
2018-07-14 22:56:03 +02:00
|
|
|
speedBattler1 = GetBattlerTotalSpeedStat(battler1);
|
2018-07-22 19:02:41 +02:00
|
|
|
holdEffectBattler1 = GetBattlerHoldEffect(battler1, TRUE);
|
|
|
|
if (holdEffectBattler1 == HOLD_EFFECT_QUICK_CLAW
|
2018-07-14 22:56:03 +02:00
|
|
|
&& gRandomTurnNumber < (0xFFFF * GetBattlerHoldEffectParam(battler1)) / 100)
|
2018-07-22 19:02:41 +02:00
|
|
|
quickClawBattler1 = TRUE;
|
2017-10-04 19:25:14 +02:00
|
|
|
|
2018-07-14 22:56:03 +02:00
|
|
|
speedBattler2 = GetBattlerTotalSpeedStat(battler2);
|
2018-07-22 19:02:41 +02:00
|
|
|
holdEffectBattler2 = GetBattlerHoldEffect(battler2, TRUE);
|
|
|
|
if (holdEffectBattler2 == HOLD_EFFECT_QUICK_CLAW
|
2018-07-14 22:56:03 +02:00
|
|
|
&& gRandomTurnNumber < (0xFFFF * GetBattlerHoldEffectParam(battler2)) / 100)
|
2018-07-22 19:02:41 +02:00
|
|
|
quickClawBattler2 = TRUE;
|
2017-10-04 19:25:14 +02:00
|
|
|
|
2018-07-28 00:25:02 +02:00
|
|
|
if (!ignoreChosenMoves)
|
2017-10-04 19:25:14 +02:00
|
|
|
{
|
2018-02-08 11:17:41 +01:00
|
|
|
if (gChosenActionByBattler[battler1] == B_ACTION_USE_MOVE)
|
2019-02-16 14:54:17 +01:00
|
|
|
priority1 = GetChosenMovePriority(battler1);
|
2018-02-08 11:17:41 +01:00
|
|
|
if (gChosenActionByBattler[battler2] == B_ACTION_USE_MOVE)
|
2019-02-16 14:54:17 +01:00
|
|
|
priority2 = GetChosenMovePriority(battler2);
|
2017-10-04 19:25:14 +02:00
|
|
|
}
|
|
|
|
|
2018-07-28 00:25:02 +02:00
|
|
|
if (priority1 == priority2)
|
2017-10-04 19:25:14 +02:00
|
|
|
{
|
2018-07-22 19:02:41 +02:00
|
|
|
// QUICK CLAW - always first
|
|
|
|
// LAGGING TAIL - always last
|
|
|
|
// STALL - always last
|
|
|
|
|
|
|
|
if (quickClawBattler1 && !quickClawBattler2)
|
|
|
|
strikesFirst = 0;
|
|
|
|
else if (quickClawBattler2 && !quickClawBattler1)
|
|
|
|
strikesFirst = 1;
|
|
|
|
else if (holdEffectBattler1 == HOLD_EFFECT_LAGGING_TAIL && holdEffectBattler2 != HOLD_EFFECT_LAGGING_TAIL)
|
|
|
|
strikesFirst = 1;
|
|
|
|
else if (holdEffectBattler2 == HOLD_EFFECT_LAGGING_TAIL && holdEffectBattler1 != HOLD_EFFECT_LAGGING_TAIL)
|
|
|
|
strikesFirst = 0;
|
|
|
|
else if (GetBattlerAbility(battler1) == ABILITY_STALL && GetBattlerAbility(battler2) != ABILITY_STALL)
|
|
|
|
strikesFirst = 1;
|
|
|
|
else if (GetBattlerAbility(battler2) == ABILITY_STALL && GetBattlerAbility(battler1) != ABILITY_STALL)
|
|
|
|
strikesFirst = 0;
|
|
|
|
else
|
2017-10-04 19:25:14 +02:00
|
|
|
{
|
2018-02-08 11:17:41 +01:00
|
|
|
if (speedBattler1 == speedBattler2 && Random() & 1)
|
2018-07-22 19:02:41 +02:00
|
|
|
{
|
2017-10-04 19:25:14 +02:00
|
|
|
strikesFirst = 2; // same speeds, same priorities
|
2018-07-22 19:02:41 +02:00
|
|
|
}
|
2018-02-08 11:17:41 +01:00
|
|
|
else if (speedBattler1 < speedBattler2)
|
2018-07-22 19:02:41 +02:00
|
|
|
{
|
|
|
|
// battler2 has more speed
|
|
|
|
if (gFieldStatuses & STATUS_FIELD_TRICK_ROOM)
|
|
|
|
strikesFirst = 0;
|
|
|
|
else
|
|
|
|
strikesFirst = 1;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
// battler1 has more speed
|
|
|
|
if (gFieldStatuses & STATUS_FIELD_TRICK_ROOM)
|
|
|
|
strikesFirst = 1;
|
|
|
|
else
|
|
|
|
strikesFirst = 0;
|
|
|
|
}
|
2017-10-04 19:25:14 +02:00
|
|
|
}
|
|
|
|
}
|
2018-07-28 00:25:02 +02:00
|
|
|
else if (priority1 < priority2)
|
2018-07-22 19:02:41 +02:00
|
|
|
{
|
|
|
|
strikesFirst = 1; // battler2's move has greater priority
|
|
|
|
}
|
2017-10-04 19:25:14 +02:00
|
|
|
else
|
|
|
|
{
|
2018-07-22 19:02:41 +02:00
|
|
|
strikesFirst = 0; // battler1's move has greater priority
|
2017-10-04 19:25:14 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
return strikesFirst;
|
|
|
|
}
|
|
|
|
|
2018-02-08 11:17:41 +01:00
|
|
|
static void SetActionsAndBattlersTurnOrder(void)
|
2017-10-04 19:25:14 +02:00
|
|
|
{
|
2018-06-28 21:06:32 +02:00
|
|
|
s32 turnOrderId = 0;
|
2017-10-04 19:25:14 +02:00
|
|
|
s32 i, j;
|
|
|
|
|
|
|
|
if (gBattleTypeFlags & BATTLE_TYPE_SAFARI)
|
|
|
|
{
|
2018-02-06 02:46:59 +01:00
|
|
|
for (gActiveBattler = 0; gActiveBattler < gBattlersCount; gActiveBattler++)
|
2017-10-04 19:25:14 +02:00
|
|
|
{
|
2018-06-28 21:06:32 +02:00
|
|
|
gActionsByTurnOrder[turnOrderId] = gChosenActionByBattler[gActiveBattler];
|
|
|
|
gBattlerByTurnOrder[turnOrderId] = gActiveBattler;
|
|
|
|
turnOrderId++;
|
2017-10-04 19:25:14 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
if (gBattleTypeFlags & BATTLE_TYPE_LINK)
|
|
|
|
{
|
2018-02-06 02:46:59 +01:00
|
|
|
for (gActiveBattler = 0; gActiveBattler < gBattlersCount; gActiveBattler++)
|
2017-10-04 19:25:14 +02:00
|
|
|
{
|
2018-02-06 23:09:39 +01:00
|
|
|
if (gChosenActionByBattler[gActiveBattler] == B_ACTION_RUN)
|
2017-10-04 19:25:14 +02:00
|
|
|
{
|
2018-06-28 21:06:32 +02:00
|
|
|
turnOrderId = 5;
|
2017-10-04 19:25:14 +02:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2018-02-06 23:09:39 +01:00
|
|
|
if (gChosenActionByBattler[0] == B_ACTION_RUN)
|
2017-10-04 19:25:14 +02:00
|
|
|
{
|
2018-02-06 02:46:59 +01:00
|
|
|
gActiveBattler = 0;
|
2018-06-28 21:06:32 +02:00
|
|
|
turnOrderId = 5;
|
2017-10-04 19:25:14 +02:00
|
|
|
}
|
2018-02-06 23:09:39 +01:00
|
|
|
if (gChosenActionByBattler[2] == B_ACTION_RUN)
|
2017-10-04 19:25:14 +02:00
|
|
|
{
|
2018-02-06 02:46:59 +01:00
|
|
|
gActiveBattler = 2;
|
2018-06-28 21:06:32 +02:00
|
|
|
turnOrderId = 5;
|
2017-10-04 19:25:14 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-06-28 21:06:32 +02:00
|
|
|
if (turnOrderId == 5) // One of battlers wants to run.
|
2017-10-04 19:25:14 +02:00
|
|
|
{
|
2018-02-06 23:09:39 +01:00
|
|
|
gActionsByTurnOrder[0] = gChosenActionByBattler[gActiveBattler];
|
2018-06-28 21:06:32 +02:00
|
|
|
gBattlerByTurnOrder[0] = gActiveBattler;
|
|
|
|
turnOrderId = 1;
|
2018-02-06 02:46:59 +01:00
|
|
|
for (i = 0; i < gBattlersCount; i++)
|
2017-10-04 19:25:14 +02:00
|
|
|
{
|
2018-02-06 02:46:59 +01:00
|
|
|
if (i != gActiveBattler)
|
2017-10-04 19:25:14 +02:00
|
|
|
{
|
2018-06-28 21:06:32 +02:00
|
|
|
gActionsByTurnOrder[turnOrderId] = gChosenActionByBattler[i];
|
|
|
|
gBattlerByTurnOrder[turnOrderId] = i;
|
|
|
|
turnOrderId++;
|
2017-10-04 19:25:14 +02:00
|
|
|
}
|
|
|
|
}
|
2018-09-16 18:55:32 +02:00
|
|
|
gBattleMainFunc = CheckMegaEvolutionBeforeTurn;
|
2018-09-20 17:33:27 +02:00
|
|
|
gBattleStruct->mega.battlerId = 0;
|
2017-10-04 19:25:14 +02:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2018-02-06 02:46:59 +01:00
|
|
|
for (gActiveBattler = 0; gActiveBattler < gBattlersCount; gActiveBattler++)
|
2017-10-04 19:25:14 +02:00
|
|
|
{
|
2018-02-06 23:09:39 +01:00
|
|
|
if (gChosenActionByBattler[gActiveBattler] == B_ACTION_USE_ITEM || gChosenActionByBattler[gActiveBattler] == B_ACTION_SWITCH)
|
2017-10-04 19:25:14 +02:00
|
|
|
{
|
2018-06-28 21:06:32 +02:00
|
|
|
gActionsByTurnOrder[turnOrderId] = gChosenActionByBattler[gActiveBattler];
|
|
|
|
gBattlerByTurnOrder[turnOrderId] = gActiveBattler;
|
|
|
|
turnOrderId++;
|
2017-10-04 19:25:14 +02:00
|
|
|
}
|
|
|
|
}
|
2018-02-06 02:46:59 +01:00
|
|
|
for (gActiveBattler = 0; gActiveBattler < gBattlersCount; gActiveBattler++)
|
2017-10-04 19:25:14 +02:00
|
|
|
{
|
2018-02-06 23:09:39 +01:00
|
|
|
if (gChosenActionByBattler[gActiveBattler] != B_ACTION_USE_ITEM && gChosenActionByBattler[gActiveBattler] != B_ACTION_SWITCH)
|
2017-10-04 19:25:14 +02:00
|
|
|
{
|
2018-06-28 21:06:32 +02:00
|
|
|
gActionsByTurnOrder[turnOrderId] = gChosenActionByBattler[gActiveBattler];
|
|
|
|
gBattlerByTurnOrder[turnOrderId] = gActiveBattler;
|
|
|
|
turnOrderId++;
|
2017-10-04 19:25:14 +02:00
|
|
|
}
|
|
|
|
}
|
2018-02-06 02:46:59 +01:00
|
|
|
for (i = 0; i < gBattlersCount - 1; i++)
|
2017-10-04 19:25:14 +02:00
|
|
|
{
|
2018-02-06 02:46:59 +01:00
|
|
|
for (j = i + 1; j < gBattlersCount; j++)
|
2017-10-04 19:25:14 +02:00
|
|
|
{
|
2018-06-28 21:06:32 +02:00
|
|
|
u8 battler1 = gBattlerByTurnOrder[i];
|
|
|
|
u8 battler2 = gBattlerByTurnOrder[j];
|
2018-02-06 23:09:39 +01:00
|
|
|
if (gActionsByTurnOrder[i] != B_ACTION_USE_ITEM
|
|
|
|
&& gActionsByTurnOrder[j] != B_ACTION_USE_ITEM
|
|
|
|
&& gActionsByTurnOrder[i] != B_ACTION_SWITCH
|
|
|
|
&& gActionsByTurnOrder[j] != B_ACTION_SWITCH)
|
2017-10-04 19:25:14 +02:00
|
|
|
{
|
2018-02-08 11:17:41 +01:00
|
|
|
if (GetWhoStrikesFirst(battler1, battler2, FALSE))
|
2017-10-04 19:25:14 +02:00
|
|
|
SwapTurnOrder(i, j);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2018-09-16 18:55:32 +02:00
|
|
|
gBattleMainFunc = CheckMegaEvolutionBeforeTurn;
|
2018-09-20 17:33:27 +02:00
|
|
|
gBattleStruct->mega.battlerId = 0;
|
2017-10-06 00:12:01 +02:00
|
|
|
}
|
|
|
|
|
2017-10-06 19:09:37 +02:00
|
|
|
static void TurnValuesCleanUp(bool8 var0)
|
2017-10-06 00:12:01 +02:00
|
|
|
{
|
|
|
|
s32 i;
|
|
|
|
|
2018-02-06 02:46:59 +01:00
|
|
|
for (gActiveBattler = 0; gActiveBattler < gBattlersCount; gActiveBattler++)
|
2017-10-06 00:12:01 +02:00
|
|
|
{
|
|
|
|
if (var0)
|
|
|
|
{
|
2018-02-06 02:46:59 +01:00
|
|
|
gProtectStructs[gActiveBattler].protected = 0;
|
2018-10-06 15:50:35 +02:00
|
|
|
gProtectStructs[gActiveBattler].spikyShielded = 0;
|
|
|
|
gProtectStructs[gActiveBattler].kingsShielded = 0;
|
|
|
|
gProtectStructs[gActiveBattler].banefulBunkered = 0;
|
2017-10-06 00:12:01 +02:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2019-01-27 13:52:02 +01:00
|
|
|
memset(&gProtectStructs[gActiveBattler], 0, sizeof(struct ProtectStruct));
|
2017-10-06 00:12:01 +02:00
|
|
|
|
2018-02-06 02:46:59 +01:00
|
|
|
if (gDisableStructs[gActiveBattler].isFirstTurn)
|
|
|
|
gDisableStructs[gActiveBattler].isFirstTurn--;
|
2017-10-06 00:12:01 +02:00
|
|
|
|
2018-10-14 18:10:54 +02:00
|
|
|
if (gDisableStructs[gActiveBattler].rechargeTimer)
|
2017-10-06 00:12:01 +02:00
|
|
|
{
|
2018-10-14 18:10:54 +02:00
|
|
|
gDisableStructs[gActiveBattler].rechargeTimer--;
|
|
|
|
if (gDisableStructs[gActiveBattler].rechargeTimer == 0)
|
2018-02-06 02:46:59 +01:00
|
|
|
gBattleMons[gActiveBattler].status2 &= ~(STATUS2_RECHARGE);
|
2017-10-06 00:12:01 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-02-06 02:46:59 +01:00
|
|
|
if (gDisableStructs[gActiveBattler].substituteHP == 0)
|
2018-06-28 21:06:32 +02:00
|
|
|
gBattleMons[gActiveBattler].status2 &= ~(STATUS2_SUBSTITUTE);
|
2017-10-06 00:12:01 +02:00
|
|
|
}
|
|
|
|
|
2019-03-31 18:17:13 +02:00
|
|
|
gSideStatuses[0] &= ~(SIDE_STATUS_QUICK_GUARD | SIDE_STATUS_WIDE_GUARD | SIDE_STATUS_CRAFTY_SHIELD | SIDE_STATUS_MAT_BLOCK);
|
|
|
|
gSideStatuses[1] &= ~(SIDE_STATUS_QUICK_GUARD | SIDE_STATUS_WIDE_GUARD | SIDE_STATUS_CRAFTY_SHIELD | SIDE_STATUS_MAT_BLOCK);
|
2017-10-06 00:12:01 +02:00
|
|
|
gSideTimers[0].followmeTimer = 0;
|
|
|
|
gSideTimers[1].followmeTimer = 0;
|
|
|
|
}
|
|
|
|
|
2017-10-06 19:09:37 +02:00
|
|
|
static void SpecialStatusesClear(void)
|
2017-10-06 00:12:01 +02:00
|
|
|
{
|
2019-01-27 13:52:02 +01:00
|
|
|
memset(&gSpecialStatuses, 0, sizeof(gSpecialStatuses));
|
2017-10-06 00:12:01 +02:00
|
|
|
}
|
|
|
|
|
2018-09-16 18:55:32 +02:00
|
|
|
static void CheckMegaEvolutionBeforeTurn(void)
|
|
|
|
{
|
|
|
|
if (!(gHitMarker & HITMARKER_RUN))
|
|
|
|
{
|
2018-09-20 17:33:27 +02:00
|
|
|
while (gBattleStruct->mega.battlerId < gBattlersCount)
|
2018-09-16 18:55:32 +02:00
|
|
|
{
|
2018-09-20 17:33:27 +02:00
|
|
|
gActiveBattler = gBattlerAttacker = gBattleStruct->mega.battlerId;
|
|
|
|
gBattleStruct->mega.battlerId++;
|
|
|
|
if (gBattleStruct->mega.toEvolve & gBitTable[gActiveBattler]
|
2018-09-16 18:55:32 +02:00
|
|
|
&& !(gProtectStructs[gActiveBattler].noValidMoves))
|
|
|
|
{
|
2018-09-20 17:33:27 +02:00
|
|
|
gBattleStruct->mega.toEvolve &= ~(gBitTable[gActiveBattler]);
|
2018-09-16 18:55:32 +02:00
|
|
|
gLastUsedItem = gBattleMons[gActiveBattler].item;
|
|
|
|
BattleScriptExecute(BattleScript_MegaEvolution);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
gBattleMainFunc = CheckFocusPunch_ClearVarsBeforeTurnStarts;
|
|
|
|
gBattleStruct->focusPunchBattlerId = 0;
|
|
|
|
}
|
|
|
|
|
2017-10-06 00:12:01 +02:00
|
|
|
static void CheckFocusPunch_ClearVarsBeforeTurnStarts(void)
|
|
|
|
{
|
2018-07-29 11:32:40 +02:00
|
|
|
u32 i;
|
|
|
|
|
2017-10-06 17:06:45 +02:00
|
|
|
if (!(gHitMarker & HITMARKER_RUN))
|
2017-10-06 00:12:01 +02:00
|
|
|
{
|
2018-02-07 22:53:40 +01:00
|
|
|
while (gBattleStruct->focusPunchBattlerId < gBattlersCount)
|
2017-10-06 00:12:01 +02:00
|
|
|
{
|
2018-02-07 22:53:40 +01:00
|
|
|
gActiveBattler = gBattlerAttacker = gBattleStruct->focusPunchBattlerId;
|
|
|
|
gBattleStruct->focusPunchBattlerId++;
|
2018-02-06 23:09:39 +01:00
|
|
|
if (gChosenMoveByBattler[gActiveBattler] == MOVE_FOCUS_PUNCH
|
2018-02-06 02:46:59 +01:00
|
|
|
&& !(gBattleMons[gActiveBattler].status1 & STATUS1_SLEEP)
|
2018-02-06 23:09:39 +01:00
|
|
|
&& !(gDisableStructs[gBattlerAttacker].truantCounter)
|
2018-07-07 19:57:09 +02:00
|
|
|
&& !(gProtectStructs[gActiveBattler].noValidMoves))
|
2017-10-06 00:12:01 +02:00
|
|
|
{
|
|
|
|
BattleScriptExecute(BattleScript_FocusPunchSetUp);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-08-11 12:16:00 +02:00
|
|
|
TryClearRageAndFuryCutter();
|
2017-10-06 00:12:01 +02:00
|
|
|
gCurrentTurnActionNumber = 0;
|
2018-07-16 21:42:03 +02:00
|
|
|
gCurrentActionFuncId = gActionsByTurnOrder[0];
|
2017-10-06 00:12:01 +02:00
|
|
|
gBattleStruct->dynamicMoveType = 0;
|
2018-07-29 11:32:40 +02:00
|
|
|
for (i = 0; i < MAX_BATTLERS_COUNT; i++)
|
|
|
|
gBattleStruct->ateBoost[i] = FALSE;
|
2017-10-06 00:12:01 +02:00
|
|
|
gBattleMainFunc = RunTurnActionsFunctions;
|
|
|
|
gBattleCommunication[3] = 0;
|
|
|
|
gBattleCommunication[4] = 0;
|
2017-12-02 23:31:58 +01:00
|
|
|
gBattleScripting.multihitMoveEffect = 0;
|
2017-10-06 00:12:01 +02:00
|
|
|
gBattleResources->battleScriptsStack->size = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void RunTurnActionsFunctions(void)
|
|
|
|
{
|
|
|
|
if (gBattleOutcome != 0)
|
|
|
|
gCurrentActionFuncId = 12;
|
|
|
|
|
2017-12-02 23:31:58 +01:00
|
|
|
*(&gBattleStruct->savedTurnActionNumber) = gCurrentTurnActionNumber;
|
2017-10-06 19:09:37 +02:00
|
|
|
sTurnActionsFuncsTable[gCurrentActionFuncId]();
|
2017-10-06 00:12:01 +02:00
|
|
|
|
2018-02-06 02:46:59 +01:00
|
|
|
if (gCurrentTurnActionNumber >= gBattlersCount) // everyone did their actions, turn finished
|
2017-10-06 00:12:01 +02:00
|
|
|
{
|
|
|
|
gHitMarker &= ~(HITMARKER_x100000);
|
2017-10-06 19:09:37 +02:00
|
|
|
gBattleMainFunc = sEndTurnFuncsTable[gBattleOutcome & 0x7F];
|
2017-10-06 00:12:01 +02:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2018-02-08 11:17:41 +01:00
|
|
|
if (gBattleStruct->savedTurnActionNumber != gCurrentTurnActionNumber) // action turn has been done, clear hitmarker bits for another battlerId
|
2017-10-06 00:12:01 +02:00
|
|
|
{
|
|
|
|
gHitMarker &= ~(HITMARKER_NO_ATTACKSTRING);
|
|
|
|
gHitMarker &= ~(HITMARKER_UNABLE_TO_USE_MOVE);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-10-06 19:09:37 +02:00
|
|
|
static void HandleEndTurn_BattleWon(void)
|
2017-10-06 00:12:01 +02:00
|
|
|
{
|
|
|
|
gCurrentActionFuncId = 0;
|
|
|
|
|
|
|
|
if (gBattleTypeFlags & (BATTLE_TYPE_LINK | BATTLE_TYPE_x2000000))
|
|
|
|
{
|
2017-11-11 01:12:18 +01:00
|
|
|
gSpecialVar_Result = gBattleOutcome;
|
2017-10-06 00:12:01 +02:00
|
|
|
gBattleTextBuff1[0] = gBattleOutcome;
|
2018-02-06 23:09:39 +01:00
|
|
|
gBattlerAttacker = GetBattlerAtPosition(B_POSITION_PLAYER_LEFT);
|
2017-10-06 00:12:01 +02:00
|
|
|
gBattlescriptCurrInstr = BattleScript_LinkBattleWonOrLost;
|
2018-01-16 22:12:38 +01:00
|
|
|
gBattleOutcome &= ~(B_OUTCOME_LINK_BATTLE_RAN);
|
2017-10-06 00:12:01 +02:00
|
|
|
}
|
|
|
|
else if (gBattleTypeFlags & BATTLE_TYPE_TRAINER
|
2018-09-20 22:00:00 +02:00
|
|
|
&& gBattleTypeFlags & (BATTLE_TYPE_FRONTIER | BATTLE_TYPE_TRAINER_HILL | BATTLE_TYPE_EREADER_TRAINER))
|
2017-10-06 00:12:01 +02:00
|
|
|
{
|
2017-11-04 16:11:13 +01:00
|
|
|
BattleStopLowHpSound();
|
2017-10-06 00:12:01 +02:00
|
|
|
gBattlescriptCurrInstr = BattleScript_FrontierTrainerBattleWon;
|
|
|
|
|
2018-06-30 18:55:34 +02:00
|
|
|
if (gTrainerBattleOpponent_A == TRAINER_FRONTIER_BRAIN)
|
2017-12-22 08:46:19 +01:00
|
|
|
PlayBGM(MUS_KACHI3);
|
2017-10-06 00:12:01 +02:00
|
|
|
else
|
2017-12-22 08:46:19 +01:00
|
|
|
PlayBGM(MUS_KACHI1);
|
2017-10-06 00:12:01 +02:00
|
|
|
}
|
|
|
|
else if (gBattleTypeFlags & BATTLE_TYPE_TRAINER && !(gBattleTypeFlags & BATTLE_TYPE_LINK))
|
|
|
|
{
|
2017-11-04 16:11:13 +01:00
|
|
|
BattleStopLowHpSound();
|
2017-10-06 00:12:01 +02:00
|
|
|
gBattlescriptCurrInstr = BattleScript_LocalTrainerBattleWon;
|
|
|
|
|
|
|
|
switch (gTrainers[gTrainerBattleOpponent_A].trainerClass)
|
|
|
|
{
|
2017-12-17 21:19:08 +01:00
|
|
|
case TRAINER_CLASS_ELITE_FOUR:
|
|
|
|
case TRAINER_CLASS_CHAMPION:
|
2017-12-22 08:46:19 +01:00
|
|
|
PlayBGM(MUS_KACHI5);
|
2017-10-06 00:12:01 +02:00
|
|
|
break;
|
2017-12-17 21:19:08 +01:00
|
|
|
case TRAINER_CLASS_TEAM_AQUA:
|
|
|
|
case TRAINER_CLASS_TEAM_MAGMA:
|
|
|
|
case TRAINER_CLASS_AQUA_ADMIN:
|
|
|
|
case TRAINER_CLASS_AQUA_LEADER:
|
|
|
|
case TRAINER_CLASS_MAGMA_ADMIN:
|
|
|
|
case TRAINER_CLASS_MAGMA_LEADER:
|
2017-12-22 08:46:19 +01:00
|
|
|
PlayBGM(MUS_KACHI4);
|
2017-10-06 00:12:01 +02:00
|
|
|
break;
|
2017-12-17 21:19:08 +01:00
|
|
|
case TRAINER_CLASS_LEADER:
|
2017-12-22 08:46:19 +01:00
|
|
|
PlayBGM(MUS_KACHI3);
|
2017-10-06 00:12:01 +02:00
|
|
|
break;
|
|
|
|
default:
|
2017-12-22 08:46:19 +01:00
|
|
|
PlayBGM(MUS_KACHI1);
|
2017-10-06 00:12:01 +02:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
gBattlescriptCurrInstr = BattleScript_PayDayMoneyAndPickUpItems;
|
|
|
|
}
|
|
|
|
|
|
|
|
gBattleMainFunc = HandleEndTurn_FinishBattle;
|
|
|
|
}
|
|
|
|
|
2017-10-06 19:09:37 +02:00
|
|
|
static void HandleEndTurn_BattleLost(void)
|
2017-10-06 00:12:01 +02:00
|
|
|
{
|
|
|
|
gCurrentActionFuncId = 0;
|
|
|
|
|
|
|
|
if (gBattleTypeFlags & (BATTLE_TYPE_LINK | BATTLE_TYPE_x2000000))
|
|
|
|
{
|
|
|
|
if (gBattleTypeFlags & BATTLE_TYPE_FRONTIER)
|
|
|
|
{
|
2018-01-16 22:12:38 +01:00
|
|
|
if (gBattleOutcome & B_OUTCOME_LINK_BATTLE_RAN)
|
2017-10-06 00:12:01 +02:00
|
|
|
{
|
2017-12-03 00:47:21 +01:00
|
|
|
gBattlescriptCurrInstr = BattleScript_PrintPlayerForfeitedLinkBattle;
|
2018-01-16 22:12:38 +01:00
|
|
|
gBattleOutcome &= ~(B_OUTCOME_LINK_BATTLE_RAN);
|
2018-06-17 12:30:09 +02:00
|
|
|
gSaveBlock2Ptr->frontier.field_CA9_b = 1;
|
2017-10-06 00:12:01 +02:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2017-11-25 18:42:31 +01:00
|
|
|
gBattlescriptCurrInstr = BattleScript_82DAA0B;
|
2018-01-16 22:12:38 +01:00
|
|
|
gBattleOutcome &= ~(B_OUTCOME_LINK_BATTLE_RAN);
|
2017-10-06 00:12:01 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
gBattleTextBuff1[0] = gBattleOutcome;
|
2018-02-06 23:09:39 +01:00
|
|
|
gBattlerAttacker = GetBattlerAtPosition(B_POSITION_PLAYER_LEFT);
|
2017-10-06 00:12:01 +02:00
|
|
|
gBattlescriptCurrInstr = BattleScript_LinkBattleWonOrLost;
|
2018-01-16 22:12:38 +01:00
|
|
|
gBattleOutcome &= ~(B_OUTCOME_LINK_BATTLE_RAN);
|
2017-10-06 00:12:01 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
gBattlescriptCurrInstr = BattleScript_LocalBattleLost;
|
|
|
|
}
|
|
|
|
|
|
|
|
gBattleMainFunc = HandleEndTurn_FinishBattle;
|
|
|
|
}
|
|
|
|
|
2017-10-06 19:09:37 +02:00
|
|
|
static void HandleEndTurn_RanFromBattle(void)
|
2017-10-06 00:12:01 +02:00
|
|
|
{
|
|
|
|
gCurrentActionFuncId = 0;
|
|
|
|
|
|
|
|
if (gBattleTypeFlags & BATTLE_TYPE_FRONTIER && gBattleTypeFlags & BATTLE_TYPE_TRAINER)
|
|
|
|
{
|
2017-12-03 00:47:21 +01:00
|
|
|
gBattlescriptCurrInstr = BattleScript_PrintPlayerForfeited;
|
2018-01-16 22:12:38 +01:00
|
|
|
gBattleOutcome = B_OUTCOME_FORFEITED;
|
2018-06-17 12:30:09 +02:00
|
|
|
gSaveBlock2Ptr->frontier.field_CA9_b = 1;
|
2017-10-06 00:12:01 +02:00
|
|
|
}
|
2018-09-20 22:00:00 +02:00
|
|
|
else if (gBattleTypeFlags & BATTLE_TYPE_TRAINER_HILL)
|
2017-10-06 00:12:01 +02:00
|
|
|
{
|
2017-12-03 00:47:21 +01:00
|
|
|
gBattlescriptCurrInstr = BattleScript_PrintPlayerForfeited;
|
2018-01-16 22:12:38 +01:00
|
|
|
gBattleOutcome = B_OUTCOME_FORFEITED;
|
2017-10-06 00:12:01 +02:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2018-02-06 23:09:39 +01:00
|
|
|
switch (gProtectStructs[gBattlerAttacker].fleeFlag)
|
2017-10-06 00:12:01 +02:00
|
|
|
{
|
|
|
|
default:
|
|
|
|
gBattlescriptCurrInstr = BattleScript_GotAwaySafely;
|
|
|
|
break;
|
|
|
|
case 1:
|
|
|
|
gBattlescriptCurrInstr = BattleScript_SmokeBallEscape;
|
|
|
|
break;
|
|
|
|
case 2:
|
|
|
|
gBattlescriptCurrInstr = BattleScript_RanAwayUsingMonAbility;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
gBattleMainFunc = HandleEndTurn_FinishBattle;
|
|
|
|
}
|
|
|
|
|
2017-10-06 19:09:37 +02:00
|
|
|
static void HandleEndTurn_MonFled(void)
|
2017-10-06 00:12:01 +02:00
|
|
|
{
|
|
|
|
gCurrentActionFuncId = 0;
|
|
|
|
|
2018-02-06 23:09:39 +01:00
|
|
|
PREPARE_MON_NICK_BUFFER(gBattleTextBuff1, gBattlerAttacker, gBattlerPartyIndexes[gBattlerAttacker]);
|
2017-10-06 00:12:01 +02:00
|
|
|
gBattlescriptCurrInstr = BattleScript_WildMonFled;
|
|
|
|
|
|
|
|
gBattleMainFunc = HandleEndTurn_FinishBattle;
|
|
|
|
}
|
|
|
|
|
2017-10-06 19:09:37 +02:00
|
|
|
static void HandleEndTurn_FinishBattle(void)
|
2017-10-06 00:12:01 +02:00
|
|
|
{
|
2018-09-16 21:08:49 +02:00
|
|
|
u32 i;
|
|
|
|
|
2017-10-06 00:12:01 +02:00
|
|
|
if (gCurrentActionFuncId == 0xB || gCurrentActionFuncId == 0xC)
|
|
|
|
{
|
|
|
|
if (!(gBattleTypeFlags & (BATTLE_TYPE_LINK
|
|
|
|
| BATTLE_TYPE_x2000000
|
|
|
|
| BATTLE_TYPE_FIRST_BATTLE
|
|
|
|
| BATTLE_TYPE_SAFARI
|
|
|
|
| BATTLE_TYPE_EREADER_TRAINER
|
|
|
|
| BATTLE_TYPE_WALLY_TUTORIAL
|
|
|
|
| BATTLE_TYPE_FRONTIER)))
|
|
|
|
{
|
2018-02-06 02:46:59 +01:00
|
|
|
for (gActiveBattler = 0; gActiveBattler < gBattlersCount; gActiveBattler++)
|
2017-10-06 00:12:01 +02:00
|
|
|
{
|
2018-02-06 02:46:59 +01:00
|
|
|
if (GetBattlerSide(gActiveBattler) == B_SIDE_PLAYER)
|
2017-10-06 00:12:01 +02:00
|
|
|
{
|
|
|
|
if (gBattleResults.playerMon1Species == SPECIES_NONE)
|
|
|
|
{
|
2018-02-06 20:48:02 +01:00
|
|
|
gBattleResults.playerMon1Species = GetMonData(&gPlayerParty[gBattlerPartyIndexes[gActiveBattler]], MON_DATA_SPECIES, NULL);
|
|
|
|
GetMonData(&gPlayerParty[gBattlerPartyIndexes[gActiveBattler]], MON_DATA_NICKNAME, gBattleResults.playerMon1Name);
|
2017-10-06 00:12:01 +02:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2018-02-06 20:48:02 +01:00
|
|
|
gBattleResults.playerMon2Species = GetMonData(&gPlayerParty[gBattlerPartyIndexes[gActiveBattler]], MON_DATA_SPECIES, NULL);
|
|
|
|
GetMonData(&gPlayerParty[gBattlerPartyIndexes[gActiveBattler]], MON_DATA_NICKNAME, gBattleResults.playerMon2Name);
|
2017-10-06 00:12:01 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2017-10-13 17:09:36 +02:00
|
|
|
PutPokemonTodayCaughtOnAir();
|
2017-10-06 00:12:01 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
if (!(gBattleTypeFlags & (BATTLE_TYPE_LINK
|
|
|
|
| BATTLE_TYPE_x2000000
|
|
|
|
| BATTLE_TYPE_TRAINER
|
|
|
|
| BATTLE_TYPE_FIRST_BATTLE
|
|
|
|
| BATTLE_TYPE_SAFARI
|
|
|
|
| BATTLE_TYPE_FRONTIER
|
|
|
|
| BATTLE_TYPE_EREADER_TRAINER
|
|
|
|
| BATTLE_TYPE_WALLY_TUTORIAL))
|
2018-06-28 21:06:32 +02:00
|
|
|
&& gBattleResults.shinyWildMon)
|
2017-10-06 00:12:01 +02:00
|
|
|
{
|
|
|
|
sub_80EE184();
|
|
|
|
}
|
|
|
|
|
|
|
|
sub_8186444();
|
|
|
|
BeginFastPaletteFade(3);
|
|
|
|
FadeOutMapMusic(5);
|
2018-09-16 21:08:49 +02:00
|
|
|
for (i = 0; i < PARTY_SIZE; i++)
|
|
|
|
UndoMegaEvolution(i);
|
2017-10-06 00:12:01 +02:00
|
|
|
gBattleMainFunc = FreeResetData_ReturnToOvOrDoEvolutions;
|
2017-10-29 16:15:23 +01:00
|
|
|
gCB2_AfterEvolution = BattleMainCB2;
|
2017-10-06 00:12:01 +02:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2018-02-06 20:48:02 +01:00
|
|
|
if (gBattleControllerExecFlags == 0)
|
2017-10-06 00:12:01 +02:00
|
|
|
gBattleScriptingCommandsTable[gBattlescriptCurrInstr[0]]();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static void FreeResetData_ReturnToOvOrDoEvolutions(void)
|
|
|
|
{
|
|
|
|
if (!gPaletteFade.active)
|
|
|
|
{
|
|
|
|
ResetSpriteData();
|
2018-01-16 22:12:38 +01:00
|
|
|
if (gLeveledUpInBattle == 0 || gBattleOutcome != B_OUTCOME_WON)
|
2017-10-06 00:12:01 +02:00
|
|
|
{
|
|
|
|
gBattleMainFunc = ReturnFromBattleToOverworld;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
gBattleMainFunc = TryEvolvePokemon;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
FreeAllWindowBuffers();
|
|
|
|
if (!(gBattleTypeFlags & BATTLE_TYPE_LINK))
|
|
|
|
{
|
|
|
|
FreeMonSpritesGfx();
|
|
|
|
FreeBattleResources();
|
|
|
|
FreeBattleSpritesData();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static void TryEvolvePokemon(void)
|
|
|
|
{
|
|
|
|
s32 i;
|
|
|
|
|
|
|
|
while (gLeveledUpInBattle != 0)
|
|
|
|
{
|
2018-02-08 11:17:41 +01:00
|
|
|
for (i = 0; i < PARTY_SIZE; i++)
|
2017-10-06 00:12:01 +02:00
|
|
|
{
|
|
|
|
if (gLeveledUpInBattle & gBitTable[i])
|
|
|
|
{
|
|
|
|
u16 species;
|
|
|
|
u8 levelUpBits = gLeveledUpInBattle;
|
|
|
|
|
|
|
|
levelUpBits &= ~(gBitTable[i]);
|
|
|
|
gLeveledUpInBattle = levelUpBits;
|
|
|
|
|
|
|
|
species = GetEvolutionTargetSpecies(&gPlayerParty[i], 0, levelUpBits);
|
|
|
|
if (species != SPECIES_NONE)
|
|
|
|
{
|
|
|
|
FreeAllWindowBuffers();
|
|
|
|
gBattleMainFunc = WaitForEvoSceneToFinish;
|
|
|
|
EvolutionScene(&gPlayerParty[i], species, TRUE, i);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
gBattleMainFunc = ReturnFromBattleToOverworld;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void WaitForEvoSceneToFinish(void)
|
|
|
|
{
|
|
|
|
if (gMain.callback2 == BattleMainCB2)
|
|
|
|
gBattleMainFunc = TryEvolvePokemon;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void ReturnFromBattleToOverworld(void)
|
|
|
|
{
|
|
|
|
if (!(gBattleTypeFlags & BATTLE_TYPE_LINK))
|
|
|
|
{
|
|
|
|
RandomlyGivePartyPokerus(gPlayerParty);
|
|
|
|
PartySpreadPokerus(gPlayerParty);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (gBattleTypeFlags & BATTLE_TYPE_LINK && gReceivedRemoteLinkPlayers != 0)
|
|
|
|
return;
|
|
|
|
|
2017-11-11 01:12:18 +01:00
|
|
|
gSpecialVar_Result = gBattleOutcome;
|
2017-10-06 00:12:01 +02:00
|
|
|
gMain.inBattle = 0;
|
|
|
|
gMain.callback1 = gPreBattleCallback1;
|
|
|
|
|
|
|
|
if (gBattleTypeFlags & BATTLE_TYPE_ROAMER)
|
|
|
|
{
|
|
|
|
UpdateRoamerHPStatus(&gEnemyParty[0]);
|
2018-02-08 00:35:13 +01:00
|
|
|
if ((gBattleOutcome & B_OUTCOME_WON) || gBattleOutcome == B_OUTCOME_CAUGHT)
|
2017-10-06 00:12:01 +02:00
|
|
|
SetRoamerInactive();
|
|
|
|
}
|
|
|
|
|
2018-05-11 07:33:32 +02:00
|
|
|
m4aSongNumStop(SE_HINSI);
|
2017-10-06 00:12:01 +02:00
|
|
|
SetMainCallback2(gMain.savedCallback);
|
|
|
|
}
|
|
|
|
|
|
|
|
void RunBattleScriptCommands_PopCallbacksStack(void)
|
|
|
|
{
|
|
|
|
if (gCurrentActionFuncId == 0xB || gCurrentActionFuncId == 0xC)
|
|
|
|
{
|
2018-02-06 23:09:39 +01:00
|
|
|
if (gBattleResources->battleCallbackStack->size != 0)
|
|
|
|
gBattleResources->battleCallbackStack->size--;
|
|
|
|
gBattleMainFunc = gBattleResources->battleCallbackStack->function[gBattleResources->battleCallbackStack->size];
|
2017-10-06 00:12:01 +02:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2018-02-06 20:48:02 +01:00
|
|
|
if (gBattleControllerExecFlags == 0)
|
2017-10-06 00:12:01 +02:00
|
|
|
gBattleScriptingCommandsTable[gBattlescriptCurrInstr[0]]();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void RunBattleScriptCommands(void)
|
|
|
|
{
|
2018-02-06 20:48:02 +01:00
|
|
|
if (gBattleControllerExecFlags == 0)
|
2017-10-06 00:12:01 +02:00
|
|
|
gBattleScriptingCommandsTable[gBattlescriptCurrInstr[0]]();
|
|
|
|
}
|
|
|
|
|
2018-07-29 11:32:40 +02:00
|
|
|
void SetTypeBeforeUsingMove(u16 move, u8 battlerAtk)
|
|
|
|
{
|
|
|
|
u32 moveType, ateType, attackerAbility;
|
|
|
|
|
|
|
|
if (move == MOVE_STRUGGLE)
|
|
|
|
return;
|
|
|
|
|
|
|
|
if (gBattleMoves[move].effect == EFFECT_WEATHER_BALL)
|
|
|
|
{
|
|
|
|
if (WEATHER_HAS_EFFECT)
|
|
|
|
{
|
|
|
|
if (gBattleWeather & WEATHER_RAIN_ANY)
|
|
|
|
*(&gBattleStruct->dynamicMoveType) = TYPE_WATER | 0x80;
|
|
|
|
else if (gBattleWeather & WEATHER_SANDSTORM_ANY)
|
|
|
|
*(&gBattleStruct->dynamicMoveType) = TYPE_ROCK | 0x80;
|
|
|
|
else if (gBattleWeather & WEATHER_SUN_ANY)
|
|
|
|
*(&gBattleStruct->dynamicMoveType) = TYPE_FIRE | 0x80;
|
|
|
|
else if (gBattleWeather & WEATHER_HAIL_ANY)
|
|
|
|
*(&gBattleStruct->dynamicMoveType) = TYPE_ICE | 0x80;
|
|
|
|
else
|
|
|
|
*(&gBattleStruct->dynamicMoveType) = TYPE_NORMAL | 0x80;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else if (gBattleMoves[move].effect == EFFECT_HIDDEN_POWER)
|
|
|
|
{
|
|
|
|
u8 typeBits = ((gBattleMons[battlerAtk].hpIV & 1) << 0)
|
|
|
|
| ((gBattleMons[battlerAtk].attackIV & 1) << 1)
|
|
|
|
| ((gBattleMons[battlerAtk].defenseIV & 1) << 2)
|
|
|
|
| ((gBattleMons[battlerAtk].speedIV & 1) << 3)
|
|
|
|
| ((gBattleMons[battlerAtk].spAttackIV & 1) << 4)
|
|
|
|
| ((gBattleMons[battlerAtk].spDefenseIV & 1) << 5);
|
|
|
|
|
|
|
|
gBattleStruct->dynamicMoveType = (15 * typeBits) / 63 + 1;
|
|
|
|
if (gBattleStruct->dynamicMoveType >= TYPE_MYSTERY)
|
|
|
|
gBattleStruct->dynamicMoveType++;
|
|
|
|
gBattleStruct->dynamicMoveType |= 0xC0;
|
|
|
|
}
|
2018-09-22 17:27:51 +02:00
|
|
|
else if (gBattleMoves[move].effect == EFFECT_TECHNO_BLAST)
|
|
|
|
{
|
|
|
|
if (GetBattlerHoldEffect(battlerAtk, TRUE) == HOLD_EFFECT_DRIVE)
|
|
|
|
gBattleStruct->dynamicMoveType = ItemId_GetSecondaryId(gBattleMons[battlerAtk].item) | 0x80;
|
|
|
|
}
|
|
|
|
else if (gBattleMoves[move].effect == EFFECT_JUDGMENT)
|
|
|
|
{
|
|
|
|
// TODO:
|
|
|
|
}
|
2018-11-03 14:35:45 +01:00
|
|
|
else if (gBattleMoves[move].effect == EFFECT_REVELATION_DANCE)
|
|
|
|
{
|
|
|
|
if (gBattleMons[battlerAtk].type1 != TYPE_MYSTERY)
|
|
|
|
gBattleStruct->dynamicMoveType = gBattleMons[battlerAtk].type1 | 0x80;
|
|
|
|
else if (gBattleMons[battlerAtk].type2 != TYPE_MYSTERY)
|
|
|
|
gBattleStruct->dynamicMoveType = gBattleMons[battlerAtk].type2 | 0x80;
|
2018-11-17 12:10:24 +01:00
|
|
|
else if (gBattleMons[battlerAtk].type3 != TYPE_MYSTERY)
|
|
|
|
gBattleStruct->dynamicMoveType = gBattleMons[battlerAtk].type3 | 0x80;
|
2018-11-03 14:35:45 +01:00
|
|
|
}
|
2018-07-29 11:32:40 +02:00
|
|
|
|
|
|
|
attackerAbility = GetBattlerAbility(battlerAtk);
|
|
|
|
GET_MOVE_TYPE(move, moveType);
|
|
|
|
if ((gFieldStatuses & STATUS_FIELD_ION_DELUGE && moveType == TYPE_NORMAL)
|
|
|
|
|| gStatuses3[battlerAtk] & STATUS3_ELECTRIFIED)
|
|
|
|
{
|
|
|
|
gBattleStruct->dynamicMoveType = 0x80 | TYPE_ELECTRIC;
|
|
|
|
}
|
|
|
|
else if (gBattleMoves[move].type == TYPE_NORMAL
|
|
|
|
&& gBattleMoves[move].effect != EFFECT_HIDDEN_POWER
|
|
|
|
&& gBattleMoves[move].effect != EFFECT_WEATHER_BALL
|
2018-09-22 17:27:51 +02:00
|
|
|
&& gBattleMoves[move].effect != EFFECT_JUDGMENT
|
2018-07-29 11:32:40 +02:00
|
|
|
&& ((attackerAbility == ABILITY_PIXILATE && (ateType = TYPE_FAIRY))
|
|
|
|
|| (attackerAbility == ABILITY_REFRIGERATE && (ateType = TYPE_ICE))
|
|
|
|
|| (attackerAbility == ABILITY_AERILATE && (ateType = TYPE_FLYING))
|
|
|
|
|| ((attackerAbility == ABILITY_GALVANIZE) && (ateType = TYPE_ELECTRIC))
|
|
|
|
)
|
|
|
|
)
|
|
|
|
{
|
|
|
|
gBattleStruct->dynamicMoveType = 0x80 | ateType;
|
|
|
|
gBattleStruct->ateBoost[battlerAtk] = 1;
|
|
|
|
}
|
|
|
|
else if (gBattleMoves[move].type != TYPE_NORMAL
|
|
|
|
&& gBattleMoves[move].effect != EFFECT_HIDDEN_POWER
|
|
|
|
&& gBattleMoves[move].effect != EFFECT_WEATHER_BALL
|
|
|
|
&& attackerAbility == ABILITY_NORMALIZE)
|
|
|
|
{
|
|
|
|
gBattleStruct->dynamicMoveType = 0x80 | TYPE_NORMAL;
|
|
|
|
gBattleStruct->ateBoost[battlerAtk] = 1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-10-06 19:09:37 +02:00
|
|
|
static void HandleAction_UseMove(void)
|
2017-10-06 00:12:01 +02:00
|
|
|
{
|
|
|
|
u8 side;
|
|
|
|
u8 var = 4;
|
2018-11-30 21:21:43 +01:00
|
|
|
u32 moveType;
|
2017-10-06 00:12:01 +02:00
|
|
|
|
2018-06-28 21:06:32 +02:00
|
|
|
gBattlerAttacker = gBattlerByTurnOrder[gCurrentTurnActionNumber];
|
2017-10-06 00:12:01 +02:00
|
|
|
|
2018-02-06 23:09:39 +01:00
|
|
|
if (*(&gBattleStruct->field_91) & gBitTable[gBattlerAttacker])
|
2017-10-06 00:12:01 +02:00
|
|
|
{
|
2018-02-06 23:09:39 +01:00
|
|
|
gCurrentActionFuncId = B_ACTION_FINISHED;
|
2017-10-06 00:12:01 +02:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2018-07-14 22:56:03 +02:00
|
|
|
gIsCriticalHit = FALSE;
|
2017-10-06 00:12:01 +02:00
|
|
|
gBattleStruct->atkCancellerTracker = 0;
|
2018-01-16 22:12:38 +01:00
|
|
|
gMoveResultFlags = 0;
|
2017-10-06 00:12:01 +02:00
|
|
|
gMultiHitCounter = 0;
|
|
|
|
gBattleCommunication[6] = 0;
|
2018-09-29 16:41:25 +02:00
|
|
|
gBattleScripting.savedMoveEffect = 0;
|
2018-02-08 11:17:41 +01:00
|
|
|
gCurrMovePos = gChosenMovePos = *(gBattleStruct->chosenMovePositions + gBattlerAttacker);
|
2017-10-06 00:12:01 +02:00
|
|
|
|
|
|
|
// choose move
|
2018-07-07 19:57:09 +02:00
|
|
|
if (gProtectStructs[gBattlerAttacker].noValidMoves)
|
2017-10-06 00:12:01 +02:00
|
|
|
{
|
2018-07-07 19:57:09 +02:00
|
|
|
gProtectStructs[gBattlerAttacker].noValidMoves = 0;
|
2017-11-26 18:07:00 +01:00
|
|
|
gCurrentMove = gChosenMove = MOVE_STRUGGLE;
|
2017-10-06 00:12:01 +02:00
|
|
|
gHitMarker |= HITMARKER_NO_PPDEDUCT;
|
2018-02-06 23:09:39 +01:00
|
|
|
*(gBattleStruct->moveTarget + gBattlerAttacker) = GetMoveTarget(MOVE_STRUGGLE, 0);
|
2017-10-06 00:12:01 +02:00
|
|
|
}
|
2018-02-06 23:09:39 +01:00
|
|
|
else if (gBattleMons[gBattlerAttacker].status2 & STATUS2_MULTIPLETURNS || gBattleMons[gBattlerAttacker].status2 & STATUS2_RECHARGE)
|
2017-10-06 00:12:01 +02:00
|
|
|
{
|
2018-02-06 23:09:39 +01:00
|
|
|
gCurrentMove = gChosenMove = gLockedMoves[gBattlerAttacker];
|
2017-10-06 00:12:01 +02:00
|
|
|
}
|
|
|
|
// encore forces you to use the same move
|
2018-02-06 23:09:39 +01:00
|
|
|
else if (gDisableStructs[gBattlerAttacker].encoredMove != MOVE_NONE
|
|
|
|
&& gDisableStructs[gBattlerAttacker].encoredMove == gBattleMons[gBattlerAttacker].moves[gDisableStructs[gBattlerAttacker].encoredMovePos])
|
2017-10-06 00:12:01 +02:00
|
|
|
{
|
2018-02-06 23:09:39 +01:00
|
|
|
gCurrentMove = gChosenMove = gDisableStructs[gBattlerAttacker].encoredMove;
|
2018-02-08 11:17:41 +01:00
|
|
|
gCurrMovePos = gChosenMovePos = gDisableStructs[gBattlerAttacker].encoredMovePos;
|
2018-02-06 23:09:39 +01:00
|
|
|
*(gBattleStruct->moveTarget + gBattlerAttacker) = GetMoveTarget(gCurrentMove, 0);
|
2017-10-06 00:12:01 +02:00
|
|
|
}
|
|
|
|
// check if the encored move wasn't overwritten
|
2018-02-06 23:09:39 +01:00
|
|
|
else if (gDisableStructs[gBattlerAttacker].encoredMove != MOVE_NONE
|
|
|
|
&& gDisableStructs[gBattlerAttacker].encoredMove != gBattleMons[gBattlerAttacker].moves[gDisableStructs[gBattlerAttacker].encoredMovePos])
|
2017-10-06 00:12:01 +02:00
|
|
|
{
|
2018-02-08 11:17:41 +01:00
|
|
|
gCurrMovePos = gChosenMovePos = gDisableStructs[gBattlerAttacker].encoredMovePos;
|
2018-02-06 23:09:39 +01:00
|
|
|
gCurrentMove = gChosenMove = gBattleMons[gBattlerAttacker].moves[gCurrMovePos];
|
|
|
|
gDisableStructs[gBattlerAttacker].encoredMove = MOVE_NONE;
|
|
|
|
gDisableStructs[gBattlerAttacker].encoredMovePos = 0;
|
2018-10-14 18:10:54 +02:00
|
|
|
gDisableStructs[gBattlerAttacker].encoreTimer = 0;
|
2018-02-06 23:09:39 +01:00
|
|
|
*(gBattleStruct->moveTarget + gBattlerAttacker) = GetMoveTarget(gCurrentMove, 0);
|
2017-10-06 00:12:01 +02:00
|
|
|
}
|
2018-02-06 23:09:39 +01:00
|
|
|
else if (gBattleMons[gBattlerAttacker].moves[gCurrMovePos] != gChosenMoveByBattler[gBattlerAttacker])
|
2017-10-06 00:12:01 +02:00
|
|
|
{
|
2018-02-06 23:09:39 +01:00
|
|
|
gCurrentMove = gChosenMove = gBattleMons[gBattlerAttacker].moves[gCurrMovePos];
|
|
|
|
*(gBattleStruct->moveTarget + gBattlerAttacker) = GetMoveTarget(gCurrentMove, 0);
|
2017-10-06 00:12:01 +02:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2018-02-06 23:09:39 +01:00
|
|
|
gCurrentMove = gChosenMove = gBattleMons[gBattlerAttacker].moves[gCurrMovePos];
|
2017-10-06 00:12:01 +02:00
|
|
|
}
|
|
|
|
|
2018-02-06 23:09:39 +01:00
|
|
|
if (gBattleMons[gBattlerAttacker].hp != 0)
|
2017-10-06 00:12:01 +02:00
|
|
|
{
|
2018-02-06 23:09:39 +01:00
|
|
|
if (GetBattlerSide(gBattlerAttacker) == B_SIDE_PLAYER)
|
2017-10-06 00:12:01 +02:00
|
|
|
gBattleResults.lastUsedMovePlayer = gCurrentMove;
|
|
|
|
else
|
|
|
|
gBattleResults.lastUsedMoveOpponent = gCurrentMove;
|
|
|
|
}
|
|
|
|
|
2018-11-30 21:21:43 +01:00
|
|
|
// Set dynamic move type.
|
|
|
|
SetTypeBeforeUsingMove(gChosenMove, gBattlerAttacker);
|
|
|
|
GET_MOVE_TYPE(gChosenMove, moveType);
|
|
|
|
|
2017-10-06 00:12:01 +02:00
|
|
|
// choose target
|
2018-02-06 23:09:39 +01:00
|
|
|
side = GetBattlerSide(gBattlerAttacker) ^ BIT_SIDE;
|
2017-10-06 00:12:01 +02:00
|
|
|
if (gSideTimers[side].followmeTimer != 0
|
|
|
|
&& gBattleMoves[gCurrentMove].target == MOVE_TARGET_SELECTED
|
2018-02-06 23:09:39 +01:00
|
|
|
&& GetBattlerSide(gBattlerAttacker) != GetBattlerSide(gSideTimers[side].followmeTarget)
|
2017-10-06 00:12:01 +02:00
|
|
|
&& gBattleMons[gSideTimers[side].followmeTarget].hp != 0)
|
|
|
|
{
|
2018-02-06 23:09:39 +01:00
|
|
|
gBattlerTarget = gSideTimers[side].followmeTarget;
|
2017-10-06 00:12:01 +02:00
|
|
|
}
|
|
|
|
else if ((gBattleTypeFlags & BATTLE_TYPE_DOUBLE)
|
|
|
|
&& gSideTimers[side].followmeTimer == 0
|
2018-07-22 19:34:13 +02:00
|
|
|
&& (gBattleMoves[gCurrentMove].power != 0 || gBattleMoves[gCurrentMove].target != MOVE_TARGET_USER)
|
2018-11-30 21:21:43 +01:00
|
|
|
&& ((gBattleMons[*(gBattleStruct->moveTarget + gBattlerAttacker)].ability != ABILITY_LIGHTNING_ROD && moveType == TYPE_ELECTRIC)
|
|
|
|
|| (gBattleMons[*(gBattleStruct->moveTarget + gBattlerAttacker)].ability != ABILITY_STORM_DRAIN && moveType == TYPE_WATER)
|
2018-07-22 19:34:13 +02:00
|
|
|
)
|
|
|
|
)
|
2017-10-06 00:12:01 +02:00
|
|
|
{
|
2018-02-06 23:09:39 +01:00
|
|
|
side = GetBattlerSide(gBattlerAttacker);
|
2018-02-06 02:46:59 +01:00
|
|
|
for (gActiveBattler = 0; gActiveBattler < gBattlersCount; gActiveBattler++)
|
2017-10-06 00:12:01 +02:00
|
|
|
{
|
2018-02-06 02:46:59 +01:00
|
|
|
if (side != GetBattlerSide(gActiveBattler)
|
2018-02-06 23:09:39 +01:00
|
|
|
&& *(gBattleStruct->moveTarget + gBattlerAttacker) != gActiveBattler
|
2018-11-30 21:21:43 +01:00
|
|
|
&& ((gBattleMons[gActiveBattler].ability == ABILITY_LIGHTNING_ROD && moveType == TYPE_ELECTRIC)
|
|
|
|
|| (gBattleMons[gActiveBattler].ability == ABILITY_STORM_DRAIN && moveType == TYPE_WATER)
|
2018-07-22 19:34:13 +02:00
|
|
|
)
|
2018-02-06 20:48:02 +01:00
|
|
|
&& GetBattlerTurnOrderNum(gActiveBattler) < var)
|
2017-10-06 00:12:01 +02:00
|
|
|
{
|
2018-02-06 20:48:02 +01:00
|
|
|
var = GetBattlerTurnOrderNum(gActiveBattler);
|
2017-10-06 00:12:01 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
if (var == 4)
|
|
|
|
{
|
2017-11-26 18:07:00 +01:00
|
|
|
if (gBattleMoves[gChosenMove].target & MOVE_TARGET_RANDOM)
|
2017-10-06 00:12:01 +02:00
|
|
|
{
|
2018-02-06 23:09:39 +01:00
|
|
|
if (GetBattlerSide(gBattlerAttacker) == B_SIDE_PLAYER)
|
2017-10-06 00:12:01 +02:00
|
|
|
{
|
|
|
|
if (Random() & 1)
|
2018-02-06 23:09:39 +01:00
|
|
|
gBattlerTarget = GetBattlerAtPosition(B_POSITION_OPPONENT_LEFT);
|
2017-10-06 00:12:01 +02:00
|
|
|
else
|
2018-02-06 23:09:39 +01:00
|
|
|
gBattlerTarget = GetBattlerAtPosition(B_POSITION_OPPONENT_RIGHT);
|
2017-10-06 00:12:01 +02:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
if (Random() & 1)
|
2018-02-06 23:09:39 +01:00
|
|
|
gBattlerTarget = GetBattlerAtPosition(B_POSITION_PLAYER_LEFT);
|
2017-10-06 00:12:01 +02:00
|
|
|
else
|
2018-02-06 23:09:39 +01:00
|
|
|
gBattlerTarget = GetBattlerAtPosition(B_POSITION_PLAYER_RIGHT);
|
2017-10-06 00:12:01 +02:00
|
|
|
}
|
|
|
|
}
|
2018-12-08 00:09:39 +01:00
|
|
|
else if (gBattleMoves[gChosenMove].target & MOVE_TARGET_FOES_AND_ALLY)
|
|
|
|
{
|
|
|
|
for (gBattlerTarget = 0; gBattlerTarget < gBattlersCount; gBattlerTarget++)
|
|
|
|
{
|
|
|
|
if (gBattlerTarget == gBattlerAttacker)
|
|
|
|
continue;
|
|
|
|
if (!(gAbsentBattlerFlags & gBitTable[gBattlerTarget]))
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
2017-10-06 00:12:01 +02:00
|
|
|
else
|
|
|
|
{
|
2018-02-06 23:09:39 +01:00
|
|
|
gBattlerTarget = *(gBattleStruct->moveTarget + gBattlerAttacker);
|
2017-10-06 00:12:01 +02:00
|
|
|
}
|
|
|
|
|
2018-02-06 23:09:39 +01:00
|
|
|
if (gAbsentBattlerFlags & gBitTable[gBattlerTarget])
|
2017-10-06 00:12:01 +02:00
|
|
|
{
|
2018-02-06 23:09:39 +01:00
|
|
|
if (GetBattlerSide(gBattlerAttacker) != GetBattlerSide(gBattlerTarget))
|
2017-10-06 00:12:01 +02:00
|
|
|
{
|
2018-02-06 23:09:39 +01:00
|
|
|
gBattlerTarget = GetBattlerAtPosition(GetBattlerPosition(gBattlerTarget) ^ BIT_FLANK);
|
2017-10-06 00:12:01 +02:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2018-02-06 23:09:39 +01:00
|
|
|
gBattlerTarget = GetBattlerAtPosition(GetBattlerPosition(gBattlerAttacker) ^ BIT_SIDE);
|
|
|
|
if (gAbsentBattlerFlags & gBitTable[gBattlerTarget])
|
|
|
|
gBattlerTarget = GetBattlerAtPosition(GetBattlerPosition(gBattlerTarget) ^ BIT_FLANK);
|
2017-10-06 00:12:01 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2018-06-28 21:06:32 +02:00
|
|
|
gActiveBattler = gBattlerByTurnOrder[var];
|
2018-02-06 02:46:59 +01:00
|
|
|
RecordAbilityBattle(gActiveBattler, gBattleMons[gActiveBattler].ability);
|
2018-07-22 19:34:13 +02:00
|
|
|
if (gBattleMons[gActiveBattler].ability == ABILITY_LIGHTNING_ROD)
|
|
|
|
gSpecialStatuses[gActiveBattler].lightningRodRedirected = 1;
|
|
|
|
else if (gBattleMons[gActiveBattler].ability == ABILITY_STORM_DRAIN)
|
|
|
|
gSpecialStatuses[gActiveBattler].stormDrainRedirected = 1;
|
2018-02-06 23:09:39 +01:00
|
|
|
gBattlerTarget = gActiveBattler;
|
2017-10-06 00:12:01 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
else if (gBattleTypeFlags & BATTLE_TYPE_DOUBLE
|
2017-11-26 18:07:00 +01:00
|
|
|
&& gBattleMoves[gChosenMove].target & MOVE_TARGET_RANDOM)
|
2017-10-06 00:12:01 +02:00
|
|
|
{
|
2018-02-06 23:09:39 +01:00
|
|
|
if (GetBattlerSide(gBattlerAttacker) == B_SIDE_PLAYER)
|
2017-10-06 00:12:01 +02:00
|
|
|
{
|
|
|
|
if (Random() & 1)
|
2018-02-06 23:09:39 +01:00
|
|
|
gBattlerTarget = GetBattlerAtPosition(B_POSITION_OPPONENT_LEFT);
|
2017-10-06 00:12:01 +02:00
|
|
|
else
|
2018-02-06 23:09:39 +01:00
|
|
|
gBattlerTarget = GetBattlerAtPosition(B_POSITION_OPPONENT_RIGHT);
|
2017-10-06 00:12:01 +02:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
if (Random() & 1)
|
2018-02-06 23:09:39 +01:00
|
|
|
gBattlerTarget = GetBattlerAtPosition(B_POSITION_PLAYER_LEFT);
|
2017-10-06 00:12:01 +02:00
|
|
|
else
|
2018-02-06 23:09:39 +01:00
|
|
|
gBattlerTarget = GetBattlerAtPosition(B_POSITION_PLAYER_RIGHT);
|
2017-10-06 00:12:01 +02:00
|
|
|
}
|
|
|
|
|
2018-02-06 23:09:39 +01:00
|
|
|
if (gAbsentBattlerFlags & gBitTable[gBattlerTarget]
|
|
|
|
&& GetBattlerSide(gBattlerAttacker) != GetBattlerSide(gBattlerTarget))
|
2017-10-06 00:12:01 +02:00
|
|
|
{
|
2018-02-06 23:09:39 +01:00
|
|
|
gBattlerTarget = GetBattlerAtPosition(GetBattlerPosition(gBattlerTarget) ^ BIT_FLANK);
|
2017-10-06 00:12:01 +02:00
|
|
|
}
|
|
|
|
}
|
2018-11-25 12:59:22 +01:00
|
|
|
else if (gBattleMoves[gChosenMove].target == MOVE_TARGET_ALLY)
|
|
|
|
{
|
|
|
|
if (IsBattlerAlive(BATTLE_PARTNER(gBattlerAttacker)))
|
|
|
|
gBattlerTarget = BATTLE_PARTNER(gBattlerAttacker);
|
|
|
|
else
|
|
|
|
gBattlerTarget = gBattlerAttacker;
|
|
|
|
}
|
2018-12-08 00:09:39 +01:00
|
|
|
else if (gBattleTypeFlags & BATTLE_TYPE_DOUBLE
|
|
|
|
&& gBattleMoves[gChosenMove].target == MOVE_TARGET_FOES_AND_ALLY)
|
|
|
|
{
|
|
|
|
for (gBattlerTarget = 0; gBattlerTarget < gBattlersCount; gBattlerTarget++)
|
|
|
|
{
|
|
|
|
if (gBattlerTarget == gBattlerAttacker)
|
|
|
|
continue;
|
|
|
|
if (!(gAbsentBattlerFlags & gBitTable[gBattlerTarget]))
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
2017-10-06 00:12:01 +02:00
|
|
|
else
|
|
|
|
{
|
2018-02-06 23:09:39 +01:00
|
|
|
gBattlerTarget = *(gBattleStruct->moveTarget + gBattlerAttacker);
|
|
|
|
if (gAbsentBattlerFlags & gBitTable[gBattlerTarget])
|
2017-10-06 00:12:01 +02:00
|
|
|
{
|
2018-02-06 23:09:39 +01:00
|
|
|
if (GetBattlerSide(gBattlerAttacker) != GetBattlerSide(gBattlerTarget))
|
2017-10-06 00:12:01 +02:00
|
|
|
{
|
2018-02-06 23:09:39 +01:00
|
|
|
gBattlerTarget = GetBattlerAtPosition(GetBattlerPosition(gBattlerTarget) ^ BIT_FLANK);
|
2017-10-06 00:12:01 +02:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2018-02-06 23:09:39 +01:00
|
|
|
gBattlerTarget = GetBattlerAtPosition(GetBattlerPosition(gBattlerAttacker) ^ BIT_SIDE);
|
|
|
|
if (gAbsentBattlerFlags & gBitTable[gBattlerTarget])
|
|
|
|
gBattlerTarget = GetBattlerAtPosition(GetBattlerPosition(gBattlerTarget) ^ BIT_FLANK);
|
2017-10-06 00:12:01 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-07-29 11:32:40 +02:00
|
|
|
// Choose battlescript.
|
2017-10-06 00:12:01 +02:00
|
|
|
if (gBattleTypeFlags & BATTLE_TYPE_PALACE
|
2019-01-29 22:22:02 +01:00
|
|
|
&& gProtectStructs[gBattlerAttacker].palaceUnableToUseMove)
|
2017-10-06 00:12:01 +02:00
|
|
|
{
|
2018-02-06 23:09:39 +01:00
|
|
|
if (gBattleMons[gBattlerAttacker].hp == 0)
|
2017-10-06 00:12:01 +02:00
|
|
|
{
|
2018-02-06 23:09:39 +01:00
|
|
|
gCurrentActionFuncId = B_ACTION_FINISHED;
|
2017-10-06 00:12:01 +02:00
|
|
|
return;
|
|
|
|
}
|
2018-02-06 23:09:39 +01:00
|
|
|
else if (gPalaceSelectionBattleScripts[gBattlerAttacker] != NULL)
|
2017-10-06 00:12:01 +02:00
|
|
|
{
|
|
|
|
gBattleCommunication[MULTISTRING_CHOOSER] = 4;
|
2018-02-06 23:09:39 +01:00
|
|
|
gBattlescriptCurrInstr = gPalaceSelectionBattleScripts[gBattlerAttacker];
|
|
|
|
gPalaceSelectionBattleScripts[gBattlerAttacker] = NULL;
|
2017-10-06 00:12:01 +02:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
gBattleCommunication[MULTISTRING_CHOOSER] = 4;
|
|
|
|
gBattlescriptCurrInstr = BattleScript_MoveUsedLoafingAround;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
gBattlescriptCurrInstr = gBattleScriptsForMoveEffects[gBattleMoves[gCurrentMove].effect];
|
|
|
|
}
|
|
|
|
|
|
|
|
if (gBattleTypeFlags & BATTLE_TYPE_ARENA)
|
2018-11-11 18:33:16 +01:00
|
|
|
BattleArena_AddMindPoints(gBattlerAttacker);
|
2017-10-06 00:12:01 +02:00
|
|
|
|
2018-02-06 23:09:39 +01:00
|
|
|
gCurrentActionFuncId = B_ACTION_EXEC_SCRIPT;
|
2017-10-06 00:12:01 +02:00
|
|
|
}
|
|
|
|
|
2017-10-06 19:09:37 +02:00
|
|
|
static void HandleAction_Switch(void)
|
2017-10-06 00:12:01 +02:00
|
|
|
{
|
2018-06-28 21:06:32 +02:00
|
|
|
gBattlerAttacker = gBattlerByTurnOrder[gCurrentTurnActionNumber];
|
2017-10-06 00:12:01 +02:00
|
|
|
gBattle_BG0_X = 0;
|
|
|
|
gBattle_BG0_Y = 0;
|
2018-02-06 23:09:39 +01:00
|
|
|
gActionSelectionCursor[gBattlerAttacker] = 0;
|
|
|
|
gMoveSelectionCursor[gBattlerAttacker] = 0;
|
2017-10-06 00:12:01 +02:00
|
|
|
|
2018-02-06 23:09:39 +01:00
|
|
|
PREPARE_MON_NICK_BUFFER(gBattleTextBuff1, gBattlerAttacker, *(gBattleStruct->field_58 + gBattlerAttacker))
|
2017-10-06 00:12:01 +02:00
|
|
|
|
2018-02-06 23:09:39 +01:00
|
|
|
gBattleScripting.battler = gBattlerAttacker;
|
2017-10-06 00:12:01 +02:00
|
|
|
gBattlescriptCurrInstr = BattleScript_ActionSwitch;
|
2018-02-06 23:09:39 +01:00
|
|
|
gCurrentActionFuncId = B_ACTION_EXEC_SCRIPT;
|
2017-10-06 00:12:01 +02:00
|
|
|
|
|
|
|
if (gBattleResults.playerSwitchesCounter < 255)
|
|
|
|
gBattleResults.playerSwitchesCounter++;
|
|
|
|
}
|
|
|
|
|
2017-10-06 19:09:37 +02:00
|
|
|
static void HandleAction_UseItem(void)
|
2017-10-06 00:12:01 +02:00
|
|
|
{
|
2018-06-28 21:06:32 +02:00
|
|
|
gBattlerAttacker = gBattlerTarget = gBattlerByTurnOrder[gCurrentTurnActionNumber];
|
2017-10-06 00:12:01 +02:00
|
|
|
gBattle_BG0_X = 0;
|
|
|
|
gBattle_BG0_Y = 0;
|
2018-02-06 23:09:39 +01:00
|
|
|
ClearFuryCutterDestinyBondGrudge(gBattlerAttacker);
|
2019-01-05 16:00:57 +01:00
|
|
|
gLastUsedItem = gBattleResources->bufferB[gBattlerAttacker][1] | (gBattleResources->bufferB[gBattlerAttacker][2] << 8);
|
2017-10-06 00:12:01 +02:00
|
|
|
|
|
|
|
if (gLastUsedItem <= ITEM_PREMIER_BALL) // is ball
|
|
|
|
{
|
|
|
|
gBattlescriptCurrInstr = gBattlescriptsForBallThrow[gLastUsedItem];
|
|
|
|
}
|
|
|
|
else if (gLastUsedItem == ITEM_POKE_DOLL || gLastUsedItem == ITEM_FLUFFY_TAIL)
|
|
|
|
{
|
|
|
|
gBattlescriptCurrInstr = gBattlescriptsForRunningByItem[0];
|
|
|
|
}
|
2018-02-06 23:09:39 +01:00
|
|
|
else if (GetBattlerSide(gBattlerAttacker) == B_SIDE_PLAYER)
|
2017-10-06 00:12:01 +02:00
|
|
|
{
|
2017-12-02 23:31:58 +01:00
|
|
|
gBattlescriptCurrInstr = gBattlescriptsForUsingItem[0];
|
2017-10-06 00:12:01 +02:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2018-02-06 23:09:39 +01:00
|
|
|
gBattleScripting.battler = gBattlerAttacker;
|
2017-10-06 00:12:01 +02:00
|
|
|
|
2018-02-06 23:09:39 +01:00
|
|
|
switch (*(gBattleStruct->AI_itemType + (gBattlerAttacker >> 1)))
|
2017-10-06 00:12:01 +02:00
|
|
|
{
|
2017-10-11 12:49:42 +02:00
|
|
|
case AI_ITEM_FULL_RESTORE:
|
|
|
|
case AI_ITEM_HEAL_HP:
|
2017-10-06 00:12:01 +02:00
|
|
|
break;
|
2017-10-11 12:49:42 +02:00
|
|
|
case AI_ITEM_CURE_CONDITION:
|
2017-10-06 00:12:01 +02:00
|
|
|
gBattleCommunication[MULTISTRING_CHOOSER] = 0;
|
2018-02-06 23:09:39 +01:00
|
|
|
if (*(gBattleStruct->AI_itemFlags + gBattlerAttacker / 2) & 1)
|
2017-10-06 00:12:01 +02:00
|
|
|
{
|
2018-02-06 23:09:39 +01:00
|
|
|
if (*(gBattleStruct->AI_itemFlags + gBattlerAttacker / 2) & 0x3E)
|
2017-10-06 00:12:01 +02:00
|
|
|
gBattleCommunication[MULTISTRING_CHOOSER] = 5;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2018-02-06 23:09:39 +01:00
|
|
|
while (!(*(gBattleStruct->AI_itemFlags + gBattlerAttacker / 2) & 1))
|
2017-10-06 00:12:01 +02:00
|
|
|
{
|
2018-02-06 23:09:39 +01:00
|
|
|
*(gBattleStruct->AI_itemFlags + gBattlerAttacker / 2) >>= 1;
|
2017-10-06 00:12:01 +02:00
|
|
|
gBattleCommunication[MULTISTRING_CHOOSER]++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
break;
|
2017-10-11 12:49:42 +02:00
|
|
|
case AI_ITEM_X_STAT:
|
2017-10-06 00:12:01 +02:00
|
|
|
gBattleCommunication[MULTISTRING_CHOOSER] = 4;
|
2018-02-06 23:09:39 +01:00
|
|
|
if (*(gBattleStruct->AI_itemFlags + (gBattlerAttacker >> 1)) & 0x80)
|
2017-10-06 00:12:01 +02:00
|
|
|
{
|
|
|
|
gBattleCommunication[MULTISTRING_CHOOSER] = 5;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
PREPARE_STAT_BUFFER(gBattleTextBuff1, STAT_ATK)
|
|
|
|
PREPARE_STRING_BUFFER(gBattleTextBuff2, 0xD2)
|
|
|
|
|
2018-02-06 23:09:39 +01:00
|
|
|
while (!((*(gBattleStruct->AI_itemFlags + (gBattlerAttacker >> 1))) & 1))
|
2017-10-06 00:12:01 +02:00
|
|
|
{
|
2018-02-06 23:09:39 +01:00
|
|
|
*(gBattleStruct->AI_itemFlags + gBattlerAttacker / 2) >>= 1;
|
2017-10-06 00:12:01 +02:00
|
|
|
gBattleTextBuff1[2]++;
|
|
|
|
}
|
|
|
|
|
|
|
|
gBattleScripting.animArg1 = gBattleTextBuff1[2] + 14;
|
|
|
|
gBattleScripting.animArg2 = 0;
|
|
|
|
}
|
|
|
|
break;
|
2017-10-11 12:49:42 +02:00
|
|
|
case AI_ITEM_GUARD_SPECS:
|
2017-10-06 00:12:01 +02:00
|
|
|
if (gBattleTypeFlags & BATTLE_TYPE_DOUBLE)
|
|
|
|
gBattleCommunication[MULTISTRING_CHOOSER] = 2;
|
|
|
|
else
|
|
|
|
gBattleCommunication[MULTISTRING_CHOOSER] = 0;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
2018-02-06 23:09:39 +01:00
|
|
|
gBattlescriptCurrInstr = gBattlescriptsForUsingItem[*(gBattleStruct->AI_itemType + gBattlerAttacker / 2)];
|
2017-10-06 00:12:01 +02:00
|
|
|
}
|
2018-02-06 23:09:39 +01:00
|
|
|
gCurrentActionFuncId = B_ACTION_EXEC_SCRIPT;
|
2017-10-06 00:12:01 +02:00
|
|
|
}
|
|
|
|
|
2018-02-06 23:09:39 +01:00
|
|
|
bool8 TryRunFromBattle(u8 battler)
|
2017-10-06 00:12:01 +02:00
|
|
|
{
|
|
|
|
bool8 effect = FALSE;
|
|
|
|
u8 holdEffect;
|
|
|
|
u8 pyramidMultiplier;
|
|
|
|
u8 speedVar;
|
|
|
|
|
2018-02-06 23:09:39 +01:00
|
|
|
if (gBattleMons[battler].item == ITEM_ENIGMA_BERRY)
|
|
|
|
holdEffect = gEnigmaBerries[battler].holdEffect;
|
2017-10-06 00:12:01 +02:00
|
|
|
else
|
2018-02-06 23:09:39 +01:00
|
|
|
holdEffect = ItemId_GetHoldEffect(gBattleMons[battler].item);
|
2017-10-06 00:12:01 +02:00
|
|
|
|
2018-02-08 12:13:29 +01:00
|
|
|
gPotentialItemEffectBattler = battler;
|
2017-10-06 00:12:01 +02:00
|
|
|
|
|
|
|
if (holdEffect == HOLD_EFFECT_CAN_ALWAYS_RUN)
|
|
|
|
{
|
2018-12-09 04:32:58 +01:00
|
|
|
gLastUsedItem = gBattleMons[battler].item;
|
2018-02-06 23:09:39 +01:00
|
|
|
gProtectStructs[battler].fleeFlag = 1;
|
2017-10-06 00:12:01 +02:00
|
|
|
effect++;
|
|
|
|
}
|
2018-02-06 23:09:39 +01:00
|
|
|
else if (gBattleMons[battler].ability == ABILITY_RUN_AWAY)
|
2017-10-06 00:12:01 +02:00
|
|
|
{
|
|
|
|
if (InBattlePyramid())
|
|
|
|
{
|
|
|
|
gBattleStruct->runTries++;
|
2018-11-18 17:52:22 +01:00
|
|
|
pyramidMultiplier = GetPyramidRunMultiplier();
|
2018-02-06 23:09:39 +01:00
|
|
|
speedVar = (gBattleMons[battler].speed * pyramidMultiplier) / (gBattleMons[BATTLE_OPPOSITE(battler)].speed) + (gBattleStruct->runTries * 30);
|
2017-10-06 00:12:01 +02:00
|
|
|
if (speedVar > (Random() & 0xFF))
|
|
|
|
{
|
|
|
|
gLastUsedAbility = ABILITY_RUN_AWAY;
|
2018-02-06 23:09:39 +01:00
|
|
|
gProtectStructs[battler].fleeFlag = 2;
|
2017-10-06 00:12:01 +02:00
|
|
|
effect++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
gLastUsedAbility = ABILITY_RUN_AWAY;
|
2018-02-06 23:09:39 +01:00
|
|
|
gProtectStructs[battler].fleeFlag = 2;
|
2017-10-06 00:12:01 +02:00
|
|
|
effect++;
|
|
|
|
}
|
|
|
|
}
|
2018-09-20 22:00:00 +02:00
|
|
|
else if (gBattleTypeFlags & (BATTLE_TYPE_FRONTIER | BATTLE_TYPE_TRAINER_HILL) && gBattleTypeFlags & BATTLE_TYPE_TRAINER)
|
2017-10-06 00:12:01 +02:00
|
|
|
{
|
|
|
|
effect++;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2018-10-15 21:19:52 +02:00
|
|
|
u8 runningFromBattler = BATTLE_OPPOSITE(battler);
|
|
|
|
if (!IsBattlerAlive(runningFromBattler))
|
|
|
|
runningFromBattler |= BIT_FLANK;
|
|
|
|
|
|
|
|
if (InBattlePyramid())
|
2017-10-06 00:12:01 +02:00
|
|
|
{
|
2018-11-18 20:49:52 +01:00
|
|
|
pyramidMultiplier = GetPyramidRunMultiplier();
|
2018-10-15 21:19:52 +02:00
|
|
|
speedVar = (gBattleMons[battler].speed * pyramidMultiplier) / (gBattleMons[runningFromBattler].speed) + (gBattleStruct->runTries * 30);
|
|
|
|
if (speedVar > (Random() & 0xFF))
|
2017-10-06 00:12:01 +02:00
|
|
|
effect++;
|
2018-10-15 21:19:52 +02:00
|
|
|
}
|
|
|
|
else if (gBattleMons[battler].speed < gBattleMons[runningFromBattler].speed)
|
|
|
|
{
|
|
|
|
speedVar = (gBattleMons[battler].speed * 128) / (gBattleMons[runningFromBattler].speed) + (gBattleStruct->runTries * 30);
|
|
|
|
if (speedVar > (Random() & 0xFF))
|
|
|
|
effect++;
|
|
|
|
}
|
|
|
|
else // same speed or faster
|
|
|
|
{
|
|
|
|
effect++;
|
2017-10-06 00:12:01 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
gBattleStruct->runTries++;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (effect)
|
|
|
|
{
|
2018-02-06 02:46:59 +01:00
|
|
|
gCurrentTurnActionNumber = gBattlersCount;
|
2018-01-16 22:12:38 +01:00
|
|
|
gBattleOutcome = B_OUTCOME_RAN;
|
2017-10-06 00:12:01 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
return effect;
|
2017-10-04 19:25:14 +02:00
|
|
|
}
|
2017-10-06 17:06:45 +02:00
|
|
|
|
2017-10-06 19:09:37 +02:00
|
|
|
static void HandleAction_Run(void)
|
2017-10-06 17:06:45 +02:00
|
|
|
{
|
2018-06-28 21:06:32 +02:00
|
|
|
gBattlerAttacker = gBattlerByTurnOrder[gCurrentTurnActionNumber];
|
2017-10-06 17:06:45 +02:00
|
|
|
|
|
|
|
if (gBattleTypeFlags & (BATTLE_TYPE_LINK | BATTLE_TYPE_x2000000))
|
|
|
|
{
|
2018-02-06 02:46:59 +01:00
|
|
|
gCurrentTurnActionNumber = gBattlersCount;
|
2017-10-06 17:06:45 +02:00
|
|
|
|
2018-02-06 02:46:59 +01:00
|
|
|
for (gActiveBattler = 0; gActiveBattler < gBattlersCount; gActiveBattler++)
|
2017-10-06 17:06:45 +02:00
|
|
|
{
|
2018-02-06 02:46:59 +01:00
|
|
|
if (GetBattlerSide(gActiveBattler) == B_SIDE_PLAYER)
|
2017-10-06 17:06:45 +02:00
|
|
|
{
|
2018-02-06 23:09:39 +01:00
|
|
|
if (gChosenActionByBattler[gActiveBattler] == B_ACTION_RUN)
|
2018-01-16 22:12:38 +01:00
|
|
|
gBattleOutcome |= B_OUTCOME_LOST;
|
2017-10-06 17:06:45 +02:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2018-02-06 23:09:39 +01:00
|
|
|
if (gChosenActionByBattler[gActiveBattler] == B_ACTION_RUN)
|
2018-01-16 22:12:38 +01:00
|
|
|
gBattleOutcome |= B_OUTCOME_WON;
|
2017-10-06 17:06:45 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-01-16 22:12:38 +01:00
|
|
|
gBattleOutcome |= B_OUTCOME_LINK_BATTLE_RAN;
|
2018-06-17 12:30:09 +02:00
|
|
|
gSaveBlock2Ptr->frontier.field_CA9_b = 1;
|
2017-10-06 17:06:45 +02:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2018-02-06 23:09:39 +01:00
|
|
|
if (GetBattlerSide(gBattlerAttacker) == B_SIDE_PLAYER)
|
2017-10-06 17:06:45 +02:00
|
|
|
{
|
2018-02-06 23:09:39 +01:00
|
|
|
if (!TryRunFromBattle(gBattlerAttacker)) // failed to run away
|
2017-10-06 17:06:45 +02:00
|
|
|
{
|
2018-02-06 23:09:39 +01:00
|
|
|
ClearFuryCutterDestinyBondGrudge(gBattlerAttacker);
|
2017-10-06 17:06:45 +02:00
|
|
|
gBattleCommunication[MULTISTRING_CHOOSER] = 3;
|
|
|
|
gBattlescriptCurrInstr = BattleScript_PrintFailedToRunString;
|
2018-02-06 23:09:39 +01:00
|
|
|
gCurrentActionFuncId = B_ACTION_EXEC_SCRIPT;
|
2017-10-06 17:06:45 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2018-02-06 23:09:39 +01:00
|
|
|
if (gBattleMons[gBattlerAttacker].status2 & (STATUS2_WRAPPED | STATUS2_ESCAPE_PREVENTION))
|
2017-10-06 17:06:45 +02:00
|
|
|
{
|
|
|
|
gBattleCommunication[MULTISTRING_CHOOSER] = 4;
|
|
|
|
gBattlescriptCurrInstr = BattleScript_PrintFailedToRunString;
|
2018-02-06 23:09:39 +01:00
|
|
|
gCurrentActionFuncId = B_ACTION_EXEC_SCRIPT;
|
2017-10-06 17:06:45 +02:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2018-02-06 02:46:59 +01:00
|
|
|
gCurrentTurnActionNumber = gBattlersCount;
|
2018-02-08 00:35:13 +01:00
|
|
|
gBattleOutcome = B_OUTCOME_MON_FLED;
|
2017-10-06 17:06:45 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-10-06 19:09:37 +02:00
|
|
|
static void HandleAction_WatchesCarefully(void)
|
2017-10-06 17:06:45 +02:00
|
|
|
{
|
2018-06-28 21:06:32 +02:00
|
|
|
gBattlerAttacker = gBattlerByTurnOrder[gCurrentTurnActionNumber];
|
2017-10-06 17:06:45 +02:00
|
|
|
gBattle_BG0_X = 0;
|
|
|
|
gBattle_BG0_Y = 0;
|
|
|
|
gBattlescriptCurrInstr = gBattlescriptsForSafariActions[0];
|
2018-02-06 23:09:39 +01:00
|
|
|
gCurrentActionFuncId = B_ACTION_EXEC_SCRIPT;
|
2017-10-06 17:06:45 +02:00
|
|
|
}
|
|
|
|
|
2017-10-06 19:09:37 +02:00
|
|
|
static void HandleAction_SafariZoneBallThrow(void)
|
2017-10-06 17:06:45 +02:00
|
|
|
{
|
2018-06-28 21:06:32 +02:00
|
|
|
gBattlerAttacker = gBattlerByTurnOrder[gCurrentTurnActionNumber];
|
2017-10-06 17:06:45 +02:00
|
|
|
gBattle_BG0_X = 0;
|
|
|
|
gBattle_BG0_Y = 0;
|
|
|
|
gNumSafariBalls--;
|
|
|
|
gLastUsedItem = ITEM_SAFARI_BALL;
|
|
|
|
gBattlescriptCurrInstr = gBattlescriptsForBallThrow[ITEM_SAFARI_BALL];
|
2018-02-06 23:09:39 +01:00
|
|
|
gCurrentActionFuncId = B_ACTION_EXEC_SCRIPT;
|
2017-10-06 17:06:45 +02:00
|
|
|
}
|
|
|
|
|
2017-10-06 19:09:37 +02:00
|
|
|
static void HandleAction_ThrowPokeblock(void)
|
2017-10-06 17:06:45 +02:00
|
|
|
{
|
2018-06-28 21:06:32 +02:00
|
|
|
gBattlerAttacker = gBattlerByTurnOrder[gCurrentTurnActionNumber];
|
2017-10-06 17:06:45 +02:00
|
|
|
gBattle_BG0_X = 0;
|
|
|
|
gBattle_BG0_Y = 0;
|
2019-01-05 16:00:57 +01:00
|
|
|
gBattleCommunication[MULTISTRING_CHOOSER] = gBattleResources->bufferB[gBattlerAttacker][1] - 1;
|
|
|
|
gLastUsedItem = gBattleResources->bufferB[gBattlerAttacker][2];
|
2017-10-06 17:06:45 +02:00
|
|
|
|
2018-06-28 21:06:32 +02:00
|
|
|
if (gBattleResults.pokeblockThrows < 0xFF)
|
|
|
|
gBattleResults.pokeblockThrows++;
|
2018-07-01 11:15:42 +02:00
|
|
|
if (gBattleStruct->safariPkblThrowCounter < 3)
|
|
|
|
gBattleStruct->safariPkblThrowCounter++;
|
|
|
|
if (gBattleStruct->safariEscapeFactor > 1)
|
2017-10-06 17:06:45 +02:00
|
|
|
{
|
2018-07-01 11:15:42 +02:00
|
|
|
if (gBattleStruct->safariEscapeFactor < sPkblToEscapeFactor[gBattleStruct->safariPkblThrowCounter][gBattleCommunication[MULTISTRING_CHOOSER]])
|
|
|
|
gBattleStruct->safariEscapeFactor = 1;
|
2017-10-06 17:06:45 +02:00
|
|
|
else
|
2018-07-01 11:15:42 +02:00
|
|
|
gBattleStruct->safariEscapeFactor -= sPkblToEscapeFactor[gBattleStruct->safariPkblThrowCounter][gBattleCommunication[MULTISTRING_CHOOSER]];
|
2017-10-06 17:06:45 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
gBattlescriptCurrInstr = gBattlescriptsForSafariActions[2];
|
2018-02-06 23:09:39 +01:00
|
|
|
gCurrentActionFuncId = B_ACTION_EXEC_SCRIPT;
|
2017-10-06 17:06:45 +02:00
|
|
|
}
|
|
|
|
|
2017-10-06 19:09:37 +02:00
|
|
|
static void HandleAction_GoNear(void)
|
2017-10-06 17:06:45 +02:00
|
|
|
{
|
2018-06-28 21:06:32 +02:00
|
|
|
gBattlerAttacker = gBattlerByTurnOrder[gCurrentTurnActionNumber];
|
2017-10-06 17:06:45 +02:00
|
|
|
gBattle_BG0_X = 0;
|
|
|
|
gBattle_BG0_Y = 0;
|
|
|
|
|
2018-07-01 11:15:42 +02:00
|
|
|
gBattleStruct->safariCatchFactor += sGoNearCounterToCatchFactor[gBattleStruct->safariGoNearCounter];
|
|
|
|
if (gBattleStruct->safariCatchFactor > 20)
|
|
|
|
gBattleStruct->safariCatchFactor = 20;
|
2017-10-06 17:06:45 +02:00
|
|
|
|
2018-07-01 11:15:42 +02:00
|
|
|
gBattleStruct->safariEscapeFactor += sGoNearCounterToEscapeFactor[gBattleStruct->safariGoNearCounter];
|
|
|
|
if (gBattleStruct->safariEscapeFactor > 20)
|
|
|
|
gBattleStruct->safariEscapeFactor = 20;
|
2017-10-06 17:06:45 +02:00
|
|
|
|
2018-07-01 11:15:42 +02:00
|
|
|
if (gBattleStruct->safariGoNearCounter < 3)
|
2017-10-06 17:06:45 +02:00
|
|
|
{
|
2018-07-01 11:15:42 +02:00
|
|
|
gBattleStruct->safariGoNearCounter++;
|
2017-10-06 17:06:45 +02:00
|
|
|
gBattleCommunication[MULTISTRING_CHOOSER] = 0;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2018-07-01 11:15:42 +02:00
|
|
|
gBattleCommunication[MULTISTRING_CHOOSER] = 1; // Can't get closer.
|
2017-10-06 17:06:45 +02:00
|
|
|
}
|
|
|
|
gBattlescriptCurrInstr = gBattlescriptsForSafariActions[1];
|
2018-02-06 23:09:39 +01:00
|
|
|
gCurrentActionFuncId = B_ACTION_EXEC_SCRIPT;
|
2017-10-06 17:06:45 +02:00
|
|
|
}
|
|
|
|
|
2018-11-22 02:10:50 +01:00
|
|
|
static void HandleAction_SafariZoneRun(void)
|
2017-10-06 17:06:45 +02:00
|
|
|
{
|
2018-06-28 21:06:32 +02:00
|
|
|
gBattlerAttacker = gBattlerByTurnOrder[gCurrentTurnActionNumber];
|
2017-10-06 17:06:45 +02:00
|
|
|
PlaySE(SE_NIGERU);
|
2018-02-06 02:46:59 +01:00
|
|
|
gCurrentTurnActionNumber = gBattlersCount;
|
2018-01-16 22:12:38 +01:00
|
|
|
gBattleOutcome = B_OUTCOME_RAN;
|
2017-10-06 17:06:45 +02:00
|
|
|
}
|
|
|
|
|
2018-06-20 23:07:51 +02:00
|
|
|
static void HandleAction_WallyBallThrow(void)
|
2017-10-06 17:06:45 +02:00
|
|
|
{
|
2018-06-28 21:06:32 +02:00
|
|
|
gBattlerAttacker = gBattlerByTurnOrder[gCurrentTurnActionNumber];
|
2017-10-06 17:06:45 +02:00
|
|
|
gBattle_BG0_X = 0;
|
|
|
|
gBattle_BG0_Y = 0;
|
|
|
|
|
2018-02-06 23:09:39 +01:00
|
|
|
PREPARE_MON_NICK_BUFFER(gBattleTextBuff1, gBattlerAttacker, gBattlerPartyIndexes[gBattlerAttacker])
|
2017-10-06 17:06:45 +02:00
|
|
|
|
|
|
|
gBattlescriptCurrInstr = gBattlescriptsForSafariActions[3];
|
2018-02-06 23:09:39 +01:00
|
|
|
gCurrentActionFuncId = B_ACTION_EXEC_SCRIPT;
|
|
|
|
gActionsByTurnOrder[1] = B_ACTION_FINISHED;
|
2017-10-06 17:06:45 +02:00
|
|
|
}
|
|
|
|
|
2019-02-02 11:32:00 +01:00
|
|
|
static void HandleAction_TryFinish(void)
|
2017-10-06 17:06:45 +02:00
|
|
|
{
|
2017-12-02 14:08:55 +01:00
|
|
|
if (!HandleFaintedMonActions())
|
2017-10-06 17:06:45 +02:00
|
|
|
{
|
2017-12-02 14:08:55 +01:00
|
|
|
gBattleStruct->faintedActionsState = 0;
|
2018-02-06 23:09:39 +01:00
|
|
|
gCurrentActionFuncId = B_ACTION_FINISHED;
|
2017-10-06 17:06:45 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-10-06 19:09:37 +02:00
|
|
|
static void HandleAction_NothingIsFainted(void)
|
2017-10-06 17:06:45 +02:00
|
|
|
{
|
|
|
|
gCurrentTurnActionNumber++;
|
|
|
|
gCurrentActionFuncId = gActionsByTurnOrder[gCurrentTurnActionNumber];
|
|
|
|
gHitMarker &= ~(HITMARKER_DESTINYBOND | HITMARKER_IGNORE_SUBSTITUTE | HITMARKER_ATTACKSTRING_PRINTED
|
|
|
|
| HITMARKER_NO_PPDEDUCT | HITMARKER_IGNORE_SAFEGUARD | HITMARKER_IGNORE_ON_AIR
|
|
|
|
| HITMARKER_IGNORE_UNDERGROUND | HITMARKER_IGNORE_UNDERWATER | HITMARKER_x100000
|
|
|
|
| HITMARKER_OBEYS | HITMARKER_x10 | HITMARKER_SYNCHRONISE_EFFECT
|
2019-01-13 20:58:42 +01:00
|
|
|
| HITMARKER_CHARGING | HITMARKER_x4000000);
|
2017-10-06 17:06:45 +02:00
|
|
|
}
|
|
|
|
|
2017-10-06 19:09:37 +02:00
|
|
|
static void HandleAction_ActionFinished(void)
|
2017-10-06 17:06:45 +02:00
|
|
|
{
|
2018-06-28 21:06:32 +02:00
|
|
|
*(gBattleStruct->monToSwitchIntoId + gBattlerByTurnOrder[gCurrentTurnActionNumber]) = 6;
|
2017-10-06 17:06:45 +02:00
|
|
|
gCurrentTurnActionNumber++;
|
|
|
|
gCurrentActionFuncId = gActionsByTurnOrder[gCurrentTurnActionNumber];
|
|
|
|
SpecialStatusesClear();
|
|
|
|
gHitMarker &= ~(HITMARKER_DESTINYBOND | HITMARKER_IGNORE_SUBSTITUTE | HITMARKER_ATTACKSTRING_PRINTED
|
|
|
|
| HITMARKER_NO_PPDEDUCT | HITMARKER_IGNORE_SAFEGUARD | HITMARKER_IGNORE_ON_AIR
|
|
|
|
| HITMARKER_IGNORE_UNDERGROUND | HITMARKER_IGNORE_UNDERWATER | HITMARKER_x100000
|
|
|
|
| HITMARKER_OBEYS | HITMARKER_x10 | HITMARKER_SYNCHRONISE_EFFECT
|
2019-01-13 20:58:42 +01:00
|
|
|
| HITMARKER_CHARGING | HITMARKER_x4000000);
|
2017-10-06 17:06:45 +02:00
|
|
|
|
|
|
|
gCurrentMove = 0;
|
|
|
|
gBattleMoveDamage = 0;
|
2018-01-16 22:12:38 +01:00
|
|
|
gMoveResultFlags = 0;
|
2017-10-06 17:06:45 +02:00
|
|
|
gBattleScripting.animTurn = 0;
|
|
|
|
gBattleScripting.animTargetsHit = 0;
|
2018-02-06 23:09:39 +01:00
|
|
|
gLastLandedMoves[gBattlerAttacker] = 0;
|
|
|
|
gLastHitByType[gBattlerAttacker] = 0;
|
2017-10-06 17:06:45 +02:00
|
|
|
gBattleStruct->dynamicMoveType = 0;
|
|
|
|
gBattleScripting.atk49_state = 0;
|
|
|
|
gBattleCommunication[3] = 0;
|
|
|
|
gBattleCommunication[4] = 0;
|
2017-12-02 23:31:58 +01:00
|
|
|
gBattleScripting.multihitMoveEffect = 0;
|
2017-10-06 17:06:45 +02:00
|
|
|
gBattleResources->battleScriptsStack->size = 0;
|
|
|
|
}
|
2019-04-02 00:31:10 +02:00
|
|
|
|
|
|
|
|