diff --git a/packages/website/src/components/TankopediaCharacteristics/index.tsx b/packages/website/src/components/TankopediaCharacteristics/index.tsx index 7fb72acfc..f79154dfa 100644 --- a/packages/website/src/components/TankopediaCharacteristics/index.tsx +++ b/packages/website/src/components/TankopediaCharacteristics/index.tsx @@ -23,7 +23,7 @@ export function TankopediaCharacteristics({
{characteristicsGroups.map((group) => { const items = group.order.filter( - (item) => "name" in item && item.name in characteristics, + (item) => "name" in item && characteristics.has(item.name), ).length; const shouldRender = items > 0; @@ -51,7 +51,7 @@ function Group({ group, characteristics }: GroupProps) { const strings = useStrings(); const toys = group.order.filter((item) => "toy" in item).length; const items = group.order.filter( - (item) => "name" in item && characteristics[item.name] !== null, + (item) => "name" in item && characteristics.has(item.name), ).length; const groupSpan = `calc(${toys} * var(--group-span) + ${items} + 2)`; const contentSpan = `calc(${toys} * var(--group-span) + ${items})`; @@ -88,8 +88,8 @@ function Group({ group, characteristics }: GroupProps) { {group.order.map((item) => ( <> {"toy" in item && } - {"name" in item && characteristics[item.name] !== null && ( - + {"name" in item && characteristics.get(item.name) && ( + )} ))} diff --git a/packages/website/src/config/characteristics.ts b/packages/website/src/config/characteristics.ts index e8eb14731..9621aaf19 100644 --- a/packages/website/src/config/characteristics.ts +++ b/packages/website/src/config/characteristics.ts @@ -26,12 +26,12 @@ export const characteristics = { damage: { type: CharacteristicType.Number, - compute({ characteristic, gun, shell, equalizer, assault_distance }) { + compute({ characteristic, gun, shell, environment }) { let coefficient = 1; if (gun.assault_ranges && gun.assault_ranges.types.includes(shell.type)) { const match = gun.assault_ranges.ranges.find( - ({ distance }) => distance >= assault_distance, + ({ distance }) => distance >= environment.assault_distance, ); if (match !== undefined) { @@ -39,7 +39,7 @@ export const characteristics = { } } - coefficient *= equalizer.damage; + // coefficient *= equalizer.damage; return coefficient * shell.armor_damage; }, diff --git a/packages/website/src/hooks/useCharacteristics.ts b/packages/website/src/hooks/useCharacteristics.ts new file mode 100644 index 000000000..bb088c60d --- /dev/null +++ b/packages/website/src/hooks/useCharacteristics.ts @@ -0,0 +1,72 @@ +import { api } from "../api/dynamic"; +import { characteristics } from "../config/characteristics"; +import { Tankopedia, type TankEnvironment } from "../stores/tankopedia"; +import type { TankState } from "../tankopedia/tankState"; +import type { + CharacteristicContext, + CharacteristicName, + ComputedCharacteristics, +} from "../types/characteristics"; +import type { DuelSide } from "./useEquipment"; + +const tanks = await api.tanks(); + +export function useCharacteristics(side: DuelSide) { + const state = Tankopedia.use((state) => state[side]); + const environment = Tankopedia.use((state) => state.environment); + + return computeCharacteristics(state, environment); +} + +export function computeCharacteristics( + state: TankState, + environment: TankEnvironment, +) { + const computed: ComputedCharacteristics = new Map(); + + const tank = tanks.tanks[state.tank]; + const engine = tank.engines.find((engine) => engine.id === state.engine)!; + const track = tank.tracks.find((track) => track.id === state.track)!; + const turret = tank.turrets.find((turret) => turret.id === state.turret)!; + const gun = turret.guns.find((gun) => gun.id === state.gun)!; + const shell = gun.shells.find((shell) => shell.id === state.shell)!; + + function characteristic(name: CharacteristicName) { + if (!computed.has(name)) { + throw new Error(`Characteristic ${name} not computed yet`); + } + + return computed.get(name)!; + } + + const context = { + state, + environment, + + tank, + engine, + track, + turret, + gun, + shell, + + characteristic, + } satisfies CharacteristicContext; + + for (const name in characteristics) { + const characteristic = characteristics[name as CharacteristicName]; + let shouldRender = true; + + if ("should_render" in characteristic) { + shouldRender = characteristic.should_render(context); + } + + if (!shouldRender) continue; + + const value = characteristic.compute(context); + + computed.set(name as CharacteristicName, value); + } + + return computed; +} diff --git a/packages/website/src/layouts/BaseLayout.astro b/packages/website/src/layouts/BaseLayout.astro index b51471d43..1b6b56dfb 100644 --- a/packages/website/src/layouts/BaseLayout.astro +++ b/packages/website/src/layouts/BaseLayout.astro @@ -43,14 +43,14 @@ const { accent, locale } = Astro.props; color: var(--gray-12); font-family: var(--font-family-regular); - .app { + main { display: flex; flex: 1; flex-direction: column; background-color: var(--gray-1); - padding: var(--space-4); + /* padding: var(--space-4); */ gap: var(--space-6); } } @@ -75,9 +75,9 @@ const { accent, locale } = Astro.props; -
+
-
+ diff --git a/packages/website/src/pages/[...chunk_default]/[...locale]/tanks/[slug]/_index.tsx b/packages/website/src/pages/[...chunk_default]/[...locale]/tanks/[slug]/_index.tsx index a13ada0e9..1bd4c01da 100644 --- a/packages/website/src/pages/[...chunk_default]/[...locale]/tanks/[slug]/_index.tsx +++ b/packages/website/src/pages/[...chunk_default]/[...locale]/tanks/[slug]/_index.tsx @@ -8,8 +8,8 @@ import { defaultEqualizer } from "../../../../../config/equalizer"; import { withErrorWrapper } from "../../../../../hocs/withErrorWrapper"; import { withLocale } from "../../../../../hocs/withLocale"; import { useAwait } from "../../../../../hooks/useAwait"; +import { useCharacteristics } from "../../../../../hooks/useCharacteristics"; import { Tankopedia } from "../../../../../stores/tankopedia"; -import { computeCharacteristics } from "../../../../../tankopedia/computeCharacteristics"; import type { MaybeSkeletonComponentProps } from "../../../../../types/maybeSkeletonComponentProps"; import styles from "./_index.module.css"; @@ -26,14 +26,10 @@ export const Page = withErrorWrapper( Tankopedia.useInitialization(protagonistTank); const protagonist = Tankopedia.use((state) => state.protagonist); - // const protagonistEquipment = useEquipment("protagonist", protagonistTank.tank!); + const equalize = Tankopedia.use((state) => state.environment.equalize); - const characteristics = useMemo( - () => computeCharacteristics(), - [protagonist], - ); + const characteristics = useCharacteristics("protagonist"); - const equalize = Tankopedia.use((state) => state.equalize); const thicknessRange = useMemo(() => { const entries = Object.values(tanks.tanks); const filtered = entries.filter( diff --git a/packages/website/src/stores/tankopedia.ts b/packages/website/src/stores/tankopedia.ts index 01c2015b6..58afd9a56 100644 --- a/packages/website/src/stores/tankopedia.ts +++ b/packages/website/src/stores/tankopedia.ts @@ -75,14 +75,18 @@ export enum TankopediaRelativeAgainst { All, } +export interface TankEnvironment { + equalize: boolean; + assault_distance: number; +} + interface Tankopedia { disturbed: boolean; revealed: boolean; protagonist: TankState; antagonist: TankState; - - equalize: boolean; + environment: TankEnvironment; shot?: Shot; skills: Record; @@ -121,7 +125,7 @@ export const Tankopedia = new Soapstone( antagonist: createTankState(tank), model: models.models[tank.id], - equalize: false, + environment: { equalize: false, assault_distance: 0 }, relativeAgainst: TankopediaRelativeAgainst.Class, editStatic: false, diff --git a/packages/website/src/tankopedia/computeCharacteristics.ts b/packages/website/src/tankopedia/computeCharacteristics.ts deleted file mode 100644 index ed53640b2..000000000 --- a/packages/website/src/tankopedia/computeCharacteristics.ts +++ /dev/null @@ -1,7 +0,0 @@ -import type { ComputedCharacteristics } from "../types/characteristics"; - -export function computeCharacteristics() { - const characteristics: Partial = {}; - - return characteristics as ComputedCharacteristics; -} diff --git a/packages/website/src/tankopedia/createTankState.ts b/packages/website/src/tankopedia/createTankState.ts index eaed6b008..967d2fbdf 100644 --- a/packages/website/src/tankopedia/createTankState.ts +++ b/packages/website/src/tankopedia/createTankState.ts @@ -27,7 +27,10 @@ export function createTankState(tank: TankDefinition) { shell: gun.shells[0].id, track: tank.tracks.at(-1)!.id, - assault_distance: (gun.assault_ranges?.ranges[0].distance ?? 0) / 2, + environment: { + assault_distance: (gun.assault_ranges?.ranges[0].distance ?? 0) / 2, + }, + speed: 0, equipment: {}, diff --git a/packages/website/src/tankopedia/tankState.ts b/packages/website/src/tankopedia/tankState.ts index 8ac07265b..e3e8e008d 100644 --- a/packages/website/src/tankopedia/tankState.ts +++ b/packages/website/src/tankopedia/tankState.ts @@ -9,7 +9,6 @@ export interface TankState { shell: number; track: number; - assault_distance: number; speed: number; equipment: Record; diff --git a/packages/website/src/types/characteristics.ts b/packages/website/src/types/characteristics.ts index c82c432ba..4dbf6c0d0 100644 --- a/packages/website/src/types/characteristics.ts +++ b/packages/website/src/types/characteristics.ts @@ -1,11 +1,16 @@ import type { Strings } from "@blitzkit/i18n"; import type { - Equalizer, + EngineDefinition, GunDefinition, ShellDefinition, + TankDefinition, + TrackDefinition, + TurretDefinition, } from "@blitzkit/protos"; import type { ReactNode } from "react"; import { characteristics } from "../config/characteristics"; +import type { TankEnvironment } from "../stores/tankopedia"; +import type { TankState } from "../tankopedia/tankState"; export type Characteristic = { should_render?(context: CharacteristicContext): boolean; @@ -20,14 +25,17 @@ export type Characteristic = { } ); -interface CharacteristicContext { +export interface CharacteristicContext { + state: TankState; + environment: TankEnvironment; + + tank: TankDefinition; + engine: EngineDefinition; + track: TrackDefinition; + turret: TurretDefinition; gun: GunDefinition; shell: ShellDefinition; - equalizer: Equalizer; - - assault_distance: number; - characteristic( name: CharacteristicName, ): ReturnType; @@ -41,8 +49,9 @@ export enum CharacteristicType { export type CharacteristicName = keyof typeof characteristics; export type CharacteristicReturnType = ReturnType; -export type ComputedCharacteristics = Partial< - Record +export type ComputedCharacteristics = Map< + CharacteristicName, + CharacteristicReturnType >; export interface CharacteristicRenderConfig {