From bdbfce0e18aaceb31edb4c1d60ccaef779ac1546 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Tr=C3=A8sAbhi?= <43380238+tresabhi@users.noreply.github.com>
Date: Fri, 22 Aug 2025 12:21:04 -0500
Subject: [PATCH] feat: auto reloader compatibility
---
.../Characteristics/components/Firepower.tsx | 78 +---------------
.../components/ReloadVisualizer/index.tsx | 92 ++++++++++---------
.../components/Characteristics/index.tsx | 2 -
3 files changed, 49 insertions(+), 123 deletions(-)
diff --git a/packages/website/src/components/Tankopedia/CharacteristicsSection/components/Characteristics/components/Firepower.tsx b/packages/website/src/components/Tankopedia/CharacteristicsSection/components/Characteristics/components/Firepower.tsx
index feb0bbedd..b97cc1f00 100644
--- a/packages/website/src/components/Tankopedia/CharacteristicsSection/components/Characteristics/components/Firepower.tsx
+++ b/packages/website/src/components/Tankopedia/CharacteristicsSection/components/Characteristics/components/Firepower.tsx
@@ -5,18 +5,9 @@ import {
resolvePenetrationCoefficient,
} from '@blitzkit/core';
import { literals } from '@blitzkit/i18n';
-import {
- Flex,
- Heading,
- IconButton,
- Slider,
- Text,
- TextField,
- Tooltip,
-} from '@radix-ui/themes';
+import { Flex, Heading, IconButton, Tooltip } from '@radix-ui/themes';
import { debounce } from 'lodash-es';
import { useEffect, useRef, useState } from 'react';
-import { lerp } from 'three/src/math/MathUtils.js';
import { useEquipment } from '../../../../../../hooks/useEquipment';
import { useLocale } from '../../../../../../hooks/useLocale';
import { useTankModelDefinition } from '../../../../../../hooks/useTankModelDefinition';
@@ -187,73 +178,6 @@ export function Firepower({
)}
- {typeof shell.penetration !== 'number' && (
- <>
-
- lerp(
- shell.penetration.near,
- shell.penetration.far,
- (penetrationDistance * penetrationLossOverDistanceCoefficient) /
- 500,
- ) * penetrationCoefficient
- }
- />
-
-
- {
- strings.website.tools.tankopedia.characteristics.values
- .at_distance_slider_label
- }
-
- {
- setPenetrationDistanceDebounced(value);
-
- if (!penetrationDistanceInput.current) return;
-
- penetrationDistanceInput.current.value = value.toString();
- }}
- />
- {
- setPenetrationDistance(
- Math.min(
- parseInt(penetrationDistanceInput.current!.value),
- 500,
- ),
- );
- }}
- onKeyDown={(event) => {
- if (event.key === 'Enter') {
- event.currentTarget.blur();
- }
- }}
- >
- m
-
-
- >
- )}
{isExplosive(shell.type) && (
(null);
const progressTime = useRef(null);
- /**
- * 3-shell gun example:
- *
- * 0-1: clip reload
- * ~~~: shell shot
- * 1-2: intra-clip
- * ~~~: shell shot
- * 2-3: intra-clip
- * ~~~: shell shot & reset to 0
- *
- * intra-clip time = intraClip * (n - 1)
- */
const state = useRef(0);
- const dpm = useRef(0);
- const shotPool = useRef(new Set());
useEffect(() => {
let cancel = false;
@@ -46,55 +32,73 @@ export function ReloadVisualizer({ stats }: StatsAcceptorProps) {
let lastState = state.current;
const shellArray = new Array(stats.shells);
- function shoot() {
- shotPool.current.add(Date.now() / 1000);
- dpm.current += stats.damage;
- }
-
function frame() {
if (!totalTime.current || !progressTime.current) return;
+ const reloadThreshold = stats.shellReloads
+ ? stats.shellReloads.length
+ : 1;
const now = Date.now() / 1000;
const dt = now - lastT;
let reload;
let shells;
- shotPool.current.forEach((t) => {
- if (now - t > 60) shotPool.current.delete(t);
- });
+ if (state.current < reloadThreshold) {
+ const shellReload =
+ reloadThreshold === 1
+ ? stats.shellReload!
+ : stats.shellReloads![Math.floor(state.current)];
- dpm.current = shotPool.current.size * stats.damage;
-
- if (state.current < 1) {
- state.current = Math.min(1, state.current + dt / stats.shellReload!);
- reload = state.current;
+ state.current = Math.min(
+ reloadThreshold,
+ state.current + dt / shellReload,
+ );
+ reload = state.current % 1;
shells = shellArray.fill(reload);
- totalTime.current.innerHTML = stats.shellReload!.toFixed(PRECISION);
- progressTime.current.innerHTML = (
- (1 - reload) *
- stats.shellReload!
- ).toFixed(PRECISION);
+ if (reloadThreshold > 1) {
+ shells = shells.map((_, index) =>
+ Math.max(0, state.current - shellArray.length + index + 1),
+ );
+ }
- if (state.current >= 1) shoot();
- } else if (state.current < stats.shells) {
- const interval =
- stats.burstShells === 1
- ? stats.intraClip!
- : Math.floor(state.current) % stats.burstShells === 0
- ? stats.intraClip!
- : stats.burstInterShell!;
+ totalTime.current.innerHTML = shellReload.toFixed(PRECISION);
+ progressTime.current.innerHTML = ((1 - reload) * shellReload).toFixed(
+ PRECISION,
+ );
+ } else if (state.current < stats.shells + reloadThreshold - 1) {
+ let interval;
- state.current = Math.min(stats.shells, state.current + dt / interval);
- shells = times(stats.shells, (index) => index > state.current - 1);
+ if (
+ stats.burstShells === 1 ||
+ Math.floor(state.current) % stats.burstShells === 0
+ ) {
+ interval = stats.intraClip!;
+ } else {
+ interval = stats.burstInterShell!;
+ }
+
+ state.current = Math.min(
+ stats.shells + reloadThreshold,
+ state.current + dt / interval,
+ );
reload = state.current % 1;
+ if (reloadThreshold > 1) {
+ shells = shellArray.map((_, index) =>
+ Math.max(
+ 0,
+ Math.floor(index + 1 + reloadThreshold - state.current),
+ ),
+ );
+ } else {
+ shells = times(stats.shells, (index) => index > state.current - 1);
+ }
+
totalTime.current.innerHTML = interval.toFixed(PRECISION);
progressTime.current.innerHTML = ((1 - reload) * interval).toFixed(
PRECISION,
);
-
- if (lastState % 1 > state.current % 1) shoot();
} else {
state.current = 0;
reload = 0;
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 77c881977..2c59e4ec5 100644
--- a/packages/website/src/components/Tankopedia/CharacteristicsSection/components/Characteristics/index.tsx
+++ b/packages/website/src/components/Tankopedia/CharacteristicsSection/components/Characteristics/index.tsx
@@ -87,8 +87,6 @@ export function Characteristics({ skeleton }: MaybeSkeletonComponentProps) {
modelTransformEvent.dispatch({ pitch, yaw });
}, [hasImprovedVerticalStabilizer, hasDownImprovedVerticalStabilizer]);
- console.log(tank.slug, gun.burst, stats.burstShells);
-
return (