Add Gen 1 Crit Chance (#5439)
Adds GEN_1 config to B_CRIT_CHANGE, only affects the chance, not multiplier or other Gen 1 quirks.
This commit is contained in:
parent
5e027754c7
commit
8d33169100
1 changed files with 92 additions and 2 deletions
|
@ -1948,6 +1948,79 @@ s32 CalcCritChanceStage(u32 battlerAtk, u32 battlerDef, u32 move, bool32 recordA
|
||||||
u32 holdEffectAtk = GetBattlerHoldEffect(battlerAtk, TRUE);
|
u32 holdEffectAtk = GetBattlerHoldEffect(battlerAtk, TRUE);
|
||||||
return CalcCritChanceStageArgs(battlerAtk, battlerDef, move, recordAbility, abilityAtk, abilityDef, holdEffectAtk);
|
return CalcCritChanceStageArgs(battlerAtk, battlerDef, move, recordAbility, abilityAtk, abilityDef, holdEffectAtk);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Bulbapedia: https://bulbapedia.bulbagarden.net/wiki/Critical_hit#Generation_I
|
||||||
|
// Crit chance = Threshold / 256, Threshold maximum of 255
|
||||||
|
// Threshold = Base Speed / 2
|
||||||
|
// High crit move = 8 * (Base Speed / 2)
|
||||||
|
// Focus Energy = 4 * (Base Speed / 2)
|
||||||
|
s32 CalcCritChanceStageGen1(u8 battlerAtk, u8 battlerDef, u32 move, bool32 recordAbility)
|
||||||
|
{
|
||||||
|
// Vanilla
|
||||||
|
u32 focusEnergyScaler = 4;
|
||||||
|
u32 highCritRatioScaler = 8;
|
||||||
|
|
||||||
|
// Not vanilla
|
||||||
|
u32 superLuckScaler = 4;
|
||||||
|
u32 scopeLensScaler = 4;
|
||||||
|
u32 luckyPunchScaler = 8;
|
||||||
|
u32 farfetchedLeekScaler = 8;
|
||||||
|
|
||||||
|
s32 critChance = 0;
|
||||||
|
s32 moveCritStage = gMovesInfo[gCurrentMove].criticalHitStage;
|
||||||
|
s32 bonusCritStage = gBattleStruct->bonusCritStages[gBattlerAttacker]; // G-Max Chi Strike
|
||||||
|
u32 abilityAtk = GetBattlerAbility(gBattlerAttacker);
|
||||||
|
u32 abilityDef = GetBattlerAbility(gBattlerTarget);
|
||||||
|
u32 holdEffectAtk = GetBattlerHoldEffect(battlerAtk, TRUE);
|
||||||
|
u16 baseSpeed = gSpeciesInfo[gBattleMons[battlerAtk].species].baseSpeed;
|
||||||
|
|
||||||
|
critChance = baseSpeed / 2;
|
||||||
|
|
||||||
|
// Crit scaling
|
||||||
|
if (moveCritStage > 0)
|
||||||
|
critChance = critChance * highCritRatioScaler * moveCritStage;
|
||||||
|
|
||||||
|
if (bonusCritStage > 0)
|
||||||
|
critChance = critChance * bonusCritStage;
|
||||||
|
|
||||||
|
if ((gBattleMons[gBattlerAttacker].status2 & STATUS2_FOCUS_ENERGY_ANY) != 0)
|
||||||
|
critChance = critChance * focusEnergyScaler;
|
||||||
|
|
||||||
|
if (holdEffectAtk == HOLD_EFFECT_SCOPE_LENS)
|
||||||
|
critChance = critChance * scopeLensScaler;
|
||||||
|
|
||||||
|
if (holdEffectAtk == HOLD_EFFECT_LUCKY_PUNCH && gBattleMons[gBattlerAttacker].species == SPECIES_CHANSEY)
|
||||||
|
critChance = critChance * luckyPunchScaler;
|
||||||
|
|
||||||
|
if (BENEFITS_FROM_LEEK(battlerAtk, holdEffectAtk))
|
||||||
|
critChance = critChance * farfetchedLeekScaler;
|
||||||
|
|
||||||
|
if (abilityAtk == ABILITY_SUPER_LUCK)
|
||||||
|
critChance = critChance * superLuckScaler;
|
||||||
|
|
||||||
|
if (critChance > 255)
|
||||||
|
critChance = 255;
|
||||||
|
|
||||||
|
// Prevented crits
|
||||||
|
if (gSideStatuses[battlerDef] & SIDE_STATUS_LUCKY_CHANT)
|
||||||
|
critChance = -1;
|
||||||
|
else if (abilityDef == ABILITY_BATTLE_ARMOR || abilityDef == ABILITY_SHELL_ARMOR)
|
||||||
|
{
|
||||||
|
if (recordAbility)
|
||||||
|
RecordAbilityBattle(battlerDef, abilityDef);
|
||||||
|
critChance = -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Guaranteed crits
|
||||||
|
else if (gStatuses3[battlerAtk] & STATUS3_LASER_FOCUS
|
||||||
|
|| gMovesInfo[move].alwaysCriticalHit == TRUE
|
||||||
|
|| (abilityAtk == ABILITY_MERCILESS && gBattleMons[battlerDef].status1 & STATUS1_PSN_ANY))
|
||||||
|
{
|
||||||
|
critChance = -2;
|
||||||
|
}
|
||||||
|
|
||||||
|
return critChance;
|
||||||
|
}
|
||||||
#undef BENEFITS_FROM_LEEK
|
#undef BENEFITS_FROM_LEEK
|
||||||
|
|
||||||
s32 GetCritHitOdds(s32 critChanceIndex)
|
s32 GetCritHitOdds(s32 critChanceIndex)
|
||||||
|
@ -1963,7 +2036,13 @@ static void Cmd_critcalc(void)
|
||||||
CMD_ARGS();
|
CMD_ARGS();
|
||||||
|
|
||||||
u16 partySlot;
|
u16 partySlot;
|
||||||
s32 critChance = CalcCritChanceStage(gBattlerAttacker, gBattlerTarget, gCurrentMove, TRUE);
|
s32 critChance;
|
||||||
|
|
||||||
|
if (B_CRIT_CHANCE == GEN_1)
|
||||||
|
critChance = CalcCritChanceStageGen1(gBattlerAttacker, gBattlerTarget, gCurrentMove, TRUE);
|
||||||
|
else
|
||||||
|
critChance = CalcCritChanceStage(gBattlerAttacker, gBattlerTarget, gCurrentMove, TRUE);
|
||||||
|
|
||||||
gPotentialItemEffectBattler = gBattlerAttacker;
|
gPotentialItemEffectBattler = gBattlerAttacker;
|
||||||
|
|
||||||
if (gBattleTypeFlags & (BATTLE_TYPE_WALLY_TUTORIAL | BATTLE_TYPE_FIRST_BATTLE))
|
if (gBattleTypeFlags & (BATTLE_TYPE_WALLY_TUTORIAL | BATTLE_TYPE_FIRST_BATTLE))
|
||||||
|
@ -1973,7 +2052,18 @@ static void Cmd_critcalc(void)
|
||||||
else if (critChance == -2)
|
else if (critChance == -2)
|
||||||
gIsCriticalHit = TRUE;
|
gIsCriticalHit = TRUE;
|
||||||
else
|
else
|
||||||
gIsCriticalHit = RandomChance(RNG_CRITICAL_HIT, 1, sCriticalHitOdds[critChance]);
|
{
|
||||||
|
if (B_CRIT_CHANCE == GEN_1)
|
||||||
|
{
|
||||||
|
u8 critRoll = RandomUniform(RNG_CRITICAL_HIT, 1, 256);
|
||||||
|
if (critRoll <= critChance)
|
||||||
|
gIsCriticalHit = 1;
|
||||||
|
else
|
||||||
|
gIsCriticalHit = 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
gIsCriticalHit = RandomChance(RNG_CRITICAL_HIT, 1, sCriticalHitOdds[critChance]);
|
||||||
|
}
|
||||||
|
|
||||||
// Counter for EVO_CRITICAL_HITS.
|
// Counter for EVO_CRITICAL_HITS.
|
||||||
partySlot = gBattlerPartyIndexes[gBattlerAttacker];
|
partySlot = gBattlerPartyIndexes[gBattlerAttacker];
|
||||||
|
|
Loading…
Reference in a new issue