Removes Crit Chance preproc (#5520)

* Removes Crit Chance preproc

* renamed the function wrongly before pushing

* add assumes back where needed

* addresses review comments

* GetHoldEffectCritChanceIncrease

* remove redudant var call

* define for gen1 leek scale

* gen1 adjustments and fix test

* inline leek check

* clean up
This commit is contained in:
Alex 2024-10-16 19:01:38 +02:00 committed by GitHub
parent 9882e0aea6
commit 2e7d856ee3
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 75 additions and 35 deletions

View file

@ -1895,15 +1895,55 @@ static void Cmd_ppreduce(void)
} }
// The chance is 1/N for each stage. // The chance is 1/N for each stage.
#if B_CRIT_CHANCE >= GEN_7 static const u32 sGen7CriticalHitOdds[] = {24, 8, 2, 1, 1};
static const u8 sCriticalHitOdds[] = {24, 8, 2, 1, 1}; static const u32 sGen6CriticalHitOdds[] = {16, 8, 2, 1, 1};
#elif B_CRIT_CHANCE == GEN_6 static const u32 sCriticalHitOdds[] = {16, 8, 4, 3, 2}; // Gens 2,3,4,5
static const u8 sCriticalHitOdds[] = {16, 8, 2, 1, 1};
#else static inline u32 GetCriticalHitOdds(u32 critChance)
static const u8 sCriticalHitOdds[] = {16, 8, 4, 3, 2}; // Gens 2,3,4,5 {
#endif // B_CRIT_CHANCE if (B_CRIT_CHANCE >= GEN_7)
return sGen7CriticalHitOdds[critChance];
if (B_CRIT_CHANCE == GEN_6)
return sGen6CriticalHitOdds[critChance];
return sCriticalHitOdds[critChance];
}
static inline u32 IsBattlerLeekAffected(u32 battler, u32 holdEffect)
{
if (holdEffect == HOLD_EFFECT_LEEK)
{
return GET_BASE_SPECIES_ID(gBattleMons[battler].species) == SPECIES_FARFETCHD
|| gBattleMons[battler].species == SPECIES_SIRFETCHD;
}
return FALSE;
}
static inline u32 GetHoldEffectCritChanceIncrease(u32 battler, u32 holdEffect)
{
u32 critStageIncrease = 0;
switch (holdEffect)
{
case HOLD_EFFECT_SCOPE_LENS:
critStageIncrease = 1;
break;
case HOLD_EFFECT_LUCKY_PUNCH:
if (gBattleMons[battler].species == SPECIES_CHANSEY)
critStageIncrease = 2;
break;
case HOLD_EFFECT_LEEK:
if (IsBattlerLeekAffected(battler, holdEffect))
critStageIncrease = 2;
break;
default:
critStageIncrease = 0;
break;
}
return critStageIncrease;
}
#define BENEFITS_FROM_LEEK(battler, holdEffect)((holdEffect == HOLD_EFFECT_LEEK) && (GET_BASE_SPECIES_ID(gBattleMons[battler].species) == SPECIES_FARFETCHD || gBattleMons[battler].species == SPECIES_SIRFETCHD))
s32 CalcCritChanceStageArgs(u32 battlerAtk, u32 battlerDef, u32 move, bool32 recordAbility, u32 abilityAtk, u32 abilityDef, u32 holdEffectAtk) s32 CalcCritChanceStageArgs(u32 battlerAtk, u32 battlerDef, u32 move, bool32 recordAbility, u32 abilityAtk, u32 abilityDef, u32 holdEffectAtk)
{ {
s32 critChance = 0; s32 critChance = 0;
@ -1923,9 +1963,7 @@ s32 CalcCritChanceStageArgs(u32 battlerAtk, u32 battlerDef, u32 move, bool32 rec
critChance = 2 * ((gBattleMons[battlerAtk].status2 & STATUS2_FOCUS_ENERGY) != 0) critChance = 2 * ((gBattleMons[battlerAtk].status2 & STATUS2_FOCUS_ENERGY) != 0)
+ 1 * ((gBattleMons[battlerAtk].status2 & STATUS2_DRAGON_CHEER) != 0) + 1 * ((gBattleMons[battlerAtk].status2 & STATUS2_DRAGON_CHEER) != 0)
+ gMovesInfo[move].criticalHitStage + gMovesInfo[move].criticalHitStage
+ (holdEffectAtk == HOLD_EFFECT_SCOPE_LENS) + GetHoldEffectCritChanceIncrease(battlerAtk, holdEffectAtk)
+ 2 * (holdEffectAtk == HOLD_EFFECT_LUCKY_PUNCH && gBattleMons[battlerAtk].species == SPECIES_CHANSEY)
+ 2 * BENEFITS_FROM_LEEK(battlerAtk, holdEffectAtk)
+ 2 * (B_AFFECTION_MECHANICS == TRUE && GetBattlerAffectionHearts(battlerAtk) == AFFECTION_FIVE_HEARTS) + 2 * (B_AFFECTION_MECHANICS == TRUE && GetBattlerAffectionHearts(battlerAtk) == AFFECTION_FIVE_HEARTS)
+ (abilityAtk == ABILITY_SUPER_LUCK) + (abilityAtk == ABILITY_SUPER_LUCK)
+ gBattleStruct->bonusCritStages[gBattlerAttacker]; + gBattleStruct->bonusCritStages[gBattlerAttacker];
@ -1941,7 +1979,7 @@ s32 CalcCritChanceStageArgs(u32 battlerAtk, u32 battlerDef, u32 move, bool32 rec
{ {
if (critChance == -2) if (critChance == -2)
RecordAbilityBattle(battlerDef, abilityDef); RecordAbilityBattle(battlerDef, abilityDef);
else if (sCriticalHitOdds[critChance] == 1) else if (GetCriticalHitOdds(critChance) == 1)
RecordAbilityBattle(battlerDef, abilityDef); RecordAbilityBattle(battlerDef, abilityDef);
} }
critChance = -1; critChance = -1;
@ -1963,7 +2001,7 @@ s32 CalcCritChanceStage(u32 battlerAtk, u32 battlerDef, u32 move, bool32 recordA
// Threshold = Base Speed / 2 // Threshold = Base Speed / 2
// High crit move = 8 * (Base Speed / 2) // High crit move = 8 * (Base Speed / 2)
// Focus Energy = 4 * (Base Speed / 2) // Focus Energy = 4 * (Base Speed / 2)
s32 CalcCritChanceStageGen1(u8 battlerAtk, u8 battlerDef, u32 move, bool32 recordAbility) s32 CalcCritChanceStageGen1(u32 battlerAtk, u32 battlerDef, u32 move, bool32 recordAbility)
{ {
// Vanilla // Vanilla
u32 focusEnergyScaler = 4; u32 focusEnergyScaler = 4;
@ -1973,13 +2011,13 @@ s32 CalcCritChanceStageGen1(u8 battlerAtk, u8 battlerDef, u32 move, bool32 recor
u32 superLuckScaler = 4; u32 superLuckScaler = 4;
u32 scopeLensScaler = 4; u32 scopeLensScaler = 4;
u32 luckyPunchScaler = 8; u32 luckyPunchScaler = 8;
u32 farfetchedLeekScaler = 8; u32 farfetchdLeekScaler = 8;
s32 critChance = 0; s32 critChance = 0;
s32 moveCritStage = gMovesInfo[gCurrentMove].criticalHitStage; s32 moveCritStage = gMovesInfo[gCurrentMove].criticalHitStage;
s32 bonusCritStage = gBattleStruct->bonusCritStages[gBattlerAttacker]; // G-Max Chi Strike s32 bonusCritStage = gBattleStruct->bonusCritStages[battlerAtk]; // G-Max Chi Strike
u32 abilityAtk = GetBattlerAbility(gBattlerAttacker); u32 abilityAtk = GetBattlerAbility(battlerAtk);
u32 abilityDef = GetBattlerAbility(gBattlerTarget); u32 abilityDef = GetBattlerAbility(battlerDef);
u32 holdEffectAtk = GetBattlerHoldEffect(battlerAtk, TRUE); u32 holdEffectAtk = GetBattlerHoldEffect(battlerAtk, TRUE);
u16 baseSpeed = gSpeciesInfo[gBattleMons[battlerAtk].species].baseSpeed; u16 baseSpeed = gSpeciesInfo[gBattleMons[battlerAtk].species].baseSpeed;
@ -1992,17 +2030,15 @@ s32 CalcCritChanceStageGen1(u8 battlerAtk, u8 battlerDef, u32 move, bool32 recor
if (bonusCritStage > 0) if (bonusCritStage > 0)
critChance = critChance * bonusCritStage; critChance = critChance * bonusCritStage;
if ((gBattleMons[gBattlerAttacker].status2 & STATUS2_FOCUS_ENERGY_ANY) != 0) if ((gBattleMons[battlerAtk].status2 & STATUS2_FOCUS_ENERGY_ANY) != 0)
critChance = critChance * focusEnergyScaler; critChance = critChance * focusEnergyScaler;
if (holdEffectAtk == HOLD_EFFECT_SCOPE_LENS) if (holdEffectAtk == HOLD_EFFECT_SCOPE_LENS)
critChance = critChance * scopeLensScaler; critChance = critChance * scopeLensScaler;
else if (holdEffectAtk == HOLD_EFFECT_LUCKY_PUNCH && gBattleMons[battlerAtk].species == SPECIES_CHANSEY)
if (holdEffectAtk == HOLD_EFFECT_LUCKY_PUNCH && gBattleMons[gBattlerAttacker].species == SPECIES_CHANSEY)
critChance = critChance * luckyPunchScaler; critChance = critChance * luckyPunchScaler;
else if (IsBattlerLeekAffected(battlerAtk, holdEffectAtk))
if (BENEFITS_FROM_LEEK(battlerAtk, holdEffectAtk)) critChance = critChance * farfetchdLeekScaler;
critChance = critChance * farfetchedLeekScaler;
if (abilityAtk == ABILITY_SUPER_LUCK) if (abilityAtk == ABILITY_SUPER_LUCK)
critChance = critChance * superLuckScaler; critChance = critChance * superLuckScaler;
@ -2030,14 +2066,13 @@ s32 CalcCritChanceStageGen1(u8 battlerAtk, u8 battlerDef, u32 move, bool32 recor
return critChance; return critChance;
} }
#undef BENEFITS_FROM_LEEK
s32 GetCritHitOdds(s32 critChanceIndex) s32 GetCritHitOdds(s32 critChanceIndex)
{ {
if (critChanceIndex < 0) if (critChanceIndex < 0)
return -1; return -1;
else else
return sCriticalHitOdds[critChanceIndex]; return GetCriticalHitOdds(critChanceIndex);
} }
static void Cmd_critcalc(void) static void Cmd_critcalc(void)
@ -2071,7 +2106,7 @@ static void Cmd_critcalc(void)
gIsCriticalHit = 0; gIsCriticalHit = 0;
} }
else else
gIsCriticalHit = RandomChance(RNG_CRITICAL_HIT, 1, sCriticalHitOdds[critChance]); gIsCriticalHit = RandomChance(RNG_CRITICAL_HIT, 1, GetCriticalHitOdds(critChance));
} }
// Counter for EVO_CRITICAL_HITS. // Counter for EVO_CRITICAL_HITS.
@ -6998,7 +7033,7 @@ static void Cmd_openpartyscreen(void)
else if (IsDoubleBattle()) else if (IsDoubleBattle())
{ {
bool32 hasReplacement; bool32 hasReplacement;
hitmarkerFaintBits = gHitMarker >> 28; hitmarkerFaintBits = gHitMarker >> 28;
for (i = 0; i < gBattlersCount; i++) for (i = 0; i < gBattlersCount; i++)
{ {
@ -7006,7 +7041,7 @@ static void Cmd_openpartyscreen(void)
{ {
if (i > 1 && ((1u << BATTLE_PARTNER(i)) & hitmarkerFaintBits)) if (i > 1 && ((1u << BATTLE_PARTNER(i)) & hitmarkerFaintBits))
continue; continue;
battler = i; battler = i;
if (HasNoMonsToSwitch(battler, PARTY_SIZE, PARTY_SIZE)) if (HasNoMonsToSwitch(battler, PARTY_SIZE, PARTY_SIZE))
{ {
@ -7028,7 +7063,7 @@ static void Cmd_openpartyscreen(void)
} }
} }
} }
for (i = 0; i < NUM_BATTLE_SIDES; i++) for (i = 0; i < NUM_BATTLE_SIDES; i++)
{ {
if (!(gSpecialStatuses[i].faintedHasReplacement)) if (!(gSpecialStatuses[i].faintedHasReplacement))
@ -8856,7 +8891,7 @@ u32 GetHighestStatId(u32 battler)
} }
if (gBattleMons[battler].speed > highestStat) if (gBattleMons[battler].speed > highestStat)
highestId = STAT_SPEED; highestId = STAT_SPEED;
return highestId; return highestId;
} }

View file

@ -1,11 +1,6 @@
#include "global.h" #include "global.h"
#include "test/battle.h" #include "test/battle.h"
ASSUMPTIONS
{
ASSUME(B_CRIT_CHANCE >= GEN_7);
}
SINGLE_BATTLE_TEST("Crit Chance: Side effected by Lucky Chant blocks critical hits") SINGLE_BATTLE_TEST("Crit Chance: Side effected by Lucky Chant blocks critical hits")
{ {
GIVEN { GIVEN {
@ -135,6 +130,7 @@ SINGLE_BATTLE_TEST("Crit Chance: Focus Energy increases the user's critical hit
{ {
PASSES_RANDOMLY(1, 2, RNG_CRITICAL_HIT); PASSES_RANDOMLY(1, 2, RNG_CRITICAL_HIT);
GIVEN { GIVEN {
ASSUME(B_CRIT_CHANCE >= GEN_7);
ASSUME(gMovesInfo[MOVE_FOCUS_ENERGY].effect == EFFECT_FOCUS_ENERGY); ASSUME(gMovesInfo[MOVE_FOCUS_ENERGY].effect == EFFECT_FOCUS_ENERGY);
PLAYER(SPECIES_WOBBUFFET); PLAYER(SPECIES_WOBBUFFET);
OPPONENT(SPECIES_WOBBUFFET); OPPONENT(SPECIES_WOBBUFFET);
@ -152,6 +148,7 @@ SINGLE_BATTLE_TEST("Crit Chance: High crit rate increases the critical hit ratio
{ {
PASSES_RANDOMLY(1, 8, RNG_CRITICAL_HIT); PASSES_RANDOMLY(1, 8, RNG_CRITICAL_HIT);
GIVEN { GIVEN {
ASSUME(B_CRIT_CHANCE >= GEN_7);
ASSUME(gMovesInfo[MOVE_SLASH].criticalHitStage == 1); ASSUME(gMovesInfo[MOVE_SLASH].criticalHitStage == 1);
PLAYER(SPECIES_WOBBUFFET); PLAYER(SPECIES_WOBBUFFET);
OPPONENT(SPECIES_WOBBUFFET); OPPONENT(SPECIES_WOBBUFFET);
@ -167,6 +164,7 @@ SINGLE_BATTLE_TEST("Crit Chance: Super Luck increases the critical hit ratio by
{ {
PASSES_RANDOMLY(1, 8, RNG_CRITICAL_HIT); PASSES_RANDOMLY(1, 8, RNG_CRITICAL_HIT);
GIVEN { GIVEN {
ASSUME(B_CRIT_CHANCE >= GEN_7);
PLAYER(SPECIES_TOGEPI) { Ability(ABILITY_SUPER_LUCK); }; PLAYER(SPECIES_TOGEPI) { Ability(ABILITY_SUPER_LUCK); };
OPPONENT(SPECIES_WOBBUFFET); OPPONENT(SPECIES_WOBBUFFET);
} WHEN { } WHEN {
@ -181,6 +179,7 @@ SINGLE_BATTLE_TEST("Crit Chance: Scope Lens increases the critical hit ratio by
{ {
PASSES_RANDOMLY(1, 8, RNG_CRITICAL_HIT); PASSES_RANDOMLY(1, 8, RNG_CRITICAL_HIT);
GIVEN { GIVEN {
ASSUME(B_CRIT_CHANCE >= GEN_7);
ASSUME(gItemsInfo[ITEM_SCOPE_LENS].holdEffect == HOLD_EFFECT_SCOPE_LENS); ASSUME(gItemsInfo[ITEM_SCOPE_LENS].holdEffect == HOLD_EFFECT_SCOPE_LENS);
PLAYER(SPECIES_WOBBUFFET) { Item(ITEM_SCOPE_LENS); }; PLAYER(SPECIES_WOBBUFFET) { Item(ITEM_SCOPE_LENS); };
OPPONENT(SPECIES_WOBBUFFET); OPPONENT(SPECIES_WOBBUFFET);
@ -195,6 +194,7 @@ SINGLE_BATTLE_TEST("Crit Chance: Scope Lens increases the critical hit ratio by
SINGLE_BATTLE_TEST("Crit Chance: High crit rate, Super Luck and Scope Lens cause the move to result in a critical hit") SINGLE_BATTLE_TEST("Crit Chance: High crit rate, Super Luck and Scope Lens cause the move to result in a critical hit")
{ {
GIVEN { GIVEN {
ASSUME(B_CRIT_CHANCE >= GEN_7);
ASSUME(gMovesInfo[MOVE_SLASH].criticalHitStage == 1); ASSUME(gMovesInfo[MOVE_SLASH].criticalHitStage == 1);
ASSUME(gItemsInfo[ITEM_SCOPE_LENS].holdEffect == HOLD_EFFECT_SCOPE_LENS); ASSUME(gItemsInfo[ITEM_SCOPE_LENS].holdEffect == HOLD_EFFECT_SCOPE_LENS);
PLAYER(SPECIES_WOBBUFFET) { Ability(ABILITY_SUPER_LUCK); Item(ITEM_SCOPE_LENS); }; PLAYER(SPECIES_WOBBUFFET) { Ability(ABILITY_SUPER_LUCK); Item(ITEM_SCOPE_LENS); };
@ -220,6 +220,7 @@ SINGLE_BATTLE_TEST("Crit Chance: Signature items Leek and Lucky Punch increase t
PARAMETRIZE { species = SPECIES_CHANSEY; item = ITEM_LUCKY_PUNCH; } PARAMETRIZE { species = SPECIES_CHANSEY; item = ITEM_LUCKY_PUNCH; }
GIVEN { GIVEN {
ASSUME(B_CRIT_CHANCE >= GEN_7);
ASSUME(gItemsInfo[ITEM_LEEK].holdEffect == HOLD_EFFECT_LEEK); ASSUME(gItemsInfo[ITEM_LEEK].holdEffect == HOLD_EFFECT_LEEK);
ASSUME(gItemsInfo[ITEM_LUCKY_PUNCH].holdEffect == HOLD_EFFECT_LUCKY_PUNCH); ASSUME(gItemsInfo[ITEM_LUCKY_PUNCH].holdEffect == HOLD_EFFECT_LUCKY_PUNCH);
PLAYER(SPECIES_WOBBUFFET); PLAYER(SPECIES_WOBBUFFET);
@ -236,6 +237,7 @@ SINGLE_BATTLE_TEST("Crit Chance: Dire Hit increases a battler's critical hit cha
{ {
PASSES_RANDOMLY(1, 2, RNG_CRITICAL_HIT); PASSES_RANDOMLY(1, 2, RNG_CRITICAL_HIT);
GIVEN { GIVEN {
ASSUME(B_CRIT_CHANCE >= GEN_7);
ASSUME(gItemsInfo[ITEM_DIRE_HIT].battleUsage == EFFECT_ITEM_SET_FOCUS_ENERGY); ASSUME(gItemsInfo[ITEM_DIRE_HIT].battleUsage == EFFECT_ITEM_SET_FOCUS_ENERGY);
PLAYER(SPECIES_WOBBUFFET); PLAYER(SPECIES_WOBBUFFET);
OPPONENT(SPECIES_WOBBUFFET); OPPONENT(SPECIES_WOBBUFFET);
@ -254,6 +256,7 @@ SINGLE_BATTLE_TEST("Crit Chance: Focus Energy increases critical hit ratio by tw
{ {
PASSES_RANDOMLY(8, 8, RNG_CRITICAL_HIT); PASSES_RANDOMLY(8, 8, RNG_CRITICAL_HIT);
GIVEN { GIVEN {
ASSUME(B_CRIT_CHANCE >= GEN_7);
ASSUME(gMovesInfo[MOVE_SLASH].criticalHitStage == 1); ASSUME(gMovesInfo[MOVE_SLASH].criticalHitStage == 1);
ASSUME(gMovesInfo[MOVE_FOCUS_ENERGY].effect == EFFECT_FOCUS_ENERGY); ASSUME(gMovesInfo[MOVE_FOCUS_ENERGY].effect == EFFECT_FOCUS_ENERGY);
PLAYER(SPECIES_WOBBUFFET); PLAYER(SPECIES_WOBBUFFET);
@ -286,6 +289,7 @@ DOUBLE_BATTLE_TEST("Crit Chance: Dragon Cheer increases critical hit ratio by on
{ {
PASSES_RANDOMLY(1, 8, RNG_CRITICAL_HIT); PASSES_RANDOMLY(1, 8, RNG_CRITICAL_HIT);
GIVEN { GIVEN {
ASSUME(B_CRIT_CHANCE >= GEN_7);
ASSUME(gMovesInfo[MOVE_TACKLE].criticalHitStage == 0); ASSUME(gMovesInfo[MOVE_TACKLE].criticalHitStage == 0);
ASSUME(gMovesInfo[MOVE_DRAGON_CHEER].effect == EFFECT_DRAGON_CHEER); ASSUME(gMovesInfo[MOVE_DRAGON_CHEER].effect == EFFECT_DRAGON_CHEER);
PLAYER(SPECIES_WOBBUFFET); PLAYER(SPECIES_WOBBUFFET);
@ -306,6 +310,7 @@ DOUBLE_BATTLE_TEST("Crit Chance: Dragon Cheer increases critical hit ratio by tw
{ {
PASSES_RANDOMLY(1, 2, RNG_CRITICAL_HIT); PASSES_RANDOMLY(1, 2, RNG_CRITICAL_HIT);
GIVEN { GIVEN {
ASSUME(B_CRIT_CHANCE >= GEN_7);
ASSUME(gMovesInfo[MOVE_TACKLE].criticalHitStage == 0); ASSUME(gMovesInfo[MOVE_TACKLE].criticalHitStage == 0);
ASSUME(gMovesInfo[MOVE_DRAGON_CHEER].effect == EFFECT_DRAGON_CHEER); ASSUME(gMovesInfo[MOVE_DRAGON_CHEER].effect == EFFECT_DRAGON_CHEER);
PLAYER(SPECIES_WOBBUFFET); PLAYER(SPECIES_WOBBUFFET);