Fixes wrong battler's Illusion wearing off when the Attacker faints and fixes Illusion tests (#6596)

This commit is contained in:
PhallenTree 2025-04-14 17:17:24 +01:00 committed by GitHub
parent 40c5ad5043
commit 3b05d7934f
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
6 changed files with 66 additions and 22 deletions

View File

@ -7030,9 +7030,9 @@ BattleScript_BattlerFormChangeWithStringEnd3::
BattleScript_IllusionOff::
spriteignore0hp TRUE
playanimation BS_TARGET, B_ANIM_ILLUSION_OFF
playanimation BS_SCRIPTING, B_ANIM_ILLUSION_OFF
waitanimation
updatenick BS_TARGET
updatenick BS_SCRIPTING
waitstate
spriteignore0hp FALSE
printstring STRINGID_ILLUSIONWOREOFF

View File

@ -699,7 +699,7 @@ const u8 *const gBattleStringsTable[BATTLESTRINGS_COUNT] =
[STRINGID_AIRBALLOONPOP] = COMPOUND_STRING("{B_DEF_NAME_WITH_PREFIX}'s Air Balloon popped!"),
[STRINGID_INCINERATEBURN] = COMPOUND_STRING("{B_EFF_NAME_WITH_PREFIX}'s {B_LAST_ITEM} was burnt up!"),
[STRINGID_BUGBITE] = COMPOUND_STRING("{B_ATK_NAME_WITH_PREFIX} stole and ate its target's {B_LAST_ITEM}!"),
[STRINGID_ILLUSIONWOREOFF] = COMPOUND_STRING("{B_DEF_NAME_WITH_PREFIX}'s illusion wore off!"),
[STRINGID_ILLUSIONWOREOFF] = COMPOUND_STRING("{B_SCR_NAME_WITH_PREFIX}'s illusion wore off!"),
[STRINGID_ATTACKERCUREDTARGETSTATUS] = COMPOUND_STRING("{B_ATK_NAME_WITH_PREFIX} cured {B_DEF_NAME_WITH_PREFIX2}'s problem!"),
[STRINGID_ATTACKERLOSTFIRETYPE] = COMPOUND_STRING("{B_ATK_NAME_WITH_PREFIX} burned itself out!"),
[STRINGID_HEALERCURE] = COMPOUND_STRING("{B_ATK_NAME_WITH_PREFIX}'s {B_LAST_ABILITY} cured {B_SCR_NAME_WITH_PREFIX2}'s problem!"),

View File

@ -10178,6 +10178,7 @@ static void Cmd_various(void)
VARIOUS_ARGS();
if (GetIllusionMonPtr(battler) != NULL)
{
gBattleScripting.battler = battler;
gBattlescriptCurrInstr = cmd->nextInstr;
BattleScriptPushCursor();
gBattlescriptCurrInstr = BattleScript_IllusionOff;

View File

@ -6013,6 +6013,7 @@ u32 AbilityBattleEffects(u32 caseID, u32 battler, u32 ability, u32 special, u32
case ABILITY_ILLUSION:
if (gBattleStruct->illusion[gBattlerTarget].on && !gBattleStruct->illusion[gBattlerTarget].broken && IsBattlerTurnDamaged(gBattlerTarget))
{
gBattleScripting.battler = gBattlerTarget;
BattleScriptPushCursor();
gBattlescriptCurrInstr = BattleScript_IllusionOff;
effect++;
@ -11269,19 +11270,12 @@ bool32 SetIllusionMon(struct Pokemon *mon, u32 battler)
{
struct Pokemon *party, *partnerMon;
s32 i, id;
u8 side, partyCount;
gBattleStruct->illusion[battler].set = 1;
if (GetMonAbility(mon) != ABILITY_ILLUSION)
return FALSE;
party = GetBattlerParty(battler);
side = GetBattlerSide(battler);
partyCount = side == B_SIDE_PLAYER ? gPlayerPartyCount : gEnemyPartyCount;
// If this pokemon is last in the party, ignore Illusion.
if (&party[partyCount - 1] == mon)
return FALSE;
if (IsBattlerAlive(BATTLE_PARTNER(battler)))
partnerMon = &party[gBattlerPartyIndexes[BATTLE_PARTNER(battler)]];
@ -11294,15 +11288,21 @@ bool32 SetIllusionMon(struct Pokemon *mon, u32 battler)
id = i;
if (GetMonData(&party[id], MON_DATA_SANITY_HAS_SPECIES)
&& GetMonData(&party[id], MON_DATA_HP)
&& !GetMonData(&party[id], MON_DATA_IS_EGG)
&& &party[id] != mon
&& &party[id] != partnerMon)
&& !GetMonData(&party[id], MON_DATA_IS_EGG))
{
gBattleStruct->illusion[battler].on = 1;
gBattleStruct->illusion[battler].broken = 0;
gBattleStruct->illusion[battler].partyId = id;
gBattleStruct->illusion[battler].mon = &party[id];
return TRUE;
if (&party[id] != mon && &party[id] != partnerMon)
{
gBattleStruct->illusion[battler].on = 1;
gBattleStruct->illusion[battler].broken = 0;
gBattleStruct->illusion[battler].partyId = id;
gBattleStruct->illusion[battler].mon = &party[id];
return TRUE;
}
else if (&party[id] == mon)
{
// If this pokemon is last in the party, ignore Illusion.
return FALSE;
}
}
}

View File

@ -22,3 +22,50 @@ SINGLE_BATTLE_TEST("Illusion can only imitate Normal Form terapagos")
TURN { MOVE(player, MOVE_CELEBRATE); MOVE(opponent, MOVE_TACKLE); }
}
}
SINGLE_BATTLE_TEST("Illusion breaks if the target faints")
{
GIVEN {
PLAYER(SPECIES_ZOROARK) { HP(1); }
PLAYER(SPECIES_WOBBUFFET);
OPPONENT(SPECIES_WOBBUFFET);
} WHEN {
TURN { MOVE(opponent, MOVE_TACKLE); SEND_OUT(player, 1); }
} SCENE {
ANIMATION(ANIM_TYPE_MOVE, MOVE_TACKLE, opponent);
HP_BAR(player);
ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_ILLUSION_OFF, player);
MESSAGE("Zoroark's illusion wore off!");
}
}
SINGLE_BATTLE_TEST("Illusion breaks if the attacker faints")
{
GIVEN {
ASSUME(GetMoveEffect(MOVE_FINAL_GAMBIT) == EFFECT_FINAL_GAMBIT);
PLAYER(SPECIES_ZOROARK) { HP(1); }
PLAYER(SPECIES_WOBBUFFET);
OPPONENT(SPECIES_WOBBUFFET);
} WHEN {
TURN { MOVE(player, MOVE_FINAL_GAMBIT); SEND_OUT(player, 1); }
} SCENE {
ANIMATION(ANIM_TYPE_MOVE, MOVE_FINAL_GAMBIT, player);
HP_BAR(player);
ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_ILLUSION_OFF, player);
MESSAGE("Zoroark's illusion wore off!");
}
}
SINGLE_BATTLE_TEST("Illusion cannot imitate if the user is on the last slot")
{
GIVEN {
PLAYER(SPECIES_WOBBUFFET);
PLAYER(SPECIES_ZOROARK);
OPPONENT(SPECIES_WOBBUFFET);
} WHEN {
TURN { SWITCH(player, 1); }
} THEN {
EXPECT_EQ(player->species, SPECIES_ZOROARK);
EXPECT_EQ(gBattleStruct->illusion[0].on, FALSE); // Battler is Zoroark and not Illusioned
}
}

View File

@ -277,11 +277,8 @@ DOUBLE_BATTLE_TEST("Ally switch swaps opposing sky drop targets if partner is be
}
}
// Test passes in isolation but fails on CI
/*
DOUBLE_BATTLE_TEST("Ally Switch swaps Illusion data")
{
KNOWN_FAILING; // Test passes in isolation but fails on CI
GIVEN {
ASSUME(GetMoveEffect(MOVE_ALLY_SWITCH) == EFFECT_ALLY_SWITCH);
PLAYER(SPECIES_HOOPA);
@ -295,7 +292,6 @@ DOUBLE_BATTLE_TEST("Ally Switch swaps Illusion data")
EXPECT(&gPlayerParty[2] == gBattleStruct->illusion[0].mon);
}
}
*/
// 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");