Simplified skyDropTargets storage and made other minor improvements

A lot of these changes are based on ghoulslash's version of Sky Drop.
This commit is contained in:
W1serV1ser 2021-12-23 15:27:11 -08:00
parent 5d1228fc2e
commit 58a5a9cbec
3 changed files with 140 additions and 238 deletions

View file

@ -2871,6 +2871,7 @@ static void BattleStartClearSetData(void)
gBattleStruct->lastTakenMoveFrom[i][2] = 0; gBattleStruct->lastTakenMoveFrom[i][2] = 0;
gBattleStruct->lastTakenMoveFrom[i][3] = 0; gBattleStruct->lastTakenMoveFrom[i][3] = 0;
gBattleStruct->AI_monToSwitchIntoId[i] = PARTY_SIZE; gBattleStruct->AI_monToSwitchIntoId[i] = PARTY_SIZE;
gBattleStruct->skyDropTargets[i] = 0xFF;
} }
gLastUsedMove = 0; gLastUsedMove = 0;
@ -2945,12 +2946,6 @@ static void BattleStartClearSetData(void)
} }
gSwapDamageCategory = FALSE; // Photon Geyser, Shell Side Arm, Light That Burns the Sky gSwapDamageCategory = FALSE; // Photon Geyser, Shell Side Arm, Light That Burns the Sky
// Clear skyDropTargets data
for (i = 0; i < 4; i++)
{
gBattleStruct->skyDropTargets[i] = 0xFF;
}
} }
void SwitchInClearSetData(void) void SwitchInClearSetData(void)
@ -3087,56 +3082,6 @@ void FaintClearSetData(void)
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_WRAPPED) && *(gBattleStruct->wrappedBy + i) == gActiveBattler)
gBattleMons[i].status2 &= ~(STATUS2_WRAPPED); gBattleMons[i].status2 &= ~(STATUS2_WRAPPED);
// If the fainted mon was holding another Pokemon in Sky Drop, release the mon and clear Sky Drop data
if (gActiveBattler == gBattleStruct->skyDropTargets[0] && i == gBattleStruct->skyDropTargets[1])
{
gBattleStruct->skyDropTargets[0] = 0xFF;
gBattleStruct->skyDropTargets[1] = 0xFF;
gStatuses3[i] &= ~(STATUS3_SKY_DROPPED | STATUS3_ON_AIR);
gSprites[gBattlerSpriteIds[i]].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[i].status2 & STATUS2_LOCK_CONFUSE)
{
gBattleMons[i].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(i) == ABILITY_OWN_TEMPO
|| gBattleMons[i].status2 & STATUS2_CONFUSION
|| IsBattlerTerrainAffected(i, STATUS_FIELD_MISTY_TERRAIN)))
{
gBattleMons[i].status2 |= STATUS2_CONFUSION_TURN(((Random()) % 4) + 2);
gBattlerAttacker = i;
gBattlescriptCurrInstr = BattleScript_ThrashConfuses - 2;
}
}
}
else if (gActiveBattler == gBattleStruct->skyDropTargets[2] && i == gBattleStruct->skyDropTargets[3])
{
gBattleStruct->skyDropTargets[2] = 0xFF;
gBattleStruct->skyDropTargets[3] = 0xFF;
gStatuses3[i] &= ~(STATUS3_SKY_DROPPED | STATUS3_ON_AIR);
gSprites[gBattlerSpriteIds[i]].invisible = FALSE;
if (gBattleMons[i].status2 & STATUS2_LOCK_CONFUSE)
{
gBattleMons[i].status2 &= ~(STATUS2_LOCK_CONFUSE);
gEffectBattler = i;
if (!(GetBattlerAbility(i) == ABILITY_OWN_TEMPO
|| gBattleMons[i].status2 & STATUS2_CONFUSION
|| IsBattlerTerrainAffected(i, STATUS_FIELD_MISTY_TERRAIN)))
{
gBattleMons[i].status2 |= STATUS2_CONFUSION_TURN(((Random()) % 4) + 2);
gBattlerAttacker = i;
gBattlescriptCurrInstr = BattleScript_ThrashConfuses - 2;
}
}
}
} }
gActionSelectionCursor[gActiveBattler] = 0; gActionSelectionCursor[gActiveBattler] = 0;
@ -3216,12 +3161,45 @@ void FaintClearSetData(void)
UndoFormChange(gBattlerPartyIndexes[gActiveBattler], GET_BATTLER_SIDE(gActiveBattler), FALSE); UndoFormChange(gBattlerPartyIndexes[gActiveBattler], GET_BATTLER_SIDE(gActiveBattler), FALSE);
if (GetBattlerSide(gActiveBattler) == B_SIDE_PLAYER) if (GetBattlerSide(gActiveBattler) == B_SIDE_PLAYER)
UndoMegaEvolution(gBattlerPartyIndexes[gActiveBattler]); UndoMegaEvolution(gBattlerPartyIndexes[gActiveBattler]);
// If the fainted Pokemon was being held by Sky Drop, clear their Sky Drop data. // If the fainted mon was involved in a Sky Drop
if (gActiveBattler == gBattleStruct->skyDropTargets[1]) if (gBattleStruct->skyDropTargets[gActiveBattler] != 0xFF)
gBattleStruct->skyDropTargets[1] = 0xFF; {
else if (gActiveBattler == gBattleStruct->skyDropTargets[3]) // Get battler id of the other Pokemon involved in this Sky Drop
gBattleStruct->skyDropTargets[3] = 0xFF; u8 otherSkyDropper = gBattleStruct->skyDropTargets[gActiveBattler];
// Clear Sky Drop data
gBattleStruct->skyDropTargets[gActiveBattler] = 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;
gBattlescriptCurrInstr = BattleScript_ThrashConfuses - 2;
}
}
}
}
} }
static void DoBattleIntro(void) static void DoBattleIntro(void)

View file

@ -1610,14 +1610,14 @@ static bool32 AccuracyCalcHelper(u16 move)
return TRUE; return TRUE;
} }
// If the attacker has the ability No Guard and they aren't targeting a Pokemon involved in a Sky Drop with the move Sky Drop, move hits. // If the attacker has the ability No Guard and they aren't targeting a Pokemon involved in a Sky Drop with the move Sky Drop, move hits.
else if (GetBattlerAbility(gBattlerAttacker) == ABILITY_NO_GUARD && (move != MOVE_SKY_DROP || (gBattlerTarget != gBattleStruct->skyDropTargets[0] && gBattlerTarget != gBattleStruct->skyDropTargets[1] && gBattlerTarget != gBattleStruct->skyDropTargets[2] && gBattlerTarget != gBattleStruct->skyDropTargets[3]))) else if (GetBattlerAbility(gBattlerAttacker) == ABILITY_NO_GUARD && (move != MOVE_SKY_DROP || gBattleStruct->skyDropTargets[gBattlerTarget] == 0xFF))
{ {
if (!JumpIfMoveFailed(7, move)) if (!JumpIfMoveFailed(7, move))
RecordAbilityBattle(gBattlerAttacker, ABILITY_NO_GUARD); RecordAbilityBattle(gBattlerAttacker, ABILITY_NO_GUARD);
return TRUE; return TRUE;
} }
// If the target has the ability No Guard and they aren't involved in a Sky Drop or the current move isn't Sky Drop, move hits. // If the target has the ability No Guard and they aren't involved in a Sky Drop or the current move isn't Sky Drop, move hits.
else if (GetBattlerAbility(gBattlerTarget) == ABILITY_NO_GUARD && (move != MOVE_SKY_DROP || (gBattlerTarget != gBattleStruct->skyDropTargets[0] && gBattlerTarget != gBattleStruct->skyDropTargets[1] && gBattlerTarget != gBattleStruct->skyDropTargets[2] && gBattlerTarget != gBattleStruct->skyDropTargets[3]))) else if (GetBattlerAbility(gBattlerTarget) == ABILITY_NO_GUARD && (move != MOVE_SKY_DROP || gBattleStruct->skyDropTargets[gBattlerTarget] == 0xFF))
{ {
if (!JumpIfMoveFailed(7, move)) if (!JumpIfMoveFailed(7, move))
RecordAbilityBattle(gBattlerTarget, ABILITY_NO_GUARD); RecordAbilityBattle(gBattlerTarget, ABILITY_NO_GUARD);
@ -1625,7 +1625,7 @@ static bool32 AccuracyCalcHelper(u16 move)
} }
if ((gStatuses3[gBattlerTarget] & STATUS3_PHANTOM_FORCE) if ((gStatuses3[gBattlerTarget] & STATUS3_PHANTOM_FORCE)
|| (!(gBattleMoves[move].flags & FLAG_DMG_IN_AIR || gBattleMoves[move].flags & FLAG_DMG_2X_IN_AIR) && gStatuses3[gBattlerTarget] & STATUS3_ON_AIR) || (!(gBattleMoves[move].flags & (FLAG_DMG_IN_AIR | FLAG_DMG_2X_IN_AIR)) && gStatuses3[gBattlerTarget] & STATUS3_ON_AIR)
|| (!(gBattleMoves[move].flags & FLAG_DMG_UNDERGROUND) && gStatuses3[gBattlerTarget] & STATUS3_UNDERGROUND) || (!(gBattleMoves[move].flags & FLAG_DMG_UNDERGROUND) && gStatuses3[gBattlerTarget] & STATUS3_UNDERGROUND)
|| (!(gBattleMoves[move].flags & FLAG_DMG_UNDERWATER) && gStatuses3[gBattlerTarget] & STATUS3_UNDERWATER)) || (!(gBattleMoves[move].flags & FLAG_DMG_UNDERWATER) && gStatuses3[gBattlerTarget] & STATUS3_UNDERWATER))
{ {
@ -5153,23 +5153,27 @@ static void Cmd_moveend(void)
} }
gBattleScripting.moveendState++; gBattleScripting.moveendState++;
break; break;
case MOVEEND_SKY_DROP_CONFUSE: // If a Pokemon was released from Sky Drop and was in LOCK_CONFUSE, go to "confused due to fatigue scripts and clear Sky Drop data. case MOVEEND_SKY_DROP_CONFUSE: // If a Pokemon was released from Sky Drop and was in LOCK_CONFUSE, go to "confused due to fatigue" scripts and clear Sky Drop data.
for (i = 0; i < gBattlersCount; i++) for (i = 0; i < gBattlersCount; i++)
{ {
if (gBattleStruct->skyDropTargets[0] == 0xFE - i) if (gBattleStruct->skyDropTargets[i] == 0xFE)
{ {
gBattlerAttacker = gBattleStruct->skyDropTargets[1]; // Find the battler id of the Pokemon that was held by Sky Drop
for (arg1 = 0; arg1 < gBattlersCount; arg1++)
{
if (gBattleStruct->skyDropTargets[arg1] == i)
break;
}
// Set gBattlerAttacker to the battler id of the target
gBattlerAttacker = arg1;
// Jump to "confused due to fatigue" script
gBattlescriptCurrInstr = BattleScript_ThrashConfuses; gBattlescriptCurrInstr = BattleScript_ThrashConfuses;
gBattleStruct->skyDropTargets[0] = 0xFF;
gBattleStruct->skyDropTargets[1] = 0xFF; // Clear skyDropTargets data
return; gBattleStruct->skyDropTargets[i] = 0xFF;
} gBattleStruct->skyDropTargets[arg1] = 0xFF;
else if (gBattleStruct->skyDropTargets[2] == 0xFE - i)
{
gBattlerAttacker = gBattleStruct->skyDropTargets[3];
gBattlescriptCurrInstr = BattleScript_ThrashConfuses;
gBattleStruct->skyDropTargets[2] = 0xFF;
gBattleStruct->skyDropTargets[3] = 0xFF;
return; return;
} }
} }
@ -7715,10 +7719,10 @@ static void Cmd_various(void)
return; return;
case VARIOUS_GRAVITY_ON_AIRBORNE_MONS: case VARIOUS_GRAVITY_ON_AIRBORNE_MONS:
// Cancel all multiturn moves of IN_AIR Pokemon except those being targeted by Sky Drop. // Cancel all multiturn moves of IN_AIR Pokemon except those being targeted by Sky Drop.
if (gStatuses3[gActiveBattler] & STATUS3_ON_AIR && !(gActiveBattler == gBattleStruct->skyDropTargets[1] || gActiveBattler == gBattleStruct->skyDropTargets[3])) if (gStatuses3[gActiveBattler] & STATUS3_ON_AIR && !(gStatuses3[gActiveBattler] & STATUS3_SKY_DROPPED))
CancelMultiTurnMoves(gActiveBattler); CancelMultiTurnMoves(gActiveBattler);
gStatuses3[gActiveBattler] &= ~(STATUS3_MAGNET_RISE | STATUS3_TELEKINESIS | STATUS3_ON_AIR); gStatuses3[gActiveBattler] &= ~(STATUS3_MAGNET_RISE | STATUS3_TELEKINESIS | STATUS3_ON_AIR | STATUS3_SKY_DROPPED);
break; break;
case VARIOUS_SPECTRAL_THIEF: case VARIOUS_SPECTRAL_THIEF:
// Raise stats // Raise stats
@ -8927,7 +8931,7 @@ static void Cmd_various(void)
MarkBattlerForControllerExec(gActiveBattler); MarkBattlerForControllerExec(gActiveBattler);
} }
if (gBattleMons[gActiveBattler].pp[i] == 0 && !(gActiveBattler == gBattleStruct->skyDropTargets[0] || gActiveBattler == gBattleStruct->skyDropTargets[2])) if (gBattleMons[gActiveBattler].pp[i] == 0 && gBattleStruct->skyDropTargets[gActiveBattler] == 0xFF)
CancelMultiTurnMoves(gActiveBattler); CancelMultiTurnMoves(gActiveBattler);
gBattlescriptCurrInstr += 7; // continue gBattlescriptCurrInstr += 7; // continue
@ -9003,21 +9007,13 @@ static void Cmd_various(void)
return; return;
case VARIOUS_SET_SKY_DROP: case VARIOUS_SET_SKY_DROP:
gStatuses3[gBattlerTarget] |= (STATUS3_SKY_DROPPED | STATUS3_ON_AIR); gStatuses3[gBattlerTarget] |= (STATUS3_SKY_DROPPED | STATUS3_ON_AIR);
/* skyDropTargets holds the information of who is the attacker and the target of Sky Drop. /* skyDropTargets holds the information of who is in a particular instance of Sky Drop.
This is needed in the case that multiple Pokemon use Sky Drop in the same turn or if This is needed in the case that multiple Pokemon use Sky Drop in the same turn or if
the target of a Sky Drop faints while in the air.*/ the target of a Sky Drop faints while in the air.*/
if (gBattleStruct->skyDropTargets[0] == 0xFF) gBattleStruct->skyDropTargets[gBattlerAttacker] = gBattlerTarget;
{ gBattleStruct->skyDropTargets[gBattlerTarget] = gBattlerAttacker;
gBattleStruct->skyDropTargets[0] = gBattlerAttacker;
gBattleStruct->skyDropTargets[1] = gBattlerTarget;
}
else
{
gBattleStruct->skyDropTargets[2] = gBattlerAttacker;
gBattleStruct->skyDropTargets[3] = gBattlerTarget;
}
// End any multiturn effects caused by the target // End any multiturn effects caused by the target except STATUS2_LOCK_CONFUSE
gBattleMons[gBattlerTarget].status2 &= ~(STATUS2_MULTIPLETURNS); gBattleMons[gBattlerTarget].status2 &= ~(STATUS2_MULTIPLETURNS);
gBattleMons[gBattlerTarget].status2 &= ~(STATUS2_UPROAR); gBattleMons[gBattlerTarget].status2 &= ~(STATUS2_UPROAR);
gBattleMons[gBattlerTarget].status2 &= ~(STATUS2_BIDE); gBattleMons[gBattlerTarget].status2 &= ~(STATUS2_BIDE);
@ -9025,34 +9021,16 @@ static void Cmd_various(void)
gDisableStructs[gBattlerTarget].furyCutterCounter = 0; gDisableStructs[gBattlerTarget].furyCutterCounter = 0;
break; break;
case VARIOUS_CLEAR_SKY_DROP: case VARIOUS_CLEAR_SKY_DROP:
if (gBattleStruct->skyDropTargets[0] == gBattlerAttacker) // Check to see if the initial target of this Sky Drop fainted before the 2nd turn of Sky Drop.
{ // If so, make the move fail. If not, clear all of the statuses and continue the move.
// Check to see if the initial target of this Sky Drop fainted before the 2nd turn of Sky Drop. if (gBattleStruct->skyDropTargets[gBattlerAttacker] == 0xFF)
// If so, make the move fail. If not, clear all of the statuses and continue the move. gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 3);
if (gBattleStruct->skyDropTargets[1] == 0xFF)
gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 3);
else
{
gStatuses3[gBattlerTarget] &= ~(STATUS3_SKY_DROPPED | STATUS3_ON_AIR);
gBattlescriptCurrInstr += 7;
}
// Clear skyDropTargets data
gBattleStruct->skyDropTargets[0] = 0xFF;
gBattleStruct->skyDropTargets[1] = 0xFF;
}
else else
{ {
if (gBattleStruct->skyDropTargets[3] == 0xFF) gBattleStruct->skyDropTargets[gBattlerAttacker] = 0xFF;
gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 3); gBattleStruct->skyDropTargets[gBattlerTarget] = 0xFF;
else gStatuses3[gBattlerTarget] &= ~(STATUS3_SKY_DROPPED | STATUS3_ON_AIR);
{ gBattlescriptCurrInstr += 7;
gStatuses3[gBattlerTarget] &= ~(STATUS3_SKY_DROPPED | STATUS3_ON_AIR);
gBattlescriptCurrInstr += 7;
}
gBattleStruct->skyDropTargets[2] = 0xFF;
gBattleStruct->skyDropTargets[3] = 0xFF;
} }
// Confuse target if they were in the middle of Petal Dance/Outrage/Thrash when targeted. // Confuse target if they were in the middle of Petal Dance/Outrage/Thrash when targeted.
@ -9060,28 +9038,19 @@ static void Cmd_various(void)
gBattleScripting.moveEffect = (MOVE_EFFECT_CONFUSION | MOVE_EFFECT_CERTAIN); gBattleScripting.moveEffect = (MOVE_EFFECT_CONFUSION | MOVE_EFFECT_CERTAIN);
return; return;
case VARIOUS_SKY_DROP_YAWN: // If the mon that's sleeping due to Yawn was holding a Pokemon in Sky Drop, release the target and clear Sky Drop data. case VARIOUS_SKY_DROP_YAWN: // If the mon that's sleeping due to Yawn was holding a Pokemon in Sky Drop, release the target and clear Sky Drop data.
if (gEffectBattler == gBattleStruct->skyDropTargets[0]) if (gBattleStruct->skyDropTargets[gEffectBattler] != 0xFF && !(gStatuses3[gEffectBattler] & STATUS3_SKY_DROPPED))
{ {
gEffectBattler = gBattleStruct->skyDropTargets[1]; // Set the target of Sky Drop as gEffectBattler
gBattleStruct->skyDropTargets[0] = 0xFF; gEffectBattler = gBattleStruct->skyDropTargets[gEffectBattler];
gBattleStruct->skyDropTargets[1] = 0xFF;
gBattleMons[gEffectBattler].status2 &= ~(STATUS2_LOCK_CONFUSE); // Clear skyDropTargets data
if (CanBeConfused(gEffectBattler)) gBattleStruct->skyDropTargets[gBattleStruct->skyDropTargets[gEffectBattler]] = 0xFF;
{ gBattleStruct->skyDropTargets[gEffectBattler] = 0xFF;
gBattlerAttacker = gEffectBattler;
gBattleMons[gBattlerTarget].status2 |= STATUS2_CONFUSION_TURN(((Random()) % 4) + 2); // If the target was in the middle of Outrage/Thrash/etc. when targeted by Sky Drop, confuse them on release and do proper animation
gBattlescriptCurrInstr = BattleScript_ThrashConfuses; if (gBattleMons[gEffectBattler].status2 & STATUS2_LOCK_CONFUSE && CanBeConfused(gEffectBattler))
return;
}
}
else if (gEffectBattler == gBattleStruct->skyDropTargets[2])
{
gEffectBattler = gBattleStruct->skyDropTargets[3];
gBattleStruct->skyDropTargets[2] = 0xFF;
gBattleStruct->skyDropTargets[3] = 0xFF;
gBattleMons[gEffectBattler].status2 &= ~(STATUS2_LOCK_CONFUSE);
if (CanBeConfused(gEffectBattler))
{ {
gBattleMons[gEffectBattler].status2 &= ~(STATUS2_LOCK_CONFUSE);
gBattlerAttacker = gEffectBattler; gBattlerAttacker = gEffectBattler;
gBattleMons[gBattlerTarget].status2 |= STATUS2_CONFUSION_TURN(((Random()) % 4) + 2); gBattleMons[gBattlerTarget].status2 |= STATUS2_CONFUSION_TURN(((Random()) % 4) + 2);
gBattlescriptCurrInstr = BattleScript_ThrashConfuses; gBattlescriptCurrInstr = BattleScript_ThrashConfuses;
@ -11482,7 +11451,7 @@ static void Cmd_tryspiteppreduce(void)
gBattlescriptCurrInstr += 5; gBattlescriptCurrInstr += 5;
// Don't cut off Sky Drop if pp is brought to zero. // Don't cut off Sky Drop if pp is brought to zero.
if (gBattleMons[gBattlerTarget].pp[i] == 0 && !(gBattlerTarget == gBattleStruct->skyDropTargets[0] || gBattlerTarget == gBattleStruct->skyDropTargets[2])) if (gBattleMons[gBattlerTarget].pp[i] == 0 && gBattleStruct->skyDropTargets[gBattlerTarget] == 0xFF)
CancelMultiTurnMoves(gBattlerTarget); CancelMultiTurnMoves(gBattlerTarget);
} }
else else

View file

@ -1427,117 +1427,72 @@ void CancelMultiTurnMoves(u8 battler)
gBattleMons[battler].status2 &= ~(STATUS2_UPROAR); gBattleMons[battler].status2 &= ~(STATUS2_UPROAR);
gBattleMons[battler].status2 &= ~(STATUS2_BIDE); gBattleMons[battler].status2 &= ~(STATUS2_BIDE);
// Don't clear battler's semi-invulnerable bits if they are held by Sky Drop. // Clear battler's semi-invulnerable bits if they are not held by Sky Drop.
if (gBattleStruct->skyDropTargets[1] != battler && gBattleStruct->skyDropTargets[3] != battler) if (!(gStatuses3[battler] & STATUS3_SKY_DROPPED))
gStatuses3[battler] &= ~(STATUS3_SEMI_INVULNERABLE); gStatuses3[battler] &= ~(STATUS3_SEMI_INVULNERABLE);
// Check to see if this Pokemon was in the middle of using Sky Drop. If so, release the target. // Check to see if this Pokemon was in the middle of using Sky Drop. If so, release the target.
if (gBattleStruct->skyDropTargets[0] == battler) if (gBattleStruct->skyDropTargets[battler] != 0xFF && !(gStatuses3[battler] & STATUS3_SKY_DROPPED))
{ {
// Sets skyDropTargets[1] to be the battler id for the target // Get the target's battler id
for (i = 0; i < MAX_BATTLERS_COUNT; i++) u8 otherSkyDropper = gBattleStruct->skyDropTargets[battler];
// Clears sky_dropped and on_air statuses
gStatuses3[otherSkyDropper] &= ~(STATUS3_SKY_DROPPED | STATUS3_ON_AIR);
// Makes both attacker and target's sprites visible
gSprites[gBattlerSpriteIds[battler]].invisible = FALSE;
gSprites[gBattlerSpriteIds[otherSkyDropper]].invisible = FALSE;
// If target was sky dropped in the middle of Outrage/Thrash/Petal Dance,
// confuse them upon release and display "confused by fatigue" message & animation.
// Don't do this if this CancelMultiTurnMoves is caused by falling asleep via Yawn.
if (gBattleMons[otherSkyDropper].status2 & STATUS2_LOCK_CONFUSE && gBattleStruct->turnEffectsTracker != 24)
{ {
if (gBattleStruct->skyDropTargets[1] == i) gBattleMons[otherSkyDropper].status2 &= ~(STATUS2_LOCK_CONFUSE);
// If the target can be confused, confuse them.
// Don't use CanBeConfused, can cause issues in edge cases.
if (!(GetBattlerAbility(otherSkyDropper) == ABILITY_OWN_TEMPO
|| gBattleMons[otherSkyDropper].status2 & STATUS2_CONFUSION
|| IsBattlerTerrainAffected(otherSkyDropper, STATUS_FIELD_MISTY_TERRAIN)))
{ {
// Clears sky dropped and on_air statuses // Set confused status
gStatuses3[i] &= ~(STATUS3_SKY_DROPPED | STATUS3_ON_AIR); gBattleMons[otherSkyDropper].status2 |= STATUS2_CONFUSION_TURN(((Random()) % 4) + 2);
// Makes both attacker and target's sprites visible // If this CancelMultiTurnMoves is occuring due to attackcanceller
gSprites[gBattlerSpriteIds[battler]].invisible = FALSE; if (gBattlescriptCurrInstr[0] == 0x0)
gSprites[gBattlerSpriteIds[i]].invisible = FALSE;
// If target was sky dropped in the middle of Outrage/Thrash/Petal Dance,
// confuse them upon release and display "confused by fatigue" message & animation.
// Don't do this if this CancelMultiTurnMoves is caused by falling asleep via Yawn.
if (gBattleMons[i].status2 & STATUS2_LOCK_CONFUSE && gBattleStruct->turnEffectsTracker != 24)
{ {
gBattleMons[i].status2 &= ~(STATUS2_LOCK_CONFUSE); gBattleStruct->skyDropTargets[battler] = 0xFE;
}
// If the target can be confused, confuse them. // If this CancelMultiTurnMoves is occuring due to VARIOUS_GRAVITY_ON_AIRBORNE_MONS
// Don't use CanBeConfused, can cause issues in edge cases. // Reapplying STATUS3_SKY_DROPPED allows for avoiding unecessary messages when Gravity is applied to the target.
if (!(GetBattlerAbility(i) == ABILITY_OWN_TEMPO else if (gBattlescriptCurrInstr[0] == 0x76 && gBattlescriptCurrInstr[2] == 76)
|| gBattleMons[i].status2 & STATUS2_CONFUSION {
|| IsBattlerTerrainAffected(i, STATUS_FIELD_MISTY_TERRAIN))) gBattleStruct->skyDropTargets[battler] = 0xFE;
{ gStatuses3[otherSkyDropper] |= STATUS3_SKY_DROPPED;
gBattleMons[i].status2 |= STATUS2_CONFUSION_TURN(((Random()) % 4) + 2); }
// If this CancelMultiTurnMoves is occuring due to cancelmultiturnmoves script
// If this CancelMultiTurnMoves is occuring due to attackcanceller or VARIOUS_GRAVITY_ON_AIRBORNE_MONS else if (gBattlescriptCurrInstr[0] == 0x76 && gBattlescriptCurrInstr[2] == 0)
if (gBattlescriptCurrInstr[0] == 0x0 || (gBattlescriptCurrInstr[0] == 0x76 && gBattlescriptCurrInstr[2] == 76)) {
{ gBattlerAttacker = otherSkyDropper;
gBattleStruct->skyDropTargets[0] = 0xFE - battler; gBattlescriptCurrInstr = BattleScript_ThrashConfuses - 3;
} }
// If this CancelMultiTurnMoves is occuring due to cancelmultiturnmoves script // If this CancelMultiTurnMoves is occuring due to receiving Sleep/Freeze status
else if (gBattlescriptCurrInstr[0] == 0x76 && gBattlescriptCurrInstr[2] == 0) else if (gBattleScripting.moveEffect <= PRIMARY_STATUS_MOVE_EFFECT)
{ {
gBattlerAttacker = i; gBattlerAttacker = otherSkyDropper;
gBattlescriptCurrInstr = BattleScript_ThrashConfuses - 3; BattleScriptPush(gBattlescriptCurrInstr + 1);
} gBattlescriptCurrInstr = BattleScript_ThrashConfuses - 1;
// If this CancelMultiTurnMoves is occuring due to receiving Sleep/Freeze status
else if (gBattleScripting.moveEffect <= PRIMARY_STATUS_MOVE_EFFECT)
{
gBattlerAttacker = i;
BattleScriptPush(gBattlescriptCurrInstr + 1);
gBattlescriptCurrInstr = BattleScript_ThrashConfuses - 1;
}
}
} }
break;
} }
} }
// Clear skyDropTargets data, unless this CancelMultiTurnMoves is caused by Yawn, attackcanceler, or VARIOUS_GRAVITY_ON_AIRBORNE_MONS // Clear skyDropTargets data, unless this CancelMultiTurnMoves is caused by Yawn, attackcanceler, or VARIOUS_GRAVITY_ON_AIRBORNE_MONS
if (!(gBattleMons[gBattleStruct->skyDropTargets[1]].status2 & STATUS2_LOCK_CONFUSE) && gBattleStruct->skyDropTargets[0] < 4) if (!(gBattleMons[otherSkyDropper].status2 & STATUS2_LOCK_CONFUSE) && gBattleStruct->skyDropTargets[battler] < 4)
{ {
gBattleStruct->skyDropTargets[0] = 0xFF; gBattleStruct->skyDropTargets[battler] = 0xFF;
gBattleStruct->skyDropTargets[1] = 0xFF; gBattleStruct->skyDropTargets[otherSkyDropper] = 0xFF;
}
}
else if (gBattleStruct->skyDropTargets[2] == battler)
{
for (i = 0; i < MAX_BATTLERS_COUNT; i++)
{
if (gBattleStruct->skyDropTargets[3] == i)
{
gStatuses3[i] &= ~(STATUS3_SKY_DROPPED | STATUS3_ON_AIR);
gSprites[gBattlerSpriteIds[battler]].invisible = FALSE;
gSprites[gBattlerSpriteIds[i]].invisible = FALSE;
if (gBattleMons[i].status2 & STATUS2_LOCK_CONFUSE && gBattleStruct->turnEffectsTracker != 24)
{
gBattleMons[i].status2 &= ~(STATUS2_LOCK_CONFUSE);
if (!(GetBattlerAbility(i) == ABILITY_OWN_TEMPO
|| gBattleMons[i].status2 & STATUS2_CONFUSION
|| IsBattlerTerrainAffected(i, STATUS_FIELD_MISTY_TERRAIN)))
{
gBattleMons[i].status2 |= STATUS2_CONFUSION_TURN(((Random()) % 4) + 2);
if (gBattlescriptCurrInstr[0] == 0x0 || (gBattlescriptCurrInstr[0] == 0x76 && gBattlescriptCurrInstr[2] == 76))
{
gBattleStruct->skyDropTargets[2] = 0xFE - battler;
}
else if (gBattlescriptCurrInstr[0] == 0x76 && gBattlescriptCurrInstr[2] == 0)
{
gBattlerAttacker = i;
gBattlescriptCurrInstr = BattleScript_ThrashConfuses - 3;
}
else if (gBattleScripting.moveEffect <= PRIMARY_STATUS_MOVE_EFFECT)
{
gBattlerAttacker = i;
BattleScriptPush(gBattlescriptCurrInstr + 1);
gBattlescriptCurrInstr = BattleScript_ThrashConfuses - 1;
}
}
}
break;
}
}
if (!(gBattleMons[gBattleStruct->skyDropTargets[3]].status2 & STATUS2_LOCK_CONFUSE) && gBattleStruct->skyDropTargets[2] < 4)
{
gBattleStruct->skyDropTargets[2] = 0xFF;
gBattleStruct->skyDropTargets[3] = 0xFF;
} }
} }