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"
2019-09-09 03:07:54 +02:00
# include "malloc.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-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"
2019-10-18 01:22:03 +02:00
# include "constants/party_menu.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
2019-07-19 02:46:00 +02:00
# if !defined(NONMATCHING) && MODERN
# define static
# endif
2017-10-01 01:12:42 +02:00
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 ) ;
2020-07-14 11:13:03 +02:00
static void SpriteCb_BlinkVisible ( struct Sprite * sprite ) ;
2017-10-06 19:09:37 +02:00
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 ) ;
static void BattleIntroGetMonsData ( void ) ;
static void BattleIntroPrepareBackgroundSlide ( void ) ;
static void BattleIntroDrawTrainersOrMonsSprites ( void ) ;
static void BattleIntroDrawPartySummaryScreens ( void ) ;
static void BattleIntroPrintTrainerWantsToBattle ( void ) ;
static void BattleIntroPrintWildMonAttacked ( void ) ;
static void BattleIntroPrintOpponentSendsOut ( void ) ;
static void BattleIntroPrintPlayerSendsOut ( void ) ;
static void BattleIntroOpponent1SendsOutMonAnimation ( void ) ;
static void BattleIntroOpponent2SendsOutMonAnimation ( void ) ;
static void BattleIntroRecordMonsToDex ( void ) ;
static void BattleIntroPlayer1SendsOutMonAnimation ( void ) ;
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 ) ;
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-06-30 15:35:54 +02:00
EWRAM_DATA u8 gDisplayedStringBattle [ 300 ] = { 0 } ;
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-08 11:17:41 +01:00
EWRAM_DATA static u32 sUnusedUnknownArray [ 25 ] = { 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 ;
2019-11-01 02:33:01 +01:00
EWRAM_DATA struct UnknownPokemonStruct4 gMultiPartnerParty [ MULTI_PARTY_SIZE ] = { 0 } ;
2019-10-18 01:22:03 +02:00
EWRAM_DATA static struct UnknownPokemonStruct4 * sMultiPartnerPartyBuffer = NULL ;
2018-02-07 22:53:40 +01:00
EWRAM_DATA u8 * gUnknown_0202305C = NULL ;
EWRAM_DATA u8 * gUnknown_02023060 = NULL ;
EWRAM_DATA u8 gBattleBufferA [ MAX_BATTLERS_COUNT ] [ 0x200 ] = { 0 } ;
EWRAM_DATA u8 gBattleBufferB [ MAX_BATTLERS_COUNT ] [ 0x200 ] = { 0 } ;
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 ;
EWRAM_DATA u8 gCritMultiplier = 0 ;
EWRAM_DATA u8 gMultiHitCounter = 0 ;
EWRAM_DATA const u8 * gBattlescriptCurrInstr = NULL ;
EWRAM_DATA u32 gUnusedBattleMainVar = 0 ;
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 } ;
EWRAM_DATA u8 gLastHitBy [ MAX_BATTLERS_COUNT ] = { 0 } ;
EWRAM_DATA u16 gChosenMoveByBattler [ MAX_BATTLERS_COUNT ] = { 0 } ;
EWRAM_DATA u8 gMoveResultFlags = 0 ;
EWRAM_DATA u32 gHitMarker = 0 ;
2018-02-08 11:17:41 +01:00
EWRAM_DATA static u8 sUnusedBattlersArray [ MAX_BATTLERS_COUNT ] = { 0 } ;
2018-02-07 22:53:40 +01:00
EWRAM_DATA u8 gTakenDmgByBattler [ MAX_BATTLERS_COUNT ] = { 0 } ;
EWRAM_DATA u8 gUnknown_0202428C = 0 ;
EWRAM_DATA u16 gSideStatuses [ 2 ] = { 0 } ;
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 gDynamicBasePower = 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-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 ( 64 x64 ) ,
2018-12-23 14:52:47 +01:00
. x = 0 ,
2019-03-11 08:12:15 +01:00
. size = SPRITE_SIZE ( 64 x64 ) ,
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 ( 64 x64 ) ,
2018-12-23 14:52:47 +01:00
. x = 0 ,
2019-03-11 08:12:15 +01:00
. size = SPRITE_SIZE ( 64 x64 ) ,
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
// Unknown and unused data. Feel free to remove.
static const u16 gUnknown_0831ACB8 [ ] = { 0 , 5 , 0xfffe , 0 } ;
static const u16 * const gUnknown_0831ACC0 = gUnknown_0831ACB8 ;
static const u16 gUnknown_0831ACC4 [ ] = { 0xfff0 , 0 , 0x0400 , 0 , 0 , 0 , 0x3c00 , 0 , 0x7ffe , 1 , 0 , 0 } ;
static const u16 * const gUnknown_0831ACDC = gUnknown_0831ACC4 ;
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
// format: attacking type, defending type, damage multiplier
// the multiplier is a (decimal) fixed-point number:
// 20 is × 2.0 TYPE_MUL_SUPER_EFFECTIVE
// 10 is × 1.0 TYPE_MUL_NORMAL
// 05 is × 0.5 TYPE_MUL_NOT_EFFECTIVE
// 00 is × 0.0 TYPE_MUL_NO_EFFECT
const u8 gTypeEffectiveness [ 336 ] =
{
TYPE_NORMAL , TYPE_ROCK , TYPE_MUL_NOT_EFFECTIVE ,
TYPE_NORMAL , TYPE_STEEL , TYPE_MUL_NOT_EFFECTIVE ,
TYPE_FIRE , TYPE_FIRE , TYPE_MUL_NOT_EFFECTIVE ,
TYPE_FIRE , TYPE_WATER , TYPE_MUL_NOT_EFFECTIVE ,
TYPE_FIRE , TYPE_GRASS , TYPE_MUL_SUPER_EFFECTIVE ,
TYPE_FIRE , TYPE_ICE , TYPE_MUL_SUPER_EFFECTIVE ,
TYPE_FIRE , TYPE_BUG , TYPE_MUL_SUPER_EFFECTIVE ,
TYPE_FIRE , TYPE_ROCK , TYPE_MUL_NOT_EFFECTIVE ,
TYPE_FIRE , TYPE_DRAGON , TYPE_MUL_NOT_EFFECTIVE ,
TYPE_FIRE , TYPE_STEEL , TYPE_MUL_SUPER_EFFECTIVE ,
TYPE_WATER , TYPE_FIRE , TYPE_MUL_SUPER_EFFECTIVE ,
TYPE_WATER , TYPE_WATER , TYPE_MUL_NOT_EFFECTIVE ,
TYPE_WATER , TYPE_GRASS , TYPE_MUL_NOT_EFFECTIVE ,
TYPE_WATER , TYPE_GROUND , TYPE_MUL_SUPER_EFFECTIVE ,
TYPE_WATER , TYPE_ROCK , TYPE_MUL_SUPER_EFFECTIVE ,
TYPE_WATER , TYPE_DRAGON , TYPE_MUL_NOT_EFFECTIVE ,
TYPE_ELECTRIC , TYPE_WATER , TYPE_MUL_SUPER_EFFECTIVE ,
TYPE_ELECTRIC , TYPE_ELECTRIC , TYPE_MUL_NOT_EFFECTIVE ,
TYPE_ELECTRIC , TYPE_GRASS , TYPE_MUL_NOT_EFFECTIVE ,
TYPE_ELECTRIC , TYPE_GROUND , TYPE_MUL_NO_EFFECT ,
TYPE_ELECTRIC , TYPE_FLYING , TYPE_MUL_SUPER_EFFECTIVE ,
TYPE_ELECTRIC , TYPE_DRAGON , TYPE_MUL_NOT_EFFECTIVE ,
TYPE_GRASS , TYPE_FIRE , TYPE_MUL_NOT_EFFECTIVE ,
TYPE_GRASS , TYPE_WATER , TYPE_MUL_SUPER_EFFECTIVE ,
TYPE_GRASS , TYPE_GRASS , TYPE_MUL_NOT_EFFECTIVE ,
TYPE_GRASS , TYPE_POISON , TYPE_MUL_NOT_EFFECTIVE ,
TYPE_GRASS , TYPE_GROUND , TYPE_MUL_SUPER_EFFECTIVE ,
TYPE_GRASS , TYPE_FLYING , TYPE_MUL_NOT_EFFECTIVE ,
TYPE_GRASS , TYPE_BUG , TYPE_MUL_NOT_EFFECTIVE ,
TYPE_GRASS , TYPE_ROCK , TYPE_MUL_SUPER_EFFECTIVE ,
TYPE_GRASS , TYPE_DRAGON , TYPE_MUL_NOT_EFFECTIVE ,
TYPE_GRASS , TYPE_STEEL , TYPE_MUL_NOT_EFFECTIVE ,
TYPE_ICE , TYPE_WATER , TYPE_MUL_NOT_EFFECTIVE ,
TYPE_ICE , TYPE_GRASS , TYPE_MUL_SUPER_EFFECTIVE ,
TYPE_ICE , TYPE_ICE , TYPE_MUL_NOT_EFFECTIVE ,
TYPE_ICE , TYPE_GROUND , TYPE_MUL_SUPER_EFFECTIVE ,
TYPE_ICE , TYPE_FLYING , TYPE_MUL_SUPER_EFFECTIVE ,
TYPE_ICE , TYPE_DRAGON , TYPE_MUL_SUPER_EFFECTIVE ,
TYPE_ICE , TYPE_STEEL , TYPE_MUL_NOT_EFFECTIVE ,
TYPE_ICE , TYPE_FIRE , TYPE_MUL_NOT_EFFECTIVE ,
TYPE_FIGHTING , TYPE_NORMAL , TYPE_MUL_SUPER_EFFECTIVE ,
TYPE_FIGHTING , TYPE_ICE , TYPE_MUL_SUPER_EFFECTIVE ,
TYPE_FIGHTING , TYPE_POISON , TYPE_MUL_NOT_EFFECTIVE ,
TYPE_FIGHTING , TYPE_FLYING , TYPE_MUL_NOT_EFFECTIVE ,
TYPE_FIGHTING , TYPE_PSYCHIC , TYPE_MUL_NOT_EFFECTIVE ,
TYPE_FIGHTING , TYPE_BUG , TYPE_MUL_NOT_EFFECTIVE ,
TYPE_FIGHTING , TYPE_ROCK , TYPE_MUL_SUPER_EFFECTIVE ,
TYPE_FIGHTING , TYPE_DARK , TYPE_MUL_SUPER_EFFECTIVE ,
TYPE_FIGHTING , TYPE_STEEL , TYPE_MUL_SUPER_EFFECTIVE ,
TYPE_POISON , TYPE_GRASS , TYPE_MUL_SUPER_EFFECTIVE ,
TYPE_POISON , TYPE_POISON , TYPE_MUL_NOT_EFFECTIVE ,
TYPE_POISON , TYPE_GROUND , TYPE_MUL_NOT_EFFECTIVE ,
TYPE_POISON , TYPE_ROCK , TYPE_MUL_NOT_EFFECTIVE ,
TYPE_POISON , TYPE_GHOST , TYPE_MUL_NOT_EFFECTIVE ,
TYPE_POISON , TYPE_STEEL , TYPE_MUL_NO_EFFECT ,
TYPE_GROUND , TYPE_FIRE , TYPE_MUL_SUPER_EFFECTIVE ,
TYPE_GROUND , TYPE_ELECTRIC , TYPE_MUL_SUPER_EFFECTIVE ,
TYPE_GROUND , TYPE_GRASS , TYPE_MUL_NOT_EFFECTIVE ,
TYPE_GROUND , TYPE_POISON , TYPE_MUL_SUPER_EFFECTIVE ,
TYPE_GROUND , TYPE_FLYING , TYPE_MUL_NO_EFFECT ,
TYPE_GROUND , TYPE_BUG , TYPE_MUL_NOT_EFFECTIVE ,
TYPE_GROUND , TYPE_ROCK , TYPE_MUL_SUPER_EFFECTIVE ,
TYPE_GROUND , TYPE_STEEL , TYPE_MUL_SUPER_EFFECTIVE ,
TYPE_FLYING , TYPE_ELECTRIC , TYPE_MUL_NOT_EFFECTIVE ,
TYPE_FLYING , TYPE_GRASS , TYPE_MUL_SUPER_EFFECTIVE ,
TYPE_FLYING , TYPE_FIGHTING , TYPE_MUL_SUPER_EFFECTIVE ,
TYPE_FLYING , TYPE_BUG , TYPE_MUL_SUPER_EFFECTIVE ,
TYPE_FLYING , TYPE_ROCK , TYPE_MUL_NOT_EFFECTIVE ,
TYPE_FLYING , TYPE_STEEL , TYPE_MUL_NOT_EFFECTIVE ,
TYPE_PSYCHIC , TYPE_FIGHTING , TYPE_MUL_SUPER_EFFECTIVE ,
TYPE_PSYCHIC , TYPE_POISON , TYPE_MUL_SUPER_EFFECTIVE ,
TYPE_PSYCHIC , TYPE_PSYCHIC , TYPE_MUL_NOT_EFFECTIVE ,
TYPE_PSYCHIC , TYPE_DARK , TYPE_MUL_NO_EFFECT ,
TYPE_PSYCHIC , TYPE_STEEL , TYPE_MUL_NOT_EFFECTIVE ,
TYPE_BUG , TYPE_FIRE , TYPE_MUL_NOT_EFFECTIVE ,
TYPE_BUG , TYPE_GRASS , TYPE_MUL_SUPER_EFFECTIVE ,
TYPE_BUG , TYPE_FIGHTING , TYPE_MUL_NOT_EFFECTIVE ,
TYPE_BUG , TYPE_POISON , TYPE_MUL_NOT_EFFECTIVE ,
TYPE_BUG , TYPE_FLYING , TYPE_MUL_NOT_EFFECTIVE ,
TYPE_BUG , TYPE_PSYCHIC , TYPE_MUL_SUPER_EFFECTIVE ,
TYPE_BUG , TYPE_GHOST , TYPE_MUL_NOT_EFFECTIVE ,
TYPE_BUG , TYPE_DARK , TYPE_MUL_SUPER_EFFECTIVE ,
TYPE_BUG , TYPE_STEEL , TYPE_MUL_NOT_EFFECTIVE ,
TYPE_ROCK , TYPE_FIRE , TYPE_MUL_SUPER_EFFECTIVE ,
TYPE_ROCK , TYPE_ICE , TYPE_MUL_SUPER_EFFECTIVE ,
TYPE_ROCK , TYPE_FIGHTING , TYPE_MUL_NOT_EFFECTIVE ,
TYPE_ROCK , TYPE_GROUND , TYPE_MUL_NOT_EFFECTIVE ,
TYPE_ROCK , TYPE_FLYING , TYPE_MUL_SUPER_EFFECTIVE ,
TYPE_ROCK , TYPE_BUG , TYPE_MUL_SUPER_EFFECTIVE ,
TYPE_ROCK , TYPE_STEEL , TYPE_MUL_NOT_EFFECTIVE ,
TYPE_GHOST , TYPE_NORMAL , TYPE_MUL_NO_EFFECT ,
TYPE_GHOST , TYPE_PSYCHIC , TYPE_MUL_SUPER_EFFECTIVE ,
TYPE_GHOST , TYPE_DARK , TYPE_MUL_NOT_EFFECTIVE ,
TYPE_GHOST , TYPE_STEEL , TYPE_MUL_NOT_EFFECTIVE ,
TYPE_GHOST , TYPE_GHOST , TYPE_MUL_SUPER_EFFECTIVE ,
TYPE_DRAGON , TYPE_DRAGON , TYPE_MUL_SUPER_EFFECTIVE ,
TYPE_DRAGON , TYPE_STEEL , TYPE_MUL_NOT_EFFECTIVE ,
TYPE_DARK , TYPE_FIGHTING , TYPE_MUL_NOT_EFFECTIVE ,
TYPE_DARK , TYPE_PSYCHIC , TYPE_MUL_SUPER_EFFECTIVE ,
TYPE_DARK , TYPE_GHOST , TYPE_MUL_SUPER_EFFECTIVE ,
TYPE_DARK , TYPE_DARK , TYPE_MUL_NOT_EFFECTIVE ,
TYPE_DARK , TYPE_STEEL , TYPE_MUL_NOT_EFFECTIVE ,
TYPE_STEEL , TYPE_FIRE , TYPE_MUL_NOT_EFFECTIVE ,
TYPE_STEEL , TYPE_WATER , TYPE_MUL_NOT_EFFECTIVE ,
TYPE_STEEL , TYPE_ELECTRIC , TYPE_MUL_NOT_EFFECTIVE ,
TYPE_STEEL , TYPE_ICE , TYPE_MUL_SUPER_EFFECTIVE ,
TYPE_STEEL , TYPE_ROCK , TYPE_MUL_SUPER_EFFECTIVE ,
TYPE_STEEL , TYPE_STEEL , TYPE_MUL_NOT_EFFECTIVE ,
TYPE_FORESIGHT , TYPE_FORESIGHT , TYPE_MUL_NO_EFFECT ,
TYPE_NORMAL , TYPE_GHOST , TYPE_MUL_NO_EFFECT ,
TYPE_FIGHTING , TYPE_GHOST , TYPE_MUL_NO_EFFECT ,
TYPE_ENDTABLE , TYPE_ENDTABLE , TYPE_MUL_NO_EFFECT
} ;
2019-10-18 01:22:03 +02:00
const u8 gTypeNames [ NUMBER_OF_MON_TYPES ] [ TYPE_NAME_LENGTH + 1 ] =
2018-02-26 14:29:17 +01:00
{
_ ( " NORMAL " ) ,
_ ( " FIGHT " ) ,
_ ( " FLYING " ) ,
_ ( " POISON " ) ,
_ ( " GROUND " ) ,
_ ( " ROCK " ) ,
_ ( " BUG " ) ,
_ ( " GHOST " ) ,
_ ( " STEEL " ) ,
_ ( " ??? " ) ,
_ ( " FIRE " ) ,
_ ( " WATER " ) ,
_ ( " GRASS " ) ,
_ ( " ELECTR " ) ,
_ ( " PSYCHC " ) ,
_ ( " ICE " ) ,
_ ( " DRAGON " ) ,
_ ( " DARK " ) ,
} ;
// 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 } ,
2018-12-05 15:31:01 +01:00
{ 0xFF , 5 } ,
2018-02-26 14:29:17 +01:00
} ;
# 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-06-30 18:55:34 +02:00
if ( gBattleTypeFlags & BATTLE_TYPE_INGAME_PARTNER & & gPartnerTrainerId ! = TRAINER_STEVEN_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
2019-11-07 01:18:11 +01:00
InitBattleBgsVideo ( ) ;
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 ) ;
if ( gBattleTypeFlags & BATTLE_TYPE_TWO_OPPONENTS )
CreateNPCTrainerParty ( & gEnemyParty [ 3 ] , gTrainerBattleOpponent_B , FALSE ) ;
SetWildMonHeldItem ( ) ;
}
gMain . inBattle = TRUE ;
2019-12-14 09:58:20 +01:00
gSaveBlock2Ptr - > frontier . disableRecordBattle = FALSE ;
2017-10-01 01:12:42 +02:00
2018-06-20 23:07:51 +02:00
for ( i = 0 ; i < PARTY_SIZE ; i + + )
2020-02-02 19:28:54 +01:00
AdjustFriendship ( & gPlayerParty [ i ] , FRIENDSHIP_EVENT_LEAGUE_BATTLE ) ;
2017-10-01 01:12:42 +02:00
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 ( ) ;
2020-06-03 21:28:29 +02:00
if ( gTrainerBattleOpponent_A = = TRAINER_UNION_ROOM )
2017-10-01 01:12:42 +02:00
{
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 ( ) ;
2019-11-07 01:18:11 +01:00
taskId = CreateTask ( InitLinkBattleVsScreen , 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 ( ) ;
2019-11-07 01:18:11 +01:00
taskId = CreateTask ( InitLinkBattleVsScreen , 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 ) ;
2019-11-01 02:33:01 +01:00
memcpy ( gPlayerParty + MULTI_PARTY_SIZE , gBlockRecvBuffer [ playerMultiplayerId ] , sizeof ( struct Pokemon ) * 2 ) ;
2017-10-01 01:12:42 +02:00
}
else
{
memcpy ( gPlayerParty , gBlockRecvBuffer [ playerMultiplayerId ] , sizeof ( struct Pokemon ) * 2 ) ;
2019-11-01 02:33:01 +01:00
memcpy ( gPlayerParty + MULTI_PARTY_SIZE , gBlockRecvBuffer [ enemyMultiplayerId ] , sizeof ( struct Pokemon ) * 2 ) ;
2017-10-01 01:12:42 +02:00
}
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 ;
2019-10-18 01:22:03 +02:00
for ( i = 0 ; i < ( int ) ARRAY_COUNT ( gMultiPartnerParty ) ; i + + )
2017-10-01 01:12:42 +02:00
{
2019-10-18 01:22:03 +02:00
gMultiPartnerParty [ i ] . species = GetMonData ( & gPlayerParty [ arrayIdPlus + i ] , MON_DATA_SPECIES ) ;
gMultiPartnerParty [ i ] . heldItem = GetMonData ( & gPlayerParty [ arrayIdPlus + i ] , MON_DATA_HELD_ITEM ) ;
GetMonData ( & gPlayerParty [ arrayIdPlus + i ] , MON_DATA_NICKNAME , gMultiPartnerParty [ i ] . nickname ) ;
gMultiPartnerParty [ i ] . level = GetMonData ( & gPlayerParty [ arrayIdPlus + i ] , MON_DATA_LEVEL ) ;
gMultiPartnerParty [ i ] . hp = GetMonData ( & gPlayerParty [ arrayIdPlus + i ] , MON_DATA_HP ) ;
gMultiPartnerParty [ i ] . maxhp = GetMonData ( & gPlayerParty [ arrayIdPlus + i ] , MON_DATA_MAX_HP ) ;
gMultiPartnerParty [ i ] . status = GetMonData ( & gPlayerParty [ arrayIdPlus + i ] , MON_DATA_STATUS ) ;
gMultiPartnerParty [ i ] . personality = GetMonData ( & gPlayerParty [ arrayIdPlus + i ] , MON_DATA_PERSONALITY ) ;
gMultiPartnerParty [ i ] . gender = GetMonGender ( & gPlayerParty [ arrayIdPlus + i ] ) ;
StripExtCtrlCodes ( gMultiPartnerParty [ i ] . nickname ) ;
2017-10-01 01:12:42 +02:00
if ( GetMonData ( & gPlayerParty [ arrayIdPlus + i ] , MON_DATA_LANGUAGE ) ! = LANGUAGE_JAPANESE )
2019-10-18 01:22:03 +02:00
PadNameString ( gMultiPartnerParty [ i ] . nickname , CHAR_SPACE ) ;
2017-10-01 01:12:42 +02:00
}
2019-10-18 01:22:03 +02:00
memcpy ( sMultiPartnerPartyBuffer , gMultiPartnerParty , sizeof ( gMultiPartnerParty ) ) ;
2017-10-01 01:12:42 +02:00
}
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
{
2019-10-18 01:22:03 +02:00
sMultiPartnerPartyBuffer = Alloc ( sizeof ( struct UnknownPokemonStruct4 ) * ARRAY_COUNT ( gMultiPartnerParty ) ) ;
2017-10-01 01:12:42 +02:00
sub_80379F8 ( 0 ) ;
2019-10-18 01:22:03 +02:00
SendBlock ( bitmask_all_link_players_but_self ( ) , sMultiPartnerPartyBuffer , sizeof ( struct UnknownPokemonStruct4 ) * ARRAY_COUNT ( gMultiPartnerParty ) ) ;
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 ;
2019-10-18 01:22:03 +02:00
if ( numPlayers = = MAX_LINK_PLAYERS )
2017-10-01 01:12:42 +02:00
{
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
{
2019-10-18 01:22:03 +02:00
memcpy ( gMultiPartnerParty , gBlockRecvBuffer [ i ] , sizeof ( struct UnknownPokemonStruct4 ) * ARRAY_COUNT ( gMultiPartnerParty ) ) ;
2017-10-01 01:12:42 +02:00
}
}
else
{
2019-10-18 01:22:03 +02:00
memcpy ( gMultiPartnerParty , gBlockRecvBuffer [ i ] , sizeof ( struct UnknownPokemonStruct4 ) * ARRAY_COUNT ( gMultiPartnerParty ) ) ;
2017-10-01 01:12:42 +02:00
}
}
gBattleCommunication [ MULTIUSE_STATE ] + + ;
* savedCallback = gMain . savedCallback ;
* savedBattleTypeFlags = gBattleTypeFlags ;
gMain . savedCallback = CB2_PreInitMultiBattle ;
2019-10-18 01:22:03 +02:00
ShowPartyMenuToShowcaseMultiBattleParty ( ) ;
2017-10-01 01:12:42 +02:00
}
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 )
2020-08-13 09:09:47 +02:00
SetLinkStandbyCallback ( ) ;
2017-10-01 01:12:42 +02:00
else
2020-08-13 09:09:47 +02:00
SetCloseLinkCallback ( ) ;
2017-10-01 01:12:42 +02:00
}
break ;
case 3 :
2017-11-13 05:58:05 +01:00
if ( gWirelessCommType )
2017-10-01 01:12:42 +02:00
{
2019-10-09 11:56:44 +02:00
if ( IsLinkRfuTaskFinished ( ) )
2017-10-01 01:12:42 +02:00
{
gBattleTypeFlags = * savedBattleTypeFlags ;
gMain . savedCallback = * savedCallback ;
SetMainCallback2 ( CB2_InitBattleInternal ) ;
2019-10-18 01:22:03 +02:00
Free ( sMultiPartnerPartyBuffer ) ;
sMultiPartnerPartyBuffer = NULL ;
2017-10-01 01:12:42 +02:00
}
}
else if ( gReceivedRemoteLinkPlayers = = 0 )
{
gBattleTypeFlags = * savedBattleTypeFlags ;
gMain . savedCallback = * savedCallback ;
SetMainCallback2 ( CB2_InitBattleInternal ) ;
2019-10-18 01:22:03 +02:00
Free ( sMultiPartnerPartyBuffer ) ;
sMultiPartnerPartyBuffer = NULL ;
2017-10-01 01:12:42 +02:00
}
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 :
2019-10-18 01:22:03 +02:00
sMultiPartnerPartyBuffer = Alloc ( sizeof ( struct UnknownPokemonStruct4 ) * ARRAY_COUNT ( gMultiPartnerParty ) ) ;
2017-10-01 01:12:42 +02:00
sub_80379F8 ( 3 ) ;
gBattleCommunication [ MULTIUSE_STATE ] + + ;
* savedCallback = gMain . savedCallback ;
* savedBattleTypeFlags = gBattleTypeFlags ;
gMain . savedCallback = CB2_PreInitIngamePlayerPartnerBattle ;
2019-10-18 01:22:03 +02:00
ShowPartyMenuToShowcaseMultiBattleParty ( ) ;
2017-10-01 01:12:42 +02:00
break ;
case 1 :
if ( ! gPaletteFade . active )
{
gBattleCommunication [ MULTIUSE_STATE ] = 2 ;
gBattleTypeFlags = * savedBattleTypeFlags ;
gMain . savedCallback = * savedCallback ;
SetMainCallback2 ( CB2_InitBattleInternal ) ;
2019-10-18 01:22:03 +02:00
Free ( sMultiPartnerPartyBuffer ) ;
sMultiPartnerPartyBuffer = NULL ;
2017-10-01 01:12:42 +02:00
}
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 ( ) ;
2019-11-07 01:18:11 +01:00
var = CreateTask ( InitLinkBattleVsScreen , 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 :
2019-11-01 02:33:01 +01:00
memcpy ( gPlayerParty + MULTI_PARTY_SIZE , gBlockRecvBuffer [ id ] , sizeof ( struct Pokemon ) * 2 ) ;
2017-10-01 01:12:42 +02:00
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 :
2019-11-01 02:33:01 +01:00
memcpy ( gPlayerParty + MULTI_PARTY_SIZE , gBlockRecvBuffer [ id ] , sizeof ( struct Pokemon ) * 2 ) ;
2017-10-01 01:12:42 +02:00
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 :
2019-11-01 02:33:01 +01:00
memcpy ( gEnemyParty + MULTI_PARTY_SIZE , gBlockRecvBuffer [ id ] , sizeof ( struct Pokemon ) * 2 ) ;
2017-10-01 01:12:42 +02:00
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 )
{
2019-09-08 18:21:24 +02:00
for ( id = 0 ; id < MAX_LINK_PLAYERS & & ( gLinkPlayers [ id ] . version & 0xFF ) = = VERSION_EMERALD ; id + + ) ;
2017-10-01 01:12:42 +02:00
2019-09-08 18:21:24 +02:00
if ( id = = MAX_LINK_PLAYERS )
2017-10-01 01:12:42 +02:00
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 ( ) ;
2020-08-21 00:02:00 +02:00
m4aSongNumStop ( SE_LOW_HEALTH ) ;
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 ;
2019-08-31 05:06:43 +02:00
CreateMon ( & party [ i ] , partyData [ i ] . species , partyData [ i ] . lvl , fixedIV , TRUE , personalityValue , OT_ID_RANDOM_NO_SHINY , 0 ) ;
2017-10-01 18:54:01 +02:00
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 ;
2019-08-31 05:06:43 +02:00
CreateMon ( & party [ i ] , partyData [ i ] . species , partyData [ i ] . lvl , fixedIV , TRUE , personalityValue , OT_ID_RANDOM_NO_SHINY , 0 ) ;
2017-10-01 18:54:01 +02:00
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 ;
2019-08-31 05:06:43 +02:00
CreateMon ( & party [ i ] , partyData [ i ] . species , partyData [ i ] . lvl , fixedIV , TRUE , personalityValue , OT_ID_RANDOM_NO_SHINY , 0 ) ;
2017-10-01 18:54:01 +02:00
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 sub_8038A04 ( void ) // unused
{
if ( REG_VCOUNT < 0xA0 & & REG_VCOUNT > = 0x6F )
SetGpuReg ( REG_OFFSET_BG0CNT , 0x9800 ) ;
}
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 ;
2020-08-21 00:02:00 +02:00
PlaySE ( SE_MUGSHOT ) ;
2017-10-01 18:54:01 +02:00
}
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 ;
2019-11-07 01:18:11 +01:00
InitBattleBgsVideo ( ) ;
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 ) ;
2019-11-07 01:18:11 +01:00
taskId = CreateTask ( InitLinkBattleVsScreen , 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 ) ;
2018-12-05 15:31:01 +01:00
gBattleCommunication [ 1 ] = 0xFF ;
2017-10-01 18:54:01 +02:00
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
2019-12-14 09:58:20 +01:00
if ( ! gSaveBlock2Ptr - > frontier . disableRecordBattle & & 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
{
2020-08-13 09:09:47 +02:00
SetLinkStandbyCallback ( ) ;
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 )
2020-08-13 09:09:47 +02:00
SetCloseLinkCallback ( ) ;
2017-10-01 18:54:01 +02:00
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 ;
2019-11-07 01:18:11 +01:00
InitBattleBgsVideo ( ) ;
2017-10-01 18:54:01 +02:00
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 )
{
2020-08-13 09:09:47 +02:00
SetLinkStandbyCallback ( ) ;
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 )
2020-08-13 09:09:47 +02:00
SetCloseLinkCallback ( ) ;
2017-10-01 18:54:01 +02:00
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
{
2019-12-14 09:58:20 +01:00
BattleStringExpandPlaceholdersToDisplayedString ( BattleFrontier_BattleTowerBattleRoom_Text_RecordCouldntBeSaved ) ;
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 )
{
2020-08-13 09:09:47 +02:00
SetLinkStandbyCallback ( ) ;
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-06-20 23:07:51 +02:00
BeginNormalPaletteFade ( 0x20000 , 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-06-20 23:07:51 +02:00
BeginNormalPaletteFade ( 0x20000 , 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_80398BC ( struct Sprite * sprite ) // unused?
{
2017-12-02 21:44:50 +01:00
sprite - > data [ 3 ] = 6 ;
sprite - > data [ 4 ] = 1 ;
2017-10-01 18:54:01 +02:00
sprite - > callback = sub_80398D0 ;
}
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-02-08 11:17:41 +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
}
}
}
2020-07-14 11:13:03 +02:00
// Used when selecting a move, which can hit multiple targets, in double battles.
void SpriteCb_ShowAsMoveTarget ( struct Sprite * sprite )
2017-10-01 18:54:01 +02:00
{
2017-12-02 21:44:50 +01:00
sprite - > data [ 3 ] = 8 ;
sprite - > data [ 4 ] = sprite - > invisible ;
2020-07-14 11:13:03 +02:00
sprite - > callback = SpriteCb_BlinkVisible ;
2017-10-01 18:54:01 +02:00
}
2020-07-14 11:13:03 +02:00
static void SpriteCb_BlinkVisible ( struct Sprite * sprite )
2017-10-01 18:54:01 +02:00
{
2020-07-14 11:13:03 +02:00
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
}
}
2020-07-14 11:13:03 +02:00
void SpriteCb_HideAsMoveTarget ( struct Sprite * sprite )
2017-10-01 18:54:01 +02:00
{
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 ;
}
2020-07-14 11:13:03 +02:00
void SpriteCb_OpponentMonFromBall ( struct Sprite * sprite )
2017-10-02 23:32:39 +02:00
{
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
}
}
2018-06-20 23:07:51 +02:00
# define sSinIndex data[0]
# define sDelta data[1]
# define sAmplitude data[2]
# define sBouncerSpriteId data[3]
# define sWhich data[4]
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 ;
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 ;
s32 index ;
2017-10-02 23:32:39 +02:00
2018-06-20 23:07:51 +02:00
if ( sprite - > sWhich = = BOUNCE_HEALTHBOX )
index = sprite - > sSinIndex ;
2017-10-02 23:32:39 +02:00
else
2018-06-20 23:07:51 +02:00
index = sprite - > sSinIndex ;
2017-10-02 23:32:39 +02:00
2018-06-20 23:07:51 +02:00
gSprites [ bouncerSpriteId ] . pos2 . y = Sin ( index , sprite - > sAmplitude ) + sprite - > sAmplitude ;
sprite - > sSinIndex = ( sprite - > sSinIndex + sprite - > sDelta ) & 0xFF ;
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
2020-07-14 11:13:03 +02:00
void SpriteCb_PlayerMonFromBall ( struct Sprite * sprite )
2017-10-02 23:32:39 +02:00
{
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 ;
gBattleMainFunc = BattleIntroGetMonsData ;
}
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 ;
u32 j ;
u8 * dataPtr ;
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
for ( i = 0 ; i < MAX_BATTLERS_COUNT ; i + + )
2017-10-02 23:32:39 +02:00
{
gStatuses3 [ i ] = 0 ;
dataPtr = ( u8 * ) & gDisableStructs [ i ] ;
for ( j = 0 ; j < sizeof ( struct DisableStruct ) ; j + + )
dataPtr [ j ] = 0 ;
2017-11-26 13:26:58 +01:00
gDisableStructs [ i ] . isFirstTurn = 2 ;
2018-02-08 11:17:41 +01:00
sUnusedBattlersArray [ i ] = 0 ;
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 ;
2018-12-05 15:31:01 +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 ;
2017-10-02 23:32:39 +02:00
}
for ( i = 0 ; i < 2 ; i + + )
{
2018-01-16 22:12:38 +01:00
gSideStatuses [ i ] = 0 ;
2017-10-02 23:32:39 +02:00
dataPtr = ( u8 * ) & gSideTimers [ i ] ;
for ( j = 0 ; j < sizeof ( struct SideTimer ) ; j + + )
dataPtr [ j ] = 0 ;
}
2018-02-06 23:09:39 +01:00
gBattlerAttacker = 0 ;
gBattlerTarget = 0 ;
2017-10-02 23:32:39 +02:00
gBattleWeather = 0 ;
dataPtr = ( u8 * ) & gWishFutureKnock ;
for ( i = 0 ; i < sizeof ( struct WishFutureKnock ) ; i + + )
dataPtr [ i ] = 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 ( ) )
2017-10-02 23:32:39 +02:00
gHitMarker | = HITMARKER_NO_ANIMATIONS ;
gBattleScripting . battleStyle = gSaveBlock2Ptr - > optionsBattleStyle ;
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 ;
* ( & gBattleStruct - > safariCatchFactor ) = gBaseStats [ GetMonData ( & gEnemyParty [ 0 ] , MON_DATA_SPECIES ) ] . catchRate * 100 / 1275 ;
gBattleStruct - > safariEscapeFactor = 3 ;
2017-10-02 23:32:39 +02:00
gBattleStruct - > wildVictorySong = 0 ;
gBattleStruct - > moneyMultiplier = 1 ;
for ( i = 0 ; i < 8 ; i + + )
{
2018-10-14 18:10:54 +02:00
* ( ( u8 * ) gBattleStruct - > lastTakenMove + i ) = 0 ;
2017-10-02 23:32:39 +02:00
* ( ( u8 * ) gBattleStruct - > usedHeldItems + i ) = 0 ;
* ( ( u8 * ) gBattleStruct - > choicedMove + i ) = 0 ;
* ( ( u8 * ) gBattleStruct - > changedItems + i ) = 0 ;
2018-10-14 18:10:54 +02:00
* ( i + 0 * 8 + ( u8 * ) ( gBattleStruct - > lastTakenMoveFrom ) + 0 ) = 0 ;
* ( i + 1 * 8 + ( u8 * ) ( gBattleStruct - > lastTakenMoveFrom ) + 0 ) = 0 ;
* ( i + 2 * 8 + ( u8 * ) ( gBattleStruct - > lastTakenMoveFrom ) + 0 ) = 0 ;
* ( i + 3 * 8 + ( u8 * ) ( gBattleStruct - > lastTakenMoveFrom ) + 0 ) = 0 ;
2017-10-02 23:32:39 +02:00
}
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 - > AI_monToSwitchIntoId + i ) = PARTY_SIZE ;
2017-10-02 23:32:39 +02:00
}
2018-12-07 23:50:56 +01:00
gBattleStruct - > givenExpMons = 0 ;
2020-07-17 02:12:12 +02:00
gBattleStruct - > palaceFlags = 0 ;
2017-10-02 23:32:39 +02:00
gRandomTurnNumber = Random ( ) ;
dataPtr = ( u8 * ) ( & gBattleResults ) ;
for ( i = 0 ; i < sizeof ( struct BattleResults ) ; i + + )
dataPtr [ i ] = 0 ;
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 ;
2017-10-02 23:32:39 +02:00
}
void SwitchInClearSetData ( void )
{
2018-02-06 02:46:59 +01:00
struct DisableStruct disableStructCopy = gDisableStructs [ gActiveBattler ] ;
2017-10-02 23:32:39 +02:00
s32 i ;
u8 * ptr ;
if ( gBattleMoves [ gCurrentMove ] . effect ! = EFFECT_BATON_PASS )
{
2018-11-18 20:00:36 +01:00
for ( i = 0 ; i < NUM_BATTLE_STATS ; i + + )
2020-08-05 02:33:05 +02:00
gBattleMons [ gActiveBattler ] . statStages [ i ] = DEFAULT_STAT_STAGE ;
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 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-01 12:16:52 +02:00
gStatuses3 [ gActiveBattler ] & = ( STATUS3_LEECHSEED_BATTLER | STATUS3_LEECHSEED | STATUS3_ALWAYS_HITS | STATUS3_PERISH_SONG | STATUS3_ROOTED | STATUS3_MUDSPORT | STATUS3_WATERSPORT ) ;
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 ) ;
2020-07-17 02:12:12 +02:00
gStatuses3 [ i ] | = STATUS3_ALWAYS_HITS_TURN ( 2 ) ;
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
2018-02-06 02:46:59 +01:00
ptr = ( u8 * ) & gDisableStructs [ gActiveBattler ] ;
2017-10-02 23:32:39 +02:00
for ( i = 0 ; i < sizeof ( struct DisableStruct ) ; i + + )
ptr [ i ] = 0 ;
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 ;
2018-12-05 15:31:01 +01:00
gLastHitBy [ gActiveBattler ] = 0xFF ;
2017-10-02 23:32:39 +02:00
2018-10-14 18:10:54 +02:00
* ( gBattleStruct - > lastTakenMove + gActiveBattler * 2 + 0 ) = 0 ;
* ( gBattleStruct - > lastTakenMove + gActiveBattler * 2 + 1 ) = 0 ;
* ( 0 * 2 + gActiveBattler * 8 + ( u8 * ) ( gBattleStruct - > lastTakenMoveFrom ) + 0 ) = 0 ;
* ( 0 * 2 + gActiveBattler * 8 + ( u8 * ) ( gBattleStruct - > lastTakenMoveFrom ) + 1 ) = 0 ;
* ( 1 * 2 + gActiveBattler * 8 + ( u8 * ) ( gBattleStruct - > lastTakenMoveFrom ) + 0 ) = 0 ;
* ( 1 * 2 + gActiveBattler * 8 + ( u8 * ) ( gBattleStruct - > lastTakenMoveFrom ) + 1 ) = 0 ;
* ( 2 * 2 + gActiveBattler * 8 + ( u8 * ) ( gBattleStruct - > lastTakenMoveFrom ) + 0 ) = 0 ;
* ( 2 * 2 + gActiveBattler * 8 + ( u8 * ) ( gBattleStruct - > lastTakenMoveFrom ) + 1 ) = 0 ;
* ( 3 * 2 + gActiveBattler * 8 + ( u8 * ) ( gBattleStruct - > lastTakenMoveFrom ) + 0 ) = 0 ;
* ( 3 * 2 + gActiveBattler * 8 + ( u8 * ) ( gBattleStruct - > lastTakenMoveFrom ) + 1 ) = 0 ;
2017-10-02 23:32:39 +02:00
2020-07-17 02:12:12 +02:00
gBattleStruct - > palaceFlags & = ~ ( 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 ) )
2017-10-02 23:32:39 +02:00
{
2018-10-14 18:10:54 +02:00
* ( gBattleStruct - > lastTakenMove + i * 2 + 0 ) = 0 ;
* ( gBattleStruct - > lastTakenMove + i * 2 + 1 ) = 0 ;
2017-10-02 23:32:39 +02:00
}
2018-10-14 18:10:54 +02:00
* ( i * 8 + gActiveBattler * 2 + ( u8 * ) ( gBattleStruct - > lastTakenMoveFrom ) + 0 ) = 0 ;
* ( i * 8 + gActiveBattler * 2 + ( u8 * ) ( gBattleStruct - > lastTakenMoveFrom ) + 1 ) = 0 ;
2017-10-02 23:32:39 +02:00
}
2018-02-06 02:46:59 +01:00
* ( u8 * ) ( ( u8 * ) ( & gBattleStruct - > choicedMove [ gActiveBattler ] ) + 0 ) = 0 ;
* ( u8 * ) ( ( u8 * ) ( & gBattleStruct - > choicedMove [ gActiveBattler ] ) + 1 ) = 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
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 ;
u8 * ptr ;
2018-11-18 20:00:36 +01:00
for ( i = 0 ; i < NUM_BATTLE_STATS ; i + + )
2020-08-05 02:33:05 +02:00
gBattleMons [ gActiveBattler ] . statStages [ i ] = DEFAULT_STAT_STAGE ;
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
2018-02-06 02:46:59 +01:00
ptr = ( u8 * ) & gDisableStructs [ gActiveBattler ] ;
2017-10-02 23:32:39 +02:00
for ( i = 0 ; i < sizeof ( struct DisableStruct ) ; i + + )
ptr [ i ] = 0 ;
2018-02-06 02:46:59 +01:00
gProtectStructs [ gActiveBattler ] . protected = 0 ;
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 ] . flag0Unknown = 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 ;
gDisableStructs [ gActiveBattler ] . isFirstTurn = 2 ;
gLastMoves [ gActiveBattler ] = 0 ;
gLastLandedMoves [ gActiveBattler ] = 0 ;
gLastHitByType [ gActiveBattler ] = 0 ;
gLastResultingMoves [ gActiveBattler ] = 0 ;
gLastPrintedMoves [ gActiveBattler ] = 0 ;
2018-12-05 15:31:01 +01:00
gLastHitBy [ gActiveBattler ] = 0xFF ;
2018-02-06 02:46:59 +01:00
* ( u8 * ) ( ( u8 * ) ( & gBattleStruct - > choicedMove [ gActiveBattler ] ) + 0 ) = 0 ;
* ( u8 * ) ( ( u8 * ) ( & gBattleStruct - > choicedMove [ gActiveBattler ] ) + 1 ) = 0 ;
2018-10-14 18:10:54 +02:00
* ( gBattleStruct - > lastTakenMove + gActiveBattler * 2 + 0 ) = 0 ;
* ( gBattleStruct - > lastTakenMove + gActiveBattler * 2 + 1 ) = 0 ;
* ( 0 * 2 + gActiveBattler * 8 + ( u8 * ) ( gBattleStruct - > lastTakenMoveFrom ) + 0 ) = 0 ;
* ( 0 * 2 + gActiveBattler * 8 + ( u8 * ) ( gBattleStruct - > lastTakenMoveFrom ) + 1 ) = 0 ;
* ( 1 * 2 + gActiveBattler * 8 + ( u8 * ) ( gBattleStruct - > lastTakenMoveFrom ) + 0 ) = 0 ;
* ( 1 * 2 + gActiveBattler * 8 + ( u8 * ) ( gBattleStruct - > lastTakenMoveFrom ) + 1 ) = 0 ;
* ( 2 * 2 + gActiveBattler * 8 + ( u8 * ) ( gBattleStruct - > lastTakenMoveFrom ) + 0 ) = 0 ;
* ( 2 * 2 + gActiveBattler * 8 + ( u8 * ) ( gBattleStruct - > lastTakenMoveFrom ) + 1 ) = 0 ;
* ( 3 * 2 + gActiveBattler * 8 + ( u8 * ) ( gBattleStruct - > lastTakenMoveFrom ) + 0 ) = 0 ;
* ( 3 * 2 + gActiveBattler * 8 + ( u8 * ) ( gBattleStruct - > lastTakenMoveFrom ) + 1 ) = 0 ;
2018-02-06 02:46:59 +01:00
2020-07-17 02:12:12 +02:00
gBattleStruct - > palaceFlags & = ~ ( gBitTable [ gActiveBattler ] ) ;
2018-02-06 02:46:59 +01:00
for ( i = 0 ; i < gBattlersCount ; i + + )
{
if ( i ! = gActiveBattler & & GetBattlerSide ( i ) ! = GetBattlerSide ( gActiveBattler ) )
2017-10-02 23:32:39 +02:00
{
2018-10-14 18:10:54 +02:00
* ( gBattleStruct - > lastTakenMove + i * 2 + 0 ) = 0 ;
* ( gBattleStruct - > lastTakenMove + i * 2 + 1 ) = 0 ;
2017-10-02 23:32:39 +02:00
}
2018-10-14 18:10:54 +02:00
* ( i * 8 + gActiveBattler * 2 + ( u8 * ) ( gBattleStruct - > lastTakenMoveFrom ) + 0 ) = 0 ;
* ( i * 8 + gActiveBattler * 2 + ( u8 * ) ( gBattleStruct - > lastTakenMoveFrom ) + 1 ) = 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 ;
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
}
static void BattleIntroGetMonsData ( void )
{
switch ( gBattleCommunication [ MULTIUSE_STATE ] )
{
case 0 :
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 ) ;
2017-10-02 23:32:39 +02:00
gBattleCommunication [ MULTIUSE_STATE ] + + ;
break ;
case 1 :
2018-02-06 20:48:02 +01:00
if ( gBattleControllerExecFlags = = 0 )
2017-10-02 23:32:39 +02:00
{
gBattleCommunication [ 1 ] + + ;
2018-02-06 02:46:59 +01:00
if ( gBattleCommunication [ 1 ] = = gBattlersCount )
2017-10-02 23:32:39 +02:00
gBattleMainFunc = BattleIntroPrepareBackgroundSlide ;
else
gBattleCommunication [ MULTIUSE_STATE ] = 0 ;
}
break ;
}
}
static void BattleIntroPrepareBackgroundSlide ( void )
{
2018-02-06 20:48:02 +01:00
if ( gBattleControllerExecFlags = = 0 )
2017-10-02 23:32:39 +02:00
{
2018-02-06 02:46:59 +01:00
gActiveBattler = GetBattlerAtPosition ( 0 ) ;
2018-02-06 20:48:02 +01:00
BtlController_EmitIntroSlide ( 0 , gBattleTerrain ) ;
MarkBattlerForControllerExec ( gActiveBattler ) ;
2017-10-02 23:32:39 +02:00
gBattleMainFunc = BattleIntroDrawTrainersOrMonsSprites ;
gBattleCommunication [ 0 ] = 0 ;
gBattleCommunication [ 1 ] = 0 ;
}
}
static void BattleIntroDrawTrainersOrMonsSprites ( void )
{
u8 * ptr ;
s32 i ;
2018-02-06 20:48:02 +01:00
if ( gBattleControllerExecFlags )
2017-10-02 23:32:39 +02:00
return ;
2018-02-06 02:46:59 +01:00
for ( gActiveBattler = 0 ; gActiveBattler < gBattlersCount ; gActiveBattler + + )
2017-10-02 23:32:39 +02:00
{
if ( ( gBattleTypeFlags & BATTLE_TYPE_SAFARI )
2018-02-06 02:46:59 +01:00
& & GetBattlerSide ( gActiveBattler ) = = B_SIDE_PLAYER )
2017-10-02 23:32:39 +02:00
{
2018-02-06 02:46:59 +01:00
ptr = ( u8 * ) & gBattleMons [ gActiveBattler ] ;
2017-10-02 23:32:39 +02:00
for ( i = 0 ; i < sizeof ( struct BattlePokemon ) ; i + + )
ptr [ i ] = 0 ;
}
else
{
u16 * hpOnSwitchout ;
2018-02-06 02:46:59 +01:00
ptr = ( u8 * ) & gBattleMons [ gActiveBattler ] ;
2017-10-02 23:32:39 +02:00
for ( i = 0 ; i < sizeof ( struct BattlePokemon ) ; i + + )
2018-02-06 02:46:59 +01:00
ptr [ i ] = gBattleBufferB [ gActiveBattler ] [ 4 + i ] ;
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 ;
2019-05-14 15:22:16 +02:00
gBattleMons [ gActiveBattler ] . ability = GetAbilityBySpecies ( gBattleMons [ gActiveBattler ] . species , gBattleMons [ gActiveBattler ] . abilityNum ) ;
2018-02-06 02:46:59 +01:00
hpOnSwitchout = & gBattleStruct - > hpOnSwitchout [ GetBattlerSide ( gActiveBattler ) ] ;
* hpOnSwitchout = gBattleMons [ gActiveBattler ] . hp ;
2018-11-18 20:00:36 +01:00
for ( i = 0 ; i < NUM_BATTLE_STATS ; i + + )
2020-08-05 02:33:05 +02:00
gBattleMons [ gActiveBattler ] . statStages [ i ] = DEFAULT_STAT_STAGE ;
2018-02-06 02:46:59 +01:00
gBattleMons [ gActiveBattler ] . status2 = 0 ;
2017-10-02 23:32:39 +02:00
}
2018-02-06 02:46:59 +01:00
if ( GetBattlerPosition ( gActiveBattler ) = = B_POSITION_PLAYER_LEFT )
2017-10-02 23:32:39 +02:00
{
2018-02-06 20:48:02 +01:00
BtlController_EmitDrawTrainerPic ( 0 ) ;
MarkBattlerForControllerExec ( gActiveBattler ) ;
2017-10-02 23:32:39 +02:00
}
if ( gBattleTypeFlags & BATTLE_TYPE_TRAINER )
{
2018-02-06 02:46:59 +01:00
if ( GetBattlerPosition ( gActiveBattler ) = = B_POSITION_OPPONENT_LEFT )
2017-10-02 23:32:39 +02:00
{
2018-02-06 20:48:02 +01:00
BtlController_EmitDrawTrainerPic ( 0 ) ;
MarkBattlerForControllerExec ( gActiveBattler ) ;
2017-10-02 23:32:39 +02:00
}
2018-02-06 02:46:59 +01:00
if ( GetBattlerSide ( gActiveBattler ) = = B_SIDE_OPPONENT
2017-10-02 23:32:39 +02:00
& & ! ( gBattleTypeFlags & ( BATTLE_TYPE_EREADER_TRAINER
| BATTLE_TYPE_FRONTIER
| BATTLE_TYPE_LINK
| BATTLE_TYPE_x2000000
2018-09-20 22:00:00 +02:00
| BATTLE_TYPE_TRAINER_HILL ) ) )
2017-10-02 23:32:39 +02:00
{
2018-02-06 02:46:59 +01:00
HandleSetPokedexFlag ( SpeciesToNationalPokedexNum ( gBattleMons [ gActiveBattler ] . species ) , FLAG_SET_SEEN , gBattleMons [ gActiveBattler ] . personality ) ;
2017-10-02 23:32:39 +02:00
}
}
else
{
2018-02-06 02:46:59 +01:00
if ( GetBattlerSide ( gActiveBattler ) = = B_SIDE_OPPONENT )
2017-10-02 23:32:39 +02:00
{
if ( ! ( gBattleTypeFlags & ( BATTLE_TYPE_EREADER_TRAINER
| BATTLE_TYPE_FRONTIER
| BATTLE_TYPE_LINK
| BATTLE_TYPE_x2000000
2018-09-20 22:00:00 +02:00
| BATTLE_TYPE_TRAINER_HILL ) ) )
2017-10-02 23:32:39 +02:00
{
2018-02-06 02:46:59 +01:00
HandleSetPokedexFlag ( SpeciesToNationalPokedexNum ( gBattleMons [ gActiveBattler ] . species ) , FLAG_SET_SEEN , gBattleMons [ gActiveBattler ] . personality ) ;
2017-10-02 23:32:39 +02:00
}
2018-02-06 20:48:02 +01:00
BtlController_EmitLoadMonSprite ( 0 ) ;
MarkBattlerForControllerExec ( gActiveBattler ) ;
gBattleResults . lastOpponentSpecies = GetMonData ( & gEnemyParty [ gBattlerPartyIndexes [ gActiveBattler ] ] , MON_DATA_SPECIES , NULL ) ;
2017-10-02 23:32:39 +02:00
}
}
if ( gBattleTypeFlags & BATTLE_TYPE_MULTI )
{
2018-02-06 02:46:59 +01:00
if ( GetBattlerPosition ( gActiveBattler ) = = B_POSITION_PLAYER_RIGHT
| | GetBattlerPosition ( gActiveBattler ) = = B_POSITION_OPPONENT_RIGHT )
2017-10-02 23:32:39 +02:00
{
2018-02-06 20:48:02 +01:00
BtlController_EmitDrawTrainerPic ( 0 ) ;
MarkBattlerForControllerExec ( gActiveBattler ) ;
2017-10-02 23:32:39 +02:00
}
}
2018-02-06 02:46:59 +01:00
if ( gBattleTypeFlags & BATTLE_TYPE_TWO_OPPONENTS & & GetBattlerPosition ( gActiveBattler ) = = B_POSITION_OPPONENT_RIGHT )
2017-10-02 23:32:39 +02:00
{
2018-02-06 20:48:02 +01:00
BtlController_EmitDrawTrainerPic ( 0 ) ;
MarkBattlerForControllerExec ( gActiveBattler ) ;
2017-10-02 23:32:39 +02:00
}
if ( gBattleTypeFlags & BATTLE_TYPE_ARENA )
2018-11-11 18:33:16 +01:00
BattleArena_InitPoints ( ) ;
2017-10-02 23:32:39 +02:00
}
gBattleMainFunc = BattleIntroDrawPartySummaryScreens ;
}
static void BattleIntroDrawPartySummaryScreens ( void )
{
s32 i ;
2018-06-28 21:06:32 +02:00
struct HpAndStatus hpStatus [ PARTY_SIZE ] ;
2017-10-02 23:32:39 +02:00
2018-02-06 20:48:02 +01:00
if ( gBattleControllerExecFlags )
2017-10-02 23:32:39 +02:00
return ;
if ( gBattleTypeFlags & BATTLE_TYPE_TRAINER )
{
2017-11-26 14:17:02 +01:00
for ( i = 0 ; i < PARTY_SIZE ; i + + )
2017-10-02 23:32:39 +02:00
{
if ( GetMonData ( & gEnemyParty [ i ] , MON_DATA_SPECIES2 ) = = SPECIES_NONE
| | GetMonData ( & gEnemyParty [ i ] , MON_DATA_SPECIES2 ) = = SPECIES_EGG )
{
2018-12-05 15:31:01 +01:00
hpStatus [ i ] . hp = 0xFFFF ;
2017-10-02 23:32:39 +02:00
hpStatus [ i ] . status = 0 ;
}
else
{
hpStatus [ i ] . hp = GetMonData ( & gEnemyParty [ i ] , MON_DATA_HP ) ;
hpStatus [ i ] . status = GetMonData ( & gEnemyParty [ i ] , MON_DATA_STATUS ) ;
}
}
2018-02-06 02:46:59 +01:00
gActiveBattler = GetBattlerAtPosition ( B_POSITION_OPPONENT_LEFT ) ;
2018-02-06 20:48:02 +01:00
BtlController_EmitDrawPartyStatusSummary ( 0 , hpStatus , 0x80 ) ;
MarkBattlerForControllerExec ( gActiveBattler ) ;
2017-10-02 23:32:39 +02:00
2017-11-26 14:17:02 +01:00
for ( i = 0 ; i < PARTY_SIZE ; i + + )
2017-10-02 23:32:39 +02:00
{
if ( GetMonData ( & gPlayerParty [ i ] , MON_DATA_SPECIES2 ) = = SPECIES_NONE
| | GetMonData ( & gPlayerParty [ i ] , MON_DATA_SPECIES2 ) = = SPECIES_EGG )
{
2018-12-05 15:31:01 +01:00
hpStatus [ i ] . hp = 0xFFFF ;
2017-10-02 23:32:39 +02:00
hpStatus [ i ] . status = 0 ;
}
else
{
hpStatus [ i ] . hp = GetMonData ( & gPlayerParty [ i ] , MON_DATA_HP ) ;
hpStatus [ i ] . status = GetMonData ( & gPlayerParty [ i ] , MON_DATA_STATUS ) ;
}
}
2018-02-06 02:46:59 +01:00
gActiveBattler = GetBattlerAtPosition ( B_POSITION_PLAYER_LEFT ) ;
2018-02-06 20:48:02 +01:00
BtlController_EmitDrawPartyStatusSummary ( 0 , hpStatus , 0x80 ) ;
MarkBattlerForControllerExec ( gActiveBattler ) ;
2017-10-02 23:32:39 +02:00
gBattleMainFunc = BattleIntroPrintTrainerWantsToBattle ;
}
else
{
// The struct gets set here, but nothing is ever done with it since
// wild battles don't show the party summary.
// Still, there's no point in having dead code.
2018-06-28 21:06:32 +02:00
for ( i = 0 ; i < PARTY_SIZE ; i + + )
2017-10-02 23:32:39 +02:00
{
if ( GetMonData ( & gPlayerParty [ i ] , MON_DATA_SPECIES2 ) = = SPECIES_NONE
| | GetMonData ( & gPlayerParty [ i ] , MON_DATA_SPECIES2 ) = = SPECIES_EGG )
{
2018-12-05 15:31:01 +01:00
hpStatus [ i ] . hp = 0xFFFF ;
2017-10-02 23:32:39 +02:00
hpStatus [ i ] . status = 0 ;
}
else
{
hpStatus [ i ] . hp = GetMonData ( & gPlayerParty [ i ] , MON_DATA_HP ) ;
hpStatus [ i ] . status = GetMonData ( & gPlayerParty [ i ] , MON_DATA_STATUS ) ;
}
}
gBattleMainFunc = BattleIntroPrintWildMonAttacked ;
}
}
static void BattleIntroPrintTrainerWantsToBattle ( void )
{
2018-02-06 20:48:02 +01:00
if ( gBattleControllerExecFlags = = 0 )
2017-10-02 23:32:39 +02:00
{
2018-02-06 02:46:59 +01:00
gActiveBattler = GetBattlerAtPosition ( B_POSITION_OPPONENT_LEFT ) ;
PrepareStringBattle ( STRINGID_INTROMSG , gActiveBattler ) ;
2017-10-02 23:32:39 +02:00
gBattleMainFunc = BattleIntroPrintOpponentSendsOut ;
}
}
static void BattleIntroPrintWildMonAttacked ( void )
{
2018-02-06 20:48:02 +01:00
if ( gBattleControllerExecFlags = = 0 )
2017-10-02 23:32:39 +02:00
{
gBattleMainFunc = BattleIntroPrintPlayerSendsOut ;
2017-10-07 15:15:47 +02:00
PrepareStringBattle ( STRINGID_INTROMSG , 0 ) ;
2017-10-02 23:32:39 +02:00
}
}
static void BattleIntroPrintOpponentSendsOut ( void )
{
2018-01-16 23:42:31 +01:00
u32 position ;
2017-10-02 23:32:39 +02:00
2018-02-06 20:48:02 +01:00
if ( gBattleControllerExecFlags )
2017-10-02 23:32:39 +02:00
return ;
if ( ! ( gBattleTypeFlags & BATTLE_TYPE_RECORDED ) )
2018-01-16 23:42:31 +01:00
position = B_POSITION_OPPONENT_LEFT ;
2017-10-02 23:32:39 +02:00
else if ( gBattleTypeFlags & BATTLE_TYPE_x2000000 )
{
if ( gBattleTypeFlags & BATTLE_TYPE_x80000000 )
2018-01-16 23:42:31 +01:00
position = B_POSITION_OPPONENT_LEFT ;
2017-10-02 23:32:39 +02:00
else
2018-01-16 23:42:31 +01:00
position = B_POSITION_PLAYER_LEFT ;
2017-10-02 23:32:39 +02:00
}
else
2018-01-16 23:42:31 +01:00
position = B_POSITION_OPPONENT_LEFT ;
2017-10-02 23:32:39 +02:00
2018-02-06 02:46:59 +01:00
PrepareStringBattle ( STRINGID_INTROSENDOUT , GetBattlerAtPosition ( position ) ) ;
2017-10-02 23:32:39 +02:00
gBattleMainFunc = BattleIntroOpponent1SendsOutMonAnimation ;
}
static void BattleIntroOpponent2SendsOutMonAnimation ( void )
{
2018-01-16 23:42:31 +01:00
u32 position ;
2017-10-02 23:32:39 +02:00
if ( ! ( gBattleTypeFlags & BATTLE_TYPE_RECORDED ) )
2018-01-16 23:42:31 +01:00
position = B_POSITION_OPPONENT_RIGHT ;
2017-10-02 23:32:39 +02:00
else if ( gBattleTypeFlags & BATTLE_TYPE_x2000000 )
{
if ( gBattleTypeFlags & BATTLE_TYPE_x80000000 )
2018-01-16 23:42:31 +01:00
position = B_POSITION_OPPONENT_RIGHT ;
2017-10-02 23:32:39 +02:00
else
2018-01-16 23:42:31 +01:00
position = B_POSITION_PLAYER_RIGHT ;
2017-10-02 23:32:39 +02:00
}
else
2018-01-16 23:42:31 +01:00
position = B_POSITION_OPPONENT_RIGHT ;
2017-10-02 23:32:39 +02:00
2018-02-06 02:46:59 +01:00
for ( gActiveBattler = 0 ; gActiveBattler < gBattlersCount ; gActiveBattler + + )
2017-10-02 23:32:39 +02:00
{
2018-02-06 02:46:59 +01:00
if ( GetBattlerPosition ( gActiveBattler ) = = position )
2017-10-02 23:32:39 +02:00
{
2018-02-06 20:48:02 +01:00
BtlController_EmitIntroTrainerBallThrow ( 0 ) ;
MarkBattlerForControllerExec ( gActiveBattler ) ;
2017-10-02 23:32:39 +02:00
}
}
gBattleMainFunc = BattleIntroRecordMonsToDex ;
}
# ifdef NONMATCHING
static void BattleIntroOpponent1SendsOutMonAnimation ( void )
{
2018-01-16 23:42:31 +01:00
u32 position ;
2017-10-02 23:32:39 +02:00
if ( ! ( gBattleTypeFlags & BATTLE_TYPE_RECORDED ) )
2018-01-16 23:42:31 +01:00
position = B_POSITION_OPPONENT_LEFT ;
2017-10-02 23:32:39 +02:00
else if ( gBattleTypeFlags & BATTLE_TYPE_x2000000 )
{
if ( gBattleTypeFlags & BATTLE_TYPE_x80000000 )
2018-01-16 23:42:31 +01:00
position = B_POSITION_OPPONENT_LEFT ;
2017-10-02 23:32:39 +02:00
else
2018-01-16 23:42:31 +01:00
position = B_POSITION_PLAYER_LEFT ;
2017-10-02 23:32:39 +02:00
}
else
2018-01-16 23:42:31 +01:00
position = B_POSITION_OPPONENT_LEFT ;
2017-10-02 23:32:39 +02:00
2018-02-06 20:48:02 +01:00
if ( gBattleControllerExecFlags )
2017-10-02 23:32:39 +02:00
return ;
2018-02-06 02:46:59 +01:00
for ( gActiveBattler = 0 ; gActiveBattler < gBattlersCount ; gActiveBattler + + )
2017-10-02 23:32:39 +02:00
{
2018-02-06 02:46:59 +01:00
if ( GetBattlerPosition ( gActiveBattler ) = = position )
2017-10-02 23:32:39 +02:00
{
2018-02-06 20:48:02 +01:00
BtlController_EmitIntroTrainerBallThrow ( 0 ) ;
MarkBattlerForControllerExec ( gActiveBattler ) ;
2017-10-02 23:32:39 +02:00
if ( gBattleTypeFlags & ( BATTLE_TYPE_MULTI | BATTLE_TYPE_TWO_OPPONENTS ) )
{
gBattleMainFunc = BattleIntroOpponent2SendsOutMonAnimation ;
return ;
}
}
}
gBattleMainFunc = BattleIntroRecordMonsToDex ;
}
# else
2018-05-12 00:24:32 +02:00
NAKED
2017-10-02 23:32:39 +02:00
static void BattleIntroOpponent1SendsOutMonAnimation ( void )
{
asm ( " .syntax unified \n \
2018-12-05 15:31:01 +01:00
push { r4 - r6 , lr } \ n \
ldr r0 , = gBattleTypeFlags \ n \
ldr r2 , [ r0 ] \ n \
movs r0 , 0x80 \ n \
lsls r0 , 17 \ n \
ands r0 , r2 \ n \
cmp r0 , 0 \ n \
beq _0803B298 \ n \
movs r0 , 0x80 \ n \
lsls r0 , 18 \ n \
ands r0 , r2 \ n \
cmp r0 , 0 \ n \
beq _0803B298 \ n \
movs r1 , 0x80 \ n \
lsls r1 , 24 \ n \
ands r1 , r2 \ n \
negs r0 , r1 \ n \
orrs r0 , r1 \ n \
lsrs r5 , r0 , 31 \ n \
b _0803B29A \ n \
. pool \ n \
2017-10-02 23:32:39 +02:00
_0803B288 : \ n \
2018-12-05 15:31:01 +01:00
ldr r1 , = gBattleMainFunc \ n \
ldr r0 , = BattleIntroOpponent2SendsOutMonAnimation \ n \
b _0803B2F0 \ n \
. pool \ n \
2017-10-02 23:32:39 +02:00
_0803B298 : \ n \
2018-12-05 15:31:01 +01:00
movs r5 , 0x1 \ n \
2017-10-02 23:32:39 +02:00
_0803B29A : \ n \
2018-12-05 15:31:01 +01:00
ldr r0 , = gBattleControllerExecFlags \ n \
ldr r2 , [ r0 ] \ n \
cmp r2 , 0 \ n \
bne _0803B2F2 \ n \
ldr r0 , = gActiveBattler \ n \
strb r2 , [ r0 ] \ n \
ldr r1 , = gBattlersCount \ n \
adds r4 , r0 , 0 \ n \
ldrb r1 , [ r1 ] \ n \
cmp r2 , r1 \ n \
bcs _0803B2EC \ n \
adds r6 , r4 , 0 \ n \
2017-10-02 23:32:39 +02:00
_0803B2B2 : \ n \
2018-12-05 15:31:01 +01:00
ldrb r0 , [ r4 ] \ n \
bl GetBattlerPosition \ n \
lsls r0 , 24 \ n \
lsrs r0 , 24 \ n \
cmp r0 , r5 \ n \
bne _0803B2D8 \ n \
movs r0 , 0 \ n \
bl BtlController_EmitIntroTrainerBallThrow \ n \
ldrb r0 , [ r4 ] \ n \
bl MarkBattlerForControllerExec \ n \
ldr r0 , = gBattleTypeFlags \ n \
ldr r0 , [ r0 ] \ n \
ldr r1 , = 0x00008040 \ n \
ands r0 , r1 \ n \
cmp r0 , 0 \ n \
bne _0803B288 \ n \
2017-10-02 23:32:39 +02:00
_0803B2D8 : \ n \
2018-12-05 15:31:01 +01:00
ldrb r0 , [ r6 ] \ n \
adds r0 , 0x1 \ n \
strb r0 , [ r6 ] \ n \
ldr r1 , = gBattlersCount \ n \
lsls r0 , 24 \ n \
lsrs r0 , 24 \ n \
ldr r4 , = gActiveBattler \ n \
ldrb r1 , [ r1 ] \ n \
cmp r0 , r1 \ n \
bcc _0803B2B2 \ n \
2017-10-02 23:32:39 +02:00
_0803B2EC : \ n \
2018-12-05 15:31:01 +01:00
ldr r1 , = gBattleMainFunc \ n \
ldr r0 , = BattleIntroRecordMonsToDex \ n \
2017-10-02 23:32:39 +02:00
_0803B2F0 : \ n \
2018-12-05 15:31:01 +01:00
str r0 , [ r1 ] \ n \
2017-10-02 23:32:39 +02:00
_0803B2F2 : \ n \
2018-12-05 15:31:01 +01:00
pop { r4 - r6 } \ n \
pop { r0 } \ n \
bx r0 \ n \
. pool \ n \
2017-10-02 23:32:39 +02:00
. syntax divided " );
}
# endif // NONMATCHING
static void BattleIntroRecordMonsToDex ( void )
{
2018-02-06 20:48:02 +01:00
if ( gBattleControllerExecFlags = = 0 )
2017-10-02 23:32:39 +02:00
{
2018-02-06 02:46:59 +01:00
for ( gActiveBattler = 0 ; gActiveBattler < gBattlersCount ; gActiveBattler + + )
2017-10-02 23:32:39 +02:00
{
2018-02-06 02:46:59 +01:00
if ( GetBattlerSide ( gActiveBattler ) = = B_SIDE_OPPONENT
2017-10-02 23:32:39 +02:00
& & ! ( gBattleTypeFlags & ( BATTLE_TYPE_EREADER_TRAINER
| BATTLE_TYPE_FRONTIER
| BATTLE_TYPE_LINK
| BATTLE_TYPE_x2000000
2018-09-20 22:00:00 +02:00
| BATTLE_TYPE_TRAINER_HILL ) ) )
2017-10-02 23:32:39 +02:00
{
2018-02-06 02:46:59 +01:00
HandleSetPokedexFlag ( SpeciesToNationalPokedexNum ( gBattleMons [ gActiveBattler ] . species ) , FLAG_SET_SEEN , gBattleMons [ gActiveBattler ] . personality ) ;
2017-10-02 23:32:39 +02:00
}
}
gBattleMainFunc = BattleIntroPrintPlayerSendsOut ;
}
}
void sub_803B3AC ( void ) // unused
{
2018-02-06 20:48:02 +01:00
if ( gBattleControllerExecFlags = = 0 )
2017-10-02 23:32:39 +02:00
gBattleMainFunc = BattleIntroPrintPlayerSendsOut ;
}
static void BattleIntroPrintPlayerSendsOut ( void )
{
2018-02-06 20:48:02 +01:00
if ( gBattleControllerExecFlags = = 0 )
2017-10-02 23:32:39 +02:00
{
2018-01-16 23:42:31 +01:00
u8 position ;
2017-10-02 23:32:39 +02:00
if ( ! ( gBattleTypeFlags & BATTLE_TYPE_RECORDED ) )
2018-01-16 23:42:31 +01:00
position = B_POSITION_PLAYER_LEFT ;
2017-10-02 23:32:39 +02:00
else if ( gBattleTypeFlags & BATTLE_TYPE_x2000000 )
{
if ( gBattleTypeFlags & BATTLE_TYPE_x80000000 )
2018-01-16 23:42:31 +01:00
position = B_POSITION_PLAYER_LEFT ;
2017-10-02 23:32:39 +02:00
else
2018-01-16 23:42:31 +01:00
position = B_POSITION_OPPONENT_LEFT ;
2017-10-02 23:32:39 +02:00
}
else
2018-01-16 23:42:31 +01:00
position = B_POSITION_PLAYER_LEFT ;
2017-10-02 23:32:39 +02:00
if ( ! ( gBattleTypeFlags & BATTLE_TYPE_SAFARI ) )
2018-02-06 02:46:59 +01:00
PrepareStringBattle ( STRINGID_INTROSENDOUT , GetBattlerAtPosition ( position ) ) ;
2017-10-02 23:32:39 +02:00
gBattleMainFunc = BattleIntroPlayer1SendsOutMonAnimation ;
}
}
static void BattleIntroPlayer2SendsOutMonAnimation ( void )
{
2018-01-16 23:42:31 +01:00
u32 position ;
2017-10-02 23:32:39 +02:00
if ( ! ( gBattleTypeFlags & BATTLE_TYPE_RECORDED ) )
2018-01-16 23:42:31 +01:00
position = B_POSITION_PLAYER_RIGHT ;
2017-10-02 23:32:39 +02:00
else if ( gBattleTypeFlags & BATTLE_TYPE_x2000000 )
{
if ( gBattleTypeFlags & BATTLE_TYPE_x80000000 )
2018-01-16 23:42:31 +01:00
position = B_POSITION_PLAYER_RIGHT ;
2017-10-02 23:32:39 +02:00
else
2018-01-16 23:42:31 +01:00
position = B_POSITION_OPPONENT_RIGHT ;
2017-10-02 23:32:39 +02:00
}
else
2018-01-16 23:42:31 +01:00
position = B_POSITION_PLAYER_RIGHT ;
2017-10-02 23:32:39 +02:00
2018-02-06 02:46:59 +01:00
for ( gActiveBattler = 0 ; gActiveBattler < gBattlersCount ; gActiveBattler + + )
2017-10-02 23:32:39 +02:00
{
2018-02-06 02:46:59 +01:00
if ( GetBattlerPosition ( gActiveBattler ) = = position )
2017-10-02 23:32:39 +02:00
{
2018-02-06 20:48:02 +01:00
BtlController_EmitIntroTrainerBallThrow ( 0 ) ;
MarkBattlerForControllerExec ( gActiveBattler ) ;
2017-10-02 23:32:39 +02:00
}
}
gBattleStruct - > switchInAbilitiesCounter = 0 ;
gBattleStruct - > switchInItemsCounter = 0 ;
gBattleStruct - > overworldWeatherDone = FALSE ;
gBattleMainFunc = TryDoEventsBeforeFirstTurn ;
}
static void BattleIntroPlayer1SendsOutMonAnimation ( void )
{
2018-01-16 23:42:31 +01:00
u32 position ;
2017-10-02 23:32:39 +02:00
if ( ! ( gBattleTypeFlags & BATTLE_TYPE_RECORDED ) )
2018-01-16 23:42:31 +01:00
position = B_POSITION_PLAYER_LEFT ;
2017-10-02 23:32:39 +02:00
else if ( gBattleTypeFlags & BATTLE_TYPE_x2000000 )
{
if ( gBattleTypeFlags & BATTLE_TYPE_x80000000 )
2018-01-16 23:42:31 +01:00
position = B_POSITION_PLAYER_LEFT ;
2017-10-02 23:32:39 +02:00
else
2018-01-16 23:42:31 +01:00
position = B_POSITION_OPPONENT_LEFT ;
2017-10-02 23:32:39 +02:00
}
else
2018-01-16 23:42:31 +01:00
position = B_POSITION_PLAYER_LEFT ;
2017-10-02 23:32:39 +02:00
2018-02-06 20:48:02 +01:00
if ( gBattleControllerExecFlags )
2017-10-02 23:32:39 +02:00
return ;
2018-02-06 02:46:59 +01:00
for ( gActiveBattler = 0 ; gActiveBattler < gBattlersCount ; gActiveBattler + + )
2017-10-02 23:32:39 +02:00
{
2018-02-06 02:46:59 +01:00
if ( GetBattlerPosition ( gActiveBattler ) = = position )
2017-10-02 23:32:39 +02:00
{
2018-02-06 20:48:02 +01:00
BtlController_EmitIntroTrainerBallThrow ( 0 ) ;
MarkBattlerForControllerExec ( gActiveBattler ) ;
2017-10-02 23:32:39 +02:00
if ( gBattleTypeFlags & ( BATTLE_TYPE_MULTI ) )
{
gBattleMainFunc = BattleIntroPlayer2SendsOutMonAnimation ;
return ;
}
}
}
gBattleStruct - > switchInAbilitiesCounter = 0 ;
gBattleStruct - > switchInItemsCounter = 0 ;
gBattleStruct - > overworldWeatherDone = FALSE ;
gBattleMainFunc = TryDoEventsBeforeFirstTurn ;
}
void sub_803B598 ( void ) // unused
{
2018-02-06 20:48:02 +01:00
if ( gBattleControllerExecFlags = = 0 )
2017-10-02 23:32:39 +02:00
{
2018-02-06 02:46:59 +01:00
for ( gActiveBattler = 0 ; gActiveBattler < gBattlersCount ; gActiveBattler + + )
2017-10-02 23:32:39 +02:00
{
2018-02-06 02:46:59 +01:00
if ( GetBattlerSide ( gActiveBattler ) = = B_SIDE_PLAYER )
2017-10-02 23:32:39 +02:00
{
2018-02-06 20:48:02 +01:00
BtlController_EmitSwitchInAnim ( 0 , gBattlerPartyIndexes [ gActiveBattler ] , FALSE ) ;
MarkBattlerForControllerExec ( gActiveBattler ) ;
2017-10-02 23:32:39 +02:00
}
}
gBattleStruct - > switchInAbilitiesCounter = 0 ;
gBattleStruct - > switchInItemsCounter = 0 ;
gBattleStruct - > overworldWeatherDone = FALSE ;
gBattleMainFunc = TryDoEventsBeforeFirstTurn ;
}
}
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 ;
2019-08-23 14:46:21 +02:00
gBattleScripting . moveendState = 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-08-03 00:13:44 +02:00
if ( DoFieldEndTurnEffects ( ) )
2017-10-02 23:32:39 +02:00
return ;
2018-08-03 00:13:44 +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 ;
2019-08-23 14:46:21 +02:00
gBattleScripting . moveendState = 0 ;
2017-10-02 23:32:39 +02:00
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 )
{
2019-09-03 21:08:25 +02:00
gCurrentActionFuncId = B_ACTION_FINISHED ;
2017-10-06 00:12:01 +02:00
gBattleMainFunc = RunTurnActionsFunctions ;
2017-10-02 23:32:39 +02:00
return ;
}
2018-12-05 15:31:01 +01:00
if ( gBattleResults . battleTurnCounter < 0xFF )
2017-10-02 23:32:39 +02:00
{
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-08-03 00:13:44 +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 )
2020-07-17 02:12:12 +02:00
BattleScriptExecute ( BattleScript_PalacePrintFlavorText ) ;
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 ) ;
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
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 ;
}
}
2018-07-01 12:16:52 +02:00
i = AbilityBattleEffects ( ABILITYEFFECT_CHECK_FIELD_EXCEPT_BATTLER , gActiveBattler , ABILITY_MAGNET_PULL , 0 , 0 ) ;
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 ;
}
if ( gBattleTypeFlags & BATTLE_TYPE_FIRST_BATTLE )
{
gBattleCommunication [ MULTISTRING_CHOOSER ] = 1 ;
return 1 ;
}
return 0 ;
}
2017-10-03 21:35:27 +02:00
2019-10-26 03:55:01 +02:00
void SwitchPartyOrder ( u8 battler )
2017-10-03 21:35:27 +02:00
{
s32 i ;
2019-10-26 03:55:01 +02:00
u8 partyId1 ;
u8 partyId2 ;
2017-10-03 21:35:27 +02:00
2018-02-06 23:09:39 +01:00
// gBattleStruct->field_60[battler][i]
2017-10-03 21:35:27 +02:00
2019-10-18 01:22:03 +02:00
for ( i = 0 ; i < ( int ) ARRAY_COUNT ( gBattlePartyCurrentOrder ) ; i + + )
gBattlePartyCurrentOrder [ i ] = * ( battler * 3 + i + ( u8 * ) ( gBattleStruct - > field_60 ) ) ;
2017-10-03 21:35:27 +02:00
2019-10-26 03:55:01 +02:00
partyId1 = GetPartyIdFromBattlePartyId ( gBattlerPartyIndexes [ battler ] ) ;
partyId2 = GetPartyIdFromBattlePartyId ( * ( gBattleStruct - > monToSwitchIntoId + battler ) ) ;
SwitchPartyMonSlots ( partyId1 , partyId2 ) ;
2017-10-03 21:35:27 +02:00
if ( gBattleTypeFlags & BATTLE_TYPE_DOUBLE )
{
2019-10-18 01:22:03 +02:00
for ( i = 0 ; i < ( int ) ARRAY_COUNT ( gBattlePartyCurrentOrder ) ; i + + )
2017-10-03 21:35:27 +02:00
{
2019-10-18 01:22:03 +02:00
* ( battler * 3 + i + ( u8 * ) ( gBattleStruct - > field_60 ) ) = gBattlePartyCurrentOrder [ i ] ;
* ( BATTLE_PARTNER ( battler ) * 3 + i + ( u8 * ) ( gBattleStruct - > field_60 ) ) = gBattlePartyCurrentOrder [ i ] ;
2017-10-03 21:35:27 +02:00
}
}
else
{
2019-10-18 01:22:03 +02:00
for ( i = 0 ; i < ( int ) ARRAY_COUNT ( gBattlePartyCurrentOrder ) ; i + + )
2017-10-03 21:35:27 +02:00
{
2019-10-18 01:22:03 +02:00
* ( battler * 3 + i + ( u8 * ) ( gBattleStruct - > field_60 ) ) = gBattlePartyCurrentOrder [ 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
}
else
{
2018-02-06 23:09:39 +01:00
BtlController_EmitChooseAction ( 0 , gChosenActionByBattler [ 0 ] , gBattleBufferB [ 0 ] [ 1 ] | ( gBattleBufferB [ 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
{
2018-02-06 20:48:02 +01:00
RecordedBattle_SetBattlerAction ( gActiveBattler , gBattleBufferB [ gActiveBattler ] [ 1 ] ) ;
2018-02-06 23:09:39 +01:00
gChosenActionByBattler [ gActiveBattler ] = gBattleBufferB [ gActiveBattler ] [ 1 ] ;
2017-10-03 21:35:27 +02:00
2018-02-06 02:46:59 +01:00
switch ( gBattleBufferB [ 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 ;
* ( gBattleStruct - > moveTarget + gActiveBattler ) = gBattleBufferB [ 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-02-06 02:46:59 +01:00
moveInfo . species = gBattleMons [ gActiveBattler ] . species ;
moveInfo . monType1 = gBattleMons [ gActiveBattler ] . type1 ;
moveInfo . monType2 = gBattleMons [ gActiveBattler ] . type2 ;
2017-10-03 21:35:27 +02:00
2019-09-08 18:21:24 +02:00
for ( i = 0 ; i < MAX_MON_MOVES ; i + + )
2017-10-03 21:35:27 +02:00
{
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
{
2019-10-18 01:22:03 +02:00
BtlController_EmitChoosePokemon ( 0 , PARTY_ACTION_CANT_SWITCH , PARTY_SIZE , ABILITY_NONE , gBattleStruct - > field_60 [ gActiveBattler ] ) ;
2017-10-03 21:35:27 +02:00
}
2018-07-01 12:16:52 +02:00
else if ( ( i = ABILITY_ON_OPPOSING_FIELD ( gActiveBattler , ABILITY_SHADOW_TAG ) )
| | ( ( i = ABILITY_ON_OPPOSING_FIELD ( 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 )
2018-07-01 12:16:52 +02:00
| | ( ( i = AbilityBattleEffects ( ABILITYEFFECT_CHECK_FIELD_EXCEPT_BATTLER , gActiveBattler , ABILITY_MAGNET_PULL , 0 , 0 ) )
2018-03-01 00:59:52 +01:00
& & IS_BATTLER_OF_TYPE ( gActiveBattler , TYPE_STEEL ) ) )
2017-10-03 21:35:27 +02:00
{
2019-10-18 01:22:03 +02:00
BtlController_EmitChoosePokemon ( 0 , ( ( i - 1 ) < < 4 ) | PARTY_ACTION_ABILITY_PREVENTS , PARTY_SIZE , 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 )
2019-10-18 01:22:03 +02:00
BtlController_EmitChoosePokemon ( 0 , PARTY_ACTION_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 )
2019-10-18 01:22:03 +02:00
BtlController_EmitChoosePokemon ( 0 , PARTY_ACTION_CHOOSE_MON , * ( gBattleStruct - > monToSwitchIntoId + 1 ) , ABILITY_NONE , gBattleStruct - > field_60 [ gActiveBattler ] ) ;
2017-10-03 21:35:27 +02:00
else
2019-10-18 01:22:03 +02:00
BtlController_EmitChoosePokemon ( 0 , PARTY_ACTION_CHOOSE_MON , PARTY_SIZE , 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-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 ;
}
if ( gBattleTypeFlags & BATTLE_TYPE_TRAINER
2018-09-20 22:00:00 +02:00
& & gBattleTypeFlags & ( BATTLE_TYPE_FRONTIER | BATTLE_TYPE_TRAINER_HILL )
2018-02-06 23:09:39 +01:00
& & gBattleBufferB [ 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 ) )
2018-02-06 23:09:39 +01:00
& & gBattleBufferB [ 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 ( )
2018-02-06 23:09:39 +01:00
& & gBattleBufferB [ 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 :
2018-02-06 02:46:59 +01:00
switch ( gBattleBufferB [ gActiveBattler ] [ 1 ] )
2017-10-03 21:35:27 +02:00
{
case 3 :
case 4 :
case 5 :
case 6 :
case 7 :
case 8 :
case 9 :
2018-02-06 23:09:39 +01:00
gChosenActionByBattler [ gActiveBattler ] = gBattleBufferB [ 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 ) ;
2018-12-05 15:31:01 +01:00
if ( ( gBattleBufferB [ gActiveBattler ] [ 2 ] | ( gBattleBufferB [ 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 ;
2020-03-18 02:11:14 +01:00
gBattleBufferB [ gActiveBattler ] [ 1 ] = B_ACTION_USE_MOVE ;
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 ) )
{
2018-02-06 20:48:02 +01:00
RecordedBattle_SetBattlerAction ( gActiveBattler , gBattleBufferB [ gActiveBattler ] [ 2 ] ) ;
RecordedBattle_SetBattlerAction ( gActiveBattler , gBattleBufferB [ gActiveBattler ] [ 3 ] ) ;
2017-10-03 21:35:27 +02:00
}
2018-02-06 02:46:59 +01:00
* ( gBattleStruct - > chosenMovePositions + gActiveBattler ) = gBattleBufferB [ gActiveBattler ] [ 2 ] ;
2018-02-06 23:09:39 +01:00
gChosenMoveByBattler [ gActiveBattler ] = gBattleMons [ gActiveBattler ] . moves [ * ( gBattleStruct - > chosenMovePositions + gActiveBattler ) ] ;
2018-02-06 02:46:59 +01:00
* ( gBattleStruct - > moveTarget + gActiveBattler ) = gBattleBufferB [ gActiveBattler ] [ 3 ] ;
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 :
2018-02-06 02:46:59 +01:00
if ( ( gBattleBufferB [ gActiveBattler ] [ 1 ] | ( gBattleBufferB [ 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
{
2018-02-06 02:46:59 +01:00
gLastUsedItem = ( gBattleBufferB [ gActiveBattler ] [ 1 ] | ( gBattleBufferB [ gActiveBattler ] [ 2 ] < < 8 ) ) ;
gBattleCommunication [ gActiveBattler ] + + ;
2017-10-03 21:35:27 +02:00
}
break ;
2018-02-06 23:09:39 +01:00
case B_ACTION_SWITCH :
2018-06-28 21:06:32 +02:00
if ( gBattleBufferB [ 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 :
2018-02-06 02:46:59 +01:00
if ( ( gBattleBufferB [ gActiveBattler ] [ 1 ] | ( gBattleBufferB [ 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 ;
}
}
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
{
2020-03-18 02:11:14 +01:00
if ( gBattleBufferB [ gActiveBattler ] [ 1 ] = = B_ACTION_NOTHING_FAINTED )
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 )
2019-10-26 03:55:01 +02:00
SwitchPartyOrderInGameMulti ( 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
{
2018-02-06 02:46:59 +01:00
* ( gBattleStruct - > monToSwitchIntoId + gActiveBattler ) = gBattleBufferB [ gActiveBattler ] [ 1 ] ;
2018-02-06 20:48:02 +01:00
RecordedBattle_SetBattlerAction ( gActiveBattler , gBattleBufferB [ 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 ;
* ( gActiveBattler * 3 + ( u8 * ) ( gBattleStruct - > field_60 ) + 0 ) | = ( gBattleBufferB [ gActiveBattler ] [ 2 ] & 0xF0 ) ;
* ( gActiveBattler * 3 + ( u8 * ) ( gBattleStruct - > field_60 ) + 1 ) = gBattleBufferB [ 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 ) ;
* ( ( gActiveBattler ^ BIT_FLANK ) * 3 + ( u8 * ) ( gBattleStruct - > field_60 ) + 0 ) | = ( gBattleBufferB [ gActiveBattler ] [ 2 ] & 0xF0 ) > > 4 ;
* ( ( gActiveBattler ^ BIT_FLANK ) * 3 + ( u8 * ) ( gBattleStruct - > field_60 ) + 2 ) = gBattleBufferB [ 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-20 11:55: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-02-08 11:17:41 +01:00
u8 GetWhoStrikesFirst ( u8 battler1 , u8 battler2 , bool8 ignoreChosenMoves )
2017-10-04 19:25:14 +02:00
{
u8 strikesFirst = 0 ;
2018-02-08 11:17:41 +01:00
u8 speedMultiplierBattler1 = 0 , speedMultiplierBattler2 = 0 ;
u32 speedBattler1 = 0 , speedBattler2 = 0 ;
2017-10-04 19:25:14 +02:00
u8 holdEffect = 0 ;
u8 holdEffectParam = 0 ;
2018-02-08 11:17:41 +01:00
u16 moveBattler1 = 0 , moveBattler2 = 0 ;
2017-10-04 19:25:14 +02:00
if ( WEATHER_HAS_EFFECT )
{
2018-02-08 11:17:41 +01:00
if ( ( gBattleMons [ battler1 ] . ability = = ABILITY_SWIFT_SWIM & & gBattleWeather & WEATHER_RAIN_ANY )
| | ( gBattleMons [ battler1 ] . ability = = ABILITY_CHLOROPHYLL & & gBattleWeather & WEATHER_SUN_ANY ) )
speedMultiplierBattler1 = 2 ;
2017-10-04 19:25:14 +02:00
else
2018-02-08 11:17:41 +01:00
speedMultiplierBattler1 = 1 ;
2017-10-04 19:25:14 +02:00
2018-02-08 11:17:41 +01:00
if ( ( gBattleMons [ battler2 ] . ability = = ABILITY_SWIFT_SWIM & & gBattleWeather & WEATHER_RAIN_ANY )
| | ( gBattleMons [ battler2 ] . ability = = ABILITY_CHLOROPHYLL & & gBattleWeather & WEATHER_SUN_ANY ) )
speedMultiplierBattler2 = 2 ;
2017-10-04 19:25:14 +02:00
else
2018-02-08 11:17:41 +01:00
speedMultiplierBattler2 = 1 ;
2017-10-04 19:25:14 +02:00
}
else
{
2018-02-08 11:17:41 +01:00
speedMultiplierBattler1 = 1 ;
speedMultiplierBattler2 = 1 ;
2017-10-04 19:25:14 +02:00
}
2018-02-08 11:17:41 +01:00
speedBattler1 = ( gBattleMons [ battler1 ] . speed * speedMultiplierBattler1 )
2018-02-08 12:13:29 +01:00
* ( gStatStageRatios [ gBattleMons [ battler1 ] . statStages [ STAT_SPEED ] ] [ 0 ] )
/ ( gStatStageRatios [ gBattleMons [ battler1 ] . statStages [ STAT_SPEED ] ] [ 1 ] ) ;
2017-10-04 19:25:14 +02:00
2018-02-08 11:17:41 +01:00
if ( gBattleMons [ battler1 ] . item = = ITEM_ENIGMA_BERRY )
2017-10-04 19:25:14 +02:00
{
2018-02-08 11:17:41 +01:00
holdEffect = gEnigmaBerries [ battler1 ] . holdEffect ;
holdEffectParam = gEnigmaBerries [ battler1 ] . holdEffectParam ;
2017-10-04 19:25:14 +02:00
}
else
{
2018-02-08 11:17:41 +01:00
holdEffect = ItemId_GetHoldEffect ( gBattleMons [ battler1 ] . item ) ;
holdEffectParam = ItemId_GetHoldEffectParam ( gBattleMons [ battler1 ] . item ) ;
2017-10-04 19:25:14 +02:00
}
// badge boost
if ( ! ( gBattleTypeFlags & ( BATTLE_TYPE_LINK | BATTLE_TYPE_x2000000 | BATTLE_TYPE_FRONTIER ) )
2017-11-08 22:20:10 +01:00
& & FlagGet ( FLAG_BADGE03_GET )
2018-02-08 11:17:41 +01:00
& & GetBattlerSide ( battler1 ) = = B_SIDE_PLAYER )
2017-10-04 19:25:14 +02:00
{
2018-02-08 11:17:41 +01:00
speedBattler1 = ( speedBattler1 * 110 ) / 100 ;
2017-10-04 19:25:14 +02:00
}
if ( holdEffect = = HOLD_EFFECT_MACHO_BRACE )
2018-02-08 11:17:41 +01:00
speedBattler1 / = 2 ;
2017-10-04 19:25:14 +02:00
2018-02-08 11:17:41 +01:00
if ( gBattleMons [ battler1 ] . status1 & STATUS1_PARALYSIS )
speedBattler1 / = 4 ;
2017-10-04 19:25:14 +02:00
if ( holdEffect = = HOLD_EFFECT_QUICK_CLAW & & gRandomTurnNumber < ( 0xFFFF * holdEffectParam ) / 100 )
2018-02-08 11:17:41 +01:00
speedBattler1 = UINT_MAX ;
2017-10-04 19:25:14 +02:00
2018-02-08 11:17:41 +01:00
// check second battlerId's speed
2017-10-04 19:25:14 +02:00
2018-02-08 11:17:41 +01:00
speedBattler2 = ( gBattleMons [ battler2 ] . speed * speedMultiplierBattler2 )
2018-02-08 12:13:29 +01:00
* ( gStatStageRatios [ gBattleMons [ battler2 ] . statStages [ STAT_SPEED ] ] [ 0 ] )
/ ( gStatStageRatios [ gBattleMons [ battler2 ] . statStages [ STAT_SPEED ] ] [ 1 ] ) ;
2017-10-04 19:25:14 +02:00
2018-02-08 11:17:41 +01:00
if ( gBattleMons [ battler2 ] . item = = ITEM_ENIGMA_BERRY )
2017-10-04 19:25:14 +02:00
{
2018-02-08 11:17:41 +01:00
holdEffect = gEnigmaBerries [ battler2 ] . holdEffect ;
holdEffectParam = gEnigmaBerries [ battler2 ] . holdEffectParam ;
2017-10-04 19:25:14 +02:00
}
else
{
2018-02-08 11:17:41 +01:00
holdEffect = ItemId_GetHoldEffect ( gBattleMons [ battler2 ] . item ) ;
holdEffectParam = ItemId_GetHoldEffectParam ( gBattleMons [ battler2 ] . item ) ;
2017-10-04 19:25:14 +02:00
}
// badge boost
if ( ! ( gBattleTypeFlags & ( BATTLE_TYPE_LINK | BATTLE_TYPE_x2000000 | BATTLE_TYPE_FRONTIER ) )
2017-11-08 22:20:10 +01:00
& & FlagGet ( FLAG_BADGE03_GET )
2018-02-08 11:17:41 +01:00
& & GetBattlerSide ( battler2 ) = = B_SIDE_PLAYER )
2017-10-04 19:25:14 +02:00
{
2018-02-08 11:17:41 +01:00
speedBattler2 = ( speedBattler2 * 110 ) / 100 ;
2017-10-04 19:25:14 +02:00
}
if ( holdEffect = = HOLD_EFFECT_MACHO_BRACE )
2018-02-08 11:17:41 +01:00
speedBattler2 / = 2 ;
2017-10-04 19:25:14 +02:00
2018-02-08 11:17:41 +01:00
if ( gBattleMons [ battler2 ] . status1 & STATUS1_PARALYSIS )
speedBattler2 / = 4 ;
2017-10-04 19:25:14 +02:00
if ( holdEffect = = HOLD_EFFECT_QUICK_CLAW & & gRandomTurnNumber < ( 0xFFFF * holdEffectParam ) / 100 )
2018-02-08 11:17:41 +01:00
speedBattler2 = UINT_MAX ;
2017-10-04 19:25:14 +02:00
if ( ignoreChosenMoves )
{
2018-02-08 11:17:41 +01:00
moveBattler1 = MOVE_NONE ;
moveBattler2 = MOVE_NONE ;
2017-10-04 19:25:14 +02:00
}
else
{
2018-02-08 11:17:41 +01:00
if ( gChosenActionByBattler [ battler1 ] = = B_ACTION_USE_MOVE )
2017-10-04 19:25:14 +02:00
{
2018-07-07 19:57:09 +02:00
if ( gProtectStructs [ battler1 ] . noValidMoves )
2018-02-08 11:17:41 +01:00
moveBattler1 = MOVE_STRUGGLE ;
2017-10-04 19:25:14 +02:00
else
2018-02-08 11:17:41 +01:00
moveBattler1 = gBattleMons [ battler1 ] . moves [ * ( gBattleStruct - > chosenMovePositions + battler1 ) ] ;
2017-10-04 19:25:14 +02:00
}
else
2018-02-08 11:17:41 +01:00
moveBattler1 = MOVE_NONE ;
2017-10-04 19:25:14 +02:00
2018-02-08 11:17:41 +01:00
if ( gChosenActionByBattler [ battler2 ] = = B_ACTION_USE_MOVE )
2017-10-04 19:25:14 +02:00
{
2018-07-07 19:57:09 +02:00
if ( gProtectStructs [ battler2 ] . noValidMoves )
2018-02-08 11:17:41 +01:00
moveBattler2 = MOVE_STRUGGLE ;
2017-10-04 19:25:14 +02:00
else
2018-02-08 11:17:41 +01:00
moveBattler2 = gBattleMons [ battler2 ] . moves [ * ( gBattleStruct - > chosenMovePositions + battler2 ) ] ;
2017-10-04 19:25:14 +02:00
}
else
2018-02-08 11:17:41 +01:00
moveBattler2 = MOVE_NONE ;
2017-10-04 19:25:14 +02:00
}
// both move priorities are different than 0
2018-02-08 11:17:41 +01:00
if ( gBattleMoves [ moveBattler1 ] . priority ! = 0 | | gBattleMoves [ moveBattler2 ] . priority ! = 0 )
2017-10-04 19:25:14 +02:00
{
// both priorities are the same
2018-02-08 11:17:41 +01:00
if ( gBattleMoves [ moveBattler1 ] . priority = = gBattleMoves [ moveBattler2 ] . priority )
2017-10-04 19:25:14 +02:00
{
2018-02-08 11:17:41 +01:00
if ( speedBattler1 = = speedBattler2 & & Random ( ) & 1 )
2017-10-04 19:25:14 +02:00
strikesFirst = 2 ; // same speeds, same priorities
2018-02-08 11:17:41 +01:00
else if ( speedBattler1 < speedBattler2 )
strikesFirst = 1 ; // battler2 has more speed
2017-10-04 19:25:14 +02:00
2018-02-08 11:17:41 +01:00
// else battler1 has more speed
2017-10-04 19:25:14 +02:00
}
2018-02-08 11:17:41 +01:00
else if ( gBattleMoves [ moveBattler1 ] . priority < gBattleMoves [ moveBattler2 ] . priority )
strikesFirst = 1 ; // battler2's move has greater priority
2017-10-04 19:25:14 +02:00
2018-02-08 11:17:41 +01:00
// else battler1's move has greater priority
2017-10-04 19:25:14 +02:00
}
// both priorities are equal to 0
else
{
2018-02-08 11:17:41 +01:00
if ( speedBattler1 = = speedBattler2 & & Random ( ) & 1 )
2017-10-04 19:25:14 +02:00
strikesFirst = 2 ; // same speeds, same priorities
2018-02-08 11:17:41 +01:00
else if ( speedBattler1 < speedBattler2 )
strikesFirst = 1 ; // battler2 has more speed
2017-10-04 19:25:14 +02:00
2018-02-08 11:17:41 +01:00
// else battler1 has more speed
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
}
}
2017-10-06 00:12:01 +02:00
gBattleMainFunc = CheckFocusPunch_ClearVarsBeforeTurnStarts ;
2018-02-07 22:53:40 +01:00
gBattleStruct - > focusPunchBattlerId = 0 ;
2017-10-04 19:25:14 +02:00
return ;
}
2020-08-28 17:59:16 +02:00
for ( gActiveBattler = 0 ; gActiveBattler < gBattlersCount ; gActiveBattler + + )
2017-10-04 19:25:14 +02:00
{
2020-08-28 17:59:16 +02:00
if ( gChosenActionByBattler [ gActiveBattler ] = = B_ACTION_USE_ITEM | | gChosenActionByBattler [ gActiveBattler ] = = B_ACTION_SWITCH )
2017-10-04 19:25:14 +02:00
{
2020-08-28 17:59:16 +02:00
gActionsByTurnOrder [ turnOrderId ] = gChosenActionByBattler [ gActiveBattler ] ;
gBattlerByTurnOrder [ turnOrderId ] = gActiveBattler ;
turnOrderId + + ;
2017-10-04 19:25:14 +02:00
}
2020-08-28 17:59:16 +02:00
}
for ( gActiveBattler = 0 ; gActiveBattler < gBattlersCount ; gActiveBattler + + )
{
if ( gChosenActionByBattler [ gActiveBattler ] ! = B_ACTION_USE_ITEM & & gChosenActionByBattler [ gActiveBattler ] ! = B_ACTION_SWITCH )
2017-10-04 19:25:14 +02:00
{
2020-08-28 17:59:16 +02:00
gActionsByTurnOrder [ turnOrderId ] = gChosenActionByBattler [ gActiveBattler ] ;
gBattlerByTurnOrder [ turnOrderId ] = gActiveBattler ;
turnOrderId + + ;
2017-10-04 19:25:14 +02:00
}
2020-08-28 17:59:16 +02:00
}
for ( i = 0 ; i < gBattlersCount - 1 ; i + + )
{
for ( j = i + 1 ; j < gBattlersCount ; j + + )
2017-10-04 19:25:14 +02:00
{
2020-08-28 17:59:16 +02:00
u8 battler1 = gBattlerByTurnOrder [ i ] ;
u8 battler2 = gBattlerByTurnOrder [ j ] ;
2020-08-28 20:35:37 +02: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
{
2020-08-28 17:59:16 +02:00
if ( GetWhoStrikesFirst ( battler1 , battler2 , FALSE ) )
SwapTurnOrder ( i , j ) ;
2017-10-04 19:25:14 +02:00
}
}
}
}
2017-10-06 00:12:01 +02:00
gBattleMainFunc = CheckFocusPunch_ClearVarsBeforeTurnStarts ;
2018-02-07 22:53:40 +01:00
gBattleStruct - > focusPunchBattlerId = 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 ;
u8 * dataPtr ;
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 ;
gProtectStructs [ gActiveBattler ] . endured = 0 ;
2017-10-06 00:12:01 +02:00
}
else
{
2018-02-06 02:46:59 +01:00
dataPtr = ( u8 * ) ( & gProtectStructs [ gActiveBattler ] ) ;
2017-10-06 00:12:01 +02:00
for ( i = 0 ; i < sizeof ( struct ProtectStruct ) ; i + + )
dataPtr [ i ] = 0 ;
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
}
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
{
2018-02-06 02:46:59 +01:00
for ( gActiveBattler = 0 ; gActiveBattler < gBattlersCount ; gActiveBattler + + )
2017-10-06 00:12:01 +02:00
{
s32 i ;
2018-02-06 02:46:59 +01:00
u8 * dataPtr = ( u8 * ) ( & gSpecialStatuses [ gActiveBattler ] ) ;
2017-10-06 00:12:01 +02:00
for ( i = 0 ; i < sizeof ( struct SpecialStatus ) ; i + + )
dataPtr [ i ] = 0 ;
}
}
static void CheckFocusPunch_ClearVarsBeforeTurnStarts ( void )
{
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 ;
}
}
}
TryClearRageStatuses ( ) ;
2020-08-27 02:27:18 +02:00
gCurrentTurnActionNumber = 0 ; //See comment underneath
2020-08-28 17:52:48 +02:00
gCurrentActionFuncId = gActionsByTurnOrder [ gCurrentTurnActionNumber ] ; //Should be gActionsByTurnOrder[(gCurrentTurnActionNumber = 0)], but that doesn't match
2017-10-06 00:12:01 +02:00
gDynamicBasePower = 0 ;
gBattleStruct - > dynamicMoveType = 0 ;
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 )
2019-09-03 21:08:25 +02:00
gCurrentActionFuncId = B_ACTION_FINISHED ;
2017-10-06 00:12:01 +02:00
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
}
2020-08-28 17:59:16 +02:00
else if ( gBattleStruct - > savedTurnActionNumber ! = gCurrentTurnActionNumber ) // action turn has been done, clear hitmarker bits for another battlerId
2017-10-06 00:12:01 +02:00
{
2020-08-28 17:59:16 +02:00
gHitMarker & = ~ ( HITMARKER_NO_ATTACKSTRING ) ;
gHitMarker & = ~ ( HITMARKER_UNABLE_TO_USE_MOVE ) ;
2017-10-06 00:12:01 +02:00
}
}
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 )
2020-08-21 00:02:00 +02:00
PlayBGM ( MUS_VICTORY_GYM_LEADER ) ;
2017-10-06 00:12:01 +02:00
else
2020-08-21 00:02:00 +02:00
PlayBGM ( MUS_VICTORY_TRAINER ) ;
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 :
2020-08-21 00:02:00 +02:00
PlayBGM ( MUS_VICTORY_LEAGUE ) ;
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 :
2020-08-21 00:02:00 +02:00
PlayBGM ( MUS_VICTORY_AQUA_MAGMA ) ;
2017-10-06 00:12:01 +02:00
break ;
2017-12-17 21:19:08 +01:00
case TRAINER_CLASS_LEADER :
2020-08-21 00:02:00 +02:00
PlayBGM ( MUS_VICTORY_GYM_LEADER ) ;
2017-10-06 00:12:01 +02:00
break ;
default :
2020-08-21 00:02:00 +02:00
PlayBGM ( MUS_VICTORY_TRAINER ) ;
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 ) ;
2019-12-14 09:58:20 +01:00
gSaveBlock2Ptr - > frontier . disableRecordBattle = TRUE ;
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 ;
2019-12-14 09:58:20 +01:00
gSaveBlock2Ptr - > frontier . disableRecordBattle = TRUE ;
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
{
2019-09-03 21:08:25 +02:00
if ( gCurrentActionFuncId = = B_ACTION_TRY_FINISH | | gCurrentActionFuncId = = B_ACTION_FINISHED )
2017-10-06 00:12:01 +02:00
{
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 ) ;
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 ( ) ;
}
2020-08-21 00:02:00 +02:00
m4aSongNumStop ( SE_LOW_HEALTH ) ;
2017-10-06 00:12:01 +02:00
SetMainCallback2 ( gMain . savedCallback ) ;
}
void RunBattleScriptCommands_PopCallbacksStack ( void )
{
2019-09-03 21:08:25 +02:00
if ( gCurrentActionFuncId = = B_ACTION_TRY_FINISH | | gCurrentActionFuncId = = B_ACTION_FINISHED )
2017-10-06 00:12:01 +02:00
{
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 ] ] ( ) ;
}
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-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 ;
}
gCritMultiplier = 1 ;
gBattleScripting . dmgMultiplier = 1 ;
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-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 ;
}
// 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
& & ( gBattleMoves [ gCurrentMove ] . power ! = 0
2018-02-26 13:24:46 +01:00
| | gBattleMoves [ gCurrentMove ] . target ! = MOVE_TARGET_USER )
2018-02-06 23:09:39 +01:00
& & gBattleMons [ * ( gBattleStruct - > moveTarget + gBattlerAttacker ) ] . ability ! = ABILITY_LIGHTNING_ROD
2017-10-06 00:12:01 +02:00
& & gBattleMoves [ gCurrentMove ] . type = = TYPE_ELECTRIC )
{
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-02-06 02:46:59 +01:00
& & gBattleMons [ gActiveBattler ] . ability = = ABILITY_LIGHTNING_ROD
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
}
}
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 ) ;
gSpecialStatuses [ gActiveBattler ] . lightningRodRedirected = 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
}
}
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
}
}
}
// choose battlescript
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 ) ;
gLastUsedItem = gBattleBufferB [ gBattlerAttacker ] [ 1 ] | ( gBattleBufferB [ gBattlerAttacker ] [ 2 ] < < 8 ) ;
2017-10-06 00:12:01 +02:00
2020-07-12 07:49:32 +02:00
if ( gLastUsedItem < = LAST_BALL ) // is ball
2017-10-06 00:12:01 +02:00
{
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 )
2019-09-04 23:06:59 +02:00
PREPARE_STRING_BUFFER ( gBattleTextBuff2 , CHAR_X )
2017-10-06 00:12:01 +02:00
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
{
if ( ! ( gBattleTypeFlags & BATTLE_TYPE_DOUBLE ) )
{
if ( InBattlePyramid ( ) )
{
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 ) )
effect + + ;
}
2018-02-06 23:09:39 +01:00
else if ( gBattleMons [ battler ] . speed < gBattleMons [ BATTLE_OPPOSITE ( battler ) ] . speed )
2017-10-06 00:12:01 +02:00
{
2018-02-06 23:09:39 +01:00
speedVar = ( gBattleMons [ battler ] . speed * 128 ) / ( gBattleMons [ BATTLE_OPPOSITE ( battler ) ] . speed ) + ( gBattleStruct - > runTries * 30 ) ;
2017-10-06 00:12:01 +02:00
if ( speedVar > ( Random ( ) & 0xFF ) )
effect + + ;
}
else // same speed or faster
{
effect + + ;
}
}
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 ;
2019-12-14 09:58:20 +01:00
gSaveBlock2Ptr - > frontier . disableRecordBattle = TRUE ;
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 ;
2018-02-06 23:09:39 +01:00
gBattleCommunication [ MULTISTRING_CHOOSER ] = gBattleBufferB [ gBattlerAttacker ] [ 1 ] - 1 ;
gLastUsedItem = gBattleBufferB [ gBattlerAttacker ] [ 2 ] ;
2017-10-06 17:06:45 +02:00
2018-12-05 15:31:01 +01:00
if ( gBattleResults . pokeblockThrows < 0xFF )
2018-06-28 21:06:32 +02:00
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 ] ;
2020-08-21 00:02:00 +02:00
PlaySE ( SE_FLEE ) ;
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 ;
gDynamicBasePower = 0 ;
2019-08-23 14:46:21 +02:00
gBattleScripting . moveendState = 0 ;
2017-10-06 17:06:45 +02:00
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