mirror of
https://github.com/blitzkit/blitzkit.git
synced 2026-10-23 11:39:50 +02:00
fix: some linting for new proto 6
This commit is contained in:
1 parent
96310a9d63
commit
95bb67bcf1
29 files changed
+229
-295
No files matched your search
@@ -24,7 +24,8 @@ export const PrimaryArmorScene = memo(() => {
|
||||
const tankModelDefinition = useTankModelDefinition();
|
||||
const trackModelDefinition = tankModelDefinition.tracks[track.id];
|
||||
const turretModelDefinition = tankModelDefinition.turrets[turret.id];
|
||||
const gunModelDefinition = turretModelDefinition.guns[gun.id];
|
||||
const gunModelDefinition =
|
||||
turretModelDefinition.guns[gun.gunType!.value.base.id];
|
||||
const hullOrigin = correctZYTuple(trackModelDefinition.origin);
|
||||
const turretOrigin = correctZYTuple(tankModelDefinition.turretOrigin);
|
||||
const gunOrigin = correctZYTuple(turretModelDefinition.gunOrigin);
|
||||
@@ -68,7 +69,7 @@ export const PrimaryArmorScene = memo(() => {
|
||||
<group ref={turretContainer}>
|
||||
{armorNodes.map((node) => {
|
||||
const isCurrentTurret = node.name.startsWith(
|
||||
`turret_${turretModelDefinition.model.toString().padStart(2, '0')}`,
|
||||
`turret_${turretModelDefinition.modelId.toString().padStart(2, '0')}`,
|
||||
);
|
||||
const isVisible = isCurrentTurret;
|
||||
const armorId = nameToArmorId(node.name);
|
||||
@@ -102,7 +103,7 @@ export const PrimaryArmorScene = memo(() => {
|
||||
<group ref={gunContainer}>
|
||||
{armorNodes.map((node) => {
|
||||
const isCurrentGun = node.name.startsWith(
|
||||
`gun_${gunModelDefinition.model.toString().padStart(2, '0')}`,
|
||||
`gun_${gunModelDefinition.modelId.toString().padStart(2, '0')}`,
|
||||
);
|
||||
const isVisible = isCurrentGun;
|
||||
const armorId = nameToArmorId(node.name);
|
||||
|
||||
+4
-5
@@ -2,7 +2,6 @@ import {
|
||||
type ShellDefinition,
|
||||
canSplash,
|
||||
isExplosive,
|
||||
resolveNearPenetration,
|
||||
resolvePenetrationCoefficient,
|
||||
} from '@blitzkit/core';
|
||||
import { useFrame } from '@react-three/fiber';
|
||||
@@ -69,7 +68,7 @@ export function PrimaryArmorSceneComponent({
|
||||
);
|
||||
material.uniforms.isExplosive.value = isExplosive(shell.type);
|
||||
material.uniforms.canSplash.value = canSplash(shell.type);
|
||||
material.uniforms.damage.value = shell.damage.armor;
|
||||
material.uniforms.damage.value = shell.armorDamage;
|
||||
material.uniforms.explosionRadius.value = shell.explosionRadius;
|
||||
|
||||
const duel = duelStore.getState();
|
||||
@@ -91,7 +90,7 @@ export function PrimaryArmorSceneComponent({
|
||||
const duel = duelStore.getState();
|
||||
const hasEnhancedArmor = await hasEquipment(
|
||||
110,
|
||||
duel.protagonist.tank.equipment,
|
||||
duel.protagonist.tank.equipmentPreset,
|
||||
equipment,
|
||||
);
|
||||
material.uniforms.thickness.value = hasEnhancedArmor
|
||||
@@ -101,10 +100,10 @@ export function PrimaryArmorSceneComponent({
|
||||
async function handleAntagonistEquipmentChange(equipment: EquipmentMatrix) {
|
||||
const duel = duelStore.getState();
|
||||
const shell = duel.antagonist.shell;
|
||||
const penetration = resolveNearPenetration(shell.penetration);
|
||||
const penetration = shell.penetration.near;
|
||||
const hasCalibratedShells = await hasEquipment(
|
||||
103,
|
||||
duel.antagonist.tank.equipment,
|
||||
duel.antagonist.tank.equipmentPreset,
|
||||
equipment,
|
||||
);
|
||||
|
||||
|
||||
@@ -37,7 +37,8 @@ export const SpacedArmorScene = memo<SpacedArmorSceneProps>(({ scene }) => {
|
||||
const tankModelDefinition = useTankModelDefinition();
|
||||
const trackModelDefinition = tankModelDefinition.tracks[track.id];
|
||||
const turretModelDefinition = tankModelDefinition.turrets[turret.id];
|
||||
const gunModelDefinition = turretModelDefinition.guns[gun.id];
|
||||
const gunModelDefinition =
|
||||
turretModelDefinition.guns[gun.gunType!.value.base.id];
|
||||
const hullOrigin = correctZYTuple(trackModelDefinition.origin);
|
||||
const turretOrigin = correctZYTuple(tankModelDefinition.turretOrigin);
|
||||
const gunOrigin = correctZYTuple(turretModelDefinition.gunOrigin);
|
||||
@@ -105,7 +106,7 @@ export const SpacedArmorScene = memo<SpacedArmorSceneProps>(({ scene }) => {
|
||||
<group ref={turretContainer}>
|
||||
{armorNodes.map((node) => {
|
||||
const isCurrentTurret = node.name.startsWith(
|
||||
`turret_${turretModelDefinition.model.toString().padStart(2, '0')}`,
|
||||
`turret_${turretModelDefinition.modelId.toString().padStart(2, '0')}`,
|
||||
);
|
||||
const isVisible = isCurrentTurret;
|
||||
const armorId = nameToArmorId(node.name);
|
||||
@@ -140,7 +141,7 @@ export const SpacedArmorScene = memo<SpacedArmorSceneProps>(({ scene }) => {
|
||||
<group ref={gunContainer}>
|
||||
{armorNodes.map((node) => {
|
||||
const isCurrentGun = node.name.startsWith(
|
||||
`gun_${gunModelDefinition.model.toString().padStart(2, '0')}`,
|
||||
`gun_${gunModelDefinition.modelId.toString().padStart(2, '0')}`,
|
||||
);
|
||||
const isVisible = isCurrentGun;
|
||||
const armorId = nameToArmorId(node.name);
|
||||
@@ -172,7 +173,7 @@ export const SpacedArmorScene = memo<SpacedArmorSceneProps>(({ scene }) => {
|
||||
})}
|
||||
|
||||
{modelNodes.map((node) => {
|
||||
const gunString = `gun_${gunModelDefinition.model
|
||||
const gunString = `gun_${gunModelDefinition.modelId
|
||||
.toString()
|
||||
.padStart(2, '0')}`;
|
||||
const isCurrentGun = gunModelDefinition.mask
|
||||
|
||||
+4
-7
@@ -1,6 +1,5 @@
|
||||
import {
|
||||
isExplosive,
|
||||
resolveNearPenetration,
|
||||
resolvePenetrationCoefficient,
|
||||
type ShellDefinition,
|
||||
} from '@blitzkit/core';
|
||||
@@ -54,9 +53,7 @@ export function SpacedArmorSubSpaced({
|
||||
|
||||
useEffect(() => {
|
||||
function handleShellChange(shell: ShellDefinition) {
|
||||
material.uniforms.penetration.value = resolveNearPenetration(
|
||||
shell.penetration,
|
||||
);
|
||||
material.uniforms.penetration.value = shell.penetration.near;
|
||||
material.uniforms.caliber.value = shell.caliber;
|
||||
material.uniforms.ricochet.value = degToRad(
|
||||
isExplosive(shell.type) ? 90 : shell.ricochet!,
|
||||
@@ -71,7 +68,7 @@ export function SpacedArmorSubSpaced({
|
||||
const duel = duelStore.getState();
|
||||
const hasEnhancedArmor = await hasEquipment(
|
||||
110,
|
||||
duel.protagonist.tank.equipment,
|
||||
duel.protagonist.tank.equipmentPreset,
|
||||
equipment,
|
||||
);
|
||||
material.uniforms.thickness.value = hasEnhancedArmor
|
||||
@@ -81,10 +78,10 @@ export function SpacedArmorSubSpaced({
|
||||
async function handleAntagonistEquipmentChange(equipment: EquipmentMatrix) {
|
||||
const duel = duelStore.getState();
|
||||
const shell = duelStore.getState().antagonist.shell;
|
||||
const penetration = resolveNearPenetration(shell.penetration);
|
||||
const penetration = shell.penetration.near;
|
||||
const hasCalibratedShells = await hasEquipment(
|
||||
103,
|
||||
duel.antagonist.tank.equipment,
|
||||
duel.antagonist.tank.equipmentPreset,
|
||||
equipment,
|
||||
);
|
||||
|
||||
|
||||
+6
-7
@@ -1,7 +1,6 @@
|
||||
import {
|
||||
ShellType,
|
||||
isExplosive,
|
||||
resolveNearPenetration,
|
||||
resolvePenetrationCoefficient,
|
||||
} from '@blitzkit/core';
|
||||
import { useThree } from '@react-three/fiber';
|
||||
@@ -104,16 +103,16 @@ export function SpacedArmorSceneComponent({
|
||||
|
||||
const hasCalibratedShells = await hasEquipment(
|
||||
103,
|
||||
antagonist.tank.equipment,
|
||||
antagonist.tank.equipmentPreset,
|
||||
antagonist.equipmentMatrix,
|
||||
);
|
||||
const hasEnhancedArmor = await hasEquipment(
|
||||
110,
|
||||
protagonist.tank.equipment,
|
||||
protagonist.tank.equipmentPreset,
|
||||
protagonist.equipmentMatrix,
|
||||
);
|
||||
const penetration =
|
||||
resolveNearPenetration(shell.penetration) *
|
||||
shell.penetration.near *
|
||||
resolvePenetrationCoefficient(hasCalibratedShells, shell.type);
|
||||
const thicknessCoefficient = hasEnhancedArmor ? 1.03 : 1;
|
||||
const filteredIntersections = intersections.filter(
|
||||
@@ -289,7 +288,7 @@ export function SpacedArmorSceneComponent({
|
||||
const finalDamage = Math.max(
|
||||
0,
|
||||
0.5 *
|
||||
shell.damage.armor *
|
||||
shell.armorDamage *
|
||||
(1 - distanceFromSpacedArmor / shell.explosionRadius!) -
|
||||
1.1 *
|
||||
(lastLayer.thicknessAngled +
|
||||
@@ -312,7 +311,7 @@ export function SpacedArmorSceneComponent({
|
||||
shot.damage = finalDamage;
|
||||
} else {
|
||||
shot.in.status = 'penetration';
|
||||
shot.damage = shell.damage.armor;
|
||||
shot.damage = shell.armorDamage;
|
||||
}
|
||||
} else {
|
||||
if (lastLayer.status === 'blocked') {
|
||||
@@ -320,7 +319,7 @@ export function SpacedArmorSceneComponent({
|
||||
shot.damage = 0;
|
||||
} else if (lastLayer.status === 'penetration') {
|
||||
shot.in.status = 'penetration';
|
||||
shot.damage = shell.damage.armor;
|
||||
shot.damage = shell.armorDamage;
|
||||
} else {
|
||||
const caster = new Raycaster();
|
||||
// https://math.stackexchange.com/a/13263/1222875
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import { type TankClass } from '@blitzkit/core';
|
||||
import { TankClass } from '@blitzkit/core';
|
||||
import type { ComponentProps, ReactNode } from 'react';
|
||||
import { StupidCat } from '../StupidCat';
|
||||
import { ClassHeavy } from './components/ClassHeavy';
|
||||
import { ClassLight } from './components/ClassLight';
|
||||
import { ClassMedium } from './components/ClassMedium';
|
||||
@@ -9,8 +10,9 @@ export const classIcons: Record<
|
||||
TankClass,
|
||||
(props: ComponentProps<'svg'>) => ReactNode
|
||||
> = {
|
||||
'AT-SPG': ClassTankDestroyer,
|
||||
heavyTank: ClassHeavy,
|
||||
lightTank: ClassLight,
|
||||
mediumTank: ClassMedium,
|
||||
[TankClass.TANK_DESTROYER]: ClassTankDestroyer,
|
||||
[TankClass.HEAVY]: ClassHeavy,
|
||||
[TankClass.LIGHT]: ClassLight,
|
||||
[TankClass.MEDIUM]: ClassMedium,
|
||||
[TankClass.UNRECOGNIZED]: StupidCat,
|
||||
};
|
||||
@@ -1,7 +1,7 @@
|
||||
import {
|
||||
asset,
|
||||
fetchSkillDefinitions,
|
||||
permanentSkills,
|
||||
skillDefinitions,
|
||||
TIER_ROMAN_NUMERALS,
|
||||
type Tier,
|
||||
} from '@blitzkit/core';
|
||||
@@ -13,7 +13,7 @@ interface CrewSkillManagerProps {
|
||||
onChange?: (skillLevels: Record<string, number>) => void;
|
||||
}
|
||||
|
||||
const awaitedSkillDefinitions = await skillDefinitions;
|
||||
const skillDefinitions = await fetchSkillDefinitions();
|
||||
|
||||
export function CrewSkillManager({
|
||||
skillLevels,
|
||||
@@ -21,41 +21,39 @@ export function CrewSkillManager({
|
||||
}: CrewSkillManagerProps) {
|
||||
return (
|
||||
<Flex direction="column" gap="2">
|
||||
{Object.entries(awaitedSkillDefinitions.classes).map(
|
||||
([tankClass, skills]) => (
|
||||
<Flex gap="2" key={tankClass}>
|
||||
{skills.map((skill) => {
|
||||
const level = skillLevels[skill];
|
||||
{Object.entries(skillDefinitions.classes).map(([tankClass, skills]) => (
|
||||
<Flex gap="2" key={tankClass}>
|
||||
{skills.skills.map((skill) => {
|
||||
const level = skillLevels[skill];
|
||||
|
||||
return (
|
||||
<GenericTankComponentButton
|
||||
key={skill}
|
||||
special={!permanentSkills.includes(skill)}
|
||||
selected={level > 0}
|
||||
discriminator={
|
||||
level === 0 ? undefined : TIER_ROMAN_NUMERALS[level as Tier]
|
||||
return (
|
||||
<GenericTankComponentButton
|
||||
key={skill}
|
||||
special={!permanentSkills.includes(skill)}
|
||||
selected={level > 0}
|
||||
discriminator={
|
||||
level === 0 ? undefined : TIER_ROMAN_NUMERALS[level as Tier]
|
||||
}
|
||||
icon={asset(`icons/skills/${skill}.webp`)}
|
||||
onClick={(event) => {
|
||||
if (!onChange) return;
|
||||
|
||||
const draft = { ...skillLevels };
|
||||
|
||||
if (event.shiftKey) {
|
||||
draft[skill] = draft[skill] === 0 ? 7 : 0;
|
||||
} else {
|
||||
draft[skill] = level - 1;
|
||||
if (draft[skill] < 0) draft[skill] = 7;
|
||||
}
|
||||
icon={asset(`icons/skills/${skill}.webp`)}
|
||||
onClick={(event) => {
|
||||
if (!onChange) return;
|
||||
|
||||
const draft = { ...skillLevels };
|
||||
|
||||
if (event.shiftKey) {
|
||||
draft[skill] = draft[skill] === 0 ? 7 : 0;
|
||||
} else {
|
||||
draft[skill] = level - 1;
|
||||
if (draft[skill] < 0) draft[skill] = 7;
|
||||
}
|
||||
|
||||
onChange(draft);
|
||||
}}
|
||||
/>
|
||||
);
|
||||
})}
|
||||
</Flex>
|
||||
),
|
||||
)}
|
||||
onChange(draft);
|
||||
}}
|
||||
/>
|
||||
);
|
||||
})}
|
||||
</Flex>
|
||||
))}
|
||||
</Flex>
|
||||
);
|
||||
}
|
||||
@@ -1,9 +1,9 @@
|
||||
---
|
||||
import { gameDefinitions } from '@blitzkit/core';
|
||||
import { fetchGameDefinitions } from '@blitzkit/core';
|
||||
import { Code, Flex, Heading, Link, Text } from '@radix-ui/themes';
|
||||
import packageJson from '../../../../package.json';
|
||||
|
||||
const awaitedGameDefinitions = await gameDefinitions;
|
||||
const gameDefinitions = await fetchGameDefinitions();
|
||||
---
|
||||
|
||||
<Flex
|
||||
@@ -133,7 +133,7 @@ const awaitedGameDefinitions = await gameDefinitions;
|
||||
{packageJson.version}
|
||||
</Code>
|
||||
<Code size="2" color="gray">
|
||||
{awaitedGameDefinitions.version}
|
||||
{gameDefinitions.version}
|
||||
</Code>
|
||||
<Code size="2" color="gray">
|
||||
{import.meta.env.PUBLIC_ASSET_BRANCH}
|
||||
@@ -148,7 +148,7 @@ const awaitedGameDefinitions = await gameDefinitions;
|
||||
</Code>
|
||||
<Text size="2" color="gray"> WoT Blitz </Text>
|
||||
<Code size="2" color="gray">
|
||||
{awaitedGameDefinitions.version}
|
||||
{gameDefinitions.version}
|
||||
</Code>
|
||||
<Text size="2" color="gray"> CDN </Text>
|
||||
<Code size="2" color="gray">
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { asset, provisionDefinitions } from '@blitzkit/core';
|
||||
import { asset, fetchProvisionDefinitions } from '@blitzkit/core';
|
||||
import { GenericTankComponentButton } from './GenericTankComponentButton';
|
||||
import type { TankComponentButtonProps } from './TankComponentButton';
|
||||
|
||||
@@ -6,12 +6,12 @@ interface ProvisionButtonProps extends TankComponentButtonProps {
|
||||
provision: number;
|
||||
}
|
||||
|
||||
const awaitedProvisionDefinitions = await provisionDefinitions;
|
||||
const provisionDefinitions = await fetchProvisionDefinitions();
|
||||
|
||||
export function ProvisionButton({ provision, ...props }: ProvisionButtonProps) {
|
||||
return (
|
||||
<GenericTankComponentButton
|
||||
tooltip={awaitedProvisionDefinitions[provision].name}
|
||||
tooltip={provisionDefinitions.provisions[provision].name}
|
||||
icon={asset(`icons/provisions/${provision}.webp`)}
|
||||
{...props}
|
||||
/>
|
||||
|
||||
@@ -0,0 +1,3 @@
|
||||
export function StupidCat() {
|
||||
return <img src="https://i.imgur.com/6FBBzb9.png" />;
|
||||
}
|
||||
@@ -2,6 +2,7 @@ import {
|
||||
asset,
|
||||
fetchGameDefinitions,
|
||||
TANK_CLASSES,
|
||||
TankType,
|
||||
TIER_ROMAN_NUMERALS,
|
||||
type Tier,
|
||||
} from '@blitzkit/core';
|
||||
@@ -35,7 +36,7 @@ export function FilterControl({ compact }: FilterControlProps) {
|
||||
>
|
||||
<Flex direction={compact ? 'column' : { sm: 'row', initial: 'column' }}>
|
||||
{times(5, (index) => {
|
||||
const tier = (index + 1) as Tier;
|
||||
const tier = index as Tier;
|
||||
const selected = tankFilters.tiers?.includes(tier);
|
||||
|
||||
return (
|
||||
@@ -46,29 +47,19 @@ export function FilterControl({ compact }: FilterControlProps) {
|
||||
radius="none"
|
||||
color={selected ? undefined : 'gray'}
|
||||
highContrast
|
||||
onClick={() =>
|
||||
// mutateTankFilters((draft) => {
|
||||
// if (draft.tiers?.includes(tier)) {
|
||||
// draft.tiers = draft.tiers?.filter((t) => t !== tier);
|
||||
// } else {
|
||||
// draft.tiers = [...(draft.tiers ?? []), tier];
|
||||
// }
|
||||
// })
|
||||
|
||||
{
|
||||
if (tankFilters.tiers.includes(tier)) {
|
||||
$tankFilters.setKey(
|
||||
'tiers',
|
||||
tankFilters.tiers.filter((t) => t !== tier),
|
||||
);
|
||||
} else {
|
||||
$tankFilters.setKey('tiers', [
|
||||
...tankFilters.tiers,
|
||||
tier,
|
||||
]);
|
||||
}
|
||||
onClick={() => {
|
||||
if (tankFilters.tiers.includes(tier)) {
|
||||
$tankFilters.setKey(
|
||||
'tiers',
|
||||
tankFilters.tiers.filter((t) => t !== tier),
|
||||
);
|
||||
} else {
|
||||
$tankFilters.setKey('tiers', [
|
||||
...tankFilters.tiers,
|
||||
tier,
|
||||
]);
|
||||
}
|
||||
}
|
||||
}}
|
||||
>
|
||||
<Text size="2">{TIER_ROMAN_NUMERALS[tier]}</Text>
|
||||
</IconButton>
|
||||
@@ -78,7 +69,7 @@ export function FilterControl({ compact }: FilterControlProps) {
|
||||
</Flex>
|
||||
<Flex direction={compact ? 'column' : { sm: 'row', initial: 'column' }}>
|
||||
{times(5, (index) => {
|
||||
const tier = (index + 6) as Tier;
|
||||
const tier = (index + 5) as Tier;
|
||||
const selected = tankFilters.tiers?.includes(tier);
|
||||
|
||||
return (
|
||||
@@ -89,28 +80,19 @@ export function FilterControl({ compact }: FilterControlProps) {
|
||||
radius="none"
|
||||
color={selected ? undefined : 'gray'}
|
||||
highContrast
|
||||
onClick={() =>
|
||||
// mutateTankFilters((draft) => {
|
||||
// if (draft.tiers?.includes(tier)) {
|
||||
// draft.tiers = draft.tiers?.filter((t) => t !== tier);
|
||||
// } else {
|
||||
// draft.tiers = [...(draft.tiers ?? []), tier];
|
||||
// }
|
||||
// })
|
||||
{
|
||||
if (tankFilters.tiers.includes(tier)) {
|
||||
$tankFilters.setKey(
|
||||
'tiers',
|
||||
tankFilters.tiers.filter((t) => t !== tier),
|
||||
);
|
||||
} else {
|
||||
$tankFilters.setKey('tiers', [
|
||||
...tankFilters.tiers,
|
||||
tier,
|
||||
]);
|
||||
}
|
||||
onClick={() => {
|
||||
if (tankFilters.tiers.includes(tier)) {
|
||||
$tankFilters.setKey(
|
||||
'tiers',
|
||||
tankFilters.tiers.filter((t) => t !== tier),
|
||||
);
|
||||
} else {
|
||||
$tankFilters.setKey('tiers', [
|
||||
...tankFilters.tiers,
|
||||
tier,
|
||||
]);
|
||||
}
|
||||
}
|
||||
}}
|
||||
>
|
||||
<Text size="2">{TIER_ROMAN_NUMERALS[tier]}</Text>
|
||||
</IconButton>
|
||||
@@ -256,30 +238,19 @@ export function FilterControl({ compact }: FilterControlProps) {
|
||||
radius="none"
|
||||
color={selected ? undefined : 'gray'}
|
||||
highContrast
|
||||
onClick={() =>
|
||||
// mutateTankFilters((draft) => {
|
||||
// if (draft.classes?.includes(tankClass)) {
|
||||
// draft.classes = draft.classes?.filter(
|
||||
// (c) => c !== tankClass,
|
||||
// );
|
||||
// } else {
|
||||
// draft.classes = [...(draft.classes ?? []), tankClass];
|
||||
// }
|
||||
// })
|
||||
{
|
||||
if (tankFilters.classes.includes(tankClass)) {
|
||||
$tankFilters.setKey(
|
||||
'classes',
|
||||
tankFilters.classes.filter((c) => c !== tankClass),
|
||||
);
|
||||
} else {
|
||||
$tankFilters.setKey('classes', [
|
||||
...tankFilters.classes,
|
||||
tankClass,
|
||||
]);
|
||||
}
|
||||
onClick={() => {
|
||||
if (tankFilters.classes.includes(tankClass)) {
|
||||
$tankFilters.setKey(
|
||||
'classes',
|
||||
tankFilters.classes.filter((c) => c !== tankClass),
|
||||
);
|
||||
} else {
|
||||
$tankFilters.setKey('classes', [
|
||||
...tankFilters.classes,
|
||||
tankClass,
|
||||
]);
|
||||
}
|
||||
}
|
||||
}}
|
||||
>
|
||||
<Icon style={{ width: '1em', height: '1em' }} />
|
||||
</IconButton>
|
||||
@@ -296,73 +267,63 @@ export function FilterControl({ compact }: FilterControlProps) {
|
||||
<Tooltip content="Researchable">
|
||||
<IconButton
|
||||
variant={
|
||||
tankFilters.types?.includes('researchable') ? 'solid' : 'soft'
|
||||
tankFilters.types?.includes(TankType.RESEARCHABLE)
|
||||
? 'solid'
|
||||
: 'soft'
|
||||
}
|
||||
radius="none"
|
||||
color={
|
||||
tankFilters.types?.includes('researchable') ? undefined : 'gray'
|
||||
tankFilters.types?.includes(TankType.RESEARCHABLE)
|
||||
? undefined
|
||||
: 'gray'
|
||||
}
|
||||
highContrast
|
||||
onClick={() =>
|
||||
// mutateTankFilters((draft) => {
|
||||
// if (draft.types?.includes('researchable')) {
|
||||
// draft.types = draft.types?.filter(
|
||||
// (t) => t !== 'researchable',
|
||||
// );
|
||||
// } else {
|
||||
// draft.types = [...(draft.types ?? []), 'researchable'];
|
||||
// }
|
||||
// })
|
||||
{
|
||||
if (tankFilters.types.includes('researchable')) {
|
||||
$tankFilters.setKey(
|
||||
'types',
|
||||
tankFilters.types.filter((t) => t !== 'researchable'),
|
||||
);
|
||||
} else {
|
||||
$tankFilters.setKey('types', [
|
||||
...tankFilters.types,
|
||||
'researchable',
|
||||
]);
|
||||
}
|
||||
onClick={() => {
|
||||
if (tankFilters.types.includes(TankType.RESEARCHABLE)) {
|
||||
$tankFilters.setKey(
|
||||
'types',
|
||||
tankFilters.types.filter((t) => t !== TankType.RESEARCHABLE),
|
||||
);
|
||||
} else {
|
||||
$tankFilters.setKey('types', [
|
||||
...tankFilters.types,
|
||||
TankType.RESEARCHABLE,
|
||||
]);
|
||||
}
|
||||
}
|
||||
}}
|
||||
>
|
||||
<ResearchedIcon style={{ width: '1em', height: '1em' }} />
|
||||
</IconButton>
|
||||
</Tooltip>
|
||||
<Tooltip content="Premium">
|
||||
<IconButton
|
||||
variant={tankFilters.types?.includes('premium') ? 'solid' : 'soft'}
|
||||
radius="none"
|
||||
color={tankFilters.types?.includes('premium') ? 'amber' : 'gray'}
|
||||
highContrast
|
||||
onClick={() =>
|
||||
// mutateTankFilters((draft) => {
|
||||
// if (draft.types?.includes('premium')) {
|
||||
// draft.types = draft.types?.filter((t) => t !== 'premium');
|
||||
// } else {
|
||||
// draft.types = [...(draft.types ?? []), 'premium'];
|
||||
// }
|
||||
// })
|
||||
{
|
||||
if (tankFilters.types.includes('premium')) {
|
||||
$tankFilters.setKey(
|
||||
'types',
|
||||
tankFilters.types.filter((t) => t !== 'premium'),
|
||||
);
|
||||
} else {
|
||||
$tankFilters.setKey('types', [
|
||||
...tankFilters.types,
|
||||
'premium',
|
||||
]);
|
||||
}
|
||||
}
|
||||
variant={
|
||||
tankFilters.types?.includes(TankType.PREMIUM) ? 'solid' : 'soft'
|
||||
}
|
||||
radius="none"
|
||||
color={
|
||||
tankFilters.types?.includes(TankType.PREMIUM) ? 'amber' : 'gray'
|
||||
}
|
||||
highContrast
|
||||
onClick={() => {
|
||||
if (tankFilters.types.includes(TankType.PREMIUM)) {
|
||||
$tankFilters.setKey(
|
||||
'types',
|
||||
tankFilters.types.filter((t) => t !== TankType.PREMIUM),
|
||||
);
|
||||
} else {
|
||||
$tankFilters.setKey('types', [
|
||||
...tankFilters.types,
|
||||
TankType.PREMIUM,
|
||||
]);
|
||||
}
|
||||
}}
|
||||
>
|
||||
<Text
|
||||
color={
|
||||
tankFilters.types?.includes('premium') ? undefined : 'amber'
|
||||
tankFilters.types?.includes(TankType.PREMIUM)
|
||||
? undefined
|
||||
: 'amber'
|
||||
}
|
||||
style={{ display: 'flex', justifyContent: 'center' }}
|
||||
>
|
||||
@@ -373,37 +334,32 @@ export function FilterControl({ compact }: FilterControlProps) {
|
||||
<Tooltip content="Collector">
|
||||
<IconButton
|
||||
variant={
|
||||
tankFilters.types?.includes('collector') ? 'solid' : 'soft'
|
||||
tankFilters.types?.includes(TankType.COLLECTOR) ? 'solid' : 'soft'
|
||||
}
|
||||
radius="none"
|
||||
color={tankFilters.types?.includes('collector') ? 'blue' : 'gray'}
|
||||
highContrast
|
||||
onClick={() =>
|
||||
// mutateTankFilters((draft) => {
|
||||
// if (draft.types?.includes('collector')) {
|
||||
// draft.types = draft.types?.filter((t) => t !== 'collector');
|
||||
// } else {
|
||||
// draft.types = [...(draft.types ?? []), 'collector'];
|
||||
// }
|
||||
// })
|
||||
{
|
||||
if (tankFilters.types.includes('collector')) {
|
||||
$tankFilters.setKey(
|
||||
'types',
|
||||
tankFilters.types.filter((t) => t !== 'collector'),
|
||||
);
|
||||
} else {
|
||||
$tankFilters.setKey('types', [
|
||||
...tankFilters.types,
|
||||
'collector',
|
||||
]);
|
||||
}
|
||||
}
|
||||
color={
|
||||
tankFilters.types?.includes(TankType.COLLECTOR) ? 'blue' : 'gray'
|
||||
}
|
||||
highContrast
|
||||
onClick={() => {
|
||||
if (tankFilters.types.includes(TankType.COLLECTOR)) {
|
||||
$tankFilters.setKey(
|
||||
'types',
|
||||
tankFilters.types.filter((t) => t !== TankType.COLLECTOR),
|
||||
);
|
||||
} else {
|
||||
$tankFilters.setKey('types', [
|
||||
...tankFilters.types,
|
||||
TankType.COLLECTOR,
|
||||
]);
|
||||
}
|
||||
}}
|
||||
>
|
||||
<Text
|
||||
color={
|
||||
tankFilters.types?.includes('collector') ? undefined : 'blue'
|
||||
tankFilters.types?.includes(TankType.COLLECTOR)
|
||||
? undefined
|
||||
: 'blue'
|
||||
}
|
||||
style={{ display: 'flex', justifyContent: 'center' }}
|
||||
>
|
||||
@@ -424,14 +380,9 @@ export function FilterControl({ compact }: FilterControlProps) {
|
||||
radius="none"
|
||||
color={tankFilters.testing === 'include' ? undefined : 'gray'}
|
||||
highContrast
|
||||
onClick={() =>
|
||||
// mutateTankFilters((draft) => {
|
||||
// draft.testing = 'include';
|
||||
// })
|
||||
{
|
||||
$tankFilters.setKey('testing', 'include');
|
||||
}
|
||||
}
|
||||
onClick={() => {
|
||||
$tankFilters.setKey('testing', 'include');
|
||||
}}
|
||||
>
|
||||
<ExperimentIcon
|
||||
style={{ width: '1em', height: '1em', color: 'currentColor' }}
|
||||
@@ -484,7 +435,6 @@ export function FilterControl({ compact }: FilterControlProps) {
|
||||
<IconButton
|
||||
color="red"
|
||||
onClick={() => {
|
||||
// tankFiltersStore.setState(tankFiltersStore.getInitialState(), true);
|
||||
$tankFilters.set(initialTankFilters);
|
||||
}}
|
||||
>
|
||||
|
||||
+3
-3
@@ -1,16 +1,16 @@
|
||||
import { equipmentDefinitions } from '@blitzkit/core';
|
||||
import { fetchEquipmentDefinitions } from '@blitzkit/core';
|
||||
import { Button, Flex, Heading } from '@radix-ui/themes';
|
||||
import { Duel } from '../../../../stores/duel';
|
||||
import { EquipmentManager } from '../../../EquipmentManager';
|
||||
import { ConfigurationChildWrapper } from './ConfigurationChildWrapper';
|
||||
|
||||
const awaitedEquipmentDefinitions = await equipmentDefinitions;
|
||||
const equipmentDefinitions = await fetchEquipmentDefinitions();
|
||||
|
||||
export function Equipment() {
|
||||
const mutateDuel = Duel.useMutation();
|
||||
const protagonist = Duel.use((state) => state.protagonist);
|
||||
const equipmentPreset =
|
||||
awaitedEquipmentDefinitions.presets[protagonist.tank.equipment];
|
||||
equipmentDefinitions.presets[protagonist.tank.equipmentPreset];
|
||||
const equipmentMatrix = Duel.use(
|
||||
(state) => state.protagonist.equipmentMatrix,
|
||||
);
|
||||
|
||||
+7
-6
@@ -28,7 +28,8 @@ export const TankModel = memo(() => {
|
||||
const tankModelDefinition = useTankModelDefinition();
|
||||
const turretModelDefinition =
|
||||
tankModelDefinition.turrets[protagonist.turret.id];
|
||||
const gunModelDefinition = turretModelDefinition.guns[protagonist.gun.id];
|
||||
const gunModelDefinition =
|
||||
turretModelDefinition.guns[protagonist.gun.gunType!.value.base.id];
|
||||
const { gltf } = useModel(protagonist.tank.id);
|
||||
const nodes = Object.values(gltf.nodes);
|
||||
const isDynamicArmorActive = Duel.use((state) =>
|
||||
@@ -135,7 +136,7 @@ export const TankModel = memo(() => {
|
||||
const isTurret = node.name.startsWith('turret_');
|
||||
const isCurrentTurret =
|
||||
node.name ===
|
||||
`turret_${turretModelDefinition.model.toString().padStart(2, '0')}`;
|
||||
`turret_${turretModelDefinition.modelId.toString().padStart(2, '0')}`;
|
||||
const isVisible = isCurrentTurret;
|
||||
const position = new Vector2();
|
||||
const delta = new Vector2();
|
||||
@@ -168,7 +169,7 @@ export const TankModel = memo(() => {
|
||||
const duel = duelStore.getState();
|
||||
const hasImprovedVerticalStabilizer = await hasEquipment(
|
||||
122,
|
||||
duel.protagonist.tank.equipment,
|
||||
duel.protagonist.tank.equipmentPreset,
|
||||
duel.protagonist.equipmentMatrix,
|
||||
);
|
||||
const boundingRect = canvas.getBoundingClientRect();
|
||||
@@ -231,12 +232,12 @@ export const TankModel = memo(() => {
|
||||
{nodes.map((node) => {
|
||||
const isCurrentMantlet =
|
||||
node.name ===
|
||||
`gun_${gunModelDefinition.model
|
||||
`gun_${gunModelDefinition.modelId
|
||||
.toString()
|
||||
.padStart(2, '0')}_mask`;
|
||||
const isCurrentGun =
|
||||
node.name ===
|
||||
`gun_${gunModelDefinition.model.toString().padStart(2, '0')}`;
|
||||
`gun_${gunModelDefinition.modelId.toString().padStart(2, '0')}`;
|
||||
const isVisible = isCurrentGun || isCurrentMantlet;
|
||||
const position = new Vector2();
|
||||
const delta = new Vector2();
|
||||
@@ -268,7 +269,7 @@ export const TankModel = memo(() => {
|
||||
const duel = duelStore.getState();
|
||||
const hasImprovedVerticalStabilizer = await hasEquipment(
|
||||
122,
|
||||
duel.protagonist.tank.equipment,
|
||||
duel.protagonist.tank.equipmentPreset,
|
||||
duel.protagonist.equipmentMatrix,
|
||||
);
|
||||
const boundingRect = canvas.getBoundingClientRect();
|
||||
|
||||
+2
-2
@@ -44,7 +44,8 @@ export const TankSandbox = forwardRef<HTMLCanvasElement, TankSandboxProps>(
|
||||
const tankModelDefinition = useTankModelDefinition();
|
||||
const turretModelDefinition =
|
||||
tankModelDefinition.turrets[protagonist.turret.id];
|
||||
const gunModelDefinition = turretModelDefinition.guns[protagonist.gun.id];
|
||||
const gunModelDefinition =
|
||||
turretModelDefinition.guns[protagonist.gun.gunType!.value.base.id];
|
||||
const display = TankopediaPersistent.useDeferred(
|
||||
(state) => state.display,
|
||||
TankopediaDisplay.Model,
|
||||
@@ -185,7 +186,6 @@ export const TankSandbox = forwardRef<HTMLCanvasElement, TankSandboxProps>(
|
||||
<ArmorPlateDisplay />
|
||||
<AutoClear />
|
||||
|
||||
{/* idk why the shot display doesn't work without suspense here lol */}
|
||||
<Suspense fallback={<ModelLoader />}>
|
||||
{display === TankopediaDisplay.DynamicArmor && <Armor />}
|
||||
{display === TankopediaDisplay.StaticArmor && (
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { fetchTankDefinitions, TankType } from '@blitzkit/core';
|
||||
import { Box, Flex, Heading, Text } from '@radix-ui/themes';
|
||||
import { Suspense, useEffect, useMemo, useRef } from 'react';
|
||||
import { Suspense, useMemo, useRef } from 'react';
|
||||
import { NAVBAR_HEIGHT } from '../../../constants/navbar';
|
||||
import { Var } from '../../../core/radix/var';
|
||||
import { useFullScreen } from '../../../hooks/useFullScreen';
|
||||
@@ -44,10 +44,6 @@ export function HeroSection() {
|
||||
return { value } satisfies ThicknessRange;
|
||||
}, [protagonist]);
|
||||
|
||||
useEffect(() => {
|
||||
// setDummyLoader(false);
|
||||
}, []);
|
||||
|
||||
return (
|
||||
<Flex justify="center" style={{ backgroundColor: Var('color-surface') }}>
|
||||
<Flex
|
||||
|
||||
@@ -199,10 +199,12 @@ export function MetaSection() {
|
||||
/>
|
||||
</Flex>
|
||||
</Listing>
|
||||
{protagonist.xp && (
|
||||
{protagonist.researchCost && (
|
||||
<Listing label="Research XP">
|
||||
<Flex align="center" gap="1">
|
||||
{protagonist.xp.toLocaleString()}
|
||||
{(
|
||||
protagonist.researchCost.researchCostType!.value as number
|
||||
).toLocaleString()}
|
||||
<img
|
||||
style={{ width: '1em', height: '1em' }}
|
||||
alt="xp"
|
||||
|
||||
Reference in new issue
Block a user