This commit is contained in:
tresabhi committed 2026-08-04 14:02:52 -05:00
1 parent 1a7a1223d5
commit 33ebbbeb65
39 files changed
+153 -208

No files matched your search

@@ -1,4 +1,4 @@
import { BlitzTankClass, SkillDefinitions, TankClass } from "@blitzkit/core"; import { BlitzTankClass, SkillDefinitions } from "@blitzkit/core";
import { Cache } from "./0_base"; import { Cache } from "./0_base";
import { ServerBlitzKitAPI7 } from "./7_provisionDefinitions"; import { ServerBlitzKitAPI7 } from "./7_provisionDefinitions";
@@ -9,10 +9,7 @@ export abstract class ServerBlitzKitAPI8 extends ServerBlitzKitAPI7 {
const skillDefinitions = SkillDefinitions.create(); const skillDefinitions = SkillDefinitions.create();
for (const tankClass in this.tankmenAvatar!.root.skillsByClasses) { for (const tankClass in this.tankmenAvatar!.root.skillsByClasses) {
const skills = const skills = this.tankmenAvatar!.root.skillsByClasses[tankClass];
this.tankmenAvatar!.root.skillsByClasses[
Number(tankClass) as TankClass
];
skillDefinitions.classes[ skillDefinitions.classes[
this.blitzTankClassToBlitzkit[tankClass as BlitzTankClass] this.blitzTankClassToBlitzkit[tankClass as BlitzTankClass]
+1 -3
View File
@@ -1,8 +1,6 @@
import { TankClass } from "@blitzkit/core";
export interface TankmenAvatar { export interface TankmenAvatar {
roles: unknown; roles: unknown;
skillsByClasses: Record<TankClass, string>; skillsByClasses: Record<string, string>;
skills: { skills: {
[name: string]: { [name: string]: {
userString: string; userString: string;
@@ -1,14 +1,14 @@
import { asset, permanentSkills, romanize } from '@blitzkit/core'; import { permanentSkills, romanize } from "@blitzkit/core";
import { Flex } from '@radix-ui/themes'; import { Flex } from "@radix-ui/themes";
import { awaitableSkillDefinitions } from '../core/awaitables/skillDefinitions'; import { api } from "../core/blitzkit/api";
import { GenericTankComponentButton } from './ModuleButtons/GenericTankComponentButton'; import { GenericTankComponentButton } from "./ModuleButtons/GenericTankComponentButton";
interface CrewSkillManagerProps { interface CrewSkillManagerProps {
skillLevels: Record<string, number>; skillLevels: Record<string, number>;
onChange?: (skillLevels: Record<string, number>) => void; onChange?: (skillLevels: Record<string, number>) => void;
} }
const skillDefinitions = await awaitableSkillDefinitions; const skillDefinitions = await api.skillDefinitions();
export function CrewSkillManager({ export function CrewSkillManager({
skillLevels, skillLevels,
@@ -27,7 +27,7 @@ export function CrewSkillManager({
special={!permanentSkills.includes(skill)} special={!permanentSkills.includes(skill)}
selected={level > 0} selected={level > 0}
discriminator={level === 0 ? undefined : romanize(level)} discriminator={level === 0 ? undefined : romanize(level)}
icon={asset(`icons/skills/${skill}.webp`)} icon={`/api/icons/skills/${skill}.webp`}
onClick={(event) => { onClick={(event) => {
if (!onChange) return; if (!onChange) return;
@@ -1,7 +1,6 @@
import { asset } from "@blitzkit/core";
import { ClockIcon, ReloadIcon } from "@radix-ui/react-icons"; import { ClockIcon, ReloadIcon } from "@radix-ui/react-icons";
import { Flex, Text } from "@radix-ui/themes"; import { Flex, Text } from "@radix-ui/themes";
import { awaitableConsumableDefinitions } from "../../core/awaitables/consumableDefinitions"; import { api } from "../../core/blitzkit/api";
import { useDelta } from "../../hooks/useDelta"; import { useDelta } from "../../hooks/useDelta";
import { useLocale } from "../../hooks/useLocale"; import { useLocale } from "../../hooks/useLocale";
import { GenericTankComponentButton } from "./GenericTankComponentButton"; import { GenericTankComponentButton } from "./GenericTankComponentButton";
@@ -13,7 +12,7 @@ interface ConsumableButtonProps extends TankComponentButtonProps {
cooldown?: number; cooldown?: number;
} }
const consumableDefinitions = await awaitableConsumableDefinitions; const consumableDefinitions = await api.consumableDefinitions();
export function ConsumableButton({ export function ConsumableButton({
consumable, consumable,
@@ -29,7 +28,7 @@ export function ConsumableButton({
<GenericTankComponentButton <GenericTankComponentButton
style={{ width: "6rem" }} style={{ width: "6rem" }}
tooltip={unwrap(consumableDefinitions.consumables[consumable].name!)} tooltip={unwrap(consumableDefinitions.consumables[consumable].name!)}
icon={asset(`icons/consumables/${consumable}.webp`)} icon={`/api/icons/consumables/${consumable}.webp`}
{...props} {...props}
> >
{(cooldown || duration) && ( {(cooldown || duration) && (
@@ -1,5 +1,4 @@
import { asset } from "@blitzkit/core"; import { api } from "../../core/blitzkit/api";
import { awaitableEquipmentDefinitions } from "../../core/awaitables/equipmentDefinitions";
import { useLocale } from "../../hooks/useLocale"; import { useLocale } from "../../hooks/useLocale";
import { GenericTankComponentButton } from "./GenericTankComponentButton"; import { GenericTankComponentButton } from "./GenericTankComponentButton";
import type { TankComponentButtonProps } from "./TankComponentButton"; import type { TankComponentButtonProps } from "./TankComponentButton";
@@ -8,7 +7,7 @@ interface EquipmentButtonProps extends TankComponentButtonProps {
equipment: number; equipment: number;
} }
const equipmentDefinitions = await awaitableEquipmentDefinitions; const equipmentDefinitions = await api.equipmentDefinitions();
export function EquipmentButton({ equipment, ...props }: EquipmentButtonProps) { export function EquipmentButton({ equipment, ...props }: EquipmentButtonProps) {
const { unwrap } = useLocale(); const { unwrap } = useLocale();
@@ -16,7 +15,7 @@ export function EquipmentButton({ equipment, ...props }: EquipmentButtonProps) {
return ( return (
<GenericTankComponentButton <GenericTankComponentButton
tooltip={unwrap(equipmentDefinitions.equipments[equipment].name!)} tooltip={unwrap(equipmentDefinitions.equipments[equipment].name!)}
icon={asset(`icons/equipment/${equipment}.webp`)} icon={`/api/icons/equipment/${equipment}.webp`}
{...props} {...props}
/> />
); );
@@ -1,5 +1,4 @@
import { asset } from "@blitzkit/core"; import { api } from "../../core/blitzkit/api";
import { awaitableProvisionDefinitions } from "../../core/awaitables/provisionDefinitions";
import { useLocale } from "../../hooks/useLocale"; import { useLocale } from "../../hooks/useLocale";
import { GenericTankComponentButton } from "./GenericTankComponentButton"; import { GenericTankComponentButton } from "./GenericTankComponentButton";
import type { TankComponentButtonProps } from "./TankComponentButton"; import type { TankComponentButtonProps } from "./TankComponentButton";
@@ -8,7 +7,7 @@ interface ProvisionButtonProps extends TankComponentButtonProps {
provision: number; provision: number;
} }
const provisionDefinitions = await awaitableProvisionDefinitions; const provisionDefinitions = await api.provisionDefinitions();
export function ProvisionButton({ provision, ...props }: ProvisionButtonProps) { export function ProvisionButton({ provision, ...props }: ProvisionButtonProps) {
const { unwrap } = useLocale(); const { unwrap } = useLocale();
@@ -16,7 +15,7 @@ export function ProvisionButton({ provision, ...props }: ProvisionButtonProps) {
return ( return (
<GenericTankComponentButton <GenericTankComponentButton
tooltip={unwrap(provisionDefinitions.provisions[provision].name!)} tooltip={unwrap(provisionDefinitions.provisions[provision].name!)}
icon={asset(`icons/provisions/${provision}.webp`)} icon={`/api/icons/provisions/${provision}.webp`}
{...props} {...props}
/> />
); );
@@ -1,5 +1,5 @@
import { Flex } from "@radix-ui/themes"; import { Flex } from "@radix-ui/themes";
import { awaitableProvisionDefinitions } from "../core/awaitables/provisionDefinitions"; import { api } from "../core/blitzkit/api";
import { ProvisionButton } from "./ModuleButtons/ProvisionButton"; import { ProvisionButton } from "./ModuleButtons/ProvisionButton";
interface ProvisionsManagerProps { interface ProvisionsManagerProps {
@@ -9,7 +9,7 @@ interface ProvisionsManagerProps {
onChange?: (provisions: number[]) => void; onChange?: (provisions: number[]) => void;
} }
const provisionDefinitions = await awaitableProvisionDefinitions; const provisionDefinitions = await api.provisionDefinitions();
export function ProvisionsManager({ export function ProvisionsManager({
provisions, provisions,
@@ -1,15 +1,16 @@
import { assertSecret, fetchTankDefinitions } from "@blitzkit/core"; import { assertSecret } from "@blitzkit/core";
import { MinusCircledIcon } from "@radix-ui/react-icons"; import { MinusCircledIcon } from "@radix-ui/react-icons";
import { Callout, Flex } from "@radix-ui/themes"; import { Callout, Flex } from "@radix-ui/themes";
import { uniq } from "lodash-es"; import { uniq } from "lodash-es";
import { useEffect } from "react"; import { useEffect } from "react";
import { api } from "../../core/blitzkit/api";
import { Duel } from "../../stores/duel"; import { Duel } from "../../stores/duel";
import { TankopediaPersistent } from "../../stores/tankopediaPersistent"; import { TankopediaPersistent } from "../../stores/tankopediaPersistent";
import { AesonPlug } from "../AesonPlug"; import { AesonPlug } from "../AesonPlug";
import { ExperimentIcon } from "../ExperimentIcon"; import { ExperimentIcon } from "../ExperimentIcon";
import { MAX_RECENTLY_VIEWED } from "../TankSearch/constants"; import { MAX_RECENTLY_VIEWED } from "../TankSearch/constants";
const tankDefinitions = await fetchTankDefinitions(); const tankDefinitions = await api.tankDefinitions();
export function CalloutsSection() { export function CalloutsSection() {
const tank = Duel.use((state) => state.protagonist.tank); const tank = Duel.use((state) => state.protagonist.tank);
@@ -3,7 +3,7 @@ import { literals } from "@blitzkit/i18n";
import { AccessibilityIcon, InfoCircledIcon } from "@radix-ui/react-icons"; import { AccessibilityIcon, InfoCircledIcon } from "@radix-ui/react-icons";
import { Flex, Heading, IconButton, Popover, Text } from "@radix-ui/themes"; import { Flex, Heading, IconButton, Popover, Text } from "@radix-ui/themes";
import { Fragment } from "react/jsx-runtime"; import { Fragment } from "react/jsx-runtime";
import { awaitableProvisionDefinitions } from "../../../../../../core/awaitables/provisionDefinitions"; import { api } from "../../../../../../core/blitzkit/api";
import { useEquipment } from "../../../../../../hooks/useEquipment"; import { useEquipment } from "../../../../../../hooks/useEquipment";
import { useLocale } from "../../../../../../hooks/useLocale"; import { useLocale } from "../../../../../../hooks/useLocale";
import { Duel } from "../../../../../../stores/duel"; import { Duel } from "../../../../../../stores/duel";
@@ -11,7 +11,7 @@ import { InfoWithDelta } from "./InfoWithDelta";
import { StatsTableWrapper } from "./StatsTableWrapper"; import { StatsTableWrapper } from "./StatsTableWrapper";
import type { StatsAcceptorProps } from "./TraverseVisualizer"; import type { StatsAcceptorProps } from "./TraverseVisualizer";
const provisionDefinitions = await awaitableProvisionDefinitions; const provisionDefinitions = await api.provisionDefinitions();
export function Crew({ stats }: StatsAcceptorProps) { export function Crew({ stats }: StatsAcceptorProps) {
const tank = Duel.use((state) => state.protagonist.tank); const tank = Duel.use((state) => state.protagonist.tank);
@@ -1,4 +1,4 @@
import { asset, isExplosive } from "@blitzkit/core"; import { isExplosive } from "@blitzkit/core";
import { literals } from "@blitzkit/i18n"; import { literals } from "@blitzkit/i18n";
import { Flex, Heading, IconButton, Tooltip } from "@radix-ui/themes"; import { Flex, Heading, IconButton, Tooltip } from "@radix-ui/themes";
import { useLocale } from "../../../../../../hooks/useLocale"; import { useLocale } from "../../../../../../hooks/useLocale";
@@ -62,7 +62,7 @@ export function Firepower({
alt={unwrap(thisShell.name!)} alt={unwrap(thisShell.name!)}
width={16} width={16}
height={16} height={16}
src={asset(`icons/shells/${thisShell.icon}.webp`)} src={`/api/icons/shells/${thisShell.icon}.webp`}
/> />
</IconButton> </IconButton>
</Tooltip> </Tooltip>
@@ -1,7 +1,7 @@
import type { QuicklimeEvent } from "quicklime"; import type { QuicklimeEvent } from "quicklime";
import { useEffect, useRef } from "react"; import { useEffect, useRef } from "react";
import type { Group } from "three"; import type { Group } from "three";
import { awaitableModelDefinitions } from "../../../../../../../../core/awaitables/modelDefinitions"; import { api } from "../../../../../../../../core/blitzkit/api";
import { import {
modelTransformEvent, modelTransformEvent,
type ModelTransformEventData, type ModelTransformEventData,
@@ -9,7 +9,7 @@ import {
import { Duel } from "../../../../../../../../stores/duel"; import { Duel } from "../../../../../../../../stores/duel";
import { ModelChunk } from "./ModelChunk"; import { ModelChunk } from "./ModelChunk";
const modelDefinitions = await awaitableModelDefinitions; const modelDefinitions = await api.modelDefinitions();
export function CanvasContent() { export function CanvasContent() {
const hullWrapper = useRef<Group>(null); const hullWrapper = useRef<Group>(null);
@@ -1,11 +1,11 @@
import { mauveDark } from "@radix-ui/colors"; import { mauveDark } from "@radix-ui/colors";
import { LineBasicMaterial, MeshBasicMaterial } from "three"; import { LineBasicMaterial, MeshBasicMaterial } from "three";
import { awaitableModelDefinitions } from "../../../../../../../../core/awaitables/modelDefinitions"; import { api } from "../../../../../../../../core/blitzkit/api";
import { jsxTree } from "../../../../../../../../core/blitzkit/jsxTree"; import { jsxTree } from "../../../../../../../../core/blitzkit/jsxTree";
import { useModel } from "../../../../../../../../hooks/useModel"; import { useModel } from "../../../../../../../../hooks/useModel";
import { Duel } from "../../../../../../../../stores/duel"; import { Duel } from "../../../../../../../../stores/duel";
const modelDefinitions = await awaitableModelDefinitions; const modelDefinitions = await api.modelDefinitions();
const surfaceMaterial: Record<Props["only"], MeshBasicMaterial> = { const surfaceMaterial: Record<Props["only"], MeshBasicMaterial> = {
gun: new MeshBasicMaterial({ gun: new MeshBasicMaterial({
@@ -3,11 +3,11 @@ import { Box, Card, Flex } from "@radix-ui/themes";
import { clamp } from "lodash-es"; import { clamp } from "lodash-es";
import { useRef, useState } from "react"; import { useRef, useState } from "react";
import { degToRad, radToDeg } from "three/src/math/MathUtils.js"; import { degToRad, radToDeg } from "three/src/math/MathUtils.js";
import { awaitableModelDefinitions } from "../../../../../../../core/awaitables/modelDefinitions";
import { import {
DEFAULT_PITCH_TRANSITION, DEFAULT_PITCH_TRANSITION,
applyPitchYawLimits, applyPitchYawLimits,
} from "../../../../../../../core/blitz/applyPitchYawLimits"; } from "../../../../../../../core/blitz/applyPitchYawLimits";
import { api } from "../../../../../../../core/blitzkit/api";
import { hasEquipment } from "../../../../../../../core/blitzkit/hasEquipment"; import { hasEquipment } from "../../../../../../../core/blitzkit/hasEquipment";
import { modelTransformEvent } from "../../../../../../../core/blitzkit/modelTransform"; import { modelTransformEvent } from "../../../../../../../core/blitzkit/modelTransform";
import { Var } from "../../../../../../../core/radix/var"; import { Var } from "../../../../../../../core/radix/var";
@@ -20,7 +20,7 @@ import { FlexibilityCanvas } from "./components/FlexibilityCanvas";
const ANGLE_COEFFICIENT = 1 / 10; const ANGLE_COEFFICIENT = 1 / 10;
const modelDefinition = await awaitableModelDefinitions; const modelDefinition = await api.modelDefinitions();
function mag(x: number) { function mag(x: number) {
return (1 / Math.PI) * Math.atan(ANGLE_COEFFICIENT * x) + 1 / 2; return (1 / Math.PI) * Math.atan(ANGLE_COEFFICIENT * x) + 1 / 2;
@@ -2,11 +2,7 @@ import { createDefaultSkills } from "@blitzkit/core";
import { Flex, Progress, Text } from "@radix-ui/themes"; import { Flex, Progress, Text } from "@radix-ui/themes";
import { clamp } from "lodash-es"; import { clamp } from "lodash-es";
import { memo, useMemo, type ComponentProps, type ReactNode } from "react"; import { memo, useMemo, type ComponentProps, type ReactNode } from "react";
import { awaitableEquipmentDefinitions } from "../../../../../../core/awaitables/equipmentDefinitions"; import { api } from "../../../../../../core/blitzkit/api";
import { awaitableModelDefinitions } from "../../../../../../core/awaitables/modelDefinitions";
import { awaitableProvisionDefinitions } from "../../../../../../core/awaitables/provisionDefinitions";
import { awaitableSkillDefinitions } from "../../../../../../core/awaitables/skillDefinitions";
import { awaitableTankDefinitions } from "../../../../../../core/awaitables/tankDefinitions";
import { import {
tankCharacteristics, tankCharacteristics,
type TankCharacteristics, type TankCharacteristics,
@@ -41,11 +37,11 @@ const [
modelDefinitions, modelDefinitions,
skillDefinitions, skillDefinitions,
] = await Promise.all([ ] = await Promise.all([
awaitableTankDefinitions, api.tankDefinitions(),
awaitableProvisionDefinitions, api.provisionDefinitions(),
awaitableEquipmentDefinitions, api.equipmentDefinitions(),
awaitableModelDefinitions, api.modelDefinitions(),
awaitableSkillDefinitions, api.skillDefinitions(),
]); ]);
export const InfoWithDelta = memo<InfoWithDeltaProps>( export const InfoWithDelta = memo<InfoWithDeltaProps>(
@@ -1,4 +1,3 @@
import { asset } from "@blitzkit/core";
import { Flex, IconButton, Tooltip } from "@radix-ui/themes"; import { Flex, IconButton, Tooltip } from "@radix-ui/themes";
import { useLocale } from "../../../../../../../../hooks/useLocale"; import { useLocale } from "../../../../../../../../hooks/useLocale";
import { Duel } from "../../../../../../../../stores/duel"; import { Duel } from "../../../../../../../../stores/duel";
@@ -38,7 +37,7 @@ export function ShellSwitcher() {
<img <img
alt={unwrap(thisShell.name!)} alt={unwrap(thisShell.name!)}
style={{ width: "1.125rem", height: "1.125rem" }} style={{ width: "1.125rem", height: "1.125rem" }}
src={asset(`icons/shells/${thisShell.icon}.webp`)} src={`/api/icons/shells/${thisShell.icon}.webp`}
/> />
</IconButton> </IconButton>
</Tooltip> </Tooltip>
@@ -1,4 +1,4 @@
import { asset, isExplosive } from "@blitzkit/core"; import { isExplosive } from "@blitzkit/core";
import { literals } from "@blitzkit/i18n"; import { literals } from "@blitzkit/i18n";
import { Box, Flex, Text } from "@radix-ui/themes"; import { Box, Flex, Text } from "@radix-ui/themes";
import { useRef, useState } from "react"; import { useRef, useState } from "react";
@@ -124,7 +124,7 @@ export function RicochetVisualizer({ stats }: StatsAcceptorProps) {
/> />
<img <img
src={asset(`icons/shells/${shell.icon}.webp`)} src={`/api/icons/shells/${shell.icon}.webp`}
style={{ style={{
objectFit: "contain", objectFit: "contain",
transform: "translate(-50%, -50%) rotate(-45deg)", transform: "translate(-50%, -50%) rotate(-45deg)",
@@ -1,8 +1,7 @@
import { Flex } from "@radix-ui/themes"; import { Flex } from "@radix-ui/themes";
import { useEffect } from "react"; import { useEffect } from "react";
import { awaitableEquipmentDefinitions } from "../../../../../core/awaitables/equipmentDefinitions";
import { awaitableProvisionDefinitions } from "../../../../../core/awaitables/provisionDefinitions";
import { applyPitchYawLimits } from "../../../../../core/blitz/applyPitchYawLimits"; import { applyPitchYawLimits } from "../../../../../core/blitz/applyPitchYawLimits";
import { api } from "../../../../../core/blitzkit/api";
import { modelTransformEvent } from "../../../../../core/blitzkit/modelTransform"; import { modelTransformEvent } from "../../../../../core/blitzkit/modelTransform";
import { tankCharacteristics } from "../../../../../core/blitzkit/tankCharacteristics"; import { tankCharacteristics } from "../../../../../core/blitzkit/tankCharacteristics";
import { useEquipment } from "../../../../../hooks/useEquipment"; import { useEquipment } from "../../../../../hooks/useEquipment";
@@ -16,8 +15,8 @@ import { Maneuverability } from "./components/Maneuverability";
import { Survivability } from "./components/Survivability"; import { Survivability } from "./components/Survivability";
const [equipmentDefinitions, provisionDefinitions] = await Promise.all([ const [equipmentDefinitions, provisionDefinitions] = await Promise.all([
awaitableEquipmentDefinitions, api.equipmentDefinitions(),
awaitableProvisionDefinitions, api.provisionDefinitions(),
]); ]);
export function Characteristics({ skeleton }: MaybeSkeletonComponentProps) { export function Characteristics({ skeleton }: MaybeSkeletonComponentProps) {
@@ -8,29 +8,29 @@ import {
Popover, Popover,
Text, Text,
} from "@radix-ui/themes"; } from "@radix-ui/themes";
import { awaitableConsumableDefinitions } from "../../../../core/awaitables/consumableDefinitions"; import { api } from "../../../../core/blitzkit/api";
import { useEquipment } from "../../../../hooks/useEquipment"; import { useEquipment } from "../../../../hooks/useEquipment";
import { useLocale } from "../../../../hooks/useLocale"; import { useLocale } from "../../../../hooks/useLocale";
import { Duel } from "../../../../stores/duel"; import { Duel } from "../../../../stores/duel";
import { ConsumablesManager } from "../../../ConsumablesManager"; import { ConsumablesManager } from "../../../ConsumablesManager";
import { ConfigurationChildWrapper } from "./ConfigurationChildWrapper"; import { ConfigurationChildWrapper } from "./ConfigurationChildWrapper";
const consumableDefinitions = await awaitableConsumableDefinitions; const consumableDefinitions = await api.consumableDefinitions();
export function Consumables() { export function Consumables() {
const protagonist = Duel.use((state) => state.protagonist); const protagonist = Duel.use((state) => state.protagonist);
const consumables = Duel.use((state) => state.protagonist.consumables); const consumables = Duel.use((state) => state.protagonist.consumables);
const consumablesList = Object.values( const consumablesList = Object.values(
consumableDefinitions.consumables consumableDefinitions.consumables,
).filter((consumable) => ).filter((consumable) =>
checkConsumableProvisionInclusivity( checkConsumableProvisionInclusivity(
consumable, consumable,
protagonist.tank, protagonist.tank,
protagonist.gun protagonist.gun,
) ),
); );
const cooldownBooster = Duel.use( const cooldownBooster = Duel.use(
(state) => state.protagonist.cooldownBooster (state) => state.protagonist.cooldownBooster,
); );
const hasConsumableDeliverySystem = useEquipment(118); const hasConsumableDeliverySystem = useEquipment(118);
const hasHighEndConsumables = useEquipment(101); const hasHighEndConsumables = useEquipment(101);
@@ -1,15 +1,4 @@
import { asset } from "@blitzkit/core"; import { Badge, Box, Flex, Heading, Switch, Text } from "@radix-ui/themes";
import { InfoCircledIcon } from "@radix-ui/react-icons";
import {
Badge,
Box,
Flex,
Heading,
Link,
Popover,
Switch,
Text,
} from "@radix-ui/themes";
import { useLocale } from "../../../../hooks/useLocale"; import { useLocale } from "../../../../hooks/useLocale";
import { Duel } from "../../../../stores/duel"; import { Duel } from "../../../../stores/duel";
import { Tankopedia } from "../../../../stores/tankopedia"; import { Tankopedia } from "../../../../stores/tankopedia";
@@ -44,7 +33,7 @@ export function Equalizer() {
style={{ style={{
cursor: "pointer", cursor: "pointer",
borderRadius: "var(--radius-3)", borderRadius: "var(--radius-3)",
backgroundImage: `url(${asset("icons/game_mode_banners/45.webp")})`, backgroundImage: "url(/api/icons/game_mode_banners/45.webp)",
backgroundSize: "cover", backgroundSize: "cover",
backgroundPosition: "center", backgroundPosition: "center",
overflow: "hidden", overflow: "hidden",
@@ -1,18 +1,18 @@
import { Button, Flex, Heading } from "@radix-ui/themes"; import { Button, Flex, Heading } from "@radix-ui/themes";
import { awaitableEquipmentDefinitions } from "../../../../core/awaitables/equipmentDefinitions"; import { api } from "../../../../core/blitzkit/api";
import { useLocale } from "../../../../hooks/useLocale"; import { useLocale } from "../../../../hooks/useLocale";
import { Duel } from "../../../../stores/duel"; import { Duel } from "../../../../stores/duel";
import { EquipmentManager } from "../../../EquipmentManager"; import { EquipmentManager } from "../../../EquipmentManager";
import { ConfigurationChildWrapper } from "./ConfigurationChildWrapper"; import { ConfigurationChildWrapper } from "./ConfigurationChildWrapper";
const equipmentDefinitions = await awaitableEquipmentDefinitions; const equipmentDefinitions = await api.equipmentDefinitions();
export function Equipment() { export function Equipment() {
const protagonist = Duel.use((state) => state.protagonist); const protagonist = Duel.use((state) => state.protagonist);
const equipmentPreset = const equipmentPreset =
equipmentDefinitions.presets[protagonist.tank.equipment_preset]; equipmentDefinitions.presets[protagonist.tank.equipment_preset];
const equipmentMatrix = Duel.use( const equipmentMatrix = Duel.use(
(state) => state.protagonist.equipmentMatrix (state) => state.protagonist.equipmentMatrix,
); );
const { strings } = useLocale(); const { strings } = useLocale();
@@ -1,4 +1,3 @@
import { asset } from "@blitzkit/core";
import { Flex, Heading } from "@radix-ui/themes"; import { Flex, Heading } from "@radix-ui/themes";
import { useLocale } from "../../../../hooks/useLocale"; import { useLocale } from "../../../../hooks/useLocale";
import { Duel } from "../../../../stores/duel"; import { Duel } from "../../../../stores/duel";
@@ -8,7 +7,7 @@ import { ConfigurationChildWrapper } from "./ConfigurationChildWrapper";
export function Miscellaneous() { export function Miscellaneous() {
const camouflage = Duel.use((state) => state.protagonist.camouflage); const camouflage = Duel.use((state) => state.protagonist.camouflage);
const cooldownBooster = Duel.use( const cooldownBooster = Duel.use(
(state) => state.protagonist.cooldownBooster (state) => state.protagonist.cooldownBooster,
); );
const { tank } = Duel.use((state) => state.protagonist); const { tank } = Duel.use((state) => state.protagonist);
const { strings } = useLocale(); const { strings } = useLocale();
@@ -22,7 +21,7 @@ export function Miscellaneous() {
<Flex gap="2" align="center"> <Flex gap="2" align="center">
{!tank.fixed_camouflage && ( {!tank.fixed_camouflage && (
<GenericTankComponentButton <GenericTankComponentButton
icon={asset("icons/camo.webp")} icon={"/api/icons/camo.webp"}
selected={camouflage} selected={camouflage}
iconStyles={{ iconStyles={{
top: "50%", top: "50%",
@@ -37,7 +36,7 @@ export function Miscellaneous() {
/> />
)} )}
<GenericTankComponentButton <GenericTankComponentButton
icon={asset("icons/boosters/equipment.webp")} icon={"/api/icons/boosters/equipment.webp"}
selected={cooldownBooster > 0} selected={cooldownBooster > 0}
banner={ banner={
cooldownBooster === 0 cooldownBooster === 0
@@ -1,5 +1,4 @@
import { import {
asset,
EngineDefinition, EngineDefinition,
formatCompact, formatCompact,
GunDefinition, GunDefinition,
@@ -20,7 +19,7 @@ import {
Text, Text,
Tooltip, Tooltip,
} from "@radix-ui/themes"; } from "@radix-ui/themes";
import { awaitableTankDefinitions } from "../../../../core/awaitables/tankDefinitions"; import { api } from "../../../../core/blitzkit/api";
import { useLocale } from "../../../../hooks/useLocale"; import { useLocale } from "../../../../hooks/useLocale";
import { Duel } from "../../../../stores/duel"; import { Duel } from "../../../../stores/duel";
import { LinkI18n } from "../../../LinkI18n"; import { LinkI18n } from "../../../LinkI18n";
@@ -111,7 +110,7 @@ function ModuleButton({
<img <img
alt={unlock.cost!.type} alt={unlock.cost!.type}
src={asset(`icons/currencies/${unlock.cost!.type}.webp`)} src={`/api/icons/currencies/${unlock.cost!.type}.webp`}
style={{ style={{
width: 12, width: 12,
height: 12, height: 12,
@@ -126,7 +125,7 @@ function ModuleButton({
src={ src={
isTank isTank
? tankIcon(unlock.id) ? tankIcon(unlock.id)
: asset(`icons/modules/${moduleTypeTypeIconName[unlock.type]}.webp`) : `/api/icons/modules/${moduleTypeTypeIconName[unlock.type]}.webp`
} }
style={{ style={{
width: isTank ? 64 : 32, width: isTank ? 64 : 32,
@@ -153,7 +152,7 @@ function ModuleButton({
return <Tooltip content={tooltip}>{node}</Tooltip>; return <Tooltip content={tooltip}>{node}</Tooltip>;
} }
const tankDefinitions = await awaitableTankDefinitions; const tankDefinitions = await api.tankDefinitions();
export function Modules() { export function Modules() {
const tank = Duel.use((state) => state.protagonist.tank); const tank = Duel.use((state) => state.protagonist.tank);
@@ -1,12 +1,12 @@
import { availableProvisions } from "@blitzkit/core"; import { availableProvisions } from "@blitzkit/core";
import { Button, Flex, Heading } from "@radix-ui/themes"; import { Button, Flex, Heading } from "@radix-ui/themes";
import { awaitableProvisionDefinitions } from "../../../../core/awaitables/provisionDefinitions"; import { api } from "../../../../core/blitzkit/api";
import { useLocale } from "../../../../hooks/useLocale"; import { useLocale } from "../../../../hooks/useLocale";
import { Duel } from "../../../../stores/duel"; import { Duel } from "../../../../stores/duel";
import { ProvisionsManager } from "../../../ProvisionsManager"; import { ProvisionsManager } from "../../../ProvisionsManager";
import { ConfigurationChildWrapper } from "./ConfigurationChildWrapper"; import { ConfigurationChildWrapper } from "./ConfigurationChildWrapper";
const provisionDefinitions = await awaitableProvisionDefinitions; const provisionDefinitions = await api.provisionDefinitions();
export function Provisions() { export function Provisions() {
const { tank, gun } = Duel.use((state) => state.protagonist); const { tank, gun } = Duel.use((state) => state.protagonist);
@@ -1,16 +1,13 @@
import { asset } from "@blitzkit/core";
import { Box, Flex, Heading, Text } from "@radix-ui/themes"; import { Box, Flex, Heading, Text } from "@radix-ui/themes";
import { awaitableConsumableDefinitions } from "../../core/awaitables/consumableDefinitions"; import { api } from "../../core/blitzkit/api";
import { awaitableGameDefinitions } from "../../core/awaitables/gameDefinitions";
import { awaitableProvisionDefinitions } from "../../core/awaitables/provisionDefinitions";
import { useLocale } from "../../hooks/useLocale"; import { useLocale } from "../../hooks/useLocale";
import { Duel } from "../../stores/duel"; import { Duel } from "../../stores/duel";
const [gameDefinitions, consumableDefinitions, provisionDefinitions] = const [gameDefinitions, consumableDefinitions, provisionDefinitions] =
await Promise.all([ await Promise.all([
awaitableGameDefinitions, api.gameDefinitions(),
awaitableConsumableDefinitions, api.consumableDefinitions(),
awaitableProvisionDefinitions, api.provisionDefinitions(),
]); ]);
export function GameModeSection() { export function GameModeSection() {
@@ -40,9 +37,7 @@ export function GameModeSection() {
direction="column" direction="column"
style={{ style={{
borderRadius: "var(--radius-3)", borderRadius: "var(--radius-3)",
background: `url(${asset( background: `url(/api/icons/game_mode_banners/${id}.webp)`,
`icons/game_mode_banners/${id}.webp`,
)})`,
backgroundSize: "cover", backgroundSize: "cover",
backgroundPosition: "center", backgroundPosition: "center",
}} }}
@@ -50,9 +45,7 @@ export function GameModeSection() {
<Box <Box
flexGrow="1" flexGrow="1"
style={{ style={{
background: `url(${asset( background: `url(/api/icons/game_mode_banners/${id}.webp)`,
`icons/game_mode_banners/${id}.webp`,
)})`,
backgroundSize: "cover", backgroundSize: "cover",
backgroundPosition: "center", backgroundPosition: "center",
}} }}
@@ -87,7 +80,7 @@ export function GameModeSection() {
height: "1.5em", height: "1.5em",
objectFit: "contain", objectFit: "contain",
}} }}
src={asset(`icons/provisions/${id}.webp`)} src={`/api/icons/provisions/${id}.webp`}
alt={unwrap(provisions.name!)} alt={unwrap(provisions.name!)}
/> />
{unwrap(provisions.name!)} {unwrap(provisions.name!)}
@@ -108,7 +101,7 @@ export function GameModeSection() {
height: "1.5em", height: "1.5em",
objectFit: "contain", objectFit: "contain",
}} }}
src={asset(`icons/consumables/${id}.webp`)} src={`/api/icons/consumables/${id}.webp`}
alt={unwrap(consumable.name!)} alt={unwrap(consumable.name!)}
/> />
{unwrap(consumable.name!)} {unwrap(consumable.name!)}
@@ -1,5 +1,4 @@
import { import {
asset,
resolvePenetrationCoefficient, resolvePenetrationCoefficient,
TIER_ROMAN_NUMERALS, TIER_ROMAN_NUMERALS,
uniqueGuns, uniqueGuns,
@@ -140,7 +139,7 @@ export function Options({ thicknessRange, canvas, skeleton }: OptionsProps) {
<img <img
alt="Antagonist Gun" alt="Antagonist Gun"
src={asset("icons/modules/gun.webp")} src={"/api/icons/modules/gun.webp"}
style={{ style={{
width: "65%", width: "65%",
height: "65%", height: "65%",
@@ -209,7 +208,7 @@ export function Options({ thicknessRange, canvas, skeleton }: OptionsProps) {
> >
<img <img
alt={unwrap(thisShell.name!)} alt={unwrap(thisShell.name!)}
src={asset(`icons/shells/${thisShell.icon}.webp`)} src={`/api/icons/shells/${thisShell.icon}.webp`}
style={{ style={{
width: "50%", width: "50%",
height: "50%", height: "50%",
@@ -246,7 +245,7 @@ export function Options({ thicknessRange, canvas, skeleton }: OptionsProps) {
> >
<img <img
alt="Calibrated Shells" alt="Calibrated Shells"
src={asset("icons/equipment/103.webp")} src={"/api/icons/equipment/103.webp"}
style={{ style={{
width: "50%", width: "50%",
height: "50%", height: "50%",
@@ -271,7 +270,7 @@ export function Options({ thicknessRange, canvas, skeleton }: OptionsProps) {
> >
<img <img
alt="Enhanced Armor" alt="Enhanced Armor"
src={asset("icons/equipment/110.webp")} src={"/api/icons/equipment/110.webp"}
style={{ style={{
width: "50%", width: "50%",
height: "50%", height: "50%",
@@ -5,8 +5,8 @@ import type { QuicklimeEvent } from "quicklime";
import { useEffect, useRef } from "react"; import { useEffect, useRef } from "react";
import { PerspectiveCamera, Vector3 } from "three"; import { PerspectiveCamera, Vector3 } from "three";
import { OrbitControls as OrbitControlsClass } from "three-stdlib"; import { OrbitControls as OrbitControlsClass } from "three-stdlib";
import { awaitableModelDefinitions } from "../../../../../../core/awaitables/modelDefinitions";
import { applyPitchYawLimits } from "../../../../../../core/blitz/applyPitchYawLimits"; import { applyPitchYawLimits } from "../../../../../../core/blitz/applyPitchYawLimits";
import { api } from "../../../../../../core/blitzkit/api";
import { hasEquipment } from "../../../../../../core/blitzkit/hasEquipment"; import { hasEquipment } from "../../../../../../core/blitzkit/hasEquipment";
import { Pose, poseEvent } from "../../../../../../core/blitzkit/pose"; import { Pose, poseEvent } from "../../../../../../core/blitzkit/pose";
import { controlsEnabledEvent } from "../../../../../../core/controlsEnabled"; import { controlsEnabledEvent } from "../../../../../../core/controlsEnabled";
@@ -21,7 +21,7 @@ const poseDistances: Record<Pose, number> = {
const inspectModeInitialPosition = new Vector3(-8, 2, -13); const inspectModeInitialPosition = new Vector3(-8, 2, -13);
const modelDefinitions = await awaitableModelDefinitions; const modelDefinitions = await api.modelDefinitions();
interface ControlsProps { interface ControlsProps {
autoRotate?: boolean; autoRotate?: boolean;
@@ -1,11 +1,11 @@
import { useEffect } from "react"; import { useEffect } from "react";
import { degToRad } from "three/src/math/MathUtils.js"; import { degToRad } from "three/src/math/MathUtils.js";
import { awaitableModelDefinitions } from "../../../../../../core/awaitables/modelDefinitions";
import { applyPitchYawLimits } from "../../../../../../core/blitz/applyPitchYawLimits"; import { applyPitchYawLimits } from "../../../../../../core/blitz/applyPitchYawLimits";
import { api } from "../../../../../../core/blitzkit/api";
import { modelTransformEvent } from "../../../../../../core/blitzkit/modelTransform"; import { modelTransformEvent } from "../../../../../../core/blitzkit/modelTransform";
import { Duel } from "../../../../../../stores/duel"; import { Duel } from "../../../../../../stores/duel";
const modelDefinitions = await awaitableModelDefinitions; const modelDefinitions = await api.modelDefinitions();
export function InitialAligner() { export function InitialAligner() {
const tank = Duel.use((state) => state.protagonist.tank); const tank = Duel.use((state) => state.protagonist.tank);
@@ -1,7 +1,7 @@
import { Box, Flex } from "@radix-ui/themes"; import { Box, Flex } from "@radix-ui/themes";
import { times } from "lodash-es"; import { times } from "lodash-es";
import { useEffect, useMemo, useRef } from "react"; import { useEffect, useMemo, useRef } from "react";
import { awaitableTankDefinitions } from "../../../core/awaitables/tankDefinitions"; import { api } from "../../../core/blitzkit/api";
import { defaultEqualizer } from "../../../core/blitzkit/tankToDuelMember"; import { defaultEqualizer } from "../../../core/blitzkit/tankToDuelMember";
import { useFullScreen } from "../../../hooks/useFullScreen"; import { useFullScreen } from "../../../hooks/useFullScreen";
import { Duel } from "../../../stores/duel"; import { Duel } from "../../../stores/duel";
@@ -12,7 +12,7 @@ import { Options } from "./components/Options";
import { TankSandbox } from "./components/TankSandbox"; import { TankSandbox } from "./components/TankSandbox";
import { Title } from "./components/TankSandbox/Title"; import { Title } from "./components/TankSandbox/Title";
const tankDefinitions = await awaitableTankDefinitions; const tankDefinitions = await api.tankDefinitions();
export function HeroSection({ skeleton }: MaybeSkeletonComponentProps) { export function HeroSection({ skeleton }: MaybeSkeletonComponentProps) {
const equalize = Duel.use((state) => state.equalize); const equalize = Duel.use((state) => state.equalize);
@@ -1,9 +1,4 @@
import { import { TankPriceType, TankType, TIER_ROMAN_NUMERALS } from "@blitzkit/core";
asset,
TankPriceType,
TankType,
TIER_ROMAN_NUMERALS,
} from "@blitzkit/core";
import { Box, Flex } from "@radix-ui/themes"; import { Box, Flex } from "@radix-ui/themes";
import { Var } from "../../../core/radix/var"; import { Var } from "../../../core/radix/var";
import { useLocale } from "../../../hooks/useLocale"; import { useLocale } from "../../../hooks/useLocale";
@@ -40,7 +35,7 @@ export function MetaSection() {
> >
<Box <Box
style={{ style={{
background: `url(${asset(`flags/scratched/${protagonist.nation}.webp`)})`, background: `url(${`/api/flags/scratched/${protagonist.nation}.webp`})`,
backgroundRepeat: "no-repeat", backgroundRepeat: "no-repeat",
backgroundSize: "min(53rem, 80vw)", backgroundSize: "min(53rem, 80vw)",
backgroundPosition: "-8rem 50%", backgroundPosition: "-8rem 50%",
@@ -65,7 +60,7 @@ export function MetaSection() {
<img <img
style={{ width: "1em", height: "1em" }} style={{ width: "1em", height: "1em" }}
alt={protagonist.nation} alt={protagonist.nation}
src={asset(`flags/circle/${protagonist.nation}.webp`)} src={`/api/flags/circle/${protagonist.nation}.webp`}
/> />
{ {
strings.common.nations[ strings.common.nations[
@@ -135,7 +130,7 @@ export function MetaSection() {
<img <img
style={{ width: "1em", height: "1em" }} style={{ width: "1em", height: "1em" }}
alt="gold" alt="gold"
src={asset("icons/currencies/gold.webp")} src={"/api/icons/currencies/gold.webp"}
/> />
</Flex> </Flex>
</Listing> </Listing>
@@ -152,14 +147,12 @@ export function MetaSection() {
<img <img
style={{ width: "1em", height: "1em" }} style={{ width: "1em", height: "1em" }}
alt={TankPriceType[protagonist.price!.type]} alt={TankPriceType[protagonist.price!.type]}
src={asset( src={`/api/icons/currencies/${
`icons/currencies/${ protagonist.price!.type ===
protagonist.price!.type === TankPriceType.TANK_PRICE_TYPE_GOLD
TankPriceType.TANK_PRICE_TYPE_GOLD ? "gold"
? "gold" : "silver"
: "silver" }.webp`}
}.webp`,
)}
/> />
</Flex> </Flex>
</Listing> </Listing>
@@ -169,14 +162,12 @@ export function MetaSection() {
<img <img
style={{ width: "1em", height: "1em" }} style={{ width: "1em", height: "1em" }}
alt={TankPriceType[protagonist.price!.type]} alt={TankPriceType[protagonist.price!.type]}
src={asset( src={`/api/icons/currencies/${
`icons/currencies/${ protagonist.price!.type ===
protagonist.price!.type === TankPriceType.TANK_PRICE_TYPE_GOLD
TankPriceType.TANK_PRICE_TYPE_GOLD ? "gold"
? "gold" : "silver"
: "silver" }.webp`}
}.webp`,
)}
/> />
</Flex> </Flex>
</Listing> </Listing>
@@ -192,7 +183,7 @@ export function MetaSection() {
<img <img
style={{ width: "1em", height: "1em" }} style={{ width: "1em", height: "1em" }}
alt="xp" alt="xp"
src={asset("icons/currencies/xp.webp")} src={"/api/icons/currencies/xp.webp"}
/> />
</Flex> </Flex>
</Listing> </Listing>
@@ -1,8 +1,8 @@
import { asset, formatCompact, TIER_ROMAN_NUMERALS } from "@blitzkit/core"; import { formatCompact, TIER_ROMAN_NUMERALS } from "@blitzkit/core";
import { literals } from "@blitzkit/i18n/src/literals"; import { literals } from "@blitzkit/i18n/src/literals";
import { Box, Flex, Skeleton, Text } from "@radix-ui/themes"; import { Box, Flex, Skeleton, Text } from "@radix-ui/themes";
import { awaitableAverageDefinitions } from "../../../../core/awaitables/averageDefinitions"; import { awaitableAverageDefinitions } from "../../../../core/awaitables/averageDefinitions";
import { awaitableTankDefinitions } from "../../../../core/awaitables/tankDefinitions"; import { api } from "../../../../core/blitzkit/api";
import { useLocale } from "../../../../hooks/useLocale"; import { useLocale } from "../../../../hooks/useLocale";
import { Tankopedia } from "../../../../stores/tankopedia"; import { Tankopedia } from "../../../../stores/tankopedia";
import type { MaybeSkeletonComponentProps } from "../../../../types/maybeSkeletonComponentProps"; import type { MaybeSkeletonComponentProps } from "../../../../types/maybeSkeletonComponentProps";
@@ -15,7 +15,7 @@ type NodeProps = MaybeSkeletonComponentProps & {
}; };
const [tankDefinitions, averageDefinitions] = await Promise.all([ const [tankDefinitions, averageDefinitions] = await Promise.all([
awaitableTankDefinitions, api.tankDefinitions(),
awaitableAverageDefinitions, awaitableAverageDefinitions,
]); ]);
@@ -58,7 +58,7 @@ export function Node({ id, highlight, nextIds, skeleton }: NodeProps) {
mx={highlight ? "2" : "0"} mx={highlight ? "2" : "0"}
style={{ style={{
background: highlight background: highlight
? `url(${asset(`flags/fade_small/${tank.nation}.webp`)})` ? `url(${`/api/flags/fade/${tank.nation}.webp`})`
: undefined, : undefined,
backgroundPosition: "center", backgroundPosition: "center",
backgroundSize: "cover", backgroundSize: "cover",
@@ -1,9 +1,9 @@
import { asset, TankType } from "@blitzkit/core"; import { TankType } from "@blitzkit/core";
import { literals } from "@blitzkit/i18n/src/literals"; import { literals } from "@blitzkit/i18n/src/literals";
import { CaretLeftIcon, CaretRightIcon, PlusIcon } from "@radix-ui/react-icons"; import { CaretLeftIcon, CaretRightIcon, PlusIcon } from "@radix-ui/react-icons";
import { Flex, Heading, IconButton, ScrollArea, Text } from "@radix-ui/themes"; import { Flex, Heading, IconButton, ScrollArea, Text } from "@radix-ui/themes";
import { Fragment, useEffect, useMemo, useRef, useState } from "react"; import { Fragment, useEffect, useMemo, useRef, useState } from "react";
import { awaitableTankDefinitions } from "../../../core/awaitables/tankDefinitions"; import { api } from "../../../core/blitzkit/api";
import { useLocale } from "../../../hooks/useLocale"; import { useLocale } from "../../../hooks/useLocale";
import { Duel } from "../../../stores/duel"; import { Duel } from "../../../stores/duel";
import { Tankopedia } from "../../../stores/tankopedia"; import { Tankopedia } from "../../../stores/tankopedia";
@@ -13,7 +13,7 @@ import { Node } from "./components/Node";
type Line = number[]; type Line = number[];
const tankDefinitions = await awaitableTankDefinitions; const tankDefinitions = await api.tankDefinitions();
export const XP_MULTIPLIERS = [1, 2, 3, 4, 5, 10]; export const XP_MULTIPLIERS = [1, 2, 3, 4, 5, 10];
@@ -105,7 +105,7 @@ export function TechTreeSection({ skeleton }: MaybeSkeletonComponentProps) {
<Flex gap="1" align="center"> <Flex gap="1" align="center">
<img <img
alt="XP" alt="XP"
src={asset("icons/currencies/xp.webp")} src={"/api/icons/currencies/xp.webp"}
style={{ style={{
width: "1em", width: "1em",
height: "1em", height: "1em",
@@ -1,3 +0,0 @@
import { fetchEquipmentDefinitions } from '@blitzkit/core';
export const awaitableEquipmentDefinitions = fetchEquipmentDefinitions();
@@ -1,3 +0,0 @@
import { fetchSkillDefinitions } from '@blitzkit/core';
export const awaitableSkillDefinitions = fetchSkillDefinitions();
@@ -1,7 +1,7 @@
import type { EquipmentMatrix } from '../../stores/duel'; import type { EquipmentMatrix } from "../../stores/duel";
import { awaitableEquipmentDefinitions } from '../awaitables/equipmentDefinitions'; import { api } from "./api";
const equipmentDefinitions = await awaitableEquipmentDefinitions; const equipmentDefinitions = await api.equipmentDefinitions();
export function hasEquipment( export function hasEquipment(
id: number, id: number,
@@ -16,7 +16,7 @@ export function hasEquipment(
if (choice === 0) return false; if (choice === 0) return false;
const equipped = slot[choice === -1 ? 'left' : 'right']; const equipped = slot[choice === -1 ? "left" : "right"];
return equipped === id; return equipped === id;
}); });
+7 -7
View File
@@ -1,17 +1,17 @@
import { useMemo } from 'react'; import { useMemo } from "react";
import { awaitableEquipmentDefinitions } from '../core/awaitables/equipmentDefinitions'; import { api } from "../core/blitzkit/api";
import { Duel } from '../stores/duel'; import { Duel } from "../stores/duel";
const equipmentDefinitions = await awaitableEquipmentDefinitions; const equipmentDefinitions = await api.equipmentDefinitions();
export function useEquipment(id: number, antagonist = false) { export function useEquipment(id: number, antagonist = false) {
const member = Duel.use( const member = Duel.use(
(state) => state[antagonist ? 'antagonist' : 'protagonist']!, (state) => state[antagonist ? "antagonist" : "protagonist"]!,
); );
const preset = equipmentDefinitions.presets[member.tank.equipment_preset]; const preset = equipmentDefinitions.presets[member.tank.equipment_preset];
const equipmentMatrix = Duel.use( const equipmentMatrix = Duel.use(
(state) => (state) =>
state[antagonist ? 'antagonist' : 'protagonist']!.equipmentMatrix, state[antagonist ? "antagonist" : "protagonist"]!.equipmentMatrix,
); );
const value = useMemo(() => { const value = useMemo(() => {
return preset.slots.some((slot, index) => { return preset.slots.some((slot, index) => {
@@ -21,7 +21,7 @@ export function useEquipment(id: number, antagonist = false) {
if (choice === 0) return false; if (choice === 0) return false;
const equipped = slot[choice === -1 ? 'left' : 'right']; const equipped = slot[choice === -1 ? "left" : "right"];
return equipped === id; return equipped === id;
}); });
@@ -1,23 +1,22 @@
import { TankType } from "@blitzkit/core"; import { TankType } from "@blitzkit/core";
import { PageWrapper } from "../../../../components/PageWrapper"; import { PageWrapper } from "../../../../../components/PageWrapper";
import { CalloutsSection } from "../../../../components/Tankopedia/CalloutsSection"; import { CalloutsSection } from "../../../../../components/Tankopedia/CalloutsSection";
import { CharacteristicsSection } from "../../../../components/Tankopedia/CharacteristicsSection"; import { CharacteristicsSection } from "../../../../../components/Tankopedia/CharacteristicsSection";
import { GameModeSection } from "../../../../components/Tankopedia/GameModeSection"; import { GameModeSection } from "../../../../../components/Tankopedia/GameModeSection";
import { GuideSection } from "../../../../components/Tankopedia/GuideSection"; import { GuideSection } from "../../../../../components/Tankopedia/GuideSection";
import { HeroSection } from "../../../../components/Tankopedia/HeroSection"; import { HeroSection } from "../../../../../components/Tankopedia/HeroSection";
import { MetaSection } from "../../../../components/Tankopedia/MetaSection"; import { MetaSection } from "../../../../../components/Tankopedia/MetaSection";
import { TechTreeSection } from "../../../../components/Tankopedia/TechTreeSection"; import { TechTreeSection } from "../../../../../components/Tankopedia/TechTreeSection";
import { VideoSection } from "../../../../components/Tankopedia/VideoSection"; import { VideoSection } from "../../../../../components/Tankopedia/VideoSection";
import { awaitableModelDefinitions } from "../../../../core/awaitables/modelDefinitions"; import { api } from "../../../../../core/blitzkit/api";
import { awaitableTankDefinitions } from "../../../../core/awaitables/tankDefinitions";
import { import {
LocaleProvider, LocaleProvider,
type LocaleAcceptorProps, type LocaleAcceptorProps,
} from "../../../../hooks/useLocale"; } from "../../../../../hooks/useLocale";
import { Duel } from "../../../../stores/duel"; import { Duel } from "../../../../../stores/duel";
import { Tankopedia } from "../../../../stores/tankopedia"; import { Tankopedia } from "../../../../../stores/tankopedia";
import type { MaybeSkeletonComponentProps } from "../../../../types/maybeSkeletonComponentProps"; import type { MaybeSkeletonComponentProps } from "../../../../../types/maybeSkeletonComponentProps";
import type { TankGuide } from "../../../../types/tankGuide"; import type { TankGuide } from "../../../../../types/tankGuide";
type PageProps = MaybeSkeletonComponentProps & type PageProps = MaybeSkeletonComponentProps &
LocaleAcceptorProps & { LocaleAcceptorProps & {
@@ -26,8 +25,8 @@ type PageProps = MaybeSkeletonComponentProps &
}; };
const [tankDefinitions, modelDefinitions] = await Promise.all([ const [tankDefinitions, modelDefinitions] = await Promise.all([
awaitableTankDefinitions, api.tankDefinitions(),
awaitableModelDefinitions, api.modelDefinitions(),
]); ]);
export function Page({ id, skeleton, locale, guide }: PageProps) { export function Page({ id, skeleton, locale, guide }: PageProps) {
@@ -2,30 +2,25 @@
import { AstroSeo } from "@astrolib/seo"; import { AstroSeo } from "@astrolib/seo";
import { import {
assertSecret, assertSecret,
asset,
createDefaultProvisions, createDefaultProvisions,
createDefaultSkills, createDefaultSkills,
fetchEquipmentDefinitions,
fetchModelDefinitions,
fetchProvisionDefinitions,
fetchSkillDefinitions,
fetchTankDefinitions,
TIER_ROMAN_NUMERALS, TIER_ROMAN_NUMERALS,
} from "@blitzkit/core"; } from "@blitzkit/core";
import { unwrapper } from "@blitzkit/i18n"; import { unwrapper } from "@blitzkit/i18n";
import { literals } from "@blitzkit/i18n/src/literals"; import { literals } from "@blitzkit/i18n/src/literals";
import type { GetStaticPaths } from "astro"; import type { GetStaticPaths } from "astro";
import { load } from "cheerio"; import { load } from "cheerio";
import { tankCharacteristics } from "../../../../core/blitzkit/tankCharacteristics"; import { api } from "../../../../../core/blitzkit/api";
import { getStrings } from "../../../../core/i18n/getStrings"; import { tankCharacteristics } from "../../../../../core/blitzkit/tankCharacteristics";
import BaseLayout from "../../../../layouts/BaseLayout.astro"; import { getStrings } from "../../../../../core/i18n/getStrings";
import { genericDefaultEquipmentMatrix } from "../../../../stores/duel/constants"; import BaseLayout from "../../../../../layouts/BaseLayout.astro";
import type { TankGuide } from "../../../../types/tankGuide"; import { genericDefaultEquipmentMatrix } from "../../../../../stores/duel/constants";
import type { TankGuide } from "../../../../../types/tankGuide";
import { getStaticPaths as parentGetStaticPaths } from "../index.astro"; import { getStaticPaths as parentGetStaticPaths } from "../index.astro";
import { Page } from "./_index"; import { Page } from "./_index";
export const getStaticPaths = (async () => { export const getStaticPaths = (async () => {
const tankDefinitions = await fetchTankDefinitions(); const tankDefinitions = await api.tankDefinitions();
const parentPaths = parentGetStaticPaths(); const parentPaths = parentGetStaticPaths();
return Object.values(tankDefinitions.tanks) return Object.values(tankDefinitions.tanks)
@@ -40,11 +35,11 @@ export const getStaticPaths = (async () => {
const { id, locale } = Astro.props; const { id, locale } = Astro.props;
const strings = getStrings(locale); const strings = getStrings(locale);
const tankDefinitions = await fetchTankDefinitions(); const tankDefinitions = await api.tankDefinitions();
const skillDefinitions = await fetchSkillDefinitions(); const skillDefinitions = await api.skillDefinitions();
const provisionDefinitions = await fetchProvisionDefinitions(); const provisionDefinitions = await api.provisionDefinitions();
const equipmentDefinitions = await fetchEquipmentDefinitions(); const equipmentDefinitions = await api.equipmentDefinitions();
const tankModelDefinitions = await fetchModelDefinitions(); const tankModelDefinitions = await api.modelDefinitions();
const tank = tankDefinitions.tanks[id]; const tank = tankDefinitions.tanks[id];
const tankModelDefinition = tankModelDefinitions.models[tank.id]; const tankModelDefinition = tankModelDefinitions.models[tank.id];
@@ -61,7 +56,7 @@ const title = literals(strings.website.tools.tankopedia.tank_seo_title, {
}); });
const url = import.meta.env.SITE + Astro.url.pathname; const url = import.meta.env.SITE + Astro.url.pathname;
const icon = asset(`icons/tanks/big/${id}.webp`); const icon = `/api/tanks/${id}/icons/big.webp`;
const turret = tank.turrets.at(-1)!; const turret = tank.turrets.at(-1)!;
const gun = turret.guns.at(-1)!; const gun = turret.guns.at(-1)!;
const shell = gun.shells[0]; const shell = gun.shells[0];
+2 -2
View File
@@ -8,7 +8,7 @@ import {
type TurretDefinition, type TurretDefinition,
} from "@blitzkit/core"; } from "@blitzkit/core";
import { Varuna } from "varuna"; import { Varuna } from "varuna";
import { awaitableProvisionDefinitions } from "../../core/awaitables/provisionDefinitions"; import { api } from "../../core/blitzkit/api";
import { tankToDuelMember } from "../../core/blitzkit/tankToDuelMember"; import { tankToDuelMember } from "../../core/blitzkit/tankToDuelMember";
type EquipmentMatrixItem = -1 | 0 | 1; type EquipmentMatrixItem = -1 | 0 | 1;
@@ -44,7 +44,7 @@ export interface DuelStore {
equalize: boolean; equalize: boolean;
} }
const provisionDefinitions = await awaitableProvisionDefinitions; const provisionDefinitions = await api.provisionDefinitions();
export const Duel = new Varuna< export const Duel = new Varuna<
DuelStore, DuelStore,
+2 -2
View File
@@ -8,7 +8,7 @@ import { Varuna } from "varuna";
import type { ArmorType } from "../components/Armor/components/SpacedArmorScene"; import type { ArmorType } from "../components/Armor/components/SpacedArmorScene";
import type { ExternalModuleVariant } from "../components/Armor/components/SpacedArmorSceneComponent"; import type { ExternalModuleVariant } from "../components/Armor/components/SpacedArmorSceneComponent";
import type { XP_MULTIPLIERS } from "../components/Tankopedia/TechTreeSection"; import type { XP_MULTIPLIERS } from "../components/Tankopedia/TechTreeSection";
import { awaitableSkillDefinitions } from "../core/awaitables/skillDefinitions"; import { api } from "../core/blitzkit/api";
import { TankopediaDisplay } from "./tankopediaPersistent/constants"; import { TankopediaDisplay } from "./tankopediaPersistent/constants";
export interface ShotLayerBase { export interface ShotLayerBase {
@@ -105,7 +105,7 @@ interface Tankopedia {
statSearch?: string; statSearch?: string;
} }
const skillDefinitions = await awaitableSkillDefinitions; const skillDefinitions = await api.skillDefinitions();
export const Tankopedia = new Varuna<Tankopedia, ModelDefinition>((model) => ({ export const Tankopedia = new Varuna<Tankopedia, ModelDefinition>((model) => ({
disturbed: false, disturbed: false,