|
|
|
|
@@ -86,7 +86,6 @@ static void SpriteCB_PlayerThrowUpdate(struct Sprite *sprite);
|
|
|
|
|
static void BattleStartClearSetData(void);
|
|
|
|
|
static void BattleIntroGetMonsData(void);
|
|
|
|
|
static void TurnValuesCleanUp(bool8 var0);
|
|
|
|
|
static void SpecialStatusesClear(void);
|
|
|
|
|
static void BattleIntroPrepareBackgroundSlide(void);
|
|
|
|
|
static void BattleIntroDrawTrainersOrMonsSprites(void);
|
|
|
|
|
static void BattleIntroDrawPartySummaryScreens(void);
|
|
|
|
|
@@ -227,6 +226,10 @@ EWRAM_DATA s32 gBideDmg[MAX_BATTLERS_COUNT] = {0};
|
|
|
|
|
EWRAM_DATA u8 gBideTarget[MAX_BATTLERS_COUNT] = {0};
|
|
|
|
|
EWRAM_DATA u16 gLastUsedMove = 0;
|
|
|
|
|
EWRAM_DATA u8 gIsCriticalHit = FALSE;
|
|
|
|
|
EWRAM_DATA struct FieldTimer gFieldTimers = {0};
|
|
|
|
|
EWRAM_DATA bool8 gHasFetchedBall = FALSE;
|
|
|
|
|
EWRAM_DATA u8 gLastUsedBall = 0;
|
|
|
|
|
EWRAM_DATA struct QueuedStatBoost gQueuedStatBoosts[MAX_BATTLERS_COUNT] = {0};
|
|
|
|
|
|
|
|
|
|
void (*gPreBattleCallback1)(void);
|
|
|
|
|
void (*gBattleMainFunc)(void);
|
|
|
|
|
@@ -2223,26 +2226,37 @@ static void BattleMainCB1(void)
|
|
|
|
|
gBattlerControllerFuncs[gActiveBattler]();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void ClearSetBScriptingStruct(void)
|
|
|
|
|
{
|
|
|
|
|
// windowsType is set up earlier in BattleInitBgsAndWindows, so we need to save the value
|
|
|
|
|
u32 temp = gBattleScripting.windowsType;
|
|
|
|
|
memset(&gBattleScripting, 0, sizeof(gBattleScripting));
|
|
|
|
|
|
|
|
|
|
gBattleScripting.windowsType = temp;
|
|
|
|
|
gBattleScripting.battleStyle = gSaveBlock2Ptr->optionsBattleStyle;
|
|
|
|
|
gBattleScripting.expOnCatch = (B_EXP_CATCH >= GEN_6);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void BattleStartClearSetData(void)
|
|
|
|
|
{
|
|
|
|
|
s32 i;
|
|
|
|
|
u32 j;
|
|
|
|
|
u8 *dataPtr;
|
|
|
|
|
|
|
|
|
|
TurnValuesCleanUp(FALSE);
|
|
|
|
|
SpecialStatusesClear();
|
|
|
|
|
|
|
|
|
|
memset(&gDisableStructs, 0, sizeof(gDisableStructs));
|
|
|
|
|
memset(&gFieldTimers, 0, sizeof(gFieldTimers));
|
|
|
|
|
memset(&gSideStatuses, 0, sizeof(gSideStatuses));
|
|
|
|
|
memset(&gSideTimers, 0, sizeof(gSideTimers));
|
|
|
|
|
memset(&gWishFutureKnock, 0, sizeof(gWishFutureKnock));
|
|
|
|
|
memset(&gBattleResults, 0, sizeof(gBattleResults));
|
|
|
|
|
ClearSetBScriptingStruct();
|
|
|
|
|
|
|
|
|
|
for (i = 0; i < MAX_BATTLERS_COUNT; i++)
|
|
|
|
|
{
|
|
|
|
|
gStatuses3[i] = 0;
|
|
|
|
|
gStatuses4[i] = 0;
|
|
|
|
|
|
|
|
|
|
dataPtr = (u8 *)&gDisableStructs[i];
|
|
|
|
|
for (j = 0; j < sizeof(struct DisableStruct); j++)
|
|
|
|
|
dataPtr[j] = 0;
|
|
|
|
|
|
|
|
|
|
gDisableStructs[i].isFirstTurn = 2;
|
|
|
|
|
sUnusedBattlersArray[i] = 0;
|
|
|
|
|
gLastMoves[i] = MOVE_NONE;
|
|
|
|
|
gLastLandedMoves[i] = MOVE_NONE;
|
|
|
|
|
gLastHitByType[i] = 0;
|
|
|
|
|
@@ -2251,32 +2265,34 @@ static void BattleStartClearSetData(void)
|
|
|
|
|
gLockedMoves[i] = MOVE_NONE;
|
|
|
|
|
gLastPrintedMoves[i] = MOVE_NONE;
|
|
|
|
|
gBattleResources->flags->flags[i] = 0;
|
|
|
|
|
gBattleStruct->lastTakenMove[i] = MOVE_NONE;
|
|
|
|
|
gBattleStruct->choicedMove[i] = MOVE_NONE;
|
|
|
|
|
gBattleStruct->changedItems[i] = 0;
|
|
|
|
|
gBattleStruct->lastTakenMoveFrom[i][0] = MOVE_NONE;
|
|
|
|
|
gBattleStruct->lastTakenMoveFrom[i][1] = MOVE_NONE;
|
|
|
|
|
gBattleStruct->lastTakenMoveFrom[i][2] = MOVE_NONE;
|
|
|
|
|
gBattleStruct->lastTakenMoveFrom[i][3] = MOVE_NONE;
|
|
|
|
|
gBattleStruct->AI_monToSwitchIntoId[i] = PARTY_SIZE;
|
|
|
|
|
gBattleStruct->skyDropTargets[i] = 0xFF;
|
|
|
|
|
gBattleStruct->overwrittenAbilities[i] = ABILITY_NONE;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
for (i = 0; i < 2; i++)
|
|
|
|
|
{
|
|
|
|
|
gSideStatuses[i] = 0;
|
|
|
|
|
gLastUsedMove = 0;
|
|
|
|
|
gFieldStatuses = 0;
|
|
|
|
|
|
|
|
|
|
dataPtr = (u8 *)&gSideTimers[i];
|
|
|
|
|
for (j = 0; j < sizeof(struct SideTimer); j++)
|
|
|
|
|
dataPtr[j] = 0;
|
|
|
|
|
}
|
|
|
|
|
gHasFetchedBall = FALSE;
|
|
|
|
|
gLastUsedBall = 0;
|
|
|
|
|
|
|
|
|
|
gBattlerAttacker = 0;
|
|
|
|
|
gBattlerTarget = 0;
|
|
|
|
|
gEffectBattler = 0;
|
|
|
|
|
gBattlerAbility = 0;
|
|
|
|
|
gBattleWeather = 0;
|
|
|
|
|
|
|
|
|
|
dataPtr = (u8 *)&gWishFutureKnock;
|
|
|
|
|
for (i = 0; i < sizeof(struct WishFutureKnock); i++)
|
|
|
|
|
dataPtr[i] = 0;
|
|
|
|
|
|
|
|
|
|
gHitMarker = 0;
|
|
|
|
|
|
|
|
|
|
if (!(gBattleTypeFlags & (BATTLE_TYPE_LINK | BATTLE_TYPE_POKEDUDE)) && gSaveBlock2Ptr->optionsBattleSceneOff)
|
|
|
|
|
gHitMarker |= HITMARKER_NO_ANIMATIONS;
|
|
|
|
|
|
|
|
|
|
gBattleScripting.battleStyle = gSaveBlock2Ptr->optionsBattleStyle;
|
|
|
|
|
|
|
|
|
|
gMultiHitCounter = 0;
|
|
|
|
|
gBattleOutcome = 0;
|
|
|
|
|
gBattleControllerExecFlags = 0;
|
|
|
|
|
@@ -2290,63 +2306,45 @@ static void BattleStartClearSetData(void)
|
|
|
|
|
gPauseCounterBattle = 0;
|
|
|
|
|
gBattleMoveDamage = 0;
|
|
|
|
|
gIntroSlideFlags = 0;
|
|
|
|
|
gBattleScripting.animTurn = 0;
|
|
|
|
|
gBattleScripting.animTargetsHit = 0;
|
|
|
|
|
gLeveledUpInBattle = 0;
|
|
|
|
|
gAbsentBattlerFlags = 0;
|
|
|
|
|
gBattleStruct->runTries = 0;
|
|
|
|
|
gBattleStruct->safariRockThrowCounter = 0;
|
|
|
|
|
gBattleStruct->safariBaitThrowCounter = 0;
|
|
|
|
|
*(&gBattleStruct->safariCatchFactor) = gSpeciesInfo[GetMonData(&gEnemyParty[0], MON_DATA_SPECIES)].catchRate * 100 / 1275;
|
|
|
|
|
*(&gBattleStruct->safariEscapeFactor) = gSpeciesInfo[GetMonData(&gEnemyParty[0], MON_DATA_SPECIES)].safariZoneFleeRate * 100 / 1275;
|
|
|
|
|
if (gBattleStruct->safariEscapeFactor <= 1)
|
|
|
|
|
gBattleStruct->safariEscapeFactor = 2;
|
|
|
|
|
gBattleStruct->safariCatchFactor = gSpeciesInfo[GetMonData(&gEnemyParty[0], MON_DATA_SPECIES)].catchRate * 100 / 1275;
|
|
|
|
|
gBattleStruct->safariEscapeFactor = 3;
|
|
|
|
|
gBattleStruct->wildVictorySong = 0;
|
|
|
|
|
gBattleStruct->moneyMultiplier = 1;
|
|
|
|
|
|
|
|
|
|
for (i = 0; i < 8; i++)
|
|
|
|
|
gBattleStruct->givenExpMons = 0;
|
|
|
|
|
|
|
|
|
|
gBattleResults.shinyWildMon = IsMonShiny(&gEnemyParty[0]);
|
|
|
|
|
|
|
|
|
|
gBattleStruct->mega.triggerSpriteId = 0xFF;
|
|
|
|
|
gBattleStruct->burst.triggerSpriteId = 0xFF;
|
|
|
|
|
|
|
|
|
|
for (i = 0; i < ARRAY_COUNT(gSideTimers); i++)
|
|
|
|
|
{
|
|
|
|
|
*((u8 *)gBattleStruct->lastTakenMove + i) = MOVE_NONE;
|
|
|
|
|
*((u8 *)gBattleStruct->usedHeldItems + i) = ITEM_NONE;
|
|
|
|
|
*((u8 *)gBattleStruct->choicedMove + i) = MOVE_NONE;
|
|
|
|
|
*((u8 *)gBattleStruct->changedItems + i) = ITEM_NONE;
|
|
|
|
|
*(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;
|
|
|
|
|
gSideTimers[i].stickyWebBattlerId = 0xFF;
|
|
|
|
|
}
|
|
|
|
|
*(gBattleStruct->AI_monToSwitchIntoId + 0) = PARTY_SIZE;
|
|
|
|
|
*(gBattleStruct->AI_monToSwitchIntoId + 1) = PARTY_SIZE;
|
|
|
|
|
*(&gBattleStruct->givenExpMons) = 0;
|
|
|
|
|
for (i = 0; i < 11; i++)
|
|
|
|
|
gBattleResults.catchAttempts[i] = 0;
|
|
|
|
|
gBattleResults.battleTurnCounter = 0;
|
|
|
|
|
gBattleResults.playerFaintCounter = 0;
|
|
|
|
|
gBattleResults.opponentFaintCounter = 0;
|
|
|
|
|
gBattleResults.playerSwitchesCounter = 0;
|
|
|
|
|
gBattleResults.numHealingItemsUsed = 0;
|
|
|
|
|
gBattleResults.numRevivesUsed = 0;
|
|
|
|
|
gBattleResults.playerMonWasDamaged = FALSE;
|
|
|
|
|
gBattleResults.usedMasterBall = FALSE;
|
|
|
|
|
gBattleResults.lastOpponentSpecies = SPECIES_NONE;
|
|
|
|
|
gBattleResults.lastUsedMovePlayer = MOVE_NONE;
|
|
|
|
|
gBattleResults.lastUsedMoveOpponent = MOVE_NONE;
|
|
|
|
|
gBattleResults.playerMon1Species = SPECIES_NONE;
|
|
|
|
|
gBattleResults.playerMon2Species = SPECIES_NONE;
|
|
|
|
|
gBattleResults.caughtMonSpecies = SPECIES_NONE;
|
|
|
|
|
for (i = 0; i < POKEMON_NAME_LENGTH; ++i)
|
|
|
|
|
gBattleStruct->appearedInBattle = 0;
|
|
|
|
|
gBattleStruct->beatUpSlot = 0;
|
|
|
|
|
|
|
|
|
|
for (i = 0; i < PARTY_SIZE; i++)
|
|
|
|
|
{
|
|
|
|
|
gBattleResults.playerMon1Name[i] = 0;
|
|
|
|
|
gBattleResults.playerMon2Name[i] = 0;
|
|
|
|
|
gBattleResults.caughtMonNick[i] = 0;
|
|
|
|
|
gBattleStruct->usedHeldItems[i][B_SIDE_PLAYER] = 0;
|
|
|
|
|
gBattleStruct->usedHeldItems[i][B_SIDE_OPPONENT] = 0;
|
|
|
|
|
gBattleStruct->itemLost[i].originalItem = GetMonData(&gPlayerParty[i], MON_DATA_HELD_ITEM);
|
|
|
|
|
gPartyCriticalHits[i] = 0;
|
|
|
|
|
gBattleStruct->allowedToChangeFormInWeather[i][B_SIDE_PLAYER] = FALSE;
|
|
|
|
|
gBattleStruct->allowedToChangeFormInWeather[i][B_SIDE_OPPONENT] = FALSE;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
for (i = 0; i < PARTY_SIZE; i++) {
|
|
|
|
|
gPartyCriticalHits[i] = 0;
|
|
|
|
|
}
|
|
|
|
|
gBattleStruct->swapDamageCategory = FALSE; // Photon Geyser, Shell Side Arm, Light That Burns the Sky
|
|
|
|
|
gSelectedMonPartyId = PARTY_SIZE; // Revival Blessing
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void SwitchInClearSetData(void)
|
|
|
|
|
void SwitchInClearSetData(u32 battler)
|
|
|
|
|
{
|
|
|
|
|
struct DisableStruct disableStructCopy = gDisableStructs[gActiveBattler];
|
|
|
|
|
s32 i;
|
|
|
|
|
@@ -2355,12 +2353,12 @@ void SwitchInClearSetData(void)
|
|
|
|
|
if (gMovesInfo[gCurrentMove].effect != EFFECT_BATON_PASS)
|
|
|
|
|
{
|
|
|
|
|
for (i = 0; i < NUM_BATTLE_STATS; i++)
|
|
|
|
|
gBattleMons[gActiveBattler].statStages[i] = DEFAULT_STAT_STAGE;
|
|
|
|
|
gBattleMons[battler].statStages[i] = DEFAULT_STAT_STAGE;
|
|
|
|
|
for (i = 0; i < gBattlersCount; i++)
|
|
|
|
|
{
|
|
|
|
|
if ((gBattleMons[i].status2 & STATUS2_ESCAPE_PREVENTION) && gDisableStructs[i].battlerPreventingEscape == gActiveBattler)
|
|
|
|
|
if ((gBattleMons[i].status2 & STATUS2_ESCAPE_PREVENTION) && gDisableStructs[i].battlerPreventingEscape == battler)
|
|
|
|
|
gBattleMons[i].status2 &= ~STATUS2_ESCAPE_PREVENTION;
|
|
|
|
|
if ((gStatuses3[i] & STATUS3_ALWAYS_HITS) && gDisableStructs[i].battlerWithSureHit == gActiveBattler)
|
|
|
|
|
if ((gStatuses3[i] & STATUS3_ALWAYS_HITS) && gDisableStructs[i].battlerWithSureHit == battler)
|
|
|
|
|
{
|
|
|
|
|
gStatuses3[i] &= ~STATUS3_ALWAYS_HITS;
|
|
|
|
|
gDisableStructs[i].battlerWithSureHit = 0;
|
|
|
|
|
@@ -2369,173 +2367,268 @@ void SwitchInClearSetData(void)
|
|
|
|
|
}
|
|
|
|
|
if (gMovesInfo[gCurrentMove].effect == EFFECT_BATON_PASS)
|
|
|
|
|
{
|
|
|
|
|
gBattleMons[gActiveBattler].status2 &= (STATUS2_CONFUSION | STATUS2_FOCUS_ENERGY | STATUS2_SUBSTITUTE | STATUS2_ESCAPE_PREVENTION | STATUS2_CURSED);
|
|
|
|
|
gStatuses3[gActiveBattler] &= (STATUS3_LEECHSEED_BATTLER | STATUS3_LEECHSEED | STATUS3_ALWAYS_HITS | STATUS3_PERISH_SONG | STATUS3_ROOTED);
|
|
|
|
|
gStatuses4[gActiveBattler] &= (STATUS4_MUD_SPORT | STATUS4_WATER_SPORT);
|
|
|
|
|
gBattleMons[battler].status2 &= (STATUS2_CONFUSION | STATUS2_FOCUS_ENERGY_ANY | STATUS2_SUBSTITUTE | STATUS2_ESCAPE_PREVENTION | STATUS2_CURSED);
|
|
|
|
|
gStatuses3[battler] &= (STATUS3_LEECHSEED_BATTLER | STATUS3_LEECHSEED | STATUS3_ALWAYS_HITS | STATUS3_PERISH_SONG | STATUS3_ROOTED
|
|
|
|
|
| STATUS3_GASTRO_ACID | STATUS3_EMBARGO | STATUS3_TELEKINESIS | STATUS3_MAGNET_RISE | STATUS3_HEAL_BLOCK
|
|
|
|
|
| STATUS3_AQUA_RING | STATUS3_POWER_TRICK);
|
|
|
|
|
gStatuses4[battler] &= (STATUS4_MUD_SPORT | STATUS4_WATER_SPORT | STATUS4_INFINITE_CONFUSION);
|
|
|
|
|
for (i = 0; i < gBattlersCount; i++)
|
|
|
|
|
{
|
|
|
|
|
if (GetBattlerSide(gActiveBattler) != GetBattlerSide(i)
|
|
|
|
|
if (GetBattlerSide(battler) != GetBattlerSide(i)
|
|
|
|
|
&& (gStatuses3[i] & STATUS3_ALWAYS_HITS) != 0
|
|
|
|
|
&& (gDisableStructs[i].battlerWithSureHit == gActiveBattler))
|
|
|
|
|
&& (gDisableStructs[i].battlerWithSureHit == battler))
|
|
|
|
|
{
|
|
|
|
|
gStatuses3[i] &= ~STATUS3_ALWAYS_HITS;
|
|
|
|
|
gStatuses3[i] |= STATUS3_ALWAYS_HITS_TURN(2);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if (gStatuses3[battler] & STATUS3_POWER_TRICK)
|
|
|
|
|
SWAP(gBattleMons[battler].attack, gBattleMons[battler].defense, i);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
gBattleMons[gActiveBattler].status2 = 0;
|
|
|
|
|
gStatuses3[gActiveBattler] = 0;
|
|
|
|
|
gStatuses4[gActiveBattler] = 0;
|
|
|
|
|
gBattleMons[battler].status2 = 0;
|
|
|
|
|
gStatuses3[battler] = 0;
|
|
|
|
|
gStatuses4[battler] = 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
for (i = 0; i < gBattlersCount; i++)
|
|
|
|
|
{
|
|
|
|
|
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)
|
|
|
|
|
if (gBattleMons[i].status2 & STATUS2_INFATUATED_WITH(battler))
|
|
|
|
|
gBattleMons[i].status2 &= ~STATUS2_INFATUATED_WITH(battler);
|
|
|
|
|
if ((gBattleMons[i].status2 & STATUS2_WRAPPED) && *(gBattleStruct->wrappedBy + i) == battler)
|
|
|
|
|
gBattleMons[i].status2 &= ~STATUS2_WRAPPED;
|
|
|
|
|
if ((gStatuses4[i] & STATUS4_SYRUP_BOMB) && *(gBattleStruct->stickySyrupdBy + i) == battler)
|
|
|
|
|
gStatuses4[i] &= ~STATUS4_SYRUP_BOMB;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
gActionSelectionCursor[gActiveBattler] = 0;
|
|
|
|
|
gMoveSelectionCursor[gActiveBattler] = 0;
|
|
|
|
|
gActionSelectionCursor[battler] = 0;
|
|
|
|
|
gMoveSelectionCursor[battler] = 0;
|
|
|
|
|
|
|
|
|
|
ptr = (u8 *)&gDisableStructs[gActiveBattler];
|
|
|
|
|
for (i = 0; i < sizeof(struct DisableStruct); i++)
|
|
|
|
|
ptr[i] = 0;
|
|
|
|
|
memset(&gDisableStructs[battler], 0, sizeof(struct DisableStruct));
|
|
|
|
|
|
|
|
|
|
if (gMovesInfo[gCurrentMove].effect == EFFECT_BATON_PASS)
|
|
|
|
|
{
|
|
|
|
|
gDisableStructs[gActiveBattler].substituteHP = disableStructCopy.substituteHP;
|
|
|
|
|
gDisableStructs[gActiveBattler].battlerWithSureHit = disableStructCopy.battlerWithSureHit;
|
|
|
|
|
gDisableStructs[gActiveBattler].perishSongTimer = disableStructCopy.perishSongTimer;
|
|
|
|
|
// gDisableStructs[gActiveBattler].perishSongTimerStartValue = disableStructCopy.perishSongTimerStartValue;
|
|
|
|
|
gDisableStructs[gActiveBattler].battlerPreventingEscape = disableStructCopy.battlerPreventingEscape;
|
|
|
|
|
gDisableStructs[battler].substituteHP = disableStructCopy.substituteHP;
|
|
|
|
|
gDisableStructs[battler].battlerWithSureHit = disableStructCopy.battlerWithSureHit;
|
|
|
|
|
gDisableStructs[battler].perishSongTimer = disableStructCopy.perishSongTimer;
|
|
|
|
|
gDisableStructs[battler].battlerPreventingEscape = disableStructCopy.battlerPreventingEscape;
|
|
|
|
|
gDisableStructs[battler].embargoTimer = disableStructCopy.embargoTimer;
|
|
|
|
|
}
|
|
|
|
|
else if (gMovesInfo[gCurrentMove].effect == EFFECT_SHED_TAIL)
|
|
|
|
|
{
|
|
|
|
|
gBattleMons[battler].status2 |= STATUS2_SUBSTITUTE;
|
|
|
|
|
gDisableStructs[battler].substituteHP = disableStructCopy.substituteHP;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
gMoveResultFlags = 0;
|
|
|
|
|
gDisableStructs[gActiveBattler].isFirstTurn = 2;
|
|
|
|
|
gLastMoves[gActiveBattler] = MOVE_NONE;
|
|
|
|
|
gLastLandedMoves[gActiveBattler] = MOVE_NONE;
|
|
|
|
|
gLastHitByType[gActiveBattler] = 0;
|
|
|
|
|
gLastResultingMoves[gActiveBattler] = MOVE_NONE;
|
|
|
|
|
gLastPrintedMoves[gActiveBattler] = MOVE_NONE;
|
|
|
|
|
gLastHitBy[gActiveBattler] = 0xFF;
|
|
|
|
|
gDisableStructs[battler].isFirstTurn = 2;
|
|
|
|
|
gDisableStructs[battler].truantSwitchInHack = disableStructCopy.truantSwitchInHack;
|
|
|
|
|
gLastMoves[battler] = MOVE_NONE;
|
|
|
|
|
gLastLandedMoves[battler] = MOVE_NONE;
|
|
|
|
|
gLastHitByType[battler] = 0;
|
|
|
|
|
gLastResultingMoves[battler] = MOVE_NONE;
|
|
|
|
|
gLastPrintedMoves[battler] = MOVE_NONE;
|
|
|
|
|
gLastHitBy[battler] = 0xFF;
|
|
|
|
|
|
|
|
|
|
*(gBattleStruct->lastTakenMove + gActiveBattler * 2 + 0) = MOVE_NONE;
|
|
|
|
|
*(gBattleStruct->lastTakenMove + gActiveBattler * 2 + 1) = MOVE_NONE;
|
|
|
|
|
*(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;
|
|
|
|
|
gBattleStruct->lastTakenMove[battler] = 0;
|
|
|
|
|
gBattleStruct->sameMoveTurns[battler] = 0;
|
|
|
|
|
gBattleStruct->lastTakenMoveFrom[battler][0] = 0;
|
|
|
|
|
gBattleStruct->lastTakenMoveFrom[battler][1] = 0;
|
|
|
|
|
gBattleStruct->lastTakenMoveFrom[battler][2] = 0;
|
|
|
|
|
gBattleStruct->lastTakenMoveFrom[battler][3] = 0;
|
|
|
|
|
gBattleStruct->lastMoveFailed &= ~(gBitTable[battler]);
|
|
|
|
|
|
|
|
|
|
for (i = 0; i < ARRAY_COUNT(gSideTimers); i++)
|
|
|
|
|
{
|
|
|
|
|
// Switched into sticky web user slot, so reset stored battler ID
|
|
|
|
|
if (gSideTimers[i].stickyWebBattlerId == battler)
|
|
|
|
|
gSideTimers[i].stickyWebBattlerId = 0xFF;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
for (i = 0; i < gBattlersCount; i++)
|
|
|
|
|
{
|
|
|
|
|
if (i != gActiveBattler)
|
|
|
|
|
{
|
|
|
|
|
*(gBattleStruct->lastTakenMove + i * 2 + 0) = MOVE_NONE;
|
|
|
|
|
*(gBattleStruct->lastTakenMove + i * 2 + 1) = MOVE_NONE;
|
|
|
|
|
}
|
|
|
|
|
*(i * 8 + gActiveBattler * 2 + (u8 *)(gBattleStruct->lastTakenMoveFrom) + 0) = 0;
|
|
|
|
|
*(i * 8 + gActiveBattler * 2 + (u8 *)(gBattleStruct->lastTakenMoveFrom) + 1) = 0;
|
|
|
|
|
if (i != battler && GetBattlerSide(i) != GetBattlerSide(battler))
|
|
|
|
|
gBattleStruct->lastTakenMove[i] = MOVE_NONE;
|
|
|
|
|
|
|
|
|
|
gBattleStruct->lastTakenMoveFrom[i][battler] = 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
*((u8 *)(&gBattleStruct->choicedMove[gActiveBattler]) + 0) = MOVE_NONE;
|
|
|
|
|
*((u8 *)(&gBattleStruct->choicedMove[gActiveBattler]) + 1) = MOVE_NONE;
|
|
|
|
|
|
|
|
|
|
gBattleResources->flags->flags[gActiveBattler] = 0;
|
|
|
|
|
gBattleStruct->choicedMove[battler] = MOVE_NONE;
|
|
|
|
|
gBattleResources->flags->flags[battler] = 0;
|
|
|
|
|
gCurrentMove = MOVE_NONE;
|
|
|
|
|
|
|
|
|
|
// Reset damage to prevent things like red card activating if the switched-in mon is holding it
|
|
|
|
|
gSpecialStatuses[battler].physicalDmg = 0;
|
|
|
|
|
gSpecialStatuses[battler].specialDmg = 0;
|
|
|
|
|
|
|
|
|
|
// Reset G-Max Chi Strike boosts.
|
|
|
|
|
gBattleStruct->bonusCritStages[battler] = 0;
|
|
|
|
|
|
|
|
|
|
// TODO: Dynamax
|
|
|
|
|
// Reset Dynamax flags.
|
|
|
|
|
// UndoDynamax(battler);
|
|
|
|
|
|
|
|
|
|
gBattleStruct->overwrittenAbilities[battler] = ABILITY_NONE;
|
|
|
|
|
|
|
|
|
|
// Clear selected party ID so Revival Blessing doesn't get confused.
|
|
|
|
|
gSelectedMonPartyId = PARTY_SIZE;
|
|
|
|
|
|
|
|
|
|
// TODO: AI
|
|
|
|
|
// Ai_UpdateSwitchInData(battler);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void FaintClearSetData(void)
|
|
|
|
|
const u8* FaintClearSetData(u32 battler)
|
|
|
|
|
{
|
|
|
|
|
s32 i;
|
|
|
|
|
u8 *ptr;
|
|
|
|
|
const u8 *result = NULL;
|
|
|
|
|
u8 battlerSide = GetBattlerSide(battler);
|
|
|
|
|
|
|
|
|
|
for (i = 0; i < NUM_BATTLE_STATS; i++)
|
|
|
|
|
gBattleMons[gActiveBattler].statStages[i] = DEFAULT_STAT_STAGE;
|
|
|
|
|
gBattleMons[battler].statStages[i] = DEFAULT_STAT_STAGE;
|
|
|
|
|
|
|
|
|
|
gBattleMons[gActiveBattler].status2 = 0;
|
|
|
|
|
gStatuses3[gActiveBattler] = 0;
|
|
|
|
|
gStatuses4[gActiveBattler] = 0;
|
|
|
|
|
gBattleMons[battler].status2 = 0;
|
|
|
|
|
gStatuses3[battler] &= STATUS3_GASTRO_ACID; // Edge case: Keep Gastro Acid if pokemon's ability can have effect after fainting, for example Innards Out.
|
|
|
|
|
gStatuses4[battler] = 0;
|
|
|
|
|
|
|
|
|
|
for (i = 0; i < gBattlersCount; i++)
|
|
|
|
|
{
|
|
|
|
|
if ((gBattleMons[i].status2 & STATUS2_ESCAPE_PREVENTION) && gDisableStructs[i].battlerPreventingEscape == gActiveBattler)
|
|
|
|
|
if ((gBattleMons[i].status2 & STATUS2_ESCAPE_PREVENTION) && gDisableStructs[i].battlerPreventingEscape == battler)
|
|
|
|
|
gBattleMons[i].status2 &= ~STATUS2_ESCAPE_PREVENTION;
|
|
|
|
|
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)
|
|
|
|
|
if (gBattleMons[i].status2 & STATUS2_INFATUATED_WITH(battler))
|
|
|
|
|
gBattleMons[i].status2 &= ~STATUS2_INFATUATED_WITH(battler);
|
|
|
|
|
if ((gBattleMons[i].status2 & STATUS2_WRAPPED) && *(gBattleStruct->wrappedBy + i) == battler)
|
|
|
|
|
gBattleMons[i].status2 &= ~STATUS2_WRAPPED;
|
|
|
|
|
if ((gStatuses4[i] & STATUS4_SYRUP_BOMB) && *(gBattleStruct->stickySyrupdBy + i) == battler)
|
|
|
|
|
gStatuses4[i] &= ~STATUS4_SYRUP_BOMB;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
gActionSelectionCursor[gActiveBattler] = 0;
|
|
|
|
|
gMoveSelectionCursor[gActiveBattler] = 0;
|
|
|
|
|
gActionSelectionCursor[battler] = 0;
|
|
|
|
|
gMoveSelectionCursor[battler] = 0;
|
|
|
|
|
|
|
|
|
|
ptr = (u8 *)&gDisableStructs[gActiveBattler];
|
|
|
|
|
for (i = 0; i < sizeof(struct DisableStruct); i++)
|
|
|
|
|
ptr[i] = 0;
|
|
|
|
|
memset(&gDisableStructs[battler], 0, sizeof(struct DisableStruct));
|
|
|
|
|
|
|
|
|
|
gProtectStructs[gActiveBattler].protected = FALSE;
|
|
|
|
|
gProtectStructs[gActiveBattler].endured = FALSE;
|
|
|
|
|
gProtectStructs[gActiveBattler].noValidMoves = FALSE;
|
|
|
|
|
gProtectStructs[gActiveBattler].helpingHand = FALSE;
|
|
|
|
|
gProtectStructs[gActiveBattler].bounceMove = FALSE;
|
|
|
|
|
gProtectStructs[gActiveBattler].stealMove = FALSE;
|
|
|
|
|
gProtectStructs[gActiveBattler].prlzImmobility = FALSE;
|
|
|
|
|
gProtectStructs[gActiveBattler].confusionSelfDmg = FALSE;
|
|
|
|
|
gProtectStructs[gActiveBattler].targetNotAffected = FALSE;
|
|
|
|
|
gProtectStructs[gActiveBattler].chargingTurn = FALSE;
|
|
|
|
|
gProtectStructs[gActiveBattler].fleeType = 0;
|
|
|
|
|
gProtectStructs[gActiveBattler].usedImprisonedMove = FALSE;
|
|
|
|
|
gProtectStructs[gActiveBattler].loveImmobility = FALSE;
|
|
|
|
|
gProtectStructs[gActiveBattler].usedDisabledMove = FALSE;
|
|
|
|
|
gProtectStructs[gActiveBattler].usedTauntedMove = FALSE;
|
|
|
|
|
gProtectStructs[gActiveBattler].flag2Unknown = FALSE;
|
|
|
|
|
gProtectStructs[gActiveBattler].flinchImmobility = FALSE;
|
|
|
|
|
gProtectStructs[gActiveBattler].notFirstStrike = FALSE;
|
|
|
|
|
gProtectStructs[battler].protected = FALSE;
|
|
|
|
|
gProtectStructs[battler].spikyShielded = FALSE;
|
|
|
|
|
gProtectStructs[battler].kingsShielded = FALSE;
|
|
|
|
|
gProtectStructs[battler].banefulBunkered = FALSE;
|
|
|
|
|
gProtectStructs[battler].quash = FALSE;
|
|
|
|
|
gProtectStructs[battler].obstructed = FALSE;
|
|
|
|
|
gProtectStructs[battler].silkTrapped = FALSE;
|
|
|
|
|
gProtectStructs[battler].burningBulwarked = FALSE;
|
|
|
|
|
gProtectStructs[battler].endured = FALSE;
|
|
|
|
|
gProtectStructs[battler].noValidMoves = FALSE;
|
|
|
|
|
gProtectStructs[battler].helpingHand = FALSE;
|
|
|
|
|
gProtectStructs[battler].bounceMove = FALSE;
|
|
|
|
|
gProtectStructs[battler].stealMove = FALSE;
|
|
|
|
|
gProtectStructs[battler].prlzImmobility = FALSE;
|
|
|
|
|
gProtectStructs[battler].confusionSelfDmg = FALSE;
|
|
|
|
|
gProtectStructs[battler].targetAffected = FALSE;
|
|
|
|
|
gProtectStructs[battler].chargingTurn = FALSE;
|
|
|
|
|
gProtectStructs[battler].fleeType = 0;
|
|
|
|
|
gProtectStructs[battler].usedImprisonedMove = FALSE;
|
|
|
|
|
gProtectStructs[battler].loveImmobility = FALSE;
|
|
|
|
|
gProtectStructs[battler].usedDisabledMove = FALSE;
|
|
|
|
|
gProtectStructs[battler].usedTauntedMove = FALSE;
|
|
|
|
|
gProtectStructs[battler].flag2Unknown = FALSE;
|
|
|
|
|
gProtectStructs[battler].flinchImmobility = FALSE;
|
|
|
|
|
gProtectStructs[battler].notFirstStrike = FALSE;
|
|
|
|
|
gProtectStructs[battler].usedHealBlockedMove = FALSE;
|
|
|
|
|
gProtectStructs[battler].usesBouncedMove = FALSE;
|
|
|
|
|
gProtectStructs[battler].usedGravityPreventedMove = FALSE;
|
|
|
|
|
gProtectStructs[battler].usedThroatChopPreventedMove = FALSE;
|
|
|
|
|
gProtectStructs[battler].statRaised = FALSE;
|
|
|
|
|
gProtectStructs[battler].statFell = FALSE;
|
|
|
|
|
gProtectStructs[battler].pranksterElevated = FALSE;
|
|
|
|
|
|
|
|
|
|
gDisableStructs[gActiveBattler].isFirstTurn = 2;
|
|
|
|
|
gDisableStructs[battler].isFirstTurn = 2;
|
|
|
|
|
|
|
|
|
|
gLastMoves[gActiveBattler] = MOVE_NONE;
|
|
|
|
|
gLastLandedMoves[gActiveBattler] = MOVE_NONE;
|
|
|
|
|
gLastHitByType[gActiveBattler] = 0;
|
|
|
|
|
gLastResultingMoves[gActiveBattler] = MOVE_NONE;
|
|
|
|
|
gLastPrintedMoves[gActiveBattler] = MOVE_NONE;
|
|
|
|
|
gLastHitBy[gActiveBattler] = 0xFF;
|
|
|
|
|
gLastMoves[battler] = MOVE_NONE;
|
|
|
|
|
gLastLandedMoves[battler] = MOVE_NONE;
|
|
|
|
|
gLastHitByType[battler] = 0;
|
|
|
|
|
gLastResultingMoves[battler] = MOVE_NONE;
|
|
|
|
|
gLastPrintedMoves[battler] = MOVE_NONE;
|
|
|
|
|
gLastHitBy[battler] = 0xFF;
|
|
|
|
|
|
|
|
|
|
*((u8 *)(&gBattleStruct->choicedMove[gActiveBattler]) + 0) = MOVE_NONE;
|
|
|
|
|
*((u8 *)(&gBattleStruct->choicedMove[gActiveBattler]) + 1) = MOVE_NONE;
|
|
|
|
|
gBattleStruct->choicedMove[battler] = MOVE_NONE;
|
|
|
|
|
gBattleStruct->sameMoveTurns[battler] = 0;
|
|
|
|
|
gBattleStruct->lastTakenMove[battler] = MOVE_NONE;
|
|
|
|
|
gBattleStruct->lastTakenMoveFrom[battler][0] = 0;
|
|
|
|
|
gBattleStruct->lastTakenMoveFrom[battler][1] = 0;
|
|
|
|
|
gBattleStruct->lastTakenMoveFrom[battler][2] = 0;
|
|
|
|
|
gBattleStruct->lastTakenMoveFrom[battler][3] = 0;
|
|
|
|
|
|
|
|
|
|
*(gBattleStruct->lastTakenMove + gActiveBattler * 2 + 0) = MOVE_NONE;
|
|
|
|
|
*(gBattleStruct->lastTakenMove + gActiveBattler * 2 + 1) = MOVE_NONE;
|
|
|
|
|
*(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;
|
|
|
|
|
for (i = 0; i < ARRAY_COUNT(gSideTimers); i++)
|
|
|
|
|
{
|
|
|
|
|
// User of sticky web fainted, so reset the stored battler ID
|
|
|
|
|
if (gSideTimers[i].stickyWebBattlerId == battler)
|
|
|
|
|
gSideTimers[i].stickyWebBattlerId = 0xFF;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
for (i = 0; i < gBattlersCount; i++)
|
|
|
|
|
{
|
|
|
|
|
if (i != gActiveBattler)
|
|
|
|
|
{
|
|
|
|
|
*(gBattleStruct->lastTakenMove + i * 2 + 0) = MOVE_NONE;
|
|
|
|
|
*(gBattleStruct->lastTakenMove + i * 2 + 1) = MOVE_NONE;
|
|
|
|
|
}
|
|
|
|
|
*(i * 8 + gActiveBattler * 2 + (u8 *)(gBattleStruct->lastTakenMoveFrom) + 0) = 0;
|
|
|
|
|
*(i * 8 + gActiveBattler * 2 + (u8 *)(gBattleStruct->lastTakenMoveFrom) + 1) = 0;
|
|
|
|
|
if (i != battler && GetBattlerSide(i) != battlerSide)
|
|
|
|
|
gBattleStruct->lastTakenMove[i] = MOVE_NONE;
|
|
|
|
|
|
|
|
|
|
gBattleStruct->lastTakenMoveFrom[i][battler] = 0;
|
|
|
|
|
}
|
|
|
|
|
gBattleResources->flags->flags[gActiveBattler] = 0;
|
|
|
|
|
gBattleMons[gActiveBattler].type1 = gSpeciesInfo[gBattleMons[gActiveBattler].species].types[0];
|
|
|
|
|
gBattleMons[gActiveBattler].type2 = gSpeciesInfo[gBattleMons[gActiveBattler].species].types[1];
|
|
|
|
|
|
|
|
|
|
gBattleResources->flags->flags[battler] = 0;
|
|
|
|
|
|
|
|
|
|
gBattleMons[battler].type1 = gSpeciesInfo[gBattleMons[battler].species].types[0];
|
|
|
|
|
gBattleMons[battler].type2 = gSpeciesInfo[gBattleMons[battler].species].types[1];
|
|
|
|
|
gBattleMons[battler].type3 = TYPE_MYSTERY;
|
|
|
|
|
|
|
|
|
|
// TODO: AI
|
|
|
|
|
// Ai_UpdateFaintData(battler);
|
|
|
|
|
TryBattleFormChange(battler, FORM_CHANGE_FAINT);
|
|
|
|
|
|
|
|
|
|
gBattleStruct->overwrittenAbilities[battler] = ABILITY_NONE;
|
|
|
|
|
|
|
|
|
|
// If the fainted mon was involved in a Sky Drop
|
|
|
|
|
if (gBattleStruct->skyDropTargets[battler] != 0xFF)
|
|
|
|
|
{
|
|
|
|
|
// Get battler id of the other Pokemon involved in this Sky Drop
|
|
|
|
|
u8 otherSkyDropper = gBattleStruct->skyDropTargets[battler];
|
|
|
|
|
|
|
|
|
|
// Clear Sky Drop data
|
|
|
|
|
gBattleStruct->skyDropTargets[battler] = 0xFF;
|
|
|
|
|
gBattleStruct->skyDropTargets[otherSkyDropper] = 0xFF;
|
|
|
|
|
|
|
|
|
|
// If the other Pokemon involved in this Sky Drop was the target, not the attacker
|
|
|
|
|
if (gStatuses3[otherSkyDropper] & STATUS3_SKY_DROPPED)
|
|
|
|
|
{
|
|
|
|
|
// Release the target and take them out of the semi-invulnerable state
|
|
|
|
|
gStatuses3[otherSkyDropper] &= ~(STATUS3_SKY_DROPPED | STATUS3_ON_AIR);
|
|
|
|
|
|
|
|
|
|
// Make the target's sprite visible
|
|
|
|
|
gSprites[gBattlerSpriteIds[otherSkyDropper]].invisible = FALSE;
|
|
|
|
|
|
|
|
|
|
// If the target was sky dropped in the middle of using Outrage/Petal Dance/Thrash,
|
|
|
|
|
// confuse them upon release and print "confused via fatigue" message and animation.
|
|
|
|
|
if (gBattleMons[otherSkyDropper].status2 & STATUS2_LOCK_CONFUSE)
|
|
|
|
|
{
|
|
|
|
|
gBattleMons[otherSkyDropper].status2 &= ~(STATUS2_LOCK_CONFUSE);
|
|
|
|
|
|
|
|
|
|
// If the released mon can be confused, do so.
|
|
|
|
|
// Don't use CanBeConfused here, since it can cause issues in edge cases.
|
|
|
|
|
if (!(GetBattlerAbility(otherSkyDropper) == ABILITY_OWN_TEMPO
|
|
|
|
|
|| gBattleMons[otherSkyDropper].status2 & STATUS2_CONFUSION
|
|
|
|
|
|| IsBattlerTerrainAffected(otherSkyDropper, STATUS_FIELD_MISTY_TERRAIN)))
|
|
|
|
|
{
|
|
|
|
|
gBattleMons[otherSkyDropper].status2 |= STATUS2_CONFUSION_TURN(((Random()) % 4) + 2);
|
|
|
|
|
gBattlerAttacker = otherSkyDropper;
|
|
|
|
|
result = BattleScript_ThrashConfuses;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Clear Z-Move data
|
|
|
|
|
gBattleStruct->zmove.active = FALSE;
|
|
|
|
|
gBattleStruct->zmove.toBeUsed[battler] = MOVE_NONE;
|
|
|
|
|
gBattleStruct->zmove.effect = EFFECT_HIT;
|
|
|
|
|
return result;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void BattleIntroGetMonsData(void)
|
|
|
|
|
@@ -3646,47 +3739,52 @@ static void SetActionsAndBattlersTurnOrder(void)
|
|
|
|
|
static void TurnValuesCleanUp(bool8 var0)
|
|
|
|
|
{
|
|
|
|
|
s32 i;
|
|
|
|
|
u8 *dataPtr;
|
|
|
|
|
|
|
|
|
|
for (gActiveBattler = 0; gActiveBattler < gBattlersCount; gActiveBattler++)
|
|
|
|
|
for (i = 0; i < gBattlersCount; i++)
|
|
|
|
|
{
|
|
|
|
|
if (var0)
|
|
|
|
|
{
|
|
|
|
|
gProtectStructs[gActiveBattler].protected = FALSE;
|
|
|
|
|
gProtectStructs[gActiveBattler].endured = FALSE;
|
|
|
|
|
gProtectStructs[i].protected = FALSE;
|
|
|
|
|
gProtectStructs[i].spikyShielded = FALSE;
|
|
|
|
|
gProtectStructs[i].kingsShielded = FALSE;
|
|
|
|
|
gProtectStructs[i].banefulBunkered = FALSE;
|
|
|
|
|
gProtectStructs[i].quash = FALSE;
|
|
|
|
|
gProtectStructs[i].usedCustapBerry = FALSE;
|
|
|
|
|
gProtectStructs[i].quickDraw = FALSE;
|
|
|
|
|
memset(&gQueuedStatBoosts[i], 0, sizeof(struct QueuedStatBoost));
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
dataPtr = (u8 *)(&gProtectStructs[gActiveBattler]);
|
|
|
|
|
for (i = 0; i < sizeof(struct ProtectStruct); i++)
|
|
|
|
|
dataPtr[i] = 0;
|
|
|
|
|
if (gDisableStructs[gActiveBattler].isFirstTurn)
|
|
|
|
|
--gDisableStructs[gActiveBattler].isFirstTurn;
|
|
|
|
|
if (gDisableStructs[gActiveBattler].rechargeTimer)
|
|
|
|
|
memset(&gProtectStructs[i], 0, sizeof(struct ProtectStruct));
|
|
|
|
|
|
|
|
|
|
if (gDisableStructs[i].isFirstTurn)
|
|
|
|
|
gDisableStructs[i].isFirstTurn--;
|
|
|
|
|
|
|
|
|
|
if (gDisableStructs[i].rechargeTimer)
|
|
|
|
|
{
|
|
|
|
|
--gDisableStructs[gActiveBattler].rechargeTimer;
|
|
|
|
|
if (gDisableStructs[gActiveBattler].rechargeTimer == 0)
|
|
|
|
|
gBattleMons[gActiveBattler].status2 &= ~(STATUS2_RECHARGE);
|
|
|
|
|
gDisableStructs[i].rechargeTimer--;
|
|
|
|
|
if (gDisableStructs[i].rechargeTimer == 0)
|
|
|
|
|
gBattleMons[i].status2 &= ~STATUS2_RECHARGE;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (gDisableStructs[gActiveBattler].substituteHP == 0)
|
|
|
|
|
gBattleMons[gActiveBattler].status2 &= ~(STATUS2_SUBSTITUTE);
|
|
|
|
|
if (gDisableStructs[i].substituteHP == 0)
|
|
|
|
|
gBattleMons[i].status2 &= ~STATUS2_SUBSTITUTE;
|
|
|
|
|
|
|
|
|
|
gSpecialStatuses[i].parentalBondState = PARENTAL_BOND_OFF;
|
|
|
|
|
}
|
|
|
|
|
gSideTimers[0].followmeTimer = 0;
|
|
|
|
|
gSideTimers[1].followmeTimer = 0;
|
|
|
|
|
|
|
|
|
|
gSideStatuses[B_SIDE_PLAYER] &= ~(SIDE_STATUS_QUICK_GUARD | SIDE_STATUS_WIDE_GUARD | SIDE_STATUS_CRAFTY_SHIELD | SIDE_STATUS_MAT_BLOCK);
|
|
|
|
|
gSideStatuses[B_SIDE_OPPONENT] &= ~(SIDE_STATUS_QUICK_GUARD | SIDE_STATUS_WIDE_GUARD | SIDE_STATUS_CRAFTY_SHIELD | SIDE_STATUS_MAT_BLOCK);
|
|
|
|
|
gSideTimers[B_SIDE_PLAYER].followmeTimer = 0;
|
|
|
|
|
gSideTimers[B_SIDE_OPPONENT].followmeTimer = 0;
|
|
|
|
|
|
|
|
|
|
gBattleStruct->pledgeMove = FALSE; // combined pledge move may not have been used due to a canceller
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void SpecialStatusesClear(void)
|
|
|
|
|
void SpecialStatusesClear(void)
|
|
|
|
|
{
|
|
|
|
|
for (gActiveBattler = 0; gActiveBattler < gBattlersCount; gActiveBattler++)
|
|
|
|
|
{
|
|
|
|
|
s32 i;
|
|
|
|
|
u8 *dataPtr = (u8 *)(&gSpecialStatuses[gActiveBattler]);
|
|
|
|
|
|
|
|
|
|
for (i = 0; i < sizeof(struct SpecialStatus); i++)
|
|
|
|
|
dataPtr[i] = 0;
|
|
|
|
|
}
|
|
|
|
|
memset(&gSpecialStatuses, 0, sizeof(gSpecialStatuses));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void CheckFocusPunch_ClearVarsBeforeTurnStarts(void)
|
|
|
|
|
|