Merge branch 'rh-hideout:master' into master
This commit is contained in:
commit
2b265bd01a
@ -3202,7 +3202,7 @@ BattleScript_StatDownEnd::
|
|||||||
BattleScript_MirrorArmorReflect::
|
BattleScript_MirrorArmorReflect::
|
||||||
pause B_WAIT_TIME_SHORT
|
pause B_WAIT_TIME_SHORT
|
||||||
call BattleScript_AbilityPopUp
|
call BattleScript_AbilityPopUp
|
||||||
jumpifsubstituteblocks BattleScript_AbilityNoSpecificStatLoss
|
jumpifstatus2 BS_ATTACKER, STATUS2_SUBSTITUTE, BattleScript_MirrorArmorDoesntAffect
|
||||||
BattleScript_MirrorArmorReflectStatLoss:
|
BattleScript_MirrorArmorReflectStatLoss:
|
||||||
statbuffchange MOVE_EFFECT_AFFECTS_USER | STAT_CHANGE_MIRROR_ARMOR | STAT_CHANGE_NOT_PROTECT_AFFECTED | STAT_CHANGE_ALLOW_PTR, BattleScript_MirrorArmorReflectEnd
|
statbuffchange MOVE_EFFECT_AFFECTS_USER | STAT_CHANGE_MIRROR_ARMOR | STAT_CHANGE_NOT_PROTECT_AFFECTED | STAT_CHANGE_ALLOW_PTR, BattleScript_MirrorArmorReflectEnd
|
||||||
jumpifbyte CMP_LESS_THAN, cMULTISTRING_CHOOSER, B_MSG_STAT_WONT_DECREASE, BattleScript_MirrorArmorReflectAnim
|
jumpifbyte CMP_LESS_THAN, cMULTISTRING_CHOOSER, B_MSG_STAT_WONT_DECREASE, BattleScript_MirrorArmorReflectAnim
|
||||||
@ -3216,6 +3216,13 @@ BattleScript_MirrorArmorReflectPrintString:
|
|||||||
BattleScript_MirrorArmorReflectEnd:
|
BattleScript_MirrorArmorReflectEnd:
|
||||||
return
|
return
|
||||||
|
|
||||||
|
BattleScript_MirrorArmorDoesntAffect:
|
||||||
|
swapattackerwithtarget
|
||||||
|
printstring STRINGID_ITDOESNTAFFECT
|
||||||
|
waitmessage B_WAIT_TIME_LONG
|
||||||
|
swapattackerwithtarget
|
||||||
|
return
|
||||||
|
|
||||||
BattleScript_MirrorArmorReflectWontFall:
|
BattleScript_MirrorArmorReflectWontFall:
|
||||||
copybyte gBattlerTarget, gBattlerAttacker @ STRINGID_STATSWONTDECREASE uses target
|
copybyte gBattlerTarget, gBattlerAttacker @ STRINGID_STATSWONTDECREASE uses target
|
||||||
goto BattleScript_MirrorArmorReflectPrintString
|
goto BattleScript_MirrorArmorReflectPrintString
|
||||||
|
|||||||
@ -228,13 +228,11 @@ struct SpecialStatus
|
|||||||
// End of byte
|
// End of byte
|
||||||
u8 dancerUsedMove:1;
|
u8 dancerUsedMove:1;
|
||||||
u8 dancerOriginalTarget:3;
|
u8 dancerOriginalTarget:3;
|
||||||
u8 preventLifeOrbDamage:1; // So that Life Orb doesn't activate various effects.
|
|
||||||
u8 distortedTypeMatchups:1;
|
u8 distortedTypeMatchups:1;
|
||||||
u8 teraShellAbilityDone:1;
|
u8 teraShellAbilityDone:1;
|
||||||
u8 criticalHit:1;
|
u8 criticalHit:1;
|
||||||
// End of byte
|
|
||||||
u8 enduredDamage:1;
|
u8 enduredDamage:1;
|
||||||
u8 padding:7;
|
// End of byte
|
||||||
};
|
};
|
||||||
|
|
||||||
struct SideTimer
|
struct SideTimer
|
||||||
|
|||||||
@ -351,5 +351,6 @@ bool32 HasWeatherEffect(void);
|
|||||||
bool32 IsMovePowderBlocked(u32 battlerAtk, u32 battlerDef, u32 move);
|
bool32 IsMovePowderBlocked(u32 battlerAtk, u32 battlerDef, u32 move);
|
||||||
bool32 EmergencyExitCanBeTriggered(u32 battler);
|
bool32 EmergencyExitCanBeTriggered(u32 battler);
|
||||||
u32 RestoreWhiteHerbStats(u32 battler);
|
u32 RestoreWhiteHerbStats(u32 battler);
|
||||||
|
bool32 IsFutureSightAttackerInParty(u32 battlerAtk, u32 battlerDef);
|
||||||
|
|
||||||
#endif // GUARD_BATTLE_UTIL_H
|
#endif // GUARD_BATTLE_UTIL_H
|
||||||
|
|||||||
@ -7064,7 +7064,6 @@ static void Cmd_moveend(void)
|
|||||||
gEffectBattler = gBattlerTarget;
|
gEffectBattler = gBattlerTarget;
|
||||||
BattleScriptPushCursor();
|
BattleScriptPushCursor();
|
||||||
gBattlescriptCurrInstr = BattleScript_MagicianActivates;
|
gBattlescriptCurrInstr = BattleScript_MagicianActivates;
|
||||||
gSpecialStatuses[gBattlerAttacker].preventLifeOrbDamage = TRUE;
|
|
||||||
effect = TRUE;
|
effect = TRUE;
|
||||||
}
|
}
|
||||||
gBattleScripting.moveendState++;
|
gBattleScripting.moveendState++;
|
||||||
@ -7404,7 +7403,6 @@ static void Cmd_moveend(void)
|
|||||||
gBattleStruct->ateBoost[gBattlerAttacker] = FALSE;
|
gBattleStruct->ateBoost[gBattlerAttacker] = FALSE;
|
||||||
gStatuses3[gBattlerAttacker] &= ~STATUS3_ME_FIRST;
|
gStatuses3[gBattlerAttacker] &= ~STATUS3_ME_FIRST;
|
||||||
gSpecialStatuses[gBattlerAttacker].gemBoost = FALSE;
|
gSpecialStatuses[gBattlerAttacker].gemBoost = FALSE;
|
||||||
gSpecialStatuses[gBattlerAttacker].preventLifeOrbDamage = 0;
|
|
||||||
gSpecialStatuses[gBattlerTarget].berryReduced = FALSE;
|
gSpecialStatuses[gBattlerTarget].berryReduced = FALSE;
|
||||||
gSpecialStatuses[gBattlerTarget].distortedTypeMatchups = FALSE;
|
gSpecialStatuses[gBattlerTarget].distortedTypeMatchups = FALSE;
|
||||||
gBattleScripting.moveEffect = 0;
|
gBattleScripting.moveEffect = 0;
|
||||||
|
|||||||
@ -2930,8 +2930,6 @@ bool32 HandleWishPerishSongOnTurnEnd(void)
|
|||||||
|
|
||||||
if (gWishFutureKnock.futureSightCounter[battler] == gBattleTurnCounter && !(gAbsentBattlerFlags & (1u << battler)))
|
if (gWishFutureKnock.futureSightCounter[battler] == gBattleTurnCounter && !(gAbsentBattlerFlags & (1u << battler)))
|
||||||
{
|
{
|
||||||
struct Pokemon *party;
|
|
||||||
|
|
||||||
if (gWishFutureKnock.futureSightCounter[battler] == gBattleTurnCounter
|
if (gWishFutureKnock.futureSightCounter[battler] == gBattleTurnCounter
|
||||||
&& gWishFutureKnock.futureSightCounter[BATTLE_PARTNER(battler)] <= gBattleTurnCounter)
|
&& gWishFutureKnock.futureSightCounter[BATTLE_PARTNER(battler)] <= gBattleTurnCounter)
|
||||||
{
|
{
|
||||||
@ -2952,8 +2950,7 @@ bool32 HandleWishPerishSongOnTurnEnd(void)
|
|||||||
gBattlerAttacker = gWishFutureKnock.futureSightBattlerIndex[battler];
|
gBattlerAttacker = gWishFutureKnock.futureSightBattlerIndex[battler];
|
||||||
gCurrentMove = gWishFutureKnock.futureSightMove[battler];
|
gCurrentMove = gWishFutureKnock.futureSightMove[battler];
|
||||||
|
|
||||||
party = GetSideParty(GetBattlerSide(gBattlerAttacker));
|
if (!IsFutureSightAttackerInParty(gBattlerAttacker, gBattlerTarget))
|
||||||
if (&party[gWishFutureKnock.futureSightPartyIndex[gBattlerTarget]] == &party[gBattlerPartyIndexes[gBattlerAttacker]])
|
|
||||||
SetTypeBeforeUsingMove(gCurrentMove, gBattlerAttacker);
|
SetTypeBeforeUsingMove(gCurrentMove, gBattlerAttacker);
|
||||||
|
|
||||||
BattleScriptExecute(BattleScript_MonTookFutureAttack);
|
BattleScriptExecute(BattleScript_MonTookFutureAttack);
|
||||||
@ -5879,12 +5876,9 @@ u32 AbilityBattleEffects(u32 caseID, u32 battler, u32 ability, u32 special, u32
|
|||||||
&& IsBattlerAlive(gBattlerAttacker))
|
&& IsBattlerAlive(gBattlerAttacker))
|
||||||
{
|
{
|
||||||
// Prevent Innards Out effect if Future Sight user is currently not on field
|
// Prevent Innards Out effect if Future Sight user is currently not on field
|
||||||
if (GetMoveEffect(gCurrentMove) == EFFECT_FUTURE_SIGHT)
|
if (GetMoveEffect(gCurrentMove) == EFFECT_FUTURE_SIGHT
|
||||||
{
|
&& IsFutureSightAttackerInParty(gBattlerAttacker, gBattlerTarget))
|
||||||
if (gWishFutureKnock.futureSightPartyIndex[gBattlerTarget] != gBattlerPartyIndexes[gBattlerAttacker]
|
break;
|
||||||
&& gWishFutureKnock.futureSightPartyIndex[gBattlerTarget] != BATTLE_PARTNER(gBattlerPartyIndexes[gBattlerAttacker]))
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
gBattleScripting.battler = gBattlerTarget;
|
gBattleScripting.battler = gBattlerTarget;
|
||||||
gBattleStruct->moveDamage[gBattlerAttacker] = gBattleStruct->moveDamage[gBattlerTarget];
|
gBattleStruct->moveDamage[gBattlerAttacker] = gBattleStruct->moveDamage[gBattlerTarget];
|
||||||
@ -8202,7 +8196,7 @@ u32 ItemBattleEffects(enum ItemCaseId caseID, u32 battler, bool32 moveTurn)
|
|||||||
&& !(TestIfSheerForceAffected(gBattlerAttacker, gCurrentMove))
|
&& !(TestIfSheerForceAffected(gBattlerAttacker, gCurrentMove))
|
||||||
&& GetBattlerAbility(gBattlerAttacker) != ABILITY_MAGIC_GUARD
|
&& GetBattlerAbility(gBattlerAttacker) != ABILITY_MAGIC_GUARD
|
||||||
&& !gProtectStructs[gBattlerAttacker].confusionSelfDmg
|
&& !gProtectStructs[gBattlerAttacker].confusionSelfDmg
|
||||||
&& !gSpecialStatuses[gBattlerAttacker].preventLifeOrbDamage)
|
&& !IsFutureSightAttackerInParty(gBattlerAttacker, gBattlerTarget))
|
||||||
{
|
{
|
||||||
gBattleStruct->moveDamage[gBattlerAttacker] = GetNonDynamaxMaxHP(gBattlerAttacker) / 10;
|
gBattleStruct->moveDamage[gBattlerAttacker] = GetNonDynamaxMaxHP(gBattlerAttacker) / 10;
|
||||||
if (gBattleStruct->moveDamage[gBattlerAttacker] == 0)
|
if (gBattleStruct->moveDamage[gBattlerAttacker] == 0)
|
||||||
@ -10510,8 +10504,6 @@ static inline s32 DoFutureSightAttackDamageCalcVars(struct DamageCalculationData
|
|||||||
if (dmg == 0)
|
if (dmg == 0)
|
||||||
dmg = 1;
|
dmg = 1;
|
||||||
|
|
||||||
gSpecialStatuses[battlerAtk].preventLifeOrbDamage = TRUE;
|
|
||||||
|
|
||||||
return dmg;
|
return dmg;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -10538,14 +10530,11 @@ static u32 GetWeather(void)
|
|||||||
return gBattleWeather;
|
return gBattleWeather;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline bool32 IsFutureSightAttackerInParty(struct DamageCalculationData *damageCalcData)
|
bool32 IsFutureSightAttackerInParty(u32 battlerAtk, u32 battlerDef)
|
||||||
{
|
{
|
||||||
if (GetMoveEffect(damageCalcData->move) != EFFECT_FUTURE_SIGHT)
|
struct Pokemon *party = GetSideParty(GetBattlerSide(battlerAtk));
|
||||||
return FALSE;
|
return &party[gWishFutureKnock.futureSightPartyIndex[battlerDef]] != &party[gBattlerPartyIndexes[battlerAtk]]
|
||||||
|
&& &party[gWishFutureKnock.futureSightPartyIndex[battlerDef]] != &party[BATTLE_PARTNER(gBattlerPartyIndexes[battlerAtk])];
|
||||||
struct Pokemon *party = GetSideParty(GetBattlerSide(damageCalcData->battlerAtk));
|
|
||||||
return &party[gWishFutureKnock.futureSightPartyIndex[damageCalcData->battlerDef]]
|
|
||||||
!= &party[gBattlerPartyIndexes[damageCalcData->battlerAtk]];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
s32 CalculateMoveDamage(struct DamageCalculationData *damageCalcData, u32 fixedBasePower)
|
s32 CalculateMoveDamage(struct DamageCalculationData *damageCalcData, u32 fixedBasePower)
|
||||||
@ -10557,7 +10546,8 @@ s32 CalculateMoveDamage(struct DamageCalculationData *damageCalcData, u32 fixedB
|
|||||||
GetBattlerAbility(damageCalcData->battlerDef),
|
GetBattlerAbility(damageCalcData->battlerDef),
|
||||||
damageCalcData->updateFlags);
|
damageCalcData->updateFlags);
|
||||||
|
|
||||||
if (IsFutureSightAttackerInParty(damageCalcData))
|
if (GetMoveEffect(damageCalcData->move) == EFFECT_FUTURE_SIGHT
|
||||||
|
&& IsFutureSightAttackerInParty(damageCalcData->battlerAtk, damageCalcData->battlerDef))
|
||||||
return DoFutureSightAttackDamageCalc(damageCalcData, typeEffectivenessMultiplier, GetWeather());
|
return DoFutureSightAttackDamageCalc(damageCalcData, typeEffectivenessMultiplier, GetWeather());
|
||||||
|
|
||||||
return DoMoveDamageCalc(damageCalcData, fixedBasePower, typeEffectivenessMultiplier, GetWeather());
|
return DoMoveDamageCalc(damageCalcData, fixedBasePower, typeEffectivenessMultiplier, GetWeather());
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
#include "global.h"
|
#include "global.h"
|
||||||
#include "test/battle.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 {
|
GIVEN {
|
||||||
ASSUME(gItemsInfo[ITEM_LIFE_ORB].holdEffect == HOLD_EFFECT_LIFE_ORB);
|
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!");
|
MESSAGE("Delphox used Tackle!");
|
||||||
ABILITY_POPUP(player, ABILITY_MAGICIAN);
|
ABILITY_POPUP(player, ABILITY_MAGICIAN);
|
||||||
MESSAGE("Delphox stole the opposing Wobbuffet's Life Orb!");
|
MESSAGE("Delphox stole the opposing Wobbuffet's Life Orb!");
|
||||||
NONE_OF {
|
HP_BAR(player);
|
||||||
HP_BAR(player);
|
MESSAGE("Delphox was hurt by the Life Orb!");
|
||||||
MESSAGE("Delphox was hurt by the Life Orb!");
|
|
||||||
}
|
|
||||||
// 2nd turn - Life Orb recoil happens now
|
// 2nd turn - Life Orb recoil happens now
|
||||||
MESSAGE("Delphox used Tackle!");
|
MESSAGE("Delphox used Tackle!");
|
||||||
HP_BAR(player);
|
HP_BAR(player);
|
||||||
|
|||||||
@ -102,10 +102,8 @@ SINGLE_BATTLE_TEST("Mirror Armor lowers the Attack of Pokemon with Intimidate")
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Unsure whether this should or should not fail, as Showdown has conflicting information. Needs testing in gen8 games.
|
|
||||||
SINGLE_BATTLE_TEST("Mirror Armor doesn't lower the stats of an attacking Pokemon behind Substitute")
|
SINGLE_BATTLE_TEST("Mirror Armor doesn't lower the stats of an attacking Pokemon behind Substitute")
|
||||||
{
|
{
|
||||||
KNOWN_FAILING;
|
|
||||||
GIVEN {
|
GIVEN {
|
||||||
PLAYER(SPECIES_CORVIKNIGHT) { Ability(ABILITY_MIRROR_ARMOR); }
|
PLAYER(SPECIES_CORVIKNIGHT) { Ability(ABILITY_MIRROR_ARMOR); }
|
||||||
OPPONENT(SPECIES_WYNAUT);
|
OPPONENT(SPECIES_WYNAUT);
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user