feat: meta section

This commit is contained in:
TrèsAbhi committed 2025-12-26 14:14:29 -06:00
1 parent 1d3cb95b89
commit 40a1eb861d
14 files changed
+141 -18

No files matched your search

+1
View File
@@ -186,6 +186,7 @@
"@blitzkit/closed": "workspace:*",
"@blitzkit/core": "workspace:*",
"@blitzkit/i18n": "workspace:*",
"@bufbuild/protobuf": "^2.10.2",
"@fontsource-variable/inter": "^5.2.8",
"@radix-ui/colors": "^3.0.0",
"@radix-ui/react-icons": "^1.3.2",
+3 -2
View File
@@ -56,7 +56,7 @@ for (const root of roots) {
"--ts_proto_opt=unrecognizedEnum=false",
"--ts_proto_opt=snakeToCamel=false",
`--ts_proto_out=${root}`,
`-I=${root}`,
...roots.map((root) => `-I=${root}`),
].join(" ");
while (true) {
@@ -66,8 +66,9 @@ for (const root of roots) {
const newLine = ` ${root}/${file}`;
if (command.length + newLine.length < MAX_COMMAND_LENGTH) {
const file = files.pop();
command += newLine;
console.log(` ${files.pop()}`);
// console.log(` ${file}`);
} else {
break;
}
+1
View File
@@ -16,6 +16,7 @@
"@blitzkit/closed": "workspace:*",
"@blitzkit/core": "workspace:*",
"@blitzkit/i18n": "workspace:*",
"@bufbuild/protobuf": "^2.10.2",
"@fontsource-variable/inter": "^5.2.8",
"@radix-ui/colors": "^3.0.0",
"@radix-ui/react-icons": "^1.3.2",
+2 -2
View File
@@ -1,4 +1,4 @@
import type { TankCatalogComponent } from "@protos/blitz_static_tank_component";
import type { Tank } from "../../protos/tank";
import type { Tanks } from "../../protos/tanks";
export abstract class AbstractAPI {
@@ -9,5 +9,5 @@ export abstract class AbstractAPI {
prefix?: string
): Promise<Record<string, string>>;
abstract tank(id: string): Promise<TankCatalogComponent>;
abstract tank(id: string): Promise<Tank>;
}
+2 -2
View File
@@ -1,4 +1,4 @@
import { TankCatalogComponent } from "@protos/blitz_static_tank_component";
import { Tank } from "../../protos/tank";
import { AbstractAPI } from "./abstract";
export class ClientAPI extends AbstractAPI {
@@ -7,6 +7,6 @@ export class ClientAPI extends AbstractAPI {
const buffer = await response.arrayBuffer();
const array = new Uint8Array(buffer);
return TankCatalogComponent.decode(array);
return Tank.decode(array);
}
}
+4 -2
View File
@@ -2,6 +2,7 @@ import type { MetadataAccessor } from "@blitzkit/closed";
import { sluggify } from "@blitzkit/core";
import type { RemoteStorageComponent } from "@protos/blitz_static_remote_storage_component";
import { parse } from "yaml";
import type { Tank } from "../../protos/tank";
import type { TanksEntry } from "../../protos/tanks";
import { AbstractAPI } from "./abstract";
@@ -115,8 +116,9 @@ export class ServerAPI extends AbstractAPI {
async tank(id: string) {
const item = this.metadata.item(`TankEntity.${id}`);
const tankCatalog = item.TankCatalog();
const tank = item.TankCatalog();
const compensation = item.Compensation();
return tankCatalog;
return { tank, compensation } satisfies Tank;
}
}
@@ -1,5 +1,6 @@
import { TankClass } from "@blitzkit/core";
import type { TankCatalogComponent } from "@protos/blitz_static_tank_component";
import type { CompensationComponent } from "@protos/blitz_static_compensation_component";
import { type TankCatalogComponent } from "@protos/blitz_static_tank_component";
import {
ShellUpgrageSingleChange_AttributeName,
StageParameters,
@@ -9,7 +10,7 @@ import { radToDeg } from "three/src/math/MathUtils.js";
import { applyPitchYawLimits } from "./applyPitchYawLimits";
import { TerrainHardness, type TankState } from "./tankState";
export type CharacteristicOutput = number | number[] | null;
export type CharacteristicOutput = number | number[] | string | null;
type Characteristic = (helpers: {
characteristic: (name: CharacteristicName) => CharacteristicOutput;
@@ -20,6 +21,8 @@ type Characteristic = (helpers: {
state: TankState;
tank: TankCatalogComponent;
parameters: StageParameters;
compensation: CompensationComponent;
id: string;
}) => CharacteristicOutput;
export type CharacteristicName = keyof typeof characteristics;
@@ -391,4 +394,28 @@ export const characteristics = {
volume() {
return -Infinity;
},
nation({ tank }) {
return tank.nation;
},
name({ tank }) {
return tank.name!.value;
},
tier({ tank }) {
return tank.tier_catalog_id;
},
type({ tank }) {
return tank.tank_type;
},
id({ id }) {
return id;
},
compensation({ compensation }) {
return compensation.compensation?.currency_reward?.amount ?? null;
},
} satisfies Record<string, Characteristic>;
@@ -1,4 +1,13 @@
import type { CharacteristicName } from "./characteristics";
import {
Nation,
TankClass,
TankType,
} from "@protos/blitz_static_tank_component";
import {
GunType,
type CharacteristicName,
type CharacteristicOutput,
} from "./characteristics";
export enum BetterDirection {
Higher,
@@ -9,6 +18,7 @@ export interface CharacteristicRenderConfig {
name: CharacteristicName;
decimals?: number;
units?: string;
render?: (output: CharacteristicOutput) => string;
}
type CharacteristicsOrder = {
@@ -22,10 +32,42 @@ type CharacteristicsOrder = {
}[];
export const characteristicsOrder: CharacteristicsOrder = [
{
group: "meta",
order: [
{ name: "name" },
{ name: "tier" },
{
name: "nation",
render(output) {
return Nation[output as Nation];
},
},
{
name: "class",
render(output) {
return TankClass[output as TankClass];
},
},
{
name: "type",
render(output) {
return TankType[output as TankType];
},
},
{ name: "compensation" },
{ name: "id" },
],
},
{
group: "firepower",
order: [
{ name: "gun_type" },
{
name: "gun_type",
render(output) {
return GunType[output as GunType];
},
},
{ name: "dpm", decimals: 0, units: "hp_min" },
{ name: "reload", decimals: 2, units: "s" },
{ name: "reloads", decimals: 2, units: "s" },
@@ -1,3 +1,4 @@
import type { CompensationComponent } from "@protos/blitz_static_compensation_component";
import type { TankCatalogComponent } from "@protos/blitz_static_tank_component";
import {
ShellUpgrageSingleChange_AttributeName,
@@ -12,7 +13,9 @@ import {
import type { TankState } from "./tankState";
export function computeCharacteristics(
id: string,
tank: TankCatalogComponent,
compensation: CompensationComponent,
state: TankState
) {
const parameters = aggregateStageParameters(
@@ -89,6 +92,8 @@ export function computeCharacteristics(
state,
tank,
parameters,
id,
compensation,
});
computed[name] = value;
}
@@ -7,6 +7,8 @@ export function renderCharacteristic(
): string | null {
if (characteristic === null) return null;
if (config.render) return config.render(characteristic);
if (typeof characteristic === "number") {
if (Number.isFinite(characteristic)) {
if (config.decimals === undefined) {
@@ -19,5 +21,9 @@ export function renderCharacteristic(
return `${characteristic < 0 ? "-" : ""}∞`;
}
if (typeof characteristic === "string") {
return characteristic;
}
return characteristic.map((c) => renderCharacteristic(c, config)).join(", ");
}
@@ -0,0 +1,27 @@
import { Nation } from "@protos/blitz_static_tank_component";
import type { APIContext, GetStaticPaths } from "astro";
const enums = {
nation: Nation,
};
export const getStaticPaths = (() => {
return Object.keys(enums).map((name) => ({ params: { enum: name } }));
}) satisfies GetStaticPaths;
/**
* The one who wipes, swipes.
*/
export function GET({
params,
}: APIContext<never, { enum: keyof typeof enums }>) {
const map: Record<number, string> = {};
for (const key in enums[params.enum]) {
const value = enums[params.enum][key];
if (typeof value !== "string") continue;
map[key] = value;
}
return Response.json(map);
}
@@ -1,6 +1,6 @@
import { TankCatalogComponent } from "@protos/blitz_static_tank_component";
import type { APIContext, GetStaticPaths } from "astro";
import { api } from "../../../core/api/dynamic";
import { Tank } from "../../../protos/tank";
export const getStaticPaths = (async () => {
const { tanks } = await api.tanks();
@@ -13,5 +13,5 @@ export const getStaticPaths = (async () => {
*/
export async function GET({ params }: APIContext<never, { id: string }>) {
const tank = await api.tank(params.id);
return new Response(TankCatalogComponent.encode(tank).finish());
return new Response(Tank.encode(tank).finish());
}
@@ -17,13 +17,13 @@ export function Page({ id }: { id: string }) {
}
function Content({ id }: { id: string }) {
const tank = useAwait(() => api.tank(id), `tank-${id}`);
const { tank, compensation } = useAwait(() => api.tank(id), `tank-${id}`);
Tankopedia.useInitialization(tank.upgrade_stages.length);
Tankopedia.useInitialization(tank!.upgrade_stages.length);
const protagonist = Tankopedia.use((state) => state.protagonist);
const { characteristics, parameters } = useMemo(
() => computeCharacteristics(tank, protagonist),
() => computeCharacteristics(id, tank!, compensation!, protagonist),
[protagonist]
);
@@ -34,7 +34,7 @@ function Content({ id }: { id: string }) {
<br />
<div style={{ display: "flex", flexWrap: "wrap" }}>
{times(tank.upgrade_stages.length + 1, (index) => (
{times(tank!.upgrade_stages.length + 1, (index) => (
<button
key={index}
onClick={() => {
+11
View File
@@ -0,0 +1,11 @@
syntax = "proto3";
package blitzkit;
import "blitz_static_compensation_component.proto";
import "blitz_static_tank_component.proto";
message Tank {
blitz_static_tank_component.TankCatalogComponent tank = 1;
blitz_static_compensation_component.CompensationComponent compensation = 2;
}