Ally Switch extra battlerId tracking (#5823)
Co-authored-by: ghoulslash <pokevoyager0@gmail.com>
This commit is contained in:
parent
99ba36b446
commit
11bc9bd2f2
@ -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)
|
static void AnimTask_AllySwitchDataSwap(u8 taskId)
|
||||||
{
|
{
|
||||||
s32 i, j;
|
s32 i, j;
|
||||||
@ -6692,6 +6765,10 @@ static void AnimTask_AllySwitchDataSwap(u8 taskId)
|
|||||||
SwitchTwoBattlersInParty(battlerAtk, battlerPartner);
|
SwitchTwoBattlersInParty(battlerAtk, battlerPartner);
|
||||||
SWAP(gBattlerPartyIndexes[battlerAtk], gBattlerPartyIndexes[battlerPartner], temp);
|
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 Snipe Shot and abilities Stalwart/Propeller Tail - keep the original target.
|
||||||
for (i = 0; i < MAX_BATTLERS_COUNT; i++)
|
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
|
// 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");
|
//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!");
|
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…
x
Reference in New Issue
Block a user