mirror of
https://github.com/blitzkit/blitzkit.git
synced 2026-10-23 19:49:50 +02:00
feat: simplified shell stats
This commit is contained in:
1 parent
def5e4fa4f
commit
68273ea295
4 files changed
+107
-74
No files matched your search
Vendored
+1
@@ -56,6 +56,7 @@
|
|||||||
"krieg",
|
"krieg",
|
||||||
"Leaderboard",
|
"Leaderboard",
|
||||||
"leaderboards",
|
"leaderboards",
|
||||||
|
"lerp",
|
||||||
"LINEARSIZE",
|
"LINEARSIZE",
|
||||||
"loddist",
|
"loddist",
|
||||||
"lods",
|
"lods",
|
||||||
|
|||||||
@@ -102,6 +102,27 @@ export function Modules() {
|
|||||||
);
|
);
|
||||||
})}
|
})}
|
||||||
</Flex>
|
</Flex>
|
||||||
|
|
||||||
|
<Flex>
|
||||||
|
{protagonist.gun.shells.map((shell, index) => {
|
||||||
|
return (
|
||||||
|
<ModuleButton
|
||||||
|
key={shell.id}
|
||||||
|
type="shell"
|
||||||
|
shell={shell.icon}
|
||||||
|
selected={protagonist.shell.id === shell.id}
|
||||||
|
first={index === 0}
|
||||||
|
last={index === protagonist.gun.shells.length - 1}
|
||||||
|
rowChild
|
||||||
|
onClick={() => {
|
||||||
|
mutateDuel((draft) => {
|
||||||
|
draft.protagonist!.shell = shell;
|
||||||
|
});
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
})}
|
||||||
|
</Flex>
|
||||||
</Flex>
|
</Flex>
|
||||||
</ConfigurationChildWrapper>
|
</ConfigurationChildWrapper>
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -1,14 +1,12 @@
|
|||||||
import { Flex, Heading } from '@radix-ui/themes';
|
import { Flex, Heading, Slider, Text, TextField } from '@radix-ui/themes';
|
||||||
import { use } from 'react';
|
import { debounce } from 'lodash';
|
||||||
import { isExplosive } from '../../../../../../core/blitz/isExplosive';
|
import { use, useEffect, useRef, useState } from 'react';
|
||||||
|
import { lerp } from 'three/src/math/MathUtils';
|
||||||
import { resolveNearPenetration } from '../../../../../../core/blitz/resolveNearPenetration';
|
import { resolveNearPenetration } from '../../../../../../core/blitz/resolveNearPenetration';
|
||||||
import { modelDefinitions } from '../../../../../../core/blitzkrieg/modelDefinitions';
|
import { modelDefinitions } from '../../../../../../core/blitzkrieg/modelDefinitions';
|
||||||
import { normalizeBoundingBox } from '../../../../../../core/blitzkrieg/normalizeBoundingBox';
|
import { normalizeBoundingBox } from '../../../../../../core/blitzkrieg/normalizeBoundingBox';
|
||||||
import { resolveDpm } from '../../../../../../core/blitzkrieg/resolveDpm';
|
import { resolveDpm } from '../../../../../../core/blitzkrieg/resolveDpm';
|
||||||
import {
|
import { GUN_TYPE_NAMES } from '../../../../../../core/blitzkrieg/tankDefinitions';
|
||||||
GUN_TYPE_NAMES,
|
|
||||||
SHELL_NAMES,
|
|
||||||
} from '../../../../../../core/blitzkrieg/tankDefinitions';
|
|
||||||
import { unionBoundingBox } from '../../../../../../core/blitzkrieg/unionBoundingBox';
|
import { unionBoundingBox } from '../../../../../../core/blitzkrieg/unionBoundingBox';
|
||||||
import { useEquipment } from '../../../../../../core/blitzkrieg/useEquipmentEquipped';
|
import { useEquipment } from '../../../../../../core/blitzkrieg/useEquipmentEquipped';
|
||||||
import { useDuel } from '../../../../../../stores/duel';
|
import { useDuel } from '../../../../../../stores/duel';
|
||||||
@@ -43,6 +41,7 @@ export function Characteristics() {
|
|||||||
stockTrack.weight +
|
stockTrack.weight +
|
||||||
stockTurret.weight +
|
stockTurret.weight +
|
||||||
stockGun.weight;
|
stockGun.weight;
|
||||||
|
const [penetrationDistance, setPenetrationDistance] = useState(0);
|
||||||
const hasRammer = useEquipment(100);
|
const hasRammer = useEquipment(100);
|
||||||
const hasCalibratedShells = useEquipment(103);
|
const hasCalibratedShells = useEquipment(103);
|
||||||
const hasEnhancedGunLayingDrive = useEquipment(104);
|
const hasEnhancedGunLayingDrive = useEquipment(104);
|
||||||
@@ -56,12 +55,19 @@ export function Characteristics() {
|
|||||||
const hasCamouflageNet = useEquipment(115);
|
const hasCamouflageNet = useEquipment(115);
|
||||||
const hasImprovedVerticalStabilizer = useEquipment(122);
|
const hasImprovedVerticalStabilizer = useEquipment(122);
|
||||||
const hasImprovedSuspension = useEquipment(123);
|
const hasImprovedSuspension = useEquipment(123);
|
||||||
|
const penetrationDistanceInput = useRef<HTMLInputElement>(null);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* TODO:
|
* TODO:
|
||||||
* - Improved Ventilation
|
* - Improved Ventilation
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (penetrationDistanceInput.current) {
|
||||||
|
penetrationDistanceInput.current.value = `${penetrationDistance}`;
|
||||||
|
}
|
||||||
|
}, [penetrationDistance]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Flex direction="column" gap="4" style={{ width: '100%' }}>
|
<Flex direction="column" gap="4" style={{ width: '100%' }}>
|
||||||
<Flex direction="column" gap="2">
|
<Flex direction="column" gap="2">
|
||||||
@@ -209,75 +215,82 @@ export function Characteristics() {
|
|||||||
<InfoWithDelta name="Caliber" decimals={0} unit="mm">
|
<InfoWithDelta name="Caliber" decimals={0} unit="mm">
|
||||||
{shell.caliber}
|
{shell.caliber}
|
||||||
</InfoWithDelta>
|
</InfoWithDelta>
|
||||||
<Info name="Penetration" unit="mm" />
|
{typeof shell.penetration !== 'number' && (
|
||||||
{gun.shells.map((shell) => (
|
<Info name="Penetration" unit="mm" />
|
||||||
|
)}
|
||||||
|
{typeof shell.penetration === 'number' && (
|
||||||
|
<InfoWithDelta
|
||||||
|
indent={typeof shell.penetration !== 'number'}
|
||||||
|
decimals={0}
|
||||||
|
name="Penetration"
|
||||||
|
>
|
||||||
|
{resolveNearPenetration(shell.penetration)}
|
||||||
|
</InfoWithDelta>
|
||||||
|
)}
|
||||||
|
{typeof shell.penetration !== 'number' && (
|
||||||
<>
|
<>
|
||||||
<InfoWithDelta
|
<Flex align="center" gap="2" style={{ paddingLeft: 24 }}>
|
||||||
decimals={0}
|
<Text>Distance</Text>
|
||||||
key={shell.type}
|
<Slider
|
||||||
|
key={penetrationDistance}
|
||||||
|
min={0}
|
||||||
|
max={500}
|
||||||
|
style={{ flex: 1 }}
|
||||||
|
defaultValue={[penetrationDistance]}
|
||||||
|
onValueChange={debounce(([value]) => {
|
||||||
|
setPenetrationDistance(value);
|
||||||
|
}, 500)}
|
||||||
|
/>
|
||||||
|
<TextField.Root style={{ width: 64 }}>
|
||||||
|
<TextField.Input
|
||||||
|
ref={penetrationDistanceInput}
|
||||||
|
defaultValue={penetrationDistance}
|
||||||
|
onBlur={() => {
|
||||||
|
setPenetrationDistance(
|
||||||
|
Math.min(
|
||||||
|
parseInt(penetrationDistanceInput.current!.value),
|
||||||
|
500,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}}
|
||||||
|
onKeyDown={(event) => {
|
||||||
|
if (event.key === 'Enter') {
|
||||||
|
event.currentTarget.blur();
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
<TextField.Slot>m</TextField.Slot>
|
||||||
|
</TextField.Root>
|
||||||
|
</Flex>
|
||||||
|
<Info
|
||||||
|
delta={
|
||||||
|
lerp(
|
||||||
|
shell.penetration[0],
|
||||||
|
shell.penetration[1],
|
||||||
|
penetrationDistance / 500,
|
||||||
|
) - shell.penetration[0]
|
||||||
|
}
|
||||||
indent
|
indent
|
||||||
name={SHELL_NAMES[shell.type]}
|
decimals={0}
|
||||||
|
name={`At ${penetrationDistance}m`}
|
||||||
>
|
>
|
||||||
{resolveNearPenetration(shell.penetration) *
|
{lerp(
|
||||||
(hasCalibratedShells
|
shell.penetration[0],
|
||||||
? isExplosive(shell.type)
|
shell.penetration[1],
|
||||||
? 1.1
|
penetrationDistance / 500,
|
||||||
: 1.05
|
)}
|
||||||
: 1)}
|
</Info>
|
||||||
</InfoWithDelta>
|
|
||||||
{typeof shell.penetration !== 'number' && (
|
|
||||||
<InfoWithDelta
|
|
||||||
decimals={0}
|
|
||||||
key={shell.type}
|
|
||||||
indent
|
|
||||||
name={`${SHELL_NAMES[shell.type]} at 500m`}
|
|
||||||
>
|
|
||||||
{(hasSupercharger
|
|
||||||
? shell.penetration[1] +
|
|
||||||
0.5 * (shell.penetration[0] - shell.penetration[1])
|
|
||||||
: shell.penetration[1]) *
|
|
||||||
(hasCalibratedShells
|
|
||||||
? isExplosive(shell.type)
|
|
||||||
? 1.1
|
|
||||||
: 1.05
|
|
||||||
: 1)}
|
|
||||||
</InfoWithDelta>
|
|
||||||
)}
|
|
||||||
</>
|
</>
|
||||||
))}
|
)}
|
||||||
<Info name="Damage" unit="hp" />
|
<InfoWithDelta name="Damage" unit="hp">
|
||||||
{gun.shells.map((shell) => (
|
{shell.damage.armor}
|
||||||
<InfoWithDelta
|
</InfoWithDelta>
|
||||||
decimals={0}
|
<InfoWithDelta name="Module damage" unit="hp">
|
||||||
key={shell.type}
|
{shell.damage.module}
|
||||||
indent
|
</InfoWithDelta>
|
||||||
name={SHELL_NAMES[shell.type]}
|
<InfoWithDelta name="Shell velocity" unit="m/s">
|
||||||
>
|
{shell.speed * (hasSupercharger ? 1.3 : 1)}
|
||||||
{shell.damage.armor}
|
</InfoWithDelta>
|
||||||
</InfoWithDelta>
|
|
||||||
))}
|
|
||||||
<Info name="Module damage" unit="hp" />
|
|
||||||
{gun.shells.map((shell, index) => (
|
|
||||||
<InfoWithDelta
|
|
||||||
decimals={0}
|
|
||||||
key={shell.type}
|
|
||||||
indent
|
|
||||||
name={SHELL_NAMES[shell.type]}
|
|
||||||
>
|
|
||||||
{shell.damage.module}
|
|
||||||
</InfoWithDelta>
|
|
||||||
))}
|
|
||||||
<Info name="Shell velocity" unit="m/s" />
|
|
||||||
{gun.shells.map((shell) => (
|
|
||||||
<InfoWithDelta
|
|
||||||
decimals={0}
|
|
||||||
key={shell.type}
|
|
||||||
indent
|
|
||||||
name={SHELL_NAMES[shell.type]}
|
|
||||||
>
|
|
||||||
{shell.speed * (hasSupercharger ? 1.3 : 1)}
|
|
||||||
</InfoWithDelta>
|
|
||||||
))}
|
|
||||||
<InfoWithDelta
|
<InfoWithDelta
|
||||||
decimals={2}
|
decimals={2}
|
||||||
name="Aim time"
|
name="Aim time"
|
||||||
|
|||||||
@@ -25,5 +25,3 @@ export interface EquipmentDefinitions {
|
|||||||
export const equipmentDefinitions = fetchCdonLz4<EquipmentDefinitions>(
|
export const equipmentDefinitions = fetchCdonLz4<EquipmentDefinitions>(
|
||||||
asset('definitions/equipment.cdon.lz4'),
|
asset('definitions/equipment.cdon.lz4'),
|
||||||
);
|
);
|
||||||
|
|
||||||
equipmentDefinitions.then(console.log);
|
|
||||||
Reference in new issue
Block a user