diff --git a/packages/i18n/src/unwrapper.ts b/packages/i18n/src/unwrapper.ts index 3f155b352..d063bef17 100644 --- a/packages/i18n/src/unwrapper.ts +++ b/packages/i18n/src/unwrapper.ts @@ -2,7 +2,11 @@ import locales from "@blitzkit/i18n/locales.json"; import { I18nString } from "@blitzkit/protos"; export function unwrapper(locale: string) { - return function (i18nString: I18nString) { + return function (i18nString?: I18nString) { + if (i18nString === undefined) { + throw new Error("i18nString is undefined"); + } + if (locale in i18nString.locales) { return i18nString.locales[locale]; } diff --git a/packages/protos/src/blitzkit/equipment_definitions.proto b/packages/protos/src/blitzkit/equipment_definitions.proto index ba4cf0cb4..fcd46bb19 100644 --- a/packages/protos/src/blitzkit/equipment_definitions.proto +++ b/packages/protos/src/blitzkit/equipment_definitions.proto @@ -1,4 +1,4 @@ -syntax = "proto2"; +syntax = "proto3"; package blitzkit; @@ -10,8 +10,8 @@ message EquipmentDefinitions { } message Equipment { - required I18nString name = 1; - required I18nString description = 2; + I18nString name = 1; + I18nString description = 2; } message EquipmentPreset { @@ -19,6 +19,5 @@ message EquipmentPreset { } message EquipmentSlot { - required uint32 left = 1; - required uint32 right = 2; + repeated uint32 options = 1; } \ No newline at end of file diff --git a/packages/website/src/components/TankopediaLoadout/index.tsx b/packages/website/src/components/TankopediaLoadout/index.tsx index 2c0ef6e9f..22b214d3e 100644 --- a/packages/website/src/components/TankopediaLoadout/index.tsx +++ b/packages/website/src/components/TankopediaLoadout/index.tsx @@ -1,30 +1,38 @@ -import type { Consumable } from "@blitzkit/core"; -import { TrashIcon } from "@radix-ui/react-icons"; +import type { Consumable, EquipmentSlot } from "@blitzkit/protos"; +import { ClockIcon, ResetIcon, TrashIcon } from "@radix-ui/react-icons"; +import { chunk } from "lodash-es"; +import { api } from "../../api/dynamic"; +import { equipmentColumns } from "../../config/equipment"; import { useConsumables } from "../../hooks/useConsumables"; -import { useProtagonistGun } from "../../hooks/useProtagonistGun"; -import { useProtagonistTank } from "../../hooks/useProtagonistTank"; +import { DuelModule, useDuel } from "../../hooks/useDuel"; +import { useEquipmentPreset } from "../../hooks/useEquipmentPreset"; import { useStrings } from "../../hooks/useStrings"; import { useTankCompatibility } from "../../hooks/useTankCompatibility"; +import { useUnwrapper } from "../../hooks/useUnwrapper"; import { Tankopedia } from "../../stores/tankopedia"; import { hasUpgrades } from "../../tankopedia/hasUpgrades"; import { vehicleStatusKeys } from "../../tankopedia/tankState"; import type { ComputedCharacteristics } from "../../types/characteristics"; +import { Button } from "../Button"; import { Heading } from "../Heading"; import { IconButton } from "../IconButton"; +import { Text } from "../Text"; import { Tooltip } from "../Tooltip"; import styles from "./index.module.css"; +const equipment = await api.equipment(); + interface TankopediaLoadoutProps { characteristics: ComputedCharacteristics; } export function TankopediaLoadout({ characteristics }: TankopediaLoadoutProps) { - const tank = useProtagonistTank(); + const tank = useDuel("protagonist", DuelModule.Tank); const showModules = hasUpgrades(tank); return ( <> - {showModules && } + {/* {showModules && } */} @@ -120,8 +128,8 @@ interface ConsumablesProps { function Consumables({ characteristics }: ConsumablesProps) { const strings = useStrings(); const consumables = useConsumables(); - const tank = useProtagonistTank(); - const gun = useProtagonistGun(); + const tank = useDuel("protagonist", DuelModule.Tank); + const gun = useDuel("protagonist", DuelModule.Gun); const isCompatible = useTankCompatibility(tank, gun); return ( @@ -148,7 +156,7 @@ function Consumables({ characteristics }: ConsumablesProps) { } return ( - + ); })} @@ -161,12 +169,12 @@ interface ConsumableProps { consumable: Consumable; } -function Consumable({ id, consumable }: ConsumableProps) { +function ConsumableEntry({ id, consumable }: ConsumableProps) { const isSelected = Tankopedia.use((state) => state.protagonist.consumables.includes(id), ); - const tank = useProtagonistTank(); - const unwrap = useUnwrap(); + const tank = useDuel("protagonist", DuelModule.Tank); + const unwrap = useUnwrapper(); return (
@@ -207,15 +215,15 @@ function Consumable({ id, consumable }: ConsumableProps) { - + {/* */}
); } function Equipment() { const strings = useStrings(); - const tank = useProtagonistTank(); - const equipment = useEquipment(tank.tank!); + const tank = useDuel("protagonist", DuelModule.Tank); + const equipment = useEquipmentPreset(tank.equipment_preset); return (
@@ -237,7 +245,7 @@ function Equipment() {
- {chunk(equipment.preset.slots, equipmentColumns).map((chunk, index) => ( + {chunk(equipment.slots, equipmentColumns).map((chunk, index) => ( ))}
@@ -246,7 +254,7 @@ function Equipment() { } interface EquipmentRowProps { - chunk: BlitzStaticEquipmentPresetComponent_EquipmentSlot[]; + chunk: EquipmentSlot[]; rowIndex: number; } @@ -254,7 +262,7 @@ function EquipmentRow({ chunk, rowIndex }: EquipmentRowProps) { return (
{chunk.map((slot, index) => ( -
- {slot.options_catalog_i_ds.map((id, index) => ( + {slot.options.map((id, index) => ( - + {/* */}
); } @@ -307,11 +319,14 @@ function EquipmentOption({ columnIndex, }: EquipmentOptionProps) { const equipmentIndex = rowIndex * equipmentColumns + columnIndex; - const tank = useProtagonistTank(); - const equipment = useEquipment(tank.tank!); - const slot = equipment.preset.slots[equipmentIndex]; - const id = slot.options_catalog_i_ds[optionIndex]; - const gameStrings = useGameStrings("EquipmentEntity"); + + const tank = useDuel("protagonist", DuelModule.Tank); + const equipmentPreset = useEquipmentPreset(tank.equipment_preset); + const unwrap = useUnwrapper(); + + const slot = equipmentPreset.slots[equipmentIndex]; + const id = slot.options[optionIndex]; + const specificEquipment = equipment.equipments[id]; const isSelected = Tankopedia.use( (state) => @@ -320,13 +335,13 @@ function EquipmentOption({ ); return ( - + - +// +// {isAlternativeLine(lineName) +// ? strings.tanks.loadout.alternative +// : romanize(stage.number)} +// +// +// - {} -
- ); -} +// {} +// +// ); +// } diff --git a/packages/website/src/components/TankopediaSandbox/index.tsx b/packages/website/src/components/TankopediaSandbox/index.tsx index b866debe5..595647e86 100644 --- a/packages/website/src/components/TankopediaSandbox/index.tsx +++ b/packages/website/src/components/TankopediaSandbox/index.tsx @@ -10,8 +10,6 @@ import { modelTransformEvent } from "../../core/blitzkit/modelTransform"; import { Pose, poseEvent } from "../../core/blitzkit/pose"; import { useEquipment } from "../../hooks/useEquipment"; import { useModel } from "../../hooks/useModel"; -import { useProtagonistGun } from "../../hooks/useProtagonistGun"; -import { useProtagonistTank } from "../../hooks/useProtagonistTank"; import { useProtagonistTurret } from "../../hooks/useProtagonistTurret"; import { Tankopedia } from "../../stores/tankopedia"; import { TankopediaPersistent } from "../../stores/tankopediaPersistent"; @@ -44,8 +42,8 @@ export const TankopediaSandbox = forwardRef< const hasImprovedVerticalStabilizer = useEquipment(122); const hasDownImprovedVerticalStabilizer = useEquipment(124); - const tank = useProtagonistTank(); - const gun = useProtagonistGun(); + const tank = useDuel("protagonist", DuelModule.Tank); + const gun = useDuel("protagonist", DuelModule.Gun); const turret = useProtagonistTurret(); const model = Tankopedia.use((state) => state.protagonist.model); diff --git a/packages/website/src/config/equipment.ts b/packages/website/src/config/equipment.ts new file mode 100644 index 000000000..fdc0f23ca --- /dev/null +++ b/packages/website/src/config/equipment.ts @@ -0,0 +1 @@ +export const equipmentColumns = 3; diff --git a/packages/website/src/hooks/useEquipment.ts b/packages/website/src/hooks/useEquipment.ts index b0005e97a..ecd36e196 100644 --- a/packages/website/src/hooks/useEquipment.ts +++ b/packages/website/src/hooks/useEquipment.ts @@ -7,7 +7,7 @@ const tanks = await api.tanks(); export type DuelSide = "protagonist" | "antagonist"; -export function useEquipment(id: number, side: DuelSide) { +export function useEquipment(side: DuelSide, id: number) { const member = Tankopedia.use((state) => state[side]); const tank = tanks.tanks[member.tank]; const preset = equipment.presets[tank.equipment_preset]; diff --git a/packages/website/src/hooks/useEquipmentPreset.ts b/packages/website/src/hooks/useEquipmentPreset.ts index b29271fd9..3b45c6264 100644 --- a/packages/website/src/hooks/useEquipmentPreset.ts +++ b/packages/website/src/hooks/useEquipmentPreset.ts @@ -1,7 +1,7 @@ import { api } from "../api/dynamic"; -const equipmentDefinitions = await api.equipment(); +const equipment = await api.equipment(); export function useEquipmentPreset(preset: string) { - return equipmentDefinitions.presets[preset]; + return equipment.presets[preset]; } diff --git a/packages/website/src/tankopedia/createTankState.ts b/packages/website/src/tankopedia/createTankState.ts index f2aa0fa36..71050b488 100644 --- a/packages/website/src/tankopedia/createTankState.ts +++ b/packages/website/src/tankopedia/createTankState.ts @@ -13,12 +13,6 @@ const models = await api.models(); const provisions = await api.provisions(); const scripts = await api.scripts(); -export const genericDefaultEquipmentMatrix: EquipmentMatrix = [ - [-1, 1, -1], - [0, 0, 0], - [0, 0, 0], -]; - export function createTankState(tank: TankDefinition) { const turret = tank.turrets.at(-1)!; const gun = turret.guns.at(-1)!; @@ -35,7 +29,7 @@ export function createTankState(tank: TankDefinition) { assault_distance: (gun.assault_ranges?.ranges[0].distance ?? 0) / 2, speed: 0, - equipment_matrix: genericDefaultEquipmentMatrix, + equipment: {}, status: createTankStatus(), model: models.models[turret.id], diff --git a/packages/website/src/tankopedia/tankState.ts b/packages/website/src/tankopedia/tankState.ts index 43cc4cb0b..8ac07265b 100644 --- a/packages/website/src/tankopedia/tankState.ts +++ b/packages/website/src/tankopedia/tankState.ts @@ -1,5 +1,4 @@ -import type { ModelDefinition } from "@blitzkit/core"; -import type { EquipmentMatrix } from "./createTankState"; +import type { ModelDefinition } from "@blitzkit/protos"; export interface TankState { tank: number; @@ -13,7 +12,7 @@ export interface TankState { assault_distance: number; speed: number; - equipment_matrix: EquipmentMatrix; + equipment: Record; status: Record; model: ModelDefinition;