mirror of
https://github.com/rh-hideout/pokeemerald-expansion.git
synced 2026-03-21 18:04:50 -05:00
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:
parent
8c7ba8a849
commit
46e6324fe2
|
|
@ -1360,6 +1360,11 @@
|
|||
.byte \battler
|
||||
.4byte \jumpInstr
|
||||
.endm
|
||||
|
||||
.macro itemstatchangeeffects battler:req
|
||||
callnative BS_RunStatChangeItems
|
||||
.byte \battler
|
||||
.endm
|
||||
|
||||
.macro allyswitchswapbattlers
|
||||
callnative BS_AllySwitchSwapBattler
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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)))
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user