Added support for XY's Sky Battles (#2950)

* Original implementation from Phlayne

* Moved Sky Battle Flag / Var into a config

* Optimized existing code and fixed existing bugs

Added error message for when sky battle var and flag are not set
Merged CanDoSkyBattle and PrepareSkyBattle into one special

* Added compatibility for Gen7+

* Commented out Volt Crash from banned moves

* Cleaned up debug scripts from testing

* Fixed bug where player did not white out even if they had no healthy Pokémon and only an egg
Zeroed out both Sky Battle configs

* Removed extra include from src/field_specials.c
Removed extra line break in src/battle_script_commands.c

* Added FLAG_DISABLED_IN_SKY_BATTLE
Added FLAG_DISABLED_IN_SKY_BATTLE to appropriate moves

* Changed DoesSkyBattleCancelCurrentMove to look at move flags

* Fixed alignment and spacing in battle_moves.h

* Added FLAG_DISABLED_IN_SKY_BATTLE to Sticky Web

* Added FLAG_DISABLED_IN_SKY_BATTLE to Steel Roller

* Disabled the ability to change Battle Terrain when Sky Battle is happening
Stopped Ceaseless Edge from spawning Spikes when Sky Battle is happening
Added B_SKY_BATTLE_STRICT_MECHANICS config

* Fixed bug with SKY_BATTLE_STRICT_MECHANICS where conditions were not consistently being applied

* Add rulesVariants to the BattleStruct
Added skyBattle check in AllocateBattleResources

* Replaced B_FLAG_SKY_BATTLE checks with rulesVariants.skyBattle checks

* Fixed debug script

* Reverted include/config/battle.h

* Fixed spacing and placement of functions

* Fixed debug script omission
Fixed bug where Spikes did not set from Ceaseless Edge and Stone Axe

* Added FLAG_DISABLED_IN_SKY_BATTLE to Psychic Terrain

* Addressed DizzyEgg PR feedback

* Forgot a file in last commit

* Addressed feedback from DizzyEggg

* Address Lunos' PR feedback

* Update specials.inc

Added an empty line at the end of data/specials.inc

* Fixed spacing

* Apply suggestions from code review

Co-authored-by: Eduardo Quezada D'Ottone <eduardo602002@gmail.com>

* Updated skyBattleBanned and HandleBattleVariantEndParty to use correct names

* Removed STRICT_MOVES and STRICT_MECHANICS

* Fixed minor spacing issues with merge

* Merged in upcoming

* Implemented feedback from Jasper
5da6117d1b

---------

Co-authored-by: Eduardo Quezada D'Ottone <eduardo602002@gmail.com>
This commit is contained in:
psf 2023-11-26 07:59:44 -08:00 committed by GitHub
parent 0fe203c7f5
commit 493478e94b
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
17 changed files with 222 additions and 6 deletions

View file

@ -95,6 +95,19 @@ Debug_BoxFilledMessage::
Debug_BoxFilledMessage_Text: Debug_BoxFilledMessage_Text:
.string "Storage boxes filled!$" .string "Storage boxes filled!$"
Debug_FlagsAndVarNotSetBattleConfigMessage::
lockall
message Debug_FlagsAndVarNotSetBattleConfigMessage_Text
waitmessage
waitbuttonpress
releaseall
end
Debug_FlagsAndVarNotSetBattleConfigMessage_Text:
.string "Feature unavailable! Please define a\n"
.string "usable flag and a usable var in:\l"
.string "'include/config/battle.h'!$"
Debug_EventScript_Script_1:: Debug_EventScript_Script_1::
end end

View file

@ -539,3 +539,4 @@ gSpecials::
def_special GetNumberSprayStrength def_special GetNumberSprayStrength
def_special GetSprayId def_special GetSprayId
def_special GetLastUsedSprayType def_special GetLastUsedSprayType
def_special TrySkyBattle

View file

@ -731,6 +731,7 @@ struct BattleStruct
u32 aiDelayFrames; // Number of frames it took to choose an action. u32 aiDelayFrames; // Number of frames it took to choose an action.
bool8 transformZeroToHero[PARTY_SIZE][NUM_BATTLE_SIDES]; bool8 transformZeroToHero[PARTY_SIZE][NUM_BATTLE_SIDES];
u8 pledgeMove:1; u8 pledgeMove:1;
bool8 isSkyBattle:1;
}; };
// The palaceFlags member of struct BattleStruct contains 1 flag per move to indicate which moves the AI should consider, // The palaceFlags member of struct BattleStruct contains 1 flag per move to indicate which moves the AI should consider,

View file

@ -27,6 +27,7 @@ s32 CalcCritChanceStage(u32 battlerAtk, u32 battlerDef, u32 move, bool32 recordA
s32 GetCritHitChance(s32 critChanceIndex); s32 GetCritHitChance(s32 critChanceIndex);
u32 GetTotalAccuracy(u32 battlerAtk, u32 battlerDef, u32 move, u32 atkAbility, u32 defAbility, u32 atkHoldEffect, u32 defHoldEffect); u32 GetTotalAccuracy(u32 battlerAtk, u32 battlerDef, u32 move, u32 atkAbility, u32 defAbility, u32 atkHoldEffect, u32 defHoldEffect);
u8 GetBattlerTurnOrderNum(u8 battlerId); u8 GetBattlerTurnOrderNum(u8 battlerId);
bool32 NoAliveMonsForPlayer(void);
bool32 NoAliveMonsForEitherParty(void); bool32 NoAliveMonsForEitherParty(void);
void SetMoveEffect(bool32 primary, u32 certain); void SetMoveEffect(bool32 primary, u32 certain);
bool32 CanBattlerSwitch(u32 battlerId); bool32 CanBattlerSwitch(u32 battlerId);
@ -52,6 +53,7 @@ void StealTargetItem(u8 battlerStealer, u8 battlerItem);
u8 GetCatchingBattler(void); u8 GetCatchingBattler(void);
u32 GetHighestStatId(u32 battlerId); u32 GetHighestStatId(u32 battlerId);
bool32 ProteanTryChangeType(u32 battler, u32 ability, u32 move, u32 moveType); bool32 ProteanTryChangeType(u32 battler, u32 ability, u32 move, u32 moveType);
bool32 IsMoveNotAllowedInSkyBattles(u32 move);
bool32 DoSwitchInAbilitiesItems(u32 battlerId); bool32 DoSwitchInAbilitiesItems(u32 battlerId);
u8 GetFirstFaintedPartyIndex(u8 battlerId); u8 GetFirstFaintedPartyIndex(u8 battlerId);
bool32 IsMoveAffectedByParentalBond(u32 move, u32 battler); bool32 IsMoveAffectedByParentalBond(u32 move, u32 battler);

View file

@ -249,5 +249,7 @@ bool32 AreBattlersOfOppositeGender(u32 battler1, u32 battler2);
bool32 AreBattlersOfSameGender(u32 battler1, u32 battler2); bool32 AreBattlersOfSameGender(u32 battler1, u32 battler2);
u32 CalcSecondaryEffectChance(u32 battler, u8 secondaryEffectChance, u16 moveEffect); u32 CalcSecondaryEffectChance(u32 battler, u8 secondaryEffectChance, u16 moveEffect);
u8 GetBattlerType(u32 battler, u8 typeIndex); u8 GetBattlerType(u32 battler, u8 typeIndex);
bool8 CanMonParticipateInSkyBattle(struct Pokemon *mon);
bool8 IsMonBannedFromSkyBattles(u16 species);
#endif // GUARD_BATTLE_UTIL_H #endif // GUARD_BATTLE_UTIL_H

View file

@ -170,6 +170,12 @@
#define VAR_TERRAIN 0 // If this var has a value, assigning a STATUS_FIELD_xx_TERRAIN to it before battle causes the battle to start with that terrain active #define VAR_TERRAIN 0 // If this var has a value, assigning a STATUS_FIELD_xx_TERRAIN to it before battle causes the battle to start with that terrain active
#define B_VAR_WILD_AI_FLAGS 0 // If not 0, you can use this var to add to default wild AI flags. NOT usable with flags above (1 << 15) #define B_VAR_WILD_AI_FLAGS 0 // If not 0, you can use this var to add to default wild AI flags. NOT usable with flags above (1 << 15)
// Sky Battles
#define B_FLAG_SKY_BATTLE 0 // If this flag has a value, the player will be able to engage in scripted Sky Battles.
#define B_VAR_SKY_BATTLE 0 // If this var has a value, the game will remember the positions of Pokémon used in Sky Battles.
#define B_SKY_BATTLE_STRICT_ELIGIBILITY FALSE //If TRUE, Sky Battles will use the eligibility from Pokémon XY. If FALSE, all Flying-types or Pokémon with Levitate are allowed.
// Flag and Var settings // Flag and Var settings
#define B_RESET_FLAGS_VARS_AFTER_WHITEOUT TRUE // If TRUE, Overworld_ResetBattleFlagsAndVars will reset battle-related Flags and Vars when the player whites out. #define B_RESET_FLAGS_VARS_AFTER_WHITEOUT TRUE // If TRUE, Overworld_ResetBattleFlagsAndVars will reset battle-related Flags and Vars when the player whites out.

View file

@ -2,6 +2,7 @@
#define GUARD_DEBUG_H #define GUARD_DEBUG_H
void Debug_ShowMainMenu(void); void Debug_ShowMainMenu(void);
extern const u8 Debug_FlagsAndVarNotSetBattleConfigMessage[];
extern EWRAM_DATA bool8 gIsDebugBattle; extern EWRAM_DATA bool8 gIsDebugBattle;
extern EWRAM_DATA u32 gDebugAIFlags; extern EWRAM_DATA u32 gDebugAIFlags;

View file

@ -31,5 +31,6 @@ bool8 UsedPokemonCenterWarp(void);
void ResetFanClub(void); void ResetFanClub(void);
bool8 ShouldShowBoxWasFullMessage(void); bool8 ShouldShowBoxWasFullMessage(void);
void SetPCBoxToSendMon(u8 boxId); void SetPCBoxToSendMon(u8 boxId);
void PreparePartyForSkyBattle(void);
#endif // GUARD_FIELD_SPECIALS_H #endif // GUARD_FIELD_SPECIALS_H

View file

@ -393,6 +393,7 @@ struct BattleMove
u32 instructBanned:1; u32 instructBanned:1;
u32 encoreBanned:1; u32 encoreBanned:1;
u32 parentalBondBanned:1; u32 parentalBondBanned:1;
u32 skyBattleBanned:1;
}; };
#define SPINDA_SPOT_WIDTH 16 #define SPINDA_SPOT_WIDTH 16

View file

@ -1256,6 +1256,11 @@ bool32 ProteanTryChangeType(u32 battler, u32 ability, u32 move, u32 moveType)
return FALSE; return FALSE;
} }
bool32 IsMoveNotAllowedInSkyBattles(u32 move)
{
return ((gBattleStruct->isSkyBattle) && (gBattleMoves[gCurrentMove].skyBattleBanned));
}
static void Cmd_attackcanceler(void) static void Cmd_attackcanceler(void)
{ {
CMD_ARGS(); CMD_ARGS();
@ -1363,9 +1368,10 @@ static void Cmd_attackcanceler(void)
} }
gHitMarker |= HITMARKER_OBEYS; gHitMarker |= HITMARKER_OBEYS;
// Check if no available target present on the field. // Check if no available target present on the field or if Sky Battles ban the move
if (NoTargetPresent(gBattlerAttacker, gCurrentMove) if ((NoTargetPresent(gBattlerAttacker, gCurrentMove)
&& (!gBattleMoves[gCurrentMove].twoTurnMove || (gBattleMons[gBattlerAttacker].status2 & STATUS2_MULTIPLETURNS))) && (!gBattleMoves[gCurrentMove].twoTurnMove || (gBattleMons[gBattlerAttacker].status2 & STATUS2_MULTIPLETURNS)))
|| (IsMoveNotAllowedInSkyBattles(gCurrentMove)))
{ {
if (gBattleMoves[gCurrentMove].effect == EFFECT_FLING) // Edge case for removing a mon's item when there is no target available after using Fling. if (gBattleMoves[gCurrentMove].effect == EFFECT_FLING) // Edge case for removing a mon's item when there is no target available after using Fling.
gBattlescriptCurrInstr = BattleScript_FlingFailConsumeItem; gBattlescriptCurrInstr = BattleScript_FlingFailConsumeItem;
@ -3595,7 +3601,11 @@ void SetMoveEffect(bool32 primary, u32 certain)
{ {
gBattleCommunication[MULTISTRING_CHOOSER] = B_MSG_SPIKESSCATTERED; gBattleCommunication[MULTISTRING_CHOOSER] = B_MSG_SPIKESSCATTERED;
BattleScriptPush(gBattlescriptCurrInstr + 1); BattleScriptPush(gBattlescriptCurrInstr + 1);
gBattlescriptCurrInstr = BattleScript_SpikesActivates;
if (gBattleStruct->isSkyBattle)
gBattlescriptCurrInstr++;
else
gBattlescriptCurrInstr = BattleScript_SpikesActivates;
} }
break; break;
case MOVE_EFFECT_TRIPLE_ARROWS: case MOVE_EFFECT_TRIPLE_ARROWS:
@ -4324,7 +4334,7 @@ static bool32 NoAliveMonsForPlayerAndPartner(void)
return (HP_count == 0); return (HP_count == 0);
} }
static bool32 NoAliveMonsForPlayer(void) bool32 NoAliveMonsForPlayer(void)
{ {
u32 i; u32 i;
u32 HP_count = 0; u32 HP_count = 0;

View file

@ -1,5 +1,6 @@
#include "global.h" #include "global.h"
#include "battle.h" #include "battle.h"
#include "load_save.h"
#include "battle_setup.h" #include "battle_setup.h"
#include "battle_transition.h" #include "battle_transition.h"
#include "main.h" #include "main.h"
@ -81,6 +82,8 @@ static void TryUpdateGymLeaderRematchFromTrainer(void);
static void CB2_GiveStarter(void); static void CB2_GiveStarter(void);
static void CB2_StartFirstBattle(void); static void CB2_StartFirstBattle(void);
static void CB2_EndFirstBattle(void); static void CB2_EndFirstBattle(void);
static void SaveChangesToPlayerParty(void);
static void HandleBattleVariantEndParty(void);
static void CB2_EndTrainerBattle(void); static void CB2_EndTrainerBattle(void);
static bool32 IsPlayerDefeated(u32 battleOutcome); static bool32 IsPlayerDefeated(u32 battleOutcome);
static u16 GetRematchTrainerId(u16 trainerId); static u16 GetRematchTrainerId(u16 trainerId);
@ -1380,15 +1383,40 @@ void BattleSetup_StartTrainerBattle_Debug(void)
ScriptContext_Stop(); ScriptContext_Stop();
} }
static void SaveChangesToPlayerParty(void)
{
u8 i = 0, j = 0;
u8 participatedPokemon = VarGet(B_VAR_SKY_BATTLE);
for (i = 0; i < PARTY_SIZE; i++)
{
if ((participatedPokemon >> i & 1) == 1)
{
gSaveBlock1Ptr->playerParty[i] = gPlayerParty[j];
j++;
}
}
}
static void HandleBattleVariantEndParty(void)
{
if (B_FLAG_SKY_BATTLE == 0 || !FlagGet(B_FLAG_SKY_BATTLE))
return;
SaveChangesToPlayerParty();
LoadPlayerParty();
FlagClear(B_FLAG_SKY_BATTLE);
}
static void CB2_EndTrainerBattle(void) static void CB2_EndTrainerBattle(void)
{ {
HandleBattleVariantEndParty();
if (gTrainerBattleOpponent_A == TRAINER_SECRET_BASE) if (gTrainerBattleOpponent_A == TRAINER_SECRET_BASE)
{ {
SetMainCallback2(CB2_ReturnToFieldContinueScriptPlayMapMusic); SetMainCallback2(CB2_ReturnToFieldContinueScriptPlayMapMusic);
} }
else if (IsPlayerDefeated(gBattleOutcome) == TRUE) else if (IsPlayerDefeated(gBattleOutcome) == TRUE)
{ {
if (InBattlePyramid() || InTrainerHillChallenge()) if (InBattlePyramid() || InTrainerHillChallenge() || (!NoAliveMonsForPlayer()))
SetMainCallback2(CB2_ReturnToFieldContinueScriptPlayMapMusic); SetMainCallback2(CB2_ReturnToFieldContinueScriptPlayMapMusic);
else else
SetMainCallback2(CB2_WhiteOut); SetMainCallback2(CB2_WhiteOut);

View file

@ -4095,7 +4095,7 @@ bool32 TryChangeBattleWeather(u32 battler, u32 weatherEnumId, bool32 viaAbility)
static bool32 TryChangeBattleTerrain(u32 battler, u32 statusFlag, u8 *timer) static bool32 TryChangeBattleTerrain(u32 battler, u32 statusFlag, u8 *timer)
{ {
if (!(gFieldStatuses & statusFlag)) if ((!(gFieldStatuses & statusFlag) && (!gBattleStruct->isSkyBattle)))
{ {
gFieldStatuses &= ~(STATUS_FIELD_MISTY_TERRAIN | STATUS_FIELD_GRASSY_TERRAIN | STATUS_FIELD_ELECTRIC_TERRAIN | STATUS_FIELD_PSYCHIC_TERRAIN); gFieldStatuses &= ~(STATUS_FIELD_MISTY_TERRAIN | STATUS_FIELD_GRASSY_TERRAIN | STATUS_FIELD_ELECTRIC_TERRAIN | STATUS_FIELD_PSYCHIC_TERRAIN);
gFieldStatuses |= statusFlag; gFieldStatuses |= statusFlag;
@ -5756,6 +5756,7 @@ u32 AbilityBattleEffects(u32 caseID, u32 battler, u32 ability, u32 special, u32
break; break;
case ABILITY_TOXIC_DEBRIS: case ABILITY_TOXIC_DEBRIS:
if (!(gMoveResultFlags & MOVE_RESULT_NO_EFFECT) if (!(gMoveResultFlags & MOVE_RESULT_NO_EFFECT)
&& (!gBattleStruct->isSkyBattle)
&& !gProtectStructs[gBattlerAttacker].confusionSelfDmg && !gProtectStructs[gBattlerAttacker].confusionSelfDmg
&& IS_MOVE_PHYSICAL(gCurrentMove) && IS_MOVE_PHYSICAL(gCurrentMove)
&& TARGET_TURN_DAMAGED && TARGET_TURN_DAMAGED
@ -11267,6 +11268,56 @@ bool32 IsGen6ExpShareEnabled(void)
#endif #endif
} }
bool8 CanMonParticipateInSkyBattle(struct Pokemon *mon)
{
u16 species = GetMonData(mon, MON_DATA_SPECIES);
u16 monAbilityNum = GetMonData(mon, MON_DATA_ABILITY_NUM, NULL);
bool8 hasLevitateAbility = gSpeciesInfo[species].abilities[monAbilityNum] == ABILITY_LEVITATE;
bool8 isFlyingType = gSpeciesInfo[species].types[0] == TYPE_FLYING || gSpeciesInfo[species].types[1] == TYPE_FLYING;
bool8 monIsValidAndNotEgg = GetMonData(mon, MON_DATA_SANITY_HAS_SPECIES) && !GetMonData(mon, MON_DATA_IS_EGG);
if (monIsValidAndNotEgg)
{
if ((hasLevitateAbility || isFlyingType) && !IsMonBannedFromSkyBattles(species))
return TRUE;
}
return FALSE;
}
bool8 IsMonBannedFromSkyBattles(u16 species)
{
switch (species)
{
#if B_SKY_BATTLE_STRICT_ELIGIBILITY == TRUE
case SPECIES_SPEAROW:
case SPECIES_FARFETCHD:
case SPECIES_DODUO:
case SPECIES_DODRIO:
case SPECIES_HOOTHOOT:
case SPECIES_NATU:
case SPECIES_MURKROW:
case SPECIES_DELIBIRD:
case SPECIES_TAILLOW:
case SPECIES_STARLY:
case SPECIES_CHATOT:
case SPECIES_SHAYMIN:
case SPECIES_PIDOVE:
case SPECIES_ARCHEN:
case SPECIES_DUCKLETT:
case SPECIES_RUFFLET:
case SPECIES_VULLABY:
case SPECIES_FLETCHLING:
case SPECIES_HAWLUCHA:
case SPECIES_ROWLET:
case SPECIES_PIKIPEK:
#endif
case SPECIES_EGG:
return TRUE;
default:
return FALSE;
}
}
u8 GetBattlerType(u32 battler, u8 typeIndex) u8 GetBattlerType(u32 battler, u8 typeIndex)
{ {

View file

@ -19,6 +19,10 @@ void AllocateBattleResources(void)
gBattleStruct = AllocZeroed(sizeof(*gBattleStruct)); gBattleStruct = AllocZeroed(sizeof(*gBattleStruct));
#if B_FLAG_SKY_BATTLE
gBattleStruct->isSkyBattle = FlagGet(B_FLAG_SKY_BATTLE);
#endif
gBattleResources = AllocZeroed(sizeof(*gBattleResources)); gBattleResources = AllocZeroed(sizeof(*gBattleResources));
gBattleResources->secretBase = AllocZeroed(sizeof(*gBattleResources->secretBase)); gBattleResources->secretBase = AllocZeroed(sizeof(*gBattleResources->secretBase));
gBattleResources->flags = AllocZeroed(sizeof(*gBattleResources->flags)); gBattleResources->flags = AllocZeroed(sizeof(*gBattleResources->flags));

View file

@ -376,6 +376,7 @@ const struct BattleMove gBattleMoves[MOVES_COUNT_DYNAMAX] =
.split = SPLIT_PHYSICAL, .split = SPLIT_PHYSICAL,
.zMoveEffect = Z_EFFECT_NONE, .zMoveEffect = Z_EFFECT_NONE,
.makesContact = TRUE, .makesContact = TRUE,
.skyBattleBanned = TRUE,
}, },
[MOVE_VINE_WHIP] = [MOVE_VINE_WHIP] =
@ -416,6 +417,7 @@ const struct BattleMove gBattleMoves[MOVES_COUNT_DYNAMAX] =
.makesContact = TRUE, .makesContact = TRUE,
.sheerForceBoost = TRUE, .sheerForceBoost = TRUE,
.minimizeDoubleDamage = TRUE, .minimizeDoubleDamage = TRUE,
.skyBattleBanned = TRUE,
}, },
[MOVE_DOUBLE_KICK] = [MOVE_DOUBLE_KICK] =
@ -604,6 +606,7 @@ const struct BattleMove gBattleMoves[MOVES_COUNT_DYNAMAX] =
.makesContact = TRUE, .makesContact = TRUE,
.sheerForceBoost = TRUE, .sheerForceBoost = TRUE,
.minimizeDoubleDamage = B_UPDATED_MOVE_FLAGS >= GEN_6, .minimizeDoubleDamage = B_UPDATED_MOVE_FLAGS >= GEN_6,
.skyBattleBanned = TRUE,
}, },
[MOVE_WRAP] = [MOVE_WRAP] =
@ -1008,6 +1011,7 @@ const struct BattleMove gBattleMoves[MOVES_COUNT_DYNAMAX] =
.split = SPLIT_SPECIAL, .split = SPLIT_SPECIAL,
.zMoveEffect = Z_EFFECT_NONE, .zMoveEffect = Z_EFFECT_NONE,
.damagesUnderwater = TRUE, .damagesUnderwater = TRUE,
.skyBattleBanned = TRUE,
}, },
[MOVE_ICE_BEAM] = [MOVE_ICE_BEAM] =
@ -1216,6 +1220,7 @@ const struct BattleMove gBattleMoves[MOVES_COUNT_DYNAMAX] =
.split = SPLIT_PHYSICAL, .split = SPLIT_PHYSICAL,
.zMoveEffect = Z_EFFECT_NONE, .zMoveEffect = Z_EFFECT_NONE,
.makesContact = TRUE, .makesContact = TRUE,
.skyBattleBanned = TRUE,
}, },
[MOVE_STRENGTH] = [MOVE_STRENGTH] =
@ -1574,6 +1579,7 @@ const struct BattleMove gBattleMoves[MOVES_COUNT_DYNAMAX] =
.zMoveEffect = Z_EFFECT_NONE, .zMoveEffect = Z_EFFECT_NONE,
.ignoresKingsRock = B_UPDATED_MOVE_FLAGS < GEN_3, .ignoresKingsRock = B_UPDATED_MOVE_FLAGS < GEN_3,
.damagesUnderground = TRUE, .damagesUnderground = TRUE,
.skyBattleBanned = TRUE,
}, },
[MOVE_FISSURE] = [MOVE_FISSURE] =
@ -1589,6 +1595,7 @@ const struct BattleMove gBattleMoves[MOVES_COUNT_DYNAMAX] =
.split = SPLIT_PHYSICAL, .split = SPLIT_PHYSICAL,
.zMoveEffect = Z_EFFECT_NONE, .zMoveEffect = Z_EFFECT_NONE,
.damagesUnderground = TRUE, .damagesUnderground = TRUE,
.skyBattleBanned = TRUE,
}, },
[MOVE_DIG] = [MOVE_DIG] =
@ -1612,6 +1619,7 @@ const struct BattleMove gBattleMoves[MOVES_COUNT_DYNAMAX] =
.sleepTalkBanned = TRUE, .sleepTalkBanned = TRUE,
.instructBanned = TRUE, .instructBanned = TRUE,
.assistBanned = TRUE, .assistBanned = TRUE,
.skyBattleBanned = TRUE,
}, },
[MOVE_TOXIC] = [MOVE_TOXIC] =
@ -2913,6 +2921,7 @@ const struct BattleMove gBattleMoves[MOVES_COUNT_DYNAMAX] =
.snatchAffected = TRUE, .snatchAffected = TRUE,
.ignoresProtect = TRUE, .ignoresProtect = TRUE,
.mirrorMoveBanned = TRUE, .mirrorMoveBanned = TRUE,
.skyBattleBanned = TRUE,
}, },
[MOVE_STRUGGLE] = [MOVE_STRUGGLE] =
@ -3416,6 +3425,7 @@ const struct BattleMove gBattleMoves[MOVES_COUNT_DYNAMAX] =
.mirrorMoveBanned = TRUE, .mirrorMoveBanned = TRUE,
.magicCoatAffected = B_UPDATED_MOVE_FLAGS >= GEN_5, .magicCoatAffected = B_UPDATED_MOVE_FLAGS >= GEN_5,
.forcePressure = TRUE, .forcePressure = TRUE,
.skyBattleBanned = TRUE,
}, },
[MOVE_ZAP_CANNON] = [MOVE_ZAP_CANNON] =
@ -3986,6 +3996,7 @@ const struct BattleMove gBattleMoves[MOVES_COUNT_DYNAMAX] =
.split = SPLIT_PHYSICAL, .split = SPLIT_PHYSICAL,
.zMoveEffect = Z_EFFECT_NONE, .zMoveEffect = Z_EFFECT_NONE,
.damagesUnderground = TRUE, .damagesUnderground = TRUE,
.skyBattleBanned = TRUE,
}, },
[MOVE_DYNAMIC_PUNCH] = [MOVE_DYNAMIC_PUNCH] =
@ -4952,6 +4963,7 @@ const struct BattleMove gBattleMoves[MOVES_COUNT_DYNAMAX] =
.snatchAffected = TRUE, .snatchAffected = TRUE,
.ignoresProtect = TRUE, .ignoresProtect = TRUE,
.mirrorMoveBanned = TRUE, .mirrorMoveBanned = TRUE,
.skyBattleBanned = TRUE,
}, },
[MOVE_SUPERPOWER] = [MOVE_SUPERPOWER] =
@ -5219,6 +5231,7 @@ const struct BattleMove gBattleMoves[MOVES_COUNT_DYNAMAX] =
.sleepTalkBanned = TRUE, .sleepTalkBanned = TRUE,
.instructBanned = TRUE, .instructBanned = TRUE,
.assistBanned = TRUE, .assistBanned = TRUE,
.skyBattleBanned = TRUE,
}, },
[MOVE_ARM_THRUST] = [MOVE_ARM_THRUST] =
@ -5368,6 +5381,7 @@ const struct BattleMove gBattleMoves[MOVES_COUNT_DYNAMAX] =
.zMoveEffect = Z_EFFECT_SPDEF_UP_1, .zMoveEffect = Z_EFFECT_SPDEF_UP_1,
.ignoresProtect = TRUE, .ignoresProtect = TRUE,
.mirrorMoveBanned = TRUE, .mirrorMoveBanned = TRUE,
.skyBattleBanned = TRUE,
}, },
[MOVE_ICE_BALL] = [MOVE_ICE_BALL] =
@ -5891,6 +5905,7 @@ const struct BattleMove gBattleMoves[MOVES_COUNT_DYNAMAX] =
.split = SPLIT_SPECIAL, .split = SPLIT_SPECIAL,
.zMoveEffect = Z_EFFECT_NONE, .zMoveEffect = Z_EFFECT_NONE,
.sheerForceBoost = TRUE, .sheerForceBoost = TRUE,
.skyBattleBanned = TRUE,
}, },
[MOVE_BULLET_SEED] = [MOVE_BULLET_SEED] =
@ -6028,6 +6043,7 @@ const struct BattleMove gBattleMoves[MOVES_COUNT_DYNAMAX] =
.priority = 0, .priority = 0,
.split = SPLIT_SPECIAL, .split = SPLIT_SPECIAL,
.zMoveEffect = Z_EFFECT_NONE, .zMoveEffect = Z_EFFECT_NONE,
.skyBattleBanned = TRUE,
}, },
[MOVE_BULK_UP] = [MOVE_BULK_UP] =
@ -6182,6 +6198,7 @@ const struct BattleMove gBattleMoves[MOVES_COUNT_DYNAMAX] =
.zMoveEffect = Z_EFFECT_SPDEF_UP_1, .zMoveEffect = Z_EFFECT_SPDEF_UP_1,
.ignoresProtect = TRUE, .ignoresProtect = TRUE,
.mirrorMoveBanned = TRUE, .mirrorMoveBanned = TRUE,
.skyBattleBanned = TRUE,
}, },
[MOVE_CALM_MIND] = [MOVE_CALM_MIND] =
@ -6360,6 +6377,7 @@ const struct BattleMove gBattleMoves[MOVES_COUNT_DYNAMAX] =
.zMoveEffect = Z_EFFECT_SPATK_UP_1, .zMoveEffect = Z_EFFECT_SPATK_UP_1,
.ignoresProtect = TRUE, .ignoresProtect = TRUE,
.mirrorMoveBanned = TRUE, .mirrorMoveBanned = TRUE,
.skyBattleBanned = TRUE,
}, },
[MOVE_MIRACLE_EYE] = [MOVE_MIRACLE_EYE] =
@ -6934,6 +6952,7 @@ const struct BattleMove gBattleMoves[MOVES_COUNT_DYNAMAX] =
.mirrorMoveBanned = TRUE, .mirrorMoveBanned = TRUE,
.magicCoatAffected = B_UPDATED_MOVE_FLAGS >= GEN_5, .magicCoatAffected = B_UPDATED_MOVE_FLAGS >= GEN_5,
.forcePressure = TRUE, .forcePressure = TRUE,
.skyBattleBanned = TRUE,
}, },
[MOVE_HEART_SWAP] = [MOVE_HEART_SWAP] =
@ -7343,6 +7362,7 @@ const struct BattleMove gBattleMoves[MOVES_COUNT_DYNAMAX] =
.split = SPLIT_SPECIAL, .split = SPLIT_SPECIAL,
.zMoveEffect = Z_EFFECT_NONE, .zMoveEffect = Z_EFFECT_NONE,
.sheerForceBoost = TRUE, .sheerForceBoost = TRUE,
.skyBattleBanned = TRUE,
}, },
[MOVE_SWITCHEROO] = [MOVE_SWITCHEROO] =
@ -7878,6 +7898,7 @@ const struct BattleMove gBattleMoves[MOVES_COUNT_DYNAMAX] =
.split = SPLIT_SPECIAL, .split = SPLIT_SPECIAL,
.zMoveEffect = Z_EFFECT_NONE, .zMoveEffect = Z_EFFECT_NONE,
.makesContact = TRUE, .makesContact = TRUE,
.skyBattleBanned = TRUE,
}, },
[MOVE_CHATTER] = [MOVE_CHATTER] =
@ -8428,6 +8449,7 @@ const struct BattleMove gBattleMoves[MOVES_COUNT_DYNAMAX] =
.split = SPLIT_PHYSICAL, .split = SPLIT_PHYSICAL,
.zMoveEffect = Z_EFFECT_NONE, .zMoveEffect = Z_EFFECT_NONE,
.damagesAirborne = TRUE, .damagesAirborne = TRUE,
.skyBattleBanned = TRUE,
}, },
[MOVE_STORM_THROW] = [MOVE_STORM_THROW] =
@ -8510,6 +8532,7 @@ const struct BattleMove gBattleMoves[MOVES_COUNT_DYNAMAX] =
.zMoveEffect = Z_EFFECT_NONE, .zMoveEffect = Z_EFFECT_NONE,
.makesContact = TRUE, .makesContact = TRUE,
.minimizeDoubleDamage = B_UPDATED_MOVE_FLAGS >= GEN_7, .minimizeDoubleDamage = B_UPDATED_MOVE_FLAGS >= GEN_7,
.skyBattleBanned = TRUE,
}, },
[MOVE_SYNCHRONOISE] = [MOVE_SYNCHRONOISE] =
@ -9077,6 +9100,7 @@ const struct BattleMove gBattleMoves[MOVES_COUNT_DYNAMAX] =
.priority = 0, .priority = 0,
.split = SPLIT_SPECIAL, .split = SPLIT_SPECIAL,
.zMoveEffect = Z_EFFECT_NONE, .zMoveEffect = Z_EFFECT_NONE,
.skyBattleBanned = TRUE,
}, },
[MOVE_FIRE_PLEDGE] = [MOVE_FIRE_PLEDGE] =
@ -9095,6 +9119,7 @@ const struct BattleMove gBattleMoves[MOVES_COUNT_DYNAMAX] =
.priority = 0, .priority = 0,
.split = SPLIT_SPECIAL, .split = SPLIT_SPECIAL,
.zMoveEffect = Z_EFFECT_NONE, .zMoveEffect = Z_EFFECT_NONE,
.skyBattleBanned = TRUE,
}, },
[MOVE_GRASS_PLEDGE] = [MOVE_GRASS_PLEDGE] =
@ -9113,6 +9138,7 @@ const struct BattleMove gBattleMoves[MOVES_COUNT_DYNAMAX] =
.priority = 0, .priority = 0,
.split = SPLIT_SPECIAL, .split = SPLIT_SPECIAL,
.zMoveEffect = Z_EFFECT_NONE, .zMoveEffect = Z_EFFECT_NONE,
.skyBattleBanned = TRUE,
}, },
[MOVE_VOLT_SWITCH] = [MOVE_VOLT_SWITCH] =
@ -9161,6 +9187,7 @@ const struct BattleMove gBattleMoves[MOVES_COUNT_DYNAMAX] =
.split = SPLIT_PHYSICAL, .split = SPLIT_PHYSICAL,
.zMoveEffect = Z_EFFECT_NONE, .zMoveEffect = Z_EFFECT_NONE,
.sheerForceBoost = TRUE, .sheerForceBoost = TRUE,
.skyBattleBanned = TRUE,
}, },
[MOVE_FROST_BREATH] = [MOVE_FROST_BREATH] =
@ -9779,6 +9806,7 @@ const struct BattleMove gBattleMoves[MOVES_COUNT_DYNAMAX] =
.makesContact = TRUE, .makesContact = TRUE,
.minimizeDoubleDamage = TRUE, .minimizeDoubleDamage = TRUE,
.gravityBanned = TRUE, .gravityBanned = TRUE,
.skyBattleBanned = TRUE,
}, },
[MOVE_MAT_BLOCK] = [MOVE_MAT_BLOCK] =
@ -9800,6 +9828,7 @@ const struct BattleMove gBattleMoves[MOVES_COUNT_DYNAMAX] =
.metronomeBanned = TRUE, .metronomeBanned = TRUE,
.copycatBanned = TRUE, .copycatBanned = TRUE,
.assistBanned = TRUE, .assistBanned = TRUE,
.skyBattleBanned = TRUE,
}, },
[MOVE_BELCH] = [MOVE_BELCH] =
@ -9838,6 +9867,7 @@ const struct BattleMove gBattleMoves[MOVES_COUNT_DYNAMAX] =
.zMoveEffect = Z_EFFECT_ATK_UP_1, .zMoveEffect = Z_EFFECT_ATK_UP_1,
.ignoresProtect = TRUE, .ignoresProtect = TRUE,
.mirrorMoveBanned = TRUE, .mirrorMoveBanned = TRUE,
.skyBattleBanned = TRUE,
}, },
[MOVE_STICKY_WEB] = [MOVE_STICKY_WEB] =
@ -9855,6 +9885,7 @@ const struct BattleMove gBattleMoves[MOVES_COUNT_DYNAMAX] =
.ignoresProtect = TRUE, .ignoresProtect = TRUE,
.mirrorMoveBanned = TRUE, .mirrorMoveBanned = TRUE,
.magicCoatAffected = TRUE, .magicCoatAffected = TRUE,
.skyBattleBanned = TRUE,
}, },
[MOVE_FELL_STINGER] = [MOVE_FELL_STINGER] =
@ -10129,6 +10160,7 @@ const struct BattleMove gBattleMoves[MOVES_COUNT_DYNAMAX] =
.zMoveEffect = Z_EFFECT_DEF_UP_1, .zMoveEffect = Z_EFFECT_DEF_UP_1,
.ignoresProtect = TRUE, .ignoresProtect = TRUE,
.mirrorMoveBanned = TRUE, .mirrorMoveBanned = TRUE,
.skyBattleBanned = TRUE,
}, },
[MOVE_MISTY_TERRAIN] = [MOVE_MISTY_TERRAIN] =
@ -10145,6 +10177,7 @@ const struct BattleMove gBattleMoves[MOVES_COUNT_DYNAMAX] =
.zMoveEffect = Z_EFFECT_SPDEF_UP_1, .zMoveEffect = Z_EFFECT_SPDEF_UP_1,
.ignoresProtect = TRUE, .ignoresProtect = TRUE,
.mirrorMoveBanned = TRUE, .mirrorMoveBanned = TRUE,
.skyBattleBanned = TRUE,
}, },
[MOVE_ELECTRIFY] = [MOVE_ELECTRIFY] =
@ -10485,6 +10518,7 @@ const struct BattleMove gBattleMoves[MOVES_COUNT_DYNAMAX] =
.twoTurnMove = TRUE, .twoTurnMove = TRUE,
.sleepTalkBanned = TRUE, .sleepTalkBanned = TRUE,
.instructBanned = TRUE, .instructBanned = TRUE,
.skyBattleBanned = TRUE,
}, },
[MOVE_MAGNETIC_FLUX] = [MOVE_MAGNETIC_FLUX] =
@ -10535,6 +10569,7 @@ const struct BattleMove gBattleMoves[MOVES_COUNT_DYNAMAX] =
.zMoveEffect = Z_EFFECT_SPD_UP_1, .zMoveEffect = Z_EFFECT_SPD_UP_1,
.ignoresProtect = TRUE, .ignoresProtect = TRUE,
.mirrorMoveBanned = TRUE, .mirrorMoveBanned = TRUE,
.skyBattleBanned = TRUE,
}, },
[MOVE_DAZZLING_GLEAM] = [MOVE_DAZZLING_GLEAM] =
@ -10704,6 +10739,7 @@ const struct BattleMove gBattleMoves[MOVES_COUNT_DYNAMAX] =
.damagesAirborne = TRUE, .damagesAirborne = TRUE,
.ignoreTypeIfFlyingAndUngrounded = TRUE, .ignoreTypeIfFlyingAndUngrounded = TRUE,
.metronomeBanned = TRUE, .metronomeBanned = TRUE,
.skyBattleBanned = TRUE,
}, },
[MOVE_THOUSAND_WAVES] = [MOVE_THOUSAND_WAVES] =
@ -10719,6 +10755,7 @@ const struct BattleMove gBattleMoves[MOVES_COUNT_DYNAMAX] =
.split = SPLIT_PHYSICAL, .split = SPLIT_PHYSICAL,
.zMoveEffect = Z_EFFECT_NONE, .zMoveEffect = Z_EFFECT_NONE,
.metronomeBanned = TRUE, .metronomeBanned = TRUE,
.skyBattleBanned = TRUE,
}, },
[MOVE_LANDS_WRATH] = [MOVE_LANDS_WRATH] =
@ -10733,6 +10770,7 @@ const struct BattleMove gBattleMoves[MOVES_COUNT_DYNAMAX] =
.priority = 0, .priority = 0,
.split = SPLIT_PHYSICAL, .split = SPLIT_PHYSICAL,
.zMoveEffect = Z_EFFECT_NONE, .zMoveEffect = Z_EFFECT_NONE,
.skyBattleBanned = TRUE,
}, },
[MOVE_LIGHT_OF_RUIN] = [MOVE_LIGHT_OF_RUIN] =
@ -11470,6 +11508,7 @@ const struct BattleMove gBattleMoves[MOVES_COUNT_DYNAMAX] =
.split = SPLIT_PHYSICAL, .split = SPLIT_PHYSICAL,
.zMoveEffect = Z_EFFECT_NONE, .zMoveEffect = Z_EFFECT_NONE,
.makesContact = TRUE, .makesContact = TRUE,
.skyBattleBanned = TRUE,
}, },
[MOVE_SHADOW_BONE] = [MOVE_SHADOW_BONE] =
@ -12232,6 +12271,7 @@ const struct BattleMove gBattleMoves[MOVES_COUNT_DYNAMAX] =
.zMoveEffect = Z_EFFECT_NONE, .zMoveEffect = Z_EFFECT_NONE,
.makesContact = TRUE, .makesContact = TRUE,
.metronomeBanned = TRUE, .metronomeBanned = TRUE,
.skyBattleBanned = TRUE,
}, },
[MOVE_DECORATE] = [MOVE_DECORATE] =
@ -12281,6 +12321,7 @@ const struct BattleMove gBattleMoves[MOVES_COUNT_DYNAMAX] =
.zMoveEffect = Z_EFFECT_NONE, .zMoveEffect = Z_EFFECT_NONE,
.makesContact = TRUE, .makesContact = TRUE,
.metronomeBanned = TRUE, .metronomeBanned = TRUE,
.skyBattleBanned = TRUE,
}, },
[MOVE_PYRO_BALL] = [MOVE_PYRO_BALL] =
@ -12599,6 +12640,7 @@ const struct BattleMove gBattleMoves[MOVES_COUNT_DYNAMAX] =
.zMoveEffect = Z_EFFECT_NONE, .zMoveEffect = Z_EFFECT_NONE,
.makesContact = TRUE, .makesContact = TRUE,
.argument = ARG_TRY_REMOVE_TERRAIN_FAIL, // Remove a field terrain if there is one and hit, otherwise fail. .argument = ARG_TRY_REMOVE_TERRAIN_FAIL, // Remove a field terrain if there is one and hit, otherwise fail.
.skyBattleBanned = TRUE,
}, },
[MOVE_SCALE_SHOT] = [MOVE_SCALE_SHOT] =
@ -12678,6 +12720,7 @@ const struct BattleMove gBattleMoves[MOVES_COUNT_DYNAMAX] =
.split = SPLIT_PHYSICAL, .split = SPLIT_PHYSICAL,
.zMoveEffect = Z_EFFECT_NONE, .zMoveEffect = Z_EFFECT_NONE,
.makesContact = TRUE, .makesContact = TRUE,
.skyBattleBanned = TRUE,
}, },
[MOVE_RISING_VOLTAGE] = [MOVE_RISING_VOLTAGE] =
@ -13199,6 +13242,7 @@ const struct BattleMove gBattleMoves[MOVES_COUNT_DYNAMAX] =
.split = SPLIT_PHYSICAL, .split = SPLIT_PHYSICAL,
.zMoveEffect = Z_EFFECT_NONE, .zMoveEffect = Z_EFFECT_NONE,
.makesContact = TRUE, .makesContact = TRUE,
.skyBattleBanned = TRUE,
}, },
[MOVE_CHLOROBLAST] = [MOVE_CHLOROBLAST] =
@ -13644,6 +13688,7 @@ const struct BattleMove gBattleMoves[MOVES_COUNT_DYNAMAX] =
.split = SPLIT_PHYSICAL, .split = SPLIT_PHYSICAL,
.zMoveEffect = Z_EFFECT_NONE, .zMoveEffect = Z_EFFECT_NONE,
.makesContact = TRUE, .makesContact = TRUE,
.skyBattleBanned = TRUE,
}, },
[MOVE_POPULATION_BOMB] = [MOVE_POPULATION_BOMB] =
@ -13678,6 +13723,7 @@ const struct BattleMove gBattleMoves[MOVES_COUNT_DYNAMAX] =
.zMoveEffect = Z_EFFECT_NONE, .zMoveEffect = Z_EFFECT_NONE,
.makesContact = TRUE, .makesContact = TRUE,
.argument = ARG_TRY_REMOVE_TERRAIN_HIT, // Remove the active field terrain if there is one. .argument = ARG_TRY_REMOVE_TERRAIN_HIT, // Remove the active field terrain if there is one.
.skyBattleBanned = TRUE,
}, },
[MOVE_GLAIVE_RUSH] = [MOVE_GLAIVE_RUSH] =
@ -14479,6 +14525,7 @@ const struct BattleMove gBattleMoves[MOVES_COUNT_DYNAMAX] =
.priority = 0, .priority = 0,
.split = SPLIT_PHYSICAL, .split = SPLIT_PHYSICAL,
.zMoveEffect = 0, .zMoveEffect = 0,
.skyBattleBanned = TRUE,
}, },
[MOVE_CONTINENTAL_CRUSH] = [MOVE_CONTINENTAL_CRUSH] =
{ {

View file

@ -402,6 +402,7 @@ static void DebugAction_Sound_MUS_SelectId(u8 taskId);
extern const u8 Debug_FlagsNotSetOverworldConfigMessage[]; extern const u8 Debug_FlagsNotSetOverworldConfigMessage[];
extern const u8 Debug_FlagsNotSetBattleConfigMessage[]; extern const u8 Debug_FlagsNotSetBattleConfigMessage[];
extern const u8 Debug_FlagsAndVarNotSetBattleConfigMessage[];
extern const u8 Debug_EventScript_Script_1[]; extern const u8 Debug_EventScript_Script_1[];
extern const u8 Debug_EventScript_Script_2[]; extern const u8 Debug_EventScript_Script_2[];
extern const u8 Debug_EventScript_Script_3[]; extern const u8 Debug_EventScript_Script_3[];

View file

@ -1,4 +1,5 @@
#include "global.h" #include "global.h"
#include "debug.h"
#include "malloc.h" #include "malloc.h"
#include "battle.h" #include "battle.h"
#include "battle_tower.h" #include "battle_tower.h"
@ -20,6 +21,7 @@
#include "international_string_util.h" #include "international_string_util.h"
#include "item_icon.h" #include "item_icon.h"
#include "link.h" #include "link.h"
#include "load_save.h"
#include "list_menu.h" #include "list_menu.h"
#include "main.h" #include "main.h"
#include "mystery_gift.h" #include "mystery_gift.h"
@ -4207,3 +4209,47 @@ u8 Script_TryGainNewFanFromCounter(void)
{ {
return TryGainNewFanFromCounter(gSpecialVar_0x8004); return TryGainNewFanFromCounter(gSpecialVar_0x8004);
} }
void TrySkyBattle(void)
{
int i;
if (B_VAR_SKY_BATTLE == 0 || B_FLAG_SKY_BATTLE == 0)
{
LockPlayerFieldControls();
ScriptContext_SetupScript(Debug_FlagsAndVarNotSetBattleConfigMessage);
return;
}
for (i = 0; i < CalculatePlayerPartyCount(); i++)
{
struct Pokemon* pokemon = &gPlayerParty[i];
if (CanMonParticipateInSkyBattle(pokemon) && GetMonData(pokemon, MON_DATA_HP, NULL) > 0)
{
PreparePartyForSkyBattle();
gSpecialVar_Result = TRUE;
return;
}
}
gSpecialVar_Result = FALSE;
}
void PreparePartyForSkyBattle(void)
{
int i, participatingPokemonSlot = 0;
u8 partyCount = CalculatePlayerPartyCount();
FlagSet(B_FLAG_SKY_BATTLE);
SavePlayerParty();
for (i = 0; i < partyCount; i++)
{
struct Pokemon* pokemon = &gPlayerParty[i];
if (CanMonParticipateInSkyBattle(pokemon))
participatingPokemonSlot += 1 << i;
else
ZeroMonData(pokemon);
}
VarSet(B_VAR_SKY_BATTLE,participatingPokemonSlot);
CompactPartySlots();
}

View file

@ -13,6 +13,7 @@
#include "gba/flash_internal.h" #include "gba/flash_internal.h"
#include "decoration_inventory.h" #include "decoration_inventory.h"
#include "agb_flash.h" #include "agb_flash.h"
#include "event_data.h"
static void ApplyNewEncryptionKeyToAllEncryptedData(u32 encryptionKey); static void ApplyNewEncryptionKeyToAllEncryptedData(u32 encryptionKey);