feat: start of better tech tree

This commit is contained in:
TrèsAbhi committed 2024-08-16 20:05:25 -05:00
1 parent 7e6e480788
commit 44f35a813c
1 file changed
+77 -79
@@ -1,9 +1,18 @@
import { ChevronRightIcon } from '@radix-ui/react-icons'; import { CaretRightIcon, ChevronRightIcon } from '@radix-ui/react-icons';
import { Box, ChevronDownIcon, Flex, Heading, Text } from '@radix-ui/themes'; import {
ChevronDownIcon,
Flex,
Heading,
ScrollArea,
Text,
} from '@radix-ui/themes';
import Link from 'next/link'; import Link from 'next/link';
import { ComponentProps, use } from 'react'; import { ComponentProps, use, useMemo } from 'react';
import { asset } from '../../../../../../core/blitzkit/asset'; import { asset } from '../../../../../../core/blitzkit/asset';
import { tankDefinitions } from '../../../../../../core/blitzkit/tankDefinitions'; import {
TankDefinition,
tankDefinitions,
} from '../../../../../../core/blitzkit/tankDefinitions';
import { TIER_ROMAN_NUMERALS } from '../../../../../../core/blitzkit/tankDefinitions/constants'; import { TIER_ROMAN_NUMERALS } from '../../../../../../core/blitzkit/tankDefinitions/constants';
import { formatCompact } from '../../../../../../core/math/formatCompact'; import { formatCompact } from '../../../../../../core/math/formatCompact';
import * as Duel from '../../../../../../stores/duel'; import * as Duel from '../../../../../../stores/duel';
@@ -49,13 +58,8 @@ export function TreeArrow({
); );
} }
export function TechTreeSection() { function Card({ id }: { id: number }) {
const awaitedTankDefinitions = use(tankDefinitions); const awaitedTankDefinitions = use(tankDefinitions);
const tank = Duel.use((state) => state.protagonist.tank);
if (tank.treeType !== 'researchable') return null;
function Card({ id }: { id: number }) {
const ancestor = awaitedTankDefinitions[id]; const ancestor = awaitedTankDefinitions[id];
return ( return (
@@ -84,7 +88,7 @@ export function TechTreeSection() {
<Text color="gray" size="1"> <Text color="gray" size="1">
{TIER_ROMAN_NUMERALS[ancestor.tier]} {TIER_ROMAN_NUMERALS[ancestor.tier]}
</Text> </Text>
<Text>{ancestor.name}</Text> <Text wrap="nowrap">{ancestor.name}</Text>
</Flex> </Flex>
<Flex gap="2" align="center"> <Flex gap="2" align="center">
@@ -98,8 +102,8 @@ export function TechTreeSection() {
objectFit: 'contain', objectFit: 'contain',
}} }}
/> />
<Text color="gray" size="1"> <Text color="gray" size="1" wrap="nowrap">
{formatCompact(ancestor.xp!)} {ancestor.xp === undefined ? 0 : formatCompact(ancestor.xp!)}
</Text> </Text>
</Flex> </Flex>
@@ -113,7 +117,7 @@ export function TechTreeSection() {
objectFit: 'contain', objectFit: 'contain',
}} }}
/> />
<Text color="gray" size="1"> <Text color="gray" size="1" wrap="nowrap">
{formatCompact(ancestor.price.value)} {formatCompact(ancestor.price.value)}
</Text> </Text>
</Flex> </Flex>
@@ -122,85 +126,79 @@ export function TechTreeSection() {
</Flex> </Flex>
</Link> </Link>
); );
}
export function TechTreeSection() {
const tank = Duel.use((state) => state.protagonist.tank);
const awaitedTankDefinitions = use(tankDefinitions);
if (
tank.treeType !== 'researchable' ||
tank.ancestors === undefined ||
tank.ancestors.length === 0
) {
return null;
} }
const ancestors = useMemo(() => {
const treeBackwards: number[] = [];
let ancestor: TankDefinition | undefined = tank;
while (ancestor !== undefined) {
if (ancestor.ancestors === undefined || ancestor.ancestors.length === 0) {
ancestor = undefined;
break;
} else if (ancestor.ancestors.length === 1) {
ancestor = awaitedTankDefinitions[ancestor.ancestors[0]];
} else {
let bestAncestor = awaitedTankDefinitions[ancestor.ancestors[0]];
ancestor.ancestors.forEach((thisAncestorId) => {
const possibleAncestor = awaitedTankDefinitions[thisAncestorId];
if (possibleAncestor.xp! < bestAncestor.xp!) {
bestAncestor = possibleAncestor;
}
});
ancestor = bestAncestor as TankDefinition;
}
treeBackwards.push(ancestor.id);
}
return treeBackwards.reverse();
}, []);
console.log(ancestors);
return ( return (
<Flex <Flex
my="6" my="6"
p="5" py="6"
direction="column"
align="center"
gap="4"
style={{ style={{
overflow: 'hidden',
backgroundColor: 'var(--color-surface)', backgroundColor: 'var(--color-surface)',
}} }}
align="center"
direction="column"
position="relative"
> >
<img <Heading size="6">Tech tree</Heading>
src={asset(`flags/scratched/${tank.nation}.webp`)}
style={{
position: 'absolute',
top: '50%',
left: '50%',
transform: 'translate(-40%, -50%)',
filter: 'blur(2px)',
opacity: 0.25,
}}
/>
<Heading mb="4">Tech tree</Heading> <ScrollArea>
<Flex align="center" gap="4" justify="center" p="4">
<Flex align="center" gap="6" direction={{ initial: 'column', sm: 'row' }}> {ancestors.map((id, index) => (
{tank.ancestors && (
<> <>
<Flex {index > 0 && (
wrap="wrap" <Text color="gray">
direction={{ initial: 'row', sm: 'column' }} <CaretRightIcon />
maxHeight={{ initial: 'unset', sm: '320px' }} </Text>
align="center" )}
justify="center"
gap="6"
>
{tank.ancestors.map((id) => (
<Card key={id} id={id} /> <Card key={id} id={id} />
</>
))} ))}
</Flex> </Flex>
</ScrollArea>
<Box display={{ initial: 'block', sm: 'none' }}>
<TreeArrow down />
</Box>
<Box display={{ initial: 'none', sm: 'block' }}>
<TreeArrow />
</Box>
</>
)}
<Card id={tank.id} />
{tank.successors && (
<>
<Box display={{ initial: 'block', sm: 'none' }}>
<TreeArrow down />
</Box>
<Box display={{ initial: 'none', sm: 'block' }}>
<TreeArrow />
</Box>
<Flex
wrap="wrap"
direction={{ initial: 'row', sm: 'column' }}
maxHeight={{ initial: 'unset', sm: '320px' }}
align="center"
justify="center"
gap="6"
>
{tank.successors.map((id) => (
<Card key={id} id={id} />
))}
</Flex>
</>
)}
</Flex>
</Flex> </Flex>
); );
} }