This commit is contained in:
tresabhi committed 2026-10-12 10:47:00 -05:00
1 parent 3d8cfc3aeb
commit bc6257a0c3
5 files changed
+110 -26

No files matched your search

+18 -2
View File
@@ -101,6 +101,24 @@ export const characteristics = {
}, },
}, },
reloads: {
type: CharacteristicType.NumberList,
should_render({ gun }) {
return gun.gun_type!.$case === "auto_reloader";
},
compute({ gun, characteristic }) {
if (gun.gun_type!.$case !== "auto_reloader") return [];
const reloadCoefficient = characteristic("_reload_coefficient") as number;
return gun.gun_type!.value.shell_reloads.map(
(reload) => reload * reloadCoefficient,
);
},
},
intra_clip: { intra_clip: {
type: CharacteristicType.Number, type: CharacteristicType.Number,
@@ -195,8 +213,6 @@ export const characteristics = {
// module_damage_range: unavailable, // module_damage_range: unavailable,
// reloads: unavailable,
clip_size: { clip_size: {
type: CharacteristicType.Number, type: CharacteristicType.Number,
@@ -87,7 +87,12 @@ export const characteristicsGroups: CharacteristicsGroup[] = [
units: "s", units: "s",
ranking: CharacteristicRanking.LowerIsBetter, ranking: CharacteristicRanking.LowerIsBetter,
}, },
{ name: "reloads", decimals: 1, units: "s" }, {
name: "reloads",
decimals: 1,
units: "s",
ranking: CharacteristicRanking.LowerIsBetter,
},
{ toy: "reload" }, { toy: "reload" },
], ],
@@ -1,10 +1,12 @@
import { literalsArray } from "@blitzkit/i18n/src/literals"; import { literalsArray } from "@blitzkit/i18n/src/literals";
import { type ReactNode } from "react"; import { Fragment, type ReactNode } from "react";
import { Text } from "../components/Text"; import { Text } from "../components/Text";
import { characteristics } from "../config/characteristics";
import type { import type {
CharacteristicRenderConfig, CharacteristicRenderConfig,
CharacteristicReturnType, CharacteristicReturnType,
} from "../types/characteristics"; } from "../types/characteristics";
import { CharacteristicType } from "../types/characteristics";
import { useLocale } from "./useLocale"; import { useLocale } from "./useLocale";
import { useStrings } from "./useStrings"; import { useStrings } from "./useStrings";
@@ -21,39 +23,61 @@ export function useCharacteristicRenderer() {
if (config.render) if (config.render)
return config.render({ output: characteristic, strings }); return config.render({ output: characteristic, strings });
if (typeof characteristic === "number") { function renderNumber(
if (Number.isFinite(characteristic)) { value: number,
let value: ReactNode = characteristic; units: CharacteristicRenderConfig["units"],
): ReactNode {
if (!Number.isFinite(value)) return `${value < 0 ? "-" : ""}∞`;
let rendered: ReactNode = value;
if (config.decimals !== undefined) { if (config.decimals !== undefined) {
value *= 10 ** config.decimals; rendered *= 10 ** config.decimals;
value = Math.round(value); rendered = Math.round(rendered);
value /= 10 ** config.decimals; rendered /= 10 ** config.decimals;
} }
if (config.localize) { if (config.localize) {
value = value.toLocaleString(locale); rendered = rendered.toLocaleString(locale);
} else { } else {
value = value.toFixed(config.decimals); rendered = rendered.toFixed(config.decimals);
} }
if (config.units !== undefined) { if (units !== undefined) {
value = literalsArray(strings.units[config.units], { rendered = literalsArray(strings.units[units], {
value: <Text>{value}</Text>, value: <Text>{rendered}</Text>,
}); });
} }
return value; return rendered;
} }
return `${characteristic < 0 ? "-" : ""}∞`; switch (characteristics[config.name].type) {
} case CharacteristicType.Enum:
return characteristic as string;
if (typeof characteristic === "string") { case CharacteristicType.Number:
return characteristic; return renderNumber(characteristic as number, config.units);
}
throw new Error("Unknown characteristic type"); case CharacteristicType.NumberList: {
const values = (characteristic as number[]).map((value, index) => (
<Fragment key={index}>
{index > 0 && ", "}
{renderNumber(value, undefined)}
</Fragment>
));
if (config.units === undefined) return values;
return (
<>
{literalsArray(strings.units[config.units], {
value: <Text>{values}</Text>,
})}
</>
);
}
}
} }
return renderCharacteristic; return renderCharacteristic;
@@ -1,8 +1,11 @@
import { characteristics as characteristicDefinitions } from "../config/characteristics";
import { characteristicsGroups } from "../config/characteristicsGroups"; import { characteristicsGroups } from "../config/characteristicsGroups";
import { import {
CharacteristicRanking as CharacteristicRankingDirection, CharacteristicRanking as CharacteristicRankingDirection,
CharacteristicType,
type CharacteristicName, type CharacteristicName,
type CharacteristicRenderConfig, type CharacteristicRenderConfig,
type CharacteristicReturnType,
type ComputedCharacteristics, type ComputedCharacteristics,
} from "../types/characteristics"; } from "../types/characteristics";
@@ -24,6 +27,35 @@ export interface CharacteristicRank {
score: number; score: number;
} }
function rankingValue(
name: CharacteristicName,
value?: CharacteristicReturnType,
) {
if (value === undefined) return;
switch (characteristicDefinitions[name].type) {
case CharacteristicType.Enum:
return;
case CharacteristicType.Number:
return value as number;
case CharacteristicType.NumberList: {
const values = value as number[];
if (values.length === 0) return;
let total = 0;
for (const current of values) {
total += current;
}
return total / values.length;
}
}
}
export function calculateRankings( export function calculateRankings(
characteristics: ComputedCharacteristics, characteristics: ComputedCharacteristics,
comparisons: ComputedCharacteristics[], comparisons: ComputedCharacteristics[],
@@ -31,7 +63,9 @@ export function calculateRankings(
const rankings = new Map<CharacteristicName, CharacteristicRank>(); const rankings = new Map<CharacteristicName, CharacteristicRank>();
for (const [name, value] of characteristics) { for (const [name, value] of characteristics) {
if (typeof value !== "number" || name[0] === "_") continue; const currentValue = rankingValue(name, value);
if (currentValue === undefined || name[0] === "_") continue;
const config = characteristicConfigs.get(name)!; const config = characteristicConfigs.get(name)!;
@@ -41,13 +75,13 @@ export function calculateRankings(
config.ranking === CharacteristicRankingDirection.LowerIsBetter; config.ranking === CharacteristicRankingDirection.LowerIsBetter;
const values = comparisons const values = comparisons
.map((comparison) => comparison.get(name)) .map((comparison) => rankingValue(name, comparison.get(name)))
.filter((other) => typeof other === "number"); .filter((other) => other !== undefined);
if (values.length === 0) continue; if (values.length === 0) continue;
const betterCount = values.filter((other) => const betterCount = values.filter((other) =>
lowerIsBetter ? other < value : other > value, lowerIsBetter ? other < currentValue : other > currentValue,
).length; ).length;
rankings.set(name, { rankings.set(name, {
@@ -27,6 +27,10 @@ export type Characteristic = {
type: CharacteristicType.Number; type: CharacteristicType.Number;
compute(context: CharacteristicContext): number; compute(context: CharacteristicContext): number;
} }
| {
type: CharacteristicType.NumberList;
compute(context: CharacteristicContext): number[];
}
); );
export type CharacteristicScript = ( export type CharacteristicScript = (
@@ -63,6 +67,7 @@ export type CrewStatRole = "commander" | "loader" | "gunner" | "driver";
export enum CharacteristicType { export enum CharacteristicType {
Enum, Enum,
Number, Number,
NumberList,
} }
export enum CharacteristicRanking { export enum CharacteristicRanking {