Merge branch 'rh-hideout:master' into master

This commit is contained in:
RoamerX 2025-04-23 15:42:35 +08:00 committed by GitHub
commit 2b265bd01a
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
7 changed files with 24 additions and 34 deletions

View File

@ -3202,7 +3202,7 @@ BattleScript_StatDownEnd::
BattleScript_MirrorArmorReflect::
pause B_WAIT_TIME_SHORT
call BattleScript_AbilityPopUp
jumpifsubstituteblocks BattleScript_AbilityNoSpecificStatLoss
jumpifstatus2 BS_ATTACKER, STATUS2_SUBSTITUTE, BattleScript_MirrorArmorDoesntAffect
BattleScript_MirrorArmorReflectStatLoss:
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
@ -3216,6 +3216,13 @@ BattleScript_MirrorArmorReflectPrintString:
BattleScript_MirrorArmorReflectEnd:
return
BattleScript_MirrorArmorDoesntAffect:
swapattackerwithtarget
printstring STRINGID_ITDOESNTAFFECT
waitmessage B_WAIT_TIME_LONG
swapattackerwithtarget
return
BattleScript_MirrorArmorReflectWontFall:
copybyte gBattlerTarget, gBattlerAttacker @ STRINGID_STATSWONTDECREASE uses target
goto BattleScript_MirrorArmorReflectPrintString

View File

@ -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

View File

@ -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

View File

@ -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;

View File

@ -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());

View File

@ -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);

View File

@ -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")
{
KNOWN_FAILING;
GIVEN {
PLAYER(SPECIES_CORVIKNIGHT) { Ability(ABILITY_MIRROR_ARMOR); }
OPPONENT(SPECIES_WYNAUT);