feat: data driven nations

This commit is contained in:
TrèsAbhi committed 2024-06-19 20:53:59 -05:00
1 parent b4bb0dcc67
commit 4927f1315c
4 files changed
+162 -148

No files matched your search

+6 -2
View File
@@ -1,5 +1,6 @@
import { readdir } from 'fs/promises';
import { readBase64DVPL } from '../../src/core/blitz/readBase64DVPL';
import sharp from 'sharp';
import { readDVPLFile } from '../../src/core/blitz/readDVPLFile';
import { commitAssets } from '../../src/core/blitzkit/commitAssets';
import { FileChange } from '../../src/core/blitzkit/commitMultipleFiles';
import { DATA, POI } from './constants';
@@ -14,7 +15,10 @@ export async function circleFlags(production: boolean) {
!flag.endsWith('@2x.packed.webp.dvpl'),
)
.map(async (flag) => {
const content = await readBase64DVPL(`${DATA}/${POI.flags}/${flag}`);
const image = sharp(await readDVPLFile(`${DATA}/${POI.flags}/${flag}`));
const content = (
await image.trim({ threshold: 100 }).toBuffer()
).toString('base64');
const name = flag.match(/flag_profile-stat_(.+)\.packed\.webp/)![1];
return {
+13 -4
View File
@@ -353,11 +353,15 @@ export interface MapAlly {
points: Array<number[]>;
}
interface AvailableNationsYaml {
available_nations: string[];
}
const blitzShellKindToBlitzkit: Record<ShellKind, ShellType> = {
ARMOR_PIERCING: 'ap',
ARMOR_PIERCING_CR: 'ap_cr',
HIGH_EXPLOSIVE: 'he',
HOLLOW_CHARGE: 'hc',
ARMOR_PIERCING: ShellType.AP,
ARMOR_PIERCING_CR: ShellType.APCR,
HIGH_EXPLOSIVE: ShellType.HE,
HOLLOW_CHARGE: ShellType.HEAT,
};
const missingStrings: Record<string, string> = {
'#artefacts:tungstentip/name': 'Tungsten Shells',
@@ -378,6 +382,11 @@ export async function definitions(production: boolean) {
.split('.')
.slice(0, 3)
.join('.'),
nations: (
await readYAMLDVPL<AvailableNationsYaml>(
`${DATA}/available_nations.yaml.dvpl`,
)
).available_nations,
};
const tankDefinitions: TankDefinitions = {};
const modelDefinitions: ModelDefinitions = {};
+142 -142
View File
@@ -15,27 +15,24 @@ import { Link } from '../../../components/Link';
import PageWrapper from '../../../components/PageWrapper';
import { TANK_CLASSES } from '../../../components/Tanks/components/Item/constants';
import { asset } from '../../../core/blitzkit/asset';
import { gameDefinitions } from '../../../core/blitzkit/gameDefinitions';
import {
NATIONS,
Tier,
tanksDefinitionsArray,
} from '../../../core/blitzkit/tankDefinitions';
import { TIER_ROMAN_NUMERALS } from '../../../core/blitzkit/tankDefinitions/constants';
import { tankIcon } from '../../../core/blitzkit/tankIcon';
import strings from '../../../lang/en-US.json';
import { treeTypeOrder } from './components/TankSearch/constants';
export default function Page() {
const awaitedTanksDefinitionsArray = use(tanksDefinitionsArray);
const awaitedNations = use(NATIONS);
const awaitedGameDefinitions = use(gameDefinitions);
return (
<PageWrapper color="purple" size={1028 + 256}>
<Flex gap="8">
<Flex direction="column" gap="4" align="start">
<Text mb="-3" weight="bold">
Class
</Text>
<Flex direction="column" gap="4" align="start" pt="9">
<Text mb="-3">Class</Text>
<Flex
direction="column"
overflow="hidden"
@@ -85,9 +82,7 @@ export default function Page() {
</Flex>
</Flex>
<Text mb="-3" weight="bold">
Type
</Text>
<Text mb="-3">Type</Text>
<Flex
overflow="hidden"
style={{
@@ -111,26 +106,55 @@ export default function Page() {
})}
</Flex>
<Text mb="-3" weight="bold">
Nation
</Text>
<Flex>
{awaitedNations.map((nation) => (
<IconButton
variant="soft"
color="gray"
highContrast
radius="none"
>
{/* TODO: trim icons */}
<img src={asset(`flags/circle/${nation}.webp`)} />
</IconButton>
))}
<Text mb="-3">Nation</Text>
<Flex
direction="column"
overflow="hidden"
style={{
borderRadius: 'var(--radius-4)',
}}
>
<Flex>
{awaitedGameDefinitions.nations
.slice(0, Math.ceil(awaitedGameDefinitions.nations.length / 2))
.map((nation) => (
<IconButton
style={{ flex: 1 }}
variant="soft"
color="gray"
highContrast
radius="none"
>
{/* TODO: trim icons */}
<img
style={{ width: '1em', height: '1em' }}
src={asset(`flags/circle/${nation}.webp`)}
/>
</IconButton>
))}
</Flex>
<Flex>
{awaitedGameDefinitions.nations
.slice(Math.ceil(awaitedGameDefinitions.nations.length / 2))
.map((nation) => (
<IconButton
style={{ flex: 1 }}
variant="soft"
color="gray"
highContrast
radius="none"
>
{/* TODO: trim icons */}
<img
style={{ width: '1em', height: '1em' }}
src={asset(`flags/circle/${nation}.webp`)}
/>
</IconButton>
))}
</Flex>
</Flex>
<Text mb="-3" weight="bold">
Test tanks
</Text>
<Text mb="-3">Test tanks</Text>
<RadioGroup.Root defaultValue="include">
<RadioGroup.Item value="include">Include</RadioGroup.Item>
<RadioGroup.Item value="exclude">Exclude</RadioGroup.Item>
@@ -141,132 +165,108 @@ export default function Page() {
<Flex direction="column" gap="8" mt="4" flexGrow="1">
{range(10, 0).map((tierUntyped) => {
const tier = tierUntyped as Tier;
const tierTanks = awaitedTanksDefinitionsArray.filter(
(tank) => tank.tier === tier,
);
const tierTanks = awaitedTanksDefinitionsArray
.filter((tank) => tank.tier === tier)
.sort(
(a, b) =>
treeTypeOrder.indexOf(a.treeType) -
treeTypeOrder.indexOf(b.treeType),
)
.sort(
(a, b) =>
TANK_CLASSES.indexOf(a.class) - TANK_CLASSES.indexOf(b.class),
)
.sort(
(a, b) =>
awaitedGameDefinitions.nations.indexOf(a.nation) -
awaitedGameDefinitions.nations.indexOf(b.nation),
);
return (
<Flex key={tier} direction="column" gap="4">
<Heading color="gray" mb="4">
Tier {TIER_ROMAN_NUMERALS[tier]}
</Heading>
<Flex align="center" mb="4" gap="4">
<Heading weight="regular">
Tier {TIER_ROMAN_NUMERALS[tier]}
</Heading>
<Separator style={{ flex: 1 }} />
</Flex>
<Flex direction="column" gap="8">
{awaitedNations.map((nation, nationIndex) => {
const nationTanks = tierTanks
.filter((tank) => tank.nation === nation)
.sort(
(a, b) =>
treeTypeOrder.indexOf(a.treeType) -
treeTypeOrder.indexOf(b.treeType),
)
.sort(
(a, b) =>
TANK_CLASSES.indexOf(a.class) -
TANK_CLASSES.indexOf(b.class),
);
if (nationTanks.length === 0) return null;
<Grid
flexGrow="1"
columns="repeat(auto-fill, minmax(100px, 1fr))"
gap="2"
gapY="6"
>
{tierTanks.map((tank) => {
const Icon = classIcons[tank.class];
return (
<Flex key={nation} direction="column" gap="4">
<Flex align="center">
<img
src={asset(`flags/scratched/${nation}.webp`)}
<Link
key={tank.id}
size="1"
color={
tank.treeType === 'collector'
? 'blue'
: tank.treeType === 'premium'
? 'amber'
: 'gray'
}
highContrast={tank.treeType === 'researchable'}
underline="hover"
href={`/tools/tankopedia/${tank.id}`}
style={{
display: 'flex',
flexDirection: 'column',
alignItems: 'center',
gap: 'var(--space-2)',
background: `url(${asset(`flags/scratched/${tank.nation}.webp`)})`,
backgroundSize: 'contain',
backgroundRepeat: 'no-repeat',
backgroundPosition: 'top left',
}}
>
<img
alt={tank.name}
src={tankIcon(tank.id)}
height={64}
style={{
width: '100%',
objectPosition: 'center right',
objectFit: 'contain',
}}
/>
<Flex
justify="center"
gap="1"
align="center"
overflow="hidden"
width="100%"
maxWidth="100%"
>
<Icon
style={{
height: 64,
aspectRatio: '2 / 1',
width: '1em',
height: '1em',
minWidth: '1em',
minHeight: '1em',
}}
/>
<Heading size="5" ml="-8" mr="4" wrap="nowrap">
{
strings.common.nations[
nation as keyof typeof strings.common.nations
]
}
</Heading>
<Separator size="4" />
<Text
align="center"
style={{
whiteSpace: 'nowrap',
overflow: 'hidden',
textOverflow: 'ellipsis',
}}
>
{tank.name}
</Text>
</Flex>
<Grid
flexGrow="1"
columns="repeat(auto-fill, minmax(80px, 1fr))"
gap="2"
gapY="4"
key={nation}
>
{nationTanks.map((tank) => {
const Icon = classIcons[tank.class];
return (
<Link
key={tank.id}
size="1"
color={
tank.treeType === 'collector'
? 'blue'
: tank.treeType === 'premium'
? 'amber'
: 'gray'
}
highContrast={tank.treeType === 'researchable'}
underline="hover"
href={`/tools/tankopedia/${tank.id}`}
style={{
display: 'flex',
flexDirection: 'column',
alignItems: 'center',
gap: 'var(--space-2)',
}}
>
<img
alt={tank.name}
src={tankIcon(tank.id)}
height={64}
style={{
width: '100%',
objectPosition: 'center',
objectFit: 'contain',
}}
/>
<Flex
justify="center"
gap="1"
align="center"
overflow="hidden"
width="100%"
maxWidth="100%"
>
<Icon
style={{
width: '1em',
height: '1em',
minWidth: '1em',
minHeight: '1em',
}}
/>
<Text
align="center"
style={{
whiteSpace: 'nowrap',
overflow: 'hidden',
textOverflow: 'ellipsis',
}}
>
{tank.name}
</Text>
</Flex>
</Link>
);
})}
</Grid>
</Flex>
</Link>
);
})}
</Flex>
</Grid>
</Flex>
);
})}
+1
View File
@@ -3,6 +3,7 @@ import { fetchCdonLz4 } from './fetchCdonLz4';
export interface GameDefinitions {
version: string;
nations: string[];
}
export const gameDefinitions = fetchCdonLz4<GameDefinitions>(