fix: stat parity with game

This commit is contained in:
TrèsAbhi committed 2024-08-12 21:12:07 -05:00
1 parent 8d32c7ce23
commit 7f796c5ec1
3 files changed
+55 -67

No files matched your search

@@ -12,7 +12,6 @@ import { debounce } from 'lodash';
import { Fragment, use, useEffect, useRef, useState } from 'react'; import { Fragment, use, useEffect, useRef, useState } from 'react';
import { lerp } from 'three/src/math/MathUtils'; import { lerp } from 'three/src/math/MathUtils';
import { Ad, AdType } from '../../../../../../components/Ad'; import { Ad, AdType } from '../../../../../../components/Ad';
import { Link } from '../../../../../../components/Link';
import { applyPitchYawLimits } from '../../../../../../core/blitz/applyPitchYawLimits'; import { applyPitchYawLimits } from '../../../../../../core/blitz/applyPitchYawLimits';
import { isExplosive } from '../../../../../../core/blitz/isExplosive'; import { isExplosive } from '../../../../../../core/blitz/isExplosive';
import { resolvePenetrationCoefficient } from '../../../../../../core/blitz/resolvePenetrationCoefficient'; import { resolvePenetrationCoefficient } from '../../../../../../core/blitz/resolvePenetrationCoefficient';
@@ -179,27 +178,14 @@ export function Characteristics() {
{stats.dpm} {stats.dpm}
</InfoWithDelta> </InfoWithDelta>
{gun.type === 'autoReloader' && ( {gun.type === 'autoReloader' && (
<> <InfoWithDelta
<InfoWithDelta decimals={0} indent name="Maximum" unit="hp / min"> decimals={0}
{stats.dpmMaximum!} indent
</InfoWithDelta> name="Effective at 60s"
<InfoWithDelta unit="hp / min"
decimals={0} >
indent {stats.dpmEffective!}
name="Effective at 60s" </InfoWithDelta>
unit="hp / min"
>
{stats.dpmEffective!}
</InfoWithDelta>
<Info
indent
name={
<Link target="_blank" href="/docs/guide/dpm">
What's the difference?
</Link>
}
/>
</>
)} )}
{gun.type !== 'regular' && ( {gun.type !== 'regular' && (
<InfoWithDelta name="Shells">{stats.shells}</InfoWithDelta> <InfoWithDelta name="Shells">{stats.shells}</InfoWithDelta>
@@ -477,15 +463,18 @@ export function Characteristics() {
> >
{(member.type === 'commander' {(member.type === 'commander'
? commanderMastery ? commanderMastery
: crewMemberMastery) * 100} : commanderMastery * 1.1) * 100}
</InfoWithDelta> </InfoWithDelta>
{member.substitute && ( {member.substitute && (
<Info <InfoWithDelta
key={`${member.type}-substitute`} key={`${member.type}-substitute`}
decimals={0}
unit="%"
indent indent
name={ name={
<> <>
<Flex align="center" gap="1"> <Flex align="center" gap="1" display="inline-flex">
<AccessibilityIcon /> <AccessibilityIcon />
{member.substitute {member.substitute
.map((sub, index) => .map((sub, index) =>
@@ -495,7 +484,9 @@ export function Characteristics() {
</Flex> </Flex>
</> </>
} }
/> >
{commanderMastery * 1.05 * 100}
</InfoWithDelta>
)} )}
</Fragment> </Fragment>
); );
+17 -12
View File
@@ -8,21 +8,26 @@ export function resolveDpm(
intraClipCoefficient = 1, intraClipCoefficient = 1,
) { ) {
const alpha = shell.damage.armor * damageCoefficient; const alpha = shell.damage.armor * damageCoefficient;
let dps: number;
if (gun.type === 'regular') { if (gun.type === 'regular') {
return (alpha / (reloadCoefficient * gun.reload)) * 60; dps = alpha / (reloadCoefficient * gun.reload);
} else if (gun.type === 'autoLoader') { } else if (gun.type === 'autoLoader') {
return ( dps =
((alpha * gun.count) / (alpha * gun.count) /
(gun.reload + (gun.count - 1) * gun.intraClip * intraClipCoefficient)) * (gun.reload * reloadCoefficient +
60 (gun.count - 1) * gun.intraClip * intraClipCoefficient);
);
} else { } else {
return ( if (gun.reload[0] < gun.reload[1] + gun.intraClip) {
((alpha * gun.count) / // first shell's the best
(reloadCoefficient * gun.reload.reduce((a, b) => a + b, 0) + dps = alpha / (gun.reload[0] * reloadCoefficient);
(gun.count - 1) * gun.intraClip * intraClipCoefficient)) * } else {
60 dps =
); alpha /
(gun.reload.at(-1)! * reloadCoefficient +
gun.intraClip * intraClipCoefficient);
}
} }
return dps * 60;
} }
+21 -29
View File
@@ -75,6 +75,8 @@ export function tankCharacteristics(
provisionDefinitions: ProvisionDefinitions; provisionDefinitions: ProvisionDefinitions;
}, },
) { ) {
console.log(tank.crew);
const presetRows = equipmentDefinitions.presets[tank.equipment]; const presetRows = equipmentDefinitions.presets[tank.equipment];
const turretModelDefinition = tankModelDefinition.turrets[turret.id]; const turretModelDefinition = tankModelDefinition.turrets[turret.id];
const gunModelDefinition = turretModelDefinition.guns[gun.id]; const gunModelDefinition = turretModelDefinition.guns[gun.id];
@@ -138,8 +140,15 @@ export function tankCharacteristics(
0, 0,
) + (hasImprovedVentilation ? 0.08 : 0); ) + (hasImprovedVentilation ? 0.08 : 0);
const commanderMastery = crewMastery + provisionCrewBonus; const commanderMastery = crewMastery + provisionCrewBonus;
const crewMemberMastery = commanderMastery * 1.1; const loaderMastery =
commanderMastery *
(tank.crew.some(({ type }) => type === 'loader') ? 1.1 : 1.05);
const gunnerMastery =
commanderMastery *
(tank.crew.some(({ type }) => type === 'gunner') ? 1.1 : 1.05);
const driverMastery =
commanderMastery *
(tank.crew.some(({ type }) => type === 'driver') ? 1.1 : 1.05);
const intraClipCoefficient = coefficient([hasShellReloadBoost, -0.3]); const intraClipCoefficient = coefficient([hasShellReloadBoost, -0.3]);
const damageCoefficient = const damageCoefficient =
coefficient([hasTungsten, 0.15]) * coefficient([hasTungsten, 0.15]) *
@@ -150,7 +159,7 @@ export function tankCharacteristics(
); );
const reloadCoefficient = const reloadCoefficient =
(coefficient([hasGunRammer, -0.05]) * (coefficient([hasGunRammer, -0.05]) *
coefficient([true, degressiveStat(crewMemberMastery)])) / coefficient([true, degressiveStat(loaderMastery)])) /
coefficient([hasAdrenaline && gun.type === 'regular', 0.17]); coefficient([hasAdrenaline && gun.type === 'regular', 0.17]);
const penetrationCoefficient = coefficient([ const penetrationCoefficient = coefficient([
hasCalibratedShells, hasCalibratedShells,
@@ -173,10 +182,10 @@ export function tankCharacteristics(
coefficient( coefficient(
[hasEnhancedGunLayingDrive, -0.15], [hasEnhancedGunLayingDrive, -0.15],
[hasReticleCalibration, -0.3], [hasReticleCalibration, -0.3],
) * coefficient([true, degressiveStat(crewMemberMastery)]); ) * coefficient([true, degressiveStat(gunnerMastery)]);
const dispersionStillCoefficient = const dispersionStillCoefficient =
coefficient([hasRefinedGun, -0.15], [hasReticleCalibration, -0.3]) * coefficient([hasRefinedGun, -0.15], [hasReticleCalibration, -0.3]) *
coefficient([true, degressiveStat(crewMemberMastery)]); coefficient([true, degressiveStat(gunnerMastery)]);
const dispersionDamagedCoefficient = coefficient([ const dispersionDamagedCoefficient = coefficient([
hasVerticalStabilizer, hasVerticalStabilizer,
-0.12, -0.12,
@@ -212,13 +221,13 @@ export function tankCharacteristics(
); );
const turretTraverseCoefficient = const turretTraverseCoefficient =
coefficient([hasStandardFuel, 0.03], [hasImprovedFuel, 0.1]) * coefficient([hasStandardFuel, 0.03], [hasImprovedFuel, 0.1]) *
coefficient([true, progressiveStat(crewMemberMastery)]); coefficient([true, progressiveStat(gunnerMastery)]);
const hullTraverseCoefficient = const hullTraverseCoefficient =
coefficient( coefficient(
[hasImprovedControl, 0.11], [hasImprovedControl, 0.11],
[hasImprovedEnginePowerBoost, 0.01], [hasImprovedEnginePowerBoost, 0.01],
[true, crewSkills.virtuoso / 100], [true, crewSkills.virtuoso / 100],
) * coefficient([true, progressiveStat(crewMemberMastery)]); ) * coefficient([true, progressiveStat(driverMastery)]);
const resistanceHardCoefficient = coefficient([hasImprovedSuspension, -0.2]); const resistanceHardCoefficient = coefficient([hasImprovedSuspension, -0.2]);
const resistanceMediumCoefficient = coefficient([ const resistanceMediumCoefficient = coefficient([
hasImprovedSuspension, hasImprovedSuspension,
@@ -305,21 +314,13 @@ export function tankCharacteristics(
reloadCoefficient, reloadCoefficient,
intraClipCoefficient, intraClipCoefficient,
); );
const dpmMaximum = const mostOptimalShellIndex =
gun.type === 'autoReloader' gun.type === 'autoReloader'
? ( ? gun.reload[0] + gun.intraClip < gun.reload[1]
gun.count > 2 ? 1
? gun.reload.at(-1)! < gun.reload.at(-2)! : gun.reload.length
: gun.reload.at(-1)! + gun.intraClip < gun.reload.at(-2)!
)
? ((damageCoefficient * shell.damage.armor) /
(gun.reload.at(-1)! * reloadCoefficient +
gun.intraClip * intraClipCoefficient)) *
60
: ((damageCoefficient * shell.damage.armor) /
(gun.reload[0] * reloadCoefficient)) *
60
: undefined; : undefined;
const damage = shell.damage.armor * damageCoefficient;
const dpmEffective = const dpmEffective =
gun.type === 'autoReloader' gun.type === 'autoReloader'
? gun.reload.at(-1)! < gun.reload.at(-2)! ? gun.reload.at(-1)! < gun.reload.at(-2)!
@@ -343,13 +344,6 @@ export function tankCharacteristics(
damageCoefficient * shell.damage.armor * gun.reload.slice(1).length damageCoefficient * shell.damage.armor * gun.reload.slice(1).length
: undefined; : undefined;
const shells = gun.type === 'regular' ? 1 : gun.count; const shells = gun.type === 'regular' ? 1 : gun.count;
console.log(gun.reload);
const mostOptimalShellIndex =
gun.type === 'autoReloader'
? gun.reload[0] + gun.intraClip < gun.reload[1]
? 1
: gun.reload.length
: undefined;
const shellReloads = const shellReloads =
gun.type === 'autoReloader' gun.type === 'autoReloader'
? gun.reload.map((reload) => reload * reloadCoefficient) ? gun.reload.map((reload) => reload * reloadCoefficient)
@@ -361,7 +355,6 @@ export function tankCharacteristics(
const caliber = shell.caliber; const caliber = shell.caliber;
const penetration = const penetration =
resolveNearPenetration(shell.penetration) * penetrationCoefficient; resolveNearPenetration(shell.penetration) * penetrationCoefficient;
const damage = shell.damage.armor * damageCoefficient;
const clipDamage = gun.type === 'regular' ? undefined : gun.count * damage; const clipDamage = gun.type === 'regular' ? undefined : gun.count * damage;
const moduleDamage = shell.damage.module * damageCoefficient; const moduleDamage = shell.damage.module * damageCoefficient;
const explosionRadius = shell.explosionRadius; const explosionRadius = shell.explosionRadius;
@@ -471,7 +464,6 @@ export function tankCharacteristics(
shellNormalization, shellNormalization,
shellRicochet, shellRicochet,
dpm, dpm,
dpmMaximum,
dpmEffective, dpmEffective,
shells, shells,
mostOptimalShellIndex, mostOptimalShellIndex,