Clean up noResultString (#7408)

This commit is contained in:
Alex 2025-08-02 15:17:44 +02:00 committed by GitHub
parent ed44da8644
commit 3841fee888
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 31 additions and 25 deletions

View File

@ -764,7 +764,7 @@ struct BattleStruct
s16 critChance[MAX_BATTLERS_COUNT];
u16 moveResultFlags[MAX_BATTLERS_COUNT];
u8 missStringId[MAX_BATTLERS_COUNT];
u8 noResultString[MAX_BATTLERS_COUNT];
enum CalcDamageState noResultString[MAX_BATTLERS_COUNT];
u8 doneDoublesSpreadHit:1;
u8 calculatedDamageDone:1;
u8 calculatedSpreadMoveAccuracy:1;
@ -865,8 +865,6 @@ static inline bool32 IsBattleMoveStatus(u32 move)
#define SET_STATCHANGER(statId, stage, goesDown) (gBattleScripting.statChanger = (statId) + ((stage) << 3) + (goesDown << 7))
#define SET_STATCHANGER2(dst, statId, stage, goesDown)(dst = (statId) + ((stage) << 3) + (goesDown << 7))
#define DO_ACCURACY_CHECK 2 // Don't skip the accuracy check before the move might be absorbed
// NOTE: The members of this struct have hard-coded offsets
// in include/constants/battle_script_commands.h
struct BattleScripting

View File

@ -700,4 +700,11 @@ enum MonState
MON_OUTSIDE_BATTLE,
};
enum __attribute__((packed)) CalcDamageState
{
CAN_DAMAGE,
WILL_FAIL,
CHECK_ACCURACY,
};
#endif // GUARD_CONSTANTS_BATTLE_H

View File

@ -1407,7 +1407,7 @@ static void AccuracyCheck(bool32 recalcDragonDarts, const u8 *nextInstr, const u
if ((!calcSpreadMove && battlerDef != gBattlerTarget)
|| IsBattlerInvalidForSpreadMove(gBattlerAttacker, battlerDef, moveTarget)
|| (gBattleStruct->noResultString[battlerDef] && gBattleStruct->noResultString[battlerDef] != DO_ACCURACY_CHECK))
|| gBattleStruct->noResultString[battlerDef] == WILL_FAIL)
continue;
numTargets++;
@ -1743,7 +1743,7 @@ static void Cmd_critcalc(void)
continue;
if (IsBattlerInvalidForSpreadMove(gBattlerAttacker, battlerDef, moveTarget)
|| gBattleStruct->noResultString[battlerDef]
|| gBattleStruct->noResultString[battlerDef] != CAN_DAMAGE
|| gBattleStruct->moveResultFlags[battlerDef] & MOVE_RESULT_NO_EFFECT)
continue;
@ -1819,7 +1819,7 @@ static void Cmd_damagecalc(void)
for (battlerDef = 0; battlerDef < gBattlersCount; battlerDef++)
{
if (IsBattlerInvalidForSpreadMove(gBattlerAttacker, battlerDef, moveTarget)
|| gBattleStruct->noResultString[battlerDef]
|| gBattleStruct->noResultString[battlerDef] != CAN_DAMAGE
|| gBattleStruct->moveResultFlags[battlerDef] & MOVE_RESULT_NO_EFFECT)
continue;
@ -1882,7 +1882,7 @@ static void Cmd_adjustdamage(void)
continue;
if (IsBattlerInvalidForSpreadMove(gBattlerAttacker, battlerDef, moveTarget)
|| gBattleStruct->noResultString[battlerDef])
|| gBattleStruct->noResultString[battlerDef] != CAN_DAMAGE)
continue;
if (DoesSubstituteBlockMove(gBattlerAttacker, battlerDef, gCurrentMove))
@ -2029,8 +2029,8 @@ static u32 UpdateEffectivenessResultFlagsForDoubleSpreadMoves(u32 resultFlags)
{
for (u32 battlerDef = 0; battlerDef < gBattlersCount; battlerDef++)
{
if ((gBattleStruct->moveResultFlags[battlerDef] & (MOVE_RESULT_MISSED | MOVE_RESULT_NO_EFFECT)
|| gBattleStruct->noResultString[battlerDef]))
if (gBattleStruct->moveResultFlags[battlerDef] & (MOVE_RESULT_MISSED | MOVE_RESULT_NO_EFFECT)
|| gBattleStruct->noResultString[battlerDef] != CAN_DAMAGE)
continue;
switch (sound)
@ -2115,7 +2115,7 @@ static bool32 ProcessPreAttackAnimationFuncs(void)
{
if (IsBattlerInvalidForSpreadMove(gBattlerAttacker, battlerDef, moveTarget)
|| (battlerDef == BATTLE_PARTNER(gBattlerAttacker) && !(moveTarget & MOVE_TARGET_FOES_AND_ALLY))
|| (gBattleStruct->noResultString[battlerDef] && gBattleStruct->noResultString[battlerDef] != DO_ACCURACY_CHECK))
|| gBattleStruct->noResultString[battlerDef] == WILL_FAIL)
continue;
if (TryStrongWindsWeakenAttack(battlerDef, moveType))
@ -2127,7 +2127,7 @@ static bool32 ProcessPreAttackAnimationFuncs(void)
{
if (IsBattlerInvalidForSpreadMove(gBattlerAttacker, battlerDef, moveTarget)
|| (battlerDef == BATTLE_PARTNER(gBattlerAttacker) && !(moveTarget & MOVE_TARGET_FOES_AND_ALLY))
|| (gBattleStruct->noResultString[battlerDef] && gBattleStruct->noResultString[battlerDef] != DO_ACCURACY_CHECK))
|| gBattleStruct->noResultString[battlerDef] == WILL_FAIL)
continue;
if (TryTeraShellDistortTypeMatchups(battlerDef))
@ -2255,7 +2255,7 @@ static void DoublesHPBarReduction(void)
{
if (gBattleStruct->moveResultFlags[battlerDef] & MOVE_RESULT_NO_EFFECT
|| gBattleStruct->moveDamage[battlerDef] == 0
|| gBattleStruct->noResultString[battlerDef]
|| gBattleStruct->noResultString[battlerDef] != CAN_DAMAGE
|| DoesSubstituteBlockMove(gBattlerAttacker, battlerDef, gCurrentMove)
|| DoesDisguiseBlockMove(battlerDef, gCurrentMove))
continue;
@ -2534,7 +2534,7 @@ static inline bool32 ShouldPrintTwoFoesMessage(u32 moveResult)
{
return gBattlerTarget == BATTLE_OPPOSITE(gBattlerAttacker)
&& gBattleStruct->moveResultFlags[BATTLE_PARTNER(gBattlerTarget)] & moveResult
&& !gBattleStruct->noResultString[BATTLE_PARTNER(gBattlerTarget)];
&& gBattleStruct->noResultString[BATTLE_PARTNER(gBattlerTarget)] == CAN_DAMAGE;
}
static inline bool32 ShouldRelyOnTwoFoesMessage(u32 moveResult)
@ -2542,7 +2542,7 @@ static inline bool32 ShouldRelyOnTwoFoesMessage(u32 moveResult)
return gBattlerTarget == BATTLE_PARTNER(BATTLE_OPPOSITE(gBattlerAttacker))
&& gBattleStruct->moveResultFlags[BATTLE_OPPOSITE(gBattlerAttacker)] & moveResult
&& !(gBattleStruct->moveResultFlags[BATTLE_OPPOSITE(gBattlerAttacker)] & MOVE_RESULT_MISSED && gBattleStruct->missStringId[BATTLE_OPPOSITE(gBattlerAttacker)] > B_MSG_AVOIDED_ATK)
&& !gBattleStruct->noResultString[BATTLE_OPPOSITE(gBattlerAttacker)];
&& gBattleStruct->noResultString[BATTLE_OPPOSITE(gBattlerAttacker)] == CAN_DAMAGE;
}
static void Cmd_resultmessage(void)
@ -8247,7 +8247,7 @@ static void Cmd_hitanimation(void)
for (battlerDef = 0; battlerDef < gBattlersCount; battlerDef++)
{
if (gBattleStruct->moveResultFlags[battlerDef] & MOVE_RESULT_NO_EFFECT
|| gBattleStruct->noResultString[battlerDef])
|| gBattleStruct->noResultString[battlerDef] != CAN_DAMAGE)
continue;
if (!(gHitMarker & HITMARKER_IGNORE_SUBSTITUTE)

View File

@ -205,7 +205,7 @@ static const struct BattleWeatherInfo sBattleWeatherInfo[BATTLE_WEATHER_COUNT] =
// Helper function for actual dmg calcs during battle. For simulated AI dmg, CalcTypeEffectivenessMultiplier should be used directly
// This should stay a static function. Ideally everything else is handled through CalcTypeEffectivenessMultiplier just like AI
static uq4_12_t CalcTypeEffectivenessMultiplierHelper(u32 move, u32 moveType, u32 battlerAtk, u32 battlerDef, u32 defAbility, bool32 recordAbilities)
static uq4_12_t CalcTypeEffectivenessMultiplierHelper(u32 move, u32 moveType, u32 battlerAtk, u32 battlerDef, u32 abilityAtk, u32 abilityDef, bool32 recordAbilities)
{
struct DamageContext ctx = {0};
ctx.battlerAtk = battlerAtk;
@ -213,8 +213,8 @@ static uq4_12_t CalcTypeEffectivenessMultiplierHelper(u32 move, u32 moveType, u3
ctx.move = move;
ctx.moveType = moveType;
ctx.updateFlags = recordAbilities;
ctx.abilityAtk = GetBattlerAbility(battlerAtk);
ctx.abilityDef = defAbility;
ctx.abilityAtk = abilityAtk;
ctx.abilityDef = abilityDef;
ctx.holdEffectAtk = GetBattlerHoldEffect(battlerAtk, TRUE);
ctx.holdEffectDef = GetBattlerHoldEffect(battlerDef, TRUE);
@ -2541,22 +2541,23 @@ static enum MoveCanceller CancellerMultiTargetMoves(void)
|| IsBattlerProtected(gBattlerAttacker, battlerDef, gCurrentMove)) // Missing Invulnerable check
{
gBattleStruct->moveResultFlags[battlerDef] = MOVE_RESULT_NO_EFFECT;
gBattleStruct->noResultString[battlerDef] = TRUE;
gBattleStruct->noResultString[battlerDef] = WILL_FAIL;
}
else if (CanAbilityBlockMove(gBattlerAttacker, battlerDef, abilityAtk, abilityDef, gCurrentMove, CHECK_TRIGGER)
|| (IsBattlerTerrainAffected(gBattlerAttacker, STATUS_FIELD_PSYCHIC_TERRAIN) && GetBattleMovePriority(gBattlerAttacker, abilityAtk, gCurrentMove) > 0))
{
gBattleStruct->moveResultFlags[battlerDef] = 0;
gBattleStruct->noResultString[battlerDef] = TRUE;
gBattleStruct->noResultString[battlerDef] = WILL_FAIL;
}
else if (CanAbilityAbsorbMove(gBattlerAttacker, battlerDef, abilityDef, gCurrentMove, GetBattleMoveType(gCurrentMove), CHECK_TRIGGER))
{
gBattleStruct->moveResultFlags[battlerDef] = 0;
gBattleStruct->noResultString[battlerDef] = DO_ACCURACY_CHECK;
gBattleStruct->noResultString[battlerDef] = CHECK_ACCURACY;
}
else
{
CalcTypeEffectivenessMultiplierHelper(gCurrentMove, GetBattleMoveType(gCurrentMove), gBattlerAttacker, battlerDef, GetBattlerAbility(battlerDef), TRUE);
CalcTypeEffectivenessMultiplierHelper(gCurrentMove, GetBattleMoveType(gCurrentMove), gBattlerAttacker, battlerDef, abilityAtk, abilityDef, TRUE); // Sets moveResultFlags
gBattleStruct->noResultString[battlerDef] = CAN_DAMAGE;
}
}
if (moveTarget == MOVE_TARGET_BOTH)
@ -5669,7 +5670,7 @@ bool32 CanSetNonVolatileStatus(u32 battlerAtk, u32 battlerDef, u32 abilityAtk, u
battleScript = BattleScript_NotAffected;
}
else if (option == RUN_SCRIPT // Check only important during battle execution for moves
&& CalcTypeEffectivenessMultiplierHelper(gCurrentMove, GetBattleMoveType(gCurrentMove), battlerAtk, battlerDef, abilityDef, TRUE)
&& CalcTypeEffectivenessMultiplierHelper(gCurrentMove, GetBattleMoveType(gCurrentMove), battlerAtk, battlerDef, abilityAtk, abilityDef, TRUE)
&& gBattleStruct->moveResultFlags[battlerDef] & MOVE_RESULT_NO_EFFECT)
{
battleScript = BattleScript_ButItFailed;
@ -11223,7 +11224,7 @@ static inline bool32 DoesBattlerHaveAbilityImmunity(u32 battlerAtk, u32 battlerD
bool32 TargetFullyImmuneToCurrMove(u32 battlerAtk, u32 battlerDef)
{
u32 moveType = GetBattleMoveType(gCurrentMove);
return ((CalcTypeEffectivenessMultiplierHelper(gCurrentMove, moveType, battlerAtk, battlerDef, GetBattlerAbility(battlerDef), FALSE) == UQ_4_12(0.0))
return ((CalcTypeEffectivenessMultiplierHelper(gCurrentMove, moveType, battlerAtk, battlerDef, GetBattlerAbility(battlerAtk), GetBattlerAbility(battlerDef), FALSE) == UQ_4_12(0.0))
|| IsBattlerProtected(battlerAtk, battlerDef, gCurrentMove)
|| IsSemiInvulnerable(battlerDef, gCurrentMove)
|| DoesBattlerHaveAbilityImmunity(battlerAtk, battlerDef, moveType));
@ -11284,7 +11285,7 @@ void ClearDamageCalcResults(void)
{
gBattleStruct->moveDamage[battler] = 0;
gBattleStruct->critChance[battler] = 0;
gBattleStruct->moveResultFlags[battler] = 0;
gBattleStruct->moveResultFlags[battler] = CAN_DAMAGE;
gBattleStruct->noResultString[battler] = 0;
gBattleStruct->missStringId[battler] = 0;
gSpecialStatuses[battler].criticalHit = FALSE;