Fix White Herb Known Failing tests (#4258)

* Fix White Herb Known Failing tests

* get out agbcc

* remove unneeded white herb test
This commit is contained in:
DizzyEggg 2024-03-29 17:43:05 +01:00 committed by GitHub
parent 8c7ba8a849
commit 46e6324fe2
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
7 changed files with 229 additions and 200 deletions

View File

@ -1360,6 +1360,11 @@
.byte \battler
.4byte \jumpInstr
.endm
.macro itemstatchangeeffects battler:req
callnative BS_RunStatChangeItems
.byte \battler
.endm
.macro allyswitchswapbattlers
callnative BS_AllySwitchSwapBattler

View File

@ -7742,11 +7742,12 @@ BattleScript_ActivateWeatherAbilities_Increment:
restoretarget
return
BattleScript_TryAdrenalineOrb:
jumpifnoholdeffect BS_TARGET, HOLD_EFFECT_ADRENALINE_ORB, BattleScript_TryAdrenalineOrbRet
jumpifstat BS_TARGET, CMP_EQUAL, STAT_SPEED, 12, BattleScript_TryAdrenalineOrbRet
BattleScript_TryIntimidateHoldEffects:
itemstatchangeeffects BS_TARGET
jumpifnoholdeffect BS_TARGET, HOLD_EFFECT_ADRENALINE_ORB, BattleScript_TryIntimidateHoldEffectsRet
jumpifstat BS_TARGET, CMP_EQUAL, STAT_SPEED, 12, BattleScript_TryIntimidateHoldEffectsRet
setstatchanger STAT_SPEED, 1, FALSE
statbuffchange STAT_CHANGE_NOT_PROTECT_AFFECTED | MOVE_EFFECT_CERTAIN | STAT_CHANGE_ALLOW_PTR, BattleScript_TryAdrenalineOrbRet
statbuffchange STAT_CHANGE_NOT_PROTECT_AFFECTED | MOVE_EFFECT_CERTAIN | STAT_CHANGE_ALLOW_PTR, BattleScript_TryIntimidateHoldEffectsRet
playanimation BS_TARGET, B_ANIM_HELD_ITEM_EFFECT
setgraphicalstatchangevalues
playanimation BS_TARGET, B_ANIM_STATS_CHANGE, sB_ANIM_ARG1
@ -7755,7 +7756,7 @@ BattleScript_TryAdrenalineOrb:
printstring STRINGID_USINGITEMSTATOFPKMNROSE
waitmessage B_WAIT_TIME_LONG
removeitem BS_TARGET
BattleScript_TryAdrenalineOrbRet:
BattleScript_TryIntimidateHoldEffectsRet:
return
BattleScript_IntimidateActivates::
@ -7781,7 +7782,7 @@ BattleScript_IntimidateEffect:
BattleScript_IntimidateEffect_WaitString:
waitmessage B_WAIT_TIME_LONG
copybyte sBATTLER, gBattlerTarget
call BattleScript_TryAdrenalineOrb
call BattleScript_TryIntimidateHoldEffects
BattleScript_IntimidateLoopIncrement:
addbyte gBattlerTarget, 1
jumpifbytenotequal gBattlerTarget, gBattlersCount, BattleScript_IntimidateLoop
@ -7807,7 +7808,7 @@ BattleScript_IntimidateInReverse:
call BattleScript_AbilityPopUpTarget
pause B_WAIT_TIME_SHORT
modifybattlerstatstage BS_TARGET, STAT_ATK, INCREASE, 1, BattleScript_IntimidateLoopIncrement, ANIM_ON
call BattleScript_TryAdrenalineOrb
call BattleScript_TryIntimidateHoldEffects
goto BattleScript_IntimidateLoopIncrement
BattleScript_SupersweetSyrupActivates::
@ -7834,7 +7835,7 @@ BattleScript_SupersweetSyrupEffect:
BattleScript_SupersweetSyrupEffect_WaitString:
waitmessage B_WAIT_TIME_LONG
copybyte sBATTLER, gBattlerTarget
call BattleScript_TryAdrenalineOrb
call BattleScript_TryIntimidateHoldEffects
BattleScript_SupersweetSyrupLoopIncrement:
addbyte gBattlerTarget, 1
jumpifbytenotequal gBattlerTarget, gBattlersCount, BattleScript_SupersweetSyrupLoop

View File

@ -54,6 +54,7 @@
#define ITEMEFFECT_ORBS 6
#define ITEMEFFECT_LIFEORB_SHELLBELL 7
#define ITEMEFFECT_USE_LAST_ITEM 8 // move end effects for just the battler, not whole field
#define ITEMEFFECT_STATS_CHANGED 9 // For White Herb and Eject Pack
#define WEATHER_HAS_EFFECT ((!IsAbilityOnField(ABILITY_CLOUD_NINE) && !IsAbilityOnField(ABILITY_AIR_LOCK)))

View File

@ -304,9 +304,9 @@
#define MOVEEND_DEFROST 23
#define MOVEEND_RECOIL 24
#define MOVEEND_MAGICIAN 25 // Occurs after final multi-hit strike, and after other items/abilities would activate
#define MOVEEND_EJECT_BUTTON 26
#define MOVEEND_RED_CARD 27
#define MOVEEND_EJECT_PACK 28
#define MOVEEND_EJECT_ITEMS 26
#define MOVEEND_WHITE_HERB 27
#define MOVEEND_RED_CARD 28
#define MOVEEND_LIFEORB_SHELLBELL 29 // Includes shell bell, throat spray, etc
#define MOVEEND_CHANGED_ITEMS 30
#define MOVEEND_PICKPOCKET 31

View File

@ -5870,31 +5870,7 @@ static void Cmd_moveend(void)
}
gBattleScripting.moveendState++;
break;
case MOVEEND_MAGICIAN:
if (GetBattlerAbility(gBattlerAttacker) == ABILITY_MAGICIAN
&& gCurrentMove != MOVE_FLING && gCurrentMove != MOVE_NATURAL_GIFT
&& gBattleMons[gBattlerAttacker].item == ITEM_NONE
&& gBattleMons[gBattlerTarget].item != ITEM_NONE
&& IsBattlerAlive(gBattlerAttacker)
&& TARGET_TURN_DAMAGED
&& CanStealItem(gBattlerAttacker, gBattlerTarget, gBattleMons[gBattlerTarget].item)
&& !gSpecialStatuses[gBattlerAttacker].gemBoost // In base game, gems are consumed after magician would activate.
&& !(gWishFutureKnock.knockedOffMons[GetBattlerSide(gBattlerTarget)] & gBitTable[gBattlerPartyIndexes[gBattlerTarget]])
&& !DoesSubstituteBlockMove(gBattlerAttacker, gBattlerTarget, gCurrentMove)
&& !(gMoveResultFlags & MOVE_RESULT_NO_EFFECT)
&& (GetBattlerAbility(gBattlerTarget) != ABILITY_STICKY_HOLD || !IsBattlerAlive(gBattlerTarget)))
{
StealTargetItem(gBattlerAttacker, gBattlerTarget);
gBattleScripting.battler = gBattlerAbility = gBattlerAttacker;
gEffectBattler = gBattlerTarget;
BattleScriptPushCursor();
gBattlescriptCurrInstr = BattleScript_MagicianActivates;
gSpecialStatuses[gBattlerAttacker].preventLifeOrbDamage = TRUE;
effect = TRUE;
}
gBattleScripting.moveendState++;
break;
case MOVEEND_NEXT_TARGET: // For moves hitting two opposing Pokémon.
case MOVEEND_NEXT_TARGET: // For moves hitting two opposing Pokemon.
{
u16 moveTarget = GetBattlerMoveTargetType(gBattlerAttacker, gCurrentMove);
// Set a flag if move hits either target (for throat spray that can't check damage)
@ -6014,98 +5990,165 @@ static void Cmd_moveend(void)
gBattleScripting.moveendState++;
break;
}
case MOVEEND_EJECT_BUTTON:
if (gMovesInfo[gCurrentMove].effect != EFFECT_HIT_SWITCH_TARGET
// The order of abilities/items activating after moves hitting multiple targets is
// 1. Magician
// 2. The fastest mon gets switched out using Eject Button / Eject Pack
// 3. White Herb activates
// 4. Red Card activates
// 5. Life Orb / Shell Bell
// 6. Pickpocket
case MOVEEND_MAGICIAN:
if (GetBattlerAbility(gBattlerAttacker) == ABILITY_MAGICIAN
&& gCurrentMove != MOVE_FLING && gCurrentMove != MOVE_NATURAL_GIFT
&& gBattleMons[gBattlerAttacker].item == ITEM_NONE
&& gBattleMons[gBattlerTarget].item != ITEM_NONE
&& IsBattlerAlive(gBattlerAttacker)
&& !TestIfSheerForceAffected(gBattlerAttacker, gCurrentMove)
&& (GetBattlerSide(gBattlerAttacker) == B_SIDE_PLAYER || (gBattleTypeFlags & BATTLE_TYPE_TRAINER)))
&& TARGET_TURN_DAMAGED
&& CanStealItem(gBattlerAttacker, gBattlerTarget, gBattleMons[gBattlerTarget].item)
&& !gSpecialStatuses[gBattlerAttacker].gemBoost // In base game, gems are consumed after magician would activate.
&& !(gWishFutureKnock.knockedOffMons[GetBattlerSide(gBattlerTarget)] & gBitTable[gBattlerPartyIndexes[gBattlerTarget]])
&& !DoesSubstituteBlockMove(gBattlerAttacker, gBattlerTarget, gCurrentMove)
&& !(gMoveResultFlags & MOVE_RESULT_NO_EFFECT)
&& (GetBattlerAbility(gBattlerTarget) != ABILITY_STICKY_HOLD || !IsBattlerAlive(gBattlerTarget)))
{
// Since we check if battler was damaged, we don't need to check move result.
// In fact, doing so actually prevents multi-target moves from activating eject button properly
u8 battlers[4] = {0, 1, 2, 3};
SortBattlersBySpeed(battlers, FALSE);
StealTargetItem(gBattlerAttacker, gBattlerTarget);
gBattleScripting.battler = gBattlerAbility = gBattlerAttacker;
gEffectBattler = gBattlerTarget;
BattleScriptPushCursor();
gBattlescriptCurrInstr = BattleScript_MagicianActivates;
gSpecialStatuses[gBattlerAttacker].preventLifeOrbDamage = TRUE;
effect = TRUE;
}
gBattleScripting.moveendState++;
break;
case MOVEEND_EJECT_ITEMS:
{
// Because sorting the battlers by speed takes lots of cycles, it's better to just check if any of the battlers has the Eject items.
u32 ejectPackBattlers = 0, ejectButtonBattlers = 0, i;
for (i = 0; i < gBattlersCount; i++)
{
u8 battler = battlers[i];
// Attacker is the damage-dealer, battler is mon to be switched out
if (IsBattlerAlive(battler)
&& gBattlerAttacker != battler
&& GetBattlerHoldEffect(battler, TRUE) == HOLD_EFFECT_EJECT_BUTTON
&& BATTLER_TURN_DAMAGED(battler)
&& CountUsablePartyMons(battler) > 0) // Has mon to switch into
u32 holdEffect;
if (i == gBattlerAttacker)
continue;
holdEffect = GetBattlerHoldEffect(i, TRUE);
if (holdEffect == HOLD_EFFECT_EJECT_BUTTON)
ejectButtonBattlers |= gBitTable[i];
else if (holdEffect == HOLD_EFFECT_EJECT_PACK)
ejectPackBattlers |= gBitTable[i];
}
if (ejectButtonBattlers || ejectPackBattlers)
{
u8 battlers[4] = {0, 1, 2, 3};
SortBattlersBySpeed(battlers, FALSE);
for (i = 0; i < gBattlersCount; i++)
{
gBattleScripting.battler = battler;
gLastUsedItem = gBattleMons[battler].item;
if (gMovesInfo[gCurrentMove].effect == EFFECT_HIT_ESCAPE)
gBattlescriptCurrInstr = BattleScript_MoveEnd; // Prevent user switch-in selection
BattleScriptPushCursor();
gBattlescriptCurrInstr = BattleScript_EjectButtonActivates;
effect = TRUE;
break; // Only the fastest Eject Button activates
u32 battler = battlers[i];
if (ejectButtonBattlers & gBitTable[battler])
{
if (TestIfSheerForceAffected(gBattlerAttacker, gCurrentMove)) // Apparently Sheer Force blocks Eject Button, but not Eject Pack
continue;
// Since we check if battler was damaged, we don't need to check move result.
// In fact, doing so actually prevents multi-target moves from activating eject button properly
if (!BATTLER_TURN_DAMAGED(battler))
continue;
}
else if (ejectPackBattlers & gBitTable[battler])
{
if (!gProtectStructs[battler].statFell || gProtectStructs[battler].disableEjectPack)
continue;
}
else
{
continue;
}
if (IsBattlerAlive(battler)
&& CountUsablePartyMons(battler) > 0 // Has mon to switch into
// Does not activate if attacker used Parting Shot and can switch out
&& !(gMovesInfo[gCurrentMove].effect == EFFECT_HIT_SWITCH_TARGET && CanBattlerSwitch(gBattlerAttacker))
)
{
gBattleScripting.battler = battler;
gLastUsedItem = gBattleMons[battler].item;
if (gMovesInfo[gCurrentMove].effect == EFFECT_HIT_ESCAPE)
gBattlescriptCurrInstr = BattleScript_MoveEnd; // Prevent user switch-in selection
effect = TRUE;
BattleScriptPushCursor();
if (ejectButtonBattlers & gBitTable[battler])
{
gBattlescriptCurrInstr = BattleScript_EjectButtonActivates;
}
else // Eject Pack
{
gBattlescriptCurrInstr = BattleScript_EjectPackActivates;
// Are these 2 lines below needed?
gProtectStructs[battler].statFell = FALSE;
gSpecialStatuses[gBattlerAttacker].preventLifeOrbDamage = TRUE;
}
break; // Only the fastest Eject item activates
}
}
}
}
gBattleScripting.moveendState++;
break;
case MOVEEND_WHITE_HERB:
for (i = 0; i < gBattlersCount; i++)
{
if (IsBattlerAlive(i)
&& ItemBattleEffects(ITEMEFFECT_STATS_CHANGED, i, FALSE))
{
effect = TRUE;
break;
}
}
if (!effect)
gBattleScripting.moveendState++;
break;
case MOVEEND_RED_CARD:
if ((gMovesInfo[gCurrentMove].effect != EFFECT_HIT_SWITCH_TARGET || gBattleStruct->hitSwitchTargetFailed)
&& IsBattlerAlive(gBattlerAttacker)
&& !TestIfSheerForceAffected(gBattlerAttacker, gCurrentMove)
&& GetBattlerAbility(gBattlerAttacker) != ABILITY_GUARD_DOG)
{
// Since we check if battler was damaged, we don't need to check move result.
// In fact, doing so actually prevents multi-target moves from activating red card properly
u8 battlers[4] = {0, 1, 2, 3};
SortBattlersBySpeed(battlers, FALSE);
u32 redCardBattlers = 0, i;
for (i = 0; i < gBattlersCount; i++)
{
u8 battler = battlers[i];
// Search for fastest hit pokemon with a red card
// Attacker is the one to be switched out, battler is one with red card
if (battler != gBattlerAttacker
&& IsBattlerAlive(battler)
&& !DoesSubstituteBlockMove(gBattlerAttacker, battler, gCurrentMove)
&& GetBattlerHoldEffect(battler, TRUE) == HOLD_EFFECT_RED_CARD
&& BATTLER_TURN_DAMAGED(battler)
&& CanBattlerSwitch(gBattlerAttacker))
{
gLastUsedItem = gBattleMons[battler].item;
gBattleStruct->savedBattlerTarget = gBattleScripting.battler = battler; // Battler with red card
gEffectBattler = gBattlerAttacker;
if (gMovesInfo[gCurrentMove].effect == EFFECT_HIT_ESCAPE)
gBattlescriptCurrInstr = BattleScript_MoveEnd; // Prevent user switch-in selection
BattleScriptPushCursor();
gBattlescriptCurrInstr = BattleScript_RedCardActivates;
gSpecialStatuses[gBattlerAttacker].preventLifeOrbDamage = TRUE;
effect = TRUE;
break; // Only fastest red card activates
}
if (i == gBattlerAttacker)
continue;
if (GetBattlerHoldEffect(i, TRUE) == HOLD_EFFECT_RED_CARD)
redCardBattlers |= gBitTable[i];
}
}
gBattleScripting.moveendState++;
break;
case MOVEEND_EJECT_PACK:
{
u8 battlers[4] = {0, 1, 2, 3};
SortBattlersBySpeed(battlers, FALSE);
for (i = 0; i < gBattlersCount; i++)
if (redCardBattlers
&& (gMovesInfo[gCurrentMove].effect != EFFECT_HIT_SWITCH_TARGET || gBattleStruct->hitSwitchTargetFailed)
&& IsBattlerAlive(gBattlerAttacker)
&& !TestIfSheerForceAffected(gBattlerAttacker, gCurrentMove)
&& GetBattlerAbility(gBattlerAttacker) != ABILITY_GUARD_DOG)
{
u8 battler = battlers[i];
if (IsBattlerAlive(battler)
&& gProtectStructs[battler].statFell
&& gProtectStructs[battler].disableEjectPack == 0
&& GetBattlerHoldEffect(battler, TRUE) == HOLD_EFFECT_EJECT_PACK
&& !(gCurrentMove == MOVE_PARTING_SHOT && CanBattlerSwitch(gBattlerAttacker)) // Does not activate if attacker used Parting Shot and can switch out
&& CountUsablePartyMons(battler) > 0) // Has mon to switch into
// Since we check if battler was damaged, we don't need to check move result.
// In fact, doing so actually prevents multi-target moves from activating red card properly
u8 battlers[4] = {0, 1, 2, 3};
SortBattlersBySpeed(battlers, FALSE);
for (i = 0; i < gBattlersCount; i++)
{
gProtectStructs[battler].statFell = FALSE;
gBattleScripting.battler = battler;
gLastUsedItem = gBattleMons[battler].item;
BattleScriptPushCursor();
gBattlescriptCurrInstr = BattleScript_EjectPackActivates;
gSpecialStatuses[gBattlerAttacker].preventLifeOrbDamage = TRUE;
effect = TRUE;
break; // Only fastest eject pack activates
u32 battler = battlers[i];
// Search for fastest hit pokemon with a red card
// Attacker is the one to be switched out, battler is one with red card
if (redCardBattlers & gBitTable[battler]
&& IsBattlerAlive(battler)
&& !DoesSubstituteBlockMove(gBattlerAttacker, battler, gCurrentMove)
&& BATTLER_TURN_DAMAGED(battler)
&& CanBattlerSwitch(gBattlerAttacker))
{
gLastUsedItem = gBattleMons[battler].item;
gBattleStruct->savedBattlerTarget = gBattleScripting.battler = battler; // Battler with red card
gEffectBattler = gBattlerAttacker;
if (gMovesInfo[gCurrentMove].effect == EFFECT_HIT_ESCAPE)
gBattlescriptCurrInstr = BattleScript_MoveEnd; // Prevent user switch-in selection
BattleScriptPushCursor();
gBattlescriptCurrInstr = BattleScript_RedCardActivates;
gSpecialStatuses[gBattlerAttacker].preventLifeOrbDamage = TRUE;
effect = TRUE;
break; // Only fastest red card activates
}
}
}
}
@ -16708,6 +16751,15 @@ void BS_SetPhotonGeyserCategory(void)
gBattlescriptCurrInstr = cmd->nextInstr;
}
void BS_RunStatChangeItems(void)
{
NATIVE_ARGS(u8 battler);
// Change instruction before calling ItemBattleEffects.
gBattlescriptCurrInstr = cmd->nextInstr;
ItemBattleEffects(ITEMEFFECT_STATS_CHANGED, GetBattlerForBattleScript(cmd->battler), FALSE);
}
static void TryUpdateEvolutionTracker(u32 evolutionMethod, u32 upAmount)
{
u32 i;

View File

@ -6762,10 +6762,29 @@ static u8 TryConsumeMirrorHerb(u32 battler, bool32 execute)
return effect;
}
static u32 RestoreWhiteHerbStats(u32 battler)
{
u32 i, effect = 0;
for (i = 0; i < NUM_BATTLE_STATS; i++)
{
if (gBattleMons[battler].statStages[i] < DEFAULT_STAT_STAGE)
{
gBattleMons[battler].statStages[i] = DEFAULT_STAT_STAGE;
effect = ITEM_STATS_CHANGE;
}
}
if (effect != 0)
{
gBattleScripting.battler = battler;
gPotentialItemEffectBattler = battler;
}
return effect;
}
static u8 ItemEffectMoveEnd(u32 battler, u16 holdEffect)
{
u8 effect = 0;
u32 i;
switch (holdEffect)
{
@ -6945,24 +6964,6 @@ static u8 ItemEffectMoveEnd(u32 battler, u16 holdEffect)
effect = ITEM_STATUS_CHANGE;
}
break;
case HOLD_EFFECT_RESTORE_STATS:
for (i = 0; i < NUM_BATTLE_STATS; i++)
{
if (gBattleMons[battler].statStages[i] < DEFAULT_STAT_STAGE)
{
gBattleMons[battler].statStages[i] = DEFAULT_STAT_STAGE;
effect = ITEM_STATS_CHANGE;
}
}
if (effect != 0)
{
gBattleScripting.battler = battler;
gPotentialItemEffectBattler = battler;
BattleScriptPushCursor();
gBattlescriptCurrInstr = BattleScript_WhiteHerbRet;
return effect;
}
break;
case HOLD_EFFECT_CRITICAL_UP: // lansat berry
if (B_BERRIES_INSTANT >= GEN_4
&& !(gBattleMons[battler].status2 & STATUS2_FOCUS_ENERGY_ANY)
@ -7032,18 +7033,9 @@ u8 ItemBattleEffects(u8 caseID, u32 battler, bool32 moveTurn)
}
break;
case HOLD_EFFECT_RESTORE_STATS:
for (i = 0; i < NUM_BATTLE_STATS; i++)
{
if (gBattleMons[battler].statStages[i] < DEFAULT_STAT_STAGE)
{
gBattleMons[battler].statStages[i] = DEFAULT_STAT_STAGE;
effect = ITEM_STATS_CHANGE;
}
}
effect = RestoreWhiteHerbStats(battler);
if (effect != 0)
{
gBattleScripting.battler = battler;
gPotentialItemEffectBattler = battler;
gBattlerAttacker = battler;
BattleScriptExecute(BattleScript_WhiteHerbEnd2);
}
@ -7314,18 +7306,9 @@ u8 ItemBattleEffects(u8 caseID, u32 battler, bool32 moveTurn)
effect = ItemRestorePp(battler, gLastUsedItem, TRUE);
break;
case HOLD_EFFECT_RESTORE_STATS:
for (i = 0; i < NUM_BATTLE_STATS; i++)
{
if (gBattleMons[battler].statStages[i] < DEFAULT_STAT_STAGE)
{
gBattleMons[battler].statStages[i] = DEFAULT_STAT_STAGE;
effect = ITEM_STATS_CHANGE;
}
}
effect = RestoreWhiteHerbStats(battler);
if (effect != 0)
{
gBattleScripting.battler = battler;
gPotentialItemEffectBattler = battler;
gBattlerAttacker = battler;
BattleScriptExecute(BattleScript_WhiteHerbEnd2);
}
@ -7885,6 +7868,19 @@ u8 ItemBattleEffects(u8 caseID, u32 battler, bool32 moveTurn)
}
}
break;
case ITEMEFFECT_STATS_CHANGED:
switch (battlerHoldEffect)
{
case HOLD_EFFECT_RESTORE_STATS:
effect = RestoreWhiteHerbStats(battler);
if (effect != 0)
{
BattleScriptPushCursor();
gBattlescriptCurrInstr = BattleScript_WhiteHerbRet;
}
break;
}
break;
}
// Berry was successfully used on a Pokemon.

View File

@ -55,10 +55,10 @@ DOUBLE_BATTLE_TEST("White Herb restores stats after Attack was lowered by Intimi
ABILITY_POPUP(playerLeft, ABILITY_INTIMIDATE);
ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_STATS_CHANGE, opponentLeft);
ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_STATS_CHANGE, opponentRight);
ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_HELD_ITEM_EFFECT, opponentLeft);
MESSAGE("Foe Wobbuffet's White Herb restored its status!");
ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_STATS_CHANGE, opponentRight);
ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_HELD_ITEM_EFFECT, opponentRight);
MESSAGE("Foe Wynaut's White Herb restored its status!");
} THEN {
@ -71,7 +71,6 @@ DOUBLE_BATTLE_TEST("White Herb restores stats after Attack was lowered by Intimi
SINGLE_BATTLE_TEST("White Herb restores stats after Attack was lowered by Intimidate while switching in")
{
KNOWN_FAILING;
GIVEN {
PLAYER(SPECIES_WOBBUFFET) { Item(ITEM_WHITE_HERB); }
OPPONENT(SPECIES_WOBBUFFET);
@ -95,7 +94,6 @@ SINGLE_BATTLE_TEST("White Herb restores stats after Attack was lowered by Intimi
}
}
SINGLE_BATTLE_TEST("White Herb restores stats after all hits of a multi hit move happened")
{
u16 species;
@ -104,7 +102,6 @@ SINGLE_BATTLE_TEST("White Herb restores stats after all hits of a multi hit move
PARAMETRIZE { species = SPECIES_SLIGGOO_HISUIAN; ability = ABILITY_GOOEY; }
PARAMETRIZE { species = SPECIES_DUGTRIO_ALOLAN; ability = ABILITY_TANGLING_HAIR; }
KNOWN_FAILING;
GIVEN {
ASSUME(gMovesInfo[MOVE_DUAL_WINGBEAT].strikeCount == 2);
PLAYER(SPECIES_WOBBUFFET) { Item(ITEM_WHITE_HERB); }
@ -114,10 +111,11 @@ SINGLE_BATTLE_TEST("White Herb restores stats after all hits of a multi hit move
} SCENE {
ANIMATION(ANIM_TYPE_MOVE, MOVE_DUAL_WINGBEAT, player);
ABILITY_POPUP(opponent, ability);
ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_STATS_CHANGE, player);
MESSAGE("Wobbuffet's Speed fell!");
ABILITY_POPUP(opponent, ability);
MESSAGE("Wobbuffet's Speed fell!");
ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_STATS_CHANGE, player);
MESSAGE("Wobbuffet's Speed fell!");
ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_HELD_ITEM_EFFECT, player);
MESSAGE("Wobbuffet's White Herb restored its status!");
} THEN {
@ -133,7 +131,6 @@ SINGLE_BATTLE_TEST("White Herb wont have time to activate if it is knocked off o
PARAMETRIZE { move = MOVE_THIEF; }
PARAMETRIZE { move = MOVE_KNOCK_OFF; }
KNOWN_FAILING; // Knock off fails, Thief is fine
GIVEN {
ASSUME(MoveHasAdditionalEffect(MOVE_THIEF, MOVE_EFFECT_STEAL_ITEM) == TRUE);
ASSUME(gMovesInfo[MOVE_KNOCK_OFF].effect == EFFECT_KNOCK_OFF);
@ -143,14 +140,16 @@ SINGLE_BATTLE_TEST("White Herb wont have time to activate if it is knocked off o
TURN { MOVE(opponent, move); }
} SCENE {
ANIMATION(ANIM_TYPE_MOVE, move, opponent);
if (move == MOVE_THIEF)
if (move == MOVE_THIEF) {
MESSAGE("Foe Wobbuffet stole Slugma's White Herb!");
else
MESSAGE("Foe Wobbuffet knocked off Slugma's White Herb!");
}
ABILITY_POPUP(player, ABILITY_WEAK_ARMOR);
ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_STATS_CHANGE, player);
MESSAGE("Slugma's Weak Armor lowered its Defense!");
MESSAGE("Slugma's Weak Armor raised its Speed!");
if (move == MOVE_KNOCK_OFF) {
MESSAGE("Foe Wobbuffet knocked off Slugma's White Herb!");
}
NONE_OF {
ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_HELD_ITEM_EFFECT, player);
MESSAGE("Wobbuffet's White Herb restored its status!");
@ -163,7 +162,6 @@ SINGLE_BATTLE_TEST("White Herb wont have time to activate if it is knocked off o
SINGLE_BATTLE_TEST("White Herb wont have time to activate if Magician steals it")
{
KNOWN_FAILING; // White Herb is activated
GIVEN {
PLAYER(SPECIES_SLUGMA) { Ability(ABILITY_WEAK_ARMOR); Item(ITEM_WHITE_HERB); }
OPPONENT(SPECIES_FENNEKIN) { Ability(ABILITY_MAGICIAN); }
@ -171,11 +169,12 @@ SINGLE_BATTLE_TEST("White Herb wont have time to activate if Magician steals it"
TURN { MOVE(opponent, MOVE_TACKLE); }
} SCENE {
ANIMATION(ANIM_TYPE_MOVE, MOVE_TACKLE, opponent);
ABILITY_POPUP(player, ABILITY_WEAK_ARMOR);
ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_STATS_CHANGE, player);
MESSAGE("Slugma's Weak Armor lowered its Defense!");
MESSAGE("Slugma's Weak Armor raised its Speed!");
ABILITY_POPUP(opponent, ABILITY_MAGICIAN);
ABILITY_POPUP(player, ABILITY_WEAK_ARMOR);
ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_STATS_CHANGE, player);
MESSAGE("Slugma's Weak Armor lowered its Defense!");
MESSAGE("Slugma's Weak Armor raised its Speed!");
MESSAGE("Foe Fennekin stole Slugma's White Herb!");
NONE_OF {
ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_HELD_ITEM_EFFECT, player);
MESSAGE("Wobbuffet's White Herb restored its status!");
@ -186,33 +185,7 @@ SINGLE_BATTLE_TEST("White Herb wont have time to activate if Magician steals it"
}
}
SINGLE_BATTLE_TEST("White Herb wont have time to activate if Pickpocket steals it")
{
KNOWN_FAILING; // White Herb is activated
GIVEN {
ASSUME(MoveHasAdditionalEffectSelf(MOVE_LEAF_STORM, MOVE_EFFECT_SP_ATK_TWO_DOWN));
PLAYER(SPECIES_SLUGMA) { Ability(ABILITY_WEAK_ARMOR); Item(ITEM_WHITE_HERB); }
OPPONENT(SPECIES_SNEASEL) { Ability(ABILITY_PICKPOCKET); }
} WHEN {
TURN { MOVE(player, MOVE_LEAF_STORM); }
} SCENE {
ANIMATION(ANIM_TYPE_MOVE, MOVE_LEAF_STORM, player);
ABILITY_POPUP(player, ABILITY_PICKPOCKET);
ABILITY_POPUP(player, ABILITY_WEAK_ARMOR);
ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_STATS_CHANGE, player);
MESSAGE("Slugma's Weak Armor lowered its Defense!");
MESSAGE("Slugma's Weak Armor raised its Speed!");
NONE_OF {
ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_HELD_ITEM_EFFECT, player);
MESSAGE("Wobbuffet's White Herb restored its status!");
}
} THEN {
EXPECT(player->statStages[STAT_DEF] = DEFAULT_STAT_STAGE - 1);
EXPECT(player->statStages[STAT_SPEED] = DEFAULT_STAT_STAGE + 1);
}
}
SINGLE_BATTLE_TEST("White Herb restores stats after Defiant or Competitive were triggered")
SINGLE_BATTLE_TEST("White Herb has correct interactions with Intimidate triggered Defiant and Competitive")
{
u16 species;
u16 ability;
@ -220,7 +193,6 @@ SINGLE_BATTLE_TEST("White Herb restores stats after Defiant or Competitive were
PARAMETRIZE { species = SPECIES_IGGLYBUFF; ability = ABILITY_COMPETITIVE; }
PARAMETRIZE { species = SPECIES_MANKEY; ability = ABILITY_DEFIANT; }
KNOWN_FAILING;
GIVEN {
PLAYER(species) { Ability(ability); Item(ITEM_WHITE_HERB); }
OPPONENT(SPECIES_ARBOK) { Ability(ABILITY_INTIMIDATE); }
@ -230,16 +202,18 @@ SINGLE_BATTLE_TEST("White Herb restores stats after Defiant or Competitive were
ABILITY_POPUP(opponent, ABILITY_INTIMIDATE);
ABILITY_POPUP(player, ability);
ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_STATS_CHANGE, player);
ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_HELD_ITEM_EFFECT, player);
MESSAGE("Wobbuffet's White Herb restored its status!");
// Defiant activates first, so White Herb doesn't have a chance to trigger.
if (ability == ABILITY_COMPETITIVE) {
ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_HELD_ITEM_EFFECT, player);
MESSAGE("Igglybuff's White Herb restored its status!");
}
} THEN {
EXPECT(player->item == ITEM_NONE);
if (species == SPECIES_IGGLYBUFF)
{
if (ability == ABILITY_COMPETITIVE) {
EXPECT(player->item == ITEM_NONE);
EXPECT(player->statStages[STAT_ATK] = DEFAULT_STAT_STAGE);
EXPECT(player->statStages[STAT_SPATK] = DEFAULT_STAT_STAGE + 2);
} else {
EXPECT(player->statStages[STAT_ATK] = DEFAULT_STAT_STAGE + 1);
}
else
EXPECT(player->statStages[STAT_ATK] = DEFAULT_STAT_STAGE + 3);
}
}