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