feat: some stas

This commit is contained in:
TrèsAbhi committed 2024-01-27 19:06:02 -06:00
1 parent ee74c5ea5b
commit eea2024549
5 files changed
+229 -68

No files matched your search

+5 -1
View File
@@ -68,6 +68,7 @@ interface VehicleDefinitions {
armor: VehicleDefinitionArmor;
turretPositions: { turret: string };
turretInitialRotation?: { yaw: 0; pitch: 6.5; roll: 0 };
maxHealth: number;
};
chassis: {
[key: string]: {
@@ -92,6 +93,7 @@ interface VehicleDefinitions {
};
turrets0: {
[key: string]: {
maxHealth: number;
armor: VehicleDefinitionArmor;
userString: number;
level: number;
@@ -345,6 +347,7 @@ export async function definitions(production: boolean) {
});
tankDefinitions[tankId] = {
health: tankDefinition.root.hull.maxHealth,
id: tankId,
equipment,
consumables: tankDefinition.root.consumableSlots,
@@ -452,6 +455,7 @@ export async function definitions(production: boolean) {
.replace(/^(Turret ([0-9] )?)+/, ''),
tier: turret.level as Tier,
guns: [],
health: turret.maxHealth,
});
modelDefinitions[tankId].turrets[turretId] = {
@@ -591,7 +595,7 @@ export async function definitions(production: boolean) {
speed: gunShellEntry.speed,
damage: {
armor: shell.damage.armor,
devices: shell.damage.devices,
module: shell.damage.devices,
},
caliber: shell.caliber,
normalization: shell.normalizationAngle,
@@ -1,21 +1,29 @@
import { Flex, Text } from '@radix-ui/themes';
import { ReactNode } from 'react';
import { theme } from '../../../../../../../stitches.config';
interface InfoProps {
name: string;
value: string;
children: ReactNode;
unit: string;
indent?: boolean;
highlight?: boolean;
}
export function Info({ name, value, unit, indent = false }: InfoProps) {
export function Info({
name,
children,
unit,
indent = false,
highlight,
}: InfoProps) {
return (
<Flex
align="center"
style={{ width: '100%', paddingLeft: indent ? 24 : 0 }}
gap="4"
>
<Text>
<Text color={highlight ? 'amber' : undefined}>
{name}{' '}
<Text color="gray" size="1">
{unit}
@@ -26,11 +34,13 @@ export function Info({ name, value, unit, indent = false }: InfoProps) {
style={{
flex: 1,
height: 1,
backgroundColor: theme.colors.componentCallToActionInteractive_alpha,
backgroundColor: highlight
? theme.colors.componentCallToActionInteractive_amberAlpha
: theme.colors.componentCallToActionInteractive_alpha,
}}
/>
<Text>{value}</Text>
<Text color={highlight ? 'amber' : undefined}>{children}</Text>
</Flex>
);
}
@@ -1,4 +1,9 @@
import { Flex, Heading, Tabs } from '@radix-ui/themes';
import { use } from 'react';
import { resolveNearPenetration } from '../../../../../../core/blitz/resolveNearPenetration';
import { modelDefinitions } from '../../../../../../core/blitzkrieg/modelDefinitions';
import { SHELL_NAMES } from '../../../../../../core/blitzkrieg/tankDefinitions';
import { useDuel } from '../../../../../../stores/duel';
import { Camouflage } from './components/Camouflage';
import { Consumables } from './components/Consumables';
import { Crew } from './components/Crew';
@@ -8,6 +13,29 @@ import { Modules } from './components/Modules';
import { Provisions } from './components/Provisions';
export function Characteristics() {
const awaitedModelDefinitions = use(modelDefinitions);
const { tank, turret, gun, shell } = useDuel((state) => state.protagonist!);
const tankModelDefinition = awaitedModelDefinitions[tank.id];
const turretModelDefinition = tankModelDefinition.turrets[turret.id];
const gunModelDefinition = turretModelDefinition.guns[gun.id];
let dpm: number;
if (gun.type === 'regular') {
dpm = (shell.damage.armor / gun.reload) * 60;
} else if (gun.type === 'auto_loader') {
dpm =
((shell.damage.armor * gun.count) /
(gun.reload + (gun.count - 1) * gun.interClip)) *
60;
} else {
dpm =
((shell.damage.armor * gun.count) /
(gun.reload.reduce((a, b) => a + b, 0) +
(gun.count - 1) * gun.interClip)) *
60;
}
return (
<Tabs.Root defaultValue="configure" style={{ width: '100%' }}>
<Flex gap="4" direction="column">
@@ -20,75 +48,190 @@ export function Characteristics() {
<Flex direction="column" gap="4">
<Flex direction="column" gap="2">
<Heading size="5">Survivability</Heading>
<Info name="Health" value="2014" unit="hp" />
<Info name="Fire chance" value="20" unit="%" />
<Info name="View range" value="302" unit="m" />
<Info name="Camouflage when still" value="30.00" unit="%" />
<Info indent name="Moving" value="30.00" unit="%" />
<Info indent name="Shooting" value="30.00" unit="%" />
<Info indent name="Shooting and moving" value="30.00" unit="%" />
<Info indent name="Size" value="6.21 x 2.43 x 2.00" unit="m" />
<Info name="Health" unit="hp">
{tank.health + turret.health}
</Info>
<Info name="Fire chance" unit="%">
TODO
</Info>
<Info name="View range" unit="m">
TODO
</Info>
<Info name="Camouflage when still" unit="%">
TODO
</Info>
<Info indent name="Moving" unit="%">
TODO
</Info>
<Info indent name="Shooting" unit="%">
TODO
</Info>
<Info indent name="Shooting and moving" unit="%">
TODO
</Info>
<Info indent name="On fire" unit="%">
TODO
</Info>
<Info indent name="Size" unit="m">
TODO
</Info>
</Flex>
<Flex direction="column" gap="2">
<Heading size="5">Fire</Heading>
<Info name="Damage per minute" value="2316" unit="hp / min" />
<Info indent name="Maximum" value="2316" unit="hp / min" />
<Info indent name="Effective" value="2316" unit="hp / min" />
<Info name="Reload" value="5.73" unit="s" />
<Info name="AP penetration" value="273" unit="mm" />
<Info indent name="AP at 500m" value="253" unit="mm" />
<Info indent name="APCR" value="312" unit="mm" />
<Info indent name="APCR at 500m" value="300" unit="mm" />
<Info indent name="HE" value="90" unit="mm" />
<Info indent name="Caliber" value="100" unit="mm" />
<Info name="AP damage" value="400" unit="hp" />
<Info name="Shell velocity" value="1535" unit="m/s" />
<Info indent name="AP module damage" value="130" unit="hp" />
<Info indent name="APCR" value="340" unit="hp" />
<Info indent name="APCR module" value="110" unit="hp" />
<Info indent name="HE" value="520" unit="hp" />
<Info indent name="HE module" value="200" unit="hp" />
<Info name="Aim time" value="1.72" unit="s" />
<Info name="Dispersion at 100m" value="0.326" unit="m" />
<Info indent name="On move" value="0.100" unit="m" />
<Info indent name="On hull traverse" value="0.100" unit="m" />
<Info indent name="On turret traverse" value="0.070" unit="m" />
<Info indent name="On shoot" value="3.500" unit="m" />
<Info name="Gun depression" value="20" unit="°" />
<Info indent name="Elevation" value="7" unit="°" />
<Info indent name="Frontal depression" value="7" unit="°" />
<Info indent name="Frontal elevation" value="7" unit="°" />
<Info indent name="Rear depression" value="7" unit="°" />
<Info indent name="Rear elevation" value="7" unit="°" />
<Info indent name="Azimuth" value="30, 30" unit="°" />
<Info name="Damage per minute" unit="hp / min">
{dpm.toFixed(0)}
</Info>
{gun.type === 'auto_reloader' && (
<>
<Info indent name="Maximum" unit="hp / min">
TODO
</Info>
<Info indent name="Effective" unit="hp / min">
TODO
</Info>
</>
)}
{gun.type === 'auto_reloader' ? (
gun.reload.map((reload, index) => (
<Info
indent={index > 0}
name={
index > 0 ? `Shell ${index + 1}` : 'Reload on shell 1'
}
unit="s"
>
{reload.toFixed(2)}
</Info>
))
) : (
<Info name="Reload" unit="s">
{gun.reload.toFixed(2)}
</Info>
)}
<Info name="Caliber" unit="mm">
{shell.caliber}
</Info>
{gun.shells.map((shell, index) => (
<Info
indent={index > 0}
name={`${SHELL_NAMES[shell.type]}${index === 0 ? ' penetration' : ''}`}
unit="mm"
>
{resolveNearPenetration(shell.penetration)}
</Info>
))}
{gun.shells.map((shell, index) => (
<Info
indent={index > 0}
name={`${SHELL_NAMES[shell.type]}${index === 0 ? ' damage' : ''}`}
unit="hp"
>
{shell.damage.armor}
</Info>
))}
{gun.shells.map((shell, index) => (
<Info
indent={index > 0}
name={`${SHELL_NAMES[shell.type]}${index === 0 ? ' module damage' : ''}`}
unit="hp"
>
{shell.damage.module}
</Info>
))}
{gun.shells.map((shell, index) => (
<Info
indent={index > 0}
name={`${SHELL_NAMES[shell.type]}${index === 0 ? ' velocity' : ''}`}
unit="m/s"
>
{shell.speed}
</Info>
))}
<Info name="Aim time" unit="s">
TODO
</Info>
<Info name="Dispersion at 100m" unit="m">
TODO
</Info>
<Info indent name="On move" unit="m">
TODO
</Info>
<Info indent name="On hull traverse" unit="m">
TODO
</Info>
<Info indent name="On turret traverse" unit="m">
TODO
</Info>
<Info indent name="On shoot" unit="m">
TODO
</Info>
<Info name="Gun depression" unit="°">
{gunModelDefinition.pitch.max}
</Info>
<Info indent name="Elevation" unit="°">
{-gunModelDefinition.pitch.min}
</Info>
{gunModelDefinition.pitch.front && (
<>
<Info indent name="Frontal depression" unit="°">
{gunModelDefinition.pitch.front.max}
</Info>
<Info indent name="Frontal elevation" unit="°">
{-gunModelDefinition.pitch.front.min}
</Info>
</>
)}
{gunModelDefinition.pitch.back && (
<>
<Info indent name="Rear depression" unit="°">
{gunModelDefinition.pitch.back.max}
</Info>
<Info indent name="Rear elevation" unit="°">
{-gunModelDefinition.pitch.back.min}
</Info>
</>
)}
{turretModelDefinition.yaw && (
<Info indent name="Azimuth" unit="°">
{-turretModelDefinition.yaw.min},{' '}
{turretModelDefinition.yaw.max}
</Info>
)}
</Flex>
<Flex direction="column" gap="2">
<Heading size="5">Maneuverability</Heading>
<Info name="Speed forwards" value="55" unit="km/s" />
<Info indent name="Backward" value="20" unit="km/s" />
{/* TODO: average speed? */}
<Info
name="Effective power on hard terrain"
value="36.86"
unit="hp/kg"
/>
<Info
indent
name="On medium terrain"
value="36.86"
unit="hp/kg"
/>
<Info indent name="On soft terrain" value="36.86" unit="hp/kg" />
<Info name="Weight" value="45" unit="mt" />
<Info
name="Traverse speed on hard terrain"
value="36.86"
unit="°/s"
/>
<Info indent name="On medium terrain" value="36.86" unit="°/s" />
<Info indent name="On soft terrain" value="36.86" unit="°/s" />
<Info name="Speed forwards" unit="km/s">
TODO
</Info>
<Info indent name="Average" unit="km/s">
TODO
</Info>
<Info indent name="Backwards" unit="km/s">
TODO
</Info>
<Info name="Effective power on hard terrain" unit="hp/kg">
TODO
</Info>
<Info indent name="On medium terrain" unit="hp/kg">
TODO
</Info>
<Info indent name="On soft terrain" unit="hp/kg">
TODO
</Info>
<Info name="Weight" unit="mt">
TODO
</Info>
<Info name="Traverse speed on hard terrain" unit="°/s">
TODO
</Info>
<Info indent name="On medium terrain" unit="°/s">
TODO
</Info>
<Info indent name="On soft terrain" unit="°/s">
TODO
</Info>
</Flex>
</Flex>
</Tabs.Content>
+3 -1
View File
@@ -15,6 +15,7 @@ export const SHELL_NAMES: Record<ShellType, string> = {
export type TankDefinitions = Record<number, TankDefinition>;
export interface TankDefinition {
id: number;
health: number;
nation: string;
name: string;
name_full?: string;
@@ -33,6 +34,7 @@ export type TankDefinitionPrice =
| { type: 'credits'; value: number }
| { type: 'gold'; value: number };
export interface TurretDefinition {
health: number;
id: number;
name: string;
tier: Tier;
@@ -66,7 +68,7 @@ export type ShellDefinition = {
id: number;
name: string;
speed: number;
damage: { armor: number; devices: number };
damage: { armor: number; module: number };
caliber: number;
icon: string;
penetration: number | Vector2Tuple;
+2
View File
@@ -1,5 +1,6 @@
import {
amberDark,
amberDarkA,
blueDark,
orangeDark,
purpleDark,
@@ -20,6 +21,7 @@ export const theme = {
...createColors(slate, 'light'),
...createColors(amberDark, 'amber'),
...createColors(amberDarkA, 'amberAlpha'),
...createColors(orangeDark, 'orange'),
...createColors(purpleDark, 'purple'),
...createColors(blueDark, 'blue'),