import { asset, GunDefinition, TankDefinition, TIER_ROMAN_NUMERALS, TurretDefinition, } from "@blitzkit/core"; import { literals } from "@blitzkit/i18n"; import { CaretRightIcon, CaretUpIcon, UpdateIcon } from "@radix-ui/react-icons"; import { Box, Button, Dialog, Flex, IconButton, Popover, Skeleton, Text, type ButtonProps, } from "@radix-ui/themes"; import { useRef, useState } from "react"; import { MixerScene } from "../../../components/MixerScene"; import { ModuleButton } from "../../../components/ModuleButtons/ModuleButton"; import { PageWrapper } from "../../../components/PageWrapper"; import { ScreenshotButton } from "../../../components/ScreenshotButton"; import { TankSearch } from "../../../components/TankSearch"; import { awaitableModelDefinitions } from "../../../core/awaitables/modelDefinitions"; import { awaitableTankDefinitions } from "../../../core/awaitables/tankDefinitions"; import { curateMixer } from "../../../core/blitzkit/curateMixer"; import { LocaleProvider, useLocale, type LocaleAcceptorProps, } from "../../../hooks/useLocale"; import { Mixer } from "../../../stores/mixer"; import { Tankopedia } from "../../../stores/tankopedia"; import type { MaybeSkeletonComponentProps } from "../../../types/maybeSkeletonComponentProps"; const modelDefinition = await awaitableModelDefinitions.then( ({ models }) => models[1] ); const tankDefinitions = await awaitableTankDefinitions; export function Page({ locale, skeleton, }: LocaleAcceptorProps & MaybeSkeletonComponentProps) { const initial = useRef(curateMixer()); Mixer.useInitialization(initial.current); Tankopedia.useInitialization(modelDefinition); return ( ); } type ModuleButtonProps = Omit & MaybeSkeletonComponentProps & { tank: number; onSelect: ( tank: TankDefinition, turret?: TurretDefinition, gun?: GunDefinition ) => void; turret?: number; gun?: number; }; function ModuleChooser({ skeleton, tank, onSelect, turret, gun, ...props }: ModuleButtonProps) { const { strings } = useLocale(); const [open, setOpen] = useState(false); const tankDefinition = tankDefinitions.tanks[tank]; const turretDefinition = tankDefinition.turrets.find((t) => t.id === turret); const gunDefinition = turretDefinition?.guns.find((g) => g.id === gun); const subSelector = turret !== undefined && (tankDefinition.turrets.length > 1 || (gun !== undefined && turretDefinition!.guns.length > 1)); return ( {strings.website.common.tank_search.select_dialog_title} { onSelect?.(tank); setOpen(false); }} /> {subSelector && ( {tankDefinition.turrets.length > 1 && ( {tankDefinition.turrets.map((turret) => ( { onSelect?.(tankDefinition, turret); }} /> ))} )} {turretDefinition && turretDefinition.guns.length > 1 && ( {turretDefinition.guns.map((gun) => ( {literals(strings.common.units.mm, { value: gun.shells[0].caliber.toFixed(0), })} } onClick={() => { onSelect?.(tankDefinition, turretDefinition, gun); }} /> ))} )} )} ); } function ModuleSeparator() { return ( ); } function Content({ skeleton }: MaybeSkeletonComponentProps) { const hullTankId = Mixer.use((state) => state.hull); const turretTankId = Mixer.use((state) => state.turret.tank.id); const turretTurretId = Mixer.use((state) => state.turret.turret.id); const gunTankId = Mixer.use((state) => state.gun.tank.id); const gunTurretId = Mixer.use((state) => state.gun.turret.id); const gunGunId = Mixer.use((state) => state.gun.gun.id); const canvas = useRef(null!); const { strings } = useLocale(); return ( {!skeleton && } {strings.website.tools.mixer.screenshot} { Mixer.mutate((draft) => { draft.hull = tank; }); }} /> { Mixer.mutate((draft) => { draft.turret = { tank, turret: turret ?? tank.turrets.at(-1)!, }; }); }} /> { Mixer.mutate((draft) => { draft.gun = { tank, turret: turret ?? tank.turrets.at(-1)!, gun: gun ?? turret?.guns.at(-1) ?? tank.turrets.at(-1)!.guns.at(-1)!, }; }); }} /> ); }