diff --git a/packages/core/src/blitzkit/api/server/5_equipments.ts b/packages/core/src/blitzkit/api/server/5_equipments.ts index 1fc1d3289..e7c0b6053 100644 --- a/packages/core/src/blitzkit/api/server/5_equipments.ts +++ b/packages/core/src/blitzkit/api/server/5_equipments.ts @@ -1,4 +1,4 @@ -import { EquipmentDefinitions, EquipmentSlot } from "@blitzkit/core"; +import { EquipmentDefinitions, EquipmentSlot } from "@blitzkit/protos"; import { Cache } from "./0_base"; import { ServerBlitzKitAPI4 } from "./4_maps"; diff --git a/packages/website/src/components/Armor/components/PrimaryArmorScene.tsx b/packages/website/src/components/Armor/components/PrimaryArmorScene.tsx index 144240a11..b937f2c51 100644 --- a/packages/website/src/components/Armor/components/PrimaryArmorScene.tsx +++ b/packages/website/src/components/Armor/components/PrimaryArmorScene.tsx @@ -4,9 +4,7 @@ import { correctZYTuple } from "../../../core/blitz/correctZYTuple"; import { nameToArmorId } from "../../../core/blitzkit/nameToArmorId"; import { resolveArmor } from "../../../core/blitzkit/resolveThickness"; import { useArmor } from "../../../hooks/useArmor"; -import { useTankModelDefinition } from "../../../hooks/useTankModelDefinition"; -import { useTankTransform } from "../../../hooks/useTankTransform"; -import { Duel } from "../../../stores/duel"; +import { DuelModule, useDuel } from "../../../hooks/useDuel"; import { ModelTankWrapper } from "./ModelTankWrapper"; import { PrimaryArmorSceneComponent } from "./PrimaryArmorSceneComponent"; @@ -14,10 +12,10 @@ export const PrimaryArmorScene = memo(() => { const wrapper = useRef(null); const turretContainer = useRef(null!); const gunContainer = useRef(null!); - const tank = Duel.use((state) => state.protagonist.tank); - const track = Duel.use((state) => state.protagonist.track); - const turret = Duel.use((state) => state.protagonist.turret); - const gun = Duel.use((state) => state.protagonist.gun); + const tank = useDuel("protagonist", DuelModule.Tank); + const track = useDuel("protagonist", DuelModule.Track); + const turret = useDuel("protagonist", DuelModule.Turret); + const gun = useDuel("protagonist", DuelModule.Gun); const armorGltf = useArmor(tank.id).gltf; const armorNodes = Object.values(armorGltf.nodes); const tankModelDefinition = useTankModelDefinition(); diff --git a/packages/website/src/hooks/useDuel.ts b/packages/website/src/hooks/useDuel.ts new file mode 100644 index 000000000..b04077e2b --- /dev/null +++ b/packages/website/src/hooks/useDuel.ts @@ -0,0 +1,74 @@ +import type { + EngineDefinition, + GunDefinition, + ShellDefinition, + TankDefinition, + TrackDefinition, + TurretDefinition, +} from "@blitzkit/protos"; +import { api } from "../api/dynamic"; +import { Tankopedia } from "../stores/tankopedia"; +import type { DuelSide } from "./useEquipment"; + +export enum DuelModule { + Tank, + Track, + Engine, + Turret, + Gun, + Shell, +} + +const tanks = await api.tanks(); + +export function useDuel( + side: DuelSide, + module: DuelModule.Tank, +): TankDefinition; +export function useDuel( + side: DuelSide, + module: DuelModule.Track, +): TrackDefinition; +export function useDuel( + side: DuelSide, + module: DuelModule.Engine, +): EngineDefinition; +export function useDuel( + side: DuelSide, + module: DuelModule.Turret, +): TurretDefinition; +export function useDuel(side: DuelSide, module: DuelModule.Gun): GunDefinition; +export function useDuel( + side: DuelSide, + module: DuelModule.Shell, +): ShellDefinition; + +export function useDuel(side: DuelSide, module: DuelModule) { + const tankId = Tankopedia.use((state) => state[side].tank); + const tank = tanks.tanks[tankId]; + + if (module === DuelModule.Tank) return tank; + + if (module === DuelModule.Track) { + const trackId = Tankopedia.use((state) => state[side].track); + return tank.tracks.find((track) => track.id === trackId)!; + } + + if (module === DuelModule.Engine) { + const engineId = Tankopedia.use((state) => state[side].engine); + return tank.engines.find((engine) => engine.id === engineId)!; + } + + const turretId = Tankopedia.use((state) => state[side].turret); + const turret = tank.turrets.find((turret) => turret.id === turretId)!; + + if (module === DuelModule.Turret) return turret; + + const gunId = Tankopedia.use((state) => state[side].gun); + const gun = turret.guns.find((gun) => gun.id === gunId)!; + + if (module === DuelModule.Gun) return gun; + + const shellId = Tankopedia.use((state) => state[side].shell); + return gun.shells.find((shell) => shell.id === shellId)!; +} diff --git a/packages/website/src/hooks/useEquipment.ts b/packages/website/src/hooks/useEquipment.ts index ab222f5f5..b0005e97a 100644 --- a/packages/website/src/hooks/useEquipment.ts +++ b/packages/website/src/hooks/useEquipment.ts @@ -1,18 +1,20 @@ import { useMemo } from "react"; import { api } from "../api/dynamic"; -import { Duel } from "../stores/duel"; +import { Tankopedia } from "../stores/tankopedia"; -const equipmentDefinitions = await api.equipment(); +const equipment = await api.equipment(); +const tanks = await api.tanks(); -export function useEquipment(id: number, antagonist = false) { - const member = Duel.use( - (state) => state[antagonist ? "antagonist" : "protagonist"]!, - ); - const preset = equipmentDefinitions.presets[member.tank.equipment_preset]; - const equipmentMatrix = Duel.use( - (state) => - state[antagonist ? "antagonist" : "protagonist"]!.equipmentMatrix, +export type DuelSide = "protagonist" | "antagonist"; + +export function useEquipment(id: number, side: DuelSide) { + const member = Tankopedia.use((state) => state[side]); + const tank = tanks.tanks[member.tank]; + const preset = equipment.presets[tank.equipment_preset]; + const equipmentMatrix = Tankopedia.use( + (state) => state[side].equipment_matrix, ); + const value = useMemo(() => { return preset.slots.some((slot, index) => { const row = Math.floor(index / 3); diff --git a/packages/website/src/hooks/useProtagonistGun.ts b/packages/website/src/hooks/useProtagonistGun.ts deleted file mode 100644 index 3b41d8203..000000000 --- a/packages/website/src/hooks/useProtagonistGun.ts +++ /dev/null @@ -1,8 +0,0 @@ -import { Tankopedia } from "../stores/tankopedia"; -import { useProtagonistTurret } from "./useProtagonistTurret"; - -export function useProtagonistGun() { - const id = Tankopedia.use((state) => state.protagonist.gun); - const turret = useProtagonistTurret(); - return turret.guns[id]; -} diff --git a/packages/website/src/hooks/useProtagonistTank.ts b/packages/website/src/hooks/useProtagonistTank.ts deleted file mode 100644 index 7c5a6d89b..000000000 --- a/packages/website/src/hooks/useProtagonistTank.ts +++ /dev/null @@ -1,9 +0,0 @@ -import { api } from "../api/dynamic"; -import { Tankopedia } from "../stores/tankopedia"; -import { useAwait } from "./useAwait"; - -export function useProtagonistTank() { - const id = Tankopedia.use((state) => state.protagonist.tank); - const tank = useAwait(() => api.tank(id), `tank-${id}`); - return tank; -} diff --git a/packages/website/src/hooks/useProtagonistTurret.ts b/packages/website/src/hooks/useProtagonistTurret.ts deleted file mode 100644 index bd6f58c35..000000000 --- a/packages/website/src/hooks/useProtagonistTurret.ts +++ /dev/null @@ -1,8 +0,0 @@ -import { Tankopedia } from "../stores/tankopedia"; -import { useProtagonistTank } from "./useProtagonistTank"; - -export function useProtagonistTurret() { - const id = Tankopedia.use((state) => state.protagonist.gun); - const tank = useProtagonistTank(); - return tank.turrets[id]; -} diff --git a/packages/website/src/stores/tankopedia.ts b/packages/website/src/stores/tankopedia.ts index d116b38e9..5729ede2f 100644 --- a/packages/website/src/stores/tankopedia.ts +++ b/packages/website/src/stores/tankopedia.ts @@ -1,8 +1,5 @@ -import { - createDefaultSkills, - ShellDefinition, - TankDefinition, -} from "@blitzkit/core"; +import { createDefaultSkills } from "@blitzkit/core"; +import type { ShellDefinition, TankDefinition } from "@blitzkit/protos"; import type { Vector3 } from "three"; import { Varuna } from "varuna"; import { api } from "../api/dynamic"; @@ -83,6 +80,7 @@ interface Tankopedia { revealed: boolean; protagonist: TankState; + antagonist: TankState; shot?: Shot; skills: Record; @@ -117,6 +115,7 @@ export const Tankopedia = new Varuna((tank) => ({ revealed: false, protagonist: createTankState(tank), + antagonist: createTankState(tank), model: models.models[tank.id], relativeAgainst: TankopediaRelativeAgainst.Class,