Ally Switch extra battlerId tracking (#5823)
Co-authored-by: ghoulslash <pokevoyager0@gmail.com>
This commit is contained in:
parent
99ba36b446
commit
11bc9bd2f2
3 changed files with 179 additions and 0 deletions
|
@ -6642,6 +6642,79 @@ static void ReloadBattlerSprites(u32 battler, struct Pokemon *party)
|
|||
}
|
||||
}
|
||||
|
||||
static void TrySwapSkyDropTargets(u32 battlerAtk, u32 battlerPartner)
|
||||
{
|
||||
u32 i, temp;
|
||||
|
||||
// battlerAtk is using Ally Switch
|
||||
// check if our partner is the target of sky drop
|
||||
// If so, change that index to battlerAtk
|
||||
for (i = 0; i < gBattlersCount; i++) {
|
||||
if (gBattleStruct->skyDropTargets[i] == battlerPartner) {
|
||||
gBattleStruct->skyDropTargets[i] = battlerAtk;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Then swap our own sky drop targets with the partner in case our partner is mid-skydrop
|
||||
SWAP(gBattleStruct->skyDropTargets[battlerAtk], gBattleStruct->skyDropTargets[battlerPartner], temp);
|
||||
}
|
||||
|
||||
#define TRY_SIDE_TIMER_BATTLER_ID_SWAP(battlerAtk, battlerPartner, side, field) \
|
||||
if (gSideTimers[side].field == battlerAtk) \
|
||||
gSideTimers[side].field = battlerPartner; \
|
||||
else if (gSideTimers[side].field == battlerPartner) \
|
||||
gSideTimers[side].field = battlerAtk;
|
||||
|
||||
static void TrySwapStickyWebBattlerId(u32 battlerAtk, u32 battlerPartner)
|
||||
{
|
||||
u32 atkSide = GetBattlerSide(battlerAtk);
|
||||
u32 oppSide = GetBattlerSide(BATTLE_OPPOSITE(battlerAtk));
|
||||
|
||||
// not all of these are needed to be swapped, but are done so to be robust to anything in the future that might care about them
|
||||
TRY_SIDE_TIMER_BATTLER_ID_SWAP(battlerAtk, battlerPartner, atkSide, reflectBattlerId);
|
||||
TRY_SIDE_TIMER_BATTLER_ID_SWAP(battlerAtk, battlerPartner, atkSide, lightscreenBattlerId);
|
||||
TRY_SIDE_TIMER_BATTLER_ID_SWAP(battlerAtk, battlerPartner, atkSide, mistBattlerId);
|
||||
TRY_SIDE_TIMER_BATTLER_ID_SWAP(battlerAtk, battlerPartner, atkSide, safeguardBattlerId);
|
||||
TRY_SIDE_TIMER_BATTLER_ID_SWAP(battlerAtk, battlerPartner, atkSide, auroraVeilBattlerId);
|
||||
TRY_SIDE_TIMER_BATTLER_ID_SWAP(battlerAtk, battlerPartner, atkSide, tailwindBattlerId);
|
||||
TRY_SIDE_TIMER_BATTLER_ID_SWAP(battlerAtk, battlerPartner, atkSide, luckyChantBattlerId);
|
||||
|
||||
// if we've set sticky web on the opposing side, need to swap stickyWebBattlerId for mirror armor
|
||||
TRY_SIDE_TIMER_BATTLER_ID_SWAP(battlerAtk, battlerPartner, oppSide, stickyWebBattlerId);
|
||||
}
|
||||
#undef TRY_SIDE_TIMER_BATTLER_ID_SWAP
|
||||
|
||||
static void TrySwapWishBattlerIds(u32 battlerAtk, u32 battlerPartner)
|
||||
{
|
||||
u32 i, temp;
|
||||
u32 oppSide = GetBattlerSide(BATTLE_OPPOSITE(battlerAtk));
|
||||
|
||||
// if used future sight on opposing side, properly track who used it
|
||||
if (gSideStatuses[oppSide] & SIDE_STATUS_FUTUREATTACK) {
|
||||
for (i = 0; i < gBattlersCount; i++) {
|
||||
if (IsAlly(i,battlerAtk))
|
||||
continue; // only on opposing side
|
||||
if (gWishFutureKnock.futureSightBattlerIndex[i] == battlerAtk) {
|
||||
// if target was attacked with future sight from us, now they'll be the partner slot
|
||||
gWishFutureKnock.futureSightBattlerIndex[i] = battlerPartner;
|
||||
gWishFutureKnock.futureSightPartyIndex[i] = gBattlerPartyIndexes[battlerPartner];
|
||||
break;
|
||||
} else if (gWishFutureKnock.futureSightBattlerIndex[i] == battlerPartner) {
|
||||
gWishFutureKnock.futureSightBattlerIndex[i] = battlerAtk;
|
||||
gWishFutureKnock.futureSightPartyIndex[i] = gBattlerPartyIndexes[battlerAtk];
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// swap wish party indices
|
||||
if (gWishFutureKnock.wishCounter[battlerAtk] > 0
|
||||
|| gWishFutureKnock.wishCounter[battlerPartner] > 0) {
|
||||
SWAP(gWishFutureKnock.wishPartyId[battlerAtk], gWishFutureKnock.wishPartyId[battlerPartner], temp);
|
||||
}
|
||||
}
|
||||
|
||||
static void AnimTask_AllySwitchDataSwap(u8 taskId)
|
||||
{
|
||||
s32 i, j;
|
||||
|
@ -6692,6 +6765,10 @@ static void AnimTask_AllySwitchDataSwap(u8 taskId)
|
|||
SwitchTwoBattlersInParty(battlerAtk, battlerPartner);
|
||||
SWAP(gBattlerPartyIndexes[battlerAtk], gBattlerPartyIndexes[battlerPartner], temp);
|
||||
|
||||
TrySwapSkyDropTargets(battlerAtk, battlerPartner);
|
||||
TrySwapStickyWebBattlerId(battlerAtk, battlerPartner);
|
||||
TrySwapWishBattlerIds(battlerAtk, battlerPartner);
|
||||
|
||||
// For Snipe Shot and abilities Stalwart/Propeller Tail - keep the original target.
|
||||
for (i = 0; i < MAX_BATTLERS_COUNT; i++)
|
||||
{
|
||||
|
|
|
@ -203,5 +203,79 @@ DOUBLE_BATTLE_TEST("Ally Switch works if ally used two-turn move like Dig")
|
|||
}
|
||||
}
|
||||
|
||||
DOUBLE_BATTLE_TEST("Ally switch swaps sky drop targets if being used by partner")
|
||||
{
|
||||
u8 visibility;
|
||||
GIVEN {
|
||||
ASSUME(gMovesInfo[MOVE_SKY_DROP].effect == EFFECT_SKY_DROP);
|
||||
PLAYER(SPECIES_FEAROW) { Speed(100); }
|
||||
PLAYER(SPECIES_XATU) { Speed(150); }
|
||||
OPPONENT(SPECIES_ARON) { Speed(25); Ability(ABILITY_STURDY); }
|
||||
OPPONENT(SPECIES_WYNAUT) { Speed(30); }
|
||||
} WHEN {
|
||||
TURN { MOVE(playerLeft, MOVE_SKY_DROP, target: opponentLeft); }
|
||||
TURN { MOVE(playerRight, MOVE_ALLY_SWITCH); SKIP_TURN(playerLeft); MOVE(opponentRight, MOVE_MUD_SPORT); MOVE(opponentLeft, MOVE_IRON_DEFENSE); }
|
||||
} SCENE {
|
||||
MESSAGE("Fearow used Sky Drop!");
|
||||
MESSAGE("Fearow took the opposing Aron into the sky!");
|
||||
// turn 2
|
||||
MESSAGE("Xatu used Ally Switch!");
|
||||
MESSAGE("Xatu and Fearow switched places!");
|
||||
MESSAGE("Fearow used Sky Drop!");
|
||||
HP_BAR(opponentLeft);
|
||||
MESSAGE("The opposing Wynaut used Mud Sport!");
|
||||
ANIMATION(ANIM_TYPE_MOVE, MOVE_MUD_SPORT, opponentRight);
|
||||
MESSAGE("The opposing Aron used Iron Defense!");
|
||||
ANIMATION(ANIM_TYPE_MOVE, MOVE_IRON_DEFENSE, opponentLeft);
|
||||
} THEN {
|
||||
// all battlers should be visible
|
||||
visibility = gBattleSpritesDataPtr->battlerData[0].invisible;
|
||||
EXPECT_EQ(visibility, 0);
|
||||
visibility = gBattleSpritesDataPtr->battlerData[1].invisible;
|
||||
EXPECT_EQ(visibility, 0);
|
||||
visibility = gBattleSpritesDataPtr->battlerData[2].invisible;
|
||||
EXPECT_EQ(visibility, 0);
|
||||
visibility = gBattleSpritesDataPtr->battlerData[3].invisible;
|
||||
EXPECT_EQ(visibility, 0);
|
||||
}
|
||||
}
|
||||
|
||||
DOUBLE_BATTLE_TEST("Ally switch swaps opposing sky drop targets if partner is being held in the air")
|
||||
{
|
||||
u8 visibility;
|
||||
GIVEN {
|
||||
ASSUME(gMovesInfo[MOVE_SKY_DROP].effect == EFFECT_SKY_DROP);
|
||||
PLAYER(SPECIES_ARON) { Speed(25); Ability(ABILITY_STURDY); }
|
||||
PLAYER(SPECIES_WYNAUT) { Speed(30); }
|
||||
OPPONENT(SPECIES_FEAROW) { Speed(100); }
|
||||
OPPONENT(SPECIES_XATU) { Speed(150); }
|
||||
} WHEN {
|
||||
TURN { MOVE(opponentLeft, MOVE_SKY_DROP, target: playerLeft); }
|
||||
TURN { MOVE(opponentRight, MOVE_ALLY_SWITCH); SKIP_TURN(opponentLeft); MOVE(playerRight, MOVE_MUD_SPORT); MOVE(playerLeft, MOVE_IRON_DEFENSE); }
|
||||
} SCENE {
|
||||
MESSAGE("The opposing Fearow used Sky Drop!");
|
||||
MESSAGE("The opposing Fearow took Aron into the sky!");
|
||||
// turn 2
|
||||
MESSAGE("The opposing Xatu used Ally Switch!");
|
||||
MESSAGE("The opposing Xatu and the opposing Fearow switched places!");
|
||||
MESSAGE("The opposing Fearow used Sky Drop!");
|
||||
HP_BAR(playerLeft);
|
||||
MESSAGE("Wynaut used Mud Sport!");
|
||||
ANIMATION(ANIM_TYPE_MOVE, MOVE_MUD_SPORT, playerRight);
|
||||
MESSAGE("Aron used Iron Defense!");
|
||||
ANIMATION(ANIM_TYPE_MOVE, MOVE_IRON_DEFENSE, playerLeft);
|
||||
} THEN {
|
||||
// all battlers should be visible
|
||||
visibility = gBattleSpritesDataPtr->battlerData[0].invisible;
|
||||
EXPECT_EQ(visibility, 0);
|
||||
visibility = gBattleSpritesDataPtr->battlerData[1].invisible;
|
||||
EXPECT_EQ(visibility, 0);
|
||||
visibility = gBattleSpritesDataPtr->battlerData[2].invisible;
|
||||
EXPECT_EQ(visibility, 0);
|
||||
visibility = gBattleSpritesDataPtr->battlerData[3].invisible;
|
||||
EXPECT_EQ(visibility, 0);
|
||||
}
|
||||
}
|
||||
|
||||
// Triple Battles required to test
|
||||
//TO_DO_BATTLE_TEST("Ally Switch fails if the user is in the middle of the field in a Triple Battle");
|
||||
|
|
|
@ -271,3 +271,31 @@ SINGLE_BATTLE_TEST("Sticky Web is placed on the correct side after Memento")
|
|||
MESSAGE("A sticky web has been laid out on the ground around your team!");
|
||||
}
|
||||
}
|
||||
|
||||
DOUBLE_BATTLE_TEST("Sticky Web setter has their speed lowered with Mirror Armor even after Ally Switch")
|
||||
{
|
||||
GIVEN {
|
||||
PLAYER(SPECIES_SQUIRTLE);
|
||||
PLAYER(SPECIES_CHARMANDER);
|
||||
PLAYER(SPECIES_CORVIKNIGHT) { Ability(ABILITY_MIRROR_ARMOR); Item(ITEM_IRON_BALL); } // Iron Ball, so that flying type Corviknight is affected by Sticky Web.
|
||||
OPPONENT(SPECIES_CATERPIE);
|
||||
OPPONENT(SPECIES_NATU);
|
||||
} WHEN {
|
||||
TURN { MOVE(opponentLeft, MOVE_STICKY_WEB); }
|
||||
TURN { MOVE(opponentRight, MOVE_ALLY_SWITCH); }
|
||||
TURN { SWITCH(playerRight, 2); }
|
||||
} SCENE {
|
||||
// Turn 1 - set up sticky web
|
||||
ANIMATION(ANIM_TYPE_MOVE, MOVE_STICKY_WEB, opponentLeft);
|
||||
MESSAGE("A sticky web has been laid out on the ground around your team!");
|
||||
// Turn 2 - ally switch
|
||||
MESSAGE("The opposing Natu used Ally Switch!");
|
||||
// turn 3 - send our corviknight
|
||||
SEND_IN_MESSAGE("Corviknight");
|
||||
MESSAGE("Corviknight was caught in a sticky web!");
|
||||
ABILITY_POPUP(playerRight, ABILITY_MIRROR_ARMOR);
|
||||
// sticky web setter - caterpie (now opponentRight) gets speed lowered
|
||||
ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_STATS_CHANGE, opponentRight);
|
||||
MESSAGE("The opposing Caterpie's Speed fell!");
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue