diff --git a/data/battle_scripts_1.s b/data/battle_scripts_1.s index a394ae30db..e8224b25fa 100644 --- a/data/battle_scripts_1.s +++ b/data/battle_scripts_1.s @@ -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 diff --git a/src/battle_message.c b/src/battle_message.c index 995f7756c6..7b02496ac7 100644 --- a/src/battle_message.c +++ b/src/battle_message.c @@ -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!"), diff --git a/src/battle_script_commands.c b/src/battle_script_commands.c index 3a2690fb55..ee367133dd 100644 --- a/src/battle_script_commands.c +++ b/src/battle_script_commands.c @@ -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; diff --git a/src/battle_util.c b/src/battle_util.c index b9b43ab663..1597674c17 100644 --- a/src/battle_util.c +++ b/src/battle_util.c @@ -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; + } } } diff --git a/test/battle/ability/illusion.c b/test/battle/ability/illusion.c index ca3bcb2ee0..8afe89817d 100644 --- a/test/battle/ability/illusion.c +++ b/test/battle/ability/illusion.c @@ -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 + } +} diff --git a/test/battle/move_effect/ally_switch.c b/test/battle/move_effect/ally_switch.c index 7222f34587..520de60106 100644 --- a/test/battle/move_effect/ally_switch.c +++ b/test/battle/move_effect/ally_switch.c @@ -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");