diff --git a/packages/scripts/src/patchNotes.ts b/packages/scripts/src/patchNotes.ts index 42fe4f190..ba02e8fe1 100644 --- a/packages/scripts/src/patchNotes.ts +++ b/packages/scripts/src/patchNotes.ts @@ -168,6 +168,7 @@ if (changedTanks.length > 0) { ) .map((id) => currentEquipmentDefinitions.equipments[id]); + const equalize = false; const currentCharacteristics = tankCharacteristics( { tank: current, @@ -193,6 +194,7 @@ if (changedTanks.length > 0) { stockTurret: current.turrets[0], track: currentTracks, turret: currentTurret, + equalize, }, { equipmentDefinitions: currentEquipmentDefinitions, @@ -225,6 +227,7 @@ if (changedTanks.length > 0) { stockTurret: preview.turrets[0], track: previewTracks, turret: previewTurret, + equalize, }, { equipmentDefinitions: previewEquipmentDefinitions, diff --git a/packages/website/src/components/Tankopedia/CharacteristicsSection/components/Characteristics/components/InfoWithDelta.tsx b/packages/website/src/components/Tankopedia/CharacteristicsSection/components/Characteristics/components/InfoWithDelta.tsx index 1c5abb66f..f29d6993a 100644 --- a/packages/website/src/components/Tankopedia/CharacteristicsSection/components/Characteristics/components/InfoWithDelta.tsx +++ b/packages/website/src/components/Tankopedia/CharacteristicsSection/components/Characteristics/components/InfoWithDelta.tsx @@ -59,11 +59,12 @@ export const InfoWithDelta = memo( const delta = useDelta(uhWhatDoICallThisVariable); const protagonistTank = Duel.use((state) => state.protagonist.tank); const shellIndex = Duel.use((state) => - state.protagonist.gun.shells.indexOf(state.protagonist.shell) + state.protagonist.gun.shells.indexOf(state.protagonist.shell), ); const equipmentMatrix = Duel.use( - (state) => state.protagonist.equipmentMatrix + (state) => state.protagonist.equipmentMatrix, ); + const equalize = Duel.use((state) => state.equalize); const others = useMemo(() => { const defaultSkills = createDefaultSkills(skillDefinitions); @@ -75,7 +76,7 @@ export const InfoWithDelta = memo( tank.class === protagonistTank.class) || (relativeAgainst === TankopediaRelativeAgainst.Tier && tank.tier === protagonistTank.tier) || - relativeAgainst === TankopediaRelativeAgainst.All + relativeAgainst === TankopediaRelativeAgainst.All, ) .map((tank) => { const member = tankToDuelMember(tank, provisionDefinitions); @@ -105,12 +106,13 @@ export const InfoWithDelta = memo( track: member.track, turret: member.turret, assaultDistance: member.assaultDistance, + equalize, }, { equipmentDefinitions, provisionDefinitions, tankModelDefinition: modelDefinitions.models[tank.id], - } + }, ); }) .filter((tank) => { @@ -123,7 +125,7 @@ export const InfoWithDelta = memo( return othersValue !== undefined; }) as TankCharacteristics[]; - }, [relativeAgainst, shellIndex, equipmentMatrix]); + }, [relativeAgainst, shellIndex, equipmentMatrix, equalize]); const betterTanks = others.filter((tank) => { const othersValue = typeof props.value === "function" @@ -183,5 +185,5 @@ export const InfoWithDelta = memo( (a, b) => (typeof a.value === "function" ? a.value(a.stats) : a.stats[a.value]) === - (typeof b.value === "function" ? b.value(b.stats) : b.stats[b.value]) + (typeof b.value === "function" ? b.value(b.stats) : b.stats[b.value]), ); diff --git a/packages/website/src/components/Tankopedia/CharacteristicsSection/components/Characteristics/index.tsx b/packages/website/src/components/Tankopedia/CharacteristicsSection/components/Characteristics/index.tsx index c52a01214..cebcf0521 100644 --- a/packages/website/src/components/Tankopedia/CharacteristicsSection/components/Characteristics/index.tsx +++ b/packages/website/src/components/Tankopedia/CharacteristicsSection/components/Characteristics/index.tsx @@ -31,6 +31,7 @@ export function Characteristics({ skeleton }: MaybeSkeletonComponentProps) { const equipmentMatrix = Duel.use( (state) => state.protagonist.equipmentMatrix, ); + const equalize = Duel.use((state) => state.equalize); const { tank, turret, gun, engine, track, shell } = Duel.use( (state) => state.protagonist, ); @@ -62,6 +63,7 @@ export function Characteristics({ skeleton }: MaybeSkeletonComponentProps) { applyDynamicArmor: false, applySpallLiner: false, assaultDistance, + equalize, }, { tankModelDefinition, diff --git a/packages/website/src/components/Tankopedia/CharacteristicsSection/components/Equalizer.tsx b/packages/website/src/components/Tankopedia/CharacteristicsSection/components/Equalizer.tsx index c112f9c99..a5804f6dd 100644 --- a/packages/website/src/components/Tankopedia/CharacteristicsSection/components/Equalizer.tsx +++ b/packages/website/src/components/Tankopedia/CharacteristicsSection/components/Equalizer.tsx @@ -16,7 +16,7 @@ import { ConfigurationChildWrapper } from "./ConfigurationChildWrapper"; export function Equalizer() { const { strings } = useLocale(); - const equalize = Duel.use((state) => state.protagonist.equalize); + const equalize = Duel.use((state) => state.equalize); return ( @@ -33,7 +33,7 @@ export function Equalizer() { mt="2" onClick={() => { Duel.mutate((draft) => { - draft.protagonist.equalize = !draft.protagonist.equalize; + draft.equalize = !draft.equalize; }); }} width="100%" diff --git a/packages/website/src/core/blitzkit/tankCharacteristics.ts b/packages/website/src/core/blitzkit/tankCharacteristics.ts index a45d01fbf..40124f4a8 100644 --- a/packages/website/src/core/blitzkit/tankCharacteristics.ts +++ b/packages/website/src/core/blitzkit/tankCharacteristics.ts @@ -47,6 +47,7 @@ export function tankCharacteristics( applyDynamicArmor, applySpallLiner, assaultDistance, + equalize, }: { tank: TankDefinition; turret: TurretDefinition; @@ -67,6 +68,7 @@ export function tankCharacteristics( applyDynamicArmor: boolean; applySpallLiner: boolean; assaultDistance: number; + equalize: boolean; }, { tankModelDefinition, @@ -81,6 +83,13 @@ export function tankCharacteristics( const preset = equipmentDefinitions.presets[tank.equipment_preset]; const turretModelDefinition = tankModelDefinition.turrets[turret.id]; const gunModelDefinition = turretModelDefinition.guns[gun.id]; + const equalizer = (equalize ? tank.equalizer : undefined) ?? { + armor: 1, + damage: 1, + health: 1, + module_health: 1, + penetration: 1, + }; function equipment(id: number) { return preset.slots.some((slot, index) => { @@ -177,15 +186,17 @@ export function tankCharacteristics( (coefficient([hasGunRammer, -0.05]) * coefficient([true, degressiveStat(loaderMastery)])) / coefficient([hasAdrenaline && gun.gun_type!.$case === "regular", 0.17]); - const penetrationCoefficient = coefficient([ - hasCalibratedShells, - resolvePenetrationCoefficient(true, shell.type) - 1, - ]); - const healthCoefficient = coefficient( - [hasSandbagArmor, 0.03], - [hasEnhancedSandbagArmor, 0.06], - [hasImprovedAssembly, 0.04], - ); + const penetrationCoefficient = + coefficient([ + hasCalibratedShells, + resolvePenetrationCoefficient(true, shell.type) - 1, + ]) * equalizer.penetration; + const healthCoefficient = + coefficient( + [hasSandbagArmor, 0.03], + [hasEnhancedSandbagArmor, 0.06], + [hasImprovedAssembly, 0.04], + ) * equalizer.health; const shellVelocityCoefficient = coefficient( [hasSupercharger, 0.35], [hasImprovedGunPowder, 0.3], @@ -345,7 +356,9 @@ export function tankCharacteristics( const resolvedEnginePower = engine.power * enginePowerCoefficient; const damageCoefficientWithoutAssault = armorDamageCoefficient; const damageCoefficient = - damageCoefficientWithoutAssault * assaultDamageCoefficient; + damageCoefficientWithoutAssault * + assaultDamageCoefficient * + equalizer.damage; const dpm = resolveDpm( gun, shell, @@ -654,13 +667,3 @@ export const characteristicsOrder: { items: ["crewCount"], }, ]; - -// export const characteristicsStyling: Record< -// TankCharacteristicsKey, -// { -// name: string; -// indent?: boolean; -// condition?: TankCharacteristicsCondition[]; -// } -// > = { -// }; diff --git a/packages/website/src/core/blitzkit/tankToDuelMember.ts b/packages/website/src/core/blitzkit/tankToDuelMember.ts index 7e5081031..94331a430 100644 --- a/packages/website/src/core/blitzkit/tankToDuelMember.ts +++ b/packages/website/src/core/blitzkit/tankToDuelMember.ts @@ -26,6 +26,5 @@ export function tankToDuelMember( track: tank.tracks.at(-1)!, turret, assaultDistance: (gun.assault_ranges?.ranges[0].distance ?? 0) / 2, - equalize: false, } satisfies DuelMember; } diff --git a/packages/website/src/pages/[...locale]/compare/_index.tsx b/packages/website/src/pages/[...locale]/compare/_index.tsx index 2a0301ddf..08615f201 100644 --- a/packages/website/src/pages/[...locale]/compare/_index.tsx +++ b/packages/website/src/pages/[...locale]/compare/_index.tsx @@ -45,6 +45,7 @@ export function Page({ locale }: LocaleAcceptorProps) { function Content() { const members = CompareEphemeral.use((state) => state.members); + const equalize = CompareEphemeral.use((state) => state.equalize); const [addTankDialogOpen, setAddTankDialogOpen] = useState(false); const crewSkills = CompareEphemeral.use((state) => state.crewSkills); const { strings } = useLocale(); @@ -61,26 +62,30 @@ function Content() { stockTurret: thisMember.tank.turrets[0], applyReactiveArmor: members.some( (member) => - member.key !== thisMember.key && member.consumables.includes(33) + member.key !== thisMember.key && + member.consumables.includes(33), ), applyDynamicArmor: members.some( (member) => - member.key !== thisMember.key && member.consumables.includes(73) + member.key !== thisMember.key && + member.consumables.includes(73), ), applySpallLiner: members.some( (member) => - member.key !== thisMember.key && member.provisions.includes(101) + member.key !== thisMember.key && + member.provisions.includes(101), ), assaultDistance: thisMember.assaultDistance, + equalize, }, { equipmentDefinitions: equipmentDefinitions, provisionDefinitions: provisionDefinitions, tankModelDefinition: modelDefinitions.models[thisMember.tank.id], - } - ) + }, + ), ), - [members, crewSkills] + [members, crewSkills], ); useEffect(() => { @@ -112,7 +117,7 @@ function Content() { window.history.replaceState( {}, "", - `${window.location.pathname}?${search.toString()}` + `${window.location.pathname}?${search.toString()}`, ); }, [members]); diff --git a/packages/website/src/pages/[...locale]/tanks/[slug]/index.astro b/packages/website/src/pages/[...locale]/tanks/[slug]/index.astro index 2a4c2872e..4933da71d 100644 --- a/packages/website/src/pages/[...locale]/tanks/[slug]/index.astro +++ b/packages/website/src/pages/[...locale]/tanks/[slug]/index.astro @@ -33,7 +33,7 @@ export const getStaticPaths = (async () => { parentPaths.map((parent) => ({ params: { ...parent.params, slug: tank.slug }, props: { ...parent.props, id: tank.id }, - })) + })), ) .flat(); }) satisfies GetStaticPaths; @@ -86,8 +86,9 @@ const characteristics = tankCharacteristics( stockTrack: tank.tracks[0], track: tank.tracks.at(-1)!, assaultDistance: 0, + equalize: false, }, - { equipmentDefinitions, provisionDefinitions, tankModelDefinition } + { equipmentDefinitions, provisionDefinitions, tankModelDefinition }, ); const description = literals( strings.website.tools.tankopedia.tank_seo_description, @@ -98,7 +99,7 @@ const description = literals( penetration: Math.round(characteristics.penetration).toLocaleString(locale), speed: Math.round(characteristics.speedForwards).toLocaleString(locale), health: Math.round(characteristics.health).toLocaleString(locale), - } + }, ); const guideUrl = `${assertSecret(import.meta.env.PUBLIC_GUIDE_WEBSITE)}/${tank.slug}`; diff --git a/packages/website/src/stores/compareEphemeral.ts b/packages/website/src/stores/compareEphemeral.ts index 625db94ec..2c5a2a6e3 100644 --- a/packages/website/src/stores/compareEphemeral.ts +++ b/packages/website/src/stores/compareEphemeral.ts @@ -7,6 +7,7 @@ export interface CompareMember extends DuelMember { export interface CompareEphemeral { crewSkills: Record; + equalize: boolean; members: CompareMember[]; sorting?: { direction: "ascending" | "descending"; @@ -19,5 +20,6 @@ export const CompareEphemeral = new Varuna< Record >((crewSkills) => ({ crewSkills, + equalize: false, members: [], })); diff --git a/packages/website/src/stores/duel/index.ts b/packages/website/src/stores/duel/index.ts index b102056d0..b8a904161 100644 --- a/packages/website/src/stores/duel/index.ts +++ b/packages/website/src/stores/duel/index.ts @@ -36,12 +36,12 @@ export interface DuelMember { camouflage: boolean; cooldownBooster: number; assaultDistance: number; - equalize: boolean; } export interface DuelStore { protagonist: DuelMember; antagonist: DuelMember; + equalize: boolean; } const provisionDefinitions = await awaitableProvisionDefinitions; @@ -52,5 +52,5 @@ export const Duel = new Varuna< >(({ tank, model }) => { const protagonist = tankToDuelMember(tank, provisionDefinitions); - return { protagonist, antagonist: protagonist, model }; + return { protagonist, antagonist: protagonist, model, equalize: false }; });