Fix Fling Mental Herb message (#7984)
Some checks are pending
CI / build (push) Waiting to run
CI / allcontributors (push) Waiting to run

This commit is contained in:
Alex 2025-10-19 22:38:27 +02:00 committed by GitHub
parent cb0d503f66
commit 786859b6bb
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
9 changed files with 95 additions and 106 deletions

View File

@ -1790,11 +1790,8 @@
.4byte \jumpInstr .4byte \jumpInstr
.endm .endm
.macro jumpiflastuseditemholdeffect holdEffect:req, secondaryId:req, jumpInstr:req .macro tryflingholdeffect
callnative BS_JumpIfLastUsedItemHoldEffect callnative BS_TryFlingHoldEffect
.byte \holdEffect
.2byte \secondaryId
.4byte \jumpInstr
.endm .endm
.macro swapsidestatuses .macro swapsidestatuses
@ -2391,10 +2388,6 @@
.4byte \failInstr .4byte \failInstr
.endm .endm
.macro curecertainstatuses
callnative BS_CureCertainStatuses
.endm
.macro tryresetnegativestatstages .macro tryresetnegativestatstages
callnative BS_TryResetNegativeStatStages callnative BS_TryResetNegativeStatStages
.endm .endm

View File

@ -697,15 +697,9 @@ BattleScript_EffectFling::
resultmessage resultmessage
waitmessage B_WAIT_TIME_MED waitmessage B_WAIT_TIME_MED
jumpiflastuseditemberry BattleScript_EffectFlingConsumeBerry jumpiflastuseditemberry BattleScript_EffectFlingConsumeBerry
jumpifability BS_TARGET, ABILITY_SHIELD_DUST, BattleScript_FlingBlockedByShieldDust tryflingholdeffect
jumpiflastuseditemholdeffect HOLD_EFFECT_FLAME_ORB, 0, BattleScript_FlingFlameOrb
jumpiflastuseditemholdeffect HOLD_EFFECT_FLINCH, 0, BattleScript_FlingFlinch
jumpiflastuseditemholdeffect HOLD_EFFECT_LIGHT_BALL, 0, BattleScript_FlingLightBall
jumpiflastuseditemholdeffect HOLD_EFFECT_MENTAL_HERB, 0, BattleScript_FlingMentalHerb
jumpiflastuseditemholdeffect HOLD_EFFECT_TYPE_POWER, TYPE_POISON, BattleScript_FlingPoisonBarb
jumpiflastuseditemholdeffect HOLD_EFFECT_TOXIC_ORB, 0, BattleScript_FlingToxicOrb
jumpiflastuseditemholdeffect HOLD_EFFECT_WHITE_HERB, 0, BattleScript_FlingWhiteHerb
goto BattleScript_FlingEnd goto BattleScript_FlingEnd
BattleScript_EffectFlingConsumeBerry: BattleScript_EffectFlingConsumeBerry:
savebattleritem savebattleritem
battleritemtolastuseditem battleritemtolastuseditem
@ -729,39 +723,6 @@ BattleScript_FlingBlockedByShieldDust::
waitmessage B_WAIT_TIME_LONG waitmessage B_WAIT_TIME_LONG
goto BattleScript_FlingEnd goto BattleScript_FlingEnd
BattleScript_FlingFlameOrb:
seteffectsecondary BS_ATTACKER, BS_TARGET, MOVE_EFFECT_BURN
goto BattleScript_FlingEnd
BattleScript_FlingFlinch:
seteffectsecondary BS_ATTACKER, BS_TARGET, MOVE_EFFECT_FLINCH
goto BattleScript_FlingEnd
BattleScript_FlingLightBall:
seteffectsecondary BS_ATTACKER, BS_TARGET, MOVE_EFFECT_PARALYSIS
goto BattleScript_FlingEnd
BattleScript_FlingMentalHerb:
curecertainstatuses
saveattacker
copybyte gBattlerAttacker, gBattlerTarget
playanimation BS_ATTACKER, B_ANIM_HELD_ITEM_EFFECT, NULL
printfromtable gMentalHerbCureStringIds
waitmessage B_WAIT_TIME_LONG
updatestatusicon BS_ATTACKER
restoreattacker
goto BattleScript_FlingEnd
BattleScript_FlingPoisonBarb:
seteffectsecondary BS_ATTACKER, BS_TARGET, MOVE_EFFECT_POISON
goto BattleScript_FlingEnd
BattleScript_FlingToxicOrb:
seteffectsecondary BS_ATTACKER, BS_TARGET, MOVE_EFFECT_TOXIC
goto BattleScript_FlingEnd
BattleScript_FlingWhiteHerb:
tryresetnegativestatstages
swapattackerwithtarget
printstring STRINGID_PKMNSTATUSNORMAL
waitmessage B_WAIT_TIME_MED
swapattackerwithtarget
goto BattleScript_FlingEnd
BattleScript_FlingMissed: BattleScript_FlingMissed:
removeitem BS_ATTACKER removeitem BS_ATTACKER
goto BattleScript_MoveMissedPause goto BattleScript_MoveMissedPause

View File

@ -781,6 +781,7 @@ struct BattleStruct
u8 hazardsCounter:4; // Counter for applying hazard on switch in u8 hazardsCounter:4; // Counter for applying hazard on switch in
enum SubmoveState submoveAnnouncement:2; enum SubmoveState submoveAnnouncement:2;
u8 padding2:2; u8 padding2:2;
u16 flingItem;
}; };
struct AiBattleData struct AiBattleData

View File

@ -20,7 +20,8 @@ struct HoldEffectInfo
u32 leftovers:1; u32 leftovers:1;
u32 orbs:1; u32 orbs:1;
u32 onEffect:1; u32 onEffect:1;
u32 padding:15; u32 onFling:1;
u32 padding:14;
}; };
extern const struct HoldEffectInfo gHoldEffectsInfo[]; extern const struct HoldEffectInfo gHoldEffectsInfo[];
@ -48,5 +49,6 @@ bool32 IsOrbsActivation(enum HoldEffect holdEffect);
bool32 IsOnEffectActivation(enum HoldEffect holdEffect); bool32 IsOnEffectActivation(enum HoldEffect holdEffect);
bool32 IsActivationForceTriggerItem(enum HoldEffect holdEffect); bool32 IsActivationForceTriggerItem(enum HoldEffect holdEffect);
bool32 IsActivationOnBerry(enum HoldEffect holdEffect); bool32 IsActivationOnBerry(enum HoldEffect holdEffect);
bool32 IsOnFlingActivation(enum HoldEffect holdEffect);
#endif // GUARD_BATTLE_HOLD_EFFECTS #endif // GUARD_BATTLE_HOLD_EFFECTS

View File

@ -14,6 +14,7 @@ extern const u8 BattleScript_MoveMissedPause[];
extern const u8 BattleScript_MoveMissedPause[]; extern const u8 BattleScript_MoveMissedPause[];
extern const u8 BattleScript_MoveMissed[]; extern const u8 BattleScript_MoveMissed[];
extern const u8 BattleScript_FlingFailConsumeItem[]; extern const u8 BattleScript_FlingFailConsumeItem[];
extern const u8 BattleScript_FlingBlockedByShieldDust[];
extern const u8 BattleScript_FailedFromAtkCanceler[]; extern const u8 BattleScript_FailedFromAtkCanceler[];
extern const u8 BattleScript_ButItFailed[]; extern const u8 BattleScript_ButItFailed[];
extern const u8 BattleScript_StatUp[]; extern const u8 BattleScript_StatUp[];

View File

@ -28,6 +28,7 @@ bool32 IsLeftoversActivation(enum HoldEffect holdEffect) { return gHol
bool32 IsOrbsActivation(enum HoldEffect holdEffect) { return gHoldEffectsInfo[holdEffect].orbs; } bool32 IsOrbsActivation(enum HoldEffect holdEffect) { return gHoldEffectsInfo[holdEffect].orbs; }
bool32 IsOnEffectActivation(enum HoldEffect holdEffect) { return gHoldEffectsInfo[holdEffect].onEffect; } bool32 IsOnEffectActivation(enum HoldEffect holdEffect) { return gHoldEffectsInfo[holdEffect].onEffect; }
bool32 IsActivationOnBerry(enum HoldEffect holdEffect) { return GetItemPocket(gLastUsedItem) == POCKET_BERRIES; } bool32 IsActivationOnBerry(enum HoldEffect holdEffect) { return GetItemPocket(gLastUsedItem) == POCKET_BERRIES; }
bool32 IsOnFlingActivation(enum HoldEffect holdEffect) { return gHoldEffectsInfo[holdEffect].onFling; }
bool32 IsActivationForceTriggerItem(enum HoldEffect holdEffect) bool32 IsActivationForceTriggerItem(enum HoldEffect holdEffect)
{ {
@ -177,7 +178,7 @@ static enum ItemEffect RestoreWhiteHerbStats(u32 battler, ActivationTiming timin
} }
if (effect != ITEM_NO_EFFECT) if (effect != ITEM_NO_EFFECT)
{ {
if (timing == IsWhiteHerbActivation) if (timing == IsWhiteHerbActivation || timing == IsOnFlingActivation)
BattleScriptCall(BattleScript_WhiteHerbRet); BattleScriptCall(BattleScript_WhiteHerbRet);
else else
BattleScriptExecute(BattleScript_WhiteHerbEnd2); BattleScriptExecute(BattleScript_WhiteHerbEnd2);

View File

@ -16332,14 +16332,68 @@ void BS_JumpIfCanGigantamax(void)
gBattlescriptCurrInstr = cmd->nextInstr; gBattlescriptCurrInstr = cmd->nextInstr;
} }
void BS_JumpIfLastUsedItemHoldEffect(void) void BS_TryFlingHoldEffect(void)
{ {
NATIVE_ARGS(u8 holdEffect, u16 secondaryId, const u8 *jumpInstr); NATIVE_ARGS();
if (GetItemHoldEffect(gLastUsedItem) == cmd->holdEffect enum HoldEffect holdEffect = GetItemHoldEffect(gBattleStruct->flingItem);
&& (cmd->secondaryId == 0 || GetItemSecondaryId(gLastUsedItem) == cmd->secondaryId)) gBattleStruct->flingItem = ITEM_NONE;
gBattlescriptCurrInstr = cmd->jumpInstr;
else if (IsMoveEffectBlockedByTarget(GetBattlerAbility(gBattlerTarget)))
{
gBattlescriptCurrInstr = BattleScript_FlingBlockedByShieldDust;
return;
}
switch (holdEffect)
{
case HOLD_EFFECT_FLAME_ORB:
gBattlescriptCurrInstr = cmd->nextInstr - 1;
gBattleScripting.moveEffect = MOVE_EFFECT_BURN;
SetMoveEffect(gBattlerAttacker, gBattlerTarget, FALSE, FALSE);
break;
case HOLD_EFFECT_TOXIC_ORB:
gBattlescriptCurrInstr = cmd->nextInstr - 1;
gBattleScripting.moveEffect = MOVE_EFFECT_TOXIC;
SetMoveEffect(gBattlerAttacker, gBattlerTarget, FALSE, FALSE);
break;
case HOLD_EFFECT_LIGHT_BALL:
gBattlescriptCurrInstr = cmd->nextInstr - 1;
gBattleScripting.moveEffect = MOVE_EFFECT_PARALYSIS;
SetMoveEffect(gBattlerAttacker, gBattlerTarget, FALSE, FALSE);
break;
case HOLD_EFFECT_TYPE_POWER:
if (GetItemSecondaryId(gLastUsedItem) != TYPE_POISON)
{
gBattlescriptCurrInstr = cmd->nextInstr;
}
else
{
gBattlescriptCurrInstr = cmd->nextInstr - 1;
gBattleScripting.moveEffect = MOVE_EFFECT_POISON;
SetMoveEffect(gBattlerAttacker, gBattlerTarget, FALSE, FALSE);
}
break;
case HOLD_EFFECT_FLINCH:
gBattlescriptCurrInstr = cmd->nextInstr - 1;
gBattleScripting.moveEffect = MOVE_EFFECT_FLINCH;
SetMoveEffect(gBattlerAttacker, gBattlerTarget, FALSE, FALSE);
break;
case HOLD_EFFECT_MENTAL_HERB:
if (ItemBattleEffects(gBattlerTarget, 0, holdEffect, IsOnFlingActivation))
return;
else
gBattlescriptCurrInstr = cmd->nextInstr;
break;
case HOLD_EFFECT_WHITE_HERB:
if (ItemBattleEffects(gBattlerTarget, 0, holdEffect, IsOnFlingActivation))
return;
else
gBattlescriptCurrInstr = cmd->nextInstr;
break;
default:
gBattlescriptCurrInstr = cmd->nextInstr; gBattlescriptCurrInstr = cmd->nextInstr;
break;
}
} }
void BS_JumpIfNoWhiteOut(void) void BS_JumpIfNoWhiteOut(void)
@ -16507,6 +16561,7 @@ void BS_SetLastUsedItem(void)
{ {
NATIVE_ARGS(u8 battler); NATIVE_ARGS(u8 battler);
gLastUsedItem = gBattleMons[GetBattlerForBattleScript(cmd->battler)].item; gLastUsedItem = gBattleMons[GetBattlerForBattleScript(cmd->battler)].item;
gBattleStruct->flingItem = gLastUsedItem;
gBattlescriptCurrInstr = cmd->nextInstr; gBattlescriptCurrInstr = cmd->nextInstr;
} }
@ -17924,54 +17979,6 @@ void BS_SetPoltergeistMessage(void)
gBattlescriptCurrInstr = cmd->nextInstr; gBattlescriptCurrInstr = cmd->nextInstr;
} }
void BS_CureCertainStatuses(void)
{
NATIVE_ARGS();
// Check infatuation
if (gBattleMons[gBattlerTarget].volatiles.infatuation)
{
gBattleMons[gBattlerTarget].volatiles.infatuation = 0;
gBattleCommunication[MULTISTRING_CHOOSER] = B_MSG_MENTALHERBCURE_INFATUATION; // STRINGID_TARGETGOTOVERINFATUATION
StringCopy(gBattleTextBuff1, gStatusConditionString_LoveJpn);
}
// Check taunt
if (gDisableStructs[gBattlerTarget].tauntTimer != 0)
{
gDisableStructs[gBattlerTarget].tauntTimer = 0;
gBattleCommunication[MULTISTRING_CHOOSER] = B_MSG_MENTALHERBCURE_TAUNT;
PREPARE_MOVE_BUFFER(gBattleTextBuff1, MOVE_TAUNT);
}
// Check encore
if (gDisableStructs[gBattlerTarget].encoreTimer != 0)
{
gDisableStructs[gBattlerTarget].encoredMove = 0;
gDisableStructs[gBattlerTarget].encoreTimer = 0;
gBattleCommunication[MULTISTRING_CHOOSER] = B_MSG_MENTALHERBCURE_ENCORE; // STRINGID_PKMNENCOREENDED
}
// Check torment
if (gBattleMons[gBattlerTarget].volatiles.torment == TRUE)
{
gBattleMons[gBattlerTarget].volatiles.torment = FALSE;
gBattleCommunication[MULTISTRING_CHOOSER] = B_MSG_MENTALHERBCURE_TORMENT;
}
// Check heal block
if (gBattleMons[gBattlerTarget].volatiles.healBlock)
{
gBattleMons[gBattlerTarget].volatiles.healBlock = FALSE;
gBattleCommunication[MULTISTRING_CHOOSER] = B_MSG_MENTALHERBCURE_HEALBLOCK;
}
// Check disable
if (gDisableStructs[gBattlerTarget].disableTimer != 0)
{
gDisableStructs[gBattlerTarget].disableTimer = 0;
gDisableStructs[gBattlerTarget].disabledMove = 0;
gBattleCommunication[MULTISTRING_CHOOSER] = B_MSG_MENTALHERBCURE_DISABLE;
}
gBattleScripting.battler = gBattlerTarget;
gBattlescriptCurrInstr = cmd->nextInstr;
}
void BS_TryResetNegativeStatStages(void) void BS_TryResetNegativeStatStages(void)
{ {
NATIVE_ARGS(); NATIVE_ARGS();

View File

@ -163,6 +163,7 @@ const struct HoldEffectInfo gHoldEffectsInfo[HOLD_EFFECT_COUNT] =
.whiteHerb = TRUE, .whiteHerb = TRUE,
.whiteHerbFirstTurn = TRUE, .whiteHerbFirstTurn = TRUE,
.whiteHerbEndTurn = TRUE, .whiteHerbEndTurn = TRUE,
.onFling = TRUE,
}, },
[HOLD_EFFECT_MACHO_BRACE] = [HOLD_EFFECT_MACHO_BRACE] =
@ -185,6 +186,7 @@ const struct HoldEffectInfo gHoldEffectsInfo[HOLD_EFFECT_COUNT] =
{ {
.onTargetAfterHit = TRUE, .onTargetAfterHit = TRUE,
.onAttackerAfterHit = TRUE, .onAttackerAfterHit = TRUE,
.onFling = TRUE,
}, },
[HOLD_EFFECT_CHOICE_BAND] = [HOLD_EFFECT_CHOICE_BAND] =

View File

@ -461,4 +461,25 @@ SINGLE_BATTLE_TEST("Fling deals damage based on items fling power")
} }
} }
SINGLE_BATTLE_TEST("Flinging a Mental Herb does not trigger the item if the target doesn't have anything that's cured by Mental Herb")
{
GIVEN {
PLAYER(SPECIES_WOBBUFFET) { Item(ITEM_MENTAL_HERB); }
OPPONENT(SPECIES_WOBBUFFET);
} WHEN {
TURN { MOVE(player, MOVE_FLING); }
} SCENE {
ANIMATION(ANIM_TYPE_MOVE, MOVE_FLING, player);
NONE_OF {
ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_HELD_ITEM_EFFECT, opponent);
MESSAGE("The opposing Wobbuffet got over its infatuation!");
MESSAGE("The opposing Wobbuffet's Taunt wore off!");
MESSAGE("The opposing Wobbuffet ended its encore!");
MESSAGE("The opposing Wobbuffet is no longer tormented!");
MESSAGE("The opposing Wobbuffet's move is no longer disabled!");
MESSAGE("The opposing Wobbuffet is cured of its heal block!");
}
}
}
TO_DO_BATTLE_TEST("Fling deals damage based on a TM's move power") TO_DO_BATTLE_TEST("Fling deals damage based on a TM's move power")