Refactor fixed damage moves (#6449)

Co-authored-by: Bassoonian <iasperbassoonian@gmail.com>
This commit is contained in:
Alex 2025-04-10 15:01:02 +02:00 committed by GitHub
parent 17d851e1f9
commit 4aca2fdcd3
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
9 changed files with 79 additions and 103 deletions

View File

@ -829,7 +829,7 @@
.4byte \failInstr
.endm
.macro damagetohalftargethp
.macro unused_0x94
.byte 0x94
.endm
@ -877,11 +877,11 @@
.byte 0x9e
.endm
.macro dmgtolevel
.macro unused_0x9f
.byte 0x9f
.endm
.macro psywavedamageeffect
.macro unused_0xA0
.byte 0xa0
.endm
@ -2030,10 +2030,6 @@
.4byte \jumpInstr
.endm
.macro setargtobattledamage
various BS_ATTACKER, VARIOUS_SET_ARG_TO_BATTLE_DAMAGE
.endm
.macro tryautotomize battler:req, failInstr:req
various \battler, VARIOUS_TRY_AUTOTOMIZE
.4byte \failInstr

View File

@ -3418,16 +3418,6 @@ BattleScript_KOFail::
waitmessage B_WAIT_TIME_LONG
goto BattleScript_MoveEnd
BattleScript_EffectSuperFang::
attackcanceler
accuracycheck BattleScript_PrintMoveMissed, ACC_CURR_MOVE
attackstring
ppreduce
typecalc
clearmoveresultflags MOVE_RESULT_SUPER_EFFECTIVE | MOVE_RESULT_NOT_VERY_EFFECTIVE
damagetohalftargethp
goto BattleScript_HitFromAtkAnimation
BattleScript_RecoilIfMiss::
printstring STRINGID_PKMNCRASHED
waitmessage B_WAIT_TIME_LONG
@ -3873,28 +3863,6 @@ BattleScript_EffectDisable::
waitmessage B_WAIT_TIME_LONG
goto BattleScript_MoveEnd
BattleScript_EffectLevelDamage::
attackcanceler
accuracycheck BattleScript_PrintMoveMissed, ACC_CURR_MOVE
attackstring
ppreduce
typecalc
clearmoveresultflags MOVE_RESULT_SUPER_EFFECTIVE | MOVE_RESULT_NOT_VERY_EFFECTIVE
dmgtolevel
adjustdamage
goto BattleScript_HitFromAtkAnimation
BattleScript_EffectPsywave::
attackcanceler
accuracycheck BattleScript_PrintMoveMissed, ACC_CURR_MOVE
attackstring
ppreduce
typecalc
clearmoveresultflags MOVE_RESULT_SUPER_EFFECTIVE | MOVE_RESULT_NOT_VERY_EFFECTIVE
psywavedamageeffect
adjustdamage
goto BattleScript_HitFromAtkAnimation
BattleScript_EffectCounter::
attackcanceler
counterdamagecalculator BattleScript_FailedFromAtkString
@ -4380,17 +4348,6 @@ BattleScript_EffectBatonPass::
switchineffects BS_ATTACKER
goto BattleScript_MoveEnd
BattleScript_EffectFixedDamageArg::
attackcanceler
accuracycheck BattleScript_PrintMoveMissed, ACC_CURR_MOVE
attackstring
ppreduce
typecalc
clearmoveresultflags MOVE_RESULT_SUPER_EFFECTIVE | MOVE_RESULT_NOT_VERY_EFFECTIVE
setargtobattledamage
adjustdamage
goto BattleScript_HitFromAtkAnimation
BattleScript_EffectMorningSun::
BattleScript_EffectSynthesis::
BattleScript_EffectMoonlight::

View File

@ -592,8 +592,6 @@ extern const u8 BattleScript_EffectToxic[];
extern const u8 BattleScript_EffectLightScreen[];
extern const u8 BattleScript_EffectRest[];
extern const u8 BattleScript_EffectOHKO[];
extern const u8 BattleScript_EffectSuperFang[];
extern const u8 BattleScript_EffectFixedDamageArg[];
extern const u8 BattleScript_EffectHealBlock[];
extern const u8 BattleScript_RecoilIfMiss[];
extern const u8 BattleScript_EffectMist[];
@ -628,8 +626,6 @@ extern const u8 BattleScript_EffectHoldHands[];
extern const u8 BattleScript_EffectCelebrate[];
extern const u8 BattleScript_EffectHappyHour[];
extern const u8 BattleScript_EffectDisable[];
extern const u8 BattleScript_EffectLevelDamage[];
extern const u8 BattleScript_EffectPsywave[];
extern const u8 BattleScript_EffectCounter[];
extern const u8 BattleScript_EffectEncore[];
extern const u8 BattleScript_EffectPainSplit[];

View File

@ -134,7 +134,6 @@ enum CmdVarious
VARIOUS_TRY_ELECTRIFY,
VARIOUS_TRY_SOAK,
VARIOUS_TRY_LAST_RESORT,
VARIOUS_SET_ARG_TO_BATTLE_DAMAGE,
VARIOUS_TRY_AUTOTOMIZE,
VARIOUS_ABILITY_POPUP,
VARIOUS_JUMP_IF_TARGET_ALLY,

View File

@ -174,6 +174,7 @@ void RecordKnownMove(u32 battlerId, u32 move)
s32 i;
for (i = 0; i < MAX_MON_MOVES; i++)
{
if (BATTLE_HISTORY->usedMoves[battlerId][i] == move)
break;
if (BATTLE_HISTORY->usedMoves[battlerId][i] == MOVE_NONE)
@ -577,15 +578,6 @@ static inline void CalcDynamicMoveDamage(struct DamageCalculationData *damageCal
switch (effect)
{
case EFFECT_LEVEL_DAMAGE:
median = maximum = minimum = gBattleMons[damageCalcData->battlerAtk].level;
break;
case EFFECT_PSYWAVE:
median = maximum = minimum = gBattleMons[damageCalcData->battlerAtk].level;
break;
case EFFECT_FIXED_DAMAGE_ARG:
median = maximum = minimum = GetMoveFixedDamage(move);
break;
case EFFECT_MULTI_HIT:
if (move == MOVE_WATER_SHURIKEN && gBattleMons[damageCalcData->battlerAtk].species == SPECIES_GRENINJA_ASH)
{
@ -617,9 +609,6 @@ static inline void CalcDynamicMoveDamage(struct DamageCalculationData *damageCal
// If target has less HP than user, Endeavor does no damage
median = maximum = minimum = max(0, gBattleMons[damageCalcData->battlerDef].hp - gBattleMons[damageCalcData->battlerAtk].hp);
break;
case EFFECT_SUPER_FANG:
median = maximum = minimum = max(1, gBattleMons[damageCalcData->battlerDef].hp / 2);
break;
case EFFECT_FINAL_GAMBIT:
median = maximum = minimum = gBattleMons[damageCalcData->battlerAtk].hp;
break;

View File

@ -494,7 +494,7 @@ static void Cmd_tryconversiontypechange(void);
static void Cmd_givepaydaymoney(void);
static void Cmd_setlightscreen(void);
static void Cmd_tryKO(void);
static void Cmd_damagetohalftargethp(void);
static void Cmd_unused_0x94(void);
static void Cmd_copybidedmg(void);
static void Cmd_unused_96(void);
static void Cmd_tryinfatuating(void);
@ -505,8 +505,8 @@ static void Cmd_transformdataexecution(void);
static void Cmd_setsubstitute(void);
static void Cmd_mimicattackcopy(void);
static void Cmd_metronome(void);
static void Cmd_dmgtolevel(void);
static void Cmd_psywavedamageeffect(void);
static void Cmd_unused_0x9f(void);
static void Cmd_unused_0xA0(void);
static void Cmd_counterdamagecalculator(void);
static void Cmd_mirrorcoatdamagecalculator(void);
static void Cmd_disablelastusedattack(void);
@ -753,7 +753,7 @@ void (* const gBattleScriptingCommandsTable[])(void) =
Cmd_givepaydaymoney, //0x91
Cmd_setlightscreen, //0x92
Cmd_tryKO, //0x93
Cmd_damagetohalftargethp, //0x94
Cmd_unused_0x94, //0x94
Cmd_copybidedmg, //0x95
Cmd_unused_96, //0x96
Cmd_tryinfatuating, //0x97
@ -764,8 +764,8 @@ void (* const gBattleScriptingCommandsTable[])(void) =
Cmd_setsubstitute, //0x9C
Cmd_mimicattackcopy, //0x9D
Cmd_metronome, //0x9E
Cmd_dmgtolevel, //0x9F
Cmd_psywavedamageeffect, //0xA0
Cmd_unused_0x9f, //0x9F
Cmd_unused_0xA0, //0xA0
Cmd_counterdamagecalculator, //0xA1
Cmd_mirrorcoatdamagecalculator, //0xA2
Cmd_disablelastusedattack, //0xA3
@ -11021,12 +11021,6 @@ static void Cmd_various(void)
gBattlescriptCurrInstr = cmd->failInstr;
return;
}
case VARIOUS_SET_ARG_TO_BATTLE_DAMAGE:
{
VARIOUS_ARGS();
gBattleStruct->moveDamage[gBattlerTarget] = GetMoveFixedDamage(gCurrentMove);
break;
}
case VARIOUS_TRY_AUTOTOMIZE:
{
VARIOUS_ARGS(const u8 *failInstr);
@ -13195,16 +13189,8 @@ static void Cmd_tryKO(void)
#undef FOCUS_BANDED
#undef AFFECTION_ENDURED
// Super Fang
static void Cmd_damagetohalftargethp(void)
static void Cmd_unused_0x94(void)
{
CMD_ARGS();
gBattleStruct->moveDamage[gBattlerTarget] = GetNonDynamaxHP(gBattlerTarget) / 2;
if (gBattleStruct->moveDamage[gBattlerTarget] == 0)
gBattleStruct->moveDamage[gBattlerTarget] = 1;
gBattlescriptCurrInstr = cmd->nextInstr;
}
static void Cmd_copybidedmg(void)
@ -13515,21 +13501,12 @@ static void Cmd_metronome(void)
ResetValuesForCalledMove();
}
static void Cmd_dmgtolevel(void)
static void Cmd_unused_0x9f(void)
{
CMD_ARGS();
gBattleStruct->moveDamage[gBattlerTarget] = gBattleMons[gBattlerAttacker].level;
gBattlescriptCurrInstr = cmd->nextInstr;
}
static void Cmd_psywavedamageeffect(void)
static void Cmd_unused_0xA0(void)
{
CMD_ARGS();
s32 randDamage = B_PSYWAVE_DMG >= GEN_6 ? (Random() % 101) : ((Random() % 11) * 10);
gBattleStruct->moveDamage[gBattlerTarget] = gBattleMons[gBattlerAttacker].level * (randDamage + 50) / 100;
gBattlescriptCurrInstr = cmd->nextInstr;
}
static void Cmd_counterdamagecalculator(void)

View File

@ -10499,6 +10499,37 @@ s32 ApplyModifiersAfterDmgRoll(s32 dmg, struct DamageCalculationData *damageCalc
return dmg;
}
static inline s32 DoFixedDamageMoveCalc(struct DamageCalculationData *damageCalcData)
{
s32 dmg = 0;
switch (GetMoveEffect(damageCalcData->move))
{
case EFFECT_LEVEL_DAMAGE:
dmg = gBattleMons[damageCalcData->battlerAtk].level;
break;
case EFFECT_PSYWAVE:
s32 randDamage = B_PSYWAVE_DMG >= GEN_6 ? (Random() % 101) : ((Random() % 11) * 10);
dmg = gBattleMons[damageCalcData->battlerAtk].level * (randDamage + 50) / 100;
break;
case EFFECT_FIXED_DAMAGE_ARG:
dmg = GetMoveFixedDamage(damageCalcData->move);
break;
case EFFECT_SUPER_FANG:
dmg = GetNonDynamaxHP(gBattlerTarget) / 2;
break;
default:
return INT32_MAX;
}
gBattleStruct->moveResultFlags[damageCalcData->battlerDef] &= ~(MOVE_RESULT_NOT_VERY_EFFECTIVE | MOVE_RESULT_SUPER_EFFECTIVE);
if (dmg == 0)
dmg = 1;
return dmg;
}
static inline s32 DoMoveDamageCalc(struct DamageCalculationData *damageCalcData, u32 fixedBasePower, uq4_12_t typeEffectivenessModifier, u32 weather)
{
u32 holdEffectAtk, holdEffectDef, abilityAtk, abilityDef;
@ -10506,6 +10537,10 @@ static inline s32 DoMoveDamageCalc(struct DamageCalculationData *damageCalcData,
if (typeEffectivenessModifier == UQ_4_12(0.0))
return 0;
s32 dmg = DoFixedDamageMoveCalc(damageCalcData);
if (dmg != INT32_MAX)
return dmg;
holdEffectAtk = GetBattlerHoldEffect(damageCalcData->battlerAtk, TRUE);
holdEffectDef = GetBattlerHoldEffect(damageCalcData->battlerDef, TRUE);
abilityAtk = GetBattlerAbility(damageCalcData->battlerAtk);
@ -10614,6 +10649,10 @@ s32 CalculateMoveDamage(struct DamageCalculationData *damageCalcData, u32 fixedB
s32 CalculateMoveDamageVars(struct DamageCalculationData *damageCalcData, u32 fixedBasePower, uq4_12_t typeEffectivenessModifier,
u32 weather, u32 holdEffectAtk, u32 holdEffectDef, u32 abilityAtk, u32 abilityDef)
{
s32 dmg = DoFixedDamageMoveCalc(damageCalcData);
if (dmg != INT32_MAX)
return dmg;
return DoMoveDamageCalcVars(damageCalcData, fixedBasePower, typeEffectivenessModifier, weather,
holdEffectAtk, holdEffectDef, abilityAtk, abilityDef);
}

View File

@ -218,14 +218,14 @@ const struct BattleMoveEffect gBattleMoveEffects[NUM_BATTLE_MOVE_EFFECTS] =
[EFFECT_SUPER_FANG] =
{
.battleScript = BattleScript_EffectSuperFang,
.battleScript = BattleScript_EffectHit,
.battleTvScore = 5,
.encourageEncore = TRUE,
},
[EFFECT_FIXED_DAMAGE_ARG] =
{
.battleScript = BattleScript_EffectFixedDamageArg,
.battleScript = BattleScript_EffectHit,
.battleTvScore = 1,
},
@ -454,13 +454,13 @@ const struct BattleMoveEffect gBattleMoveEffects[NUM_BATTLE_MOVE_EFFECTS] =
[EFFECT_LEVEL_DAMAGE] =
{
.battleScript = BattleScript_EffectLevelDamage,
.battleScript = BattleScript_EffectHit,
.battleTvScore = 2,
},
[EFFECT_PSYWAVE] =
{
.battleScript = BattleScript_EffectPsywave,
.battleScript = BattleScript_EffectHit,
.battleTvScore = 1,
},

View File

@ -0,0 +1,23 @@
#include "global.h"
#include "test/battle.h"
ASSUMPTIONS
{
ASSUME(GetMoveEffect(MOVE_SEISMIC_TOSS) == EFFECT_LEVEL_DAMAGE);
}
SINGLE_BATTLE_TEST("Level Damage: Seismic Toss deals damage based on user's level")
{
s16 dmg;
GIVEN {
PLAYER(SPECIES_WOBBUFFET) { Level(50); }
OPPONENT(SPECIES_WOBBUFFET);
} WHEN {
TURN { MOVE(player, MOVE_SEISMIC_TOSS); }
} SCENE {
ANIMATION(ANIM_TYPE_MOVE, MOVE_SEISMIC_TOSS, player);
HP_BAR(opponent, captureDamage: &dmg);
} THEN {
EXPECT(dmg == 50);
}
}