Fixes Eject Pack triggering twice on Intimidate (#6072)
This commit is contained in:
parent
b2f2a8c9fb
commit
f2840cb047
@ -65,7 +65,7 @@ enum {
|
||||
#define ABILITYEFFECT_WATER_SPORT 253 // Only used if B_SPORT_TURNS >= GEN_6
|
||||
|
||||
// For the first argument of ItemBattleEffects, to deteremine which block of item effects to try
|
||||
enum ItemEffect
|
||||
enum ItemCaseId
|
||||
{
|
||||
ITEMEFFECT_NONE,
|
||||
ITEMEFFECT_ON_SWITCH_IN,
|
||||
@ -80,6 +80,16 @@ enum ItemEffect
|
||||
ITEMEFFECT_STATS_CHANGED, // For White Herb and Eject Pack
|
||||
};
|
||||
|
||||
enum ItemEffect
|
||||
{
|
||||
ITEM_NO_EFFECT,
|
||||
ITEM_STATUS_CHANGE,
|
||||
ITEM_EFFECT_OTHER,
|
||||
ITEM_PP_CHANGE,
|
||||
ITEM_HP_CHANGE,
|
||||
ITEM_STATS_CHANGE,
|
||||
};
|
||||
|
||||
#define WEATHER_HAS_EFFECT ((!IsAbilityOnField(ABILITY_CLOUD_NINE) && !IsAbilityOnField(ABILITY_AIR_LOCK)))
|
||||
|
||||
#define IS_WHOLE_SIDE_ALIVE(battler) ((IsBattlerAlive(battler) && IsBattlerAlive(BATTLE_PARTNER(battler))))
|
||||
@ -215,7 +225,7 @@ bool32 IsBattlerProtected(u32 battlerAtk, u32 battlerDef, u32 move);
|
||||
bool32 CanBattlerEscape(u32 battler); // no ability check
|
||||
void BattleScriptExecute(const u8 *BS_ptr);
|
||||
void BattleScriptPushCursorAndCallback(const u8 *BS_ptr);
|
||||
u32 ItemBattleEffects(enum ItemEffect, u32 battler, bool32 moveTurn);
|
||||
u32 ItemBattleEffects(enum ItemCaseId, u32 battler, bool32 moveTurn);
|
||||
void ClearVariousBattlerFlags(u32 battler);
|
||||
void HandleAction_RunBattleScript(void);
|
||||
u32 SetRandomTarget(u32 battler);
|
||||
@ -272,7 +282,7 @@ void TryRestoreHeldItems(void);
|
||||
bool32 CanStealItem(u32 battlerStealing, u32 battlerItem, u16 item);
|
||||
void TrySaveExchangedItem(u32 battler, u16 stolenItem);
|
||||
bool32 IsPartnerMonFromSameTrainer(u32 battler);
|
||||
u32 TryHandleSeed(u32 battler, u32 terrainFlag, u32 statId, u32 itemId, enum ItemEffect caseID);
|
||||
enum ItemEffect TryHandleSeed(u32 battler, u32 terrainFlag, u32 statId, u32 itemId, enum ItemCaseId caseID);
|
||||
bool32 IsBattlerAffectedByHazards(u32 battler, bool32 toxicSpikes);
|
||||
void SortBattlersBySpeed(u8 *battlers, bool32 slowToFast);
|
||||
bool32 CompareStat(u32 battler, u8 statId, u8 cmpTo, u8 cmpKind);
|
||||
|
||||
@ -10536,25 +10536,25 @@ static void Cmd_various(void)
|
||||
VARIOUS_ARGS(const u8 *failInstr);
|
||||
if (GetBattlerHoldEffect(battler, TRUE) == HOLD_EFFECT_SEEDS)
|
||||
{
|
||||
u8 effect = 0;
|
||||
enum ItemEffect effect = ITEM_NO_EFFECT;
|
||||
u16 item = gBattleMons[battler].item;
|
||||
switch (GetBattlerHoldEffectParam(battler))
|
||||
{
|
||||
case HOLD_EFFECT_PARAM_ELECTRIC_TERRAIN:
|
||||
effect = TryHandleSeed(battler, STATUS_FIELD_ELECTRIC_TERRAIN, STAT_DEF, item, ITEMEFFECT_NONE);
|
||||
effect = TryHandleSeed(battler, STATUS_FIELD_ELECTRIC_TERRAIN, STAT_DEF, item, ITEMEFFECT_ON_SWITCH_IN_FIRST_TURN);
|
||||
break;
|
||||
case HOLD_EFFECT_PARAM_GRASSY_TERRAIN:
|
||||
effect = TryHandleSeed(battler, STATUS_FIELD_GRASSY_TERRAIN, STAT_DEF, item, ITEMEFFECT_NONE);
|
||||
effect = TryHandleSeed(battler, STATUS_FIELD_GRASSY_TERRAIN, STAT_DEF, item, ITEMEFFECT_ON_SWITCH_IN_FIRST_TURN);
|
||||
break;
|
||||
case HOLD_EFFECT_PARAM_MISTY_TERRAIN:
|
||||
effect = TryHandleSeed(battler, STATUS_FIELD_MISTY_TERRAIN, STAT_SPDEF, item, ITEMEFFECT_NONE);
|
||||
effect = TryHandleSeed(battler, STATUS_FIELD_MISTY_TERRAIN, STAT_SPDEF, item, ITEMEFFECT_ON_SWITCH_IN_FIRST_TURN);
|
||||
break;
|
||||
case HOLD_EFFECT_PARAM_PSYCHIC_TERRAIN:
|
||||
effect = TryHandleSeed(battler, STATUS_FIELD_PSYCHIC_TERRAIN, STAT_SPDEF, item, ITEMEFFECT_NONE);
|
||||
effect = TryHandleSeed(battler, STATUS_FIELD_PSYCHIC_TERRAIN, STAT_SPDEF, item, ITEMEFFECT_ON_SWITCH_IN_FIRST_TURN);
|
||||
break;
|
||||
}
|
||||
|
||||
if (effect)
|
||||
if (effect != ITEM_NO_EFFECT)
|
||||
return;
|
||||
}
|
||||
gBattlescriptCurrInstr = cmd->failInstr;
|
||||
|
||||
@ -6699,16 +6699,6 @@ void BattleScriptPushCursorAndCallback(const u8 *BS_ptr)
|
||||
gBattleMainFunc = RunBattleScriptCommands;
|
||||
}
|
||||
|
||||
enum
|
||||
{
|
||||
ITEM_NO_EFFECT,
|
||||
ITEM_STATUS_CHANGE,
|
||||
ITEM_EFFECT_OTHER,
|
||||
ITEM_PP_CHANGE,
|
||||
ITEM_HP_CHANGE,
|
||||
ITEM_STATS_CHANGE,
|
||||
};
|
||||
|
||||
bool32 IsBattlerTerrainAffected(u32 battler, u32 terrainFlag)
|
||||
{
|
||||
if (!(gFieldStatuses & terrainFlag))
|
||||
@ -6844,7 +6834,7 @@ bool32 HasEnoughHpToEatBerry(u32 battler, u32 hpFraction, u32 itemId)
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static u32 HealConfuseBerry(u32 battler, u32 itemId, u32 flavorId, enum ItemEffect caseID)
|
||||
static enum ItemEffect HealConfuseBerry(u32 battler, u32 itemId, u32 flavorId, enum ItemCaseId caseID)
|
||||
{
|
||||
if (HasEnoughHpToEatBerry(battler, (B_CONFUSE_BERRIES_HEAL >= GEN_7 ? 4 : 2), itemId)
|
||||
&& (B_HEAL_BLOCKING < GEN_5 || !(gStatuses3[battler] & STATUS3_HEAL_BLOCK)))
|
||||
@ -6880,10 +6870,10 @@ static u32 HealConfuseBerry(u32 battler, u32 itemId, u32 flavorId, enum ItemEffe
|
||||
|
||||
return ITEM_HP_CHANGE;
|
||||
}
|
||||
return 0;
|
||||
return ITEM_NO_EFFECT;
|
||||
}
|
||||
|
||||
static u32 StatRaiseBerry(u32 battler, u32 itemId, u32 statId, enum ItemEffect caseID)
|
||||
static enum ItemEffect StatRaiseBerry(u32 battler, u32 itemId, u32 statId, enum ItemCaseId caseID)
|
||||
{
|
||||
if (CompareStat(battler, statId, MAX_STAT_STAGE, CMP_LESS_THAN) && HasEnoughHpToEatBerry(battler, GetBattlerItemHoldEffectParam(battler, itemId), itemId))
|
||||
{
|
||||
@ -6911,7 +6901,7 @@ static u32 StatRaiseBerry(u32 battler, u32 itemId, u32 statId, enum ItemEffect c
|
||||
return ITEM_NO_EFFECT;
|
||||
}
|
||||
|
||||
static u32 RandomStatRaiseBerry(u32 battler, u32 itemId, enum ItemEffect caseID)
|
||||
static enum ItemEffect RandomStatRaiseBerry(u32 battler, u32 itemId, enum ItemCaseId caseID)
|
||||
{
|
||||
s32 i;
|
||||
u16 stringId;
|
||||
@ -6959,10 +6949,10 @@ static u32 RandomStatRaiseBerry(u32 battler, u32 itemId, enum ItemEffect caseID)
|
||||
|
||||
return ITEM_STATS_CHANGE;
|
||||
}
|
||||
return 0;
|
||||
return ITEM_NO_EFFECT;
|
||||
}
|
||||
|
||||
static u32 TrySetMicleBerry(u32 battler, u32 itemId, enum ItemEffect caseID)
|
||||
static enum ItemEffect TrySetMicleBerry(u32 battler, u32 itemId, enum ItemCaseId caseID)
|
||||
{
|
||||
if (HasEnoughHpToEatBerry(battler, 4, itemId))
|
||||
{
|
||||
@ -6978,10 +6968,10 @@ static u32 TrySetMicleBerry(u32 battler, u32 itemId, enum ItemEffect caseID)
|
||||
}
|
||||
return ITEM_EFFECT_OTHER;
|
||||
}
|
||||
return 0;
|
||||
return ITEM_NO_EFFECT;
|
||||
}
|
||||
|
||||
static u8 TrySetEnigmaBerry(u32 battler)
|
||||
static enum ItemEffect TrySetEnigmaBerry(u32 battler)
|
||||
{
|
||||
if (IsBattlerAlive(battler)
|
||||
&& !DoesSubstituteBlockMove(gBattlerAttacker, battler, gCurrentMove)
|
||||
@ -6998,10 +6988,10 @@ static u8 TrySetEnigmaBerry(u32 battler)
|
||||
gBattlescriptCurrInstr = BattleScript_ItemHealHP_RemoveItemRet;
|
||||
return ITEM_HP_CHANGE;
|
||||
}
|
||||
return 0;
|
||||
return ITEM_NO_EFFECT;
|
||||
}
|
||||
|
||||
static u8 DamagedStatBoostBerryEffect(u32 battler, u8 statId, u8 category)
|
||||
static enum ItemEffect DamagedStatBoostBerryEffect(u32 battler, u8 statId, u8 category)
|
||||
{
|
||||
if (IsBattlerAlive(battler)
|
||||
&& CompareStat(battler, statId, MAX_STAT_STAGE, CMP_LESS_THAN)
|
||||
@ -7027,10 +7017,10 @@ static u8 DamagedStatBoostBerryEffect(u32 battler, u8 statId, u8 category)
|
||||
gBattlescriptCurrInstr = BattleScript_BerryStatRaiseRet;
|
||||
return ITEM_STATS_CHANGE;
|
||||
}
|
||||
return 0;
|
||||
return ITEM_NO_EFFECT;
|
||||
}
|
||||
|
||||
u32 TryHandleSeed(u32 battler, u32 terrainFlag, u32 statId, u32 itemId, enum ItemEffect caseID)
|
||||
enum ItemEffect TryHandleSeed(u32 battler, u32 terrainFlag, u32 statId, u32 itemId, enum ItemCaseId caseID)
|
||||
{
|
||||
if (gFieldStatuses & terrainFlag && CompareStat(battler, statId, MAX_STAT_STAGE, CMP_LESS_THAN))
|
||||
{
|
||||
@ -7040,7 +7030,7 @@ u32 TryHandleSeed(u32 battler, u32 terrainFlag, u32 statId, u32 itemId, enum Ite
|
||||
SET_STATCHANGER(statId, 1, FALSE);
|
||||
gBattleScripting.animArg1 = STAT_ANIM_PLUS1 + statId;
|
||||
gBattleScripting.animArg2 = 0;
|
||||
if (caseID == ITEMEFFECT_ON_SWITCH_IN_FIRST_TURN || caseID == ITEMEFFECT_NORMAL)
|
||||
if (caseID == ITEMEFFECT_ON_SWITCH_IN_FIRST_TURN)
|
||||
{
|
||||
BattleScriptExecute(BattleScript_BerryStatRaiseEnd2);
|
||||
}
|
||||
@ -7051,10 +7041,33 @@ u32 TryHandleSeed(u32 battler, u32 terrainFlag, u32 statId, u32 itemId, enum Ite
|
||||
}
|
||||
return ITEM_STATS_CHANGE;
|
||||
}
|
||||
return 0;
|
||||
return ITEM_NO_EFFECT;
|
||||
}
|
||||
|
||||
static u32 ItemRestorePp(u32 battler, u32 itemId, enum ItemEffect caseID)
|
||||
static enum ItemEffect TryEjectPack(u32 battler, enum ItemCaseId caseID)
|
||||
{
|
||||
if (gProtectStructs[battler].statFell
|
||||
&& !gProtectStructs[battler].disableEjectPack
|
||||
&& CountUsablePartyMons(battler) > 0
|
||||
&& !(gCurrentMove == MOVE_PARTING_SHOT && CanBattlerSwitch(gBattlerAttacker))) // Does not activate if attacker used Parting Shot and can switch out
|
||||
{
|
||||
gProtectStructs[battler].statFell = FALSE;
|
||||
gBattleScripting.battler = battler;
|
||||
if (caseID == ITEMEFFECT_ON_SWITCH_IN_FIRST_TURN)
|
||||
{
|
||||
BattleScriptExecute(BattleScript_EjectPackActivate_End2);
|
||||
}
|
||||
else
|
||||
{
|
||||
BattleScriptPushCursor();
|
||||
gBattlescriptCurrInstr = BattleScript_EjectPackActivate_Ret;
|
||||
}
|
||||
return ITEM_STATS_CHANGE;
|
||||
}
|
||||
return ITEM_NO_EFFECT;
|
||||
}
|
||||
|
||||
static u32 ItemRestorePp(u32 battler, u32 itemId, enum ItemCaseId caseID)
|
||||
{
|
||||
struct Pokemon *party = GetBattlerParty(battler);
|
||||
struct Pokemon *mon = &party[gBattlerPartyIndexes[battler]];
|
||||
@ -7101,7 +7114,7 @@ static u32 ItemRestorePp(u32 battler, u32 itemId, enum ItemEffect caseID)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static u32 ItemHealHp(u32 battler, u32 itemId, enum ItemEffect caseID, bool32 percentHeal)
|
||||
static u32 ItemHealHp(u32 battler, u32 itemId, enum ItemCaseId caseID, bool32 percentHeal)
|
||||
{
|
||||
if (!(gBattleScripting.overrideBerryRequirements && gBattleMons[battler].hp == gBattleMons[battler].maxHP)
|
||||
&& (B_HEAL_BLOCKING < GEN_5 || !(gStatuses3[battler] & STATUS3_HEAL_BLOCK))
|
||||
@ -7198,7 +7211,7 @@ static bool32 GetMentalHerbEffect(u32 battler)
|
||||
return ret;
|
||||
}
|
||||
|
||||
static u32 TryConsumeMirrorHerb(u32 battler, enum ItemEffect caseID)
|
||||
static u32 TryConsumeMirrorHerb(u32 battler, enum ItemCaseId caseID)
|
||||
{
|
||||
u32 effect = 0;
|
||||
|
||||
@ -7223,7 +7236,7 @@ static u32 TryConsumeMirrorHerb(u32 battler, enum ItemEffect caseID)
|
||||
return effect;
|
||||
}
|
||||
|
||||
static inline u32 TryBoosterEnergy(u32 battler, enum ItemEffect caseID)
|
||||
static inline u32 TryBoosterEnergy(u32 battler, enum ItemCaseId caseID)
|
||||
{
|
||||
if (gBattleStruct->boosterEnergyActivates & (1u << battler) || gBattleMons[battler].status2 & STATUS2_TRANSFORMED)
|
||||
return ITEM_NO_EFFECT;
|
||||
@ -7487,7 +7500,7 @@ static u8 ItemEffectMoveEnd(u32 battler, u16 holdEffect)
|
||||
return effect;
|
||||
}
|
||||
|
||||
static inline bool32 TryCureStatus(u32 battler, enum ItemEffect caseId)
|
||||
static inline bool32 TryCureStatus(u32 battler, enum ItemCaseId caseId)
|
||||
{
|
||||
u32 effect = ITEM_NO_EFFECT;
|
||||
u32 string = 0;
|
||||
@ -7546,10 +7559,10 @@ static inline bool32 TryCureStatus(u32 battler, enum ItemEffect caseId)
|
||||
return effect;
|
||||
}
|
||||
|
||||
u32 ItemBattleEffects(enum ItemEffect caseID, u32 battler, bool32 moveTurn)
|
||||
u32 ItemBattleEffects(enum ItemCaseId caseID, u32 battler, bool32 moveTurn)
|
||||
{
|
||||
u32 moveType = 0;
|
||||
u32 effect = ITEM_NO_EFFECT;
|
||||
enum ItemEffect effect = ITEM_NO_EFFECT;
|
||||
u32 battlerHoldEffect = 0, atkHoldEffect = 0;
|
||||
u32 atkHoldEffectParam = 0;
|
||||
u32 atkItem = 0;
|
||||
@ -7746,24 +7759,7 @@ u32 ItemBattleEffects(enum ItemEffect caseID, u32 battler, bool32 moveTurn)
|
||||
}
|
||||
break;
|
||||
case HOLD_EFFECT_EJECT_PACK:
|
||||
if (gProtectStructs[battler].statFell
|
||||
&& gProtectStructs[battler].disableEjectPack == 0
|
||||
&& CountUsablePartyMons(battler) > 0
|
||||
&& !(gCurrentMove == MOVE_PARTING_SHOT && CanBattlerSwitch(gBattlerAttacker))) // Does not activate if attacker used Parting Shot and can switch out
|
||||
{
|
||||
gProtectStructs[battler].statFell = FALSE;
|
||||
gBattleScripting.battler = battler;
|
||||
effect = ITEM_STATS_CHANGE;
|
||||
if (moveTurn)
|
||||
{
|
||||
BattleScriptPushCursor();
|
||||
gBattlescriptCurrInstr = BattleScript_EjectPackActivate_Ret;
|
||||
}
|
||||
else
|
||||
{
|
||||
BattleScriptExecute(BattleScript_EjectPackActivate_End2);
|
||||
}
|
||||
}
|
||||
effect = TryEjectPack(battler, caseID);
|
||||
break;
|
||||
case HOLD_EFFECT_BERSERK_GENE:
|
||||
BufferStatChange(battler, STAT_ATK, STRINGID_STATROSE);
|
||||
@ -7791,12 +7787,10 @@ u32 ItemBattleEffects(enum ItemEffect caseID, u32 battler, bool32 moveTurn)
|
||||
{
|
||||
gSpecialStatuses[battler].switchInItemDone = TRUE;
|
||||
gBattlerAttacker = gPotentialItemEffectBattler = gBattleScripting.battler = battler;
|
||||
switch (effect)
|
||||
if (effect == ITEM_STATUS_CHANGE)
|
||||
{
|
||||
case ITEM_STATUS_CHANGE:
|
||||
BtlController_EmitSetMonData(battler, BUFFER_A, REQUEST_STATUS_BATTLE, 0, 4, &gBattleMons[battler].status1);
|
||||
MarkBattlerForControllerExec(battler);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -8007,12 +8001,10 @@ u32 ItemBattleEffects(enum ItemEffect caseID, u32 battler, bool32 moveTurn)
|
||||
if (effect != 0)
|
||||
{
|
||||
gBattlerAttacker = gPotentialItemEffectBattler = gBattleScripting.battler = battler;
|
||||
switch (effect)
|
||||
if (effect == ITEM_STATUS_CHANGE)
|
||||
{
|
||||
case ITEM_STATUS_CHANGE:
|
||||
BtlController_EmitSetMonData(battler, BUFFER_A, REQUEST_STATUS_BATTLE, 0, 4, &gBattleMons[battler].status1);
|
||||
MarkBattlerForControllerExec(battler);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -8369,16 +8361,7 @@ u32 ItemBattleEffects(enum ItemEffect caseID, u32 battler, bool32 moveTurn)
|
||||
}
|
||||
break;
|
||||
case HOLD_EFFECT_EJECT_PACK:
|
||||
if (gProtectStructs[battler].statFell
|
||||
&& gProtectStructs[battler].disableEjectPack == 0
|
||||
&& CountUsablePartyMons(battler) > 0)
|
||||
{
|
||||
gBattleScripting.battler = battler;
|
||||
gPotentialItemEffectBattler = battler;
|
||||
effect = ITEM_STATS_CHANGE;
|
||||
BattleScriptPushCursor();
|
||||
gBattlescriptCurrInstr = BattleScript_EjectPackActivates;
|
||||
}
|
||||
effect = TryEjectPack(battler, ITEMEFFECT_ON_SWITCH_IN);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
@ -105,7 +105,6 @@ SINGLE_BATTLE_TEST("Eject Pack activates once intimidate mon switches in")
|
||||
|
||||
SINGLE_BATTLE_TEST("Eject Pack will not activate if Parting Shot user can switch out")
|
||||
{
|
||||
ASSUME(gItemsInfo[ITEM_EJECT_PACK].holdEffect == HOLD_EFFECT_EJECT_PACK);
|
||||
GIVEN {
|
||||
PLAYER(SPECIES_WOBBUFFET) { Item(ITEM_EJECT_PACK); }
|
||||
PLAYER(SPECIES_WOBBUFFET);
|
||||
@ -121,3 +120,20 @@ SINGLE_BATTLE_TEST("Eject Pack will not activate if Parting Shot user can switch
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
DOUBLE_BATTLE_TEST("Eject Pack will not trigger if the conditions are not met")
|
||||
{
|
||||
GIVEN {
|
||||
PLAYER(SPECIES_WOBBUFFET) { Item(ITEM_EJECT_PACK); }
|
||||
PLAYER(SPECIES_BELDUM) { Ability(ABILITY_CLEAR_BODY); };
|
||||
PLAYER(SPECIES_RALTS) { Ability(ABILITY_TRACE); Item(ITEM_EJECT_PACK); }
|
||||
PLAYER(SPECIES_WYNAUT);
|
||||
OPPONENT(SPECIES_WYNAUT);
|
||||
OPPONENT(SPECIES_WOBBUFFET);
|
||||
OPPONENT(SPECIES_EKANS) { Ability(ABILITY_INTIMIDATE); }
|
||||
} WHEN {
|
||||
TURN { SWITCH(opponentLeft, 2); SEND_OUT(playerLeft, 2); }
|
||||
} SCENE {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user