fix ai crit calculations
This commit is contained in:
parent
db15190508
commit
1ca4676c4c
3 changed files with 34 additions and 18 deletions
|
@ -24,7 +24,7 @@ struct PickupItem
|
|||
|
||||
s32 CalcCritChanceStageArgs(u32 battlerAtk, u32 battlerDef, u32 move, bool32 recordAbility, u32 abilityAtk, u32 abilityDef, u32 holdEffectAtk);
|
||||
s32 CalcCritChanceStage(u32 battlerAtk, u32 battlerDef, u32 move, bool32 recordAbility);
|
||||
s32 GetCritHitChance(s32 critChanceIndex);
|
||||
s32 GetCritHitOdds(s32 critChanceIndex);
|
||||
u32 GetTotalAccuracy(u32 battlerAtk, u32 battlerDef, u32 move, u32 atkAbility, u32 defAbility, u32 atkHoldEffect, u32 defHoldEffect);
|
||||
u8 GetBattlerTurnOrderNum(u8 battlerId);
|
||||
bool32 NoAliveMonsForPlayer(void);
|
||||
|
|
|
@ -515,15 +515,23 @@ s32 AI_CalcDamage(u32 move, u32 battlerAtk, u32 battlerDef, u8 *typeEffectivenes
|
|||
aiData->abilities[battlerAtk], aiData->abilities[battlerDef]);
|
||||
|
||||
critChanceIndex = CalcCritChanceStageArgs(battlerAtk, battlerDef, move, FALSE, aiData->abilities[battlerAtk], aiData->abilities[battlerDef], aiData->holdEffects[battlerAtk]);
|
||||
if (critChanceIndex > 1) // Consider crit damage only if a move has at least +1 crit chance
|
||||
if (critChanceIndex > 1) // Consider crit damage only if a move has at least +2 crit chance
|
||||
{
|
||||
s32 critDmg = CalculateMoveDamageVars(move, battlerAtk, battlerDef, moveType, fixedBasePower,
|
||||
effectivenessMultiplier, weather, TRUE,
|
||||
aiData->holdEffects[battlerAtk], aiData->holdEffects[battlerDef],
|
||||
aiData->abilities[battlerAtk], aiData->abilities[battlerDef]);
|
||||
u32 critChance = GetCritHitChance(critChanceIndex);
|
||||
// With critChance getting closer to 1, dmg gets closer to critDmg.
|
||||
dmg = LowestRollDmg((critDmg + normalDmg * (critChance - 1)) / (critChance));
|
||||
u32 critOdds = GetCritHitOdds(critChanceIndex); // Crit chance is 1/critOdds
|
||||
// With critOdds getting closer to 1, dmg gets closer to critDmg.
|
||||
dmg = LowestRollDmg((critDmg + normalDmg * (critOdds - 1)) / (critOdds));
|
||||
}
|
||||
else if (critChanceIndex == -2) // Guaranteed critical
|
||||
{
|
||||
s32 critDmg = CalculateMoveDamageVars(move, battlerAtk, battlerDef, moveType, fixedBasePower,
|
||||
effectivenessMultiplier, weather, TRUE,
|
||||
aiData->holdEffects[battlerAtk], aiData->holdEffects[battlerDef],
|
||||
aiData->abilities[battlerAtk], aiData->abilities[battlerDef]);
|
||||
dmg = LowestRollDmg(critDmg);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
|
@ -1905,11 +1905,11 @@ static void Cmd_ppreduce(void)
|
|||
|
||||
// The chance is 1/N for each stage.
|
||||
#if B_CRIT_CHANCE >= GEN_7
|
||||
static const u8 sCriticalHitChance[] = {24, 8, 2, 1, 1};
|
||||
static const u8 sCriticalHitOdds[] = {24, 8, 2, 1, 1};
|
||||
#elif B_CRIT_CHANCE == GEN_6
|
||||
static const u8 sCriticalHitChance[] = {16, 8, 2, 1, 1};
|
||||
static const u8 sCriticalHitOdds[] = {16, 8, 2, 1, 1};
|
||||
#else
|
||||
static const u8 sCriticalHitChance[] = {16, 8, 4, 3, 2}; // Gens 2,3,4,5
|
||||
static const u8 sCriticalHitOdds[] = {16, 8, 4, 3, 2}; // Gens 2,3,4,5
|
||||
#endif // B_CRIT_CHANCE
|
||||
|
||||
#define BENEFITS_FROM_LEEK(battler, holdEffect)((holdEffect == HOLD_EFFECT_LEEK) && (GET_BASE_SPECIES_ID(gBattleMons[battler].species) == SPECIES_FARFETCHD || gBattleMons[battler].species == SPECIES_SIRFETCHD))
|
||||
|
@ -1917,8 +1917,7 @@ s32 CalcCritChanceStageArgs(u32 battlerAtk, u32 battlerDef, u32 move, bool32 rec
|
|||
{
|
||||
s32 critChance = 0;
|
||||
|
||||
if (gSideStatuses[battlerDef] & SIDE_STATUS_LUCKY_CHANT
|
||||
|| abilityDef == ABILITY_BATTLE_ARMOR || abilityDef == ABILITY_SHELL_ARMOR)
|
||||
if (gSideStatuses[battlerDef] & SIDE_STATUS_LUCKY_CHANT)
|
||||
{
|
||||
critChance = -1;
|
||||
}
|
||||
|
@ -1940,12 +1939,21 @@ s32 CalcCritChanceStageArgs(u32 battlerAtk, u32 battlerDef, u32 move, bool32 rec
|
|||
+ (abilityAtk == ABILITY_SUPER_LUCK)
|
||||
+ gBattleStruct->bonusCritStages[gBattlerAttacker];
|
||||
|
||||
// Record ability only if move had at least +3 chance to get a crit
|
||||
if (critChance >= 3 && recordAbility && (abilityDef == ABILITY_BATTLE_ARMOR || abilityDef == ABILITY_SHELL_ARMOR))
|
||||
RecordAbilityBattle(battlerDef, abilityDef);
|
||||
if (critChance >= ARRAY_COUNT(sCriticalHitOdds))
|
||||
critChance = ARRAY_COUNT(sCriticalHitOdds) - 1;
|
||||
}
|
||||
|
||||
if (critChance >= ARRAY_COUNT(sCriticalHitChance))
|
||||
critChance = ARRAY_COUNT(sCriticalHitChance) - 1;
|
||||
if (critChance != -1 && (abilityDef == ABILITY_BATTLE_ARMOR || abilityDef == ABILITY_SHELL_ARMOR))
|
||||
{
|
||||
// Record ability only if move had 100% chance to get a crit
|
||||
if (recordAbility)
|
||||
{
|
||||
if (critChance == -2)
|
||||
RecordAbilityBattle(battlerDef, abilityDef);
|
||||
else if (sCriticalHitOdds[critChance] == 1)
|
||||
RecordAbilityBattle(battlerDef, abilityDef);
|
||||
}
|
||||
critChance = -1;
|
||||
}
|
||||
|
||||
return critChance;
|
||||
|
@ -1960,12 +1968,12 @@ s32 CalcCritChanceStage(u32 battlerAtk, u32 battlerDef, u32 move, bool32 recordA
|
|||
}
|
||||
#undef BENEFITS_FROM_LEEK
|
||||
|
||||
s32 GetCritHitChance(s32 critChanceIndex)
|
||||
s32 GetCritHitOdds(s32 critChanceIndex)
|
||||
{
|
||||
if (critChanceIndex < 0)
|
||||
return -1;
|
||||
else
|
||||
return sCriticalHitChance[critChanceIndex];
|
||||
return sCriticalHitOdds[critChanceIndex];
|
||||
}
|
||||
|
||||
static void Cmd_critcalc(void)
|
||||
|
@ -1983,7 +1991,7 @@ static void Cmd_critcalc(void)
|
|||
else if (critChance == -2)
|
||||
gIsCriticalHit = TRUE;
|
||||
else
|
||||
gIsCriticalHit = RandomWeighted(RNG_CRITICAL_HIT, sCriticalHitChance[critChance] - 1, 1);
|
||||
gIsCriticalHit = RandomWeighted(RNG_CRITICAL_HIT, sCriticalHitOdds[critChance] - 1, 1);
|
||||
|
||||
// Counter for EVO_CRITICAL_HITS.
|
||||
partySlot = gBattlerPartyIndexes[gBattlerAttacker];
|
||||
|
|
Loading…
Reference in a new issue