Compare commits

..
39 Commits
Author SHA1 Message Date
TrèsAbhi c55f4c311f fix: typo 2026-03-31 21:02:36 -05:00
TrèsAbhi e063970c58 feat: plug 2026-03-31 21:01:00 -05:00
TrèsAbhi fdf8580f5f feat: functionality 2026-03-31 17:15:25 -05:00
TrèsAbhi cffd37c6f1 feat: ui 2026-03-31 17:01:47 -05:00
TrèsAbhi 7419b3f29e fix: consumable times 2026-03-31 16:51:07 -05:00
TrèsAbhi e2f50871ec fix: update all 2026-03-31 14:11:45 -05:00
TrèsAbhi bdea9fdab3 fix: consistent protos 2026-03-31 13:35:47 -05:00
TrèsAbhi ae793c1c28 Merge pull request #229 from karelpak1/fix-large-repair-kit-icon 2026-03-26 20:05:56 -05:00
GonnaHetzMe 3d912036a7 fix: use proper icon for large repair kit 2026-03-27 02:03:15 +01:00
TrèsAbhi 1866077a82 Merge pull request #228 from karelpak1/feat-dev-name
Feat: dev name
2026-03-26 08:08:20 -05:00
TrèsAbhi 8345f99603 fix: use dev name directly 2026-03-26 08:06:43 -05:00
GonnaHetzMe 2ab576a37c fix: Set pointer cursor and simplify devName access 2026-03-26 09:29:35 +01:00
GonnaHetzMe 5b9ff7acb3 feat: CopyableCode styles and remove DEV name fallback 2026-03-25 17:25:52 +01:00
GonnaHetzMe 4cdb712013 feat: add CopyableCode component 2026-03-25 11:18:53 +01:00
GonnaHetzMe e6fcfdb514 Feat: dev name 2026-03-25 02:58:16 +01:00
TrèsAbhi 9df1800e10 Merge pull request #224 from karelpak1/fix-techtree
fix: include non-tier1 roots in tank tech tree routes
2026-03-24 19:31:46 -05:00
TrèsAbhi 95ba925d27 Merge pull request #226 from karelpak1/fix-yaw-pitch-inputs
fix: initialize tank quick inputs from current model transform
2026-03-24 19:29:21 -05:00
GonnaHetzMe 41882ddf23 fix: initialize tank quick inputs from current model transform 2026-03-25 01:12:06 +01:00
GonnaHetzMe fe9b543a75 fix: include non-tier1 roots in tank tech tree routes 2026-03-25 00:43:30 +01:00
TrèsAbhi 191843f972 Merge pull request #220 from blitzkit/main-i18n
New Crowdin updates
2026-03-24 09:39:43 -05:00
TrèsAbhi c1fde44809 Merge pull request #223 from blitzkit/fixes
fixes
2026-03-24 09:39:28 -05:00
TrèsAbhi 1a3517e035 feat: logs 2026-03-23 22:50:34 -05:00
TrèsAbhi afec6d9851 feat: enable all tiers 2026-03-23 22:41:34 -05:00
TrèsAbhi e3f2fd70ad fix: use turret mantlet 2026-03-23 22:36:10 -05:00
TrèsAbhi 5adbec25c4 fix: compact compare headers 2026-03-23 22:20:29 -05:00
TrèsAbhi 4ff8d77460 fix: object review videos 2026-03-23 22:13:29 -05:00
TrèsAbhi 22faa6d294 fix: stale compare indices 2026-03-23 22:07:20 -05:00
TrèsAbhi a2abfa7f85 fix: v-stabs now give 12% 2026-03-23 21:56:33 -05:00
TrèsAbhi 7b93b12fcb Merge pull request #222 from karelpak1/Position-fix 2026-03-23 19:56:17 -05:00
GonnaHetzMe ed252d5dfe Reset localTranslation for model extraction 2026-03-23 13:17:42 +01:00
TrèsAbhi c365993541 feat: remove discord bot
.
2026-03-19 09:21:58 -05:00
TrèsAbhi 30f9475208 feat: disable bot 2026-03-19 09:19:28 -05:00
TrèsAbhi 454c526666 New translations en.json (Polish) 2026-03-16 18:24:41 -05:00
TrèsAbhi e67970d2b9 New translations en.json (Polish) 2026-03-16 16:55:46 -05:00
TrèsAbhi 0f1c03d1e5 New translations en.json (Chinese Simplified) 2026-03-12 22:52:18 -05:00
tresabhi 8394f2ec1e feat: logs 2026-03-11 16:51:32 -05:00
tresabhi f14e73d811 fix: alpha clipping 2026-03-11 16:50:18 -05:00
TrèsAbhi 23e00b4199 New translations en.json (Polish) 2026-03-10 14:55:15 -05:00
TrèsAbhi 427b189a34 New Crowdin updates (#217) 2026-03-04 17:42:01 -06:00
148 changed files with 4451 additions and 4059 deletions

No files matched your search

-6
View File
@@ -1,13 +1,7 @@
name: Host
on:
push:
branches: main
schedule:
- cron: "0 */5 * * *"
workflow_dispatch:
release:
types: [created, published, released, edited]
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
+5
View File
@@ -0,0 +1,5 @@
# BlitzKit 1.29.15
## Fixes
- Tanks now use alpha clipping to render translucency, fixing a lot of "ghostly" looking tanks
+18
View File
@@ -0,0 +1,18 @@
# BlitzKit 1.29.16
Thank you to [GonnaHetzMe](https://github.com/karelpak1) for your contributions this update.
## Fixes
- [GonnaHetzMe] The turret for Centurion I is no longer offset from the body
- Please allow up to 24 hours for the model to update
- Vertical Stabilizers now give the correct 12% buff instead of 15%
- Re-ordering tanks in Compare now works once again
- Fixed review videos from being about the Object 452K across all tanks
- Please allow up to 2 weeks for all tanks to refresh their videos
- Tanks in Mixer with oscillating turrets are not handled properly
## Features
- Headings in the Compare tool are now even more compact for mobile devices
- Enabled all tiers for the randomizer in Mixer
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "blitzkit",
"version": "1.29.14",
"version": "1.29.16",
"license": "BlitzKit License",
"private": true,
"scripts": {
+4 -4
View File
@@ -43,7 +43,7 @@ export const ownedTanksCommand = new Promise<CommandRegistry>((resolve) => {
tankStats.map(async (tankData) => ({
tankDefinitions: (await tankDefinitions).tanks[tankData.tank_id]!,
id: tankData.tank_id,
}))
})),
)
).filter((tank) => tank.tankDefinitions?.tier === tier);
const groupedTanks: Record<string, TankDefinition[]> = {};
@@ -69,16 +69,16 @@ export const ownedTanksCommand = new Promise<CommandRegistry>((resolve) => {
.filter((tank) => tank.tier === tier)
.sort(
(a, b) =>
TANK_CLASSES.indexOf(a.class) - TANK_CLASSES.indexOf(b.class)
TANK_CLASSES.indexOf(a.class) - TANK_CLASSES.indexOf(b.class),
)
.sort(
(a, b) =>
awaitedGameDefinitions.nations.indexOf(a.nation) -
awaitedGameDefinitions.nations.indexOf(b.nation)
awaitedGameDefinitions.nations.indexOf(b.nation),
)
.map(
(tank) =>
`[${flags[tank.nation]} ${markdownEscape(unwrap(tank.name))}](<https://blitzkit.app/tanks/${tank.slug}>)`
`[${flags[tank.nation]} ${markdownEscape(unwrap(tank.name!))}](<https://blitzkit.app/tanks/${tank.slug}>)`,
);
const lines = [title, ...tankList];
+2 -2
View File
@@ -280,7 +280,7 @@ async function playerListing(
}}
>
<img
alt={unwrap(tank.name)}
alt={unwrap(tank.name!)}
src={await iconPng(tankIcon(tank.id))}
style={{
width: 32,
@@ -317,7 +317,7 @@ async function playerListing(
fontSize: 16,
}}
>
{unwrap(tank.name)}
{unwrap(tank.name!)}
</span>
</div>
+47 -47
View File
@@ -35,49 +35,49 @@ export const researchCommand = new Promise<CommandRegistry>((resolve) => {
command: createLocalizedCommand("research")
.addStringOption((option) =>
option
.setName(strings.bot.commands.research.options.target_tank.name)
.setName(strings.bot.commands.research.options.target_tank.name!)
.setNameLocalizations(
localizationObject(
(strings) =>
strings.bot.commands.research.options.target_tank.name,
undefined,
true
)
true,
),
)
.setDescription(
strings.bot.commands.research.options.target_tank.description
strings.bot.commands.research.options.target_tank.description,
)
.setDescriptionLocalizations(
localizationObject(
(strings) =>
strings.bot.commands.research.options.target_tank.description
)
strings.bot.commands.research.options.target_tank.description,
),
)
.setAutocomplete(true)
.setRequired(true)
.setRequired(true),
)
.addStringOption((option) =>
option
.setName(strings.bot.commands.research.options.starting_tank.name)
.setName(strings.bot.commands.research.options.starting_tank.name!)
.setNameLocalizations(
localizationObject(
(strings) =>
strings.bot.commands.research.options.starting_tank.name,
undefined,
true
)
true,
),
)
.setDescription(
strings.bot.commands.research.options.starting_tank.description
strings.bot.commands.research.options.starting_tank.description,
)
.setDescriptionLocalizations(
localizationObject(
(strings) =>
strings.bot.commands.research.options.starting_tank.description
)
strings.bot.commands.research.options.starting_tank.description,
),
)
.setAutocomplete(true)
.setRequired(false)
.setRequired(false),
)
.addStringOption(addUsernameChoices),
@@ -87,7 +87,7 @@ export const researchCommand = new Promise<CommandRegistry>((resolve) => {
const targetTankId = await resolveTankId(
interaction.options.getString("target-tank", true),
interaction.locale,
true
true,
);
const startingTankRaw = interaction.options.getString("starting-tank");
const targetTank = awaitedTankDefinitions.tanks[targetTankId];
@@ -99,13 +99,13 @@ export const researchCommand = new Promise<CommandRegistry>((resolve) => {
startingTankId = await resolveTankId(
startingTankRaw,
interaction.locale,
true
true,
);
if (targetTankId === startingTankId) {
return literals(
strings.bot.commands.research.errors.start_end_equal,
{ tank: escapeMarkdown(unwrap(targetTank.name)) }
{ tank: escapeMarkdown(unwrap(targettank.name!)) },
);
}
@@ -113,8 +113,8 @@ export const researchCommand = new Promise<CommandRegistry>((resolve) => {
if (startingTank.tier > targetTank.tier) {
return literals(strings.bot.commands.research.errors.unordered, {
tank_1: escapeMarkdown(unwrap(startingTank.name)),
tank_2: escapeMarkdown(unwrap(targetTank.name)),
tank_1: escapeMarkdown(unwrap(startingtank.name!)),
tank_2: escapeMarkdown(unwrap(targettank.name!)),
});
}
@@ -122,21 +122,21 @@ export const researchCommand = new Promise<CommandRegistry>((resolve) => {
return literals(
strings.bot.commands.research.errors.tanks_not_on_line,
{
tank_1: escapeMarkdown(unwrap(targetTank.name)),
tank_2: escapeMarkdown(unwrap(startingTank.name)),
}
tank_1: escapeMarkdown(unwrap(targettank.name!)),
tank_2: escapeMarkdown(unwrap(startingtank.name!)),
},
);
}
} else {
if (targetTank.type !== TankType.RESEARCHABLE) {
if (targetTank.type !== TankType.TANK_TYPE_RESEARCHABLE) {
return literals(strings.bot.commands.research.errors.non_tech_tree, {
tank: escapeMarkdown(unwrap(targetTank.name)),
tank: escapeMarkdown(unwrap(targettank.name!)),
});
}
if (targetTank.tier === 1) {
return literals(strings.bot.commands.research.errors.tier_1, {
tank: escapeMarkdown(unwrap(targetTank.name)),
tank: escapeMarkdown(unwrap(targettank.name!)),
});
}
@@ -149,14 +149,14 @@ export const researchCommand = new Promise<CommandRegistry>((resolve) => {
if (tankStats.some(({ tank_id }) => tank_id === targetTankId)) {
return literals(
strings.bot.commands.research.errors.already_researched,
{ tank: escapeMarkdown(unwrap(targetTank.name)) }
{ tank: escapeMarkdown(unwrap(targettank.name!)) },
);
}
const foundAncestor = targetTankAncestry.find(
(id) =>
awaitedTankDefinitions.tanks[id].tier === 1 ||
tankStats.some(({ tank_id }) => tank_id === id)
tankStats.some(({ tank_id }) => tank_id === id),
);
if (foundAncestor === undefined) {
@@ -168,7 +168,7 @@ export const researchCommand = new Promise<CommandRegistry>((resolve) => {
const techTreeLine = await buildTechTreeLine(
startingTankId,
targetTankId
targetTankId,
);
const line = [...techTreeLine, startingTankId].reverse();
@@ -190,7 +190,7 @@ export const researchCommand = new Promise<CommandRegistry>((resolve) => {
) {
turretXps.set(
turret.id,
turret.research_cost.research_cost_type!.value
turret.research_cost.research_cost_type!.value,
);
}
@@ -211,7 +211,7 @@ export const researchCommand = new Promise<CommandRegistry>((resolve) => {
) {
engineXps.set(
engine.id,
engine.research_cost.research_cost_type!.value
engine.research_cost.research_cost_type!.value,
);
}
});
@@ -223,7 +223,7 @@ export const researchCommand = new Promise<CommandRegistry>((resolve) => {
) {
trackXps.set(
track.id,
track.research_cost.research_cost_type!.value
track.research_cost.research_cost_type!.value,
);
}
});
@@ -245,13 +245,13 @@ export const researchCommand = new Promise<CommandRegistry>((resolve) => {
return {
research: tank.research_cost!.research_cost_type!.value as number,
upgrades: moduleXp,
purchase: tank.price.value,
purchase: tank.price!.value,
equipment: equipmentPriceMatrix[tank.tier].reduce(
(a, b) => a + 3 * b,
0
0,
),
};
})
}),
);
const image = (
@@ -456,7 +456,7 @@ export const researchCommand = new Promise<CommandRegistry>((resolve) => {
}}
>
<img
alt={unwrap(tank.name)}
alt={unwrap(tank.name!)}
src={TANK_ICONS[tank.class]}
width={16}
height={16}
@@ -467,7 +467,7 @@ export const researchCommand = new Promise<CommandRegistry>((resolve) => {
color: theme.colors.textHighContrast,
}}
>
{unwrap(tank.name)}
{unwrap(tank.name!)}
</span>
</div>
</div>
@@ -505,9 +505,9 @@ export const researchCommand = new Promise<CommandRegistry>((resolve) => {
strings.bot.commands.research.body.research,
{
cost: costs[index].research?.toLocaleString(
interaction.locale
interaction.locale,
),
}
},
)}
</span>
</div>
@@ -523,7 +523,7 @@ export const researchCommand = new Promise<CommandRegistry>((resolve) => {
<img
alt="Free XP icon"
src={await iconPng(
asset("icons/currencies/free-xp.webp")
asset("icons/currencies/free-xp.webp"),
)}
width={16}
height={16}
@@ -536,7 +536,7 @@ export const researchCommand = new Promise<CommandRegistry>((resolve) => {
>
{literals(
strings.bot.commands.research.body.upgrades,
{ cost: costs[index].upgrades.toLocaleString() }
{ cost: costs[index].upgrades.toLocaleString() },
)}
</span>
</div>
@@ -552,7 +552,7 @@ export const researchCommand = new Promise<CommandRegistry>((resolve) => {
<img
alt="Silver icon"
src={await iconPng(
asset("icons/currencies/silver.webp")
asset("icons/currencies/silver.webp"),
)}
width={16}
height={16}
@@ -567,9 +567,9 @@ export const researchCommand = new Promise<CommandRegistry>((resolve) => {
strings.bot.commands.research.body.purchase,
{
cost: costs[index].purchase.toLocaleString(
interaction.locale
interaction.locale,
),
}
},
)}
</span>
</div>
@@ -584,7 +584,7 @@ export const researchCommand = new Promise<CommandRegistry>((resolve) => {
<img
alt="Silver icon"
src={await iconPng(
asset("icons/currencies/silver.webp")
asset("icons/currencies/silver.webp"),
)}
width={16}
height={16}
@@ -599,16 +599,16 @@ export const researchCommand = new Promise<CommandRegistry>((resolve) => {
strings.bot.commands.research.body.equipment,
{
cost: costs[index].equipment.toLocaleString(
interaction.locale
interaction.locale,
),
}
},
)}
</span>
</div>
</div>
</div>
);
})
}),
)}
</div>
</CommandWrapper>
@@ -3,14 +3,14 @@ import {
TankClass,
TankType,
TREE_TYPE_ICONS,
} from '@blitzkit/core';
import { createColors } from 'bepaint';
} from "@blitzkit/core";
import { createColors } from "bepaint";
import {
type AccentColor,
type GrayColor,
PALETTES,
} from '../../../core/radix/radixColors';
import { RowStat } from './RowStat';
} from "../../../core/radix/radixColors";
import { RowStat } from "./RowStat";
export interface RowStatItem {
title: string;
@@ -21,7 +21,7 @@ export interface RowStatItem {
}
interface RowProps {
displayType?: 'tank' | 'summary';
displayType?: "tank" | "summary";
naked?: boolean;
title: string;
minimized?: boolean;
@@ -32,7 +32,7 @@ interface RowProps {
}
export function Row({
color = 'slate',
color = "slate",
stats,
title,
minimized,
@@ -49,20 +49,20 @@ export function Row({
className="session-tracker-row"
style={{
maxWidth: naked ? 600 : Infinity,
display: 'flex',
flexDirection: 'column',
display: "flex",
flexDirection: "column",
borderRadius: 4,
backgroundColor: naked
? `${theme.appBackground2}c0`
: theme.appBackground2,
overflow: 'hidden',
overflow: "hidden",
}}
>
<div
style={{
display: 'flex',
alignItems: 'center',
justifyContent: 'center',
display: "flex",
alignItems: "center",
justifyContent: "center",
padding: 8,
gap: 4,
backgroundColor: naked
@@ -70,10 +70,14 @@ export function Row({
: theme.componentInteractive,
}}
>
{displayType === 'tank' && tankClass !== undefined && (
{displayType === "tank" && tankClass !== undefined && (
<img
alt={TankClass[tankClass]}
src={TREE_TYPE_ICONS[type ?? TankType.RESEARCHABLE][tankClass]}
src={
TREE_TYPE_ICONS[type ?? TankType.TANK_TYPE_RESEARCHABLE][
tankClass
]
}
style={{ width: 16, height: 16 }}
/>
)}
@@ -81,10 +85,10 @@ export function Row({
<span
style={{
color:
displayType === 'tank'
? type === TankType.COLLECTOR
displayType === "tank"
? type === TankType.TANK_TYPE_COLLECTOR
? theme.textLowContrast_blue
: type === TankType.PREMIUM
: type === TankType.TANK_TYPE_PREMIUM
? theme.textLowContrast_amber
: theme.textHighContrast
: theme.textLowContrast,
@@ -98,7 +102,7 @@ export function Row({
<div
style={{
display: 'flex',
display: "flex",
paddingTop: 8,
paddingBottom: 8,
}}
@@ -109,8 +113,8 @@ export function Row({
<RowStat
minimized={minimized}
key={index}
name={`${row.title} • ${row.career ?? '--'}`}
value={row.current ?? '--'}
name={`${row.title} • ${row.career ?? "--"}`}
value={row.current ?? "--"}
delta={row.delta}
percentile={row.percentile}
/>
@@ -1,5 +1,5 @@
import { TankClass, TankType, TREE_TYPE_ICONS } from '@blitzkit/core';
import { theme } from '../../../../stitches.config';
import { TankClass, TankType, TREE_TYPE_ICONS } from "@blitzkit/core";
import { theme } from "../../../../stitches.config";
export interface ItemProps {
tankClass?: TankClass;
@@ -8,9 +8,9 @@ export interface ItemProps {
}
const TREE_TYPE_COLOR = {
[TankType.RESEARCHABLE]: '',
[TankType.PREMIUM]: '_amber',
[TankType.COLLECTOR]: '_blue',
[TankType.TANK_TYPE_RESEARCHABLE]: "",
[TankType.TANK_TYPE_PREMIUM]: "_amber",
[TankType.TANK_TYPE_COLLECTOR]: "_blue",
} as const;
export function Item({
@@ -21,12 +21,12 @@ export function Item({
return (
<div
style={{
display: 'flex',
display: "flex",
height: 32,
paddingLeft: 8,
paddingRight: 8,
overflow: 'hidden',
alignItems: 'center',
overflow: "hidden",
alignItems: "center",
borderRadius: 4,
backgroundColor:
theme.colors[`componentInteractive${TREE_TYPE_COLOR[treeType]}`],
@@ -34,12 +34,12 @@ export function Item({
>
<div
style={{
display: 'flex',
display: "flex",
gap: 4,
flex: 1,
alignItems: 'center',
justifyContent: 'flex-start',
overflow: 'hidden',
alignItems: "center",
justifyContent: "flex-start",
overflow: "hidden",
}}
>
{tankType && (
@@ -52,7 +52,7 @@ export function Item({
<span
style={{
fontSize: 16,
whiteSpace: 'nowrap',
whiteSpace: "nowrap",
color: theme.colors[`textLowContrast${TREE_TYPE_COLOR[treeType]}`],
}}
>
@@ -6,21 +6,21 @@ import { translator } from "../localization/translator";
export async function filtersToDescription(
{ nation, tier, type, class: tankClass, tank }: StatFilters,
locale: Locale
locale: Locale,
) {
const { strings, bkLocale } = translator(locale);
const awaitedTankDefinitions = await fetchTankDefinitions();
const info: string[] = [];
// TODO: somehow localize tank names?
if (tank) return awaitedTankDefinitions.tanks[tank].name.locales[bkLocale];
if (tank) return awaitedTankDefinitions.tanks[tank].name!.locales[bkLocale];
if (nation)
info.push((strings.common.nations as Record<string, string>)[nation]);
if (tier) {
info.push(
literals(strings.bot.common.filters.tier, {
tier: TIER_ROMAN_NUMERALS[tier],
})
}),
);
}
if (tankClass) info.push(strings.common.tank_class_short[tankClass]);
@@ -34,12 +34,12 @@ export async function filterStats(
(filters.tier === undefined || entry.tier === filters.tier) &&
(filters.class === undefined || entry.class === filters.class) &&
(filters.type === undefined ||
(filters.type === TankType.COLLECTOR &&
entry.type === TankType.COLLECTOR) ||
(filters.type === TankType.PREMIUM &&
entry.type === TankType.PREMIUM) ||
(filters.type === TankType.RESEARCHABLE &&
entry.type === TankType.RESEARCHABLE)) &&
(filters.type === TankType.TANK_TYPE_COLLECTOR &&
entry.type === TankType.TANK_TYPE_COLLECTOR) ||
(filters.type === TankType.TANK_TYPE_PREMIUM &&
entry.type === TankType.TANK_TYPE_PREMIUM) ||
(filters.type === TankType.TANK_TYPE_RESEARCHABLE &&
entry.type === TankType.TANK_TYPE_RESEARCHABLE)) &&
(filters.tank === undefined || entry.id === filters.tank)
);
});
@@ -1,12 +1,12 @@
import { Locale, SlashCommandStringOption } from 'discord.js';
import { translator } from '../localization/translator';
import { localizationObject } from './localizationObject';
import { Locale, SlashCommandStringOption } from "discord.js";
import { translator } from "../localization/translator";
import { localizationObject } from "./localizationObject";
export function addTankChoices(option: SlashCommandStringOption) {
const { strings } = translator(Locale.EnglishUS);
return option
.setName(strings.bot.common.options.tank.name)
.setName(strings.bot.common.options.tank.name!)
.setNameLocalizations(
localizationObject(
(strings) => strings.bot.common.options.tank.name,
@@ -13,13 +13,13 @@ import {
} from "./autocompleteClan/constants";
export const tankNamesTechTreeOnly = fetchTankNames().then((names) =>
names.filter((tank) => tank.treeType === TankType.RESEARCHABLE)
names.filter((tank) => tank.treeType === TankType.TANK_TYPE_RESEARCHABLE),
);
export async function autocompleteTanks(
interaction: AutocompleteInteraction<CacheType>,
techTreeOnly = false,
fields = ["tank"]
fields = ["tank"],
) {
const { unwrap } = translator(interaction.locale);
const focusedOption = interaction.options.getFocused(true);
@@ -31,7 +31,7 @@ export async function autocompleteTanks(
go(
focusedOption.value,
await (techTreeOnly ? tankNamesTechTreeOnly : tankNames),
{ keys: SEARCH_KEYS, limit: 10 }
{ keys: SEARCH_KEYS, limit: 10 },
).map(async (item) => {
let name = unwrap(item.obj.searchableName);
@@ -42,7 +42,7 @@ export async function autocompleteTanks(
0,
unwrap(item.obj.searchableName).length -
overSize -
OVERFLOW_SUFFIX.length
OVERFLOW_SUFFIX.length,
)}${OVERFLOW_SUFFIX}`;
}
@@ -50,8 +50,8 @@ export async function autocompleteTanks(
name,
value: `${item.obj.id}`,
} satisfies ApplicationCommandOptionChoiceData<string>;
})
}),
)
: []
: [],
);
}
+4 -2
View File
@@ -1,5 +1,7 @@
import { ShellDefinition, ShellType } from "../protos";
export function canSplash(type: ShellDefinition["type"]): type is ShellType.HE {
return type === ShellType.HE;
export function canSplash(
type: ShellDefinition["type"],
): type is ShellType.SHELL_TYPE_HE {
return type === ShellType.SHELL_TYPE_HE;
}
+10 -10
View File
@@ -2,22 +2,22 @@ import { TankClass, TankType } from "../protos";
import type { BlitzStats } from "../statistics";
export const TANK_TYPES = [
TankType.RESEARCHABLE,
TankType.PREMIUM,
TankType.COLLECTOR,
TankType.TANK_TYPE_RESEARCHABLE,
TankType.TANK_TYPE_PREMIUM,
TankType.TANK_TYPE_COLLECTOR,
];
export const TANK_TYPE_COMMAND_NAMES = {
[TankType.RESEARCHABLE]: "researchable",
[TankType.PREMIUM]: "premium",
[TankType.COLLECTOR]: "collector",
[TankType.TANK_TYPE_RESEARCHABLE]: "researchable",
[TankType.TANK_TYPE_PREMIUM]: "premium",
[TankType.TANK_TYPE_COLLECTOR]: "collector",
};
export const TANK_CLASSES = [
TankClass.LIGHT,
TankClass.MEDIUM,
TankClass.HEAVY,
TankClass.TANK_DESTROYER,
TankClass.TANK_CLASS_LIGHT,
TankClass.TANK_CLASS_MEDIUM,
TankClass.TANK_CLASS_HEAVY,
TankClass.TANK_CLASS_TANK_DESTROYER,
];
export const emptyAllStats: BlitzStats = {
@@ -9,7 +9,7 @@ import {
export function checkConsumableProvisionInclusivity(
consumableProvision: Consumable | Provision,
tank: TankDefinition,
gun: GunDefinition
gun: GunDefinition,
) {
const included = consumableProvision.include?.every((rule) => {
switch (rule.filter_type!.$case) {
@@ -46,7 +46,7 @@ export function checkConsumableProvisionInclusivity(
case "categories":
return rule.filter_type!.value.categories.some((category) => {
switch (category) {
case ConsumableTankCategoryFilterCategory.CLIP:
case ConsumableTankCategoryFilterCategory.CONSUMABLE_TANK_CATEGORY_FILTER_CATEGORY_CLIP:
return gun.gun_type!.$case !== "regular";
}
});
+3 -3
View File
@@ -1,7 +1,7 @@
import { ShellDefinition, ShellType } from "../protos";
export function isExplosive(
type: ShellDefinition["type"]
): type is ShellType.HEAT | ShellType.HE {
return type === ShellType.HEAT || type === ShellType.HE;
type: ShellDefinition["type"],
): type is ShellType.SHELL_TYPE_HEAT | ShellType.SHELL_TYPE_HE {
return type === ShellType.SHELL_TYPE_HEAT || type === ShellType.SHELL_TYPE_HE;
}
+7 -7
View File
@@ -2,27 +2,27 @@ import { TANK_CLASSES } from "../blitz/constants";
import { GameDefinitions, TankDefinition, TankType } from "../protos";
const treeTypeOrder = [
TankType.RESEARCHABLE,
TankType.PREMIUM,
TankType.COLLECTOR,
TankType.TANK_TYPE_RESEARCHABLE,
TankType.TANK_TYPE_PREMIUM,
TankType.TANK_TYPE_COLLECTOR,
];
export function metaSortTank(
tanks: TankDefinition[],
gameDefinitions: GameDefinitions
gameDefinitions: GameDefinitions,
) {
return tanks
.sort((a, b) => b.tier - a.tier)
.sort(
(a, b) => treeTypeOrder.indexOf(b.type) - treeTypeOrder.indexOf(a.type)
(a, b) => treeTypeOrder.indexOf(b.type) - treeTypeOrder.indexOf(a.type),
)
.sort(
(a, b) => TANK_CLASSES.indexOf(b.class) - TANK_CLASSES.indexOf(a.class)
(a, b) => TANK_CLASSES.indexOf(b.class) - TANK_CLASSES.indexOf(a.class),
)
.sort(
(a, b) =>
gameDefinitions.nations.indexOf(b.nation) -
gameDefinitions.nations.indexOf(a.nation)
gameDefinitions.nations.indexOf(a.nation),
)
.sort((a, b) => a.tier - b.tier);
}
@@ -2,8 +2,8 @@ import { BoundingBox, Vector3 } from "../protos";
export function normalizeBoundingBox(boundingBox: BoundingBox) {
return {
x: boundingBox.max.x - boundingBox.min.x,
y: boundingBox.max.y - boundingBox.min.y,
z: boundingBox.max.z - boundingBox.min.z,
x: boundingBox.max!.x - boundingBox.min!.x,
y: boundingBox.max!.y - boundingBox.min!.y,
z: boundingBox.max!.z - boundingBox.min!.z,
} satisfies Vector3;
}
@@ -1,4 +1,4 @@
import { ShellType } from '../protos';
import { ShellType } from "../protos";
export function resolvePenetrationCoefficient(
calibratedShells: boolean,
@@ -6,11 +6,11 @@ export function resolvePenetrationCoefficient(
) {
if (!calibratedShells) return 1;
return type === ShellType.AP
return type === ShellType.SHELL_TYPE_AP
? 1.08
: type === ShellType.APCR
: type === ShellType.SHELL_TYPE_APCR
? 1.05
: type === ShellType.HEAT
: type === ShellType.SHELL_TYPE_HEAT
? 1.13
: 1.08;
}
@@ -1,74 +1,74 @@
import { times } from 'lodash-es';
import { CrewType, ShellType, TankClass, TankType } from '../../protos';
import { times } from "lodash-es";
import { CrewType, ShellType, TankClass, TankType } from "../../protos";
export const SHELL_NAMES: Record<ShellType, string> = {
[ShellType.AP]: 'AP',
[ShellType.APCR]: 'APCR',
[ShellType.HEAT]: 'HEAT',
[ShellType.HE]: 'HE',
[ShellType.SHELL_TYPE_AP]: "AP",
[ShellType.SHELL_TYPE_APCR]: "APCR",
[ShellType.SHELL_TYPE_HEAT]: "HEAT",
[ShellType.SHELL_TYPE_HE]: "HE",
};
export const CREW_MEMBER_NAMES = {
[CrewType.COMMANDER]: 'commander',
[CrewType.DRIVER]: 'driver',
[CrewType.GUNNER]: 'gunner',
[CrewType.LOADER]: 'loader',
[CrewType.RADIOMAN]: 'radioman',
[CrewType.CREW_TYPE_COMMANDER]: "commander",
[CrewType.CREW_TYPE_DRIVER]: "driver",
[CrewType.CREW_TYPE_GUNNER]: "gunner",
[CrewType.CREW_TYPE_LOADER]: "loader",
[CrewType.CREW_TYPE_RADIOMAN]: "radioman",
} as const;
/**
* @deprecated use svg
*/
export const TANK_ICONS: Record<TankClass, string> = {
[TankClass.TANK_DESTROYER]: 'https://i.imgur.com/BIHSEH0.png',
[TankClass.LIGHT]: 'https://i.imgur.com/CSNha5V.png',
[TankClass.MEDIUM]: 'https://i.imgur.com/wvf3ltm.png',
[TankClass.HEAVY]: 'https://i.imgur.com/ECeqlZa.png',
[TankClass.TANK_CLASS_TANK_DESTROYER]: "https://i.imgur.com/BIHSEH0.png",
[TankClass.TANK_CLASS_LIGHT]: "https://i.imgur.com/CSNha5V.png",
[TankClass.TANK_CLASS_MEDIUM]: "https://i.imgur.com/wvf3ltm.png",
[TankClass.TANK_CLASS_HEAVY]: "https://i.imgur.com/ECeqlZa.png",
};
/**
* @deprecated use svg
*/
export const TANK_ICONS_PREMIUM: Record<TankClass, string> = {
[TankClass.TANK_DESTROYER]: 'https://i.imgur.com/TCu3EdR.png',
[TankClass.LIGHT]: 'https://i.imgur.com/zdkpTRb.png',
[TankClass.MEDIUM]: 'https://i.imgur.com/3z7eHX6.png',
[TankClass.HEAVY]: 'https://i.imgur.com/P3vbmyA.png',
[TankClass.TANK_CLASS_TANK_DESTROYER]: "https://i.imgur.com/TCu3EdR.png",
[TankClass.TANK_CLASS_LIGHT]: "https://i.imgur.com/zdkpTRb.png",
[TankClass.TANK_CLASS_MEDIUM]: "https://i.imgur.com/3z7eHX6.png",
[TankClass.TANK_CLASS_HEAVY]: "https://i.imgur.com/P3vbmyA.png",
};
/**
* @deprecated use svg
*/
export const TANK_ICONS_COLLECTOR: Record<TankClass, string> = {
[TankClass.TANK_DESTROYER]: 'https://i.imgur.com/WTjeirB.png',
[TankClass.LIGHT]: 'https://i.imgur.com/EwhtKkU.png',
[TankClass.MEDIUM]: 'https://i.imgur.com/u8YDMBh.png',
[TankClass.HEAVY]: 'https://i.imgur.com/8xRf3nc.png',
[TankClass.TANK_CLASS_TANK_DESTROYER]: "https://i.imgur.com/WTjeirB.png",
[TankClass.TANK_CLASS_LIGHT]: "https://i.imgur.com/EwhtKkU.png",
[TankClass.TANK_CLASS_MEDIUM]: "https://i.imgur.com/u8YDMBh.png",
[TankClass.TANK_CLASS_HEAVY]: "https://i.imgur.com/8xRf3nc.png",
};
export const TIERS = times(10, (index) => index + 1);
export const TIER_ROMAN_NUMERALS: Record<number, string> = {
1: 'I',
2: 'II',
3: 'III',
4: 'IV',
5: 'V',
6: 'VI',
7: 'VII',
8: 'VIII',
9: 'IX',
10: 'X',
1: "I",
2: "II",
3: "III",
4: "IV",
5: "V",
6: "VI",
7: "VII",
8: "VIII",
9: "IX",
10: "X",
};
export const flags: Record<string, string> = {
ussr: '<:ussr:1218421042033197197>',
germany: '🇩🇪',
usa: '🇺🇸',
china: '🇨🇳',
uk: '🇬🇧',
france: '🇫🇷',
japan: '🇯🇵',
european: '🇪🇺',
other: '<:other:1218421572243558482>',
ussr: "<:ussr:1218421042033197197>",
germany: "🇩🇪",
usa: "🇺🇸",
china: "🇨🇳",
uk: "🇬🇧",
france: "🇫🇷",
japan: "🇯🇵",
european: "🇪🇺",
other: "<:other:1218421572243558482>",
};
export const TREE_TYPE_ICONS: Record<TankType, Record<TankClass, string>> = {
[TankType.RESEARCHABLE]: TANK_ICONS,
[TankType.PREMIUM]: TANK_ICONS_PREMIUM,
[TankType.COLLECTOR]: TANK_ICONS_COLLECTOR,
[TankType.TANK_TYPE_RESEARCHABLE]: TANK_ICONS,
[TankType.TANK_TYPE_PREMIUM]: TANK_ICONS_PREMIUM,
[TankType.TANK_TYPE_COLLECTOR]: TANK_ICONS_COLLECTOR,
};
+4 -4
View File
@@ -15,7 +15,7 @@ export async function fetchTankNames() {
tankDefinitionsArray.map(async (tank) => {
const searchableNameDeburr: I18nString = { locales: {} };
Object.entries(tank.name).forEach(([key, value]) => {
Object.entries(tank.name!).forEach(([key, value]) => {
searchableNameDeburr.locales[key] = deburr(value);
});
@@ -28,8 +28,8 @@ export async function fetchTankNames() {
?.map((id) =>
locales.supported.map(
({ locale }) =>
camouflageDefinitions.camouflages[id]?.name.locales[locale]
)
camouflageDefinitions.camouflages[id]?.name!.locales[locale],
),
)
.flat()
.filter(Boolean)
@@ -37,7 +37,7 @@ export async function fetchTankNames() {
.join(" "),
treeType: tank.type,
};
})
}),
);
}
@@ -3,14 +3,14 @@ import { BoundingBox } from "../protos";
export function unionBoundingBox(a: BoundingBox, b: BoundingBox) {
return {
min: {
x: Math.min(a.min.x, b.min.x),
y: Math.min(a.min.y, b.min.y),
z: Math.min(a.min.z, b.min.z),
x: Math.min(a.min!.x, b.min!.x),
y: Math.min(a.min!.y, b.min!.y),
z: Math.min(a.min!.z, b.min!.z),
},
max: {
x: Math.max(a.max.x, b.max.x),
y: Math.max(a.max.y, b.max.y),
z: Math.max(a.max.z, b.max.z),
x: Math.max(a.max!.x, b.max!.x),
y: Math.max(a.max!.y, b.max!.y),
z: Math.max(a.max!.z, b.max!.z),
},
} satisfies BoundingBox;
}
@@ -4,44 +4,44 @@ package blitzkit;
message AverageDefinitions {
map<uint32, AverageDefinitionsEntry> averages = 1;
required Samples samples = 2;
required uint64 time = 3;
required Samples samples = 2;
required uint64 time = 3;
}
message AverageDefinitionsEntry {
required AverageDefinitionsAllStats mu = 1;
required AverageDefinitionsAllStats sigma = 2;
required AverageDefinitionsAllStats r = 3;
required Samples samples = 4;
required AverageDefinitionsAllStats mu = 1;
required AverageDefinitionsAllStats sigma = 2;
required AverageDefinitionsAllStats r = 3;
required Samples samples = 4;
}
message AverageDefinitionsAllStats {
required float battles = 1;
required float capture_points = 2;
required float damage_dealt = 3;
required float damage_received = 4;
required float battles = 1;
required float capture_points = 2;
required float damage_dealt = 3;
required float damage_received = 4;
required float dropped_capture_points = 5;
required float frags = 6;
required float frags8p = 7;
required float hits = 8;
required float losses = 9;
required float max_frags = 10;
required float max_xp = 11;
required float shots = 12;
required float spotted = 13;
required float survived_battles = 14;
required float win_and_survived = 15;
required float wins = 16;
required float xp = 17;
required float battle_life_time = 18;
required float frags = 6;
required float frags8p = 7;
required float hits = 8;
required float losses = 9;
required float max_frags = 10;
required float max_xp = 11;
required float shots = 12;
required float spotted = 13;
required float survived_battles = 14;
required float win_and_survived = 15;
required float wins = 16;
required float xp = 17;
required float battle_life_time = 18;
}
message Samples {
required uint32 d_1 = 1;
required uint32 d_7 = 2;
required uint32 d_30 = 3;
required uint32 d_60 = 4;
required uint32 d_90 = 5;
required uint32 d_1 = 1;
required uint32 d_7 = 2;
required uint32 d_30 = 3;
required uint32 d_60 = 4;
required uint32 d_90 = 5;
required uint32 d_120 = 6;
required uint32 total = 7;
}
+127 -107
View File
@@ -1,8 +1,8 @@
// Code generated by protoc-gen-ts_proto. DO NOT EDIT.
// versions:
// protoc-gen-ts_proto v2.2.2
// protoc-gen-ts_proto v2.11.2
// protoc v5.28.2
// source: packages/core/src/protos/average_definitions.proto
// source: average_definitions.proto
/* eslint-disable */
import { BinaryReader, BinaryWriter } from "@bufbuild/protobuf/wire";
@@ -11,7 +11,7 @@ export const protobufPackage = "blitzkit";
export interface AverageDefinitions {
averages: { [key: number]: AverageDefinitionsEntry };
samples: Samples;
samples: Samples | undefined;
time: number;
}
@@ -21,10 +21,10 @@ export interface AverageDefinitions_AveragesEntry {
}
export interface AverageDefinitionsEntry {
mu: AverageDefinitionsAllStats;
sigma: AverageDefinitionsAllStats;
r: AverageDefinitionsAllStats;
samples: Samples;
mu: AverageDefinitionsAllStats | undefined;
sigma: AverageDefinitionsAllStats | undefined;
r: AverageDefinitionsAllStats | undefined;
samples: Samples | undefined;
}
export interface AverageDefinitionsAllStats {
@@ -58,13 +58,13 @@ export interface Samples {
total: number;
}
export function createBaseAverageDefinitions(): AverageDefinitions {
return { averages: {}, samples: createBaseSamples(), time: 0 };
function createBaseAverageDefinitions(): AverageDefinitions {
return { averages: {}, samples: undefined, time: 0 };
}
export const AverageDefinitions: MessageFns<AverageDefinitions> = {
encode(message: AverageDefinitions, writer: BinaryWriter = new BinaryWriter()): BinaryWriter {
Object.entries(message.averages).forEach(([key, value]) => {
globalThis.Object.entries(message.averages).forEach(([key, value]: [string, AverageDefinitionsEntry]) => {
AverageDefinitions_AveragesEntry.encode({ key: key as any, value }, writer.uint32(10).fork()).join();
});
if (message.samples !== undefined) {
@@ -78,7 +78,7 @@ export const AverageDefinitions: MessageFns<AverageDefinitions> = {
decode(input: BinaryReader | Uint8Array, length?: number): AverageDefinitions {
const reader = input instanceof BinaryReader ? input : new BinaryReader(input);
let end = length === undefined ? reader.len : reader.pos + length;
const end = length === undefined ? reader.len : reader.pos + length;
const message = createBaseAverageDefinitions();
while (reader.pos < end) {
const tag = reader.uint32();
@@ -122,20 +122,23 @@ export const AverageDefinitions: MessageFns<AverageDefinitions> = {
fromJSON(object: any): AverageDefinitions {
return {
averages: isObject(object.averages)
? Object.entries(object.averages).reduce<{ [key: number]: AverageDefinitionsEntry }>((acc, [key, value]) => {
acc[globalThis.Number(key)] = AverageDefinitionsEntry.fromJSON(value);
return acc;
}, {})
? (globalThis.Object.entries(object.averages) as [string, any][]).reduce(
(acc: { [key: number]: AverageDefinitionsEntry }, [key, value]: [string, any]) => {
acc[globalThis.Number(key)] = AverageDefinitionsEntry.fromJSON(value);
return acc;
},
{},
)
: {},
samples: Samples.fromJSON(assertSet("AverageDefinitions.samples", object.samples)),
time: globalThis.Number(assertSet("AverageDefinitions.time", object.time)),
samples: isSet(object.samples) ? Samples.fromJSON(object.samples) : undefined,
time: isSet(object.time) ? globalThis.Number(object.time) : 0,
};
},
toJSON(message: AverageDefinitions): unknown {
const obj: any = {};
if (message.averages) {
const entries = Object.entries(message.averages);
const entries = globalThis.Object.entries(message.averages) as [string, AverageDefinitionsEntry][];
if (entries.length > 0) {
obj.averages = {};
entries.forEach(([k, v]) => {
@@ -157,8 +160,8 @@ export const AverageDefinitions: MessageFns<AverageDefinitions> = {
},
fromPartial<I extends Exact<DeepPartial<AverageDefinitions>, I>>(object: I): AverageDefinitions {
const message = createBaseAverageDefinitions();
message.averages = Object.entries(object.averages ?? {}).reduce<{ [key: number]: AverageDefinitionsEntry }>(
(acc, [key, value]) => {
message.averages = (globalThis.Object.entries(object.averages ?? {}) as [string, AverageDefinitionsEntry][]).reduce(
(acc: { [key: number]: AverageDefinitionsEntry }, [key, value]: [string, AverageDefinitionsEntry]) => {
if (value !== undefined) {
acc[globalThis.Number(key)] = AverageDefinitionsEntry.fromPartial(value);
}
@@ -168,19 +171,19 @@ export const AverageDefinitions: MessageFns<AverageDefinitions> = {
);
message.samples = (object.samples !== undefined && object.samples !== null)
? Samples.fromPartial(object.samples)
: createBaseSamples();
: undefined;
message.time = object.time ?? 0;
return message;
},
};
export function createBaseAverageDefinitions_AveragesEntry(): AverageDefinitions_AveragesEntry {
return { key: 0, value: createBaseAverageDefinitionsEntry() };
function createBaseAverageDefinitions_AveragesEntry(): AverageDefinitions_AveragesEntry {
return { key: 0, value: undefined };
}
export const AverageDefinitions_AveragesEntry: MessageFns<AverageDefinitions_AveragesEntry> = {
encode(message: AverageDefinitions_AveragesEntry, writer: BinaryWriter = new BinaryWriter()): BinaryWriter {
if (message.key !== undefined) {
if (message.key !== 0) {
writer.uint32(8).uint32(message.key);
}
if (message.value !== undefined) {
@@ -191,7 +194,7 @@ export const AverageDefinitions_AveragesEntry: MessageFns<AverageDefinitions_Ave
decode(input: BinaryReader | Uint8Array, length?: number): AverageDefinitions_AveragesEntry {
const reader = input instanceof BinaryReader ? input : new BinaryReader(input);
let end = length === undefined ? reader.len : reader.pos + length;
const end = length === undefined ? reader.len : reader.pos + length;
const message = createBaseAverageDefinitions_AveragesEntry();
while (reader.pos < end) {
const tag = reader.uint32();
@@ -223,14 +226,14 @@ export const AverageDefinitions_AveragesEntry: MessageFns<AverageDefinitions_Ave
fromJSON(object: any): AverageDefinitions_AveragesEntry {
return {
key: globalThis.Number(assertSet("AverageDefinitions_AveragesEntry.key", object.key)),
value: AverageDefinitionsEntry.fromJSON(assertSet("AverageDefinitions_AveragesEntry.value", object.value)),
key: isSet(object.key) ? globalThis.Number(object.key) : 0,
value: isSet(object.value) ? AverageDefinitionsEntry.fromJSON(object.value) : undefined,
};
},
toJSON(message: AverageDefinitions_AveragesEntry): unknown {
const obj: any = {};
if (message.key !== undefined) {
if (message.key !== 0) {
obj.key = Math.round(message.key);
}
if (message.value !== undefined) {
@@ -251,18 +254,13 @@ export const AverageDefinitions_AveragesEntry: MessageFns<AverageDefinitions_Ave
message.key = object.key ?? 0;
message.value = (object.value !== undefined && object.value !== null)
? AverageDefinitionsEntry.fromPartial(object.value)
: createBaseAverageDefinitionsEntry();
: undefined;
return message;
},
};
export function createBaseAverageDefinitionsEntry(): AverageDefinitionsEntry {
return {
mu: createBaseAverageDefinitionsAllStats(),
sigma: createBaseAverageDefinitionsAllStats(),
r: createBaseAverageDefinitionsAllStats(),
samples: createBaseSamples(),
};
function createBaseAverageDefinitionsEntry(): AverageDefinitionsEntry {
return { mu: undefined, sigma: undefined, r: undefined, samples: undefined };
}
export const AverageDefinitionsEntry: MessageFns<AverageDefinitionsEntry> = {
@@ -284,7 +282,7 @@ export const AverageDefinitionsEntry: MessageFns<AverageDefinitionsEntry> = {
decode(input: BinaryReader | Uint8Array, length?: number): AverageDefinitionsEntry {
const reader = input instanceof BinaryReader ? input : new BinaryReader(input);
let end = length === undefined ? reader.len : reader.pos + length;
const end = length === undefined ? reader.len : reader.pos + length;
const message = createBaseAverageDefinitionsEntry();
while (reader.pos < end) {
const tag = reader.uint32();
@@ -332,10 +330,10 @@ export const AverageDefinitionsEntry: MessageFns<AverageDefinitionsEntry> = {
fromJSON(object: any): AverageDefinitionsEntry {
return {
mu: AverageDefinitionsAllStats.fromJSON(assertSet("AverageDefinitionsEntry.mu", object.mu)),
sigma: AverageDefinitionsAllStats.fromJSON(assertSet("AverageDefinitionsEntry.sigma", object.sigma)),
r: AverageDefinitionsAllStats.fromJSON(assertSet("AverageDefinitionsEntry.r", object.r)),
samples: Samples.fromJSON(assertSet("AverageDefinitionsEntry.samples", object.samples)),
mu: isSet(object.mu) ? AverageDefinitionsAllStats.fromJSON(object.mu) : undefined,
sigma: isSet(object.sigma) ? AverageDefinitionsAllStats.fromJSON(object.sigma) : undefined,
r: isSet(object.r) ? AverageDefinitionsAllStats.fromJSON(object.r) : undefined,
samples: isSet(object.samples) ? Samples.fromJSON(object.samples) : undefined,
};
},
@@ -363,21 +361,21 @@ export const AverageDefinitionsEntry: MessageFns<AverageDefinitionsEntry> = {
const message = createBaseAverageDefinitionsEntry();
message.mu = (object.mu !== undefined && object.mu !== null)
? AverageDefinitionsAllStats.fromPartial(object.mu)
: createBaseAverageDefinitionsAllStats();
: undefined;
message.sigma = (object.sigma !== undefined && object.sigma !== null)
? AverageDefinitionsAllStats.fromPartial(object.sigma)
: createBaseAverageDefinitionsAllStats();
: undefined;
message.r = (object.r !== undefined && object.r !== null)
? AverageDefinitionsAllStats.fromPartial(object.r)
: createBaseAverageDefinitionsAllStats();
: undefined;
message.samples = (object.samples !== undefined && object.samples !== null)
? Samples.fromPartial(object.samples)
: createBaseSamples();
: undefined;
return message;
},
};
export function createBaseAverageDefinitionsAllStats(): AverageDefinitionsAllStats {
function createBaseAverageDefinitionsAllStats(): AverageDefinitionsAllStats {
return {
battles: 0,
capture_points: 0,
@@ -461,7 +459,7 @@ export const AverageDefinitionsAllStats: MessageFns<AverageDefinitionsAllStats>
decode(input: BinaryReader | Uint8Array, length?: number): AverageDefinitionsAllStats {
const reader = input instanceof BinaryReader ? input : new BinaryReader(input);
let end = length === undefined ? reader.len : reader.pos + length;
const end = length === undefined ? reader.len : reader.pos + length;
const message = createBaseAverageDefinitionsAllStats();
while (reader.pos < end) {
const tag = reader.uint32();
@@ -621,34 +619,60 @@ export const AverageDefinitionsAllStats: MessageFns<AverageDefinitionsAllStats>
fromJSON(object: any): AverageDefinitionsAllStats {
return {
battles: globalThis.Number(assertSet("AverageDefinitionsAllStats.battles", object.battles)),
capture_points: globalThis.Number(assertSet("AverageDefinitionsAllStats.capture_points", object.capture_points)),
damage_dealt: globalThis.Number(assertSet("AverageDefinitionsAllStats.damage_dealt", object.damage_dealt)),
damage_received: globalThis.Number(
assertSet("AverageDefinitionsAllStats.damage_received", object.damage_received),
),
dropped_capture_points: globalThis.Number(
assertSet("AverageDefinitionsAllStats.dropped_capture_points", object.dropped_capture_points),
),
frags: globalThis.Number(assertSet("AverageDefinitionsAllStats.frags", object.frags)),
frags8p: globalThis.Number(assertSet("AverageDefinitionsAllStats.frags8p", object.frags8p)),
hits: globalThis.Number(assertSet("AverageDefinitionsAllStats.hits", object.hits)),
losses: globalThis.Number(assertSet("AverageDefinitionsAllStats.losses", object.losses)),
max_frags: globalThis.Number(assertSet("AverageDefinitionsAllStats.max_frags", object.max_frags)),
max_xp: globalThis.Number(assertSet("AverageDefinitionsAllStats.max_xp", object.max_xp)),
shots: globalThis.Number(assertSet("AverageDefinitionsAllStats.shots", object.shots)),
spotted: globalThis.Number(assertSet("AverageDefinitionsAllStats.spotted", object.spotted)),
survived_battles: globalThis.Number(
assertSet("AverageDefinitionsAllStats.survived_battles", object.survived_battles),
),
win_and_survived: globalThis.Number(
assertSet("AverageDefinitionsAllStats.win_and_survived", object.win_and_survived),
),
wins: globalThis.Number(assertSet("AverageDefinitionsAllStats.wins", object.wins)),
xp: globalThis.Number(assertSet("AverageDefinitionsAllStats.xp", object.xp)),
battle_life_time: globalThis.Number(
assertSet("AverageDefinitionsAllStats.battle_life_time", object.battle_life_time),
),
battles: isSet(object.battles) ? globalThis.Number(object.battles) : 0,
capture_points: isSet(object.capturePoints)
? globalThis.Number(object.capturePoints)
: isSet(object.capture_points)
? globalThis.Number(object.capture_points)
: 0,
damage_dealt: isSet(object.damageDealt)
? globalThis.Number(object.damageDealt)
: isSet(object.damage_dealt)
? globalThis.Number(object.damage_dealt)
: 0,
damage_received: isSet(object.damageReceived)
? globalThis.Number(object.damageReceived)
: isSet(object.damage_received)
? globalThis.Number(object.damage_received)
: 0,
dropped_capture_points: isSet(object.droppedCapturePoints)
? globalThis.Number(object.droppedCapturePoints)
: isSet(object.dropped_capture_points)
? globalThis.Number(object.dropped_capture_points)
: 0,
frags: isSet(object.frags) ? globalThis.Number(object.frags) : 0,
frags8p: isSet(object.frags8p) ? globalThis.Number(object.frags8p) : 0,
hits: isSet(object.hits) ? globalThis.Number(object.hits) : 0,
losses: isSet(object.losses) ? globalThis.Number(object.losses) : 0,
max_frags: isSet(object.maxFrags)
? globalThis.Number(object.maxFrags)
: isSet(object.max_frags)
? globalThis.Number(object.max_frags)
: 0,
max_xp: isSet(object.maxXp)
? globalThis.Number(object.maxXp)
: isSet(object.max_xp)
? globalThis.Number(object.max_xp)
: 0,
shots: isSet(object.shots) ? globalThis.Number(object.shots) : 0,
spotted: isSet(object.spotted) ? globalThis.Number(object.spotted) : 0,
survived_battles: isSet(object.survivedBattles)
? globalThis.Number(object.survivedBattles)
: isSet(object.survived_battles)
? globalThis.Number(object.survived_battles)
: 0,
win_and_survived: isSet(object.winAndSurvived)
? globalThis.Number(object.winAndSurvived)
: isSet(object.win_and_survived)
? globalThis.Number(object.win_and_survived)
: 0,
wins: isSet(object.wins) ? globalThis.Number(object.wins) : 0,
xp: isSet(object.xp) ? globalThis.Number(object.xp) : 0,
battle_life_time: isSet(object.battleLifeTime)
? globalThis.Number(object.battleLifeTime)
: isSet(object.battle_life_time)
? globalThis.Number(object.battle_life_time)
: 0,
};
},
@@ -658,16 +682,16 @@ export const AverageDefinitionsAllStats: MessageFns<AverageDefinitionsAllStats>
obj.battles = message.battles;
}
if (message.capture_points !== 0) {
obj.capture_points = message.capture_points;
obj.capturePoints = message.capture_points;
}
if (message.damage_dealt !== 0) {
obj.damage_dealt = message.damage_dealt;
obj.damageDealt = message.damage_dealt;
}
if (message.damage_received !== 0) {
obj.damage_received = message.damage_received;
obj.damageReceived = message.damage_received;
}
if (message.dropped_capture_points !== 0) {
obj.dropped_capture_points = message.dropped_capture_points;
obj.droppedCapturePoints = message.dropped_capture_points;
}
if (message.frags !== 0) {
obj.frags = message.frags;
@@ -682,10 +706,10 @@ export const AverageDefinitionsAllStats: MessageFns<AverageDefinitionsAllStats>
obj.losses = message.losses;
}
if (message.max_frags !== 0) {
obj.max_frags = message.max_frags;
obj.maxFrags = message.max_frags;
}
if (message.max_xp !== 0) {
obj.max_xp = message.max_xp;
obj.maxXp = message.max_xp;
}
if (message.shots !== 0) {
obj.shots = message.shots;
@@ -694,10 +718,10 @@ export const AverageDefinitionsAllStats: MessageFns<AverageDefinitionsAllStats>
obj.spotted = message.spotted;
}
if (message.survived_battles !== 0) {
obj.survived_battles = message.survived_battles;
obj.survivedBattles = message.survived_battles;
}
if (message.win_and_survived !== 0) {
obj.win_and_survived = message.win_and_survived;
obj.winAndSurvived = message.win_and_survived;
}
if (message.wins !== 0) {
obj.wins = message.wins;
@@ -706,7 +730,7 @@ export const AverageDefinitionsAllStats: MessageFns<AverageDefinitionsAllStats>
obj.xp = message.xp;
}
if (message.battle_life_time !== 0) {
obj.battle_life_time = message.battle_life_time;
obj.battleLifeTime = message.battle_life_time;
}
return obj;
},
@@ -738,7 +762,7 @@ export const AverageDefinitionsAllStats: MessageFns<AverageDefinitionsAllStats>
},
};
export function createBaseSamples(): Samples {
function createBaseSamples(): Samples {
return { d_1: 0, d_7: 0, d_30: 0, d_60: 0, d_90: 0, d_120: 0, total: 0 };
}
@@ -770,7 +794,7 @@ export const Samples: MessageFns<Samples> = {
decode(input: BinaryReader | Uint8Array, length?: number): Samples {
const reader = input instanceof BinaryReader ? input : new BinaryReader(input);
let end = length === undefined ? reader.len : reader.pos + length;
const end = length === undefined ? reader.len : reader.pos + length;
const message = createBaseSamples();
while (reader.pos < end) {
const tag = reader.uint32();
@@ -842,35 +866,39 @@ export const Samples: MessageFns<Samples> = {
fromJSON(object: any): Samples {
return {
d_1: globalThis.Number(assertSet("Samples.d_1", object.d_1)),
d_7: globalThis.Number(assertSet("Samples.d_7", object.d_7)),
d_30: globalThis.Number(assertSet("Samples.d_30", object.d_30)),
d_60: globalThis.Number(assertSet("Samples.d_60", object.d_60)),
d_90: globalThis.Number(assertSet("Samples.d_90", object.d_90)),
d_120: globalThis.Number(assertSet("Samples.d_120", object.d_120)),
total: globalThis.Number(assertSet("Samples.total", object.total)),
d_1: isSet(object.d1) ? globalThis.Number(object.d1) : isSet(object.d_1) ? globalThis.Number(object.d_1) : 0,
d_7: isSet(object.d7) ? globalThis.Number(object.d7) : isSet(object.d_7) ? globalThis.Number(object.d_7) : 0,
d_30: isSet(object.d30) ? globalThis.Number(object.d30) : isSet(object.d_30) ? globalThis.Number(object.d_30) : 0,
d_60: isSet(object.d60) ? globalThis.Number(object.d60) : isSet(object.d_60) ? globalThis.Number(object.d_60) : 0,
d_90: isSet(object.d90) ? globalThis.Number(object.d90) : isSet(object.d_90) ? globalThis.Number(object.d_90) : 0,
d_120: isSet(object.d120)
? globalThis.Number(object.d120)
: isSet(object.d_120)
? globalThis.Number(object.d_120)
: 0,
total: isSet(object.total) ? globalThis.Number(object.total) : 0,
};
},
toJSON(message: Samples): unknown {
const obj: any = {};
if (message.d_1 !== 0) {
obj.d_1 = Math.round(message.d_1);
obj.d1 = Math.round(message.d_1);
}
if (message.d_7 !== 0) {
obj.d_7 = Math.round(message.d_7);
obj.d7 = Math.round(message.d_7);
}
if (message.d_30 !== 0) {
obj.d_30 = Math.round(message.d_30);
obj.d30 = Math.round(message.d_30);
}
if (message.d_60 !== 0) {
obj.d_60 = Math.round(message.d_60);
obj.d60 = Math.round(message.d_60);
}
if (message.d_90 !== 0) {
obj.d_90 = Math.round(message.d_90);
obj.d90 = Math.round(message.d_90);
}
if (message.d_120 !== 0) {
obj.d_120 = Math.round(message.d_120);
obj.d120 = Math.round(message.d_120);
}
if (message.total !== 0) {
obj.total = Math.round(message.total);
@@ -926,14 +954,6 @@ function isSet(value: any): boolean {
return value !== null && value !== undefined;
}
function assertSet<T>(field: string, value: T | undefined): T {
if (!isSet(value)) {
throw new TypeError(`Required field ${field} is not set`);
}
return value as T;
}
export interface MessageFns<T> {
encode(message: T, writer?: BinaryWriter): BinaryWriter;
decode(input: BinaryReader | Uint8Array, length?: number): T;
@@ -2,15 +2,15 @@ syntax = "proto2";
package blitzkit;
import "packages/core/src/protos/i18n.proto";
import "i18n.proto";
message CamouflageDefinitions {
map<uint32, Camouflage> camouflages = 1;
}
message Camouflage {
required uint32 id = 1;
required I18nString name = 2;
optional I18nString tank_name = 3;
required uint32 id = 1;
required I18nString name = 2;
optional I18nString tank_name = 3;
optional I18nString tank_name_full = 4;
}
+140 -209
View File
@@ -1,14 +1,14 @@
// Code generated by protoc-gen-ts_proto. DO NOT EDIT.
// versions:
// protoc-gen-ts_proto v2.2.2
// protoc-gen-ts_proto v2.11.2
// protoc v5.28.2
// source: packages/core/src/protos/camouflage_definitions.proto
// source: camouflage_definitions.proto
/* eslint-disable */
import { BinaryReader, BinaryWriter } from '@bufbuild/protobuf/wire';
import { createBaseI18nString, I18nString } from './i18n';
import { BinaryReader, BinaryWriter } from "@bufbuild/protobuf/wire";
import { I18nString } from "./i18n";
export const protobufPackage = 'blitzkit';
export const protobufPackage = "blitzkit";
export interface CamouflageDefinitions {
camouflages: { [key: number]: Camouflage };
@@ -21,36 +21,26 @@ export interface CamouflageDefinitions_CamouflagesEntry {
export interface Camouflage {
id: number;
name: I18nString;
tank_name?: I18nString;
tank_name_full?: I18nString;
name: I18nString | undefined;
tank_name?: I18nString | undefined;
tank_name_full?: I18nString | undefined;
}
export function createBaseCamouflageDefinitions(): CamouflageDefinitions {
function createBaseCamouflageDefinitions(): CamouflageDefinitions {
return { camouflages: {} };
}
export const CamouflageDefinitions: MessageFns<CamouflageDefinitions> = {
encode(
message: CamouflageDefinitions,
writer: BinaryWriter = new BinaryWriter(),
): BinaryWriter {
Object.entries(message.camouflages).forEach(([key, value]) => {
CamouflageDefinitions_CamouflagesEntry.encode(
{ key: key as any, value },
writer.uint32(10).fork(),
).join();
encode(message: CamouflageDefinitions, writer: BinaryWriter = new BinaryWriter()): BinaryWriter {
globalThis.Object.entries(message.camouflages).forEach(([key, value]: [string, Camouflage]) => {
CamouflageDefinitions_CamouflagesEntry.encode({ key: key as any, value }, writer.uint32(10).fork()).join();
});
return writer;
},
decode(
input: BinaryReader | Uint8Array,
length?: number,
): CamouflageDefinitions {
const reader =
input instanceof BinaryReader ? input : new BinaryReader(input);
let end = length === undefined ? reader.len : reader.pos + length;
decode(input: BinaryReader | Uint8Array, length?: number): CamouflageDefinitions {
const reader = input instanceof BinaryReader ? input : new BinaryReader(input);
const end = length === undefined ? reader.len : reader.pos + length;
const message = createBaseCamouflageDefinitions();
while (reader.pos < end) {
const tag = reader.uint32();
@@ -60,10 +50,7 @@ export const CamouflageDefinitions: MessageFns<CamouflageDefinitions> = {
break;
}
const entry1 = CamouflageDefinitions_CamouflagesEntry.decode(
reader,
reader.uint32(),
);
const entry1 = CamouflageDefinitions_CamouflagesEntry.decode(reader, reader.uint32());
if (entry1.value !== undefined) {
message.camouflages[entry1.key] = entry1.value;
}
@@ -81,12 +68,13 @@ export const CamouflageDefinitions: MessageFns<CamouflageDefinitions> = {
fromJSON(object: any): CamouflageDefinitions {
return {
camouflages: isObject(object.camouflages)
? Object.entries(object.camouflages).reduce<{
[key: number]: Camouflage;
}>((acc, [key, value]) => {
? (globalThis.Object.entries(object.camouflages) as [string, any][]).reduce(
(acc: { [key: number]: Camouflage }, [key, value]: [string, any]) => {
acc[globalThis.Number(key)] = Camouflage.fromJSON(value);
return acc;
}, {})
},
{},
)
: {},
};
},
@@ -94,7 +82,7 @@ export const CamouflageDefinitions: MessageFns<CamouflageDefinitions> = {
toJSON(message: CamouflageDefinitions): unknown {
const obj: any = {};
if (message.camouflages) {
const entries = Object.entries(message.camouflages);
const entries = globalThis.Object.entries(message.camouflages) as [string, Camouflage][];
if (entries.length > 0) {
obj.camouflages = {};
entries.forEach(([k, v]) => {
@@ -105,141 +93,112 @@ export const CamouflageDefinitions: MessageFns<CamouflageDefinitions> = {
return obj;
},
create<I extends Exact<DeepPartial<CamouflageDefinitions>, I>>(
base?: I,
): CamouflageDefinitions {
create<I extends Exact<DeepPartial<CamouflageDefinitions>, I>>(base?: I): CamouflageDefinitions {
return CamouflageDefinitions.fromPartial(base ?? ({} as any));
},
fromPartial<I extends Exact<DeepPartial<CamouflageDefinitions>, I>>(
object: I,
): CamouflageDefinitions {
fromPartial<I extends Exact<DeepPartial<CamouflageDefinitions>, I>>(object: I): CamouflageDefinitions {
const message = createBaseCamouflageDefinitions();
message.camouflages = Object.entries(object.camouflages ?? {}).reduce<{
[key: number]: Camouflage;
}>((acc, [key, value]) => {
if (value !== undefined) {
acc[globalThis.Number(key)] = Camouflage.fromPartial(value);
}
return acc;
}, {});
message.camouflages = (globalThis.Object.entries(object.camouflages ?? {}) as [string, Camouflage][]).reduce(
(acc: { [key: number]: Camouflage }, [key, value]: [string, Camouflage]) => {
if (value !== undefined) {
acc[globalThis.Number(key)] = Camouflage.fromPartial(value);
}
return acc;
},
{},
);
return message;
},
};
export function createBaseCamouflageDefinitions_CamouflagesEntry(): CamouflageDefinitions_CamouflagesEntry {
return { key: 0, value: createBaseCamouflage() };
function createBaseCamouflageDefinitions_CamouflagesEntry(): CamouflageDefinitions_CamouflagesEntry {
return { key: 0, value: undefined };
}
export const CamouflageDefinitions_CamouflagesEntry: MessageFns<CamouflageDefinitions_CamouflagesEntry> =
{
encode(
message: CamouflageDefinitions_CamouflagesEntry,
writer: BinaryWriter = new BinaryWriter(),
): BinaryWriter {
if (message.key !== undefined) {
writer.uint32(8).uint32(message.key);
}
if (message.value !== undefined) {
Camouflage.encode(message.value, writer.uint32(18).fork()).join();
}
return writer;
},
export const CamouflageDefinitions_CamouflagesEntry: MessageFns<CamouflageDefinitions_CamouflagesEntry> = {
encode(message: CamouflageDefinitions_CamouflagesEntry, writer: BinaryWriter = new BinaryWriter()): BinaryWriter {
if (message.key !== 0) {
writer.uint32(8).uint32(message.key);
}
if (message.value !== undefined) {
Camouflage.encode(message.value, writer.uint32(18).fork()).join();
}
return writer;
},
decode(
input: BinaryReader | Uint8Array,
length?: number,
): CamouflageDefinitions_CamouflagesEntry {
const reader =
input instanceof BinaryReader ? input : new BinaryReader(input);
let end = length === undefined ? reader.len : reader.pos + length;
const message = createBaseCamouflageDefinitions_CamouflagesEntry();
while (reader.pos < end) {
const tag = reader.uint32();
switch (tag >>> 3) {
case 1: {
if (tag !== 8) {
break;
}
message.key = reader.uint32();
continue;
decode(input: BinaryReader | Uint8Array, length?: number): CamouflageDefinitions_CamouflagesEntry {
const reader = input instanceof BinaryReader ? input : new BinaryReader(input);
const end = length === undefined ? reader.len : reader.pos + length;
const message = createBaseCamouflageDefinitions_CamouflagesEntry();
while (reader.pos < end) {
const tag = reader.uint32();
switch (tag >>> 3) {
case 1: {
if (tag !== 8) {
break;
}
case 2: {
if (tag !== 18) {
break;
}
message.value = Camouflage.decode(reader, reader.uint32());
continue;
message.key = reader.uint32();
continue;
}
case 2: {
if (tag !== 18) {
break;
}
message.value = Camouflage.decode(reader, reader.uint32());
continue;
}
if ((tag & 7) === 4 || tag === 0) {
break;
}
reader.skip(tag & 7);
}
return message;
},
fromJSON(object: any): CamouflageDefinitions_CamouflagesEntry {
return {
key: globalThis.Number(
assertSet('CamouflageDefinitions_CamouflagesEntry.key', object.key),
),
value: Camouflage.fromJSON(
assertSet(
'CamouflageDefinitions_CamouflagesEntry.value',
object.value,
),
),
};
},
toJSON(message: CamouflageDefinitions_CamouflagesEntry): unknown {
const obj: any = {};
if (message.key !== undefined) {
obj.key = Math.round(message.key);
if ((tag & 7) === 4 || tag === 0) {
break;
}
if (message.value !== undefined) {
obj.value = Camouflage.toJSON(message.value);
}
return obj;
},
reader.skip(tag & 7);
}
return message;
},
create<
I extends Exact<DeepPartial<CamouflageDefinitions_CamouflagesEntry>, I>,
>(base?: I): CamouflageDefinitions_CamouflagesEntry {
return CamouflageDefinitions_CamouflagesEntry.fromPartial(
base ?? ({} as any),
);
},
fromPartial<
I extends Exact<DeepPartial<CamouflageDefinitions_CamouflagesEntry>, I>,
>(object: I): CamouflageDefinitions_CamouflagesEntry {
const message = createBaseCamouflageDefinitions_CamouflagesEntry();
message.key = object.key ?? 0;
message.value =
object.value !== undefined && object.value !== null
? Camouflage.fromPartial(object.value)
: createBaseCamouflage();
return message;
},
};
fromJSON(object: any): CamouflageDefinitions_CamouflagesEntry {
return {
key: isSet(object.key) ? globalThis.Number(object.key) : 0,
value: isSet(object.value) ? Camouflage.fromJSON(object.value) : undefined,
};
},
export function createBaseCamouflage(): Camouflage {
return {
id: 0,
name: createBaseI18nString(),
tank_name: undefined,
tank_name_full: undefined,
};
toJSON(message: CamouflageDefinitions_CamouflagesEntry): unknown {
const obj: any = {};
if (message.key !== 0) {
obj.key = Math.round(message.key);
}
if (message.value !== undefined) {
obj.value = Camouflage.toJSON(message.value);
}
return obj;
},
create<I extends Exact<DeepPartial<CamouflageDefinitions_CamouflagesEntry>, I>>(
base?: I,
): CamouflageDefinitions_CamouflagesEntry {
return CamouflageDefinitions_CamouflagesEntry.fromPartial(base ?? ({} as any));
},
fromPartial<I extends Exact<DeepPartial<CamouflageDefinitions_CamouflagesEntry>, I>>(
object: I,
): CamouflageDefinitions_CamouflagesEntry {
const message = createBaseCamouflageDefinitions_CamouflagesEntry();
message.key = object.key ?? 0;
message.value = (object.value !== undefined && object.value !== null)
? Camouflage.fromPartial(object.value)
: undefined;
return message;
},
};
function createBaseCamouflage(): Camouflage {
return { id: 0, name: undefined, tank_name: undefined, tank_name_full: undefined };
}
export const Camouflage: MessageFns<Camouflage> = {
encode(
message: Camouflage,
writer: BinaryWriter = new BinaryWriter(),
): BinaryWriter {
encode(message: Camouflage, writer: BinaryWriter = new BinaryWriter()): BinaryWriter {
if (message.id !== 0) {
writer.uint32(8).uint32(message.id);
}
@@ -250,18 +209,14 @@ export const Camouflage: MessageFns<Camouflage> = {
I18nString.encode(message.tank_name, writer.uint32(26).fork()).join();
}
if (message.tank_name_full !== undefined) {
I18nString.encode(
message.tank_name_full,
writer.uint32(34).fork(),
).join();
I18nString.encode(message.tank_name_full, writer.uint32(34).fork()).join();
}
return writer;
},
decode(input: BinaryReader | Uint8Array, length?: number): Camouflage {
const reader =
input instanceof BinaryReader ? input : new BinaryReader(input);
let end = length === undefined ? reader.len : reader.pos + length;
const reader = input instanceof BinaryReader ? input : new BinaryReader(input);
const end = length === undefined ? reader.len : reader.pos + length;
const message = createBaseCamouflage();
while (reader.pos < end) {
const tag = reader.uint32();
@@ -309,12 +264,16 @@ export const Camouflage: MessageFns<Camouflage> = {
fromJSON(object: any): Camouflage {
return {
id: globalThis.Number(assertSet('Camouflage.id', object.id)),
name: I18nString.fromJSON(assertSet('Camouflage.name', object.name)),
tank_name: isSet(object.tank_name)
id: isSet(object.id) ? globalThis.Number(object.id) : 0,
name: isSet(object.name) ? I18nString.fromJSON(object.name) : undefined,
tank_name: isSet(object.tankName)
? I18nString.fromJSON(object.tankName)
: isSet(object.tank_name)
? I18nString.fromJSON(object.tank_name)
: undefined,
tank_name_full: isSet(object.tank_name_full)
tank_name_full: isSet(object.tankNameFull)
? I18nString.fromJSON(object.tankNameFull)
: isSet(object.tank_name_full)
? I18nString.fromJSON(object.tank_name_full)
: undefined,
};
@@ -329,10 +288,10 @@ export const Camouflage: MessageFns<Camouflage> = {
obj.name = I18nString.toJSON(message.name);
}
if (message.tank_name !== undefined) {
obj.tank_name = I18nString.toJSON(message.tank_name);
obj.tankName = I18nString.toJSON(message.tank_name);
}
if (message.tank_name_full !== undefined) {
obj.tank_name_full = I18nString.toJSON(message.tank_name_full);
obj.tankNameFull = I18nString.toJSON(message.tank_name_full);
}
return obj;
},
@@ -340,71 +299,43 @@ export const Camouflage: MessageFns<Camouflage> = {
create<I extends Exact<DeepPartial<Camouflage>, I>>(base?: I): Camouflage {
return Camouflage.fromPartial(base ?? ({} as any));
},
fromPartial<I extends Exact<DeepPartial<Camouflage>, I>>(
object: I,
): Camouflage {
fromPartial<I extends Exact<DeepPartial<Camouflage>, I>>(object: I): Camouflage {
const message = createBaseCamouflage();
message.id = object.id ?? 0;
message.name =
object.name !== undefined && object.name !== null
? I18nString.fromPartial(object.name)
: createBaseI18nString();
message.tank_name =
object.tank_name !== undefined && object.tank_name !== null
? I18nString.fromPartial(object.tank_name)
: undefined;
message.tank_name_full =
object.tank_name_full !== undefined && object.tank_name_full !== null
? I18nString.fromPartial(object.tank_name_full)
: undefined;
message.name = (object.name !== undefined && object.name !== null)
? I18nString.fromPartial(object.name)
: undefined;
message.tank_name = (object.tank_name !== undefined && object.tank_name !== null)
? I18nString.fromPartial(object.tank_name)
: undefined;
message.tank_name_full = (object.tank_name_full !== undefined && object.tank_name_full !== null)
? I18nString.fromPartial(object.tank_name_full)
: undefined;
return message;
},
};
type Builtin =
| Date
| Function
| Uint8Array
| string
| number
| boolean
| undefined;
type Builtin = Date | Function | Uint8Array | string | number | boolean | undefined;
export type DeepPartial<T> = T extends Builtin
? T
: T extends globalThis.Array<infer U>
? globalThis.Array<DeepPartial<U>>
: T extends ReadonlyArray<infer U>
? ReadonlyArray<DeepPartial<U>>
: T extends { $case: string; value: unknown }
? { $case: T['$case']; value?: DeepPartial<T['value']> }
: T extends {}
? { [K in keyof T]?: DeepPartial<T[K]> }
: Partial<T>;
export type DeepPartial<T> = T extends Builtin ? T
: T extends globalThis.Array<infer U> ? globalThis.Array<DeepPartial<U>>
: T extends ReadonlyArray<infer U> ? ReadonlyArray<DeepPartial<U>>
: T extends { $case: string; value: unknown } ? { $case: T["$case"]; value?: DeepPartial<T["value"]> }
: T extends {} ? { [K in keyof T]?: DeepPartial<T[K]> }
: Partial<T>;
type KeysOfUnion<T> = T extends T ? keyof T : never;
export type Exact<P, I extends P> = P extends Builtin
? P
: P & { [K in keyof P]: Exact<P[K], I[K]> } & {
[K in Exclude<keyof I, KeysOfUnion<P>>]: never;
};
export type Exact<P, I extends P> = P extends Builtin ? P
: P & { [K in keyof P]: Exact<P[K], I[K]> } & { [K in Exclude<keyof I, KeysOfUnion<P>>]: never };
function isObject(value: any): boolean {
return typeof value === 'object' && value !== null;
return typeof value === "object" && value !== null;
}
function isSet(value: any): boolean {
return value !== null && value !== undefined;
}
function assertSet<T>(field: string, value: T | undefined): T {
if (!isSet(value)) {
throw new TypeError(`Required field ${field} is not set`);
}
return value as T;
}
export interface MessageFns<T> {
encode(message: T, writer?: BinaryWriter): BinaryWriter;
decode(input: BinaryReader | Uint8Array, length?: number): T;
@@ -2,28 +2,28 @@ syntax = "proto2";
package blitzkit;
import "packages/core/src/protos/i18n.proto";
import "i18n.proto";
message ConsumableDefinitions {
map<uint32, Consumable> consumables = 1;
}
message Consumable {
required uint32 id = 1;
required I18nString name = 2;
required uint32 cooldown = 3;
optional float duration = 4;
required bool game_mode_exclusive = 5;
repeated ConsumableTankFilter include = 6;
repeated ConsumableTankFilter exclude = 7;
required uint32 id = 1;
required I18nString name = 2;
required uint32 cooldown = 3;
optional float duration = 4;
required bool game_mode_exclusive = 5;
repeated ConsumableTankFilter include = 6;
repeated ConsumableTankFilter exclude = 7;
}
message ConsumableTankFilter {
oneof filter_type {
ConsumableTankTierFilter tiers = 1;
ConsumableTankIdsFilter ids = 2;
ConsumableTankTierFilter tiers = 1;
ConsumableTankIdsFilter ids = 2;
ConsumableTankCategoryFilter categories = 3;
ConsumableTankNationFilter nations = 4;
ConsumableTankNationFilter nations = 4;
}
}
@@ -1,24 +1,24 @@
// Code generated by protoc-gen-ts_proto. DO NOT EDIT.
// versions:
// protoc-gen-ts_proto v2.2.2
// protoc-gen-ts_proto v2.11.2
// protoc v5.28.2
// source: packages/core/src/protos/consumable_definitions.proto
// source: consumable_definitions.proto
/* eslint-disable */
import { BinaryReader, BinaryWriter } from "@bufbuild/protobuf/wire";
import { createBaseI18nString, I18nString } from "./i18n";
import { I18nString } from "./i18n";
export const protobufPackage = "blitzkit";
export enum ConsumableTankCategoryFilterCategory {
CLIP = 0,
CONSUMABLE_TANK_CATEGORY_FILTER_CATEGORY_CLIP = 0,
}
export function consumableTankCategoryFilterCategoryFromJSON(object: any): ConsumableTankCategoryFilterCategory {
switch (object) {
case 0:
case "CONSUMABLE_TANK_CATEGORY_FILTER_CATEGORY_CLIP":
return ConsumableTankCategoryFilterCategory.CLIP;
return ConsumableTankCategoryFilterCategory.CONSUMABLE_TANK_CATEGORY_FILTER_CATEGORY_CLIP;
default:
throw new globalThis.Error(
"Unrecognized enum value " + object + " for enum ConsumableTankCategoryFilterCategory",
@@ -28,7 +28,7 @@ export function consumableTankCategoryFilterCategoryFromJSON(object: any): Consu
export function consumableTankCategoryFilterCategoryToJSON(object: ConsumableTankCategoryFilterCategory): string {
switch (object) {
case ConsumableTankCategoryFilterCategory.CLIP:
case ConsumableTankCategoryFilterCategory.CONSUMABLE_TANK_CATEGORY_FILTER_CATEGORY_CLIP:
return "CONSUMABLE_TANK_CATEGORY_FILTER_CATEGORY_CLIP";
default:
throw new globalThis.Error(
@@ -48,7 +48,7 @@ export interface ConsumableDefinitions_ConsumablesEntry {
export interface Consumable {
id: number;
name: I18nString;
name: I18nString | undefined;
cooldown: number;
duration?: number | undefined;
game_mode_exclusive: boolean;
@@ -82,13 +82,13 @@ export interface ConsumableTankNationFilter {
nations: string[];
}
export function createBaseConsumableDefinitions(): ConsumableDefinitions {
function createBaseConsumableDefinitions(): ConsumableDefinitions {
return { consumables: {} };
}
export const ConsumableDefinitions: MessageFns<ConsumableDefinitions> = {
encode(message: ConsumableDefinitions, writer: BinaryWriter = new BinaryWriter()): BinaryWriter {
Object.entries(message.consumables).forEach(([key, value]) => {
globalThis.Object.entries(message.consumables).forEach(([key, value]: [string, Consumable]) => {
ConsumableDefinitions_ConsumablesEntry.encode({ key: key as any, value }, writer.uint32(10).fork()).join();
});
return writer;
@@ -96,7 +96,7 @@ export const ConsumableDefinitions: MessageFns<ConsumableDefinitions> = {
decode(input: BinaryReader | Uint8Array, length?: number): ConsumableDefinitions {
const reader = input instanceof BinaryReader ? input : new BinaryReader(input);
let end = length === undefined ? reader.len : reader.pos + length;
const end = length === undefined ? reader.len : reader.pos + length;
const message = createBaseConsumableDefinitions();
while (reader.pos < end) {
const tag = reader.uint32();
@@ -124,10 +124,13 @@ export const ConsumableDefinitions: MessageFns<ConsumableDefinitions> = {
fromJSON(object: any): ConsumableDefinitions {
return {
consumables: isObject(object.consumables)
? Object.entries(object.consumables).reduce<{ [key: number]: Consumable }>((acc, [key, value]) => {
acc[globalThis.Number(key)] = Consumable.fromJSON(value);
return acc;
}, {})
? (globalThis.Object.entries(object.consumables) as [string, any][]).reduce(
(acc: { [key: number]: Consumable }, [key, value]: [string, any]) => {
acc[globalThis.Number(key)] = Consumable.fromJSON(value);
return acc;
},
{},
)
: {},
};
},
@@ -135,7 +138,7 @@ export const ConsumableDefinitions: MessageFns<ConsumableDefinitions> = {
toJSON(message: ConsumableDefinitions): unknown {
const obj: any = {};
if (message.consumables) {
const entries = Object.entries(message.consumables);
const entries = globalThis.Object.entries(message.consumables) as [string, Consumable][];
if (entries.length > 0) {
obj.consumables = {};
entries.forEach(([k, v]) => {
@@ -151,8 +154,8 @@ export const ConsumableDefinitions: MessageFns<ConsumableDefinitions> = {
},
fromPartial<I extends Exact<DeepPartial<ConsumableDefinitions>, I>>(object: I): ConsumableDefinitions {
const message = createBaseConsumableDefinitions();
message.consumables = Object.entries(object.consumables ?? {}).reduce<{ [key: number]: Consumable }>(
(acc, [key, value]) => {
message.consumables = (globalThis.Object.entries(object.consumables ?? {}) as [string, Consumable][]).reduce(
(acc: { [key: number]: Consumable }, [key, value]: [string, Consumable]) => {
if (value !== undefined) {
acc[globalThis.Number(key)] = Consumable.fromPartial(value);
}
@@ -164,13 +167,13 @@ export const ConsumableDefinitions: MessageFns<ConsumableDefinitions> = {
},
};
export function createBaseConsumableDefinitions_ConsumablesEntry(): ConsumableDefinitions_ConsumablesEntry {
return { key: 0, value: createBaseConsumable() };
function createBaseConsumableDefinitions_ConsumablesEntry(): ConsumableDefinitions_ConsumablesEntry {
return { key: 0, value: undefined };
}
export const ConsumableDefinitions_ConsumablesEntry: MessageFns<ConsumableDefinitions_ConsumablesEntry> = {
encode(message: ConsumableDefinitions_ConsumablesEntry, writer: BinaryWriter = new BinaryWriter()): BinaryWriter {
if (message.key !== undefined) {
if (message.key !== 0) {
writer.uint32(8).uint32(message.key);
}
if (message.value !== undefined) {
@@ -181,7 +184,7 @@ export const ConsumableDefinitions_ConsumablesEntry: MessageFns<ConsumableDefini
decode(input: BinaryReader | Uint8Array, length?: number): ConsumableDefinitions_ConsumablesEntry {
const reader = input instanceof BinaryReader ? input : new BinaryReader(input);
let end = length === undefined ? reader.len : reader.pos + length;
const end = length === undefined ? reader.len : reader.pos + length;
const message = createBaseConsumableDefinitions_ConsumablesEntry();
while (reader.pos < end) {
const tag = reader.uint32();
@@ -213,14 +216,14 @@ export const ConsumableDefinitions_ConsumablesEntry: MessageFns<ConsumableDefini
fromJSON(object: any): ConsumableDefinitions_ConsumablesEntry {
return {
key: globalThis.Number(assertSet("ConsumableDefinitions_ConsumablesEntry.key", object.key)),
value: Consumable.fromJSON(assertSet("ConsumableDefinitions_ConsumablesEntry.value", object.value)),
key: isSet(object.key) ? globalThis.Number(object.key) : 0,
value: isSet(object.value) ? Consumable.fromJSON(object.value) : undefined,
};
},
toJSON(message: ConsumableDefinitions_ConsumablesEntry): unknown {
const obj: any = {};
if (message.key !== undefined) {
if (message.key !== 0) {
obj.key = Math.round(message.key);
}
if (message.value !== undefined) {
@@ -241,21 +244,13 @@ export const ConsumableDefinitions_ConsumablesEntry: MessageFns<ConsumableDefini
message.key = object.key ?? 0;
message.value = (object.value !== undefined && object.value !== null)
? Consumable.fromPartial(object.value)
: createBaseConsumable();
: undefined;
return message;
},
};
export function createBaseConsumable(): Consumable {
return {
id: 0,
name: createBaseI18nString(),
cooldown: 0,
duration: undefined,
game_mode_exclusive: false,
include: [],
exclude: [],
};
function createBaseConsumable(): Consumable {
return { id: 0, name: undefined, cooldown: 0, duration: 0, game_mode_exclusive: false, include: [], exclude: [] };
}
export const Consumable: MessageFns<Consumable> = {
@@ -269,7 +264,7 @@ export const Consumable: MessageFns<Consumable> = {
if (message.cooldown !== 0) {
writer.uint32(24).uint32(message.cooldown);
}
if (message.duration !== undefined && message.duration !== undefined) {
if (message.duration !== undefined && message.duration !== 0) {
writer.uint32(37).float(message.duration);
}
if (message.game_mode_exclusive !== false) {
@@ -286,7 +281,7 @@ export const Consumable: MessageFns<Consumable> = {
decode(input: BinaryReader | Uint8Array, length?: number): Consumable {
const reader = input instanceof BinaryReader ? input : new BinaryReader(input);
let end = length === undefined ? reader.len : reader.pos + length;
const end = length === undefined ? reader.len : reader.pos + length;
const message = createBaseConsumable();
while (reader.pos < end) {
const tag = reader.uint32();
@@ -358,11 +353,15 @@ export const Consumable: MessageFns<Consumable> = {
fromJSON(object: any): Consumable {
return {
id: globalThis.Number(assertSet("Consumable.id", object.id)),
name: I18nString.fromJSON(assertSet("Consumable.name", object.name)),
cooldown: globalThis.Number(assertSet("Consumable.cooldown", object.cooldown)),
duration: isSet(object.duration) ? globalThis.Number(object.duration) : undefined,
game_mode_exclusive: globalThis.Boolean(assertSet("Consumable.game_mode_exclusive", object.game_mode_exclusive)),
id: isSet(object.id) ? globalThis.Number(object.id) : 0,
name: isSet(object.name) ? I18nString.fromJSON(object.name) : undefined,
cooldown: isSet(object.cooldown) ? globalThis.Number(object.cooldown) : 0,
duration: isSet(object.duration) ? globalThis.Number(object.duration) : 0,
game_mode_exclusive: isSet(object.gameModeExclusive)
? globalThis.Boolean(object.gameModeExclusive)
: isSet(object.game_mode_exclusive)
? globalThis.Boolean(object.game_mode_exclusive)
: false,
include: globalThis.Array.isArray(object?.include)
? object.include.map((e: any) => ConsumableTankFilter.fromJSON(e))
: [],
@@ -383,11 +382,11 @@ export const Consumable: MessageFns<Consumable> = {
if (message.cooldown !== 0) {
obj.cooldown = Math.round(message.cooldown);
}
if (message.duration !== undefined && message.duration !== undefined) {
if (message.duration !== undefined && message.duration !== 0) {
obj.duration = message.duration;
}
if (message.game_mode_exclusive !== false) {
obj.game_mode_exclusive = message.game_mode_exclusive;
obj.gameModeExclusive = message.game_mode_exclusive;
}
if (message.include?.length) {
obj.include = message.include.map((e) => ConsumableTankFilter.toJSON(e));
@@ -406,9 +405,9 @@ export const Consumable: MessageFns<Consumable> = {
message.id = object.id ?? 0;
message.name = (object.name !== undefined && object.name !== null)
? I18nString.fromPartial(object.name)
: createBaseI18nString();
: undefined;
message.cooldown = object.cooldown ?? 0;
message.duration = object.duration ?? undefined;
message.duration = object.duration ?? 0;
message.game_mode_exclusive = object.game_mode_exclusive ?? false;
message.include = object.include?.map((e) => ConsumableTankFilter.fromPartial(e)) || [];
message.exclude = object.exclude?.map((e) => ConsumableTankFilter.fromPartial(e)) || [];
@@ -416,7 +415,7 @@ export const Consumable: MessageFns<Consumable> = {
},
};
export function createBaseConsumableTankFilter(): ConsumableTankFilter {
function createBaseConsumableTankFilter(): ConsumableTankFilter {
return { filter_type: undefined };
}
@@ -441,7 +440,7 @@ export const ConsumableTankFilter: MessageFns<ConsumableTankFilter> = {
decode(input: BinaryReader | Uint8Array, length?: number): ConsumableTankFilter {
const reader = input instanceof BinaryReader ? input : new BinaryReader(input);
let end = length === undefined ? reader.len : reader.pos + length;
const end = length === undefined ? reader.len : reader.pos + length;
const message = createBaseConsumableTankFilter();
while (reader.pos < end) {
const tag = reader.uint32();
@@ -508,14 +507,11 @@ export const ConsumableTankFilter: MessageFns<ConsumableTankFilter> = {
const obj: any = {};
if (message.filter_type?.$case === "tiers") {
obj.tiers = ConsumableTankTierFilter.toJSON(message.filter_type.value);
}
if (message.filter_type?.$case === "ids") {
} else if (message.filter_type?.$case === "ids") {
obj.ids = ConsumableTankIdsFilter.toJSON(message.filter_type.value);
}
if (message.filter_type?.$case === "categories") {
} else if (message.filter_type?.$case === "categories") {
obj.categories = ConsumableTankCategoryFilter.toJSON(message.filter_type.value);
}
if (message.filter_type?.$case === "nations") {
} else if (message.filter_type?.$case === "nations") {
obj.nations = ConsumableTankNationFilter.toJSON(message.filter_type.value);
}
return obj;
@@ -526,45 +522,46 @@ export const ConsumableTankFilter: MessageFns<ConsumableTankFilter> = {
},
fromPartial<I extends Exact<DeepPartial<ConsumableTankFilter>, I>>(object: I): ConsumableTankFilter {
const message = createBaseConsumableTankFilter();
if (
object.filter_type?.$case === "tiers" &&
object.filter_type?.value !== undefined &&
object.filter_type?.value !== null
) {
message.filter_type = { $case: "tiers", value: ConsumableTankTierFilter.fromPartial(object.filter_type.value) };
}
if (
object.filter_type?.$case === "ids" &&
object.filter_type?.value !== undefined &&
object.filter_type?.value !== null
) {
message.filter_type = { $case: "ids", value: ConsumableTankIdsFilter.fromPartial(object.filter_type.value) };
}
if (
object.filter_type?.$case === "categories" &&
object.filter_type?.value !== undefined &&
object.filter_type?.value !== null
) {
message.filter_type = {
$case: "categories",
value: ConsumableTankCategoryFilter.fromPartial(object.filter_type.value),
};
}
if (
object.filter_type?.$case === "nations" &&
object.filter_type?.value !== undefined &&
object.filter_type?.value !== null
) {
message.filter_type = {
$case: "nations",
value: ConsumableTankNationFilter.fromPartial(object.filter_type.value),
};
switch (object.filter_type?.$case) {
case "tiers": {
if (object.filter_type?.value !== undefined && object.filter_type?.value !== null) {
message.filter_type = {
$case: "tiers",
value: ConsumableTankTierFilter.fromPartial(object.filter_type.value),
};
}
break;
}
case "ids": {
if (object.filter_type?.value !== undefined && object.filter_type?.value !== null) {
message.filter_type = { $case: "ids", value: ConsumableTankIdsFilter.fromPartial(object.filter_type.value) };
}
break;
}
case "categories": {
if (object.filter_type?.value !== undefined && object.filter_type?.value !== null) {
message.filter_type = {
$case: "categories",
value: ConsumableTankCategoryFilter.fromPartial(object.filter_type.value),
};
}
break;
}
case "nations": {
if (object.filter_type?.value !== undefined && object.filter_type?.value !== null) {
message.filter_type = {
$case: "nations",
value: ConsumableTankNationFilter.fromPartial(object.filter_type.value),
};
}
break;
}
}
return message;
},
};
export function createBaseConsumableTankTierFilter(): ConsumableTankTierFilter {
function createBaseConsumableTankTierFilter(): ConsumableTankTierFilter {
return { min: 0, max: 0 };
}
@@ -581,7 +578,7 @@ export const ConsumableTankTierFilter: MessageFns<ConsumableTankTierFilter> = {
decode(input: BinaryReader | Uint8Array, length?: number): ConsumableTankTierFilter {
const reader = input instanceof BinaryReader ? input : new BinaryReader(input);
let end = length === undefined ? reader.len : reader.pos + length;
const end = length === undefined ? reader.len : reader.pos + length;
const message = createBaseConsumableTankTierFilter();
while (reader.pos < end) {
const tag = reader.uint32();
@@ -613,8 +610,8 @@ export const ConsumableTankTierFilter: MessageFns<ConsumableTankTierFilter> = {
fromJSON(object: any): ConsumableTankTierFilter {
return {
min: globalThis.Number(assertSet("ConsumableTankTierFilter.min", object.min)),
max: globalThis.Number(assertSet("ConsumableTankTierFilter.max", object.max)),
min: isSet(object.min) ? globalThis.Number(object.min) : 0,
max: isSet(object.max) ? globalThis.Number(object.max) : 0,
};
},
@@ -640,23 +637,21 @@ export const ConsumableTankTierFilter: MessageFns<ConsumableTankTierFilter> = {
},
};
export function createBaseConsumableTankIdsFilter(): ConsumableTankIdsFilter {
function createBaseConsumableTankIdsFilter(): ConsumableTankIdsFilter {
return { ids: [] };
}
export const ConsumableTankIdsFilter: MessageFns<ConsumableTankIdsFilter> = {
encode(message: ConsumableTankIdsFilter, writer: BinaryWriter = new BinaryWriter()): BinaryWriter {
writer.uint32(10).fork();
for (const v of message.ids) {
writer.uint32(v);
writer.uint32(8).uint32(v!);
}
writer.join();
return writer;
},
decode(input: BinaryReader | Uint8Array, length?: number): ConsumableTankIdsFilter {
const reader = input instanceof BinaryReader ? input : new BinaryReader(input);
let end = length === undefined ? reader.len : reader.pos + length;
const end = length === undefined ? reader.len : reader.pos + length;
const message = createBaseConsumableTankIdsFilter();
while (reader.pos < end) {
const tag = reader.uint32();
@@ -710,23 +705,21 @@ export const ConsumableTankIdsFilter: MessageFns<ConsumableTankIdsFilter> = {
},
};
export function createBaseConsumableTankCategoryFilter(): ConsumableTankCategoryFilter {
function createBaseConsumableTankCategoryFilter(): ConsumableTankCategoryFilter {
return { categories: [] };
}
export const ConsumableTankCategoryFilter: MessageFns<ConsumableTankCategoryFilter> = {
encode(message: ConsumableTankCategoryFilter, writer: BinaryWriter = new BinaryWriter()): BinaryWriter {
writer.uint32(10).fork();
for (const v of message.categories) {
writer.int32(v);
writer.uint32(8).int32(v!);
}
writer.join();
return writer;
},
decode(input: BinaryReader | Uint8Array, length?: number): ConsumableTankCategoryFilter {
const reader = input instanceof BinaryReader ? input : new BinaryReader(input);
let end = length === undefined ? reader.len : reader.pos + length;
const end = length === undefined ? reader.len : reader.pos + length;
const message = createBaseConsumableTankCategoryFilter();
while (reader.pos < end) {
const tag = reader.uint32();
@@ -784,7 +777,7 @@ export const ConsumableTankCategoryFilter: MessageFns<ConsumableTankCategoryFilt
},
};
export function createBaseConsumableTankNationFilter(): ConsumableTankNationFilter {
function createBaseConsumableTankNationFilter(): ConsumableTankNationFilter {
return { nations: [] };
}
@@ -798,7 +791,7 @@ export const ConsumableTankNationFilter: MessageFns<ConsumableTankNationFilter>
decode(input: BinaryReader | Uint8Array, length?: number): ConsumableTankNationFilter {
const reader = input instanceof BinaryReader ? input : new BinaryReader(input);
let end = length === undefined ? reader.len : reader.pos + length;
const end = length === undefined ? reader.len : reader.pos + length;
const message = createBaseConsumableTankNationFilter();
while (reader.pos < end) {
const tag = reader.uint32();
@@ -865,14 +858,6 @@ function isSet(value: any): boolean {
return value !== null && value !== undefined;
}
function assertSet<T>(field: string, value: T | undefined): T {
if (!isSet(value)) {
throw new TypeError(`Required field ${field} is not set`);
}
return value as T;
}
export interface MessageFns<T> {
encode(message: T, writer?: BinaryWriter): BinaryWriter;
decode(input: BinaryReader | Uint8Array, length?: number): T;
@@ -2,15 +2,15 @@ syntax = "proto2";
package blitzkit;
import "packages/core/src/protos/i18n.proto";
import "i18n.proto";
message EquipmentDefinitions {
map<string, EquipmentPreset> presets = 1;
map<uint32, Equipment> equipments = 2;
map<string, EquipmentPreset> presets = 1;
map<uint32, Equipment> equipments = 2;
}
message Equipment {
required I18nString name = 1;
required I18nString name = 1;
required I18nString description = 2;
}
@@ -19,6 +19,6 @@ message EquipmentPreset {
}
message EquipmentSlot {
required uint32 left = 1;
required uint32 left = 1;
required uint32 right = 2;
}
@@ -1,12 +1,12 @@
// Code generated by protoc-gen-ts_proto. DO NOT EDIT.
// versions:
// protoc-gen-ts_proto v2.2.2
// protoc-gen-ts_proto v2.11.2
// protoc v5.28.2
// source: packages/core/src/protos/equipment_definitions.proto
// source: equipment_definitions.proto
/* eslint-disable */
import { BinaryReader, BinaryWriter } from "@bufbuild/protobuf/wire";
import { createBaseI18nString, I18nString } from "./i18n";
import { I18nString } from "./i18n";
export const protobufPackage = "blitzkit";
@@ -26,8 +26,8 @@ export interface EquipmentDefinitions_EquipmentsEntry {
}
export interface Equipment {
name: I18nString;
description: I18nString;
name: I18nString | undefined;
description: I18nString | undefined;
}
export interface EquipmentPreset {
@@ -39,16 +39,16 @@ export interface EquipmentSlot {
right: number;
}
export function createBaseEquipmentDefinitions(): EquipmentDefinitions {
function createBaseEquipmentDefinitions(): EquipmentDefinitions {
return { presets: {}, equipments: {} };
}
export const EquipmentDefinitions: MessageFns<EquipmentDefinitions> = {
encode(message: EquipmentDefinitions, writer: BinaryWriter = new BinaryWriter()): BinaryWriter {
Object.entries(message.presets).forEach(([key, value]) => {
globalThis.Object.entries(message.presets).forEach(([key, value]: [string, EquipmentPreset]) => {
EquipmentDefinitions_PresetsEntry.encode({ key: key as any, value }, writer.uint32(10).fork()).join();
});
Object.entries(message.equipments).forEach(([key, value]) => {
globalThis.Object.entries(message.equipments).forEach(([key, value]: [string, Equipment]) => {
EquipmentDefinitions_EquipmentsEntry.encode({ key: key as any, value }, writer.uint32(18).fork()).join();
});
return writer;
@@ -56,7 +56,7 @@ export const EquipmentDefinitions: MessageFns<EquipmentDefinitions> = {
decode(input: BinaryReader | Uint8Array, length?: number): EquipmentDefinitions {
const reader = input instanceof BinaryReader ? input : new BinaryReader(input);
let end = length === undefined ? reader.len : reader.pos + length;
const end = length === undefined ? reader.len : reader.pos + length;
const message = createBaseEquipmentDefinitions();
while (reader.pos < end) {
const tag = reader.uint32();
@@ -95,16 +95,22 @@ export const EquipmentDefinitions: MessageFns<EquipmentDefinitions> = {
fromJSON(object: any): EquipmentDefinitions {
return {
presets: isObject(object.presets)
? Object.entries(object.presets).reduce<{ [key: string]: EquipmentPreset }>((acc, [key, value]) => {
acc[key] = EquipmentPreset.fromJSON(value);
return acc;
}, {})
? (globalThis.Object.entries(object.presets) as [string, any][]).reduce(
(acc: { [key: string]: EquipmentPreset }, [key, value]: [string, any]) => {
acc[key] = EquipmentPreset.fromJSON(value);
return acc;
},
{},
)
: {},
equipments: isObject(object.equipments)
? Object.entries(object.equipments).reduce<{ [key: number]: Equipment }>((acc, [key, value]) => {
acc[globalThis.Number(key)] = Equipment.fromJSON(value);
return acc;
}, {})
? (globalThis.Object.entries(object.equipments) as [string, any][]).reduce(
(acc: { [key: number]: Equipment }, [key, value]: [string, any]) => {
acc[globalThis.Number(key)] = Equipment.fromJSON(value);
return acc;
},
{},
)
: {},
};
},
@@ -112,7 +118,7 @@ export const EquipmentDefinitions: MessageFns<EquipmentDefinitions> = {
toJSON(message: EquipmentDefinitions): unknown {
const obj: any = {};
if (message.presets) {
const entries = Object.entries(message.presets);
const entries = globalThis.Object.entries(message.presets) as [string, EquipmentPreset][];
if (entries.length > 0) {
obj.presets = {};
entries.forEach(([k, v]) => {
@@ -121,7 +127,7 @@ export const EquipmentDefinitions: MessageFns<EquipmentDefinitions> = {
}
}
if (message.equipments) {
const entries = Object.entries(message.equipments);
const entries = globalThis.Object.entries(message.equipments) as [string, Equipment][];
if (entries.length > 0) {
obj.equipments = {};
entries.forEach(([k, v]) => {
@@ -137,8 +143,8 @@ export const EquipmentDefinitions: MessageFns<EquipmentDefinitions> = {
},
fromPartial<I extends Exact<DeepPartial<EquipmentDefinitions>, I>>(object: I): EquipmentDefinitions {
const message = createBaseEquipmentDefinitions();
message.presets = Object.entries(object.presets ?? {}).reduce<{ [key: string]: EquipmentPreset }>(
(acc, [key, value]) => {
message.presets = (globalThis.Object.entries(object.presets ?? {}) as [string, EquipmentPreset][]).reduce(
(acc: { [key: string]: EquipmentPreset }, [key, value]: [string, EquipmentPreset]) => {
if (value !== undefined) {
acc[key] = EquipmentPreset.fromPartial(value);
}
@@ -146,8 +152,8 @@ export const EquipmentDefinitions: MessageFns<EquipmentDefinitions> = {
},
{},
);
message.equipments = Object.entries(object.equipments ?? {}).reduce<{ [key: number]: Equipment }>(
(acc, [key, value]) => {
message.equipments = (globalThis.Object.entries(object.equipments ?? {}) as [string, Equipment][]).reduce(
(acc: { [key: number]: Equipment }, [key, value]: [string, Equipment]) => {
if (value !== undefined) {
acc[globalThis.Number(key)] = Equipment.fromPartial(value);
}
@@ -159,13 +165,13 @@ export const EquipmentDefinitions: MessageFns<EquipmentDefinitions> = {
},
};
export function createBaseEquipmentDefinitions_PresetsEntry(): EquipmentDefinitions_PresetsEntry {
return { key: "", value: createBaseEquipmentPreset() };
function createBaseEquipmentDefinitions_PresetsEntry(): EquipmentDefinitions_PresetsEntry {
return { key: "", value: undefined };
}
export const EquipmentDefinitions_PresetsEntry: MessageFns<EquipmentDefinitions_PresetsEntry> = {
encode(message: EquipmentDefinitions_PresetsEntry, writer: BinaryWriter = new BinaryWriter()): BinaryWriter {
if (message.key !== undefined) {
if (message.key !== "") {
writer.uint32(10).string(message.key);
}
if (message.value !== undefined) {
@@ -176,7 +182,7 @@ export const EquipmentDefinitions_PresetsEntry: MessageFns<EquipmentDefinitions_
decode(input: BinaryReader | Uint8Array, length?: number): EquipmentDefinitions_PresetsEntry {
const reader = input instanceof BinaryReader ? input : new BinaryReader(input);
let end = length === undefined ? reader.len : reader.pos + length;
const end = length === undefined ? reader.len : reader.pos + length;
const message = createBaseEquipmentDefinitions_PresetsEntry();
while (reader.pos < end) {
const tag = reader.uint32();
@@ -208,14 +214,14 @@ export const EquipmentDefinitions_PresetsEntry: MessageFns<EquipmentDefinitions_
fromJSON(object: any): EquipmentDefinitions_PresetsEntry {
return {
key: globalThis.String(assertSet("EquipmentDefinitions_PresetsEntry.key", object.key)),
value: EquipmentPreset.fromJSON(assertSet("EquipmentDefinitions_PresetsEntry.value", object.value)),
key: isSet(object.key) ? globalThis.String(object.key) : "",
value: isSet(object.value) ? EquipmentPreset.fromJSON(object.value) : undefined,
};
},
toJSON(message: EquipmentDefinitions_PresetsEntry): unknown {
const obj: any = {};
if (message.key !== undefined) {
if (message.key !== "") {
obj.key = message.key;
}
if (message.value !== undefined) {
@@ -236,18 +242,18 @@ export const EquipmentDefinitions_PresetsEntry: MessageFns<EquipmentDefinitions_
message.key = object.key ?? "";
message.value = (object.value !== undefined && object.value !== null)
? EquipmentPreset.fromPartial(object.value)
: createBaseEquipmentPreset();
: undefined;
return message;
},
};
export function createBaseEquipmentDefinitions_EquipmentsEntry(): EquipmentDefinitions_EquipmentsEntry {
return { key: 0, value: createBaseEquipment() };
function createBaseEquipmentDefinitions_EquipmentsEntry(): EquipmentDefinitions_EquipmentsEntry {
return { key: 0, value: undefined };
}
export const EquipmentDefinitions_EquipmentsEntry: MessageFns<EquipmentDefinitions_EquipmentsEntry> = {
encode(message: EquipmentDefinitions_EquipmentsEntry, writer: BinaryWriter = new BinaryWriter()): BinaryWriter {
if (message.key !== undefined) {
if (message.key !== 0) {
writer.uint32(8).uint32(message.key);
}
if (message.value !== undefined) {
@@ -258,7 +264,7 @@ export const EquipmentDefinitions_EquipmentsEntry: MessageFns<EquipmentDefinitio
decode(input: BinaryReader | Uint8Array, length?: number): EquipmentDefinitions_EquipmentsEntry {
const reader = input instanceof BinaryReader ? input : new BinaryReader(input);
let end = length === undefined ? reader.len : reader.pos + length;
const end = length === undefined ? reader.len : reader.pos + length;
const message = createBaseEquipmentDefinitions_EquipmentsEntry();
while (reader.pos < end) {
const tag = reader.uint32();
@@ -290,14 +296,14 @@ export const EquipmentDefinitions_EquipmentsEntry: MessageFns<EquipmentDefinitio
fromJSON(object: any): EquipmentDefinitions_EquipmentsEntry {
return {
key: globalThis.Number(assertSet("EquipmentDefinitions_EquipmentsEntry.key", object.key)),
value: Equipment.fromJSON(assertSet("EquipmentDefinitions_EquipmentsEntry.value", object.value)),
key: isSet(object.key) ? globalThis.Number(object.key) : 0,
value: isSet(object.value) ? Equipment.fromJSON(object.value) : undefined,
};
},
toJSON(message: EquipmentDefinitions_EquipmentsEntry): unknown {
const obj: any = {};
if (message.key !== undefined) {
if (message.key !== 0) {
obj.key = Math.round(message.key);
}
if (message.value !== undefined) {
@@ -318,13 +324,13 @@ export const EquipmentDefinitions_EquipmentsEntry: MessageFns<EquipmentDefinitio
message.key = object.key ?? 0;
message.value = (object.value !== undefined && object.value !== null)
? Equipment.fromPartial(object.value)
: createBaseEquipment();
: undefined;
return message;
},
};
export function createBaseEquipment(): Equipment {
return { name: createBaseI18nString(), description: createBaseI18nString() };
function createBaseEquipment(): Equipment {
return { name: undefined, description: undefined };
}
export const Equipment: MessageFns<Equipment> = {
@@ -340,7 +346,7 @@ export const Equipment: MessageFns<Equipment> = {
decode(input: BinaryReader | Uint8Array, length?: number): Equipment {
const reader = input instanceof BinaryReader ? input : new BinaryReader(input);
let end = length === undefined ? reader.len : reader.pos + length;
const end = length === undefined ? reader.len : reader.pos + length;
const message = createBaseEquipment();
while (reader.pos < end) {
const tag = reader.uint32();
@@ -372,8 +378,8 @@ export const Equipment: MessageFns<Equipment> = {
fromJSON(object: any): Equipment {
return {
name: I18nString.fromJSON(assertSet("Equipment.name", object.name)),
description: I18nString.fromJSON(assertSet("Equipment.description", object.description)),
name: isSet(object.name) ? I18nString.fromJSON(object.name) : undefined,
description: isSet(object.description) ? I18nString.fromJSON(object.description) : undefined,
};
},
@@ -395,15 +401,15 @@ export const Equipment: MessageFns<Equipment> = {
const message = createBaseEquipment();
message.name = (object.name !== undefined && object.name !== null)
? I18nString.fromPartial(object.name)
: createBaseI18nString();
: undefined;
message.description = (object.description !== undefined && object.description !== null)
? I18nString.fromPartial(object.description)
: createBaseI18nString();
: undefined;
return message;
},
};
export function createBaseEquipmentPreset(): EquipmentPreset {
function createBaseEquipmentPreset(): EquipmentPreset {
return { slots: [] };
}
@@ -417,7 +423,7 @@ export const EquipmentPreset: MessageFns<EquipmentPreset> = {
decode(input: BinaryReader | Uint8Array, length?: number): EquipmentPreset {
const reader = input instanceof BinaryReader ? input : new BinaryReader(input);
let end = length === undefined ? reader.len : reader.pos + length;
const end = length === undefined ? reader.len : reader.pos + length;
const message = createBaseEquipmentPreset();
while (reader.pos < end) {
const tag = reader.uint32();
@@ -463,7 +469,7 @@ export const EquipmentPreset: MessageFns<EquipmentPreset> = {
},
};
export function createBaseEquipmentSlot(): EquipmentSlot {
function createBaseEquipmentSlot(): EquipmentSlot {
return { left: 0, right: 0 };
}
@@ -480,7 +486,7 @@ export const EquipmentSlot: MessageFns<EquipmentSlot> = {
decode(input: BinaryReader | Uint8Array, length?: number): EquipmentSlot {
const reader = input instanceof BinaryReader ? input : new BinaryReader(input);
let end = length === undefined ? reader.len : reader.pos + length;
const end = length === undefined ? reader.len : reader.pos + length;
const message = createBaseEquipmentSlot();
while (reader.pos < end) {
const tag = reader.uint32();
@@ -512,8 +518,8 @@ export const EquipmentSlot: MessageFns<EquipmentSlot> = {
fromJSON(object: any): EquipmentSlot {
return {
left: globalThis.Number(assertSet("EquipmentSlot.left", object.left)),
right: globalThis.Number(assertSet("EquipmentSlot.right", object.right)),
left: isSet(object.left) ? globalThis.Number(object.left) : 0,
right: isSet(object.right) ? globalThis.Number(object.right) : 0,
};
},
@@ -560,14 +566,6 @@ function isSet(value: any): boolean {
return value !== null && value !== undefined;
}
function assertSet<T>(field: string, value: T | undefined): T {
if (!isSet(value)) {
throw new TypeError(`Required field ${field} is not set`);
}
return value as T;
}
export interface MessageFns<T> {
encode(message: T, writer?: BinaryWriter): BinaryWriter;
decode(input: BinaryReader | Uint8Array, length?: number): T;
+4 -4
View File
@@ -2,14 +2,14 @@ syntax = "proto2";
package blitzkit;
import "packages/core/src/protos/i18n.proto";
import "i18n.proto";
message Gallery {
repeated Avatar avatars = 1;
}
message Avatar {
required string id = 1;
required I18nString name = 2;
required string extension = 3;
required string id = 1;
required I18nString name = 2;
required string extension = 3;
}
+13 -21
View File
@@ -1,12 +1,12 @@
// Code generated by protoc-gen-ts_proto. DO NOT EDIT.
// versions:
// protoc-gen-ts_proto v2.2.2
// protoc-gen-ts_proto v2.11.2
// protoc v5.28.2
// source: packages/core/src/protos/gallery.proto
// source: gallery.proto
/* eslint-disable */
import { BinaryReader, BinaryWriter } from "@bufbuild/protobuf/wire";
import { createBaseI18nString, I18nString } from "./i18n";
import { I18nString } from "./i18n";
export const protobufPackage = "blitzkit";
@@ -16,11 +16,11 @@ export interface Gallery {
export interface Avatar {
id: string;
name: I18nString;
name: I18nString | undefined;
extension: string;
}
export function createBaseGallery(): Gallery {
function createBaseGallery(): Gallery {
return { avatars: [] };
}
@@ -34,7 +34,7 @@ export const Gallery: MessageFns<Gallery> = {
decode(input: BinaryReader | Uint8Array, length?: number): Gallery {
const reader = input instanceof BinaryReader ? input : new BinaryReader(input);
let end = length === undefined ? reader.len : reader.pos + length;
const end = length === undefined ? reader.len : reader.pos + length;
const message = createBaseGallery();
while (reader.pos < end) {
const tag = reader.uint32();
@@ -80,8 +80,8 @@ export const Gallery: MessageFns<Gallery> = {
},
};
export function createBaseAvatar(): Avatar {
return { id: "", name: createBaseI18nString(), extension: "" };
function createBaseAvatar(): Avatar {
return { id: "", name: undefined, extension: "" };
}
export const Avatar: MessageFns<Avatar> = {
@@ -100,7 +100,7 @@ export const Avatar: MessageFns<Avatar> = {
decode(input: BinaryReader | Uint8Array, length?: number): Avatar {
const reader = input instanceof BinaryReader ? input : new BinaryReader(input);
let end = length === undefined ? reader.len : reader.pos + length;
const end = length === undefined ? reader.len : reader.pos + length;
const message = createBaseAvatar();
while (reader.pos < end) {
const tag = reader.uint32();
@@ -140,9 +140,9 @@ export const Avatar: MessageFns<Avatar> = {
fromJSON(object: any): Avatar {
return {
id: globalThis.String(assertSet("Avatar.id", object.id)),
name: I18nString.fromJSON(assertSet("Avatar.name", object.name)),
extension: globalThis.String(assertSet("Avatar.extension", object.extension)),
id: isSet(object.id) ? globalThis.String(object.id) : "",
name: isSet(object.name) ? I18nString.fromJSON(object.name) : undefined,
extension: isSet(object.extension) ? globalThis.String(object.extension) : "",
};
},
@@ -168,7 +168,7 @@ export const Avatar: MessageFns<Avatar> = {
message.id = object.id ?? "";
message.name = (object.name !== undefined && object.name !== null)
? I18nString.fromPartial(object.name)
: createBaseI18nString();
: undefined;
message.extension = object.extension ?? "";
return message;
},
@@ -191,14 +191,6 @@ function isSet(value: any): boolean {
return value !== null && value !== undefined;
}
function assertSet<T>(field: string, value: T | undefined): T {
if (!isSet(value)) {
throw new TypeError(`Required field ${field} is not set`);
}
return value as T;
}
export interface MessageFns<T> {
encode(message: T, writer?: BinaryWriter): BinaryWriter;
decode(input: BinaryReader | Uint8Array, length?: number): T;
@@ -2,13 +2,13 @@ syntax = "proto2";
package blitzkit;
import "packages/core/src/protos/i18n.proto";
import "i18n.proto";
message GameDefinitions {
required string version = 1;
repeated string nations = 2;
map<uint32, GameMode> gameModes = 3;
map<uint32, GameModeRole> roles = 4;
required string version = 1;
repeated string nations = 2;
map<uint32, GameMode> gameModes = 3;
map<uint32, GameModeRole> roles = 4;
}
message GameMode {
@@ -16,6 +16,6 @@ message GameMode {
}
message GameModeRole {
repeated uint32 provisions = 1;
repeated uint32 provisions = 1;
repeated uint32 consumables = 2;
}
+61 -64
View File
@@ -1,12 +1,12 @@
// Code generated by protoc-gen-ts_proto. DO NOT EDIT.
// versions:
// protoc-gen-ts_proto v2.2.2
// protoc-gen-ts_proto v2.11.2
// protoc v5.28.2
// source: packages/core/src/protos/game_definitions.proto
// source: game_definitions.proto
/* eslint-disable */
import { BinaryReader, BinaryWriter } from "@bufbuild/protobuf/wire";
import { createBaseI18nString, I18nString } from "./i18n";
import { I18nString } from "./i18n";
export const protobufPackage = "blitzkit";
@@ -28,7 +28,7 @@ export interface GameDefinitions_RolesEntry {
}
export interface GameMode {
name: I18nString;
name: I18nString | undefined;
}
export interface GameModeRole {
@@ -36,7 +36,7 @@ export interface GameModeRole {
consumables: number[];
}
export function createBaseGameDefinitions(): GameDefinitions {
function createBaseGameDefinitions(): GameDefinitions {
return { version: "", nations: [], gameModes: {}, roles: {} };
}
@@ -48,10 +48,10 @@ export const GameDefinitions: MessageFns<GameDefinitions> = {
for (const v of message.nations) {
writer.uint32(18).string(v!);
}
Object.entries(message.gameModes).forEach(([key, value]) => {
globalThis.Object.entries(message.gameModes).forEach(([key, value]: [string, GameMode]) => {
GameDefinitions_GameModesEntry.encode({ key: key as any, value }, writer.uint32(26).fork()).join();
});
Object.entries(message.roles).forEach(([key, value]) => {
globalThis.Object.entries(message.roles).forEach(([key, value]: [string, GameModeRole]) => {
GameDefinitions_RolesEntry.encode({ key: key as any, value }, writer.uint32(34).fork()).join();
});
return writer;
@@ -59,7 +59,7 @@ export const GameDefinitions: MessageFns<GameDefinitions> = {
decode(input: BinaryReader | Uint8Array, length?: number): GameDefinitions {
const reader = input instanceof BinaryReader ? input : new BinaryReader(input);
let end = length === undefined ? reader.len : reader.pos + length;
const end = length === undefined ? reader.len : reader.pos + length;
const message = createBaseGameDefinitions();
while (reader.pos < end) {
const tag = reader.uint32();
@@ -113,19 +113,25 @@ export const GameDefinitions: MessageFns<GameDefinitions> = {
fromJSON(object: any): GameDefinitions {
return {
version: globalThis.String(assertSet("GameDefinitions.version", object.version)),
version: isSet(object.version) ? globalThis.String(object.version) : "",
nations: globalThis.Array.isArray(object?.nations) ? object.nations.map((e: any) => globalThis.String(e)) : [],
gameModes: isObject(object.gameModes)
? Object.entries(object.gameModes).reduce<{ [key: number]: GameMode }>((acc, [key, value]) => {
acc[globalThis.Number(key)] = GameMode.fromJSON(value);
return acc;
}, {})
? (globalThis.Object.entries(object.gameModes) as [string, any][]).reduce(
(acc: { [key: number]: GameMode }, [key, value]: [string, any]) => {
acc[globalThis.Number(key)] = GameMode.fromJSON(value);
return acc;
},
{},
)
: {},
roles: isObject(object.roles)
? Object.entries(object.roles).reduce<{ [key: number]: GameModeRole }>((acc, [key, value]) => {
acc[globalThis.Number(key)] = GameModeRole.fromJSON(value);
return acc;
}, {})
? (globalThis.Object.entries(object.roles) as [string, any][]).reduce(
(acc: { [key: number]: GameModeRole }, [key, value]: [string, any]) => {
acc[globalThis.Number(key)] = GameModeRole.fromJSON(value);
return acc;
},
{},
)
: {},
};
},
@@ -139,7 +145,7 @@ export const GameDefinitions: MessageFns<GameDefinitions> = {
obj.nations = message.nations;
}
if (message.gameModes) {
const entries = Object.entries(message.gameModes);
const entries = globalThis.Object.entries(message.gameModes) as [string, GameMode][];
if (entries.length > 0) {
obj.gameModes = {};
entries.forEach(([k, v]) => {
@@ -148,7 +154,7 @@ export const GameDefinitions: MessageFns<GameDefinitions> = {
}
}
if (message.roles) {
const entries = Object.entries(message.roles);
const entries = globalThis.Object.entries(message.roles) as [string, GameModeRole][];
if (entries.length > 0) {
obj.roles = {};
entries.forEach(([k, v]) => {
@@ -166,8 +172,8 @@ export const GameDefinitions: MessageFns<GameDefinitions> = {
const message = createBaseGameDefinitions();
message.version = object.version ?? "";
message.nations = object.nations?.map((e) => e) || [];
message.gameModes = Object.entries(object.gameModes ?? {}).reduce<{ [key: number]: GameMode }>(
(acc, [key, value]) => {
message.gameModes = (globalThis.Object.entries(object.gameModes ?? {}) as [string, GameMode][]).reduce(
(acc: { [key: number]: GameMode }, [key, value]: [string, GameMode]) => {
if (value !== undefined) {
acc[globalThis.Number(key)] = GameMode.fromPartial(value);
}
@@ -175,23 +181,26 @@ export const GameDefinitions: MessageFns<GameDefinitions> = {
},
{},
);
message.roles = Object.entries(object.roles ?? {}).reduce<{ [key: number]: GameModeRole }>((acc, [key, value]) => {
if (value !== undefined) {
acc[globalThis.Number(key)] = GameModeRole.fromPartial(value);
}
return acc;
}, {});
message.roles = (globalThis.Object.entries(object.roles ?? {}) as [string, GameModeRole][]).reduce(
(acc: { [key: number]: GameModeRole }, [key, value]: [string, GameModeRole]) => {
if (value !== undefined) {
acc[globalThis.Number(key)] = GameModeRole.fromPartial(value);
}
return acc;
},
{},
);
return message;
},
};
export function createBaseGameDefinitions_GameModesEntry(): GameDefinitions_GameModesEntry {
return { key: 0, value: createBaseGameMode() };
function createBaseGameDefinitions_GameModesEntry(): GameDefinitions_GameModesEntry {
return { key: 0, value: undefined };
}
export const GameDefinitions_GameModesEntry: MessageFns<GameDefinitions_GameModesEntry> = {
encode(message: GameDefinitions_GameModesEntry, writer: BinaryWriter = new BinaryWriter()): BinaryWriter {
if (message.key !== undefined) {
if (message.key !== 0) {
writer.uint32(8).uint32(message.key);
}
if (message.value !== undefined) {
@@ -202,7 +211,7 @@ export const GameDefinitions_GameModesEntry: MessageFns<GameDefinitions_GameMode
decode(input: BinaryReader | Uint8Array, length?: number): GameDefinitions_GameModesEntry {
const reader = input instanceof BinaryReader ? input : new BinaryReader(input);
let end = length === undefined ? reader.len : reader.pos + length;
const end = length === undefined ? reader.len : reader.pos + length;
const message = createBaseGameDefinitions_GameModesEntry();
while (reader.pos < end) {
const tag = reader.uint32();
@@ -234,14 +243,14 @@ export const GameDefinitions_GameModesEntry: MessageFns<GameDefinitions_GameMode
fromJSON(object: any): GameDefinitions_GameModesEntry {
return {
key: globalThis.Number(assertSet("GameDefinitions_GameModesEntry.key", object.key)),
value: GameMode.fromJSON(assertSet("GameDefinitions_GameModesEntry.value", object.value)),
key: isSet(object.key) ? globalThis.Number(object.key) : 0,
value: isSet(object.value) ? GameMode.fromJSON(object.value) : undefined,
};
},
toJSON(message: GameDefinitions_GameModesEntry): unknown {
const obj: any = {};
if (message.key !== undefined) {
if (message.key !== 0) {
obj.key = Math.round(message.key);
}
if (message.value !== undefined) {
@@ -260,18 +269,18 @@ export const GameDefinitions_GameModesEntry: MessageFns<GameDefinitions_GameMode
message.key = object.key ?? 0;
message.value = (object.value !== undefined && object.value !== null)
? GameMode.fromPartial(object.value)
: createBaseGameMode();
: undefined;
return message;
},
};
export function createBaseGameDefinitions_RolesEntry(): GameDefinitions_RolesEntry {
return { key: 0, value: createBaseGameModeRole() };
function createBaseGameDefinitions_RolesEntry(): GameDefinitions_RolesEntry {
return { key: 0, value: undefined };
}
export const GameDefinitions_RolesEntry: MessageFns<GameDefinitions_RolesEntry> = {
encode(message: GameDefinitions_RolesEntry, writer: BinaryWriter = new BinaryWriter()): BinaryWriter {
if (message.key !== undefined) {
if (message.key !== 0) {
writer.uint32(8).uint32(message.key);
}
if (message.value !== undefined) {
@@ -282,7 +291,7 @@ export const GameDefinitions_RolesEntry: MessageFns<GameDefinitions_RolesEntry>
decode(input: BinaryReader | Uint8Array, length?: number): GameDefinitions_RolesEntry {
const reader = input instanceof BinaryReader ? input : new BinaryReader(input);
let end = length === undefined ? reader.len : reader.pos + length;
const end = length === undefined ? reader.len : reader.pos + length;
const message = createBaseGameDefinitions_RolesEntry();
while (reader.pos < end) {
const tag = reader.uint32();
@@ -314,14 +323,14 @@ export const GameDefinitions_RolesEntry: MessageFns<GameDefinitions_RolesEntry>
fromJSON(object: any): GameDefinitions_RolesEntry {
return {
key: globalThis.Number(assertSet("GameDefinitions_RolesEntry.key", object.key)),
value: GameModeRole.fromJSON(assertSet("GameDefinitions_RolesEntry.value", object.value)),
key: isSet(object.key) ? globalThis.Number(object.key) : 0,
value: isSet(object.value) ? GameModeRole.fromJSON(object.value) : undefined,
};
},
toJSON(message: GameDefinitions_RolesEntry): unknown {
const obj: any = {};
if (message.key !== undefined) {
if (message.key !== 0) {
obj.key = Math.round(message.key);
}
if (message.value !== undefined) {
@@ -338,13 +347,13 @@ export const GameDefinitions_RolesEntry: MessageFns<GameDefinitions_RolesEntry>
message.key = object.key ?? 0;
message.value = (object.value !== undefined && object.value !== null)
? GameModeRole.fromPartial(object.value)
: createBaseGameModeRole();
: undefined;
return message;
},
};
export function createBaseGameMode(): GameMode {
return { name: createBaseI18nString() };
function createBaseGameMode(): GameMode {
return { name: undefined };
}
export const GameMode: MessageFns<GameMode> = {
@@ -357,7 +366,7 @@ export const GameMode: MessageFns<GameMode> = {
decode(input: BinaryReader | Uint8Array, length?: number): GameMode {
const reader = input instanceof BinaryReader ? input : new BinaryReader(input);
let end = length === undefined ? reader.len : reader.pos + length;
const end = length === undefined ? reader.len : reader.pos + length;
const message = createBaseGameMode();
while (reader.pos < end) {
const tag = reader.uint32();
@@ -380,7 +389,7 @@ export const GameMode: MessageFns<GameMode> = {
},
fromJSON(object: any): GameMode {
return { name: I18nString.fromJSON(assertSet("GameMode.name", object.name)) };
return { name: isSet(object.name) ? I18nString.fromJSON(object.name) : undefined };
},
toJSON(message: GameMode): unknown {
@@ -398,33 +407,29 @@ export const GameMode: MessageFns<GameMode> = {
const message = createBaseGameMode();
message.name = (object.name !== undefined && object.name !== null)
? I18nString.fromPartial(object.name)
: createBaseI18nString();
: undefined;
return message;
},
};
export function createBaseGameModeRole(): GameModeRole {
function createBaseGameModeRole(): GameModeRole {
return { provisions: [], consumables: [] };
}
export const GameModeRole: MessageFns<GameModeRole> = {
encode(message: GameModeRole, writer: BinaryWriter = new BinaryWriter()): BinaryWriter {
writer.uint32(10).fork();
for (const v of message.provisions) {
writer.uint32(v);
writer.uint32(8).uint32(v!);
}
writer.join();
writer.uint32(18).fork();
for (const v of message.consumables) {
writer.uint32(v);
writer.uint32(16).uint32(v!);
}
writer.join();
return writer;
},
decode(input: BinaryReader | Uint8Array, length?: number): GameModeRole {
const reader = input instanceof BinaryReader ? input : new BinaryReader(input);
let end = length === undefined ? reader.len : reader.pos + length;
const end = length === undefined ? reader.len : reader.pos + length;
const message = createBaseGameModeRole();
while (reader.pos < end) {
const tag = reader.uint32();
@@ -528,14 +533,6 @@ function isSet(value: any): boolean {
return value !== null && value !== undefined;
}
function assertSet<T>(field: string, value: T | undefined): T {
if (!isSet(value)) {
throw new TypeError(`Required field ${field} is not set`);
}
return value as T;
}
export interface MessageFns<T> {
encode(message: T, writer?: BinaryWriter): BinaryWriter;
decode(input: BinaryReader | Uint8Array, length?: number): T;
+30 -32
View File
@@ -1,8 +1,8 @@
// Code generated by protoc-gen-ts_proto. DO NOT EDIT.
// versions:
// protoc-gen-ts_proto v2.2.2
// protoc-gen-ts_proto v2.11.2
// protoc v5.28.2
// source: packages/core/src/protos/i18n.proto
// source: i18n.proto
/* eslint-disable */
import { BinaryReader, BinaryWriter } from "@bufbuild/protobuf/wire";
@@ -18,13 +18,13 @@ export interface I18nString_LocalesEntry {
value: string;
}
export function createBaseI18nString(): I18nString {
function createBaseI18nString(): I18nString {
return { locales: {} };
}
export const I18nString: MessageFns<I18nString> = {
encode(message: I18nString, writer: BinaryWriter = new BinaryWriter()): BinaryWriter {
Object.entries(message.locales).forEach(([key, value]) => {
globalThis.Object.entries(message.locales).forEach(([key, value]: [string, string]) => {
I18nString_LocalesEntry.encode({ key: key as any, value }, writer.uint32(10).fork()).join();
});
return writer;
@@ -32,7 +32,7 @@ export const I18nString: MessageFns<I18nString> = {
decode(input: BinaryReader | Uint8Array, length?: number): I18nString {
const reader = input instanceof BinaryReader ? input : new BinaryReader(input);
let end = length === undefined ? reader.len : reader.pos + length;
const end = length === undefined ? reader.len : reader.pos + length;
const message = createBaseI18nString();
while (reader.pos < end) {
const tag = reader.uint32();
@@ -60,10 +60,13 @@ export const I18nString: MessageFns<I18nString> = {
fromJSON(object: any): I18nString {
return {
locales: isObject(object.locales)
? Object.entries(object.locales).reduce<{ [key: string]: string }>((acc, [key, value]) => {
acc[key] = String(value);
return acc;
}, {})
? (globalThis.Object.entries(object.locales) as [string, any][]).reduce(
(acc: { [key: string]: string }, [key, value]: [string, any]) => {
acc[key] = globalThis.String(value);
return acc;
},
{},
)
: {},
};
},
@@ -71,7 +74,7 @@ export const I18nString: MessageFns<I18nString> = {
toJSON(message: I18nString): unknown {
const obj: any = {};
if (message.locales) {
const entries = Object.entries(message.locales);
const entries = globalThis.Object.entries(message.locales) as [string, string][];
if (entries.length > 0) {
obj.locales = {};
entries.forEach(([k, v]) => {
@@ -87,26 +90,29 @@ export const I18nString: MessageFns<I18nString> = {
},
fromPartial<I extends Exact<DeepPartial<I18nString>, I>>(object: I): I18nString {
const message = createBaseI18nString();
message.locales = Object.entries(object.locales ?? {}).reduce<{ [key: string]: string }>((acc, [key, value]) => {
if (value !== undefined) {
acc[key] = globalThis.String(value);
}
return acc;
}, {});
message.locales = (globalThis.Object.entries(object.locales ?? {}) as [string, string][]).reduce(
(acc: { [key: string]: string }, [key, value]: [string, string]) => {
if (value !== undefined) {
acc[key] = globalThis.String(value);
}
return acc;
},
{},
);
return message;
},
};
export function createBaseI18nString_LocalesEntry(): I18nString_LocalesEntry {
function createBaseI18nString_LocalesEntry(): I18nString_LocalesEntry {
return { key: "", value: "" };
}
export const I18nString_LocalesEntry: MessageFns<I18nString_LocalesEntry> = {
encode(message: I18nString_LocalesEntry, writer: BinaryWriter = new BinaryWriter()): BinaryWriter {
if (message.key !== undefined) {
if (message.key !== "") {
writer.uint32(10).string(message.key);
}
if (message.value !== undefined) {
if (message.value !== "") {
writer.uint32(18).string(message.value);
}
return writer;
@@ -114,7 +120,7 @@ export const I18nString_LocalesEntry: MessageFns<I18nString_LocalesEntry> = {
decode(input: BinaryReader | Uint8Array, length?: number): I18nString_LocalesEntry {
const reader = input instanceof BinaryReader ? input : new BinaryReader(input);
let end = length === undefined ? reader.len : reader.pos + length;
const end = length === undefined ? reader.len : reader.pos + length;
const message = createBaseI18nString_LocalesEntry();
while (reader.pos < end) {
const tag = reader.uint32();
@@ -146,17 +152,17 @@ export const I18nString_LocalesEntry: MessageFns<I18nString_LocalesEntry> = {
fromJSON(object: any): I18nString_LocalesEntry {
return {
key: globalThis.String(assertSet("I18nString_LocalesEntry.key", object.key)),
value: globalThis.String(assertSet("I18nString_LocalesEntry.value", object.value)),
key: isSet(object.key) ? globalThis.String(object.key) : "",
value: isSet(object.value) ? globalThis.String(object.value) : "",
};
},
toJSON(message: I18nString_LocalesEntry): unknown {
const obj: any = {};
if (message.key !== undefined) {
if (message.key !== "") {
obj.key = message.key;
}
if (message.value !== undefined) {
if (message.value !== "") {
obj.value = message.value;
}
return obj;
@@ -194,14 +200,6 @@ function isSet(value: any): boolean {
return value !== null && value !== undefined;
}
function assertSet<T>(field: string, value: T | undefined): T {
if (!isSet(value)) {
throw new TypeError(`Required field ${field} is not set`);
}
return value as T;
}
export interface MessageFns<T> {
encode(message: T, writer?: BinaryWriter): BinaryWriter;
decode(input: BinaryReader | Uint8Array, length?: number): T;
@@ -2,13 +2,13 @@ syntax = "proto2";
package blitzkit;
import "packages/core/src/protos/i18n.proto";
import "i18n.proto";
message MapDefinitions {
map<int32, MapDefinition> maps = 1;
}
message MapDefinition {
required uint32 id = 1;
required uint32 id = 1;
required I18nString name = 2;
}
+38 -40
View File
@@ -1,12 +1,12 @@
// Code generated by protoc-gen-ts_proto. DO NOT EDIT.
// versions:
// protoc-gen-ts_proto v2.2.2
// protoc-gen-ts_proto v2.11.2
// protoc v5.28.2
// source: packages/core/src/protos/map_definitions.proto
// source: map_definitions.proto
/* eslint-disable */
import { BinaryReader, BinaryWriter } from "@bufbuild/protobuf/wire";
import { createBaseI18nString, I18nString } from "./i18n";
import { I18nString } from "./i18n";
export const protobufPackage = "blitzkit";
@@ -21,16 +21,16 @@ export interface MapDefinitions_MapsEntry {
export interface MapDefinition {
id: number;
name: I18nString;
name: I18nString | undefined;
}
export function createBaseMapDefinitions(): MapDefinitions {
function createBaseMapDefinitions(): MapDefinitions {
return { maps: {} };
}
export const MapDefinitions: MessageFns<MapDefinitions> = {
encode(message: MapDefinitions, writer: BinaryWriter = new BinaryWriter()): BinaryWriter {
Object.entries(message.maps).forEach(([key, value]) => {
globalThis.Object.entries(message.maps).forEach(([key, value]: [string, MapDefinition]) => {
MapDefinitions_MapsEntry.encode({ key: key as any, value }, writer.uint32(10).fork()).join();
});
return writer;
@@ -38,7 +38,7 @@ export const MapDefinitions: MessageFns<MapDefinitions> = {
decode(input: BinaryReader | Uint8Array, length?: number): MapDefinitions {
const reader = input instanceof BinaryReader ? input : new BinaryReader(input);
let end = length === undefined ? reader.len : reader.pos + length;
const end = length === undefined ? reader.len : reader.pos + length;
const message = createBaseMapDefinitions();
while (reader.pos < end) {
const tag = reader.uint32();
@@ -66,10 +66,13 @@ export const MapDefinitions: MessageFns<MapDefinitions> = {
fromJSON(object: any): MapDefinitions {
return {
maps: isObject(object.maps)
? Object.entries(object.maps).reduce<{ [key: number]: MapDefinition }>((acc, [key, value]) => {
acc[globalThis.Number(key)] = MapDefinition.fromJSON(value);
return acc;
}, {})
? (globalThis.Object.entries(object.maps) as [string, any][]).reduce(
(acc: { [key: number]: MapDefinition }, [key, value]: [string, any]) => {
acc[globalThis.Number(key)] = MapDefinition.fromJSON(value);
return acc;
},
{},
)
: {},
};
},
@@ -77,7 +80,7 @@ export const MapDefinitions: MessageFns<MapDefinitions> = {
toJSON(message: MapDefinitions): unknown {
const obj: any = {};
if (message.maps) {
const entries = Object.entries(message.maps);
const entries = globalThis.Object.entries(message.maps) as [string, MapDefinition][];
if (entries.length > 0) {
obj.maps = {};
entries.forEach(([k, v]) => {
@@ -93,23 +96,26 @@ export const MapDefinitions: MessageFns<MapDefinitions> = {
},
fromPartial<I extends Exact<DeepPartial<MapDefinitions>, I>>(object: I): MapDefinitions {
const message = createBaseMapDefinitions();
message.maps = Object.entries(object.maps ?? {}).reduce<{ [key: number]: MapDefinition }>((acc, [key, value]) => {
if (value !== undefined) {
acc[globalThis.Number(key)] = MapDefinition.fromPartial(value);
}
return acc;
}, {});
message.maps = (globalThis.Object.entries(object.maps ?? {}) as [string, MapDefinition][]).reduce(
(acc: { [key: number]: MapDefinition }, [key, value]: [string, MapDefinition]) => {
if (value !== undefined) {
acc[globalThis.Number(key)] = MapDefinition.fromPartial(value);
}
return acc;
},
{},
);
return message;
},
};
export function createBaseMapDefinitions_MapsEntry(): MapDefinitions_MapsEntry {
return { key: 0, value: createBaseMapDefinition() };
function createBaseMapDefinitions_MapsEntry(): MapDefinitions_MapsEntry {
return { key: 0, value: undefined };
}
export const MapDefinitions_MapsEntry: MessageFns<MapDefinitions_MapsEntry> = {
encode(message: MapDefinitions_MapsEntry, writer: BinaryWriter = new BinaryWriter()): BinaryWriter {
if (message.key !== undefined) {
if (message.key !== 0) {
writer.uint32(8).int32(message.key);
}
if (message.value !== undefined) {
@@ -120,7 +126,7 @@ export const MapDefinitions_MapsEntry: MessageFns<MapDefinitions_MapsEntry> = {
decode(input: BinaryReader | Uint8Array, length?: number): MapDefinitions_MapsEntry {
const reader = input instanceof BinaryReader ? input : new BinaryReader(input);
let end = length === undefined ? reader.len : reader.pos + length;
const end = length === undefined ? reader.len : reader.pos + length;
const message = createBaseMapDefinitions_MapsEntry();
while (reader.pos < end) {
const tag = reader.uint32();
@@ -152,14 +158,14 @@ export const MapDefinitions_MapsEntry: MessageFns<MapDefinitions_MapsEntry> = {
fromJSON(object: any): MapDefinitions_MapsEntry {
return {
key: globalThis.Number(assertSet("MapDefinitions_MapsEntry.key", object.key)),
value: MapDefinition.fromJSON(assertSet("MapDefinitions_MapsEntry.value", object.value)),
key: isSet(object.key) ? globalThis.Number(object.key) : 0,
value: isSet(object.value) ? MapDefinition.fromJSON(object.value) : undefined,
};
},
toJSON(message: MapDefinitions_MapsEntry): unknown {
const obj: any = {};
if (message.key !== undefined) {
if (message.key !== 0) {
obj.key = Math.round(message.key);
}
if (message.value !== undefined) {
@@ -176,13 +182,13 @@ export const MapDefinitions_MapsEntry: MessageFns<MapDefinitions_MapsEntry> = {
message.key = object.key ?? 0;
message.value = (object.value !== undefined && object.value !== null)
? MapDefinition.fromPartial(object.value)
: createBaseMapDefinition();
: undefined;
return message;
},
};
export function createBaseMapDefinition(): MapDefinition {
return { id: 0, name: createBaseI18nString() };
function createBaseMapDefinition(): MapDefinition {
return { id: 0, name: undefined };
}
export const MapDefinition: MessageFns<MapDefinition> = {
@@ -198,7 +204,7 @@ export const MapDefinition: MessageFns<MapDefinition> = {
decode(input: BinaryReader | Uint8Array, length?: number): MapDefinition {
const reader = input instanceof BinaryReader ? input : new BinaryReader(input);
let end = length === undefined ? reader.len : reader.pos + length;
const end = length === undefined ? reader.len : reader.pos + length;
const message = createBaseMapDefinition();
while (reader.pos < end) {
const tag = reader.uint32();
@@ -230,8 +236,8 @@ export const MapDefinition: MessageFns<MapDefinition> = {
fromJSON(object: any): MapDefinition {
return {
id: globalThis.Number(assertSet("MapDefinition.id", object.id)),
name: I18nString.fromJSON(assertSet("MapDefinition.name", object.name)),
id: isSet(object.id) ? globalThis.Number(object.id) : 0,
name: isSet(object.name) ? I18nString.fromJSON(object.name) : undefined,
};
},
@@ -254,7 +260,7 @@ export const MapDefinition: MessageFns<MapDefinition> = {
message.id = object.id ?? 0;
message.name = (object.name !== undefined && object.name !== null)
? I18nString.fromPartial(object.name)
: createBaseI18nString();
: undefined;
return message;
},
};
@@ -280,14 +286,6 @@ function isSet(value: any): boolean {
return value !== null && value !== undefined;
}
function assertSet<T>(field: string, value: T | undefined): T {
if (!isSet(value)) {
throw new TypeError(`Required field ${field} is not set`);
}
return value as T;
}
export interface MessageFns<T> {
encode(message: T, writer?: BinaryWriter): BinaryWriter;
decode(input: BinaryReader | Uint8Array, length?: number): T;
@@ -7,17 +7,17 @@ message ModelDefinitions {
}
message ModelDefinition {
required Armor armor = 1;
required Vector3 turret_origin = 2;
optional InitialTurretRotation initial_turret_rotation = 3;
map<uint32, TurretModelDefinition> turrets = 4;
map<uint32, TrackModelDefinition> tracks = 5;
required BoundingBox bounding_box = 6;
required Armor armor = 1;
required Vector3 turret_origin = 2;
optional InitialTurretRotation initial_turret_rotation = 3;
map<uint32, TurretModelDefinition> turrets = 4;
map<uint32, TrackModelDefinition> tracks = 5;
required BoundingBox bounding_box = 6;
}
message Armor {
map<uint32, float> thickness = 1;
repeated uint32 spaced = 2;
repeated uint32 spaced = 2;
}
message Vector3 {
@@ -27,18 +27,18 @@ message Vector3 {
}
message InitialTurretRotation {
required float yaw = 1;
required float yaw = 1;
required float pitch = 2;
required float roll = 3;
required float roll = 3;
}
message TurretModelDefinition {
required BoundingBox bounding_box = 1;
required Armor armor = 2;
required uint32 model_id = 3;
required Vector3 gun_origin = 4;
map<uint32, GunModelDefinition> guns = 5;
optional YawLimits yaw = 6;
required BoundingBox bounding_box = 1;
required Armor armor = 2;
required uint32 model_id = 3;
required Vector3 gun_origin = 4;
map<uint32, GunModelDefinition> guns = 5;
optional YawLimits yaw = 6;
}
message YawLimits {
@@ -52,28 +52,28 @@ message BoundingBox {
}
message TrackModelDefinition {
required float thickness = 1;
required Vector3 origin = 2;
required float thickness = 1;
required Vector3 origin = 2;
}
message GunModelDefinition {
required Armor armor = 1;
required float thickness = 2;
required uint32 model_id = 3;
required PitchLimits pitch = 4;
optional float mask = 5;
required Armor armor = 1;
required float thickness = 2;
required uint32 model_id = 3;
required PitchLimits pitch = 4;
optional float mask = 5;
}
message PitchLimits {
required float min = 1;
required float max = 2;
optional PitchLimitsExtrema front = 3;
optional PitchLimitsExtrema back = 4;
optional float transition = 5;
required float min = 1;
required float max = 2;
optional PitchLimitsExtrema front = 3;
optional PitchLimitsExtrema back = 4;
optional float transition = 5;
}
message PitchLimitsExtrema {
required float min = 1;
required float max = 2;
required float min = 1;
required float max = 2;
required float range = 3;
}
File diff suppressed because it is too large. Load diff
+1 -1
View File
@@ -7,6 +7,6 @@ message PopularTanks {
}
message PopularTank {
required uint32 id = 1;
required uint32 id = 1;
required uint32 views = 2; // views in the last 7 days
}
+8 -16
View File
@@ -1,8 +1,8 @@
// Code generated by protoc-gen-ts_proto. DO NOT EDIT.
// versions:
// protoc-gen-ts_proto v2.2.2
// protoc-gen-ts_proto v2.11.2
// protoc v5.28.2
// source: packages/core/src/protos/popular_tanks.proto
// source: popular_tanks.proto
/* eslint-disable */
import { BinaryReader, BinaryWriter } from "@bufbuild/protobuf/wire";
@@ -19,7 +19,7 @@ export interface PopularTank {
views: number;
}
export function createBasePopularTanks(): PopularTanks {
function createBasePopularTanks(): PopularTanks {
return { tanks: [] };
}
@@ -33,7 +33,7 @@ export const PopularTanks: MessageFns<PopularTanks> = {
decode(input: BinaryReader | Uint8Array, length?: number): PopularTanks {
const reader = input instanceof BinaryReader ? input : new BinaryReader(input);
let end = length === undefined ? reader.len : reader.pos + length;
const end = length === undefined ? reader.len : reader.pos + length;
const message = createBasePopularTanks();
while (reader.pos < end) {
const tag = reader.uint32();
@@ -79,7 +79,7 @@ export const PopularTanks: MessageFns<PopularTanks> = {
},
};
export function createBasePopularTank(): PopularTank {
function createBasePopularTank(): PopularTank {
return { id: 0, views: 0 };
}
@@ -96,7 +96,7 @@ export const PopularTank: MessageFns<PopularTank> = {
decode(input: BinaryReader | Uint8Array, length?: number): PopularTank {
const reader = input instanceof BinaryReader ? input : new BinaryReader(input);
let end = length === undefined ? reader.len : reader.pos + length;
const end = length === undefined ? reader.len : reader.pos + length;
const message = createBasePopularTank();
while (reader.pos < end) {
const tag = reader.uint32();
@@ -128,8 +128,8 @@ export const PopularTank: MessageFns<PopularTank> = {
fromJSON(object: any): PopularTank {
return {
id: globalThis.Number(assertSet("PopularTank.id", object.id)),
views: globalThis.Number(assertSet("PopularTank.views", object.views)),
id: isSet(object.id) ? globalThis.Number(object.id) : 0,
views: isSet(object.views) ? globalThis.Number(object.views) : 0,
};
},
@@ -172,14 +172,6 @@ function isSet(value: any): boolean {
return value !== null && value !== undefined;
}
function assertSet<T>(field: string, value: T | undefined): T {
if (!isSet(value)) {
throw new TypeError(`Required field ${field} is not set`);
}
return value as T;
}
export interface MessageFns<T> {
encode(message: T, writer?: BinaryWriter): BinaryWriter;
decode(input: BinaryReader | Uint8Array, length?: number): T;
@@ -2,18 +2,18 @@ syntax = "proto2";
package blitzkit;
import "packages/core/src/protos/consumable_definitions.proto";
import "packages/core/src/protos/i18n.proto";
import "consumable_definitions.proto";
import "i18n.proto";
message ProvisionDefinitions {
map<uint32, Provision> provisions = 1;
}
message Provision {
required uint32 id = 1;
required I18nString name = 2;
optional float crew = 3;
required bool game_mode_exclusive = 5;
repeated ConsumableTankFilter include = 6;
repeated ConsumableTankFilter exclude = 7;
required uint32 id = 1;
required I18nString name = 2;
optional float crew = 3;
required bool game_mode_exclusive = 5;
repeated ConsumableTankFilter include = 6;
repeated ConsumableTankFilter exclude = 7;
}
@@ -1,13 +1,13 @@
// Code generated by protoc-gen-ts_proto. DO NOT EDIT.
// versions:
// protoc-gen-ts_proto v2.2.2
// protoc-gen-ts_proto v2.11.2
// protoc v5.28.2
// source: packages/core/src/protos/provision_definitions.proto
// source: provision_definitions.proto
/* eslint-disable */
import { BinaryReader, BinaryWriter } from "@bufbuild/protobuf/wire";
import { ConsumableTankFilter } from "./consumable_definitions";
import { createBaseI18nString, I18nString } from "./i18n";
import { I18nString } from "./i18n";
export const protobufPackage = "blitzkit";
@@ -22,20 +22,20 @@ export interface ProvisionDefinitions_ProvisionsEntry {
export interface Provision {
id: number;
name: I18nString;
name: I18nString | undefined;
crew?: number | undefined;
game_mode_exclusive: boolean;
include: ConsumableTankFilter[];
exclude: ConsumableTankFilter[];
}
export function createBaseProvisionDefinitions(): ProvisionDefinitions {
function createBaseProvisionDefinitions(): ProvisionDefinitions {
return { provisions: {} };
}
export const ProvisionDefinitions: MessageFns<ProvisionDefinitions> = {
encode(message: ProvisionDefinitions, writer: BinaryWriter = new BinaryWriter()): BinaryWriter {
Object.entries(message.provisions).forEach(([key, value]) => {
globalThis.Object.entries(message.provisions).forEach(([key, value]: [string, Provision]) => {
ProvisionDefinitions_ProvisionsEntry.encode({ key: key as any, value }, writer.uint32(10).fork()).join();
});
return writer;
@@ -43,7 +43,7 @@ export const ProvisionDefinitions: MessageFns<ProvisionDefinitions> = {
decode(input: BinaryReader | Uint8Array, length?: number): ProvisionDefinitions {
const reader = input instanceof BinaryReader ? input : new BinaryReader(input);
let end = length === undefined ? reader.len : reader.pos + length;
const end = length === undefined ? reader.len : reader.pos + length;
const message = createBaseProvisionDefinitions();
while (reader.pos < end) {
const tag = reader.uint32();
@@ -71,10 +71,13 @@ export const ProvisionDefinitions: MessageFns<ProvisionDefinitions> = {
fromJSON(object: any): ProvisionDefinitions {
return {
provisions: isObject(object.provisions)
? Object.entries(object.provisions).reduce<{ [key: number]: Provision }>((acc, [key, value]) => {
acc[globalThis.Number(key)] = Provision.fromJSON(value);
return acc;
}, {})
? (globalThis.Object.entries(object.provisions) as [string, any][]).reduce(
(acc: { [key: number]: Provision }, [key, value]: [string, any]) => {
acc[globalThis.Number(key)] = Provision.fromJSON(value);
return acc;
},
{},
)
: {},
};
},
@@ -82,7 +85,7 @@ export const ProvisionDefinitions: MessageFns<ProvisionDefinitions> = {
toJSON(message: ProvisionDefinitions): unknown {
const obj: any = {};
if (message.provisions) {
const entries = Object.entries(message.provisions);
const entries = globalThis.Object.entries(message.provisions) as [string, Provision][];
if (entries.length > 0) {
obj.provisions = {};
entries.forEach(([k, v]) => {
@@ -98,8 +101,8 @@ export const ProvisionDefinitions: MessageFns<ProvisionDefinitions> = {
},
fromPartial<I extends Exact<DeepPartial<ProvisionDefinitions>, I>>(object: I): ProvisionDefinitions {
const message = createBaseProvisionDefinitions();
message.provisions = Object.entries(object.provisions ?? {}).reduce<{ [key: number]: Provision }>(
(acc, [key, value]) => {
message.provisions = (globalThis.Object.entries(object.provisions ?? {}) as [string, Provision][]).reduce(
(acc: { [key: number]: Provision }, [key, value]: [string, Provision]) => {
if (value !== undefined) {
acc[globalThis.Number(key)] = Provision.fromPartial(value);
}
@@ -111,13 +114,13 @@ export const ProvisionDefinitions: MessageFns<ProvisionDefinitions> = {
},
};
export function createBaseProvisionDefinitions_ProvisionsEntry(): ProvisionDefinitions_ProvisionsEntry {
return { key: 0, value: createBaseProvision() };
function createBaseProvisionDefinitions_ProvisionsEntry(): ProvisionDefinitions_ProvisionsEntry {
return { key: 0, value: undefined };
}
export const ProvisionDefinitions_ProvisionsEntry: MessageFns<ProvisionDefinitions_ProvisionsEntry> = {
encode(message: ProvisionDefinitions_ProvisionsEntry, writer: BinaryWriter = new BinaryWriter()): BinaryWriter {
if (message.key !== undefined) {
if (message.key !== 0) {
writer.uint32(8).uint32(message.key);
}
if (message.value !== undefined) {
@@ -128,7 +131,7 @@ export const ProvisionDefinitions_ProvisionsEntry: MessageFns<ProvisionDefinitio
decode(input: BinaryReader | Uint8Array, length?: number): ProvisionDefinitions_ProvisionsEntry {
const reader = input instanceof BinaryReader ? input : new BinaryReader(input);
let end = length === undefined ? reader.len : reader.pos + length;
const end = length === undefined ? reader.len : reader.pos + length;
const message = createBaseProvisionDefinitions_ProvisionsEntry();
while (reader.pos < end) {
const tag = reader.uint32();
@@ -160,14 +163,14 @@ export const ProvisionDefinitions_ProvisionsEntry: MessageFns<ProvisionDefinitio
fromJSON(object: any): ProvisionDefinitions_ProvisionsEntry {
return {
key: globalThis.Number(assertSet("ProvisionDefinitions_ProvisionsEntry.key", object.key)),
value: Provision.fromJSON(assertSet("ProvisionDefinitions_ProvisionsEntry.value", object.value)),
key: isSet(object.key) ? globalThis.Number(object.key) : 0,
value: isSet(object.value) ? Provision.fromJSON(object.value) : undefined,
};
},
toJSON(message: ProvisionDefinitions_ProvisionsEntry): unknown {
const obj: any = {};
if (message.key !== undefined) {
if (message.key !== 0) {
obj.key = Math.round(message.key);
}
if (message.value !== undefined) {
@@ -188,13 +191,13 @@ export const ProvisionDefinitions_ProvisionsEntry: MessageFns<ProvisionDefinitio
message.key = object.key ?? 0;
message.value = (object.value !== undefined && object.value !== null)
? Provision.fromPartial(object.value)
: createBaseProvision();
: undefined;
return message;
},
};
export function createBaseProvision(): Provision {
return { id: 0, name: createBaseI18nString(), crew: undefined, game_mode_exclusive: false, include: [], exclude: [] };
function createBaseProvision(): Provision {
return { id: 0, name: undefined, crew: 0, game_mode_exclusive: false, include: [], exclude: [] };
}
export const Provision: MessageFns<Provision> = {
@@ -205,7 +208,7 @@ export const Provision: MessageFns<Provision> = {
if (message.name !== undefined) {
I18nString.encode(message.name, writer.uint32(18).fork()).join();
}
if (message.crew !== undefined && message.crew !== undefined) {
if (message.crew !== undefined && message.crew !== 0) {
writer.uint32(29).float(message.crew);
}
if (message.game_mode_exclusive !== false) {
@@ -222,7 +225,7 @@ export const Provision: MessageFns<Provision> = {
decode(input: BinaryReader | Uint8Array, length?: number): Provision {
const reader = input instanceof BinaryReader ? input : new BinaryReader(input);
let end = length === undefined ? reader.len : reader.pos + length;
const end = length === undefined ? reader.len : reader.pos + length;
const message = createBaseProvision();
while (reader.pos < end) {
const tag = reader.uint32();
@@ -286,10 +289,14 @@ export const Provision: MessageFns<Provision> = {
fromJSON(object: any): Provision {
return {
id: globalThis.Number(assertSet("Provision.id", object.id)),
name: I18nString.fromJSON(assertSet("Provision.name", object.name)),
crew: isSet(object.crew) ? globalThis.Number(object.crew) : undefined,
game_mode_exclusive: globalThis.Boolean(assertSet("Provision.game_mode_exclusive", object.game_mode_exclusive)),
id: isSet(object.id) ? globalThis.Number(object.id) : 0,
name: isSet(object.name) ? I18nString.fromJSON(object.name) : undefined,
crew: isSet(object.crew) ? globalThis.Number(object.crew) : 0,
game_mode_exclusive: isSet(object.gameModeExclusive)
? globalThis.Boolean(object.gameModeExclusive)
: isSet(object.game_mode_exclusive)
? globalThis.Boolean(object.game_mode_exclusive)
: false,
include: globalThis.Array.isArray(object?.include)
? object.include.map((e: any) => ConsumableTankFilter.fromJSON(e))
: [],
@@ -307,11 +314,11 @@ export const Provision: MessageFns<Provision> = {
if (message.name !== undefined) {
obj.name = I18nString.toJSON(message.name);
}
if (message.crew !== undefined && message.crew !== undefined) {
if (message.crew !== undefined && message.crew !== 0) {
obj.crew = message.crew;
}
if (message.game_mode_exclusive !== false) {
obj.game_mode_exclusive = message.game_mode_exclusive;
obj.gameModeExclusive = message.game_mode_exclusive;
}
if (message.include?.length) {
obj.include = message.include.map((e) => ConsumableTankFilter.toJSON(e));
@@ -330,8 +337,8 @@ export const Provision: MessageFns<Provision> = {
message.id = object.id ?? 0;
message.name = (object.name !== undefined && object.name !== null)
? I18nString.fromPartial(object.name)
: createBaseI18nString();
message.crew = object.crew ?? undefined;
: undefined;
message.crew = object.crew ?? 0;
message.game_mode_exclusive = object.game_mode_exclusive ?? false;
message.include = object.include?.map((e) => ConsumableTankFilter.fromPartial(e)) || [];
message.exclude = object.exclude?.map((e) => ConsumableTankFilter.fromPartial(e)) || [];
@@ -360,14 +367,6 @@ function isSet(value: any): boolean {
return value !== null && value !== undefined;
}
function assertSet<T>(field: string, value: T | undefined): T {
if (!isSet(value)) {
throw new TypeError(`Required field ${field} is not set`);
}
return value as T;
}
export interface MessageFns<T> {
encode(message: T, writer?: BinaryWriter): BinaryWriter;
decode(input: BinaryReader | Uint8Array, length?: number): T;
@@ -14,7 +14,7 @@ message RatingLeaderboardV1 {
}
message RatingLeaderboardEntryV1 {
required uint32 id = 1;
required uint32 id = 1;
required uint32 score = 2;
}
@@ -23,11 +23,11 @@ message RatingLeaderboardV2 {
}
message RatingLeaderboardEntryV2 {
required uint32 id = 1;
required uint32 score = 2;
required uint32 battles = 3;
required uint32 wins = 4;
required uint32 id = 1;
required uint32 score = 2;
required uint32 battles = 3;
required uint32 wins = 4;
required uint32 survived = 5;
required uint32 damage = 6;
required uint32 kills = 7;
required uint32 damage = 6;
required uint32 kills = 7;
}
+35 -36
View File
@@ -1,8 +1,8 @@
// Code generated by protoc-gen-ts_proto. DO NOT EDIT.
// versions:
// protoc-gen-ts_proto v2.2.2
// protoc-gen-ts_proto v2.11.2
// protoc v5.28.2
// source: packages/core/src/protos/rating_leaderboard.proto
// source: rating_leaderboard.proto
/* eslint-disable */
import { BinaryReader, BinaryWriter } from "@bufbuild/protobuf/wire";
@@ -36,7 +36,7 @@ export interface RatingLeaderboardEntryV2 {
kills: number;
}
export function createBaseRatingLeaderboard(): RatingLeaderboard {
function createBaseRatingLeaderboard(): RatingLeaderboard {
return { version: undefined };
}
@@ -55,7 +55,7 @@ export const RatingLeaderboard: MessageFns<RatingLeaderboard> = {
decode(input: BinaryReader | Uint8Array, length?: number): RatingLeaderboard {
const reader = input instanceof BinaryReader ? input : new BinaryReader(input);
let end = length === undefined ? reader.len : reader.pos + length;
const end = length === undefined ? reader.len : reader.pos + length;
const message = createBaseRatingLeaderboard();
while (reader.pos < end) {
const tag = reader.uint32();
@@ -99,8 +99,7 @@ export const RatingLeaderboard: MessageFns<RatingLeaderboard> = {
const obj: any = {};
if (message.version?.$case === "v1") {
obj.v1 = RatingLeaderboardV1.toJSON(message.version.value);
}
if (message.version?.$case === "v2") {
} else if (message.version?.$case === "v2") {
obj.v2 = RatingLeaderboardV2.toJSON(message.version.value);
}
return obj;
@@ -111,17 +110,25 @@ export const RatingLeaderboard: MessageFns<RatingLeaderboard> = {
},
fromPartial<I extends Exact<DeepPartial<RatingLeaderboard>, I>>(object: I): RatingLeaderboard {
const message = createBaseRatingLeaderboard();
if (object.version?.$case === "v1" && object.version?.value !== undefined && object.version?.value !== null) {
message.version = { $case: "v1", value: RatingLeaderboardV1.fromPartial(object.version.value) };
}
if (object.version?.$case === "v2" && object.version?.value !== undefined && object.version?.value !== null) {
message.version = { $case: "v2", value: RatingLeaderboardV2.fromPartial(object.version.value) };
switch (object.version?.$case) {
case "v1": {
if (object.version?.value !== undefined && object.version?.value !== null) {
message.version = { $case: "v1", value: RatingLeaderboardV1.fromPartial(object.version.value) };
}
break;
}
case "v2": {
if (object.version?.value !== undefined && object.version?.value !== null) {
message.version = { $case: "v2", value: RatingLeaderboardV2.fromPartial(object.version.value) };
}
break;
}
}
return message;
},
};
export function createBaseRatingLeaderboardV1(): RatingLeaderboardV1 {
function createBaseRatingLeaderboardV1(): RatingLeaderboardV1 {
return { entries: [] };
}
@@ -135,7 +142,7 @@ export const RatingLeaderboardV1: MessageFns<RatingLeaderboardV1> = {
decode(input: BinaryReader | Uint8Array, length?: number): RatingLeaderboardV1 {
const reader = input instanceof BinaryReader ? input : new BinaryReader(input);
let end = length === undefined ? reader.len : reader.pos + length;
const end = length === undefined ? reader.len : reader.pos + length;
const message = createBaseRatingLeaderboardV1();
while (reader.pos < end) {
const tag = reader.uint32();
@@ -183,7 +190,7 @@ export const RatingLeaderboardV1: MessageFns<RatingLeaderboardV1> = {
},
};
export function createBaseRatingLeaderboardEntryV1(): RatingLeaderboardEntryV1 {
function createBaseRatingLeaderboardEntryV1(): RatingLeaderboardEntryV1 {
return { id: 0, score: 0 };
}
@@ -200,7 +207,7 @@ export const RatingLeaderboardEntryV1: MessageFns<RatingLeaderboardEntryV1> = {
decode(input: BinaryReader | Uint8Array, length?: number): RatingLeaderboardEntryV1 {
const reader = input instanceof BinaryReader ? input : new BinaryReader(input);
let end = length === undefined ? reader.len : reader.pos + length;
const end = length === undefined ? reader.len : reader.pos + length;
const message = createBaseRatingLeaderboardEntryV1();
while (reader.pos < end) {
const tag = reader.uint32();
@@ -232,8 +239,8 @@ export const RatingLeaderboardEntryV1: MessageFns<RatingLeaderboardEntryV1> = {
fromJSON(object: any): RatingLeaderboardEntryV1 {
return {
id: globalThis.Number(assertSet("RatingLeaderboardEntryV1.id", object.id)),
score: globalThis.Number(assertSet("RatingLeaderboardEntryV1.score", object.score)),
id: isSet(object.id) ? globalThis.Number(object.id) : 0,
score: isSet(object.score) ? globalThis.Number(object.score) : 0,
};
},
@@ -259,7 +266,7 @@ export const RatingLeaderboardEntryV1: MessageFns<RatingLeaderboardEntryV1> = {
},
};
export function createBaseRatingLeaderboardV2(): RatingLeaderboardV2 {
function createBaseRatingLeaderboardV2(): RatingLeaderboardV2 {
return { entries: [] };
}
@@ -273,7 +280,7 @@ export const RatingLeaderboardV2: MessageFns<RatingLeaderboardV2> = {
decode(input: BinaryReader | Uint8Array, length?: number): RatingLeaderboardV2 {
const reader = input instanceof BinaryReader ? input : new BinaryReader(input);
let end = length === undefined ? reader.len : reader.pos + length;
const end = length === undefined ? reader.len : reader.pos + length;
const message = createBaseRatingLeaderboardV2();
while (reader.pos < end) {
const tag = reader.uint32();
@@ -321,7 +328,7 @@ export const RatingLeaderboardV2: MessageFns<RatingLeaderboardV2> = {
},
};
export function createBaseRatingLeaderboardEntryV2(): RatingLeaderboardEntryV2 {
function createBaseRatingLeaderboardEntryV2(): RatingLeaderboardEntryV2 {
return { id: 0, score: 0, battles: 0, wins: 0, survived: 0, damage: 0, kills: 0 };
}
@@ -353,7 +360,7 @@ export const RatingLeaderboardEntryV2: MessageFns<RatingLeaderboardEntryV2> = {
decode(input: BinaryReader | Uint8Array, length?: number): RatingLeaderboardEntryV2 {
const reader = input instanceof BinaryReader ? input : new BinaryReader(input);
let end = length === undefined ? reader.len : reader.pos + length;
const end = length === undefined ? reader.len : reader.pos + length;
const message = createBaseRatingLeaderboardEntryV2();
while (reader.pos < end) {
const tag = reader.uint32();
@@ -425,13 +432,13 @@ export const RatingLeaderboardEntryV2: MessageFns<RatingLeaderboardEntryV2> = {
fromJSON(object: any): RatingLeaderboardEntryV2 {
return {
id: globalThis.Number(assertSet("RatingLeaderboardEntryV2.id", object.id)),
score: globalThis.Number(assertSet("RatingLeaderboardEntryV2.score", object.score)),
battles: globalThis.Number(assertSet("RatingLeaderboardEntryV2.battles", object.battles)),
wins: globalThis.Number(assertSet("RatingLeaderboardEntryV2.wins", object.wins)),
survived: globalThis.Number(assertSet("RatingLeaderboardEntryV2.survived", object.survived)),
damage: globalThis.Number(assertSet("RatingLeaderboardEntryV2.damage", object.damage)),
kills: globalThis.Number(assertSet("RatingLeaderboardEntryV2.kills", object.kills)),
id: isSet(object.id) ? globalThis.Number(object.id) : 0,
score: isSet(object.score) ? globalThis.Number(object.score) : 0,
battles: isSet(object.battles) ? globalThis.Number(object.battles) : 0,
wins: isSet(object.wins) ? globalThis.Number(object.wins) : 0,
survived: isSet(object.survived) ? globalThis.Number(object.survived) : 0,
damage: isSet(object.damage) ? globalThis.Number(object.damage) : 0,
kills: isSet(object.kills) ? globalThis.Number(object.kills) : 0,
};
},
@@ -494,14 +501,6 @@ function isSet(value: any): boolean {
return value !== null && value !== undefined;
}
function assertSet<T>(field: string, value: T | undefined): T {
if (!isSet(value)) {
throw new TypeError(`Required field ${field} is not set`);
}
return value as T;
}
export interface MessageFns<T> {
encode(message: T, writer?: BinaryWriter): BinaryWriter;
decode(input: BinaryReader | Uint8Array, length?: number): T;
+2 -2
View File
@@ -8,10 +8,10 @@ message Reviews {
message Review {
required float last_updated = 1;
repeated Video videos = 2;
repeated Video videos = 2;
}
message Video {
required string id = 1;
required string id = 1;
required string author = 2;
}
+42 -40
View File
@@ -1,8 +1,8 @@
// Code generated by protoc-gen-ts_proto. DO NOT EDIT.
// versions:
// protoc-gen-ts_proto v2.2.2
// protoc-gen-ts_proto v2.11.2
// protoc v5.28.2
// source: packages/core/src/protos/reviews.proto
// source: reviews.proto
/* eslint-disable */
import { BinaryReader, BinaryWriter } from "@bufbuild/protobuf/wire";
@@ -28,13 +28,13 @@ export interface Video {
author: string;
}
export function createBaseReviews(): Reviews {
function createBaseReviews(): Reviews {
return { reviews: {} };
}
export const Reviews: MessageFns<Reviews> = {
encode(message: Reviews, writer: BinaryWriter = new BinaryWriter()): BinaryWriter {
Object.entries(message.reviews).forEach(([key, value]) => {
globalThis.Object.entries(message.reviews).forEach(([key, value]: [string, Review]) => {
Reviews_ReviewsEntry.encode({ key: key as any, value }, writer.uint32(10).fork()).join();
});
return writer;
@@ -42,7 +42,7 @@ export const Reviews: MessageFns<Reviews> = {
decode(input: BinaryReader | Uint8Array, length?: number): Reviews {
const reader = input instanceof BinaryReader ? input : new BinaryReader(input);
let end = length === undefined ? reader.len : reader.pos + length;
const end = length === undefined ? reader.len : reader.pos + length;
const message = createBaseReviews();
while (reader.pos < end) {
const tag = reader.uint32();
@@ -70,10 +70,13 @@ export const Reviews: MessageFns<Reviews> = {
fromJSON(object: any): Reviews {
return {
reviews: isObject(object.reviews)
? Object.entries(object.reviews).reduce<{ [key: number]: Review }>((acc, [key, value]) => {
acc[globalThis.Number(key)] = Review.fromJSON(value);
return acc;
}, {})
? (globalThis.Object.entries(object.reviews) as [string, any][]).reduce(
(acc: { [key: number]: Review }, [key, value]: [string, any]) => {
acc[globalThis.Number(key)] = Review.fromJSON(value);
return acc;
},
{},
)
: {},
};
},
@@ -81,7 +84,7 @@ export const Reviews: MessageFns<Reviews> = {
toJSON(message: Reviews): unknown {
const obj: any = {};
if (message.reviews) {
const entries = Object.entries(message.reviews);
const entries = globalThis.Object.entries(message.reviews) as [string, Review][];
if (entries.length > 0) {
obj.reviews = {};
entries.forEach(([k, v]) => {
@@ -97,23 +100,26 @@ export const Reviews: MessageFns<Reviews> = {
},
fromPartial<I extends Exact<DeepPartial<Reviews>, I>>(object: I): Reviews {
const message = createBaseReviews();
message.reviews = Object.entries(object.reviews ?? {}).reduce<{ [key: number]: Review }>((acc, [key, value]) => {
if (value !== undefined) {
acc[globalThis.Number(key)] = Review.fromPartial(value);
}
return acc;
}, {});
message.reviews = (globalThis.Object.entries(object.reviews ?? {}) as [string, Review][]).reduce(
(acc: { [key: number]: Review }, [key, value]: [string, Review]) => {
if (value !== undefined) {
acc[globalThis.Number(key)] = Review.fromPartial(value);
}
return acc;
},
{},
);
return message;
},
};
export function createBaseReviews_ReviewsEntry(): Reviews_ReviewsEntry {
return { key: 0, value: createBaseReview() };
function createBaseReviews_ReviewsEntry(): Reviews_ReviewsEntry {
return { key: 0, value: undefined };
}
export const Reviews_ReviewsEntry: MessageFns<Reviews_ReviewsEntry> = {
encode(message: Reviews_ReviewsEntry, writer: BinaryWriter = new BinaryWriter()): BinaryWriter {
if (message.key !== undefined) {
if (message.key !== 0) {
writer.uint32(8).uint32(message.key);
}
if (message.value !== undefined) {
@@ -124,7 +130,7 @@ export const Reviews_ReviewsEntry: MessageFns<Reviews_ReviewsEntry> = {
decode(input: BinaryReader | Uint8Array, length?: number): Reviews_ReviewsEntry {
const reader = input instanceof BinaryReader ? input : new BinaryReader(input);
let end = length === undefined ? reader.len : reader.pos + length;
const end = length === undefined ? reader.len : reader.pos + length;
const message = createBaseReviews_ReviewsEntry();
while (reader.pos < end) {
const tag = reader.uint32();
@@ -156,14 +162,14 @@ export const Reviews_ReviewsEntry: MessageFns<Reviews_ReviewsEntry> = {
fromJSON(object: any): Reviews_ReviewsEntry {
return {
key: globalThis.Number(assertSet("Reviews_ReviewsEntry.key", object.key)),
value: Review.fromJSON(assertSet("Reviews_ReviewsEntry.value", object.value)),
key: isSet(object.key) ? globalThis.Number(object.key) : 0,
value: isSet(object.value) ? Review.fromJSON(object.value) : undefined,
};
},
toJSON(message: Reviews_ReviewsEntry): unknown {
const obj: any = {};
if (message.key !== undefined) {
if (message.key !== 0) {
obj.key = Math.round(message.key);
}
if (message.value !== undefined) {
@@ -180,12 +186,12 @@ export const Reviews_ReviewsEntry: MessageFns<Reviews_ReviewsEntry> = {
message.key = object.key ?? 0;
message.value = (object.value !== undefined && object.value !== null)
? Review.fromPartial(object.value)
: createBaseReview();
: undefined;
return message;
},
};
export function createBaseReview(): Review {
function createBaseReview(): Review {
return { last_updated: 0, videos: [] };
}
@@ -202,7 +208,7 @@ export const Review: MessageFns<Review> = {
decode(input: BinaryReader | Uint8Array, length?: number): Review {
const reader = input instanceof BinaryReader ? input : new BinaryReader(input);
let end = length === undefined ? reader.len : reader.pos + length;
const end = length === undefined ? reader.len : reader.pos + length;
const message = createBaseReview();
while (reader.pos < end) {
const tag = reader.uint32();
@@ -234,7 +240,11 @@ export const Review: MessageFns<Review> = {
fromJSON(object: any): Review {
return {
last_updated: globalThis.Number(assertSet("Review.last_updated", object.last_updated)),
last_updated: isSet(object.lastUpdated)
? globalThis.Number(object.lastUpdated)
: isSet(object.last_updated)
? globalThis.Number(object.last_updated)
: 0,
videos: globalThis.Array.isArray(object?.videos) ? object.videos.map((e: any) => Video.fromJSON(e)) : [],
};
},
@@ -242,7 +252,7 @@ export const Review: MessageFns<Review> = {
toJSON(message: Review): unknown {
const obj: any = {};
if (message.last_updated !== 0) {
obj.last_updated = message.last_updated;
obj.lastUpdated = message.last_updated;
}
if (message.videos?.length) {
obj.videos = message.videos.map((e) => Video.toJSON(e));
@@ -261,7 +271,7 @@ export const Review: MessageFns<Review> = {
},
};
export function createBaseVideo(): Video {
function createBaseVideo(): Video {
return { id: "", author: "" };
}
@@ -278,7 +288,7 @@ export const Video: MessageFns<Video> = {
decode(input: BinaryReader | Uint8Array, length?: number): Video {
const reader = input instanceof BinaryReader ? input : new BinaryReader(input);
let end = length === undefined ? reader.len : reader.pos + length;
const end = length === undefined ? reader.len : reader.pos + length;
const message = createBaseVideo();
while (reader.pos < end) {
const tag = reader.uint32();
@@ -310,8 +320,8 @@ export const Video: MessageFns<Video> = {
fromJSON(object: any): Video {
return {
id: globalThis.String(assertSet("Video.id", object.id)),
author: globalThis.String(assertSet("Video.author", object.author)),
id: isSet(object.id) ? globalThis.String(object.id) : "",
author: isSet(object.author) ? globalThis.String(object.author) : "",
};
},
@@ -358,14 +368,6 @@ function isSet(value: any): boolean {
return value !== null && value !== undefined;
}
function assertSet<T>(field: string, value: T | undefined): T {
if (!isSet(value)) {
throw new TypeError(`Required field ${field} is not set`);
}
return value as T;
}
export interface MessageFns<T> {
encode(message: T, writer?: BinaryWriter): BinaryWriter;
decode(input: BinaryReader | Uint8Array, length?: number): T;
+32 -36
View File
@@ -1,8 +1,8 @@
// Code generated by protoc-gen-ts_proto. DO NOT EDIT.
// versions:
// protoc-gen-ts_proto v2.2.2
// protoc-gen-ts_proto v2.11.2
// protoc v5.28.2
// source: packages/core/src/protos/skill_definitions.proto
// source: skill_definitions.proto
/* eslint-disable */
import { BinaryReader, BinaryWriter } from "@bufbuild/protobuf/wire";
@@ -23,13 +23,13 @@ export interface Skill {
skills: string[];
}
export function createBaseSkillDefinitions(): SkillDefinitions {
function createBaseSkillDefinitions(): SkillDefinitions {
return { classes: {} };
}
export const SkillDefinitions: MessageFns<SkillDefinitions> = {
encode(message: SkillDefinitions, writer: BinaryWriter = new BinaryWriter()): BinaryWriter {
Object.entries(message.classes).forEach(([key, value]) => {
globalThis.Object.entries(message.classes).forEach(([key, value]: [string, Skill]) => {
SkillDefinitions_ClassesEntry.encode({ key: key as any, value }, writer.uint32(10).fork()).join();
});
return writer;
@@ -37,7 +37,7 @@ export const SkillDefinitions: MessageFns<SkillDefinitions> = {
decode(input: BinaryReader | Uint8Array, length?: number): SkillDefinitions {
const reader = input instanceof BinaryReader ? input : new BinaryReader(input);
let end = length === undefined ? reader.len : reader.pos + length;
const end = length === undefined ? reader.len : reader.pos + length;
const message = createBaseSkillDefinitions();
while (reader.pos < end) {
const tag = reader.uint32();
@@ -65,10 +65,13 @@ export const SkillDefinitions: MessageFns<SkillDefinitions> = {
fromJSON(object: any): SkillDefinitions {
return {
classes: isObject(object.classes)
? Object.entries(object.classes).reduce<{ [key: number]: Skill }>((acc, [key, value]) => {
acc[globalThis.Number(key)] = Skill.fromJSON(value);
return acc;
}, {})
? (globalThis.Object.entries(object.classes) as [string, any][]).reduce(
(acc: { [key: number]: Skill }, [key, value]: [string, any]) => {
acc[globalThis.Number(key)] = Skill.fromJSON(value);
return acc;
},
{},
)
: {},
};
},
@@ -76,7 +79,7 @@ export const SkillDefinitions: MessageFns<SkillDefinitions> = {
toJSON(message: SkillDefinitions): unknown {
const obj: any = {};
if (message.classes) {
const entries = Object.entries(message.classes);
const entries = globalThis.Object.entries(message.classes) as [string, Skill][];
if (entries.length > 0) {
obj.classes = {};
entries.forEach(([k, v]) => {
@@ -92,23 +95,26 @@ export const SkillDefinitions: MessageFns<SkillDefinitions> = {
},
fromPartial<I extends Exact<DeepPartial<SkillDefinitions>, I>>(object: I): SkillDefinitions {
const message = createBaseSkillDefinitions();
message.classes = Object.entries(object.classes ?? {}).reduce<{ [key: number]: Skill }>((acc, [key, value]) => {
if (value !== undefined) {
acc[globalThis.Number(key)] = Skill.fromPartial(value);
}
return acc;
}, {});
message.classes = (globalThis.Object.entries(object.classes ?? {}) as [string, Skill][]).reduce(
(acc: { [key: number]: Skill }, [key, value]: [string, Skill]) => {
if (value !== undefined) {
acc[globalThis.Number(key)] = Skill.fromPartial(value);
}
return acc;
},
{},
);
return message;
},
};
export function createBaseSkillDefinitions_ClassesEntry(): SkillDefinitions_ClassesEntry {
return { key: 0, value: createBaseSkill() };
function createBaseSkillDefinitions_ClassesEntry(): SkillDefinitions_ClassesEntry {
return { key: 0, value: undefined };
}
export const SkillDefinitions_ClassesEntry: MessageFns<SkillDefinitions_ClassesEntry> = {
encode(message: SkillDefinitions_ClassesEntry, writer: BinaryWriter = new BinaryWriter()): BinaryWriter {
if (message.key !== undefined) {
if (message.key !== 0) {
writer.uint32(8).uint32(message.key);
}
if (message.value !== undefined) {
@@ -119,7 +125,7 @@ export const SkillDefinitions_ClassesEntry: MessageFns<SkillDefinitions_ClassesE
decode(input: BinaryReader | Uint8Array, length?: number): SkillDefinitions_ClassesEntry {
const reader = input instanceof BinaryReader ? input : new BinaryReader(input);
let end = length === undefined ? reader.len : reader.pos + length;
const end = length === undefined ? reader.len : reader.pos + length;
const message = createBaseSkillDefinitions_ClassesEntry();
while (reader.pos < end) {
const tag = reader.uint32();
@@ -151,14 +157,14 @@ export const SkillDefinitions_ClassesEntry: MessageFns<SkillDefinitions_ClassesE
fromJSON(object: any): SkillDefinitions_ClassesEntry {
return {
key: globalThis.Number(assertSet("SkillDefinitions_ClassesEntry.key", object.key)),
value: Skill.fromJSON(assertSet("SkillDefinitions_ClassesEntry.value", object.value)),
key: isSet(object.key) ? globalThis.Number(object.key) : 0,
value: isSet(object.value) ? Skill.fromJSON(object.value) : undefined,
};
},
toJSON(message: SkillDefinitions_ClassesEntry): unknown {
const obj: any = {};
if (message.key !== undefined) {
if (message.key !== 0) {
obj.key = Math.round(message.key);
}
if (message.value !== undefined) {
@@ -175,14 +181,12 @@ export const SkillDefinitions_ClassesEntry: MessageFns<SkillDefinitions_ClassesE
): SkillDefinitions_ClassesEntry {
const message = createBaseSkillDefinitions_ClassesEntry();
message.key = object.key ?? 0;
message.value = (object.value !== undefined && object.value !== null)
? Skill.fromPartial(object.value)
: createBaseSkill();
message.value = (object.value !== undefined && object.value !== null) ? Skill.fromPartial(object.value) : undefined;
return message;
},
};
export function createBaseSkill(): Skill {
function createBaseSkill(): Skill {
return { skills: [] };
}
@@ -196,7 +200,7 @@ export const Skill: MessageFns<Skill> = {
decode(input: BinaryReader | Uint8Array, length?: number): Skill {
const reader = input instanceof BinaryReader ? input : new BinaryReader(input);
let end = length === undefined ? reader.len : reader.pos + length;
const end = length === undefined ? reader.len : reader.pos + length;
const message = createBaseSkill();
while (reader.pos < end) {
const tag = reader.uint32();
@@ -263,14 +267,6 @@ function isSet(value: any): boolean {
return value !== null && value !== undefined;
}
function assertSet<T>(field: string, value: T | undefined): T {
if (!isSet(value)) {
throw new TypeError(`Required field ${field} is not set`);
}
return value as T;
}
export interface MessageFns<T> {
encode(message: T, writer?: BinaryWriter): BinaryWriter;
decode(input: BinaryReader | Uint8Array, length?: number): T;
+125 -124
View File
@@ -2,48 +2,49 @@ syntax = "proto2";
package blitzkit;
import "packages/core/src/protos/i18n.proto";
import "i18n.proto";
message TankDefinitions {
map<uint32, TankDefinition> tanks = 1;
}
message TankDefinition {
required uint32 id = 1;
required string slug = 2;
map<uint32, uint32> roles = 3;
required bool fixed_camouflage = 5;
repeated int32 camouflages = 6;
repeated int32 ancestors = 7;
repeated int32 successors = 8;
repeated Crew crew = 9;
required uint32 health = 10;
required string nation = 11;
required I18nString name = 12;
required TankType type = 13;
required uint32 max_consumables = 14;
required uint32 max_provisions = 15;
required uint32 tier = 16;
required TankClass class = 17;
required bool testing = 18;
required bool deprecated = 19;
repeated TurretDefinition turrets = 20;
repeated EngineDefinition engines = 21;
repeated TrackDefinition tracks = 22;
required TankPrice price = 23;
optional ResearchCost research_cost = 24;
required float speed_forwards = 25;
required float speed_backwards = 26;
required float camouflage_still = 27;
required float camouflage_moving = 28;
required float camouflage_onFire = 29;
required string equipment_preset = 30;
required uint32 weight = 31;
required uint32 id = 1;
required string slug = 2;
map<uint32, uint32> roles = 3;
required bool fixed_camouflage = 5;
repeated int32 camouflages = 6;
repeated int32 ancestors = 7;
repeated int32 successors = 8;
repeated Crew crew = 9;
required uint32 health = 10;
required string nation = 11;
required I18nString name = 12;
required TankType type = 13;
required uint32 max_consumables = 14;
required uint32 max_provisions = 15;
required uint32 tier = 16;
required TankClass class = 17;
required bool testing = 18;
required bool deprecated = 19;
repeated TurretDefinition turrets = 20;
repeated EngineDefinition engines = 21;
repeated TrackDefinition tracks = 22;
required TankPrice price = 23;
optional ResearchCost research_cost = 24;
required float speed_forwards = 25;
required float speed_backwards = 26;
required float camouflage_still = 27;
required float camouflage_moving = 28;
required float camouflage_on_fire = 29;
required string equipment_preset = 30;
required uint32 weight = 31;
required string dev_name = 32;
}
message ResearchCost {
oneof research_cost_type {
uint32 xp = 1;
uint32 xp = 1;
ResearchCostSeasonalTokens seasonal_tokens = 2;
}
}
@@ -55,77 +56,77 @@ message ResearchCostSeasonalTokens {
enum TankPriceType {
TANK_PRICE_TYPE_CREDITS = 0;
TANK_PRICE_TYPE_GOLD = 1;
TANK_PRICE_TYPE_GOLD = 1;
}
message TankPrice {
required TankPriceType type = 1;
required uint32 value = 2;
required TankPriceType type = 1;
required uint32 value = 2;
}
message TrackDefinition {
required uint32 id = 1;
required uint32 tier = 2;
required I18nString name = 3;
required uint32 weight = 4;
required float traverse_speed = 5;
optional ResearchCost research_cost = 6;
required float dispersion_move = 7;
required float dispersion_traverse = 8;
required float resistance_hard = 9;
required float resistance_medium = 10;
required float resistance_soft = 11;
repeated Unlock unlocks = 12;
required uint32 id = 1;
required uint32 tier = 2;
required I18nString name = 3;
required uint32 weight = 4;
required float traverse_speed = 5;
optional ResearchCost research_cost = 6;
required float dispersion_move = 7;
required float dispersion_traverse = 8;
required float resistance_hard = 9;
required float resistance_medium = 10;
required float resistance_soft = 11;
repeated Unlock unlocks = 12;
}
message EngineDefinition {
required uint32 id = 1;
required I18nString name = 2;
required uint32 id = 1;
required I18nString name = 2;
optional ResearchCost research_cost = 3;
required uint32 tier = 4;
required float fire_chance = 5;
required uint32 power = 6;
required uint32 weight = 7;
repeated Unlock unlocks = 8;
required uint32 tier = 4;
required float fire_chance = 5;
required uint32 power = 6;
required uint32 weight = 7;
repeated Unlock unlocks = 8;
}
message TurretDefinition {
required uint32 id = 1;
required uint32 health = 2;
required uint32 view_range = 3;
required float traverse_speed = 4;
optional ResearchCost research_cost = 5;
required I18nString name = 6;
required uint32 tier = 7;
required uint32 weight = 8;
repeated GunDefinition guns = 9;
repeated Unlock unlocks = 10;
required uint32 id = 1;
required uint32 health = 2;
required uint32 view_range = 3;
required float traverse_speed = 4;
optional ResearchCost research_cost = 5;
required I18nString name = 6;
required uint32 tier = 7;
required uint32 weight = 8;
repeated GunDefinition guns = 9;
repeated Unlock unlocks = 10;
}
message GunDefinition {
oneof gun_type {
GunDefinitionRegular regular = 1;
GunDefinitionAutoLoader auto_loader = 2;
GunDefinitionRegular regular = 1;
GunDefinitionAutoLoader auto_loader = 2;
GunDefinitionAutoReloader auto_reloader = 3;
}
required uint32 id = 4;
required float rotation_speed = 5;
optional ResearchCost research_cost = 6;
required uint32 weight = 7;
required I18nString name = 8;
required uint32 tier = 9;
repeated ShellDefinition shells = 10;
required float camouflage_loss = 11;
required float aim_time = 12;
required float dispersion_base = 13;
required float dispersion_traverse = 14;
required float dispersion_shot = 15;
required float dispersion_damaged = 16;
repeated Unlock unlocks = 17;
required uint32 shell_capacity = 18;
optional AssaultRanges assault_ranges = 19;
optional Burst burst = 20;
required uint32 id = 4;
required float rotation_speed = 5;
optional ResearchCost research_cost = 6;
required uint32 weight = 7;
required I18nString name = 8;
required uint32 tier = 9;
repeated ShellDefinition shells = 10;
required float camouflage_loss = 11;
required float aim_time = 12;
required float dispersion_base = 13;
required float dispersion_traverse = 14;
required float dispersion_shot = 15;
required float dispersion_damaged = 16;
repeated Unlock unlocks = 17;
required uint32 shell_capacity = 18;
optional AssaultRanges assault_ranges = 19;
optional Burst burst = 20;
}
message GunDefinitionRegular {
@@ -134,101 +135,101 @@ message GunDefinitionRegular {
message GunDefinitionAutoLoader {
required float clip_reload = 1;
required float intra_clip = 2;
required float intra_clip = 2;
required float shell_count = 3;
}
message Burst {
required uint32 count = 1;
required float interval = 2;
required uint32 count = 1;
required float interval = 2;
}
message GunDefinitionAutoReloader {
repeated float shell_reloads = 1;
required float intra_clip = 2;
required float shell_count = 3;
required float intra_clip = 2;
required float shell_count = 3;
}
message AssaultRanges {
repeated AssaultRange ranges = 1;
repeated ShellType types = 2;
repeated ShellType types = 2;
}
message AssaultRange {
required float distance = 1;
required float factor = 2;
required float factor = 2;
}
message ShellDefinition {
required uint32 id = 1;
required I18nString name = 2;
required uint32 velocity = 3;
required uint32 armor_damage = 4;
required uint32 module_damage = 5;
required float caliber = 6;
required string icon = 7;
required ShellPenetration penetration = 8;
required ShellType type = 9;
optional float normalization = 10;
optional float ricochet = 11;
optional float explosion_radius = 12;
required uint32 range = 13;
required uint32 id = 1;
required I18nString name = 2;
required uint32 velocity = 3;
required uint32 armor_damage = 4;
required uint32 module_damage = 5;
required float caliber = 6;
required string icon = 7;
required ShellPenetration penetration = 8;
required ShellType type = 9;
optional float normalization = 10;
optional float ricochet = 11;
optional float explosion_radius = 12;
required uint32 range = 13;
}
enum ShellType {
SHELL_TYPE_AP = 0;
SHELL_TYPE_AP = 0;
SHELL_TYPE_APCR = 1;
SHELL_TYPE_HEAT = 2;
SHELL_TYPE_HE = 3;
SHELL_TYPE_HE = 3;
}
message ShellPenetration {
required float near = 1;
required float far = 2;
required float far = 2;
}
message Unlock {
required int32 id = 1;
required int32 id = 1;
required ModuleType type = 2;
required UnlockCost cost = 3;
}
message UnlockCost {
required string type = 1;
required int32 value = 2;
required string type = 1;
required int32 value = 2;
}
enum ModuleType {
MODULE_TYPE_VEHICLE = 0;
MODULE_TYPE_ENGINE = 1;
MODULE_TYPE_TRACKS = 2;
MODULE_TYPE_TURRET = 3;
MODULE_TYPE_GUN = 4;
MODULE_TYPE_ENGINE = 1;
MODULE_TYPE_TRACKS = 2;
MODULE_TYPE_TURRET = 3;
MODULE_TYPE_GUN = 4;
}
enum TankClass {
TANK_CLASS_LIGHT = 0;
TANK_CLASS_MEDIUM = 1;
TANK_CLASS_HEAVY = 2;
TANK_CLASS_LIGHT = 0;
TANK_CLASS_MEDIUM = 1;
TANK_CLASS_HEAVY = 2;
TANK_CLASS_TANK_DESTROYER = 3;
}
enum TankType {
TANK_TYPE_RESEARCHABLE = 0;
TANK_TYPE_PREMIUM = 1;
TANK_TYPE_COLLECTOR = 2;
TANK_TYPE_PREMIUM = 1;
TANK_TYPE_COLLECTOR = 2;
}
message Crew {
required CrewType type = 1;
required uint32 count = 2;
required CrewType type = 1;
required uint32 count = 2;
repeated CrewType substitute = 3;
}
enum CrewType {
CREW_TYPE_COMMANDER = 0;
CREW_TYPE_RADIOMAN = 1;
CREW_TYPE_GUNNER = 2;
CREW_TYPE_DRIVER = 3;
CREW_TYPE_LOADER = 4;
CREW_TYPE_RADIOMAN = 1;
CREW_TYPE_GUNNER = 2;
CREW_TYPE_DRIVER = 3;
CREW_TYPE_LOADER = 4;
}
File diff suppressed because it is too large. Load diff
@@ -0,0 +1,3 @@
export function bufferToBigInt(buffer: ArrayBuffer) {
return new DataView(buffer).getBigUint64(0, true);
}
+2
View File
@@ -1,4 +1,5 @@
export * from './buffer';
export * from './bufferToBigInt';
export * from './dds';
export * from './dids';
export * from './pvr';
@@ -7,3 +8,4 @@ export * from './sc2';
export * from './scg';
export * from './scpg';
export * from './windows';
+5
View File
@@ -1083,6 +1083,7 @@
"tier": "Tier",
"type": "Type",
"dev_id": "DEV: ID",
"dev_name": "DEV: NAME",
"purchase": "Purchase price",
"restoration": "Restoration price",
"sale": "Sale price",
@@ -1108,6 +1109,10 @@
"configuration": {
"title": "Configuration",
"equalizer": {
"title": "Equalizer",
"equalize": "Equalize"
},
"modules": {
"title": "Modules",
"stock": "Stock",
+10 -3
View File
@@ -320,9 +320,16 @@
}
},
"commands": {
"dead": "# Stat Commands Are Dead\n\nThe BlitzKit Discord bot used to use BlitzStars to fetch periodic statistics. BlitzStars has enabled aggressive Cloudflare protections; hence, disabling BlitzKit from using BlitzStar's API. This has impacted the following commands:\n\n- `/stats`\n- `/today`\n- `/breakdown`\n- `/evolution`\n- `/full-stats`\n\nPlease use [Aftermath](<https://amth.one/invite>) as an alternative which is completely independent of BlitzStars. BlitzKit-hosted stat commands will return in the near future.",
"replay": {
"name": "repetición",
"description": "Mostrar resultados de la repetición"
"description": "Mostrar resultados de la repetición",
"options": {
"file": {
"name": "file",
"description": "Replay file"
}
}
},
"research": {
"name": "desarollar",
@@ -1005,8 +1012,8 @@
"title": "Características",
"compare": {
"label": "Comparar con",
"class": "Tier {tier} {class}",
"tier": "All of tier {tier}",
"class": "{tier} {class}",
"tier": "All tier {tier}",
"all": "Todos los tanques"
},
"values": {
+10 -3
View File
@@ -320,9 +320,16 @@
}
},
"commands": {
"dead": "# Stat Commands Are Dead\n\nThe BlitzKit Discord bot used to use BlitzStars to fetch periodic statistics. BlitzStars has enabled aggressive Cloudflare protections; hence, disabling BlitzKit from using BlitzStar's API. This has impacted the following commands:\n\n- `/stats`\n- `/today`\n- `/breakdown`\n- `/evolution`\n- `/full-stats`\n\nPlease use [Aftermath](<https://amth.one/invite>) as an alternative which is completely independent of BlitzStars. BlitzKit-hosted stat commands will return in the near future.",
"replay": {
"name": "rejouer",
"description": "Afficher les résultats de la relecture"
"description": "Afficher les résultats de la relecture",
"options": {
"file": {
"name": "file",
"description": "Replay file"
}
}
},
"research": {
"name": "recherche",
@@ -1005,8 +1012,8 @@
"title": "Characteristics",
"compare": {
"label": "Compare against",
"class": "Tier {tier} {class}",
"tier": "All of tier {tier}",
"class": "{tier} {class}",
"tier": "All tier {tier}",
"all": "All tanks"
},
"values": {
+10 -3
View File
@@ -320,9 +320,16 @@
}
},
"commands": {
"dead": "# Stat Commands Are Dead\n\nThe BlitzKit Discord bot used to use BlitzStars to fetch periodic statistics. BlitzStars has enabled aggressive Cloudflare protections; hence, disabling BlitzKit from using BlitzStar's API. This has impacted the following commands:\n\n- `/stats`\n- `/today`\n- `/breakdown`\n- `/evolution`\n- `/full-stats`\n\nPlease use [Aftermath](<https://amth.one/invite>) as an alternative which is completely independent of BlitzStars. BlitzKit-hosted stat commands will return in the near future.",
"replay": {
"name": "replay",
"description": "Display replay results"
"description": "Display replay results",
"options": {
"file": {
"name": "file",
"description": "Replay file"
}
}
},
"research": {
"name": "研究",
@@ -1005,8 +1012,8 @@
"title": "性能値",
"compare": {
"label": "比較対象",
"class": "Tier {tier} {class}",
"tier": "All of tier {tier}",
"class": "{tier} {class}",
"tier": "All tier {tier}",
"all": "全車輌"
},
"values": {
+45 -38
View File
@@ -1,6 +1,6 @@
{
"test": {
"default": "",
"default": "test",
"long": "This is a long test string. You MUST NEVER see this in the UI. My favorite fruit is {fruit} because it has the color of {color}. I like it so much that I will say its name 3 times! {fruit}! {fruit}! {fruit}! Once again, it's {color}, not {not_color}.",
"fox": "Szybki brązowy lis przeskoczył nad leniwym psem."
},
@@ -17,9 +17,9 @@
"plus": "+{value}"
},
"gun_types": {
"auto_loader": "Auto loader",
"auto_loader": "Samo ładowacz",
"auto_reloader": "Automatyczne przeładowanie",
"regular": ""
"regular": "Regular"
},
"shells": {
"ap": "AP",
@@ -28,18 +28,18 @@
"he": "OB"
},
"player_count_period": {
"total": "Total",
"d_120": "Past 120 days",
"d_90": "Past 90 days",
"d_60": "Past 60 days",
"d_30": "Past month",
"total": "Łącznie",
"d_120": "Powyżej 120 dni",
"d_90": "Powyżej 90 dni",
"d_60": "Powyżej 60 dni",
"d_30": "W ciągu miesiąca",
"d_7": "W minionym tygodniu",
"d_1": "Yesterday"
"d_1": "Wczoraj"
},
"branches": {
"local": "dev",
"dev": "beta",
"opentest": "opentest",
"opentest": "otwarty test",
"preview": "podgląd"
},
"locales": {
@@ -80,45 +80,45 @@
},
"nations": {
"ussr": "ZSRR",
"germany": "Germany",
"usa": "U.S.A.",
"germany": "Niemcy",
"usa": "Stany Zjednoczone.",
"china": "Chiny",
"uk": "Wielka Brytania",
"france": "France",
"japan": "Japan",
"france": "Francja",
"japan": "Japonia",
"european": "Nacja Europejska",
"other": "Nacja Hybrydowa"
},
"nations_adjectives": {
"ussr": "ZSRR",
"germany": "German",
"germany": "Niemcy",
"usa": "Amerykański",
"china": "Chiński",
"uk": "Wielkiej Brytanii",
"france": "Francuski",
"japan": "Japoński",
"european": "European",
"other": "Hybrid"
"european": "Europa",
"other": "Hybryda"
},
"tank_class_short": {
"-1": "unrecognized",
"0": "Light",
"1": "Medium",
"2": "Heavy",
"0": "Lekki",
"1": "Średni",
"2": "Ciężki",
"3": "TD"
},
"tank_class_short_plural_lowercase": {
"0": "lights",
"1": "mediums",
"2": "heavies",
"0": "lekkie",
"1": "średnie",
"2": "ciężkie",
"3": "TDs"
},
"tank_class_medium": {
"-1": "unrecognized",
"0": "Lekki",
"1": "Medium",
"2": "Heavy",
"3": "Tank destroyer"
"1": "Średni",
"2": "Ciężki",
"3": "Niszczyciel czołgów"
},
"tree_type": {
"-1": "unrecognized",
@@ -210,7 +210,7 @@
"good": "Dobrze",
"very_good": "Bardzo dobrze",
"great": "Świetne",
"unicum": "Unikalny ",
"unicum": "Unikalny",
"super_unicum": "Bardzo unikalny"
}
},
@@ -236,7 +236,7 @@
"description": "Kariera"
},
"custom": {
"name": "Niestandardowy",
"name": "custom",
"description": "Zakres niestandardowy",
"options": {
"start": {
@@ -320,9 +320,16 @@
}
},
"commands": {
"dead": "# Stat Commands Are Dead\n\nThe BlitzKit Discord bot used to use BlitzStars to fetch periodic statistics. BlitzStars has enabled aggressive Cloudflare protections; hence, disabling BlitzKit from using BlitzStar's API. This has impacted the following commands:\n\n- `/stats`\n- `/today`\n- `/breakdown`\n- `/evolution`\n- `/full-stats`\n\nPlease use [Aftermath](<https://amth.one/invite>) as an alternative which is completely independent of BlitzStars. BlitzKit-hosted stat commands will return in the near future.",
"replay": {
"name": "powtórz",
"description": "Wyświetl wyniki powtórki"
"description": "Wyświetl wyniki powtórki",
"options": {
"file": {
"name": "file",
"description": "Replay file"
}
}
},
"research": {
"name": "badanie",
@@ -849,7 +856,7 @@
"hull": "Hull",
"turret": "Turret",
"hard": "Hard",
"medium": "Medium",
"medium": "Średni",
"soft": "Soft",
"effective": "Effective"
},
@@ -1005,8 +1012,8 @@
"title": "Characteristics",
"compare": {
"label": "Compare against",
"class": "Tier {tier} {class}",
"tier": "All of tier {tier}",
"class": "{tier} {class}",
"tier": "All tier {tier}",
"all": "All tanks"
},
"values": {
@@ -1059,19 +1066,19 @@
"speedBackwards": "Backwards",
"hardTerrainCoefficient": "Hard",
"hardTerrainCoefficientRaw": "Hard",
"mediumTerrainCoefficient": "Medium",
"mediumTerrainCoefficientRaw": "Medium",
"mediumTerrainCoefficient": "Średni",
"mediumTerrainCoefficientRaw": "Średni",
"softTerrainCoefficient": "Soft",
"softTerrainCoefficientRaw": "Soft",
"enginePower": "Engine power",
"powerToWeightRatioHardTerrain": "Hard",
"powerToWeightRatioMediumTerrain": "Medium",
"powerToWeightRatioMediumTerrain": "Średni",
"powerToWeightRatioSoftTerrain": "Soft",
"weight": "Weight",
"turretTraverseSpeed": "Turret traverse speed",
"gunTraverseSpeed": "Gun traverse speed",
"hullTraverseHardTerrain": "Hard",
"hullTraverseMediumTerrain": "Medium",
"hullTraverseMediumTerrain": "Średni",
"hullTraverseSoftTerrain": "Soft",
"health": "Health",
"fireChance": "Fire chance",
@@ -1174,7 +1181,7 @@
"table": {
"tanks": {
"header": "Tank",
"total": "Total"
"total": "Łącznie"
},
"stats": {
"winrate": "Śr. wygranych",
@@ -1232,7 +1239,7 @@
},
"table": {
"tank": "Tank",
"total": "Total",
"total": "Łącznie",
"remove": "Remove"
}
},
+10 -3
View File
@@ -320,9 +320,16 @@
}
},
"commands": {
"dead": "# Stat Commands Are Dead\n\nThe BlitzKit Discord bot used to use BlitzStars to fetch periodic statistics. BlitzStars has enabled aggressive Cloudflare protections; hence, disabling BlitzKit from using BlitzStar's API. This has impacted the following commands:\n\n- `/stats`\n- `/today`\n- `/breakdown`\n- `/evolution`\n- `/full-stats`\n\nPlease use [Aftermath](<https://amth.one/invite>) as an alternative which is completely independent of BlitzStars. BlitzKit-hosted stat commands will return in the near future.",
"replay": {
"name": "replay",
"description": "Exibir resultados de replays"
"description": "Exibir resultados de replays",
"options": {
"file": {
"name": "file",
"description": "Replay file"
}
}
},
"research": {
"name": "pesquisa",
@@ -1005,8 +1012,8 @@
"title": "Características",
"compare": {
"label": "Comparar com",
"class": "Tier {tier} {class}",
"tier": "All of tier {tier}",
"class": "{tier} {class}",
"tier": "All tier {tier}",
"all": "Todos os tanques"
},
"values": {
+10 -3
View File
@@ -320,9 +320,16 @@
}
},
"commands": {
"dead": ".",
"replay": {
"name": "повтор",
"description": "Показать результаты повтора"
"description": "Показать результаты повтора",
"options": {
"file": {
"name": "Файл",
"description": "Запись повтора"
}
}
},
"research": {
"name": "исследование",
@@ -1005,8 +1012,8 @@
"title": "Характеристики",
"compare": {
"label": "Сравнивать с",
"class": "{class} {tier} уровня",
"tier": "Все {tier} уровня",
"class": "Уровень Тип",
"tier": "Все уровни",
"all": "Все танки"
},
"values": {
+21 -14
View File
@@ -1,7 +1,7 @@
{
"test": {
"default": "тест",
"long": "{fruit}",
"long": "{color}{fruit}",
"fox": "Швидка бура лисиця перестрибує через лінивого собаку."
},
"common": {
@@ -23,7 +23,7 @@
},
"shells": {
"ap": "ББ",
"ap_cr": "APCR",
"ap_cr": "",
"hc": "HEAT",
"he": "ОФ"
},
@@ -320,9 +320,16 @@
}
},
"commands": {
"dead": ".",
"replay": {
"name": "реплей",
"description": "Показати результати реплею"
"description": "Показати результати реплею",
"options": {
"file": {
"name": "",
"description": "Replay filehttps://crowdin.com/editor/blitzkrieg/80/en-uk?view=side-by-side#9706"
}
}
},
"research": {
"name": "дослідження",
@@ -660,7 +667,7 @@
},
"tank_search": {
"select_dialog_title": "Знайти танк",
"swap_dialog_title": "Swap tank",
"swap_dialog_title": "Резервуар підміни",
"clear_filters": "Очистити",
"login": "Увійдіть, щоб скористатися",
"search_bar_hint": "Шукайте техніку...",
@@ -671,8 +678,8 @@
"sorting_by": "Відсортувати за {name}",
"clear": "Clear",
"tier": "Рівень {tier}",
"passive": "{name} (Passive)",
"active": "{name} (Active)",
"passive": "",
"active": "{name}{name}",
"no_tanks_found": {
"body": "Нічого не знайдено.",
"search_again": "Спробуйте шукати заново.",
@@ -735,11 +742,11 @@
},
"home": {
"pwa": {
"title": "Install the BlitzKit App",
"title": "",
"new": "",
"checking": "Checking compatibility...",
"instructions": "Instructions for Apple devices.",
"install": "Install",
"checking": "",
"instructions": ".",
"install": "",
"dismiss": "Dismiss"
},
"discord": {
@@ -823,7 +830,7 @@
"help": {
"title": "Partially reveal tank?",
"description": "Reveals the tank without showing the name. This round will be considered incorrect and break your streak!",
"cancel": "Cancel",
"cancel": "",
"reveal": "Reveal"
},
"clear": "Clear",
@@ -1005,8 +1012,8 @@
"title": "Characteristics",
"compare": {
"label": "Compare against",
"class": "Tier {tier} {class}",
"tier": "All of tier {tier}",
"class": "{tier} {class}",
"tier": "All tier {tier}",
"all": "Усі танки"
},
"values": {
@@ -1274,7 +1281,7 @@
"button": "Generate URL",
"title": "Generate URL",
"subtitle": "Search an account to track",
"cancel": "Cancel",
"cancel": "",
"success": {
"title": "Copy URL",
"info": "Generated the URL for {name}. The embed will start tracking as soon as the URL is pasted. Reset at any time by right-clicking on PC or long-pressing on mobile and then selecting \"Reset\".",
+52 -45
View File
@@ -86,8 +86,8 @@
"uk": "英国",
"france": "法国",
"japan": "日本",
"european": "欧洲国家",
"other": "混合型国家"
"european": "欧盟 (E系)",
"other": "X系"
},
"nations_adjectives": {
"ussr": "苏联",
@@ -97,34 +97,34 @@
"uk": "英国",
"france": "法国",
"japan": "日本",
"european": "欧洲国家",
"other": "混合型国家"
"european": "欧盟 (E系)",
"other": "X系"
},
"tank_class_short": {
"-1": "未识别",
"0": "轻型坦克",
"1": "中型坦克",
"2": "重型战车",
"3": "驱逐战车"
"3": "坦克歼击车"
},
"tank_class_short_plural_lowercase": {
"0": "轻型战车",
"1": "中型战车",
"2": "重型战车",
"3": "驱逐战车"
"0": "轻型坦克",
"1": "中型坦克",
"2": "重型坦克",
"3": "坦克歼击车"
},
"tank_class_medium": {
"-1": "未识别",
"0": "轻型战车",
"1": "中型战车",
"2": "重型战车",
"3": "驱逐战车"
"0": "轻型坦克",
"1": "中型坦克",
"2": "重型坦克",
"3": "坦克歼击车"
},
"tree_type": {
"-1": "未识别",
"0": "科技树",
"1": "加值战车",
"2": "收藏家战车"
"1": "金币车",
"2": "收藏车"
},
"regions": {
"normal": {
@@ -140,8 +140,8 @@
},
"leagues": {
"diamond": "钻石",
"platinum": "白金",
"gold": "黃金",
"platinum": "铂金",
"gold": "黄金",
"silver": "白银",
"bronze": "青铜"
},
@@ -210,7 +210,7 @@
"good": "好",
"very_good": "非常好",
"great": "很好",
"unicum": "極品",
"unicum": "极品",
"super_unicum": "超强势玩家"
}
},
@@ -256,7 +256,7 @@
"description": "公会名称或标签"
},
"tank": {
"name": "战车",
"name": "坦克",
"description": "要获取战绩的坦克"
},
"username": {
@@ -269,8 +269,8 @@
"description": "国别"
},
"class": {
"name": "战车车型",
"description": "战车车型"
"name": "坦克车型",
"description": "坦克车型"
},
"type": {
"name": "战车类型",
@@ -320,9 +320,16 @@
}
},
"commands": {
"dead": "# 统计指令现已停用\nBlitzKit Discord 机器人此前依赖 BlitzStars 获取周期性的统计数据。由于 BlitzStars 已启用严格的 Cloudflare 防护,导致 BlitzKit 无法继续使用其 API。这已导致以下指令失效:\n/统计\n/今日\n/损坏\n/演变\n/完整统计\n请使用 [Aftermath](<https://amth.one/invite>) \n作为完全独立于 BlitzStars 的替代方案。由 BlitzKit 托管的统计指令将在近期内恢复。",
"replay": {
"name": "回放",
"description": "显示重播结果"
"description": "显示重播结果",
"options": {
"file": {
"name": "file",
"description": "Replay file"
}
}
},
"research": {
"name": "研发",
@@ -420,8 +427,8 @@
"description": "玩家数据统计"
},
"tank": {
"name": "战车",
"description": "战车数据统计"
"name": "坦克",
"description": "坦克数据统计"
}
}
},
@@ -557,15 +564,15 @@
},
"today": {
"name": "今日",
"description": "今天玩过的战车和统计资料"
"description": "今天玩过的坦克和统计数据"
},
"stats": {
"name": "统计资料",
"description": "一段时间内的快速统计"
},
"owned_tanks": {
"name": "已拥有的战车",
"description": "显示该阶级中所有您已拥有的战车",
"name": "已拥有的坦克",
"description": "在一个等级中显示所有已拥有的坦克",
"body": {
"title": "# {name} 所拥有的 {tier} 阶坦克\n\n"
}
@@ -578,7 +585,7 @@
"view_channels": "查看频道:需要找到重新整理按钮使用的讯息",
"read_message_history": "读取消息历史: 需要找到消息以刷新",
"attach_files": "附加文件:需要将图像添加到基于图像的命令",
"external_emojis": "外部表情符号:需要添加国家旗帜和战车类别"
"external_emojis": "外部表情:需要添加国家旗帜和坦克等级表情"
}
},
"ping": {
@@ -595,7 +602,7 @@
},
"wotb": {
"name": "战车世界闪击战",
"description": "测试战车世界闪击战的ping值(延迟值)"
"description": "测试坦克世界闪击战的ping值(延迟值)"
}
}
},
@@ -666,7 +673,7 @@
"search_bar_hint": "搜寻战车……",
"recent": "最近查看的",
"select_all": "全选",
"count_singular": "1辆战车",
"count_singular": "1 辆坦克",
"count_plural": "{count} 辆坦克",
"sorting_by": "按 {name} 排序",
"clear": "清除",
@@ -674,7 +681,7 @@
"passive": "{name} (被动)",
"active": "{name} (主动)",
"no_tanks_found": {
"body": "找不到战车。",
"body": "未找到坦克。",
"search_again": "请尝试重新搜索。",
"clear_filters": "请尝试清除筛选。"
},
@@ -688,11 +695,11 @@
"survivability.volume": "体积",
"survivability.length": "长度",
"fire.dpm": "标准炮弹 每分钟伤害血量",
"fire.dpmPremium": "加值炮弹 每分钟伤害血量",
"fire.dpmPremium": "金币炮弹 每分钟伤害值",
"fire.reload": "装填时间",
"fire.caliber": "口径",
"fire.standardPenetration": "标准炮弹穿透力",
"fire.premiumPenetration": "加值炮弹穿透力",
"fire.premiumPenetration": "金币炮弹穿透力",
"fire.tertiaryPenetration": "第三种炮弹穿透力",
"fire.damage": "炮弹伤害值",
"fire.moduleDamage": "模组伤害值",
@@ -743,8 +750,8 @@
"dismiss": "取消"
},
"discord": {
"join_short": "加入超級酷的人群!",
"join_long": "加入我們的Discord社群,和超酷的人一起聊天!",
"join_short": "加入超级酷的人群!",
"join_long": "加入我们的Discord社群,和超酷的人一起聊天!",
"action": "Discord"
},
"hero": {
@@ -758,7 +765,7 @@
"title": "其他酷炫的项目"
},
"help_translate": "请帮忙将 {name} 翻译成 {language}!",
"seo_description": "战车世界闪击战 全方位工具"
"seo_description": "坦克世界闪击战 全方位工具"
},
"docs": {
"patches": {
@@ -793,7 +800,7 @@
"proceed": "继续操作"
},
"generate": "创建游玩列表",
"name": "遊玩列表",
"name": "游玩列表",
"description": "坦克游玩列表生成器",
"seo_description": "想不到在坦克世界闪击战玩什么? 使用BlitzKit 游玩列表来获得建议!",
"button": "生成",
@@ -954,7 +961,7 @@
"type": "战车类型",
"dev_id": "开发参数:ID",
"purchase": "购买价格",
"restoration": "恢复战车价格",
"restoration": "恢复坦克价格",
"sale": "出售价格",
"research": "研发所需经验"
},
@@ -1005,8 +1012,8 @@
"title": "属性",
"compare": {
"label": "比较",
"class": "{tier}阶 {class}",
"tier": "所有 {tier} 阶",
"class": "{tier} {class}",
"tier": "All tier {tier}",
"all": "所有坦克"
},
"values": {
@@ -1049,10 +1056,10 @@
"dispersionGunDamaged": "主炮损坏时",
"gunDepression": "俯角",
"gunElevation": "仰角",
"gunFrontalDepression": "车辆前部俯角",
"gunFrontalElevation": "车辆前部仰角",
"gunRearDepression": "车辆後部俯角",
"gunRearElevation": "车辆後部仰角",
"gunFrontalDepression": "车体前部俯角",
"gunFrontalElevation": "车体前部仰角",
"gunRearDepression": "车体后部俯角",
"gunRearElevation": "车体后部仰角",
"azimuthLeft": "左射界",
"azimuthRight": "右射界",
"speedForwards": "最高前进速度",
@@ -1252,7 +1259,7 @@
"description": "用于串流的嵌入",
"seo_description": "创建具有极高自订化的《坦克世界:闪击战》串流嵌入功能",
"coming_soon": "更多嵌入功能即将推出。",
"suggest": "建议与想法",
"suggest": "建议与想法。",
"preview": {
"title": "示例预览",
"upload": "上传测试背景"
+23 -20
View File
@@ -1,5 +1,6 @@
import {
AverageDefinitions,
AverageDefinitionsAllStats,
AverageDefinitionsEntry,
type AverageDefinitionsManifest,
type IndividualTankStats,
@@ -30,9 +31,6 @@ type OptionalSecondLevel<T> = {
};
};
type AverageDefinitionsEntrySubPartial =
OptionalSecondLevel<AverageDefinitionsEntry>;
const MINUTE = 60 * 1000;
const HOUR = 60 * MINUTE;
const DAY = 24 * HOUR;
@@ -47,15 +45,15 @@ const preDiscoveredIds = await fetchPreDiscoveredIds();
const playerIds: Record<Region, number[][]> = {
asia: chunk(
preDiscoveredIds.filter((id) => idToRegion(id) === "asia"),
PLAYER_IDS_PER_CALL
PLAYER_IDS_PER_CALL,
),
com: chunk(
preDiscoveredIds.filter((id) => idToRegion(id) === "com"),
PLAYER_IDS_PER_CALL
PLAYER_IDS_PER_CALL,
),
eu: chunk(
preDiscoveredIds.filter((id) => idToRegion(id) === "eu"),
PLAYER_IDS_PER_CALL
PLAYER_IDS_PER_CALL,
),
};
let regionIndex = 0;
@@ -71,7 +69,7 @@ times(THREADS, async () => {
const regionIds = playerIds[region];
const [ids] = regionIds.splice(
Math.floor(Math.random() * regionIds.length),
1
1,
);
const accountInfo = await getAccountInfo(region, ids, undefined, {
fields: "last_battle_time,statistics.all.battles",
@@ -104,8 +102,8 @@ times(THREADS, async () => {
filteredIds.map((id) =>
getTankStats(region, id, {
fields: "last_battle_time,battle_life_time,all,tank_id",
})
)
}),
),
);
players.forEach((tanks) => {
@@ -114,7 +112,7 @@ times(THREADS, async () => {
if (!tankIds.includes(tank.tank_id)) {
console.log(
`Found new tank: ${tank.tank_id} (${tankIds.length + 1})`
`Found new tank: ${tank.tank_id} (${tankIds.length + 1})`,
);
tankIds.push(tank.tank_id);
tanksSorted[tank.tank_id] = [];
@@ -140,7 +138,7 @@ async function postWork() {
console.log(
`Generating statistics based on ${samples.d_120.toLocaleString()} players (${samples.total.toLocaleString()} checked in total) and ${
tankIds.length
} tanks...`
} tanks...`,
);
using uploader = new AssetUploader("averages");
@@ -152,7 +150,12 @@ async function postWork() {
// (tank) => Date.now() - tank.last_battle_time * 1000 <= MAX_ACTIVITY_TIME,
// );
const tanks = tanksSortedEntry;
const entry: AverageDefinitionsEntrySubPartial = {
const entry: {
mu: Partial<Record<keyof AverageDefinitionsAllStats, number>>;
sigma: Partial<Record<keyof AverageDefinitionsAllStats, number>>;
r: Partial<Record<keyof AverageDefinitionsAllStats, number>>;
samples: Samples;
} = {
mu: {},
sigma: {},
r: {},
@@ -162,13 +165,13 @@ async function postWork() {
tanks.forEach((tank) => {
const timeSinceLastActivity = Date.now() - tank.last_battle_time * 1000;
entry.samples.total++;
if (timeSinceLastActivity <= 120 * DAY) entry.samples.d_120++;
if (timeSinceLastActivity <= 90 * DAY) entry.samples.d_90++;
if (timeSinceLastActivity <= 60 * DAY) entry.samples.d_60++;
if (timeSinceLastActivity <= 30 * DAY) entry.samples.d_30++;
if (timeSinceLastActivity <= 7 * DAY) entry.samples.d_7++;
if (timeSinceLastActivity <= 1 * DAY) entry.samples.d_1++;
entry.samples!.total++;
if (timeSinceLastActivity <= 120 * DAY) entry.samples!.d_120++;
if (timeSinceLastActivity <= 90 * DAY) entry.samples!.d_90++;
if (timeSinceLastActivity <= 60 * DAY) entry.samples!.d_60++;
if (timeSinceLastActivity <= 30 * DAY) entry.samples!.d_30++;
if (timeSinceLastActivity <= 7 * DAY) entry.samples!.d_7++;
if (timeSinceLastActivity <= 1 * DAY) entry.samples!.d_1++;
});
const dataWY = tanks.map((tank) => ({
@@ -191,7 +194,7 @@ async function postWork() {
function sum(slicer: (data: DataPoint) => number) {
return data.reduce(
(accumulator, data) => accumulator + slicer(data),
0
0,
);
}
@@ -18,9 +18,9 @@ export async function consumableProvisionIcons() {
using uploader = new AssetUploader("consumable and provision icons");
const styles = [
"UI/Styles/Lobby/Inventory/InventoryNormalStyles.yaml",
"UI/Styles/Lobby/Inventory/Event/InventoryBigStyles.yaml",
"UI/Styles/Lobby/Inventory/Event/InventoryNormalStyles.yaml",
"UI/Styles/Lobby/Inventory/InventoryNormalStyles.yaml",
"UI/Screens3/Lobby/Inventory/Equipment/EquipmentItemImage.style.yaml",
"UI/Screens/Battle/Styles/BattleEquipmentStyles.yaml",
];
+99 -98
View File
@@ -81,16 +81,16 @@ const blitzTankFilterDefinitionCategoryToBlitzkit: Record<
BlitzTankFilterDefinitionCategory,
ConsumableTankCategoryFilterCategory
> = {
clip: ConsumableTankCategoryFilterCategory.CLIP,
clip: ConsumableTankCategoryFilterCategory.CONSUMABLE_TANK_CATEGORY_FILTER_CATEGORY_CLIP,
};
function vector3TupleToBlitzkit(tuple: Vector3Tuple) {
return { x: tuple[0], y: tuple[1], z: tuple[2] } satisfies Vector3;
}
const blitzTankClassToBlitzkit: Record<BlitzTankClass, TankClass> = {
lightTank: TankClass.LIGHT,
"AT-SPG": TankClass.TANK_DESTROYER,
heavyTank: TankClass.HEAVY,
mediumTank: TankClass.MEDIUM,
lightTank: TankClass.TANK_CLASS_LIGHT,
"AT-SPG": TankClass.TANK_CLASS_TANK_DESTROYER,
heavyTank: TankClass.TANK_CLASS_HEAVY,
mediumTank: TankClass.TANK_CLASS_MEDIUM,
};
export interface BlitzStrings {
[key: string]: string;
@@ -149,18 +149,18 @@ type BlitzModuleType = {
type UnlocksListing = BlitzModuleType | undefined;
type BlitzCrewType = "commander" | "radioman" | "gunner" | "driver" | "loader";
const blitzCrewTypeToBlitzkit: Record<BlitzCrewType, CrewType> = {
commander: CrewType.COMMANDER,
driver: CrewType.DRIVER,
gunner: CrewType.GUNNER,
loader: CrewType.LOADER,
radioman: CrewType.RADIOMAN,
commander: CrewType.CREW_TYPE_COMMANDER,
driver: CrewType.CREW_TYPE_DRIVER,
gunner: CrewType.CREW_TYPE_GUNNER,
loader: CrewType.CREW_TYPE_LOADER,
radioman: CrewType.CREW_TYPE_RADIOMAN,
};
const blitzkitCrewTypeToBlitz: Record<CrewType, BlitzCrewType> = {
[CrewType.COMMANDER]: "commander",
[CrewType.DRIVER]: "driver",
[CrewType.GUNNER]: "gunner",
[CrewType.LOADER]: "loader",
[CrewType.RADIOMAN]: "radioman",
[CrewType.CREW_TYPE_COMMANDER]: "commander",
[CrewType.CREW_TYPE_DRIVER]: "driver",
[CrewType.CREW_TYPE_GUNNER]: "gunner",
[CrewType.CREW_TYPE_LOADER]: "loader",
[CrewType.CREW_TYPE_RADIOMAN]: "radioman",
};
interface VehicleDefinitions {
invisibility: {
@@ -298,7 +298,7 @@ interface VehicleDefinitions {
type: "default";
enabled: false;
factorsModifiers: "";
}
},
];
};
};
@@ -517,18 +517,18 @@ type CombatRolesYaml = Record<
>;
const blitzShellKindToBlitzkit: Record<ShellKind, ShellType> = {
ARMOR_PIERCING: ShellType.AP,
ARMOR_PIERCING_CR: ShellType.APCR,
HIGH_EXPLOSIVE: ShellType.HE,
HOLLOW_CHARGE: ShellType.HEAT,
ARMOR_PIERCING: ShellType.SHELL_TYPE_AP,
ARMOR_PIERCING_CR: ShellType.SHELL_TYPE_APCR,
HIGH_EXPLOSIVE: ShellType.SHELL_TYPE_HE,
HOLLOW_CHARGE: ShellType.SHELL_TYPE_HEAT,
};
export const botPattern = /^.+((tutorial_bot(\d+)?)|(TU))$/;
const blitzModuleTypeToBlitzkit: Record<keyof BlitzModuleType, ModuleType> = {
chassis: ModuleType.TRACKS,
engine: ModuleType.ENGINE,
gun: ModuleType.GUN,
turret: ModuleType.TURRET,
vehicle: ModuleType.VEHICLE,
chassis: ModuleType.MODULE_TYPE_TRACKS,
engine: ModuleType.MODULE_TYPE_ENGINE,
gun: ModuleType.MODULE_TYPE_GUN,
turret: ModuleType.MODULE_TYPE_TURRET,
vehicle: ModuleType.MODULE_TYPE_VEHICLE,
};
export async function definitions() {
@@ -555,10 +555,10 @@ export async function definitions() {
const provisionDefinitions: ProvisionDefinitions = { provisions: {} };
const skillDefinitions: SkillDefinitions = {
classes: {
[TankClass.LIGHT]: { skills: [] },
[TankClass.MEDIUM]: { skills: [] },
[TankClass.HEAVY]: { skills: [] },
[TankClass.TANK_DESTROYER]: { skills: [] },
[TankClass.TANK_CLASS_LIGHT]: { skills: [] },
[TankClass.TANK_CLASS_MEDIUM]: { skills: [] },
[TankClass.TANK_CLASS_HEAVY]: { skills: [] },
[TankClass.TANK_CLASS_TANK_DESTROYER]: { skills: [] },
},
};
const nations = vfs
@@ -566,7 +566,7 @@ export async function definitions() {
.filter((nation) => nation !== "common");
const tankStringIdMap: Record<string, number> = {};
const optionalDevices = await vfs.xml<{ root: OptionalDevices }>(
"Data/XML/item_defs/vehicles/common/optional_devices.xml"
"Data/XML/item_defs/vehicles/common/optional_devices.xml",
);
const stringsI18n: Record<string, Record<string, string>> = {};
@@ -574,12 +574,12 @@ export async function definitions() {
locales.supported.map(async ({ locale }) => {
const blitzLocale = SUPPORTED_LOCALE_BLITZ_MAP[locale];
const cache = await fetch(
`https://stufficons.wgcdn.co/localizations/${blitzLocale}.yaml`
`https://stufficons.wgcdn.co/localizations/${blitzLocale}.yaml`,
)
.then((response) => response.text())
.then((string) => parseYaml(string) as BlitzStrings);
const preInstalled = await vfs.yaml<BlitzStrings>(
`Data/Strings/${blitzLocale}.yaml`
`Data/Strings/${blitzLocale}.yaml`,
);
stringsI18n[locale] = {
@@ -588,7 +588,7 @@ export async function definitions() {
};
console.log(`Loaded strings for ${locale}`);
})
}),
);
function getString(name: string) {
@@ -627,9 +627,9 @@ export async function definitions() {
consumables,
(
await vfs.xml<{ root: ConsumablesCommon }>(
`Data/XML/item_defs/vehicles/common/consumables/${match[1]}.xml`
`Data/XML/item_defs/vehicles/common/consumables/${match[1]}.xml`,
)
).root
).root,
);
}
@@ -642,39 +642,39 @@ export async function definitions() {
provisions,
(
await vfs.xml<{ root: ConsumablesCommon }>(
`Data/XML/item_defs/vehicles/common/provisions/${match[1]}.xml`
`Data/XML/item_defs/vehicles/common/provisions/${match[1]}.xml`,
)
).root
).root,
);
}
const avatar = await vfs.xml<{ root: Avatar }>(
`Data/XML/item_defs/tankmen/avatar.xml`
`Data/XML/item_defs/tankmen/avatar.xml`,
);
const maps = await vfs.yaml<Maps>(`Data/maps.yaml`);
const tankXps = new Map<number, ResearchCost>();
const camouflagesXml = await vfs.xml<{ root: CamouflagesXML }>(
`Data/XML/item_defs/vehicles/common/camouflages.xml`
`Data/XML/item_defs/vehicles/common/camouflages.xml`,
);
const camouflagesYaml = await vfs.yaml<CamouflagesYaml>(
`Data/camouflages.yaml`
`Data/camouflages.yaml`,
);
const camouflagesXmlEntries = Object.entries(camouflagesXml.root.camouflages);
const squadBattleTypeStyles = await vfs.yaml<SquadBattleTypeStyles>(
`Data/UI/Screens3/Lobby/Hangar/Squad/SquadBattleType.yaml`
`Data/UI/Screens3/Lobby/Hangar/Squad/SquadBattleType.yaml`,
);
const gameTypeSelectorStyles = await vfs.yaml<SquadBattleTypeStyles>(
`Data/UI/Screens/Lobby/Hangar/GameTypeSelector.yaml`
`Data/UI/Screens/Lobby/Hangar/GameTypeSelector.yaml`,
);
const gameModeNativeNames: Record<string, number> = {};
const combatRoles = await vfs.yaml<CombatRolesYaml>(
`Data/XML/item_defs/vehicles/common/combat_roles.yaml`
`Data/XML/item_defs/vehicles/common/combat_roles.yaml`,
);
const consumableNativeNames: Record<string, number> = {};
const provisionNativeNames: Record<string, number> = {};
for (const match of squadBattleTypeStyles.Prototypes[0].components.UIDataLocalBindingsComponent.data[1][2].matchAll(
/"(\d+)" -> "(battleType\/([a-zA-Z]+))"/g
/"(\d+)" -> "(battleType\/([a-zA-Z]+))"/g,
)) {
const id = Number(match[1]);
const name = getString(match[2]);
@@ -686,7 +686,7 @@ export async function definitions() {
}
for (const match of gameTypeSelectorStyles.Prototypes[0].components.UIDataLocalBindingsComponent.data[1][2].matchAll(
/eGameMode\.([a-zA-Z]+) -> "~res:\/Gfx\/UI\/Hangar\/GameTypes\/battle-type_([^"]+)"/g
/eGameMode\.([a-zA-Z]+) -> "~res:\/Gfx\/UI\/Hangar\/GameTypes\/battle-type_([^"]+)"/g,
)) {
Object.entries(gameModeNativeNames).forEach(([key, value]) => {
if (key.toLowerCase() === match[2].toLowerCase()) {
@@ -720,7 +720,7 @@ export async function definitions() {
for (const nation of nations) {
const tankList = await vfs.xml<{ root: VehicleDefinitionList }>(
`Data/XML/item_defs/vehicles/${nation}/list.xml`
`Data/XML/item_defs/vehicles/${nation}/list.xml`,
);
for (const tankKey in tankList.root) {
@@ -761,7 +761,7 @@ export async function definitions() {
console.warn(
`Multiple tanks share slug ${slug}: ${requesters
.map(({ key }) => key)
.join(", ")}`
.join(", ")}`,
);
if (requesters.length !== 2) {
@@ -791,7 +791,7 @@ export async function definitions() {
if (canonical === undefined) {
throw new Error(
"Two tutorial bots share the same slug? The world is truly broken."
"Two tutorial bots share the same slug? The world is truly broken.",
);
}
@@ -804,7 +804,7 @@ export async function definitions() {
for (const nation of nations) {
const tankList = await vfs.xml<{ root: VehicleDefinitionList }>(
`Data/XML/item_defs/vehicles/${nation}/list.xml`
`Data/XML/item_defs/vehicles/${nation}/list.xml`,
);
const turretList = await vfs.xml<{
root: TurretDefinitionsList;
@@ -857,7 +857,7 @@ export async function definitions() {
: Number(item.cost.split(":")[1]),
},
} satisfies Unlock;
})
}),
)
.flat();
}
@@ -872,10 +872,10 @@ export async function definitions() {
const tank = tankList.root[tankKey];
let tankPrice: TankPrice;
const tankDefinition = await vfs.xml<{ root: VehicleDefinitions }>(
`Data/XML/item_defs/vehicles/${nation}/${tankKey}.xml`
`Data/XML/item_defs/vehicles/${nation}/${tankKey}.xml`,
);
const tankParameters = await vfs.yaml<TankParameters>(
`Data/3d/Tanks/Parameters/${nation}/${tankKey}.yaml`
`Data/3d/Tanks/Parameters/${nation}/${tankKey}.yaml`,
);
const turretOrigin = tankDefinition.root.hull.turretPositions.turret
.split(" ")
@@ -890,23 +890,23 @@ export async function definitions() {
if (slug === undefined) {
throw new Error(
`Could not find slug for ${nation}/${tankKey} (${tankId})`
`Could not find slug for ${nation}/${tankKey} (${tankId})`,
);
}
if (tank.sellPrice) {
tankPrice = {
type: TankPriceType.GOLD,
type: TankPriceType.TANK_PRICE_TYPE_GOLD,
value: tank.sellPrice["#text"] * 2,
};
} else if (typeof tank.price === "number") {
tankPrice = {
type: TankPriceType.CREDITS,
type: TankPriceType.TANK_PRICE_TYPE_CREDITS,
value: tank.price,
};
} else {
tankPrice = {
type: TankPriceType.CREDITS,
type: TankPriceType.TANK_PRICE_TYPE_CREDITS,
value: tank.price["#text"] * 400,
};
}
@@ -938,7 +938,7 @@ export async function definitions() {
Object.entries(tankDefinition.root.crew).forEach(([crewKey, value]) => {
let entry: Crew;
const index = crew.findIndex(
({ type }) => blitzkitCrewTypeToBlitz[type] === crewKey
({ type }) => blitzkitCrewTypeToBlitz[type] === crewKey,
);
if (index === -1) {
if (crewKey === "#text") return;
@@ -992,6 +992,7 @@ export async function definitions() {
ancestors: [],
successors: [],
id: tankId,
dev_name: tankKey,
roles: {},
camouflages: camouflages,
fixed_camouflage: fixedCamouflage,
@@ -1011,10 +1012,10 @@ export async function definitions() {
slug,
nation,
type: tankTags.includes("collectible")
? TankType.COLLECTOR
? TankType.TANK_TYPE_COLLECTOR
: (typeof tank.price === "number" ? false : "gold" in tank.price)
? TankType.PREMIUM
: TankType.RESEARCHABLE,
? TankType.TANK_TYPE_PREMIUM
: TankType.TANK_TYPE_RESEARCHABLE,
tier: tank.level,
class: blitzTankClassToBlitzkit[tankTags[0] as BlitzTankClass],
testing: tankTags.includes("testTank"),
@@ -1022,7 +1023,7 @@ export async function definitions() {
price: tankPrice,
camouflage_still: tankDefinition.root.invisibility.still,
camouflage_moving: tankDefinition.root.invisibility.moving,
camouflage_onFire: tankDefinition.root.invisibility.firePenalty,
camouflage_on_fire: tankDefinition.root.invisibility.firePenalty,
turrets: [],
engines: [],
tracks: [],
@@ -1031,12 +1032,12 @@ export async function definitions() {
if (tank.combatRole) {
Object.entries(tank.combatRole).forEach(([gameMode, role]) => {
const id = Object.entries(gameModeNativeNames).find(
([key]) => key.toLowerCase() === gameMode.toLowerCase()
([key]) => key.toLowerCase() === gameMode.toLowerCase(),
)?.[1];
if (id === undefined) {
throw new Error(
`Unknown game mode in tank ${tankKey}: ${gameMode}`
`Unknown game mode in tank ${tankKey}: ${gameMode}`,
);
}
@@ -1118,7 +1119,7 @@ export async function definitions() {
(turretKey, turretIndex) => {
const turret = tankDefinition.root.turrets0[turretKey];
const turretModel = Number(
parsePath(turret.models.undamaged).name.split("_")[1]
parsePath(turret.models.undamaged).name.split("_")[1],
);
const turretId = toUniqueId(nation, turretList.root.ids[turretKey]);
const turretYaw = (
@@ -1186,12 +1187,12 @@ export async function definitions() {
min: vector3TupleToBlitzkit(
tankParameters.collision[
parsePath(turret.hitTester.collisionModel).name.toLowerCase()
].bbox.min
].bbox.min,
),
max: vector3TupleToBlitzkit(
tankParameters.collision[
parsePath(turret.hitTester.collisionModel).name.toLowerCase()
].bbox.max
].bbox.max,
),
},
};
@@ -1209,7 +1210,7 @@ export async function definitions() {
.split(" ")
.map(Number) as [number, number];
const gunModel = Number(
parsePath(gun.models.undamaged).name.split("_")[1]
parsePath(gun.models.undamaged).name.split("_")[1],
);
const gunName = getString(gunListEntry.userString);
const gunType =
@@ -1332,24 +1333,24 @@ export async function definitions() {
},
}
: gunType === "autoReloader"
? {
$case: "auto_reloader",
value: {
intra_clip: 60 / gun.clip!.rate,
shell_count: gunClipCount,
shell_reloads: gun
.pumpGunReloadTimes!.split(" ")
.map(Number),
? {
$case: "auto_reloader",
value: {
intra_clip: 60 / gun.clip!.rate,
shell_count: gunClipCount,
shell_reloads: gun
.pumpGunReloadTimes!.split(" ")
.map(Number),
},
}
: {
$case: "auto_loader",
value: {
intra_clip: 60 / gun.clip!.rate,
clip_reload: gun.reloadTime,
shell_count: gunClipCount,
},
},
}
: {
$case: "auto_loader",
value: {
intra_clip: 60 / gun.clip!.rate,
clip_reload: gun.reloadTime,
shell_count: gunClipCount,
},
},
} satisfies GunDefinition);
modelDefinitions.models[tankId].turrets[turretId].guns[gunId] = {
@@ -1360,8 +1361,8 @@ export async function definitions() {
gun.armor.gun === undefined
? 0
: typeof gun.armor.gun === "number"
? gun.armor.gun
: gun.armor.gun["#text"],
? gun.armor.gun
: gun.armor.gun["#text"],
pitch: {
min: gunPitch[0],
max: gunPitch[1],
@@ -1408,7 +1409,7 @@ export async function definitions() {
type: blitzShellKindToBlitzkit[shell.kind],
explosion_radius:
shell.kind === "HIGH_EXPLOSIVE"
? shell.explosionRadius ?? 0
? (shell.explosionRadius ?? 0)
: undefined,
icon: shell.icon,
penetration: {
@@ -1419,7 +1420,7 @@ export async function definitions() {
});
});
});
}
},
);
totalUnlocks.forEach((unlocks) => {
@@ -1447,7 +1448,7 @@ export async function definitions() {
case "gun": {
gunXps.set(
toUniqueId(nation, gunList.root.ids[vehicle["#text"]]),
parseResearchCost(vehicle.cost)
parseResearchCost(vehicle.cost),
);
break;
}
@@ -1455,7 +1456,7 @@ export async function definitions() {
case "turret": {
turretXps.set(
toUniqueId(nation, turretList.root.ids[vehicle["#text"]]),
parseResearchCost(vehicle.cost)
parseResearchCost(vehicle.cost),
);
break;
}
@@ -1463,7 +1464,7 @@ export async function definitions() {
case "engine": {
engineXps.set(
toUniqueId(nation, enginesList.root.ids[vehicle["#text"]]),
parseResearchCost(vehicle.cost)
parseResearchCost(vehicle.cost),
);
break;
}
@@ -1471,7 +1472,7 @@ export async function definitions() {
case "chassis": {
trackXps.set(
toUniqueId(nation, chassisList.root.ids[vehicle["#text"]]),
parseResearchCost(vehicle.cost)
parseResearchCost(vehicle.cost),
);
break;
}
@@ -1518,7 +1519,7 @@ export async function definitions() {
name: getString(optionalDeviceEntry.userString),
description: getString(optionalDeviceEntry.description),
};
}
},
);
Object.entries(optionalDeviceSlots.root.presets).forEach(
@@ -1537,7 +1538,7 @@ export async function definitions() {
})
.flat(),
};
}
},
);
Object.entries(consumables).forEach(([key, consumable]) => {
@@ -1620,7 +1621,7 @@ export async function definitions() {
(item) =>
blitzTankFilterDefinitionCategoryToBlitzkit[
item as BlitzTankFilterDefinitionCategory
]
],
),
},
},
@@ -1718,7 +1719,7 @@ export async function definitions() {
(item) =>
blitzTankFilterDefinitionCategoryToBlitzkit[
item as BlitzTankFilterDefinitionCategory
]
],
),
},
},
@@ -1749,11 +1750,11 @@ export async function definitions() {
value.default_abilities.forEach((ability) => {
if (ability in consumableNativeNames) {
gameDefinitions.roles[value.id].consumables.push(
consumableNativeNames[ability]
consumableNativeNames[ability],
);
} else if (ability in provisionNativeNames) {
gameDefinitions.roles[value.id].provisions.push(
provisionNativeNames[ability]
provisionNativeNames[ability],
);
} else throw new Error(`Unknown ability ${ability}`);
});
+6 -6
View File
@@ -15,7 +15,7 @@ export async function glossary() {
const glossary = await fetchGlossary(supported.blitz ?? supported.locale);
console.log(
`Found ${Object.keys(glossary).length} things for ${supported.locale}`
`Found ${Object.keys(glossary).length} things for ${supported.locale}`,
);
for (const key in glossary) {
@@ -30,7 +30,7 @@ export async function glossary() {
}
if (key in avatars) {
avatars[key].avatar.name.locales[supported.locale] =
avatars[key].avatar.name!.locales[supported.locale] =
glossaryEntry.title;
} else {
const extension = extname(glossaryEntry.image_url);
@@ -45,7 +45,7 @@ export async function glossary() {
};
}
}
})
}),
);
const gallery: Gallery = { avatars: [] };
@@ -53,12 +53,12 @@ export async function glossary() {
const bar = new ProgressBar(
`Fetching avatars of ${totalCount} things :bar`,
totalCount
totalCount,
);
await Promise.all(
Object.entries(avatars).map(async ([key, { url, avatar }]) => {
if (!(locales.default in avatars[key].avatar.name.locales)) {
if (!(locales.default in avatars[key].avatar.name!.locales)) {
console.warn(`Avatar ${key} has no ${locales.default} name`);
bar.tick();
@@ -77,7 +77,7 @@ export async function glossary() {
});
bar.tick();
})
}),
);
await uploader.add({
@@ -12,12 +12,14 @@ export async function tankModels() {
using uploader = new AssetUploader("tank models");
const nodeIO = new NodeIO().registerExtensions(ALL_EXTENSIONS);
const nations = vfs.dir(`Data/XML/item_defs/vehicles`).filter((nation) => nation !== "common")
const nations = vfs
.dir(`Data/XML/item_defs/vehicles`)
.filter((nation) => nation !== "common");
for (const nationIndex in nations) {
const nation = nations[nationIndex];
const tanks = await vfs.xml<{ root: VehicleDefinitionList }>(
`Data/XML/item_defs/vehicles/${nation}/list.xml`
`Data/XML/item_defs/vehicles/${nation}/list.xml`,
);
const entries = Object.entries(tanks.root);
@@ -26,11 +28,11 @@ export async function tankModels() {
const id = toUniqueId(nation, tank.id);
const parameters = await vfs.yaml<TankParameters>(
`Data/3d/Tanks/Parameters/${nation}/${tankKey}.yaml`
`Data/3d/Tanks/Parameters/${nation}/${tankKey}.yaml`,
);
const model = await extractModel(
vfs,
parameters.resourcesPath.blitzModelPath.replace(/\.sc2$/, "")
parameters.resourcesPath.blitzModelPath.replace(/\.sc2$/, ""),
);
const content = Buffer.from(await nodeIO.writeBinary(model));
@@ -39,4 +41,4 @@ export async function tankModels() {
}
await uploader.flush();
}
}
@@ -6,13 +6,13 @@ import {
} from "@blitzkit/core";
import { Accessor, Document, Node, Scene } from "@gltf-transform/core";
import { times } from "lodash-es";
import { SteamVFS } from "../vfs/steam";
import { AbstractVFS } from "../vfs/abstract";
import {
vertexAttributeGLTFName,
vertexAttributeGltfVectorSizes,
} from "./extractModel/constants";
export async function extractArmor(vfs: SteamVFS, fileName: string) {
export async function extractArmor(vfs: AbstractVFS, fileName: string) {
const sc2Path = `Data/3d/Tanks/CollisionMeshes/${fileName}.sc2`;
const scgPath = `Data/3d/Tanks/CollisionMeshes/${fileName}.scg`;
const sc2 = new Sc2ReadStream(
@@ -141,4 +141,4 @@ export async function extractArmor(vfs: SteamVFS, fileName: string) {
parseHierarchies(sc2["#hierarchy"], scene);
return document;
}
}
@@ -1,4 +1,5 @@
import {
bufferToBigInt,
Hierarchy,
Sc2ReadStream,
ScgReadStream,
@@ -9,7 +10,7 @@ import { Document, Material, Node, Scene } from "@gltf-transform/core";
import { dedup, prune } from "@gltf-transform/functions";
import { times } from "lodash-es";
import { dirname } from "path";
import { SteamVFS } from "../../vfs/steam";
import { AbstractVFS } from "../../vfs/abstract";
import { readBaseColor } from "../readBaseColor";
import { readNormal } from "../readNormal";
import { readRoughnessMetallic } from "../readRoughnessMetallic";
@@ -25,7 +26,7 @@ const omitMeshNames = {
end: ["_POINT"],
};
export async function extractModel(vfs: SteamVFS, path: string) {
export async function extractModel(vfs: AbstractVFS, path: string) {
const sc2Path = `Data/3d/${path}.sc2`;
const scgPath = `Data/3d/${path}.scg`;
const sc2 = new Sc2ReadStream(
@@ -40,7 +41,7 @@ export async function extractModel(vfs: SteamVFS, path: string) {
const materials = new Map<bigint, Material | bigint | undefined>();
for (const node of sc2["#dataNodes"]) {
const id = new DataView(node["#id"]).getBigUint64(0, true);
const id = bufferToBigInt(node["#id"]);
if (node.parentMaterialKey !== undefined) {
/**
@@ -80,8 +81,20 @@ export async function extractModel(vfs: SteamVFS, path: string) {
configIndex < node.configCount;
configIndex++
) {
if (!hasAlpha) continue;
material.setAlphaMode("BLEND").setDoubleSided(true);
const archive = node[`configArchive_${configIndex}`];
if (
archive.configName !== "Default" ||
!archive.enabledPresets?.AlphaTest
) {
continue;
}
const view = new DataView(archive.properties.alphatestThreshold);
const _ = view.getUint8(0); // only god knows what these flags are
const alphaCutoff = view.getFloat32(1, true);
material.setAlphaMode("MASK").setAlphaCutoff(alphaCutoff);
}
}
@@ -116,7 +129,7 @@ export async function extractModel(vfs: SteamVFS, path: string) {
);
}
materials.set(new DataView(node["#id"]).getBigUint64(0, true), material);
materials.set(id, material);
}
}
@@ -157,6 +170,7 @@ export async function extractModel(vfs: SteamVFS, path: string) {
break;
case "TransformComponent": {
component["tc.localTranslation"] = [0, 0, 0]; // Game when is loading model resets position to [0, 0, 0], so any set value is ignored.
node.setTranslation(component["tc.localTranslation"]);
node.setRotation(component["tc.localRotation"]);
node.setScale(component["tc.localScale"]);
@@ -266,4 +280,4 @@ export async function extractModel(vfs: SteamVFS, path: string) {
await document.transform(prune({ keepAttributes: true }), dedup());
return document;
}
}
+4 -4
View File
@@ -1,5 +1,5 @@
import { crc32 } from 'crc';
import { compressBlock } from 'lz4js';
import { crc32 } from "crc";
import { compressBlock } from "lz4js";
/**
* Thanks Maddoxkkm! Modernized heavily.
@@ -14,7 +14,7 @@ export function writeDVPL(buffer: Buffer) {
destination,
0,
source.length,
0,
[0],
);
let output = Buffer.from(destination);
@@ -58,7 +58,7 @@ function toDVPLFooter(
result.writeUInt32LE(compressedSize, 4);
result.writeUInt32LE(crc32, 8);
result.writeUInt32LE(type, 12);
result.write('DVPL', 16, 4, 'utf8');
result.write("DVPL", 16, 4, "utf8");
return result;
}
+3 -2
View File
@@ -38,7 +38,7 @@ export class SteamVFS extends AbstractVFS {
private username: string,
private password: string,
private app: number,
private depot: number
private depot: number,
) {
super();
}
@@ -57,13 +57,14 @@ export class SteamVFS extends AbstractVFS {
this.steam.getManifest(
this.app,
this.depot,
// @ts-expect-error
productInfo.apps[this.app].appinfo.depots[this.depot].manifests.public
.gid,
"public",
// @ts-expect-error
(_, response) => {
resolve(response);
}
},
);
});
+32 -30
View File
@@ -53,7 +53,7 @@ if (newTanks.length > 0) {
notes += "## New Tanks\n\n";
for (const tank of newTanks) {
notes += `### [${tank.name.locales.en}](${domain}/tanks/${tank.slug})\n`;
notes += `### [${tank.name!.locales.en}](${domain}/tanks/${tank.slug})\n`;
notes += `![](${tankIcon(tank.id)})\n\n`;
}
@@ -96,49 +96,49 @@ if (changedTanks.length > 0) {
const previewTankModel = previewModelDefinitions.models[preview.id];
const currentConsumables = Object.values(
currentConsumableDefinitions.consumables
currentConsumableDefinitions.consumables,
).filter((consumable) =>
checkConsumableProvisionInclusivity(consumable, current, currentGun)
checkConsumableProvisionInclusivity(consumable, current, currentGun),
);
const previewConsumables = Object.values(
previewConsumableDefinitions.consumables
previewConsumableDefinitions.consumables,
).filter((consumable) =>
checkConsumableProvisionInclusivity(consumable, preview, previewGun)
checkConsumableProvisionInclusivity(consumable, preview, previewGun),
);
const addedConsumables = previewConsumables.filter(
(previewConsumable) =>
!currentConsumables.some(
(currentConsumable) => currentConsumable.id === previewConsumable.id
)
(currentConsumable) => currentConsumable.id === previewConsumable.id,
),
);
const removedConsumables = currentConsumables.filter(
(currentConsumable) =>
!previewConsumables.some(
(previewConsumable) => previewConsumable.id === currentConsumable.id
)
(previewConsumable) => previewConsumable.id === currentConsumable.id,
),
);
const currentProvisions = availableProvisions(
current,
currentGun,
currentProvisionDefinitions
currentProvisionDefinitions,
);
const previewProvisions = availableProvisions(
preview,
previewGun,
previewProvisionDefinitions
previewProvisionDefinitions,
);
const addedProvisions = previewProvisions.filter(
(previewProvision) =>
!currentProvisions.some(
(currentProvision) => currentProvision.id === previewProvision.id
)
(currentProvision) => currentProvision.id === previewProvision.id,
),
);
const removedProvisions = currentProvisions.filter(
(currentProvision) =>
!previewProvisions.some(
(previewProvision) => previewProvision.id === currentProvision.id
)
(previewProvision) => previewProvision.id === currentProvision.id,
),
);
const currentEquipment = currentEquipmentDefinitions.presets[
@@ -155,16 +155,16 @@ if (changedTanks.length > 0) {
.filter(
(previewEquipment) =>
!currentEquipment.some(
(currentEquipment) => currentEquipment === previewEquipment
)
(currentEquipment) => currentEquipment === previewEquipment,
),
)
.map((id) => previewEquipmentDefinitions.equipments[id]);
const removedEquipment = currentEquipment
.filter(
(currentEquipment) =>
!previewEquipment.some(
(previewEquipment) => previewEquipment === currentEquipment
)
(previewEquipment) => previewEquipment === currentEquipment,
),
)
.map((id) => currentEquipmentDefinitions.equipments[id]);
@@ -184,7 +184,7 @@ if (changedTanks.length > 0) {
provisions: createDefaultProvisions(
current,
currentGun,
currentProvisionDefinitions
currentProvisionDefinitions,
),
equipmentMatrix: genericDefaultEquipmentMatrix,
stockEngine: current.engines[0],
@@ -198,7 +198,7 @@ if (changedTanks.length > 0) {
equipmentDefinitions: currentEquipmentDefinitions,
provisionDefinitions: currentProvisionDefinitions,
tankModelDefinition: currentTankModel,
}
},
);
const previewCharacteristics = tankCharacteristics(
{
@@ -216,7 +216,7 @@ if (changedTanks.length > 0) {
provisions: createDefaultProvisions(
preview,
previewGun,
previewProvisionDefinitions
previewProvisionDefinitions,
),
equipmentMatrix: genericDefaultEquipmentMatrix,
stockEngine: preview.engines[0],
@@ -230,7 +230,7 @@ if (changedTanks.length > 0) {
equipmentDefinitions: previewEquipmentDefinitions,
provisionDefinitions: previewProvisionDefinitions,
tankModelDefinition: previewTankModel,
}
},
);
const changedCharacteristics: string[] = [];
@@ -244,17 +244,17 @@ if (changedTanks.length > 0) {
}
}
notes += `### [${preview.name.locales.en}](${domain}/tanks/${preview.slug})\n`;
notes += `### [${preview.name!.locales.en}](${domain}/tanks/${preview.slug})\n`;
notes += `![](${tankIcon(preview.id)})\n\n`;
if (addedConsumables.length + removedConsumables.length > 0) {
notes += `Consumables: `;
notes += [
...addedConsumables.map(
(consumable) => `🟢 ${consumable.name.locales.en}`
(consumable) => `🟢 ${consumable.name!.locales.en}`,
),
...removedConsumables.map(
(consumable) => `🔴 ${consumable.name.locales.en}`
(consumable) => `🔴 ${consumable.name!.locales.en}`,
),
].join(", ");
notes += `\n`;
@@ -264,10 +264,10 @@ if (changedTanks.length > 0) {
notes += `Provisions: `;
notes += [
...addedProvisions.map(
(provision) => `🟢 ${provision.name.locales.en}`
(provision) => `🟢 ${provision.name!.locales.en}`,
),
...removedProvisions.map(
(provision) => `🔴 ${provision.name.locales.en}`
(provision) => `🔴 ${provision.name!.locales.en}`,
),
].join(", ");
notes += `\n`;
@@ -276,9 +276,11 @@ if (changedTanks.length > 0) {
if (addedEquipment.length + removedEquipment.length > 0) {
notes += `-Equipment: `;
notes += [
...addedEquipment.map((equipment) => `🟢 ${equipment.name.locales.en}`),
...addedEquipment.map(
(equipment) => `🟢 ${equipment.name!.locales.en}`,
),
...removedEquipment.map(
(equipment) => `🔴 ${equipment.name.locales.en}`
(equipment) => `🔴 ${equipment.name!.locales.en}`,
),
].join(", ");
notes += `\n`;
+3 -3
View File
@@ -10,7 +10,7 @@ const TS_PROTO_EXECUTABLE_LOCATIONS = [
];
const roots = [
// "../../packages/core/src/protos",
"../../packages/core/src/protos",
"../../packages/closed/protos",
];
@@ -31,8 +31,8 @@ for (const location of TS_PROTO_EXECUTABLE_LOCATIONS) {
if (!tsProtoExecutableLocation) {
throw new Error(
`Could not find ts-proto executable. Checked locations: ${TS_PROTO_EXECUTABLE_LOCATIONS.join(
", "
)}`
", ",
)}`,
);
}
+10 -5
View File
@@ -5,6 +5,7 @@ import {
Video,
youtubers,
} from "@blitzkit/core";
import locales from "@blitzkit/i18n/locales.json";
import { google } from "googleapis";
import { cloneDeep, uniqBy } from "lodash-es";
import { AssetUploader } from "./core/github/assetUploader";
@@ -42,9 +43,11 @@ for (const tank of tanksSanitized) {
}
try {
const q = `World of Tanks Blitz ${tank.name!.locales[locales.default]}`;
const results = await youtube.search.list({
part: ["snippet"],
q: `World of Tanks Blitz ${tank.name}`,
q,
});
if (!results.data.items || results.data.items.length === 0) continue;
@@ -54,9 +57,9 @@ for (const tank of tanksSanitized) {
(item) =>
item.snippet?.channelId &&
item.id?.videoId &&
youtubers.some(({ id }) => id === item.snippet?.channelId)
youtubers.some(({ id }) => id === item.snippet?.channelId),
),
(item) => item.snippet!.channelId
(item) => item.snippet!.channelId,
);
reviews.reviews[tank.id] = {
@@ -66,11 +69,13 @@ for (const tank of tanksSanitized) {
({
id: item.id!.videoId!,
author: item.snippet!.channelId!,
} satisfies Video)
}) satisfies Video,
),
};
console.log(`${++done} done; found ${items.length} for ${tank.name.locales.en}`);
console.log(
`${++done} done; found ${items.length} for ${tank.name!.locales.en}`,
);
await new Promise((resolve) => setTimeout(resolve, 1000 / 5));
} catch (error) {
@@ -1,12 +1,5 @@
import { ReloadIcon } from "@radix-ui/react-icons";
import {
Card,
Code,
Flex,
IconButton,
Text,
TextField,
} from "@radix-ui/themes";
import { Card, Flex, IconButton, Text, TextField } from "@radix-ui/themes";
import { Html } from "@react-three/drei";
import { useRef } from "react";
import { radToDeg } from "three/src/math/MathUtils.js";
@@ -14,6 +7,7 @@ import { resolveArmorIndex } from "../../../core/blitzkit/resolveArmorIndex";
import { App } from "../../../stores/app";
import { Duel } from "../../../stores/duel";
import { Tankopedia } from "../../../stores/tankopedia";
import { CopyableCode } from "../../CopyableCode";
import { layerTypeNames } from "./ShotDisplayCard";
import { ArmorType } from "./SpacedArmorScene";
@@ -60,7 +54,15 @@ export function ArmorPlateDisplay() {
{developerMode && (
<>
<Text mt="2" color="gray" size="2">
<b>DEV:</b> <Code>{highlightArmor.name}</Code>
<b>DEV:</b>{" "}
<CopyableCode
copy={highlightArmor.name}
variant="soft"
highContrast
color="gray"
>
{highlightArmor.name}
</CopyableCode>
</Text>
</>
)}
@@ -99,12 +101,12 @@ export function ArmorPlateDisplay() {
const track = tank.tracks[protagonist.track.id];
if (highlightArmor.name.startsWith("hull_")) {
tank.armor.thickness[index] = thickness;
tank.armor!.thickness[index] = thickness;
} else if (highlightArmor.name.startsWith("turret_")) {
turret.armor.thickness[index] = thickness;
turret.armor!.thickness[index] = thickness;
} else if (highlightArmor.name.startsWith("gun_")) {
if (highlightArmor.name.includes("_armor_")) {
gun.armor.thickness[index] = thickness;
gun.armor!.thickness[index] = thickness;
} else {
gun.thickness = thickness;
}
@@ -154,15 +156,15 @@ export function ArmorPlateDisplay() {
initialTank.tracks[protagonist.track.id];
if (highlightArmor.name.startsWith("hull_")) {
tank.armor.thickness[index] =
initialTank.armor.thickness[index];
tank.armor!.thickness[index] =
initialTank.armor!.thickness[index];
} else if (highlightArmor.name.startsWith("turret_")) {
turret.armor.thickness[index] =
initialTurret.armor.thickness[index];
turret.armor!.thickness[index] =
initialTurret.armor!.thickness[index];
} else if (highlightArmor.name.startsWith("gun_")) {
if (highlightArmor.name.includes("_armor_")) {
gun.armor.thickness[index] =
initialGun.armor.thickness[index];
gun.armor!.thickness[index] =
initialGun.armor!.thickness[index];
} else {
gun.thickness = initialGun.thickness;
}
@@ -24,11 +24,11 @@ export const PrimaryArmorScene = memo(() => {
const trackModelDefinition = tankModelDefinition.tracks[track.id];
const turretModelDefinition = tankModelDefinition.turrets[turret.id];
const gunModelDefinition = turretModelDefinition.guns[gun.id];
const hullOrigin = correctZYTuple(trackModelDefinition.origin);
const turretOrigin = correctZYTuple(tankModelDefinition.turret_origin);
const gunOrigin = correctZYTuple(turretModelDefinition.gun_origin);
const hullOrigin = correctZYTuple(trackModelDefinition.origin!);
const turretOrigin = correctZYTuple(tankModelDefinition.turret_origin!);
const gunOrigin = correctZYTuple(turretModelDefinition.gun_origin!);
const isDynamicArmorActive = Duel.use((state) =>
state.protagonist.consumables.includes(73)
state.protagonist.consumables.includes(73),
);
useTankTransform(track, turret, turretContainer, gunContainer);
@@ -41,8 +41,8 @@ export const PrimaryArmorScene = memo(() => {
const isVisible = isHull;
const armorId = nameToArmorId(node.name);
const { spaced, thickness } = resolveArmor(
tankModelDefinition.armor,
armorId
tankModelDefinition.armor!,
armorId,
);
if (
@@ -69,13 +69,13 @@ export const PrimaryArmorScene = memo(() => {
const isCurrentTurret = node.name.startsWith(
`turret_${turretModelDefinition.model_id
.toString()
.padStart(2, "0")}`
.padStart(2, "0")}`,
);
const isVisible = isCurrentTurret;
const armorId = nameToArmorId(node.name);
const { spaced, thickness } = resolveArmor(
turretModelDefinition.armor,
armorId
turretModelDefinition.armor!,
armorId,
);
if (
@@ -103,13 +103,13 @@ export const PrimaryArmorScene = memo(() => {
<group ref={gunContainer}>
{armorNodes.map((node) => {
const isCurrentGun = node.name.startsWith(
`gun_${gunModelDefinition.model_id.toString().padStart(2, "0")}`
`gun_${gunModelDefinition.model_id.toString().padStart(2, "0")}`,
);
const isVisible = isCurrentGun;
const armorId = nameToArmorId(node.name);
const { spaced, thickness } = resolveArmor(
gunModelDefinition.armor,
armorId
gunModelDefinition.armor!,
armorId,
);
if (
@@ -88,10 +88,10 @@ export function PrimaryArmorSceneComponent({
material.uniforms.caliber.value = shell.caliber;
material.uniforms.ricochet.value = degToRad(
isExplosive(shell.type) ? 90 : shell.ricochet!
isExplosive(shell.type) ? 90 : shell.ricochet!,
);
material.uniforms.normalization.value = degToRad(
shell.normalization ?? 0
shell.normalization ?? 0,
);
material.uniforms.isExplosive.value = isExplosive(shell.type);
material.uniforms.canSplash.value = canSplash(shell.type);
@@ -100,11 +100,11 @@ export function PrimaryArmorSceneComponent({
handleProtagonistEquipmentChange(
Duel.state.protagonist.equipmentMatrix,
true
true,
);
handleAntagonistEquipmentChange(
Duel.state.antagonist.equipmentMatrix,
true
true,
);
invalidate();
@@ -124,12 +124,12 @@ export function PrimaryArmorSceneComponent({
}
function handleProtagonistEquipmentChange(
equipment: EquipmentMatrix,
noInvalidate = false
noInvalidate = false,
) {
const hasEnhancedArmor = hasEquipment(
110,
Duel.state.protagonist.tank.equipment_preset,
equipment
equipment,
);
material.uniforms.thickness.value = hasEnhancedArmor
? thickness * 1.03
@@ -139,16 +139,16 @@ export function PrimaryArmorSceneComponent({
}
function handleAntagonistEquipmentChange(
equipment: EquipmentMatrix,
noInvalidate = false
noInvalidate = false,
) {
const tankopediaEphemeral = Tankopedia.state;
const shell =
tankopediaEphemeral.customShell ?? Duel.state.antagonist.shell;
const penetration = shell.penetration.near;
const penetration = shell.penetration!.near;
const hasCalibratedShells = hasEquipment(
103,
Duel.state.antagonist.tank.equipment_preset,
equipment
equipment,
);
material.uniforms.penetration.value =
@@ -165,7 +165,7 @@ export function PrimaryArmorSceneComponent({
handleShellChange();
handleGreenPenetrationChange(TankopediaPersistent.state.greenPenetration);
handleAdvancedHighlightingChange(
TankopediaPersistent.state.advancedHighlighting
TankopediaPersistent.state.advancedHighlighting,
);
handleOpaqueChange(TankopediaPersistent.state.opaque);
handleWireframeChange(TankopediaPersistent.state.wireframe);
@@ -179,20 +179,20 @@ export function PrimaryArmorSceneComponent({
Tankopedia.on((state) => state.customShell, handleShellChange),
TankopediaPersistent.on(
(state) => state.greenPenetration,
handleGreenPenetrationChange
handleGreenPenetrationChange,
),
TankopediaPersistent.on(
(state) => state.advancedHighlighting,
handleAdvancedHighlightingChange
handleAdvancedHighlightingChange,
),
TankopediaPersistent.on((state) => state.opaque, handleOpaqueChange),
Duel.on(
(state) => state.protagonist.equipmentMatrix,
(equipment) => handleProtagonistEquipmentChange(equipment)
(equipment) => handleProtagonistEquipmentChange(equipment),
),
Duel.on(
(state) => state.antagonist.equipmentMatrix,
(equipment) => handleAntagonistEquipmentChange(equipment)
(equipment) => handleAntagonistEquipmentChange(equipment),
),
() => transitionEvent.off(handleTransitionEvent),
];
@@ -204,7 +204,7 @@ export function PrimaryArmorSceneComponent({
useFrame(({ gl, camera }) => {
gl.getSize(material.uniforms.resolution.value).multiplyScalar(
gl.getPixelRatio()
gl.getPixelRatio(),
);
material.uniforms.spacedArmorBuffer.value = spacedArmorRenderTarget.texture;
material.uniforms.spacedArmorDepth.value =
@@ -37,15 +37,15 @@ export const SpacedArmorScene = memo<SpacedArmorSceneProps>(({ scene }) => {
const trackModelDefinition = tankModelDefinition.tracks[track.id];
const turretModelDefinition = tankModelDefinition.turrets[turret.id];
const gunModelDefinition = turretModelDefinition.guns[gun.id];
const hullOrigin = correctZYTuple(trackModelDefinition.origin);
const turretOrigin = correctZYTuple(tankModelDefinition.turret_origin);
const gunOrigin = correctZYTuple(turretModelDefinition.gun_origin);
const hullOrigin = correctZYTuple(trackModelDefinition.origin!);
const turretOrigin = correctZYTuple(tankModelDefinition.turret_origin!);
const gunOrigin = correctZYTuple(turretModelDefinition.gun_origin!);
const maskOrigin =
gunModelDefinition.mask === undefined
? undefined
: gunModelDefinition.mask + hullOrigin.y + turretOrigin.y + gunOrigin.y;
const isDynamicArmorActive = Duel.use((state) =>
state.protagonist.consumables.includes(73)
state.protagonist.consumables.includes(73),
);
useTankTransform(track, turret, turretContainer, gunContainer);
@@ -58,8 +58,8 @@ export const SpacedArmorScene = memo<SpacedArmorSceneProps>(({ scene }) => {
const isVisible = isHull;
const armorId = nameToArmorId(node.name);
const { spaced, thickness } = resolveArmor(
tankModelDefinition.armor,
armorId
tankModelDefinition.armor!,
armorId,
);
if (
@@ -104,13 +104,13 @@ export const SpacedArmorScene = memo<SpacedArmorSceneProps>(({ scene }) => {
<group ref={turretContainer}>
{armorNodes.map((node) => {
const isCurrentTurret = node.name.startsWith(
`turret_${turretModelDefinition.model_id.toString().padStart(2, "0")}`
`turret_${turretModelDefinition.model_id.toString().padStart(2, "0")}`,
);
const isVisible = isCurrentTurret;
const armorId = nameToArmorId(node.name);
const { spaced, thickness } = resolveArmor(
turretModelDefinition.armor,
armorId
turretModelDefinition.armor!,
armorId,
);
if (
@@ -139,13 +139,13 @@ export const SpacedArmorScene = memo<SpacedArmorSceneProps>(({ scene }) => {
<group ref={gunContainer}>
{armorNodes.map((node) => {
const isCurrentGun = node.name.startsWith(
`gun_${gunModelDefinition.model_id.toString().padStart(2, "0")}`
`gun_${gunModelDefinition.model_id.toString().padStart(2, "0")}`,
);
const isVisible = isCurrentGun;
const armorId = nameToArmorId(node.name);
const { spaced, thickness } = resolveArmor(
gunModelDefinition.armor,
armorId
gunModelDefinition.armor!,
armorId,
);
if (
@@ -50,13 +50,13 @@ export function SpacedArmorSubExternal({
const tankopediaEphemeral = Tankopedia.state;
const shell =
tankopediaEphemeral.customShell ?? Duel.state.antagonist.shell;
material.uniforms.penetration.value = shell.penetration.near;
material.uniforms.penetration.value = shell.penetration!.near;
}
function handleProtagonistEquipmentChange(equipment: EquipmentMatrix) {
const hasEnhancedArmor = hasEquipment(
110,
Duel.state.protagonist.tank.equipment_preset,
equipment
equipment,
);
material.uniforms.thickness.value = hasEnhancedArmor
? thickness * 1.03
@@ -66,11 +66,11 @@ export function SpacedArmorSubExternal({
const tankopediaEphemeral = Tankopedia.state;
const shell =
tankopediaEphemeral.customShell ?? Duel.state.antagonist.shell;
const penetration = shell.penetration.near;
const penetration = shell.penetration!.near;
const hasCalibratedShells = hasEquipment(
103,
Duel.state.antagonist.tank.equipment_preset,
equipment
equipment,
);
material.uniforms.penetration.value =
@@ -87,11 +87,11 @@ export function SpacedArmorSubExternal({
Tankopedia.on((state) => state.customShell, handleShellChange),
Duel.on(
(state) => state.protagonist.equipmentMatrix,
handleProtagonistEquipmentChange
handleProtagonistEquipmentChange,
),
Duel.on(
(state) => state.antagonist.equipmentMatrix,
handleAntagonistEquipmentChange
handleAntagonistEquipmentChange,
),
];
@@ -53,20 +53,20 @@ export function SpacedArmorSubSpaced({
const shell =
tankopediaEphemeral.customShell ?? Duel.state.antagonist.shell;
material.uniforms.penetration.value = shell.penetration.near;
material.uniforms.penetration.value = shell.penetration!.near;
material.uniforms.caliber.value = shell.caliber;
material.uniforms.ricochet.value = degToRad(
isExplosive(shell.type) ? 90 : shell.ricochet!
isExplosive(shell.type) ? 90 : shell.ricochet!,
);
material.uniforms.normalization.value = degToRad(
shell.normalization ?? 0
shell.normalization ?? 0,
);
}
function handleProtagonistEquipmentChange(equipment: EquipmentMatrix) {
const hasEnhancedArmor = hasEquipment(
110,
Duel.state.protagonist.tank.equipment_preset,
equipment
equipment,
);
material.uniforms.thickness.value = hasEnhancedArmor
? thickness * 1.03
@@ -76,11 +76,11 @@ export function SpacedArmorSubSpaced({
const tankopediaEphemeral = Tankopedia.state;
const shell =
tankopediaEphemeral.customShell ?? Duel.state.antagonist.shell;
const penetration = shell.penetration.near;
const penetration = shell.penetration!.near;
const hasCalibratedShells = hasEquipment(
103,
Duel.state.antagonist.tank.equipment_preset,
equipment
equipment,
);
material.uniforms.penetration.value =
@@ -97,11 +97,11 @@ export function SpacedArmorSubSpaced({
Tankopedia.on((state) => state.customShell, handleShellChange),
Duel.on(
(state) => state.protagonist.equipmentMatrix,
handleProtagonistEquipmentChange
handleProtagonistEquipmentChange,
),
Duel.on(
(state) => state.antagonist.equipmentMatrix,
handleAntagonistEquipmentChange
handleAntagonistEquipmentChange,
),
];
@@ -83,16 +83,18 @@ export function SpacedArmorSceneComponent({
point: Vector3,
intersections: Intersection[],
allowRicochet: boolean,
remainingPenetrationInput?: number
remainingPenetrationInput?: number,
) => {
const { customShell } = Tankopedia.state;
const shell = customShell ?? Duel.state.antagonist.shell;
const cameraNormal = camera.position.clone().sub(point).normalize();
const shot: Shot = {
splashRadius:
shell.type === ShellType.HE ? shell.explosion_radius : undefined,
shell.type === ShellType.SHELL_TYPE_HE
? shell.explosion_radius
: undefined,
damage: -1,
containsGaps: shell.type === ShellType.HEAT,
containsGaps: shell.type === ShellType.SHELL_TYPE_HEAT,
in: {
surfaceNormal: cameraNormal,
layers: [],
@@ -103,21 +105,21 @@ export function SpacedArmorSceneComponent({
const hasCalibratedShells = hasEquipment(
103,
Duel.state.antagonist.tank.equipment_preset,
Duel.state.antagonist.equipmentMatrix
Duel.state.antagonist.equipmentMatrix,
);
const hasEnhancedArmor = hasEquipment(
110,
Duel.state.protagonist.tank.equipment_preset,
Duel.state.protagonist.equipmentMatrix
Duel.state.protagonist.equipmentMatrix,
);
const penetration =
shell.penetration.near *
shell.penetration!.near *
resolvePenetrationCoefficient(hasCalibratedShells, shell.type);
const thicknessCoefficient = hasEnhancedArmor ? 1.03 : 1;
const filteredIntersections = intersections.filter(
(intersection) =>
"type" in intersection.object.userData &&
!discardClippingPlane(intersection.object, intersection.point)
!discardClippingPlane(intersection.object, intersection.point),
) as unknown as Intersection<Object3D & { userData: ArmorUserData }>[];
const encounteredExternalModuleVariants: ExternalModuleVariant[] = [];
const noDuplicateIntersections: typeof filteredIntersections = [];
@@ -126,12 +128,12 @@ export function SpacedArmorSceneComponent({
if (intersection.object.userData.type === ArmorType.External) {
if (
!encounteredExternalModuleVariants.includes(
intersection.object.userData.variant
intersection.object.userData.variant,
)
) {
noDuplicateIntersections.push(intersection);
encounteredExternalModuleVariants.push(
intersection.object.userData.variant
intersection.object.userData.variant,
);
}
} else {
@@ -159,10 +161,10 @@ export function SpacedArmorSceneComponent({
const surfaceNormal = intersection
.normal!.clone()
.applyQuaternion(
intersection.object.getWorldQuaternion(new Quaternion())
intersection.object.getWorldQuaternion(new Quaternion()),
);
if (shell.type === ShellType.HEAT && index > 0) {
if (shell.type === ShellType.SHELL_TYPE_HEAT && index > 0) {
const lastLayer = shot.in.layers.at(-1) as ShotLayerBase;
const distance = lastLayer.point.distanceTo(intersection.point);
remainingPenetration -= 0.5 * remainingPenetration * distance;
@@ -181,7 +183,7 @@ export function SpacedArmorSceneComponent({
const thickness = layer.thickness * thicknessCoefficient;
remainingPenetration -= thickness;
const blocked =
remainingPenetration <= 0 || shell.type === ShellType.HE;
remainingPenetration <= 0 || shell.type === ShellType.SHELL_TYPE_HE;
shot.in.layers.push({
type: ArmorType.External,
@@ -190,7 +192,7 @@ export function SpacedArmorSceneComponent({
point: intersection.point,
surfaceNormal,
status:
shell.type === ShellType.HE
shell.type === ShellType.SHELL_TYPE_HE
? "blocked"
: blocked
? "blocked"
@@ -200,7 +202,7 @@ export function SpacedArmorSceneComponent({
} else {
const thickness = layer.thickness * thicknessCoefficient;
const ricochet = degToRad(
isExplosive(shell.type) ? 90 : shell.ricochet!
isExplosive(shell.type) ? 90 : shell.ricochet!,
);
const angle = surfaceNormal.angleTo(cameraNormal);
@@ -241,7 +243,8 @@ export function SpacedArmorSceneComponent({
point: intersection.point,
surfaceNormal: intersection.face!.normal,
status:
shell.type === ShellType.HE && layer.type !== ArmorType.Primary
shell.type === ShellType.SHELL_TYPE_HE &&
layer.type !== ArmorType.Primary
? "blocked"
: blocked
? "blocked"
@@ -251,7 +254,10 @@ export function SpacedArmorSceneComponent({
}
}
if (shell.type !== ShellType.HE && remainingPenetration <= 0) {
if (
shell.type !== ShellType.SHELL_TYPE_HE &&
remainingPenetration <= 0
) {
break;
}
@@ -266,7 +272,7 @@ export function SpacedArmorSceneComponent({
if (!lastLayer || !firstLayer) {
return null;
} else {
if (shell.type === ShellType.HE) {
if (shell.type === ShellType.SHELL_TYPE_HE) {
const totalSpacedArmorThickness = shot.in.layers.reduce(
(acc, layer) => {
if (layer.type === null || layer.type === ArmorType.Primary) {
@@ -279,10 +285,10 @@ export function SpacedArmorSceneComponent({
return acc + layer.thicknessAngled;
},
0
0,
);
const distanceFromSpacedArmor = firstLayer.point.distanceTo(
lastLayer.point
lastLayer.point,
);
const finalDamage = Math.max(
0,
@@ -291,7 +297,7 @@ export function SpacedArmorSceneComponent({
(1 - distanceFromSpacedArmor / shell.explosion_radius!) -
1.1 *
(lastLayer.thicknessAngled +
Math.min(penetration, totalSpacedArmorThickness))
Math.min(penetration, totalSpacedArmorThickness)),
);
/**
@@ -328,20 +334,20 @@ export function SpacedArmorSceneComponent({
.sub(
lastLayer.surfaceNormal
.clone()
.multiplyScalar(2 * shellNormal.dot(lastLayer.surfaceNormal))
.multiplyScalar(2 * shellNormal.dot(lastLayer.surfaceNormal)),
);
caster.set(lastLayer.point, ricochetNormal);
const ricochetIntersections = caster.intersectObjects(
props.scene.children,
true
true,
);
const outShot = shoot(
lastLayer.point,
ricochetIntersections,
false,
remainingPenetration
remainingPenetration,
);
shot.in.status = "ricochet";
@@ -363,7 +369,7 @@ export function SpacedArmorSceneComponent({
return shot;
},
[camera]
[camera],
);
return (
@@ -43,9 +43,9 @@ export const StaticArmor = memo<ArmorSceneProps>(({ thicknessRange }) => {
const trackModelDefinition = tankModelDefinition.tracks[track.id];
const turretModelDefinition = tankModelDefinition.turrets[turret.id];
const gunModelDefinition = turretModelDefinition.guns[gun.id];
const hullOrigin = correctZYTuple(trackModelDefinition.origin);
const turretOrigin = correctZYTuple(tankModelDefinition.turret_origin);
const gunOrigin = correctZYTuple(turretModelDefinition.gun_origin);
const hullOrigin = correctZYTuple(trackModelDefinition.origin!);
const turretOrigin = correctZYTuple(tankModelDefinition.turret_origin!);
const gunOrigin = correctZYTuple(turretModelDefinition.gun_origin!);
const canvas = useThree((state) => state.gl.domElement);
const maskOrigin =
@@ -53,16 +53,16 @@ export const StaticArmor = memo<ArmorSceneProps>(({ thicknessRange }) => {
? undefined
: gunModelDefinition.mask + hullOrigin.y + turretOrigin.y + gunOrigin.y;
const showPrimaryArmor = TankopediaPersistent.use(
(state) => state.showPrimaryArmor
(state) => state.showPrimaryArmor,
);
const showSpacedArmor = TankopediaPersistent.use(
(state) => state.showSpacedArmor
(state) => state.showSpacedArmor,
);
const showExternalModules = TankopediaPersistent.use(
(state) => state.showExternalModules
(state) => state.showExternalModules,
);
const isDynamicArmorActive = Duel.use((state) =>
state.protagonist.consumables.includes(73)
state.protagonist.consumables.includes(73),
);
useTankTransform(track, turret, turretContainer, gunContainer);
@@ -75,8 +75,8 @@ export const StaticArmor = memo<ArmorSceneProps>(({ thicknessRange }) => {
const isVisible = isHull;
const armorId = nameToArmorId(node.name);
const { spaced, thickness } = resolveArmor(
tankModelDefinition.armor,
armorId
tankModelDefinition.armor!,
armorId,
);
if (
@@ -127,13 +127,13 @@ export const StaticArmor = memo<ArmorSceneProps>(({ thicknessRange }) => {
<group ref={turretContainer}>
{armorNodes.map((node) => {
const isCurrentTurret = node.name.startsWith(
`turret_${turretModelDefinition.model_id.toString().padStart(2, "0")}`
`turret_${turretModelDefinition.model_id.toString().padStart(2, "0")}`,
);
const isVisible = isCurrentTurret;
const armorId = nameToArmorId(node.name);
const { spaced, thickness } = resolveArmor(
turretModelDefinition.armor,
armorId
turretModelDefinition.armor!,
armorId,
);
if (
@@ -168,12 +168,12 @@ export const StaticArmor = memo<ArmorSceneProps>(({ thicknessRange }) => {
const hasImprovedVerticalStabilizer = hasEquipment(
122,
Duel.state.protagonist.tank.equipment_preset,
Duel.state.protagonist.equipmentMatrix
Duel.state.protagonist.equipmentMatrix,
);
const hasDownImprovedVerticalStabilizer = hasEquipment(
124,
Duel.state.protagonist.tank.equipment_preset,
Duel.state.protagonist.equipmentMatrix
Duel.state.protagonist.equipmentMatrix,
);
const boundingRect = canvas.getBoundingClientRect();
@@ -184,10 +184,10 @@ export const StaticArmor = memo<ArmorSceneProps>(({ thicknessRange }) => {
modelTransformEvent.last!.pitch,
modelTransformEvent.last!.yaw +
delta.x * (Math.PI / boundingRect.width),
gunModelDefinition.pitch,
gunModelDefinition.pitch!,
turretModelDefinition.yaw,
hasImprovedVerticalStabilizer,
hasDownImprovedVerticalStabilizer
hasDownImprovedVerticalStabilizer,
);
modelTransformEvent.dispatch({ pitch, yaw });
}
@@ -216,13 +216,13 @@ export const StaticArmor = memo<ArmorSceneProps>(({ thicknessRange }) => {
<group ref={gunContainer}>
{armorNodes.map((node) => {
const isCurrentGun = node.name.startsWith(
`gun_${gunModelDefinition.model_id.toString().padStart(2, "0")}`
`gun_${gunModelDefinition.model_id.toString().padStart(2, "0")}`,
);
const isVisible = isCurrentGun;
const armorId = nameToArmorId(node.name);
const { spaced, thickness } = resolveArmor(
gunModelDefinition.armor,
armorId
gunModelDefinition.armor!,
armorId,
);
if (
@@ -256,12 +256,12 @@ export const StaticArmor = memo<ArmorSceneProps>(({ thicknessRange }) => {
const hasImprovedVerticalStabilizer = hasEquipment(
122,
Duel.state.protagonist.tank.equipment_preset,
Duel.state.protagonist.equipmentMatrix
Duel.state.protagonist.equipmentMatrix,
);
const hasDownImprovedVerticalStabilizer = hasEquipment(
124,
Duel.state.protagonist.tank.equipment_preset,
Duel.state.protagonist.equipmentMatrix
Duel.state.protagonist.equipmentMatrix,
);
const boundingRect = canvas.getBoundingClientRect();
delta.set(event.clientX, event.clientY).sub(position);
@@ -272,10 +272,10 @@ export const StaticArmor = memo<ArmorSceneProps>(({ thicknessRange }) => {
delta.y * (Math.PI / boundingRect.height),
modelTransformEvent.last!.yaw +
delta.x * (Math.PI / boundingRect.width),
gunModelDefinition.pitch,
gunModelDefinition.pitch!,
turretModelDefinition.yaw,
hasImprovedVerticalStabilizer,
hasDownImprovedVerticalStabilizer
hasDownImprovedVerticalStabilizer,
);
modelTransformEvent.dispatch({ pitch, yaw });
}
@@ -332,12 +332,12 @@ export const StaticArmor = memo<ArmorSceneProps>(({ thicknessRange }) => {
const hasImprovedVerticalStabilizer = hasEquipment(
122,
Duel.state.protagonist.tank.equipment_preset,
Duel.state.protagonist.equipmentMatrix
Duel.state.protagonist.equipmentMatrix,
);
const hasDownImprovedVerticalStabilizer = hasEquipment(
124,
Duel.state.protagonist.tank.equipment_preset,
Duel.state.protagonist.equipmentMatrix
Duel.state.protagonist.equipmentMatrix,
);
const boundingRect = canvas.getBoundingClientRect();
delta.set(event.clientX, event.clientY).sub(position);
@@ -348,10 +348,10 @@ export const StaticArmor = memo<ArmorSceneProps>(({ thicknessRange }) => {
delta.y * (Math.PI / boundingRect.height),
modelTransformEvent.last!.yaw +
delta.x * (Math.PI / boundingRect.width),
gunModelDefinition.pitch,
gunModelDefinition.pitch!,
turretModelDefinition.yaw,
hasImprovedVerticalStabilizer,
hasDownImprovedVerticalStabilizer
hasDownImprovedVerticalStabilizer,
);
modelTransformEvent.dispatch({ pitch, yaw });
}
@@ -1,16 +1,16 @@
import { TankClass } from '@blitzkit/core';
import type { ComponentProps, ReactNode } from 'react';
import { ClassHeavy } from './components/ClassHeavy';
import { ClassLight } from './components/ClassLight';
import { ClassMedium } from './components/ClassMedium';
import { ClassTankDestroyer } from './components/ClassTankDestroyer';
import { TankClass } from "@blitzkit/core";
import type { ComponentProps, ReactNode } from "react";
import { ClassHeavy } from "./components/ClassHeavy";
import { ClassLight } from "./components/ClassLight";
import { ClassMedium } from "./components/ClassMedium";
import { ClassTankDestroyer } from "./components/ClassTankDestroyer";
export const classIcons: Record<
TankClass,
(props: ComponentProps<'svg'>) => ReactNode
(props: ComponentProps<"svg">) => ReactNode
> = {
[TankClass.TANK_DESTROYER]: ClassTankDestroyer,
[TankClass.HEAVY]: ClassHeavy,
[TankClass.LIGHT]: ClassLight,
[TankClass.MEDIUM]: ClassMedium,
[TankClass.TANK_CLASS_TANK_DESTROYER]: ClassTankDestroyer,
[TankClass.TANK_CLASS_HEAVY]: ClassHeavy,
[TankClass.TANK_CLASS_LIGHT]: ClassLight,
[TankClass.TANK_CLASS_MEDIUM]: ClassMedium,
};
@@ -15,7 +15,7 @@ interface BodyProps {
export function Body({ stats }: BodyProps) {
const members = CompareEphemeral.use((state) => state.members);
const hasNonRegularGun = members.some(
({ gun }) => gun.gun_type!.$case !== "regular"
({ gun }) => gun.gun_type!.$case !== "regular",
);
const { unwrap, strings } = useLocale();
@@ -55,7 +55,7 @@ export function Body({ stats }: BodyProps) {
}}
>
<img
alt={unwrap(thisShell.name)}
alt={unwrap(thisShell.name!)}
width={16}
height={16}
src={asset(`icons/shells/${thisShell.icon}.webp`)}
@@ -14,7 +14,7 @@ import { StickyRowHeaderCell } from "../StickyRowHeaderCell";
type CompareRowProps = {
display?: (
member: Awaited<TankCharacteristics>
member: Awaited<TankCharacteristics>,
) => number | string | undefined;
deltaType?: CompareCellDirection;
decimals?: number;
@@ -46,7 +46,7 @@ export function CompareRow({
const values = stats.map((stat) =>
typeof props.value === "function"
? props.value(stat)!
: (stat[props.value] as number)
: (stat[props.value] as number),
);
const id = useRef(Math.random());
const name =
@@ -56,10 +56,10 @@ export function CompareRow({
return (
<Table.Row>
<StickyRowHeaderCell>
<StickyRowHeaderCell left="-1.25rem">
<Flex
align="center"
style={{ whiteSpace: "nowrap" }}
maxWidth={{ initial: "6rem", sm: "unset" }}
gap={indent ? { initial: "4", sm: "6" } : { initial: "1", sm: "2" }}
>
<IconButton
@@ -111,8 +111,8 @@ export function CompareRow({
const resolvedDisplayValue = display
? display(stats[index])
: decimals === undefined
? value
: value?.toFixed(decimals);
? value
: value?.toFixed(decimals);
return (
<CompareCell
@@ -145,8 +145,8 @@ export function CompareRow({
deltaNominalDisplay
? deltaNominalDisplay(delta)
: decimals === undefined
? delta
: delta.toFixed(decimals)
? delta
: delta.toFixed(decimals)
}`}
)
</Text>
@@ -156,7 +156,7 @@ export function CompareRow({
<Text color="gray">
(
{`${deltaPercentage > 0 ? "+" : ""}${Math.round(
deltaPercentage * 100
deltaPercentage * 100,
)}%`}
)
</Text>
@@ -1,7 +1,7 @@
import { Heading, Table } from '@radix-ui/themes';
import { times } from 'lodash-es';
import { CompareEphemeral } from '../../stores/compareEphemeral';
import { StickyColumnHeaderCell } from '../StickyColumnHeaderCell';
import { Heading, Table } from "@radix-ui/themes";
import { times } from "lodash-es";
import { CompareEphemeral } from "../../stores/compareEphemeral";
import { StickyColumnHeaderCell } from "../StickyColumnHeaderCell";
export function CompareSectionTitle({ children }: { children: string }) {
const memberCount = CompareEphemeral.use((state) => state.members.length);
@@ -105,13 +105,13 @@ export function CompareTable({ stats }: CompareTableProps) {
crewSkills[skill] === 0
? Var("gray-11")
: permanentSkills.includes(skill)
? Var("crimson-11")
: Var("amber-11"),
? Var("crimson-11")
: Var("amber-11"),
}}
/>
))}
</Flex>
)
),
)}
</Flex>
</Button>
@@ -173,19 +173,19 @@ export function CompareTable({ stats }: CompareTableProps) {
consumables,
camouflage,
},
index
index,
) => {
const equipmentPreset =
equipmentDefinitions.presets[tank.equipment_preset];
const provisionsList = availableProvisions(
tank,
gun,
provisionDefinitions
provisionDefinitions,
);
const consumablesList = Object.values(
consumableDefinitions.consumables
consumableDefinitions.consumables,
).filter((consumable) =>
checkConsumableProvisionInclusivity(consumable, tank, gun)
checkConsumableProvisionInclusivity(consumable, tank, gun),
);
return (
@@ -294,11 +294,11 @@ export function CompareTable({ stats }: CompareTableProps) {
<img
alt={unwrap(
provisionDefinitions.provisions[provision]
.name
.name!,
)}
key={provision}
src={asset(
`/icons/provisions/${provision}.webp`
`/icons/provisions/${provision}.webp`,
)}
style={{
left: "50%",
@@ -335,7 +335,7 @@ export function CompareTable({ stats }: CompareTableProps) {
<Popover.Content>
<ProvisionsManager
provisions={provisionsList.map(
(provision) => provision.id
(provision) => provision.id,
)}
selected={provisions}
disabled={tank.max_provisions === provisions.length}
@@ -452,7 +452,7 @@ export function CompareTable({ stats }: CompareTableProps) {
CompareEphemeral.mutate((draft) => {
draft.members[index].equipmentMatrix = times(
3,
() => times(3, () => 0)
() => times(3, () => 0),
) as EquipmentMatrix;
draft.sorting = undefined;
});
@@ -501,11 +501,11 @@ export function CompareTable({ stats }: CompareTableProps) {
alt={unwrap(
consumableDefinitions.consumables[
consumable
].name
].name!,
)}
key={consumable}
src={asset(
`/icons/consumables/${consumable}.webp`
`/icons/consumables/${consumable}.webp`,
)}
style={{
left: "50%",
@@ -610,7 +610,7 @@ export function CompareTable({ stats }: CompareTableProps) {
</Flex>
</Table.Cell>
);
}
},
)}
</Table.Row>
</Table.Body>
@@ -55,7 +55,7 @@ export function TankCard({ index, tank }: TankCardProps) {
};
});
const closest = distances.reduce((a, b) =>
a.distance < b.distance ? a : b
a.distance < b.distance ? a : b,
);
dropIndex = closest.index;
@@ -85,8 +85,8 @@ export function TankCard({ index, tank }: TankCardProps) {
CompareEphemeral.mutate((draft) => {
const fromIndex = index;
const toIndex = dropIndex > index ? dropIndex - 1 : dropIndex;
const member = draft.members[fromIndex];
draft.members.splice(fromIndex, 1);
draft.members.splice(toIndex, 0, member);
});
@@ -99,7 +99,7 @@ export function TankCard({ index, tank }: TankCardProps) {
return () => {
draggable.current?.removeEventListener("pointerdown", handlePointerDown);
};
}, []);
}, [index]);
return (
<StickyColumnHeaderCell width="0">
@@ -119,7 +119,7 @@ export function TankCard({ index, tank }: TankCardProps) {
}}
>
<img
alt={unwrap(tank.name)}
alt={unwrap(tank.name!)}
src={tankIcon(tank.id)}
width={64}
height={64}
@@ -137,11 +137,10 @@ export function TankCard({ index, tank }: TankCardProps) {
textOverflow: "ellipsis",
}}
>
{unwrap(tank.name)}
{unwrap(tank.name!)}
</Text>
</Flex>
</Flex>
<InsertionMarker index={index + 1} />
</StickyColumnHeaderCell>
);
@@ -36,9 +36,8 @@ export function ConsumablesManager({
special={consumable.duration === undefined}
duration={
timers
? consumable.duration === undefined
? undefined
: consumable.duration * (hasHighEndConsumables ? 1.33 : 1)
? (consumable.duration ?? 0) *
(hasHighEndConsumables ? 1.33 : 1) || undefined
: undefined
}
cooldown={
@@ -0,0 +1,40 @@
import { Code, Tooltip, type CodeProps } from "@radix-ui/themes";
import { useState } from "react";
import { useLocale } from "../hooks/useLocale";
export interface CopyableCodeProps extends CodeProps {
copy?: string;
}
export function CopyableCode({
copy,
onClick,
onPointerLeave,
style,
children,
...props
}: CopyableCodeProps) {
const [copied, setCopied] = useState(false);
const { strings } = useLocale();
return (
<Tooltip open={copied} content={strings.website.common.copy_button.copied}>
<Code
{...props}
style={{ ...style, cursor: "pointer" }}
onClick={(event) => {
onClick?.(event);
if (!copy) return;
navigator.clipboard.writeText(copy);
setCopied(true);
}}
onPointerLeave={(event) => {
onPointerLeave?.(event);
setCopied(false);
}}
>
{children}
</Code>
</Tooltip>
);
}
@@ -55,7 +55,7 @@ export const fakeCompositeStats = compositeStats(
wins: 30,
xp: 1230 * 50,
},
averageDefinitions.averages[7297].mu
averageDefinitions.averages[7297].mu!,
);
export function BreakdownPreview() {
@@ -88,9 +88,9 @@ export function BreakdownRenderer() {
const diff = useMemo(
() =>
deltaTankStats(tankStatsA, tankStatsB).sort(
(a, b) => b.last_battle_time - a.last_battle_time
(a, b) => b.last_battle_time - a.last_battle_time,
),
[tankStatsB]
[tankStatsB],
);
const compositeStats = diff
.map((diff) => {
@@ -100,14 +100,14 @@ export function BreakdownRenderer() {
const compositeStats = calculateCompositeStats(
{ battle_life_time: diff.battle_life_time, ...diff.all },
average.mu
average.mu!,
);
return { id: diff.tank_id, compositeStats };
})
.filter((stats) => stats !== null);
const sum = sumCompositeStats(
compositeStats.map(({ compositeStats }) => compositeStats)
compositeStats.map(({ compositeStats }) => compositeStats),
);
useEffect(() => {
@@ -19,7 +19,7 @@ type GalleryCardProps = MaybeSkeletonComponentProps<{
export function GalleryCard(props: GalleryCardProps) {
const src = asset(
`gallery/avatars/${!props.skeleton && `${props.avatar.id}${props.avatar.extension}`}`
`gallery/avatars/${!props.skeleton && `${props.avatar.id}${props.avatar.extension}`}`,
);
const card = useRef<HTMLDivElement>(null!);
const { unwrap } = useLocale();
@@ -54,11 +54,11 @@ export function GalleryCard(props: GalleryCardProps) {
objectFit: "cover",
}}
src={src}
alt={unwrap(props.avatar.name)}
alt={unwrap(props.avatar.name!)}
/>
<Text size="1" align="center" style={{ maxWidth: "100%" }}>
{unwrap(props.avatar.name)}
{unwrap(props.avatar.name!)}
</Text>
</>
)}
@@ -90,12 +90,12 @@ export function GalleryCard(props: GalleryCardProps) {
</Flex>
<Flex px="4" justify="center" mt="3">
<img src={src} alt={unwrap(props.avatar.name)} />
<img src={src} alt={unwrap(props.avatar.name!)} />
</Flex>
<Flex justify="center" mt="4">
<Dialog.Title align="center" style={{ maxWidth: "10rem" }}>
{unwrap(props.avatar.name)}
{unwrap(props.avatar.name!)}
</Dialog.Title>
</Flex>
</Dialog.Content>
+5 -5
View File
@@ -82,10 +82,10 @@ export function Guesser() {
});
setResults(
searchResults.map((result) => tankDefinitions.tanks[result.obj.id])
searchResults.map((result) => tankDefinitions.tanks[result.obj.id]),
);
}, 500),
[]
[],
);
useEffect(() => {
@@ -126,11 +126,11 @@ export function Guesser() {
onClick={() => {
if (!input.current) return;
input.current.value = unwrap(result.name);
input.current.value = unwrap(result.name!);
setSelected(result);
setResults(null);
}}
text={unwrap(result.name)}
text={unwrap(result.name!)}
prefix={
<img
style={{ width: "1em", height: "1em" }}
@@ -321,7 +321,7 @@ export function Guesser() {
return tiers.includes(tank.tier);
});
const id = Number(
filteredIds[Math.floor(Math.random() * filteredIds.length)]
filteredIds[Math.floor(Math.random() * filteredIds.length)],
);
const tank = tankDefinitions.tanks[id];
@@ -84,7 +84,7 @@ export function Model() {
useEffect(() => {
function handleModelTransform(
event: QuicklimeEvent<ModelTransformEventData>
event: QuicklimeEvent<ModelTransformEventData>,
) {
turretGroup.current.rotation.z = event.data.yaw;
gunGroup.current.rotation.x = event.data.pitch;
@@ -118,16 +118,16 @@ export function Model() {
ref={turretGroup}
rotation={[0, 0, modelTransformEvent.last!.yaw]}
position={[
tankModel.turret_origin.x + trackModel.origin.x,
tankModel.turret_origin.z + trackModel.origin.z,
tankModel.turret_origin.y + trackModel.origin.y,
tankModel.turret_origin!.x + trackModel.origin!.x,
tankModel.turret_origin!.z + trackModel.origin!.z,
tankModel.turret_origin!.y + trackModel.origin!.y,
]}
>
<group
position={[
-turretTankModel.turret_origin.x - turretTrackModel.origin.x,
-turretTankModel.turret_origin.z - turretTrackModel.origin.z,
-turretTankModel.turret_origin.y - turretTrackModel.origin.y,
-turretTankModel.turret_origin!.x - turretTrackModel.origin!.x,
-turretTankModel.turret_origin!.z - turretTrackModel.origin!.z,
-turretTankModel.turret_origin!.y - turretTrackModel.origin!.y,
]}
>
{turretNodes.map((node) => {
@@ -160,38 +160,81 @@ export function Model() {
ref={gunGroup}
rotation={[modelTransformEvent.last!.pitch, 0, 0]}
position={[
turretTankModel.turret_origin.x +
turretTrackModel.origin.x +
turretModel.gun_origin.x,
turretTankModel.turret_origin.z +
turretTrackModel.origin.z +
turretModel.gun_origin.z,
turretTankModel.turret_origin.y +
turretTrackModel.origin.y +
turretModel.gun_origin.y,
turretTankModel.turret_origin!.x +
turretTrackModel.origin!.x +
turretModel.gun_origin!.x,
turretTankModel.turret_origin!.z +
turretTrackModel.origin!.z +
turretModel.gun_origin!.z,
turretTankModel.turret_origin!.y +
turretTrackModel.origin!.y +
turretModel.gun_origin!.y,
]}
>
<group
position={[
-gunTankModel.turret_origin.x -
gunTrackModel.origin.x -
gunTurretModel.gun_origin.x,
-gunTankModel.turret_origin.z -
gunTrackModel.origin.z -
gunTurretModel.gun_origin.z,
-gunTankModel.turret_origin.y -
gunTrackModel.origin.y -
gunTurretModel.gun_origin.y,
-turretTankModel.turret_origin!.x -
turretTrackModel.origin!.x -
turretModel.gun_origin!.x,
-turretTankModel.turret_origin!.z -
turretTrackModel.origin!.z -
turretModel.gun_origin!.z,
-turretTankModel.turret_origin!.y -
turretTrackModel.origin!.y -
turretModel.gun_origin!.y,
]}
>
{turretNodes.map((node) => {
const isCurrentMantlet =
node.name ===
`gun_${turretModel.guns[turret.turret.guns.at(-1)!.id].model_id.toString().padStart(2, "0")}_mask`;
// const isCurrentGun =
// node.name ===
// `gun_${gunModel.model_id.toString().padStart(2, "0")}`;
const isVisible = isCurrentMantlet;
if (!isVisible) return null;
return jsxTree(node, {
mesh(_, props, key) {
return (
<mesh
{...props}
key={key}
castShadow
receiveShadow
onPointerDown={(event) => {
enablePitchRotation.current = true;
handlePointerDown(event);
}}
/>
);
},
});
})}
</group>
<group
position={[
-gunTankModel.turret_origin!.x -
gunTrackModel.origin!.x -
gunTurretModel.gun_origin!.x,
-gunTankModel.turret_origin!.z -
gunTrackModel.origin!.z -
gunTurretModel.gun_origin!.z,
-gunTankModel.turret_origin!.y -
gunTrackModel.origin!.y -
gunTurretModel.gun_origin!.y,
]}
>
{gunNodes.map((node) => {
const isCurrentMantlet =
node.name ===
`gun_${gunModel.model_id.toString().padStart(2, "0")}_mask`;
// const isCurrentMantlet =
// node.name ===
// `gun_${gunModel.model_id.toString().padStart(2, "0")}_mask`;
const isCurrentGun =
node.name ===
`gun_${gunModel.model_id.toString().padStart(2, "0")}`;
const isVisible = isCurrentGun || isCurrentMantlet;
const isVisible = isCurrentGun;
if (!isVisible) return null;
@@ -1,11 +1,11 @@
import { asset } from '@blitzkit/core';
import { ClockIcon, ReloadIcon } from '@radix-ui/react-icons';
import { Flex, Text } from '@radix-ui/themes';
import { awaitableConsumableDefinitions } from '../../core/awaitables/consumableDefinitions';
import { useDelta } from '../../hooks/useDelta';
import { useLocale } from '../../hooks/useLocale';
import { GenericTankComponentButton } from './GenericTankComponentButton';
import type { TankComponentButtonProps } from './TankComponentButton';
import { asset } from "@blitzkit/core";
import { ClockIcon, ReloadIcon } from "@radix-ui/react-icons";
import { Flex, Text } from "@radix-ui/themes";
import { awaitableConsumableDefinitions } from "../../core/awaitables/consumableDefinitions";
import { useDelta } from "../../hooks/useDelta";
import { useLocale } from "../../hooks/useLocale";
import { GenericTankComponentButton } from "./GenericTankComponentButton";
import type { TankComponentButtonProps } from "./TankComponentButton";
interface ConsumableButtonProps extends TankComponentButtonProps {
consumable: number;
@@ -27,8 +27,8 @@ export function ConsumableButton({
return (
<GenericTankComponentButton
style={{ width: '6rem' }}
tooltip={unwrap(consumableDefinitions.consumables[consumable].name)}
style={{ width: "6rem" }}
tooltip={unwrap(consumableDefinitions.consumables[consumable].name!)}
icon={asset(`icons/consumables/${consumable}.webp`)}
{...props}
>
@@ -39,9 +39,9 @@ export function ConsumableButton({
size="1"
color={
durationDelta > 0
? 'green'
? "green"
: durationDelta < 0
? 'tomato'
? "tomato"
: undefined
}
>
@@ -56,9 +56,9 @@ export function ConsumableButton({
size="1"
color={
cooldownDelta < 0
? 'green'
? "green"
: cooldownDelta > 0
? 'tomato'
? "tomato"
: undefined
}
>
@@ -1,8 +1,8 @@
import { asset } from '@blitzkit/core';
import { awaitableEquipmentDefinitions } from '../../core/awaitables/equipmentDefinitions';
import { useLocale } from '../../hooks/useLocale';
import { GenericTankComponentButton } from './GenericTankComponentButton';
import type { TankComponentButtonProps } from './TankComponentButton';
import { asset } from "@blitzkit/core";
import { awaitableEquipmentDefinitions } from "../../core/awaitables/equipmentDefinitions";
import { useLocale } from "../../hooks/useLocale";
import { GenericTankComponentButton } from "./GenericTankComponentButton";
import type { TankComponentButtonProps } from "./TankComponentButton";
interface EquipmentButtonProps extends TankComponentButtonProps {
equipment: number;
@@ -15,7 +15,7 @@ export function EquipmentButton({ equipment, ...props }: EquipmentButtonProps) {
return (
<GenericTankComponentButton
tooltip={unwrap(equipmentDefinitions.equipments[equipment].name)}
tooltip={unwrap(equipmentDefinitions.equipments[equipment].name!)}
icon={asset(`icons/equipment/${equipment}.webp`)}
{...props}
/>
@@ -1,8 +1,8 @@
import { asset } from '@blitzkit/core';
import { awaitableProvisionDefinitions } from '../../core/awaitables/provisionDefinitions';
import { useLocale } from '../../hooks/useLocale';
import { GenericTankComponentButton } from './GenericTankComponentButton';
import type { TankComponentButtonProps } from './TankComponentButton';
import { asset } from "@blitzkit/core";
import { awaitableProvisionDefinitions } from "../../core/awaitables/provisionDefinitions";
import { useLocale } from "../../hooks/useLocale";
import { GenericTankComponentButton } from "./GenericTankComponentButton";
import type { TankComponentButtonProps } from "./TankComponentButton";
interface ProvisionButtonProps extends TankComponentButtonProps {
provision: number;
@@ -15,7 +15,7 @@ export function ProvisionButton({ provision, ...props }: ProvisionButtonProps) {
return (
<GenericTankComponentButton
tooltip={unwrap(provisionDefinitions.provisions[provision].name)}
tooltip={unwrap(provisionDefinitions.provisions[provision].name!)}
icon={asset(`icons/provisions/${provision}.webp`)}
{...props}
/>
@@ -6,11 +6,11 @@ import {
type TankDefinition,
type TrackDefinition,
type TurretDefinition,
} from '@blitzkit/core';
import { DropdownMenu, Flex } from '@radix-ui/themes';
import { useState } from 'react';
import { useLocale } from '../hooks/useLocale';
import { ModuleButton } from './ModuleButtons/ModuleButton';
} from "@blitzkit/core";
import { DropdownMenu, Flex } from "@radix-ui/themes";
import { useState } from "react";
import { useLocale } from "../hooks/useLocale";
import { ModuleButton } from "./ModuleButtons/ModuleButton";
interface ModuleManagerProps {
tank: TankDefinition;
@@ -72,8 +72,8 @@ export function ModuleManager({
variant="ghost"
module="turret"
discriminator={TIER_ROMAN_NUMERALS[turret.tier]}
/>{' '}
{unwrap(turret.name)}
/>{" "}
{unwrap(turret.name!)}
</DropdownMenu.RadioItem>
);
})}
@@ -112,8 +112,8 @@ export function ModuleManager({
variant="ghost"
module="gun"
discriminator={TIER_ROMAN_NUMERALS[gun.tier]}
/>{' '}
{unwrap(gun.name)}
/>{" "}
{unwrap(gun.name!)}
</DropdownMenu.RadioItem>
);
})}
@@ -151,8 +151,8 @@ export function ModuleManager({
variant="ghost"
module="engine"
discriminator={TIER_ROMAN_NUMERALS[engine.tier]}
/>{' '}
{unwrap(engine.name)}
/>{" "}
{unwrap(engine.name!)}
</DropdownMenu.RadioItem>
);
})}
@@ -190,8 +190,8 @@ export function ModuleManager({
variant="ghost"
module="chassis"
discriminator={TIER_ROMAN_NUMERALS[track.tier]}
/>{' '}
{unwrap(track.name)}
/>{" "}
{unwrap(track.name!)}
</DropdownMenu.RadioItem>
);
})}
@@ -20,7 +20,7 @@ export const TankRow = memo<TankRowProps>(
const averages = averageDefinitions.averages[tank.id];
const ratio = useAveragesExclusionRatio();
const playerCountPeriod = Performance.use(
(state) => state.playerCountPeriod
(state) => state.playerCountPeriod,
);
const { locale } = useLocale();
@@ -29,107 +29,109 @@ export const TankRow = memo<TankRowProps>(
<TankRowHeaderCell tank={tank} />
<CompareCell
value={averages.mu.wins / averages.mu.battles}
value={averages.mu!.wins / averages.mu!.battles}
truth={average.winrate}
align="center"
>
{((averages.mu.wins / averages.mu.battles) * 100).toFixed(1)}%
{((averages.mu!.wins / averages.mu!.battles) * 100).toFixed(1)}%
</CompareCell>
<Table.Cell align="center">
{formatCompact(
locale,
Math.round(ratio * averages.samples[playerCountPeriod])
Math.round(ratio * averages.samples![playerCountPeriod]),
)}
</Table.Cell>
<CompareCell
value={averages.mu.damage_dealt / averages.mu.battles}
value={averages.mu!.damage_dealt / averages.mu!.battles}
truth={average.damage}
align="center"
>
{Math.round(
averages.mu.damage_dealt / averages.mu.battles
averages.mu!.damage_dealt / averages.mu!.battles,
).toLocaleString(locale)}
</CompareCell>
<CompareCell
value={averages.mu.survived_battles / averages.mu.battles}
value={averages.mu!.survived_battles / averages.mu!.battles}
truth={average.survival}
align="center"
>
{Math.round(
(averages.mu.survived_battles / averages.mu.battles) * 100
(averages.mu!.survived_battles / averages.mu!.battles) * 100,
)}
%
</CompareCell>
<CompareCell
value={averages.mu.xp / averages.mu.battles}
value={averages.mu!.xp / averages.mu!.battles}
truth={average.xp}
align="center"
>
{Math.round(averages.mu.xp / averages.mu.battles).toLocaleString(
locale
{Math.round(averages.mu!.xp / averages.mu!.battles).toLocaleString(
locale,
)}
</CompareCell>
<CompareCell
value={averages.mu.frags / averages.mu.battles}
value={averages.mu!.frags / averages.mu!.battles}
truth={average.kills}
align="center"
>
{(averages.mu.frags / averages.mu.battles).toFixed(2)}
{(averages.mu!.frags / averages.mu!.battles).toFixed(2)}
</CompareCell>
<CompareCell
value={averages.mu.spotted / averages.mu.battles}
value={averages.mu!.spotted / averages.mu!.battles}
truth={average.spots}
align="center"
>
{(averages.mu.spotted / averages.mu.battles).toFixed(2)}
{(averages.mu!.spotted / averages.mu!.battles).toFixed(2)}
</CompareCell>
<CompareCell
value={averages.mu.hits / averages.mu.shots}
value={averages.mu!.hits / averages.mu!.shots}
truth={average.accuracy}
align="center"
>
{Math.round((averages.mu.hits / averages.mu.shots) * 100)}%
{Math.round((averages.mu!.hits / averages.mu!.shots) * 100)}%
</CompareCell>
<CompareCell
value={averages.mu.shots / averages.mu.battles}
value={averages.mu!.shots / averages.mu!.battles}
truth={average.shots}
align="center"
>
{(averages.mu.shots / averages.mu.battles).toFixed(1)}
{(averages.mu!.shots / averages.mu!.battles).toFixed(1)}
</CompareCell>
<CompareCell
value={averages.mu.hits / averages.mu.battles}
value={averages.mu!.hits / averages.mu!.battles}
truth={average.hits}
align="center"
>
{(averages.mu.hits / averages.mu.battles).toFixed(1)}
{(averages.mu!.hits / averages.mu!.battles).toFixed(1)}
</CompareCell>
<CompareCell
value={averages.mu.damage_dealt / averages.mu.damage_received}
value={averages.mu!.damage_dealt / averages.mu!.damage_received}
truth={average.damageRatio}
align="center"
>
{(averages.mu.damage_dealt / averages.mu.damage_received).toFixed(2)}
{(averages.mu!.damage_dealt / averages.mu!.damage_received).toFixed(
2,
)}
</CompareCell>
<CompareCell
value={averages.mu.damage_received / averages.mu.battles}
value={averages.mu!.damage_received / averages.mu!.battles}
truth={average.damageReceived}
direction={CompareCellDirection.LOWER_IS_BETTER}
align="center"
>
{Math.round(
averages.mu.damage_received / averages.mu.battles
averages.mu!.damage_received / averages.mu!.battles,
).toLocaleString(locale)}
</CompareCell>
<CompareCell
value={averages.mu.capture_points / averages.mu.battles}
value={averages.mu!.capture_points / averages.mu!.battles}
truth={average.capturePoints}
align="center"
>
{(averages.mu.capture_points / averages.mu.battles).toFixed(2)}
{(averages.mu!.capture_points / averages.mu!.battles).toFixed(2)}
</CompareCell>
</Table.Row>
);
},
(prev, next) => prev.tank.id === next.tank.id
(prev, next) => prev.tank.id === next.tank.id,
);
@@ -49,10 +49,10 @@ export function Tanks({ skeleton }: MaybeSkeletonComponentProps) {
const filteredTanks = usePromise(
() =>
filterTanks(filters, tankList).then((tanks) =>
tanks.filter(({ id }) => id in averageDefinitions.averages)
tanks.filter(({ id }) => id in averageDefinitions.averages),
),
// react-promise-suspense has awful type annotations
[filters] as any
[filters] as any,
);
const tanksMapped = useMemo(
() =>
@@ -60,7 +60,7 @@ export function Tanks({ skeleton }: MaybeSkeletonComponentProps) {
id,
...averageDefinitions.averages[id],
})),
[filters]
[filters],
);
const tanksSorted = useMemo(() => {
const { playerCountPeriod } = Performance.state;
@@ -69,83 +69,85 @@ export function Tanks({ skeleton }: MaybeSkeletonComponentProps) {
case "accuracy":
return tanksMapped.sort(
(a, b) =>
sort.direction * (a.mu.hits / a.mu.shots - b.mu.hits / b.mu.shots)
sort.direction *
(a.mu!.hits / a.mu!.shots - b.mu!.hits / b.mu!.shots),
);
case "capture_points":
return tanksMapped.sort(
(a, b) =>
sort.direction *
(a.mu.capture_points / a.mu.battles -
b.mu.capture_points / b.mu.battles)
(a.mu!.capture_points / a.mu!.battles -
b.mu!.capture_points / b.mu!.battles),
);
case "damage":
return tanksMapped.sort(
(a, b) =>
sort.direction *
(a.mu.damage_dealt / a.mu.battles -
b.mu.damage_dealt / b.mu.battles)
(a.mu!.damage_dealt / a.mu!.battles -
b.mu!.damage_dealt / b.mu!.battles),
);
case "damage_ratio":
return tanksMapped.sort(
(a, b) =>
sort.direction *
(a.mu.damage_dealt / a.mu.damage_received -
b.mu.damage_dealt / b.mu.damage_received)
(a.mu!.damage_dealt / a.mu!.damage_received -
b.mu!.damage_dealt / b.mu!.damage_received),
);
case "damage_taken":
return tanksMapped.sort(
(a, b) =>
sort.direction *
(a.mu.damage_received / a.mu.battles -
b.mu.damage_received / b.mu.battles)
(a.mu!.damage_received / a.mu!.battles -
b.mu!.damage_received / b.mu!.battles),
);
case "hits":
return tanksMapped.sort(
(a, b) =>
sort.direction *
(a.mu.hits / a.mu.battles - b.mu.hits / b.mu.battles)
(a.mu!.hits / a.mu!.battles - b.mu!.hits / b.mu!.battles),
);
case "kills":
return tanksMapped.sort(
(a, b) =>
sort.direction *
(a.mu.frags / a.mu.battles - b.mu.frags / b.mu.battles)
(a.mu!.frags / a.mu!.battles - b.mu!.frags / b.mu!.battles),
);
case "shots":
return tanksMapped.sort(
(a, b) =>
sort.direction *
(a.mu.shots / a.mu.battles - b.mu.shots / b.mu.battles)
(a.mu!.shots / a.mu!.battles - b.mu!.shots / b.mu!.battles),
);
case "players":
return tanksMapped.sort(
(a, b) =>
sort.direction *
(a.samples[playerCountPeriod] - b.samples[playerCountPeriod])
(a.samples![playerCountPeriod] - b.samples![playerCountPeriod]),
);
case "spots":
return tanksMapped.sort(
(a, b) =>
sort.direction *
(a.mu.spotted / a.mu.battles - b.mu.spotted / b.mu.battles)
(a.mu!.spotted / a.mu!.battles - b.mu!.spotted / b.mu!.battles),
);
case "survival":
return tanksMapped.sort(
(a, b) =>
sort.direction *
(a.mu.survived_battles / a.mu.battles -
b.mu.survived_battles / b.mu.battles)
(a.mu!.survived_battles / a.mu!.battles -
b.mu!.survived_battles / b.mu!.battles),
);
case "winrate":
return tanksMapped.sort(
(a, b) =>
sort.direction *
(a.mu.wins / a.mu.battles - b.mu.wins / b.mu.battles)
(a.mu!.wins / a.mu!.battles - b.mu!.wins / b.mu!.battles),
);
case "xp":
return tanksMapped.sort(
(a, b) =>
sort.direction * (a.mu.xp / a.mu.battles - b.mu.xp / b.mu.battles)
sort.direction *
(a.mu!.xp / a.mu!.battles - b.mu!.xp / b.mu!.battles),
);
}
}, [filters, sort]);
@@ -161,11 +163,11 @@ export function Tanks({ skeleton }: MaybeSkeletonComponentProps) {
const sum = useCallback(
(slice: (tank: BlitzkitStats) => number) => {
return tanksSorted.reduce(
(acc, tank) => acc + tank.samples[playerCountPeriod] * slice(tank.mu),
0
(acc, tank) => acc + tank.samples![playerCountPeriod] * slice(tank.mu!),
0,
);
},
[tanksSorted]
[tanksSorted],
);
const battles = sum(({ battles }) => battles);
@@ -209,7 +211,7 @@ export function Tanks({ skeleton }: MaybeSkeletonComponentProps) {
<Table.Cell align="center">
{formatCompact(
locale,
ratio * averageDefinitions.samples[playerCountPeriod]
ratio * averageDefinitions.samples![playerCountPeriod],
)}
</Table.Cell>
<Table.Cell align="center">
@@ -255,12 +257,12 @@ export function Tanks({ skeleton }: MaybeSkeletonComponentProps) {
key={index}
onIntersection={() => {
setLoadedRows((state) =>
Math.min(state + 2, tanksSorted.length)
Math.min(state + 2, tanksSorted.length),
);
}}
/>
);
}
},
)}
</Table.Body>
);
Loaded 100 of 148 files, more files were not shown because too many files have changed in this diff. Show more