Fixes Magician Life Orb interaction (#6676)
This commit is contained in:
parent
91fc406b0a
commit
71cfab6477
@ -228,13 +228,11 @@ struct SpecialStatus
|
||||
// End of byte
|
||||
u8 dancerUsedMove:1;
|
||||
u8 dancerOriginalTarget:3;
|
||||
u8 preventLifeOrbDamage:1; // So that Life Orb doesn't activate various effects.
|
||||
u8 distortedTypeMatchups:1;
|
||||
u8 teraShellAbilityDone:1;
|
||||
u8 criticalHit:1;
|
||||
// End of byte
|
||||
u8 enduredDamage:1;
|
||||
u8 padding:7;
|
||||
// End of byte
|
||||
};
|
||||
|
||||
struct SideTimer
|
||||
|
||||
@ -351,5 +351,6 @@ bool32 HasWeatherEffect(void);
|
||||
bool32 IsMovePowderBlocked(u32 battlerAtk, u32 battlerDef, u32 move);
|
||||
bool32 EmergencyExitCanBeTriggered(u32 battler);
|
||||
u32 RestoreWhiteHerbStats(u32 battler);
|
||||
bool32 IsFutureSightAttackerInParty(u32 battlerAtk, u32 battlerDef);
|
||||
|
||||
#endif // GUARD_BATTLE_UTIL_H
|
||||
|
||||
@ -7064,7 +7064,6 @@ static void Cmd_moveend(void)
|
||||
gEffectBattler = gBattlerTarget;
|
||||
BattleScriptPushCursor();
|
||||
gBattlescriptCurrInstr = BattleScript_MagicianActivates;
|
||||
gSpecialStatuses[gBattlerAttacker].preventLifeOrbDamage = TRUE;
|
||||
effect = TRUE;
|
||||
}
|
||||
gBattleScripting.moveendState++;
|
||||
@ -7404,7 +7403,6 @@ static void Cmd_moveend(void)
|
||||
gBattleStruct->ateBoost[gBattlerAttacker] = FALSE;
|
||||
gStatuses3[gBattlerAttacker] &= ~STATUS3_ME_FIRST;
|
||||
gSpecialStatuses[gBattlerAttacker].gemBoost = FALSE;
|
||||
gSpecialStatuses[gBattlerAttacker].preventLifeOrbDamage = 0;
|
||||
gSpecialStatuses[gBattlerTarget].berryReduced = FALSE;
|
||||
gSpecialStatuses[gBattlerTarget].distortedTypeMatchups = FALSE;
|
||||
gBattleScripting.moveEffect = 0;
|
||||
|
||||
@ -2930,8 +2930,6 @@ bool32 HandleWishPerishSongOnTurnEnd(void)
|
||||
|
||||
if (gWishFutureKnock.futureSightCounter[battler] == gBattleTurnCounter && !(gAbsentBattlerFlags & (1u << battler)))
|
||||
{
|
||||
struct Pokemon *party;
|
||||
|
||||
if (gWishFutureKnock.futureSightCounter[battler] == gBattleTurnCounter
|
||||
&& gWishFutureKnock.futureSightCounter[BATTLE_PARTNER(battler)] <= gBattleTurnCounter)
|
||||
{
|
||||
@ -2952,8 +2950,7 @@ bool32 HandleWishPerishSongOnTurnEnd(void)
|
||||
gBattlerAttacker = gWishFutureKnock.futureSightBattlerIndex[battler];
|
||||
gCurrentMove = gWishFutureKnock.futureSightMove[battler];
|
||||
|
||||
party = GetSideParty(GetBattlerSide(gBattlerAttacker));
|
||||
if (&party[gWishFutureKnock.futureSightPartyIndex[gBattlerTarget]] == &party[gBattlerPartyIndexes[gBattlerAttacker]])
|
||||
if (!IsFutureSightAttackerInParty(gBattlerAttacker, gBattlerTarget))
|
||||
SetTypeBeforeUsingMove(gCurrentMove, gBattlerAttacker);
|
||||
|
||||
BattleScriptExecute(BattleScript_MonTookFutureAttack);
|
||||
@ -5879,12 +5876,9 @@ u32 AbilityBattleEffects(u32 caseID, u32 battler, u32 ability, u32 special, u32
|
||||
&& IsBattlerAlive(gBattlerAttacker))
|
||||
{
|
||||
// Prevent Innards Out effect if Future Sight user is currently not on field
|
||||
if (GetMoveEffect(gCurrentMove) == EFFECT_FUTURE_SIGHT)
|
||||
{
|
||||
if (gWishFutureKnock.futureSightPartyIndex[gBattlerTarget] != gBattlerPartyIndexes[gBattlerAttacker]
|
||||
&& gWishFutureKnock.futureSightPartyIndex[gBattlerTarget] != BATTLE_PARTNER(gBattlerPartyIndexes[gBattlerAttacker]))
|
||||
break;
|
||||
}
|
||||
if (GetMoveEffect(gCurrentMove) == EFFECT_FUTURE_SIGHT
|
||||
&& IsFutureSightAttackerInParty(gBattlerAttacker, gBattlerTarget))
|
||||
break;
|
||||
|
||||
gBattleScripting.battler = gBattlerTarget;
|
||||
gBattleStruct->moveDamage[gBattlerAttacker] = gBattleStruct->moveDamage[gBattlerTarget];
|
||||
@ -8202,7 +8196,7 @@ u32 ItemBattleEffects(enum ItemCaseId caseID, u32 battler, bool32 moveTurn)
|
||||
&& !(TestIfSheerForceAffected(gBattlerAttacker, gCurrentMove))
|
||||
&& GetBattlerAbility(gBattlerAttacker) != ABILITY_MAGIC_GUARD
|
||||
&& !gProtectStructs[gBattlerAttacker].confusionSelfDmg
|
||||
&& !gSpecialStatuses[gBattlerAttacker].preventLifeOrbDamage)
|
||||
&& !IsFutureSightAttackerInParty(gBattlerAttacker, gBattlerTarget))
|
||||
{
|
||||
gBattleStruct->moveDamage[gBattlerAttacker] = GetNonDynamaxMaxHP(gBattlerAttacker) / 10;
|
||||
if (gBattleStruct->moveDamage[gBattlerAttacker] == 0)
|
||||
@ -10510,8 +10504,6 @@ static inline s32 DoFutureSightAttackDamageCalcVars(struct DamageCalculationData
|
||||
if (dmg == 0)
|
||||
dmg = 1;
|
||||
|
||||
gSpecialStatuses[battlerAtk].preventLifeOrbDamage = TRUE;
|
||||
|
||||
return dmg;
|
||||
}
|
||||
|
||||
@ -10538,14 +10530,11 @@ static u32 GetWeather(void)
|
||||
return gBattleWeather;
|
||||
}
|
||||
|
||||
static inline bool32 IsFutureSightAttackerInParty(struct DamageCalculationData *damageCalcData)
|
||||
bool32 IsFutureSightAttackerInParty(u32 battlerAtk, u32 battlerDef)
|
||||
{
|
||||
if (GetMoveEffect(damageCalcData->move) != EFFECT_FUTURE_SIGHT)
|
||||
return FALSE;
|
||||
|
||||
struct Pokemon *party = GetSideParty(GetBattlerSide(damageCalcData->battlerAtk));
|
||||
return &party[gWishFutureKnock.futureSightPartyIndex[damageCalcData->battlerDef]]
|
||||
!= &party[gBattlerPartyIndexes[damageCalcData->battlerAtk]];
|
||||
struct Pokemon *party = GetSideParty(GetBattlerSide(battlerAtk));
|
||||
return &party[gWishFutureKnock.futureSightPartyIndex[battlerDef]] != &party[gBattlerPartyIndexes[battlerAtk]]
|
||||
&& &party[gWishFutureKnock.futureSightPartyIndex[battlerDef]] != &party[BATTLE_PARTNER(gBattlerPartyIndexes[battlerAtk])];
|
||||
}
|
||||
|
||||
s32 CalculateMoveDamage(struct DamageCalculationData *damageCalcData, u32 fixedBasePower)
|
||||
@ -10557,7 +10546,8 @@ s32 CalculateMoveDamage(struct DamageCalculationData *damageCalcData, u32 fixedB
|
||||
GetBattlerAbility(damageCalcData->battlerDef),
|
||||
damageCalcData->updateFlags);
|
||||
|
||||
if (IsFutureSightAttackerInParty(damageCalcData))
|
||||
if (GetMoveEffect(damageCalcData->move) == EFFECT_FUTURE_SIGHT
|
||||
&& IsFutureSightAttackerInParty(damageCalcData->battlerAtk, damageCalcData->battlerDef))
|
||||
return DoFutureSightAttackDamageCalc(damageCalcData, typeEffectivenessMultiplier, GetWeather());
|
||||
|
||||
return DoMoveDamageCalc(damageCalcData, fixedBasePower, typeEffectivenessMultiplier, GetWeather());
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
#include "global.h"
|
||||
#include "test/battle.h"
|
||||
|
||||
SINGLE_BATTLE_TEST("Magician does not get self-damage recoil after stealing Life Orb")
|
||||
SINGLE_BATTLE_TEST("Magician gets self-damage recoil after stealing Life Orb")
|
||||
{
|
||||
GIVEN {
|
||||
ASSUME(gItemsInfo[ITEM_LIFE_ORB].holdEffect == HOLD_EFFECT_LIFE_ORB);
|
||||
@ -16,10 +16,8 @@ SINGLE_BATTLE_TEST("Magician does not get self-damage recoil after stealing Life
|
||||
MESSAGE("Delphox used Tackle!");
|
||||
ABILITY_POPUP(player, ABILITY_MAGICIAN);
|
||||
MESSAGE("Delphox stole the opposing Wobbuffet's Life Orb!");
|
||||
NONE_OF {
|
||||
HP_BAR(player);
|
||||
MESSAGE("Delphox was hurt by the Life Orb!");
|
||||
}
|
||||
HP_BAR(player);
|
||||
MESSAGE("Delphox was hurt by the Life Orb!");
|
||||
// 2nd turn - Life Orb recoil happens now
|
||||
MESSAGE("Delphox used Tackle!");
|
||||
HP_BAR(player);
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user