Minor Recoil Effect refactor (#6409)

This commit is contained in:
Alex 2025-03-14 12:43:45 +01:00 committed by GitHub
parent b08a5fb15a
commit 7df3298534
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
7 changed files with 56 additions and 50 deletions

View File

@ -352,6 +352,7 @@ enum {
EFFECT_ORDER_UP,
EFFECT_RAPID_SPIN,
EFFECT_SPECTRAL_THIEF,
EFFECT_RECOIL,
NUM_BATTLE_MOVE_EFFECTS,
};

View File

@ -56,7 +56,6 @@ struct MoveInfo
} zMove;
// end of word
s32 priority:4;
u32 recoil:7;
u32 strikeCount:4; // Max 15 hits. Defaults to 1 if not set. May apply its effect on each hit.
u32 criticalHitStage:2;
bool32 alwaysCriticalHit:1;
@ -74,7 +73,6 @@ struct MoveInfo
bool32 ballisticMove:1;
bool32 powderMove:1;
bool32 danceMove:1;
// end of word
bool32 windMove:1;
bool32 slicingMove:1;
bool32 healingMove:1;
@ -82,6 +80,7 @@ struct MoveInfo
bool32 ignoresTargetAbility:1;
bool32 ignoresTargetDefenseEvasionStages:1;
bool32 damagesUnderground:1;
// end of word
bool32 damagesUnderwater:1;
bool32 damagesAirborne:1;
bool32 damagesAirborneDoubleDamage:1;
@ -106,7 +105,7 @@ struct MoveInfo
bool32 sketchBanned:1;
//Other
bool32 validApprenticeMove:1;
u32 padding:3;
u32 padding:10;
// end of word
union {
@ -119,11 +118,12 @@ struct MoveInfo
u16 property; // can be used to remove the hardcoded values
} protect;
u32 status;
u16 moveProperty;
u16 holdEffect;
u16 type;
u16 fixedDamage;
u16 absorbPercentage;
u32 moveProperty;
u32 holdEffect;
u32 type;
u32 fixedDamage;
u32 absorbPercentage;
u32 recoilPercentage;
} argument;
// primary/secondary effects
@ -212,11 +212,6 @@ static inline s32 GetMovePriority(u32 moveId)
return gMovesInfo[SanitizeMoveId(moveId)].priority;
}
static inline u32 GetMoveRecoil(u32 moveId)
{
return gMovesInfo[SanitizeMoveId(moveId)].recoil;
}
static inline u32 GetMoveStrikeCount(u32 moveId)
{
return gMovesInfo[SanitizeMoveId(moveId)].strikeCount;
@ -490,6 +485,11 @@ static inline u32 GetMoveAbsorbPercentage(u32 moveId)
return gMovesInfo[moveId].argument.absorbPercentage;
}
static inline u32 GetMoveRecoil(u32 moveId)
{
return gMovesInfo[SanitizeMoveId(moveId)].argument.recoilPercentage;
}
static inline const struct AdditionalEffect *GetMoveAdditionalEffectById(u32 moveId, u32 effect)
{
return &gMovesInfo[SanitizeMoveId(moveId)].additionalEffects[effect];

View File

@ -947,10 +947,6 @@ static bool32 AI_IsMoveEffectInMinus(u32 battlerAtk, u32 battlerDef, u32 move, s
u32 abilityDef = AI_DATA->abilities[battlerDef];
u8 i;
// recoil
if (GetMoveRecoil(move) > 0 && AI_IsDamagedByRecoil(battlerAtk))
return TRUE;
switch (GetMoveEffect(move))
{
case EFFECT_MAX_HP_50_RECOIL:
@ -961,6 +957,9 @@ static bool32 AI_IsMoveEffectInMinus(u32 battlerAtk, u32 battlerDef, u32 move, s
case EFFECT_RECOIL_IF_MISS:
if (AI_IsDamagedByRecoil(battlerAtk))
return TRUE;
case EFFECT_RECOIL:
if (AI_IsDamagedByRecoil(battlerAtk))
return TRUE;
break;
default:
{
@ -3923,7 +3922,7 @@ static u32 IncreaseStatUpScoreInternal(u32 battlerAtk, u32 battlerDef, u32 statI
{
if (GetMonData(&playerParty[AI_DATA->mostSuitableMonId[battlerDef]], MON_DATA_SPEED, NULL) > gBattleMons[battlerAtk].speed)
return NO_INCREASE;
}
}
}
// Otherwise if predicting switch, stat increases are great momentum
tempScore += WEAK_EFFECT;

View File

@ -6361,7 +6361,7 @@ static void Cmd_moveend(void)
gBattleScripting.moveendState++;
break;
}
else if (moveRecoil > 0
else if (moveEffect == EFFECT_RECOIL
&& !(gBattleStruct->moveResultFlags[gBattlerTarget] & MOVE_RESULT_NO_EFFECT)
&& IsBattlerAlive(gBattlerAttacker)
&& IsBattlerTurnDamaged(gBattlerTarget)

View File

@ -2246,4 +2246,10 @@ const struct BattleMoveEffect gBattleMoveEffects[NUM_BATTLE_MOVE_EFFECTS] =
.battleScript = BattleScript_EffectSpectralThief,
.battleTvScore = 0, // TODO: Assign points
},
[EFFECT_RECOIL] =
{
.battleScript = BattleScript_EffectHit,
.battleTvScore = 0, // TODO: Assign points
},
};

View File

@ -1019,15 +1019,15 @@ const struct MoveInfo gMovesInfo[MOVES_COUNT_ALL] =
.description = COMPOUND_STRING(
"A reckless charge attack\n"
"that also hurts the user."),
.effect = EFFECT_HIT,
.effect = EFFECT_RECOIL,
.power = 90,
.type = TYPE_NORMAL,
.accuracy = 85,
.recoil = 25,
.pp = 20,
.target = MOVE_TARGET_SELECTED,
.priority = 0,
.category = DAMAGE_CATEGORY_PHYSICAL,
.argument = { .recoilPercentage = 25 },
.makesContact = TRUE,
.contestEffect = CONTEST_EFFECT_USER_MORE_EASILY_STARTLED,
.contestCategory = CONTEST_CATEGORY_TOUGH,
@ -1071,15 +1071,15 @@ const struct MoveInfo gMovesInfo[MOVES_COUNT_ALL] =
.description = COMPOUND_STRING(
"A life-risking tackle that\n"
"also hurts the user."),
.effect = EFFECT_HIT,
.effect = EFFECT_RECOIL,
.power = 120,
.type = TYPE_NORMAL,
.accuracy = 100,
.recoil = 33,
.pp = 15,
.target = MOVE_TARGET_SELECTED,
.priority = 0,
.category = DAMAGE_CATEGORY_PHYSICAL,
.argument = { .recoilPercentage = 33 },
.makesContact = TRUE,
.contestEffect = CONTEST_EFFECT_USER_MORE_EASILY_STARTLED,
.contestCategory = CONTEST_CATEGORY_TOUGH,
@ -1785,16 +1785,16 @@ const struct MoveInfo gMovesInfo[MOVES_COUNT_ALL] =
.description = COMPOUND_STRING(
"A reckless body slam that\n"
"also hurts the user."),
.effect = EFFECT_HIT,
.effect = EFFECT_RECOIL,
.power = 80,
.type = TYPE_FIGHTING,
.accuracy = 80,
.pp = B_UPDATED_MOVE_DATA >= GEN_6 ? 20 : 25,
.recoil = 25,
.target = MOVE_TARGET_SELECTED,
.priority = 0,
.category = DAMAGE_CATEGORY_PHYSICAL,
.makesContact = TRUE,
.argument = { .recoilPercentage = 25 },
.contestEffect = CONTEST_EFFECT_USER_MORE_EASILY_STARTLED,
.contestCategory = CONTEST_CATEGORY_COOL,
.contestComboStarterId = 0,
@ -4333,9 +4333,9 @@ const struct MoveInfo gMovesInfo[MOVES_COUNT_ALL] =
.self = TRUE,
}),
#else
.effect = EFFECT_HIT,
.effect = EFFECT_RECOIL,
.accuracy = 100,
.recoil = 25,
.argument = { .recoilPercentage = 25 },
#endif
.power = 50,
.type = TYPE_NORMAL,
@ -8989,11 +8989,11 @@ const struct MoveInfo gMovesInfo[MOVES_COUNT_ALL] =
.power = 120,
.type = TYPE_ELECTRIC,
.accuracy = 100,
.recoil = 33,
.pp = 15,
.target = MOVE_TARGET_SELECTED,
.priority = 0,
.category = DAMAGE_CATEGORY_PHYSICAL,
.argument = { .recoilPercentage = 33 },
.makesContact = TRUE,
#if B_UPDATED_MOVE_DATA >= GEN_4
.additionalEffects = ADDITIONAL_EFFECTS({
@ -10191,15 +10191,15 @@ const struct MoveInfo gMovesInfo[MOVES_COUNT_ALL] =
.description = COMPOUND_STRING(
"A charge that may burn the\n"
"foe. Also hurts the user."),
.effect = EFFECT_HIT,
.effect = EFFECT_RECOIL,
.power = 120,
.type = TYPE_FIRE,
.accuracy = 100,
.recoil = 33,
.pp = 15,
.target = MOVE_TARGET_SELECTED,
.priority = 0,
.category = DAMAGE_CATEGORY_PHYSICAL,
.argument = { .recoilPercentage = 33 },
.makesContact = TRUE,
.thawsUser = TRUE,
.additionalEffects = ADDITIONAL_EFFECTS({
@ -10655,15 +10655,15 @@ const struct MoveInfo gMovesInfo[MOVES_COUNT_ALL] =
.description = COMPOUND_STRING(
"A low altitude charge that\n"
"also hurts the user."),
.effect = EFFECT_HIT,
.effect = EFFECT_RECOIL,
.power = 120,
.type = TYPE_FLYING,
.accuracy = 100,
.recoil = 33,
.pp = 15,
.target = MOVE_TARGET_SELECTED,
.priority = 0,
.category = DAMAGE_CATEGORY_PHYSICAL,
.argument = { .recoilPercentage = 33 },
.makesContact = TRUE,
.contestEffect = CONTEST_EFFECT_USER_MORE_EASILY_STARTLED,
.contestCategory = CONTEST_CATEGORY_CUTE,
@ -11632,15 +11632,15 @@ const struct MoveInfo gMovesInfo[MOVES_COUNT_ALL] =
.description = COMPOUND_STRING(
"Slams the body into a foe.\n"
"The user gets hurt too."),
.effect = EFFECT_HIT,
.effect = EFFECT_RECOIL,
.power = 120,
.type = TYPE_GRASS,
.accuracy = 100,
.recoil = 33,
.pp = 15,
.target = MOVE_TARGET_SELECTED,
.priority = 0,
.category = DAMAGE_CATEGORY_PHYSICAL,
.argument = { .recoilPercentage = 33 },
.makesContact = TRUE,
.contestEffect = CONTEST_EFFECT_USER_MORE_EASILY_STARTLED,
.contestCategory = CONTEST_CATEGORY_TOUGH,
@ -11750,15 +11750,15 @@ const struct MoveInfo gMovesInfo[MOVES_COUNT_ALL] =
.description = COMPOUND_STRING(
"A life-risking headbutt that\n"
"seriously hurts the user."),
.effect = EFFECT_HIT,
.effect = EFFECT_RECOIL,
.power = 150,
.type = TYPE_ROCK,
.accuracy = 80,
.recoil = 50,
.pp = 5,
.target = MOVE_TARGET_SELECTED,
.priority = 0,
.category = DAMAGE_CATEGORY_PHYSICAL,
.argument = { .recoilPercentage = 50 },
.makesContact = TRUE,
.contestEffect = CONTEST_EFFECT_USER_MORE_EASILY_STARTLED,
.contestCategory = CONTEST_CATEGORY_TOUGH,
@ -13445,15 +13445,15 @@ const struct MoveInfo gMovesInfo[MOVES_COUNT_ALL] =
.description = COMPOUND_STRING(
"An electrical tackle that\n"
"also hurts the user."),
.effect = EFFECT_HIT,
.effect = EFFECT_RECOIL,
.power = 90,
.type = TYPE_ELECTRIC,
.accuracy = 100,
.recoil = 25,
.pp = 15,
.target = MOVE_TARGET_SELECTED,
.priority = 0,
.category = DAMAGE_CATEGORY_PHYSICAL,
.argument = { .recoilPercentage = 25 },
.makesContact = TRUE,
.contestEffect = CONTEST_EFFECT_USER_MORE_EASILY_STARTLED,
.contestCategory = CONTEST_CATEGORY_COOL,
@ -13802,15 +13802,15 @@ const struct MoveInfo gMovesInfo[MOVES_COUNT_ALL] =
.description = COMPOUND_STRING(
"A charge using guard hair.\n"
"It hurts the user a little."),
.effect = EFFECT_HIT,
.effect = EFFECT_RECOIL,
.power = 120,
.type = TYPE_NORMAL,
.accuracy = 100,
.recoil = 25,
.pp = 15,
.target = MOVE_TARGET_SELECTED,
.priority = 0,
.category = DAMAGE_CATEGORY_PHYSICAL,
.argument = { .recoilPercentage = 25 },
.makesContact = TRUE,
.contestEffect = CONTEST_EFFECT_USER_MORE_EASILY_STARTLED,
.contestCategory = CONTEST_CATEGORY_TOUGH,
@ -15655,15 +15655,15 @@ const struct MoveInfo gMovesInfo[MOVES_COUNT_ALL] =
.description = COMPOUND_STRING(
"Fires a great beam of light\n"
"that also hurts the user."),
.effect = EFFECT_HIT,
.effect = EFFECT_RECOIL,
.power = 140,
.type = TYPE_FAIRY,
.accuracy = 90,
.recoil = 50,
.pp = 5,
.target = MOVE_TARGET_SELECTED,
.priority = 0,
.category = DAMAGE_CATEGORY_SPECIAL,
.argument = { .recoilPercentage = 50 },
.metronomeBanned = TRUE,
.battleAnimScript = gBattleAnimMove_LightOfRuin,
},
@ -19202,15 +19202,15 @@ const struct MoveInfo gMovesInfo[MOVES_COUNT_ALL] =
.description = COMPOUND_STRING(
"A slam shrouded in water.\n"
"It also hurts the user."),
.effect = EFFECT_HIT,
.effect = EFFECT_RECOIL,
.power = B_UPDATED_MOVE_DATA >= GEN_9 ? 120 : 75,
.type = TYPE_WATER,
.accuracy = 100,
.recoil = 33,
.pp = 10,
.target = MOVE_TARGET_SELECTED,
.priority = 0,
.category = DAMAGE_CATEGORY_PHYSICAL,
.argument = { .recoilPercentage = 33 },
.makesContact = TRUE,
.skyBattleBanned = B_EXTRAPOLATED_MOVE_FLAGS,
.battleAnimScript = gBattleAnimMove_WaveCrash,

View File

@ -1,7 +1,7 @@
#include "global.h"
#include "test/battle.h"
SINGLE_BATTLE_TEST("Take Down deals 25% of recoil damage to the user")
SINGLE_BATTLE_TEST("Recoil: Take Down deals 25% of recoil damage to the user")
{
s16 directDamage;
s16 recoilDamage;
@ -21,7 +21,7 @@ SINGLE_BATTLE_TEST("Take Down deals 25% of recoil damage to the user")
}
}
SINGLE_BATTLE_TEST("Double Edge deals 33% of recoil damage to the user")
SINGLE_BATTLE_TEST("Recoil: Double Edge deals 33% of recoil damage to the user")
{
s16 directDamage;
s16 recoilDamage;
@ -41,7 +41,7 @@ SINGLE_BATTLE_TEST("Double Edge deals 33% of recoil damage to the user")
}
}
SINGLE_BATTLE_TEST("Head Smash deals 50% of recoil damage to the user")
SINGLE_BATTLE_TEST("Recoil: Head Smash deals 50% of recoil damage to the user")
{
s16 directDamage;
s16 recoilDamage;
@ -61,7 +61,7 @@ SINGLE_BATTLE_TEST("Head Smash deals 50% of recoil damage to the user")
}
}
SINGLE_BATTLE_TEST("Flare Blitz deals 33% of recoil damage to the user and can burn target")
SINGLE_BATTLE_TEST("Recoil: Flare Blitz deals 33% of recoil damage to the user and can burn target")
{
s16 directDamage;
s16 recoilDamage;
@ -84,10 +84,10 @@ SINGLE_BATTLE_TEST("Flare Blitz deals 33% of recoil damage to the user and can b
}
}
SINGLE_BATTLE_TEST("Flare Blitz is absorbed by Flash Fire and no recoil damage is dealt")
SINGLE_BATTLE_TEST("Recoil: Flare Blitz is absorbed by Flash Fire and no recoil damage is dealt")
{
GIVEN {
ASSUME(gMovesInfo[MOVE_FLARE_BLITZ].recoil > 0);
ASSUME(GetMoveRecoil(MOVE_FLARE_BLITZ) > 0);
PLAYER(SPECIES_WOBBUFFET);
OPPONENT(SPECIES_VULPIX) { Ability(ABILITY_FLASH_FIRE); };
} WHEN {