mirror of
https://github.com/blitzkit/blitzkit.git
synced 2026-10-24 20:19:49 +02:00
Merge branch 'main' into ue
This commit is contained in:
commit
c0376182f8
164 files changed
+5145
-4079
No files matched your search
@@ -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
|
||||||
@@ -0,0 +1,23 @@
|
|||||||
|
# BlitzKit 1.30.0
|
||||||
|
|
||||||
|
Thank you to [GonnaHetzMe](https://github.com/karelpak1) for your contributions this update.
|
||||||
|
|
||||||
|
## Features
|
||||||
|
|
||||||
|
- Added an equalizer mode for Tankopedia and Compare to preview what tank stats will look like in the upcoming Equalizer game mode
|
||||||
|
- This feature is in Beta and the stats are subject to change
|
||||||
|
- Thanks to WoTB News for sourcing data well ahead of the release of the gamemode
|
||||||
|
- Added a toggle in Tankopedia, right beneath Provisions
|
||||||
|
- Added button under the shell selector in the Tank Sandbox
|
||||||
|
- Added another toggle in the Compare table to enable equalizer for all tanks
|
||||||
|
|
||||||
|
## Technical Features
|
||||||
|
|
||||||
|
- [GonnaHetzMe] Enabling dev mode now displays the tank's non-numerical id
|
||||||
|
- [GonnaHetzMe] The dev id and the new dev name are now copyable on click
|
||||||
|
|
||||||
|
## Fixes
|
||||||
|
|
||||||
|
- [GonnaHetzMe] Tech trees that start at tiers higher than tier 1 like the Blitz Nation ones now properly render their trees in Tankopedia
|
||||||
|
- [GonnaHetzMe] The tank pitch/yaw inputs in the Tank Sandbox now initialize with the correct values instead of 0
|
||||||
|
- [GonnaHetzMe] Large Repair Kits once again use the correct modern icon
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
# BlitzKit 1.30.1
|
||||||
|
|
||||||
|
Thank you to [GonnaHetzMe](https://github.com/karelpak1) for your contributions this update.
|
||||||
|
|
||||||
|
## Fixes
|
||||||
|
|
||||||
|
- [GonnaHetzMe] Tank hit points in Equalizer mode is now accurate to the game
|
||||||
|
- Armor highlighting now reflects the actual thicknesses of tanks in Equalizer mode
|
||||||
@@ -43,7 +43,7 @@ export const ownedTanksCommand = new Promise<CommandRegistry>((resolve) => {
|
|||||||
tankStats.map(async (tankData) => ({
|
tankStats.map(async (tankData) => ({
|
||||||
tankDefinitions: (await tankDefinitions).tanks[tankData.tank_id]!,
|
tankDefinitions: (await tankDefinitions).tanks[tankData.tank_id]!,
|
||||||
id: tankData.tank_id,
|
id: tankData.tank_id,
|
||||||
}))
|
})),
|
||||||
)
|
)
|
||||||
).filter((tank) => tank.tankDefinitions?.tier === tier);
|
).filter((tank) => tank.tankDefinitions?.tier === tier);
|
||||||
const groupedTanks: Record<string, TankDefinition[]> = {};
|
const groupedTanks: Record<string, TankDefinition[]> = {};
|
||||||
@@ -69,16 +69,16 @@ export const ownedTanksCommand = new Promise<CommandRegistry>((resolve) => {
|
|||||||
.filter((tank) => tank.tier === tier)
|
.filter((tank) => tank.tier === tier)
|
||||||
.sort(
|
.sort(
|
||||||
(a, b) =>
|
(a, b) =>
|
||||||
TANK_CLASSES.indexOf(a.class) - TANK_CLASSES.indexOf(b.class)
|
TANK_CLASSES.indexOf(a.class) - TANK_CLASSES.indexOf(b.class),
|
||||||
)
|
)
|
||||||
.sort(
|
.sort(
|
||||||
(a, b) =>
|
(a, b) =>
|
||||||
awaitedGameDefinitions.nations.indexOf(a.nation) -
|
awaitedGameDefinitions.nations.indexOf(a.nation) -
|
||||||
awaitedGameDefinitions.nations.indexOf(b.nation)
|
awaitedGameDefinitions.nations.indexOf(b.nation),
|
||||||
)
|
)
|
||||||
.map(
|
.map(
|
||||||
(tank) =>
|
(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];
|
const lines = [title, ...tankList];
|
||||||
|
|
||||||
|
|||||||
@@ -280,7 +280,7 @@ async function playerListing(
|
|||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<img
|
<img
|
||||||
alt={unwrap(tank.name)}
|
alt={unwrap(tank.name!)}
|
||||||
src={await iconPng(tankIcon(tank.id))}
|
src={await iconPng(tankIcon(tank.id))}
|
||||||
style={{
|
style={{
|
||||||
width: 32,
|
width: 32,
|
||||||
@@ -317,7 +317,7 @@ async function playerListing(
|
|||||||
fontSize: 16,
|
fontSize: 16,
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
{unwrap(tank.name)}
|
{unwrap(tank.name!)}
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|||||||
@@ -35,49 +35,49 @@ export const researchCommand = new Promise<CommandRegistry>((resolve) => {
|
|||||||
command: createLocalizedCommand("research")
|
command: createLocalizedCommand("research")
|
||||||
.addStringOption((option) =>
|
.addStringOption((option) =>
|
||||||
option
|
option
|
||||||
.setName(strings.bot.commands.research.options.target_tank.name)
|
.setName(strings.bot.commands.research.options.target_tank.name!)
|
||||||
.setNameLocalizations(
|
.setNameLocalizations(
|
||||||
localizationObject(
|
localizationObject(
|
||||||
(strings) =>
|
(strings) =>
|
||||||
strings.bot.commands.research.options.target_tank.name,
|
strings.bot.commands.research.options.target_tank.name,
|
||||||
undefined,
|
undefined,
|
||||||
true
|
true,
|
||||||
)
|
),
|
||||||
)
|
)
|
||||||
.setDescription(
|
.setDescription(
|
||||||
strings.bot.commands.research.options.target_tank.description
|
strings.bot.commands.research.options.target_tank.description,
|
||||||
)
|
)
|
||||||
.setDescriptionLocalizations(
|
.setDescriptionLocalizations(
|
||||||
localizationObject(
|
localizationObject(
|
||||||
(strings) =>
|
(strings) =>
|
||||||
strings.bot.commands.research.options.target_tank.description
|
strings.bot.commands.research.options.target_tank.description,
|
||||||
)
|
),
|
||||||
)
|
)
|
||||||
.setAutocomplete(true)
|
.setAutocomplete(true)
|
||||||
.setRequired(true)
|
.setRequired(true),
|
||||||
)
|
)
|
||||||
.addStringOption((option) =>
|
.addStringOption((option) =>
|
||||||
option
|
option
|
||||||
.setName(strings.bot.commands.research.options.starting_tank.name)
|
.setName(strings.bot.commands.research.options.starting_tank.name!)
|
||||||
.setNameLocalizations(
|
.setNameLocalizations(
|
||||||
localizationObject(
|
localizationObject(
|
||||||
(strings) =>
|
(strings) =>
|
||||||
strings.bot.commands.research.options.starting_tank.name,
|
strings.bot.commands.research.options.starting_tank.name,
|
||||||
undefined,
|
undefined,
|
||||||
true
|
true,
|
||||||
)
|
),
|
||||||
)
|
)
|
||||||
.setDescription(
|
.setDescription(
|
||||||
strings.bot.commands.research.options.starting_tank.description
|
strings.bot.commands.research.options.starting_tank.description,
|
||||||
)
|
)
|
||||||
.setDescriptionLocalizations(
|
.setDescriptionLocalizations(
|
||||||
localizationObject(
|
localizationObject(
|
||||||
(strings) =>
|
(strings) =>
|
||||||
strings.bot.commands.research.options.starting_tank.description
|
strings.bot.commands.research.options.starting_tank.description,
|
||||||
)
|
),
|
||||||
)
|
)
|
||||||
.setAutocomplete(true)
|
.setAutocomplete(true)
|
||||||
.setRequired(false)
|
.setRequired(false),
|
||||||
)
|
)
|
||||||
.addStringOption(addUsernameChoices),
|
.addStringOption(addUsernameChoices),
|
||||||
|
|
||||||
@@ -87,7 +87,7 @@ export const researchCommand = new Promise<CommandRegistry>((resolve) => {
|
|||||||
const targetTankId = await resolveTankId(
|
const targetTankId = await resolveTankId(
|
||||||
interaction.options.getString("target-tank", true),
|
interaction.options.getString("target-tank", true),
|
||||||
interaction.locale,
|
interaction.locale,
|
||||||
true
|
true,
|
||||||
);
|
);
|
||||||
const startingTankRaw = interaction.options.getString("starting-tank");
|
const startingTankRaw = interaction.options.getString("starting-tank");
|
||||||
const targetTank = awaitedTankDefinitions.tanks[targetTankId];
|
const targetTank = awaitedTankDefinitions.tanks[targetTankId];
|
||||||
@@ -99,13 +99,13 @@ export const researchCommand = new Promise<CommandRegistry>((resolve) => {
|
|||||||
startingTankId = await resolveTankId(
|
startingTankId = await resolveTankId(
|
||||||
startingTankRaw,
|
startingTankRaw,
|
||||||
interaction.locale,
|
interaction.locale,
|
||||||
true
|
true,
|
||||||
);
|
);
|
||||||
|
|
||||||
if (targetTankId === startingTankId) {
|
if (targetTankId === startingTankId) {
|
||||||
return literals(
|
return literals(
|
||||||
strings.bot.commands.research.errors.start_end_equal,
|
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) {
|
if (startingTank.tier > targetTank.tier) {
|
||||||
return literals(strings.bot.commands.research.errors.unordered, {
|
return literals(strings.bot.commands.research.errors.unordered, {
|
||||||
tank_1: escapeMarkdown(unwrap(startingTank.name)),
|
tank_1: escapeMarkdown(unwrap(startingtank.name!)),
|
||||||
tank_2: escapeMarkdown(unwrap(targetTank.name)),
|
tank_2: escapeMarkdown(unwrap(targettank.name!)),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -122,21 +122,21 @@ export const researchCommand = new Promise<CommandRegistry>((resolve) => {
|
|||||||
return literals(
|
return literals(
|
||||||
strings.bot.commands.research.errors.tanks_not_on_line,
|
strings.bot.commands.research.errors.tanks_not_on_line,
|
||||||
{
|
{
|
||||||
tank_1: escapeMarkdown(unwrap(targetTank.name)),
|
tank_1: escapeMarkdown(unwrap(targettank.name!)),
|
||||||
tank_2: escapeMarkdown(unwrap(startingTank.name)),
|
tank_2: escapeMarkdown(unwrap(startingtank.name!)),
|
||||||
}
|
},
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (targetTank.type !== TankType.RESEARCHABLE) {
|
if (targetTank.type !== TankType.TANK_TYPE_RESEARCHABLE) {
|
||||||
return literals(strings.bot.commands.research.errors.non_tech_tree, {
|
return literals(strings.bot.commands.research.errors.non_tech_tree, {
|
||||||
tank: escapeMarkdown(unwrap(targetTank.name)),
|
tank: escapeMarkdown(unwrap(targettank.name!)),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
if (targetTank.tier === 1) {
|
if (targetTank.tier === 1) {
|
||||||
return literals(strings.bot.commands.research.errors.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)) {
|
if (tankStats.some(({ tank_id }) => tank_id === targetTankId)) {
|
||||||
return literals(
|
return literals(
|
||||||
strings.bot.commands.research.errors.already_researched,
|
strings.bot.commands.research.errors.already_researched,
|
||||||
{ tank: escapeMarkdown(unwrap(targetTank.name)) }
|
{ tank: escapeMarkdown(unwrap(targettank.name!)) },
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
const foundAncestor = targetTankAncestry.find(
|
const foundAncestor = targetTankAncestry.find(
|
||||||
(id) =>
|
(id) =>
|
||||||
awaitedTankDefinitions.tanks[id].tier === 1 ||
|
awaitedTankDefinitions.tanks[id].tier === 1 ||
|
||||||
tankStats.some(({ tank_id }) => tank_id === id)
|
tankStats.some(({ tank_id }) => tank_id === id),
|
||||||
);
|
);
|
||||||
|
|
||||||
if (foundAncestor === undefined) {
|
if (foundAncestor === undefined) {
|
||||||
@@ -168,7 +168,7 @@ export const researchCommand = new Promise<CommandRegistry>((resolve) => {
|
|||||||
|
|
||||||
const techTreeLine = await buildTechTreeLine(
|
const techTreeLine = await buildTechTreeLine(
|
||||||
startingTankId,
|
startingTankId,
|
||||||
targetTankId
|
targetTankId,
|
||||||
);
|
);
|
||||||
|
|
||||||
const line = [...techTreeLine, startingTankId].reverse();
|
const line = [...techTreeLine, startingTankId].reverse();
|
||||||
@@ -190,7 +190,7 @@ export const researchCommand = new Promise<CommandRegistry>((resolve) => {
|
|||||||
) {
|
) {
|
||||||
turretXps.set(
|
turretXps.set(
|
||||||
turret.id,
|
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(
|
engineXps.set(
|
||||||
engine.id,
|
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(
|
trackXps.set(
|
||||||
track.id,
|
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 {
|
return {
|
||||||
research: tank.research_cost!.research_cost_type!.value as number,
|
research: tank.research_cost!.research_cost_type!.value as number,
|
||||||
upgrades: moduleXp,
|
upgrades: moduleXp,
|
||||||
purchase: tank.price.value,
|
purchase: tank.price!.value,
|
||||||
equipment: equipmentPriceMatrix[tank.tier].reduce(
|
equipment: equipmentPriceMatrix[tank.tier].reduce(
|
||||||
(a, b) => a + 3 * b,
|
(a, b) => a + 3 * b,
|
||||||
0
|
0,
|
||||||
),
|
),
|
||||||
};
|
};
|
||||||
})
|
}),
|
||||||
);
|
);
|
||||||
|
|
||||||
const image = (
|
const image = (
|
||||||
@@ -456,7 +456,7 @@ export const researchCommand = new Promise<CommandRegistry>((resolve) => {
|
|||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<img
|
<img
|
||||||
alt={unwrap(tank.name)}
|
alt={unwrap(tank.name!)}
|
||||||
src={TANK_ICONS[tank.class]}
|
src={TANK_ICONS[tank.class]}
|
||||||
width={16}
|
width={16}
|
||||||
height={16}
|
height={16}
|
||||||
@@ -467,7 +467,7 @@ export const researchCommand = new Promise<CommandRegistry>((resolve) => {
|
|||||||
color: theme.colors.textHighContrast,
|
color: theme.colors.textHighContrast,
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
{unwrap(tank.name)}
|
{unwrap(tank.name!)}
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -505,9 +505,9 @@ export const researchCommand = new Promise<CommandRegistry>((resolve) => {
|
|||||||
strings.bot.commands.research.body.research,
|
strings.bot.commands.research.body.research,
|
||||||
{
|
{
|
||||||
cost: costs[index].research?.toLocaleString(
|
cost: costs[index].research?.toLocaleString(
|
||||||
interaction.locale
|
interaction.locale,
|
||||||
),
|
),
|
||||||
}
|
},
|
||||||
)}
|
)}
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
@@ -523,7 +523,7 @@ export const researchCommand = new Promise<CommandRegistry>((resolve) => {
|
|||||||
<img
|
<img
|
||||||
alt="Free XP icon"
|
alt="Free XP icon"
|
||||||
src={await iconPng(
|
src={await iconPng(
|
||||||
asset("icons/currencies/free-xp.webp")
|
asset("icons/currencies/free-xp.webp"),
|
||||||
)}
|
)}
|
||||||
width={16}
|
width={16}
|
||||||
height={16}
|
height={16}
|
||||||
@@ -536,7 +536,7 @@ export const researchCommand = new Promise<CommandRegistry>((resolve) => {
|
|||||||
>
|
>
|
||||||
{literals(
|
{literals(
|
||||||
strings.bot.commands.research.body.upgrades,
|
strings.bot.commands.research.body.upgrades,
|
||||||
{ cost: costs[index].upgrades.toLocaleString() }
|
{ cost: costs[index].upgrades.toLocaleString() },
|
||||||
)}
|
)}
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
@@ -552,7 +552,7 @@ export const researchCommand = new Promise<CommandRegistry>((resolve) => {
|
|||||||
<img
|
<img
|
||||||
alt="Silver icon"
|
alt="Silver icon"
|
||||||
src={await iconPng(
|
src={await iconPng(
|
||||||
asset("icons/currencies/silver.webp")
|
asset("icons/currencies/silver.webp"),
|
||||||
)}
|
)}
|
||||||
width={16}
|
width={16}
|
||||||
height={16}
|
height={16}
|
||||||
@@ -567,9 +567,9 @@ export const researchCommand = new Promise<CommandRegistry>((resolve) => {
|
|||||||
strings.bot.commands.research.body.purchase,
|
strings.bot.commands.research.body.purchase,
|
||||||
{
|
{
|
||||||
cost: costs[index].purchase.toLocaleString(
|
cost: costs[index].purchase.toLocaleString(
|
||||||
interaction.locale
|
interaction.locale,
|
||||||
),
|
),
|
||||||
}
|
},
|
||||||
)}
|
)}
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
@@ -584,7 +584,7 @@ export const researchCommand = new Promise<CommandRegistry>((resolve) => {
|
|||||||
<img
|
<img
|
||||||
alt="Silver icon"
|
alt="Silver icon"
|
||||||
src={await iconPng(
|
src={await iconPng(
|
||||||
asset("icons/currencies/silver.webp")
|
asset("icons/currencies/silver.webp"),
|
||||||
)}
|
)}
|
||||||
width={16}
|
width={16}
|
||||||
height={16}
|
height={16}
|
||||||
@@ -599,16 +599,16 @@ export const researchCommand = new Promise<CommandRegistry>((resolve) => {
|
|||||||
strings.bot.commands.research.body.equipment,
|
strings.bot.commands.research.body.equipment,
|
||||||
{
|
{
|
||||||
cost: costs[index].equipment.toLocaleString(
|
cost: costs[index].equipment.toLocaleString(
|
||||||
interaction.locale
|
interaction.locale,
|
||||||
),
|
),
|
||||||
}
|
},
|
||||||
)}
|
)}
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
})
|
}),
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
</CommandWrapper>
|
</CommandWrapper>
|
||||||
|
|||||||
@@ -3,14 +3,14 @@ import {
|
|||||||
TankClass,
|
TankClass,
|
||||||
TankType,
|
TankType,
|
||||||
TREE_TYPE_ICONS,
|
TREE_TYPE_ICONS,
|
||||||
} from '@blitzkit/core';
|
} from "@blitzkit/core";
|
||||||
import { createColors } from 'bepaint';
|
import { createColors } from "bepaint";
|
||||||
import {
|
import {
|
||||||
type AccentColor,
|
type AccentColor,
|
||||||
type GrayColor,
|
type GrayColor,
|
||||||
PALETTES,
|
PALETTES,
|
||||||
} from '../../../core/radix/radixColors';
|
} from "../../../core/radix/radixColors";
|
||||||
import { RowStat } from './RowStat';
|
import { RowStat } from "./RowStat";
|
||||||
|
|
||||||
export interface RowStatItem {
|
export interface RowStatItem {
|
||||||
title: string;
|
title: string;
|
||||||
@@ -21,7 +21,7 @@ export interface RowStatItem {
|
|||||||
}
|
}
|
||||||
|
|
||||||
interface RowProps {
|
interface RowProps {
|
||||||
displayType?: 'tank' | 'summary';
|
displayType?: "tank" | "summary";
|
||||||
naked?: boolean;
|
naked?: boolean;
|
||||||
title: string;
|
title: string;
|
||||||
minimized?: boolean;
|
minimized?: boolean;
|
||||||
@@ -32,7 +32,7 @@ interface RowProps {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export function Row({
|
export function Row({
|
||||||
color = 'slate',
|
color = "slate",
|
||||||
stats,
|
stats,
|
||||||
title,
|
title,
|
||||||
minimized,
|
minimized,
|
||||||
@@ -49,20 +49,20 @@ export function Row({
|
|||||||
className="session-tracker-row"
|
className="session-tracker-row"
|
||||||
style={{
|
style={{
|
||||||
maxWidth: naked ? 600 : Infinity,
|
maxWidth: naked ? 600 : Infinity,
|
||||||
display: 'flex',
|
display: "flex",
|
||||||
flexDirection: 'column',
|
flexDirection: "column",
|
||||||
borderRadius: 4,
|
borderRadius: 4,
|
||||||
backgroundColor: naked
|
backgroundColor: naked
|
||||||
? `${theme.appBackground2}c0`
|
? `${theme.appBackground2}c0`
|
||||||
: theme.appBackground2,
|
: theme.appBackground2,
|
||||||
overflow: 'hidden',
|
overflow: "hidden",
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
style={{
|
style={{
|
||||||
display: 'flex',
|
display: "flex",
|
||||||
alignItems: 'center',
|
alignItems: "center",
|
||||||
justifyContent: 'center',
|
justifyContent: "center",
|
||||||
padding: 8,
|
padding: 8,
|
||||||
gap: 4,
|
gap: 4,
|
||||||
backgroundColor: naked
|
backgroundColor: naked
|
||||||
@@ -70,10 +70,14 @@ export function Row({
|
|||||||
: theme.componentInteractive,
|
: theme.componentInteractive,
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
{displayType === 'tank' && tankClass !== undefined && (
|
{displayType === "tank" && tankClass !== undefined && (
|
||||||
<img
|
<img
|
||||||
alt={TankClass[tankClass]}
|
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 }}
|
style={{ width: 16, height: 16 }}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
@@ -81,10 +85,10 @@ export function Row({
|
|||||||
<span
|
<span
|
||||||
style={{
|
style={{
|
||||||
color:
|
color:
|
||||||
displayType === 'tank'
|
displayType === "tank"
|
||||||
? type === TankType.COLLECTOR
|
? type === TankType.TANK_TYPE_COLLECTOR
|
||||||
? theme.textLowContrast_blue
|
? theme.textLowContrast_blue
|
||||||
: type === TankType.PREMIUM
|
: type === TankType.TANK_TYPE_PREMIUM
|
||||||
? theme.textLowContrast_amber
|
? theme.textLowContrast_amber
|
||||||
: theme.textHighContrast
|
: theme.textHighContrast
|
||||||
: theme.textLowContrast,
|
: theme.textLowContrast,
|
||||||
@@ -98,7 +102,7 @@ export function Row({
|
|||||||
|
|
||||||
<div
|
<div
|
||||||
style={{
|
style={{
|
||||||
display: 'flex',
|
display: "flex",
|
||||||
paddingTop: 8,
|
paddingTop: 8,
|
||||||
paddingBottom: 8,
|
paddingBottom: 8,
|
||||||
}}
|
}}
|
||||||
@@ -109,8 +113,8 @@ export function Row({
|
|||||||
<RowStat
|
<RowStat
|
||||||
minimized={minimized}
|
minimized={minimized}
|
||||||
key={index}
|
key={index}
|
||||||
name={`${row.title} • ${row.career ?? '--'}`}
|
name={`${row.title} • ${row.career ?? "--"}`}
|
||||||
value={row.current ?? '--'}
|
value={row.current ?? "--"}
|
||||||
delta={row.delta}
|
delta={row.delta}
|
||||||
percentile={row.percentile}
|
percentile={row.percentile}
|
||||||
/>
|
/>
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import { TankClass, TankType, TREE_TYPE_ICONS } from '@blitzkit/core';
|
import { TankClass, TankType, TREE_TYPE_ICONS } from "@blitzkit/core";
|
||||||
import { theme } from '../../../../stitches.config';
|
import { theme } from "../../../../stitches.config";
|
||||||
|
|
||||||
export interface ItemProps {
|
export interface ItemProps {
|
||||||
tankClass?: TankClass;
|
tankClass?: TankClass;
|
||||||
@@ -8,9 +8,9 @@ export interface ItemProps {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const TREE_TYPE_COLOR = {
|
const TREE_TYPE_COLOR = {
|
||||||
[TankType.RESEARCHABLE]: '',
|
[TankType.TANK_TYPE_RESEARCHABLE]: "",
|
||||||
[TankType.PREMIUM]: '_amber',
|
[TankType.TANK_TYPE_PREMIUM]: "_amber",
|
||||||
[TankType.COLLECTOR]: '_blue',
|
[TankType.TANK_TYPE_COLLECTOR]: "_blue",
|
||||||
} as const;
|
} as const;
|
||||||
|
|
||||||
export function Item({
|
export function Item({
|
||||||
@@ -21,12 +21,12 @@ export function Item({
|
|||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
style={{
|
style={{
|
||||||
display: 'flex',
|
display: "flex",
|
||||||
height: 32,
|
height: 32,
|
||||||
paddingLeft: 8,
|
paddingLeft: 8,
|
||||||
paddingRight: 8,
|
paddingRight: 8,
|
||||||
overflow: 'hidden',
|
overflow: "hidden",
|
||||||
alignItems: 'center',
|
alignItems: "center",
|
||||||
borderRadius: 4,
|
borderRadius: 4,
|
||||||
backgroundColor:
|
backgroundColor:
|
||||||
theme.colors[`componentInteractive${TREE_TYPE_COLOR[treeType]}`],
|
theme.colors[`componentInteractive${TREE_TYPE_COLOR[treeType]}`],
|
||||||
@@ -34,12 +34,12 @@ export function Item({
|
|||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
style={{
|
style={{
|
||||||
display: 'flex',
|
display: "flex",
|
||||||
gap: 4,
|
gap: 4,
|
||||||
flex: 1,
|
flex: 1,
|
||||||
alignItems: 'center',
|
alignItems: "center",
|
||||||
justifyContent: 'flex-start',
|
justifyContent: "flex-start",
|
||||||
overflow: 'hidden',
|
overflow: "hidden",
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
{tankType && (
|
{tankType && (
|
||||||
@@ -52,7 +52,7 @@ export function Item({
|
|||||||
<span
|
<span
|
||||||
style={{
|
style={{
|
||||||
fontSize: 16,
|
fontSize: 16,
|
||||||
whiteSpace: 'nowrap',
|
whiteSpace: "nowrap",
|
||||||
color: theme.colors[`textLowContrast${TREE_TYPE_COLOR[treeType]}`],
|
color: theme.colors[`textLowContrast${TREE_TYPE_COLOR[treeType]}`],
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
|
|||||||
@@ -6,21 +6,21 @@ import { translator } from "../localization/translator";
|
|||||||
|
|
||||||
export async function filtersToDescription(
|
export async function filtersToDescription(
|
||||||
{ nation, tier, type, class: tankClass, tank }: StatFilters,
|
{ nation, tier, type, class: tankClass, tank }: StatFilters,
|
||||||
locale: Locale
|
locale: Locale,
|
||||||
) {
|
) {
|
||||||
const { strings, bkLocale } = translator(locale);
|
const { strings, bkLocale } = translator(locale);
|
||||||
const awaitedTankDefinitions = await fetchTankDefinitions();
|
const awaitedTankDefinitions = await fetchTankDefinitions();
|
||||||
const info: string[] = [];
|
const info: string[] = [];
|
||||||
|
|
||||||
// TODO: somehow localize tank names?
|
// 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)
|
if (nation)
|
||||||
info.push((strings.common.nations as Record<string, string>)[nation]);
|
info.push((strings.common.nations as Record<string, string>)[nation]);
|
||||||
if (tier) {
|
if (tier) {
|
||||||
info.push(
|
info.push(
|
||||||
literals(strings.bot.common.filters.tier, {
|
literals(strings.bot.common.filters.tier, {
|
||||||
tier: TIER_ROMAN_NUMERALS[tier],
|
tier: TIER_ROMAN_NUMERALS[tier],
|
||||||
})
|
}),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
if (tankClass) info.push(strings.common.tank_class_short[tankClass]);
|
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.tier === undefined || entry.tier === filters.tier) &&
|
||||||
(filters.class === undefined || entry.class === filters.class) &&
|
(filters.class === undefined || entry.class === filters.class) &&
|
||||||
(filters.type === undefined ||
|
(filters.type === undefined ||
|
||||||
(filters.type === TankType.COLLECTOR &&
|
(filters.type === TankType.TANK_TYPE_COLLECTOR &&
|
||||||
entry.type === TankType.COLLECTOR) ||
|
entry.type === TankType.TANK_TYPE_COLLECTOR) ||
|
||||||
(filters.type === TankType.PREMIUM &&
|
(filters.type === TankType.TANK_TYPE_PREMIUM &&
|
||||||
entry.type === TankType.PREMIUM) ||
|
entry.type === TankType.TANK_TYPE_PREMIUM) ||
|
||||||
(filters.type === TankType.RESEARCHABLE &&
|
(filters.type === TankType.TANK_TYPE_RESEARCHABLE &&
|
||||||
entry.type === TankType.RESEARCHABLE)) &&
|
entry.type === TankType.TANK_TYPE_RESEARCHABLE)) &&
|
||||||
(filters.tank === undefined || entry.id === filters.tank)
|
(filters.tank === undefined || entry.id === filters.tank)
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -1,12 +1,12 @@
|
|||||||
import { Locale, SlashCommandStringOption } from 'discord.js';
|
import { Locale, SlashCommandStringOption } from "discord.js";
|
||||||
import { translator } from '../localization/translator';
|
import { translator } from "../localization/translator";
|
||||||
import { localizationObject } from './localizationObject';
|
import { localizationObject } from "./localizationObject";
|
||||||
|
|
||||||
export function addTankChoices(option: SlashCommandStringOption) {
|
export function addTankChoices(option: SlashCommandStringOption) {
|
||||||
const { strings } = translator(Locale.EnglishUS);
|
const { strings } = translator(Locale.EnglishUS);
|
||||||
|
|
||||||
return option
|
return option
|
||||||
.setName(strings.bot.common.options.tank.name)
|
.setName(strings.bot.common.options.tank.name!)
|
||||||
.setNameLocalizations(
|
.setNameLocalizations(
|
||||||
localizationObject(
|
localizationObject(
|
||||||
(strings) => strings.bot.common.options.tank.name,
|
(strings) => strings.bot.common.options.tank.name,
|
||||||
|
|||||||
@@ -13,13 +13,13 @@ import {
|
|||||||
} from "./autocompleteClan/constants";
|
} from "./autocompleteClan/constants";
|
||||||
|
|
||||||
export const tankNamesTechTreeOnly = fetchTankNames().then((names) =>
|
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(
|
export async function autocompleteTanks(
|
||||||
interaction: AutocompleteInteraction<CacheType>,
|
interaction: AutocompleteInteraction<CacheType>,
|
||||||
techTreeOnly = false,
|
techTreeOnly = false,
|
||||||
fields = ["tank"]
|
fields = ["tank"],
|
||||||
) {
|
) {
|
||||||
const { unwrap } = translator(interaction.locale);
|
const { unwrap } = translator(interaction.locale);
|
||||||
const focusedOption = interaction.options.getFocused(true);
|
const focusedOption = interaction.options.getFocused(true);
|
||||||
@@ -31,7 +31,7 @@ export async function autocompleteTanks(
|
|||||||
go(
|
go(
|
||||||
focusedOption.value,
|
focusedOption.value,
|
||||||
await (techTreeOnly ? tankNamesTechTreeOnly : tankNames),
|
await (techTreeOnly ? tankNamesTechTreeOnly : tankNames),
|
||||||
{ keys: SEARCH_KEYS, limit: 10 }
|
{ keys: SEARCH_KEYS, limit: 10 },
|
||||||
).map(async (item) => {
|
).map(async (item) => {
|
||||||
let name = unwrap(item.obj.searchableName);
|
let name = unwrap(item.obj.searchableName);
|
||||||
|
|
||||||
@@ -42,7 +42,7 @@ export async function autocompleteTanks(
|
|||||||
0,
|
0,
|
||||||
unwrap(item.obj.searchableName).length -
|
unwrap(item.obj.searchableName).length -
|
||||||
overSize -
|
overSize -
|
||||||
OVERFLOW_SUFFIX.length
|
OVERFLOW_SUFFIX.length,
|
||||||
)}${OVERFLOW_SUFFIX}`;
|
)}${OVERFLOW_SUFFIX}`;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -50,8 +50,8 @@ export async function autocompleteTanks(
|
|||||||
name,
|
name,
|
||||||
value: `${item.obj.id}`,
|
value: `${item.obj.id}`,
|
||||||
} satisfies ApplicationCommandOptionChoiceData<string>;
|
} satisfies ApplicationCommandOptionChoiceData<string>;
|
||||||
})
|
}),
|
||||||
)
|
)
|
||||||
: []
|
: [],
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -1,5 +1,7 @@
|
|||||||
import { ShellDefinition, ShellType } from "../protos";
|
import { ShellDefinition, ShellType } from "../protos";
|
||||||
|
|
||||||
export function canSplash(type: ShellDefinition["type"]): type is ShellType.HE {
|
export function canSplash(
|
||||||
return type === ShellType.HE;
|
type: ShellDefinition["type"],
|
||||||
|
): type is ShellType.SHELL_TYPE_HE {
|
||||||
|
return type === ShellType.SHELL_TYPE_HE;
|
||||||
}
|
}
|
||||||
@@ -2,22 +2,22 @@ import { TankClass, TankType } from "../protos";
|
|||||||
import type { BlitzStats } from "../statistics";
|
import type { BlitzStats } from "../statistics";
|
||||||
|
|
||||||
export const TANK_TYPES = [
|
export const TANK_TYPES = [
|
||||||
TankType.RESEARCHABLE,
|
TankType.TANK_TYPE_RESEARCHABLE,
|
||||||
TankType.PREMIUM,
|
TankType.TANK_TYPE_PREMIUM,
|
||||||
TankType.COLLECTOR,
|
TankType.TANK_TYPE_COLLECTOR,
|
||||||
];
|
];
|
||||||
|
|
||||||
export const TANK_TYPE_COMMAND_NAMES = {
|
export const TANK_TYPE_COMMAND_NAMES = {
|
||||||
[TankType.RESEARCHABLE]: "researchable",
|
[TankType.TANK_TYPE_RESEARCHABLE]: "researchable",
|
||||||
[TankType.PREMIUM]: "premium",
|
[TankType.TANK_TYPE_PREMIUM]: "premium",
|
||||||
[TankType.COLLECTOR]: "collector",
|
[TankType.TANK_TYPE_COLLECTOR]: "collector",
|
||||||
};
|
};
|
||||||
|
|
||||||
export const TANK_CLASSES = [
|
export const TANK_CLASSES = [
|
||||||
TankClass.LIGHT,
|
TankClass.TANK_CLASS_LIGHT,
|
||||||
TankClass.MEDIUM,
|
TankClass.TANK_CLASS_MEDIUM,
|
||||||
TankClass.HEAVY,
|
TankClass.TANK_CLASS_HEAVY,
|
||||||
TankClass.TANK_DESTROYER,
|
TankClass.TANK_CLASS_TANK_DESTROYER,
|
||||||
];
|
];
|
||||||
|
|
||||||
export const emptyAllStats: BlitzStats = {
|
export const emptyAllStats: BlitzStats = {
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ import {
|
|||||||
export function checkConsumableProvisionInclusivity(
|
export function checkConsumableProvisionInclusivity(
|
||||||
consumableProvision: Consumable | Provision,
|
consumableProvision: Consumable | Provision,
|
||||||
tank: TankDefinition,
|
tank: TankDefinition,
|
||||||
gun: GunDefinition
|
gun: GunDefinition,
|
||||||
) {
|
) {
|
||||||
const included = consumableProvision.include?.every((rule) => {
|
const included = consumableProvision.include?.every((rule) => {
|
||||||
switch (rule.filter_type!.$case) {
|
switch (rule.filter_type!.$case) {
|
||||||
@@ -46,7 +46,7 @@ export function checkConsumableProvisionInclusivity(
|
|||||||
case "categories":
|
case "categories":
|
||||||
return rule.filter_type!.value.categories.some((category) => {
|
return rule.filter_type!.value.categories.some((category) => {
|
||||||
switch (category) {
|
switch (category) {
|
||||||
case ConsumableTankCategoryFilterCategory.CLIP:
|
case ConsumableTankCategoryFilterCategory.CONSUMABLE_TANK_CATEGORY_FILTER_CATEGORY_CLIP:
|
||||||
return gun.gun_type!.$case !== "regular";
|
return gun.gun_type!.$case !== "regular";
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import { ShellDefinition, ShellType } from "../protos";
|
import { ShellDefinition, ShellType } from "../protos";
|
||||||
|
|
||||||
export function isExplosive(
|
export function isExplosive(
|
||||||
type: ShellDefinition["type"]
|
type: ShellDefinition["type"],
|
||||||
): type is ShellType.HEAT | ShellType.HE {
|
): type is ShellType.SHELL_TYPE_HEAT | ShellType.SHELL_TYPE_HE {
|
||||||
return type === ShellType.HEAT || type === ShellType.HE;
|
return type === ShellType.SHELL_TYPE_HEAT || type === ShellType.SHELL_TYPE_HE;
|
||||||
}
|
}
|
||||||
@@ -2,27 +2,27 @@ import { TANK_CLASSES } from "../blitz/constants";
|
|||||||
import { GameDefinitions, TankDefinition, TankType } from "../protos";
|
import { GameDefinitions, TankDefinition, TankType } from "../protos";
|
||||||
|
|
||||||
const treeTypeOrder = [
|
const treeTypeOrder = [
|
||||||
TankType.RESEARCHABLE,
|
TankType.TANK_TYPE_RESEARCHABLE,
|
||||||
TankType.PREMIUM,
|
TankType.TANK_TYPE_PREMIUM,
|
||||||
TankType.COLLECTOR,
|
TankType.TANK_TYPE_COLLECTOR,
|
||||||
];
|
];
|
||||||
|
|
||||||
export function metaSortTank(
|
export function metaSortTank(
|
||||||
tanks: TankDefinition[],
|
tanks: TankDefinition[],
|
||||||
gameDefinitions: GameDefinitions
|
gameDefinitions: GameDefinitions,
|
||||||
) {
|
) {
|
||||||
return tanks
|
return tanks
|
||||||
.sort((a, b) => b.tier - a.tier)
|
.sort((a, b) => b.tier - a.tier)
|
||||||
.sort(
|
.sort(
|
||||||
(a, b) => treeTypeOrder.indexOf(b.type) - treeTypeOrder.indexOf(a.type)
|
(a, b) => treeTypeOrder.indexOf(b.type) - treeTypeOrder.indexOf(a.type),
|
||||||
)
|
)
|
||||||
.sort(
|
.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(
|
.sort(
|
||||||
(a, b) =>
|
(a, b) =>
|
||||||
gameDefinitions.nations.indexOf(b.nation) -
|
gameDefinitions.nations.indexOf(b.nation) -
|
||||||
gameDefinitions.nations.indexOf(a.nation)
|
gameDefinitions.nations.indexOf(a.nation),
|
||||||
)
|
)
|
||||||
.sort((a, b) => a.tier - b.tier);
|
.sort((a, b) => a.tier - b.tier);
|
||||||
}
|
}
|
||||||
@@ -2,8 +2,8 @@ import { BoundingBox, Vector3 } from "../protos";
|
|||||||
|
|
||||||
export function normalizeBoundingBox(boundingBox: BoundingBox) {
|
export function normalizeBoundingBox(boundingBox: BoundingBox) {
|
||||||
return {
|
return {
|
||||||
x: boundingBox.max.x - boundingBox.min.x,
|
x: boundingBox.max!.x - boundingBox.min!.x,
|
||||||
y: boundingBox.max.y - boundingBox.min.y,
|
y: boundingBox.max!.y - boundingBox.min!.y,
|
||||||
z: boundingBox.max.z - boundingBox.min.z,
|
z: boundingBox.max!.z - boundingBox.min!.z,
|
||||||
} satisfies Vector3;
|
} satisfies Vector3;
|
||||||
}
|
}
|
||||||
@@ -1,16 +1,21 @@
|
|||||||
import { ShellType } from '../protos';
|
import { Equalizer, ShellType } from "../protos";
|
||||||
|
|
||||||
export function resolvePenetrationCoefficient(
|
export function resolvePenetrationCoefficient(
|
||||||
calibratedShells: boolean,
|
calibratedShells: boolean,
|
||||||
|
equalize: boolean,
|
||||||
type: ShellType,
|
type: ShellType,
|
||||||
|
equalizerObj?: Equalizer,
|
||||||
) {
|
) {
|
||||||
if (!calibratedShells) return 1;
|
const calibrated = calibratedShells
|
||||||
|
? type === ShellType.SHELL_TYPE_AP
|
||||||
|
? 1.08
|
||||||
|
: type === ShellType.SHELL_TYPE_APCR
|
||||||
|
? 1.05
|
||||||
|
: type === ShellType.SHELL_TYPE_HEAT
|
||||||
|
? 1.13
|
||||||
|
: 1.08
|
||||||
|
: 1;
|
||||||
|
const equalizer = (equalize ? equalizerObj?.penetration : undefined) ?? 1;
|
||||||
|
|
||||||
return type === ShellType.AP
|
return calibrated * equalizer;
|
||||||
? 1.08
|
|
||||||
: type === ShellType.APCR
|
|
||||||
? 1.05
|
|
||||||
: type === ShellType.HEAT
|
|
||||||
? 1.13
|
|
||||||
: 1.08;
|
|
||||||
}
|
}
|
||||||
@@ -1,74 +1,74 @@
|
|||||||
import { times } from 'lodash-es';
|
import { times } from "lodash-es";
|
||||||
import { CrewType, ShellType, TankClass, TankType } from '../../protos';
|
import { CrewType, ShellType, TankClass, TankType } from "../../protos";
|
||||||
|
|
||||||
export const SHELL_NAMES: Record<ShellType, string> = {
|
export const SHELL_NAMES: Record<ShellType, string> = {
|
||||||
[ShellType.AP]: 'AP',
|
[ShellType.SHELL_TYPE_AP]: "AP",
|
||||||
[ShellType.APCR]: 'APCR',
|
[ShellType.SHELL_TYPE_APCR]: "APCR",
|
||||||
[ShellType.HEAT]: 'HEAT',
|
[ShellType.SHELL_TYPE_HEAT]: "HEAT",
|
||||||
[ShellType.HE]: 'HE',
|
[ShellType.SHELL_TYPE_HE]: "HE",
|
||||||
};
|
};
|
||||||
export const CREW_MEMBER_NAMES = {
|
export const CREW_MEMBER_NAMES = {
|
||||||
[CrewType.COMMANDER]: 'commander',
|
[CrewType.CREW_TYPE_COMMANDER]: "commander",
|
||||||
[CrewType.DRIVER]: 'driver',
|
[CrewType.CREW_TYPE_DRIVER]: "driver",
|
||||||
[CrewType.GUNNER]: 'gunner',
|
[CrewType.CREW_TYPE_GUNNER]: "gunner",
|
||||||
[CrewType.LOADER]: 'loader',
|
[CrewType.CREW_TYPE_LOADER]: "loader",
|
||||||
[CrewType.RADIOMAN]: 'radioman',
|
[CrewType.CREW_TYPE_RADIOMAN]: "radioman",
|
||||||
} as const;
|
} as const;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @deprecated use svg
|
* @deprecated use svg
|
||||||
*/
|
*/
|
||||||
export const TANK_ICONS: Record<TankClass, string> = {
|
export const TANK_ICONS: Record<TankClass, string> = {
|
||||||
[TankClass.TANK_DESTROYER]: 'https://i.imgur.com/BIHSEH0.png',
|
[TankClass.TANK_CLASS_TANK_DESTROYER]: "https://i.imgur.com/BIHSEH0.png",
|
||||||
[TankClass.LIGHT]: 'https://i.imgur.com/CSNha5V.png',
|
[TankClass.TANK_CLASS_LIGHT]: "https://i.imgur.com/CSNha5V.png",
|
||||||
[TankClass.MEDIUM]: 'https://i.imgur.com/wvf3ltm.png',
|
[TankClass.TANK_CLASS_MEDIUM]: "https://i.imgur.com/wvf3ltm.png",
|
||||||
[TankClass.HEAVY]: 'https://i.imgur.com/ECeqlZa.png',
|
[TankClass.TANK_CLASS_HEAVY]: "https://i.imgur.com/ECeqlZa.png",
|
||||||
};
|
};
|
||||||
/**
|
/**
|
||||||
* @deprecated use svg
|
* @deprecated use svg
|
||||||
*/
|
*/
|
||||||
export const TANK_ICONS_PREMIUM: Record<TankClass, string> = {
|
export const TANK_ICONS_PREMIUM: Record<TankClass, string> = {
|
||||||
[TankClass.TANK_DESTROYER]: 'https://i.imgur.com/TCu3EdR.png',
|
[TankClass.TANK_CLASS_TANK_DESTROYER]: "https://i.imgur.com/TCu3EdR.png",
|
||||||
[TankClass.LIGHT]: 'https://i.imgur.com/zdkpTRb.png',
|
[TankClass.TANK_CLASS_LIGHT]: "https://i.imgur.com/zdkpTRb.png",
|
||||||
[TankClass.MEDIUM]: 'https://i.imgur.com/3z7eHX6.png',
|
[TankClass.TANK_CLASS_MEDIUM]: "https://i.imgur.com/3z7eHX6.png",
|
||||||
[TankClass.HEAVY]: 'https://i.imgur.com/P3vbmyA.png',
|
[TankClass.TANK_CLASS_HEAVY]: "https://i.imgur.com/P3vbmyA.png",
|
||||||
};
|
};
|
||||||
/**
|
/**
|
||||||
* @deprecated use svg
|
* @deprecated use svg
|
||||||
*/
|
*/
|
||||||
export const TANK_ICONS_COLLECTOR: Record<TankClass, string> = {
|
export const TANK_ICONS_COLLECTOR: Record<TankClass, string> = {
|
||||||
[TankClass.TANK_DESTROYER]: 'https://i.imgur.com/WTjeirB.png',
|
[TankClass.TANK_CLASS_TANK_DESTROYER]: "https://i.imgur.com/WTjeirB.png",
|
||||||
[TankClass.LIGHT]: 'https://i.imgur.com/EwhtKkU.png',
|
[TankClass.TANK_CLASS_LIGHT]: "https://i.imgur.com/EwhtKkU.png",
|
||||||
[TankClass.MEDIUM]: 'https://i.imgur.com/u8YDMBh.png',
|
[TankClass.TANK_CLASS_MEDIUM]: "https://i.imgur.com/u8YDMBh.png",
|
||||||
[TankClass.HEAVY]: 'https://i.imgur.com/8xRf3nc.png',
|
[TankClass.TANK_CLASS_HEAVY]: "https://i.imgur.com/8xRf3nc.png",
|
||||||
};
|
};
|
||||||
export const TIERS = times(10, (index) => index + 1);
|
export const TIERS = times(10, (index) => index + 1);
|
||||||
export const TIER_ROMAN_NUMERALS: Record<number, string> = {
|
export const TIER_ROMAN_NUMERALS: Record<number, string> = {
|
||||||
1: 'I',
|
1: "I",
|
||||||
2: 'II',
|
2: "II",
|
||||||
3: 'III',
|
3: "III",
|
||||||
4: 'IV',
|
4: "IV",
|
||||||
5: 'V',
|
5: "V",
|
||||||
6: 'VI',
|
6: "VI",
|
||||||
7: 'VII',
|
7: "VII",
|
||||||
8: 'VIII',
|
8: "VIII",
|
||||||
9: 'IX',
|
9: "IX",
|
||||||
10: 'X',
|
10: "X",
|
||||||
};
|
};
|
||||||
|
|
||||||
export const flags: Record<string, string> = {
|
export const flags: Record<string, string> = {
|
||||||
ussr: '<:ussr:1218421042033197197>',
|
ussr: "<:ussr:1218421042033197197>",
|
||||||
germany: '🇩🇪',
|
germany: "🇩🇪",
|
||||||
usa: '🇺🇸',
|
usa: "🇺🇸",
|
||||||
china: '🇨🇳',
|
china: "🇨🇳",
|
||||||
uk: '🇬🇧',
|
uk: "🇬🇧",
|
||||||
france: '🇫🇷',
|
france: "🇫🇷",
|
||||||
japan: '🇯🇵',
|
japan: "🇯🇵",
|
||||||
european: '🇪🇺',
|
european: "🇪🇺",
|
||||||
other: '<:other:1218421572243558482>',
|
other: "<:other:1218421572243558482>",
|
||||||
};
|
};
|
||||||
export const TREE_TYPE_ICONS: Record<TankType, Record<TankClass, string>> = {
|
export const TREE_TYPE_ICONS: Record<TankType, Record<TankClass, string>> = {
|
||||||
[TankType.RESEARCHABLE]: TANK_ICONS,
|
[TankType.TANK_TYPE_RESEARCHABLE]: TANK_ICONS,
|
||||||
[TankType.PREMIUM]: TANK_ICONS_PREMIUM,
|
[TankType.TANK_TYPE_PREMIUM]: TANK_ICONS_PREMIUM,
|
||||||
[TankType.COLLECTOR]: TANK_ICONS_COLLECTOR,
|
[TankType.TANK_TYPE_COLLECTOR]: TANK_ICONS_COLLECTOR,
|
||||||
};
|
};
|
||||||
@@ -15,7 +15,7 @@ export async function fetchTankNames() {
|
|||||||
tankDefinitionsArray.map(async (tank) => {
|
tankDefinitionsArray.map(async (tank) => {
|
||||||
const searchableNameDeburr: I18nString = { locales: {} };
|
const searchableNameDeburr: I18nString = { locales: {} };
|
||||||
|
|
||||||
Object.entries(tank.name).forEach(([key, value]) => {
|
Object.entries(tank.name!).forEach(([key, value]) => {
|
||||||
searchableNameDeburr.locales[key] = deburr(value);
|
searchableNameDeburr.locales[key] = deburr(value);
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -28,8 +28,8 @@ export async function fetchTankNames() {
|
|||||||
?.map((id) =>
|
?.map((id) =>
|
||||||
locales.supported.map(
|
locales.supported.map(
|
||||||
({ locale }) =>
|
({ locale }) =>
|
||||||
camouflageDefinitions.camouflages[id]?.name.locales[locale]
|
camouflageDefinitions.camouflages[id]?.name!.locales[locale],
|
||||||
)
|
),
|
||||||
)
|
)
|
||||||
.flat()
|
.flat()
|
||||||
.filter(Boolean)
|
.filter(Boolean)
|
||||||
@@ -37,7 +37,7 @@ export async function fetchTankNames() {
|
|||||||
.join(" "),
|
.join(" "),
|
||||||
treeType: tank.type,
|
treeType: tank.type,
|
||||||
};
|
};
|
||||||
})
|
}),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -3,14 +3,14 @@ import { BoundingBox } from "../protos";
|
|||||||
export function unionBoundingBox(a: BoundingBox, b: BoundingBox) {
|
export function unionBoundingBox(a: BoundingBox, b: BoundingBox) {
|
||||||
return {
|
return {
|
||||||
min: {
|
min: {
|
||||||
x: Math.min(a.min.x, b.min.x),
|
x: Math.min(a.min!.x, b.min!.x),
|
||||||
y: Math.min(a.min.y, b.min.y),
|
y: Math.min(a.min!.y, b.min!.y),
|
||||||
z: Math.min(a.min.z, b.min.z),
|
z: Math.min(a.min!.z, b.min!.z),
|
||||||
},
|
},
|
||||||
max: {
|
max: {
|
||||||
x: Math.max(a.max.x, b.max.x),
|
x: Math.max(a.max!.x, b.max!.x),
|
||||||
y: Math.max(a.max.y, b.max.y),
|
y: Math.max(a.max!.y, b.max!.y),
|
||||||
z: Math.max(a.max.z, b.max.z),
|
z: Math.max(a.max!.z, b.max!.z),
|
||||||
},
|
},
|
||||||
} satisfies BoundingBox;
|
} satisfies BoundingBox;
|
||||||
}
|
}
|
||||||
@@ -4,44 +4,44 @@ package blitzkit;
|
|||||||
|
|
||||||
message AverageDefinitions {
|
message AverageDefinitions {
|
||||||
map<uint32, AverageDefinitionsEntry> averages = 1;
|
map<uint32, AverageDefinitionsEntry> averages = 1;
|
||||||
required Samples samples = 2;
|
required Samples samples = 2;
|
||||||
required uint64 time = 3;
|
required uint64 time = 3;
|
||||||
}
|
}
|
||||||
|
|
||||||
message AverageDefinitionsEntry {
|
message AverageDefinitionsEntry {
|
||||||
required AverageDefinitionsAllStats mu = 1;
|
required AverageDefinitionsAllStats mu = 1;
|
||||||
required AverageDefinitionsAllStats sigma = 2;
|
required AverageDefinitionsAllStats sigma = 2;
|
||||||
required AverageDefinitionsAllStats r = 3;
|
required AverageDefinitionsAllStats r = 3;
|
||||||
required Samples samples = 4;
|
required Samples samples = 4;
|
||||||
}
|
}
|
||||||
|
|
||||||
message AverageDefinitionsAllStats {
|
message AverageDefinitionsAllStats {
|
||||||
required float battles = 1;
|
required float battles = 1;
|
||||||
required float capture_points = 2;
|
required float capture_points = 2;
|
||||||
required float damage_dealt = 3;
|
required float damage_dealt = 3;
|
||||||
required float damage_received = 4;
|
required float damage_received = 4;
|
||||||
required float dropped_capture_points = 5;
|
required float dropped_capture_points = 5;
|
||||||
required float frags = 6;
|
required float frags = 6;
|
||||||
required float frags8p = 7;
|
required float frags8p = 7;
|
||||||
required float hits = 8;
|
required float hits = 8;
|
||||||
required float losses = 9;
|
required float losses = 9;
|
||||||
required float max_frags = 10;
|
required float max_frags = 10;
|
||||||
required float max_xp = 11;
|
required float max_xp = 11;
|
||||||
required float shots = 12;
|
required float shots = 12;
|
||||||
required float spotted = 13;
|
required float spotted = 13;
|
||||||
required float survived_battles = 14;
|
required float survived_battles = 14;
|
||||||
required float win_and_survived = 15;
|
required float win_and_survived = 15;
|
||||||
required float wins = 16;
|
required float wins = 16;
|
||||||
required float xp = 17;
|
required float xp = 17;
|
||||||
required float battle_life_time = 18;
|
required float battle_life_time = 18;
|
||||||
}
|
}
|
||||||
|
|
||||||
message Samples {
|
message Samples {
|
||||||
required uint32 d_1 = 1;
|
required uint32 d_1 = 1;
|
||||||
required uint32 d_7 = 2;
|
required uint32 d_7 = 2;
|
||||||
required uint32 d_30 = 3;
|
required uint32 d_30 = 3;
|
||||||
required uint32 d_60 = 4;
|
required uint32 d_60 = 4;
|
||||||
required uint32 d_90 = 5;
|
required uint32 d_90 = 5;
|
||||||
required uint32 d_120 = 6;
|
required uint32 d_120 = 6;
|
||||||
required uint32 total = 7;
|
required uint32 total = 7;
|
||||||
}
|
}
|
||||||
@@ -1,8 +1,8 @@
|
|||||||
// Code generated by protoc-gen-ts_proto. DO NOT EDIT.
|
// Code generated by protoc-gen-ts_proto. DO NOT EDIT.
|
||||||
// versions:
|
// versions:
|
||||||
// protoc-gen-ts_proto v2.2.2
|
// protoc-gen-ts_proto v2.11.2
|
||||||
// protoc v5.28.2
|
// protoc v5.28.2
|
||||||
// source: packages/core/src/protos/average_definitions.proto
|
// source: average_definitions.proto
|
||||||
|
|
||||||
/* eslint-disable */
|
/* eslint-disable */
|
||||||
import { BinaryReader, BinaryWriter } from "@bufbuild/protobuf/wire";
|
import { BinaryReader, BinaryWriter } from "@bufbuild/protobuf/wire";
|
||||||
@@ -11,7 +11,7 @@ export const protobufPackage = "blitzkit";
|
|||||||
|
|
||||||
export interface AverageDefinitions {
|
export interface AverageDefinitions {
|
||||||
averages: { [key: number]: AverageDefinitionsEntry };
|
averages: { [key: number]: AverageDefinitionsEntry };
|
||||||
samples: Samples;
|
samples: Samples | undefined;
|
||||||
time: number;
|
time: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -21,10 +21,10 @@ export interface AverageDefinitions_AveragesEntry {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export interface AverageDefinitionsEntry {
|
export interface AverageDefinitionsEntry {
|
||||||
mu: AverageDefinitionsAllStats;
|
mu: AverageDefinitionsAllStats | undefined;
|
||||||
sigma: AverageDefinitionsAllStats;
|
sigma: AverageDefinitionsAllStats | undefined;
|
||||||
r: AverageDefinitionsAllStats;
|
r: AverageDefinitionsAllStats | undefined;
|
||||||
samples: Samples;
|
samples: Samples | undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface AverageDefinitionsAllStats {
|
export interface AverageDefinitionsAllStats {
|
||||||
@@ -58,13 +58,13 @@ export interface Samples {
|
|||||||
total: number;
|
total: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function createBaseAverageDefinitions(): AverageDefinitions {
|
function createBaseAverageDefinitions(): AverageDefinitions {
|
||||||
return { averages: {}, samples: createBaseSamples(), time: 0 };
|
return { averages: {}, samples: undefined, time: 0 };
|
||||||
}
|
}
|
||||||
|
|
||||||
export const AverageDefinitions: MessageFns<AverageDefinitions> = {
|
export const AverageDefinitions: MessageFns<AverageDefinitions> = {
|
||||||
encode(message: AverageDefinitions, writer: BinaryWriter = new BinaryWriter()): BinaryWriter {
|
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();
|
AverageDefinitions_AveragesEntry.encode({ key: key as any, value }, writer.uint32(10).fork()).join();
|
||||||
});
|
});
|
||||||
if (message.samples !== undefined) {
|
if (message.samples !== undefined) {
|
||||||
@@ -78,7 +78,7 @@ export const AverageDefinitions: MessageFns<AverageDefinitions> = {
|
|||||||
|
|
||||||
decode(input: BinaryReader | Uint8Array, length?: number): AverageDefinitions {
|
decode(input: BinaryReader | Uint8Array, length?: number): AverageDefinitions {
|
||||||
const reader = input instanceof BinaryReader ? input : new BinaryReader(input);
|
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();
|
const message = createBaseAverageDefinitions();
|
||||||
while (reader.pos < end) {
|
while (reader.pos < end) {
|
||||||
const tag = reader.uint32();
|
const tag = reader.uint32();
|
||||||
@@ -122,20 +122,23 @@ export const AverageDefinitions: MessageFns<AverageDefinitions> = {
|
|||||||
fromJSON(object: any): AverageDefinitions {
|
fromJSON(object: any): AverageDefinitions {
|
||||||
return {
|
return {
|
||||||
averages: isObject(object.averages)
|
averages: isObject(object.averages)
|
||||||
? Object.entries(object.averages).reduce<{ [key: number]: AverageDefinitionsEntry }>((acc, [key, value]) => {
|
? (globalThis.Object.entries(object.averages) as [string, any][]).reduce(
|
||||||
acc[globalThis.Number(key)] = AverageDefinitionsEntry.fromJSON(value);
|
(acc: { [key: number]: AverageDefinitionsEntry }, [key, value]: [string, any]) => {
|
||||||
return acc;
|
acc[globalThis.Number(key)] = AverageDefinitionsEntry.fromJSON(value);
|
||||||
}, {})
|
return acc;
|
||||||
|
},
|
||||||
|
{},
|
||||||
|
)
|
||||||
: {},
|
: {},
|
||||||
samples: Samples.fromJSON(assertSet("AverageDefinitions.samples", object.samples)),
|
samples: isSet(object.samples) ? Samples.fromJSON(object.samples) : undefined,
|
||||||
time: globalThis.Number(assertSet("AverageDefinitions.time", object.time)),
|
time: isSet(object.time) ? globalThis.Number(object.time) : 0,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
|
||||||
toJSON(message: AverageDefinitions): unknown {
|
toJSON(message: AverageDefinitions): unknown {
|
||||||
const obj: any = {};
|
const obj: any = {};
|
||||||
if (message.averages) {
|
if (message.averages) {
|
||||||
const entries = Object.entries(message.averages);
|
const entries = globalThis.Object.entries(message.averages) as [string, AverageDefinitionsEntry][];
|
||||||
if (entries.length > 0) {
|
if (entries.length > 0) {
|
||||||
obj.averages = {};
|
obj.averages = {};
|
||||||
entries.forEach(([k, v]) => {
|
entries.forEach(([k, v]) => {
|
||||||
@@ -157,8 +160,8 @@ export const AverageDefinitions: MessageFns<AverageDefinitions> = {
|
|||||||
},
|
},
|
||||||
fromPartial<I extends Exact<DeepPartial<AverageDefinitions>, I>>(object: I): AverageDefinitions {
|
fromPartial<I extends Exact<DeepPartial<AverageDefinitions>, I>>(object: I): AverageDefinitions {
|
||||||
const message = createBaseAverageDefinitions();
|
const message = createBaseAverageDefinitions();
|
||||||
message.averages = Object.entries(object.averages ?? {}).reduce<{ [key: number]: AverageDefinitionsEntry }>(
|
message.averages = (globalThis.Object.entries(object.averages ?? {}) as [string, AverageDefinitionsEntry][]).reduce(
|
||||||
(acc, [key, value]) => {
|
(acc: { [key: number]: AverageDefinitionsEntry }, [key, value]: [string, AverageDefinitionsEntry]) => {
|
||||||
if (value !== undefined) {
|
if (value !== undefined) {
|
||||||
acc[globalThis.Number(key)] = AverageDefinitionsEntry.fromPartial(value);
|
acc[globalThis.Number(key)] = AverageDefinitionsEntry.fromPartial(value);
|
||||||
}
|
}
|
||||||
@@ -168,19 +171,19 @@ export const AverageDefinitions: MessageFns<AverageDefinitions> = {
|
|||||||
);
|
);
|
||||||
message.samples = (object.samples !== undefined && object.samples !== null)
|
message.samples = (object.samples !== undefined && object.samples !== null)
|
||||||
? Samples.fromPartial(object.samples)
|
? Samples.fromPartial(object.samples)
|
||||||
: createBaseSamples();
|
: undefined;
|
||||||
message.time = object.time ?? 0;
|
message.time = object.time ?? 0;
|
||||||
return message;
|
return message;
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
export function createBaseAverageDefinitions_AveragesEntry(): AverageDefinitions_AveragesEntry {
|
function createBaseAverageDefinitions_AveragesEntry(): AverageDefinitions_AveragesEntry {
|
||||||
return { key: 0, value: createBaseAverageDefinitionsEntry() };
|
return { key: 0, value: undefined };
|
||||||
}
|
}
|
||||||
|
|
||||||
export const AverageDefinitions_AveragesEntry: MessageFns<AverageDefinitions_AveragesEntry> = {
|
export const AverageDefinitions_AveragesEntry: MessageFns<AverageDefinitions_AveragesEntry> = {
|
||||||
encode(message: AverageDefinitions_AveragesEntry, writer: BinaryWriter = new BinaryWriter()): BinaryWriter {
|
encode(message: AverageDefinitions_AveragesEntry, writer: BinaryWriter = new BinaryWriter()): BinaryWriter {
|
||||||
if (message.key !== undefined) {
|
if (message.key !== 0) {
|
||||||
writer.uint32(8).uint32(message.key);
|
writer.uint32(8).uint32(message.key);
|
||||||
}
|
}
|
||||||
if (message.value !== undefined) {
|
if (message.value !== undefined) {
|
||||||
@@ -191,7 +194,7 @@ export const AverageDefinitions_AveragesEntry: MessageFns<AverageDefinitions_Ave
|
|||||||
|
|
||||||
decode(input: BinaryReader | Uint8Array, length?: number): AverageDefinitions_AveragesEntry {
|
decode(input: BinaryReader | Uint8Array, length?: number): AverageDefinitions_AveragesEntry {
|
||||||
const reader = input instanceof BinaryReader ? input : new BinaryReader(input);
|
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();
|
const message = createBaseAverageDefinitions_AveragesEntry();
|
||||||
while (reader.pos < end) {
|
while (reader.pos < end) {
|
||||||
const tag = reader.uint32();
|
const tag = reader.uint32();
|
||||||
@@ -223,14 +226,14 @@ export const AverageDefinitions_AveragesEntry: MessageFns<AverageDefinitions_Ave
|
|||||||
|
|
||||||
fromJSON(object: any): AverageDefinitions_AveragesEntry {
|
fromJSON(object: any): AverageDefinitions_AveragesEntry {
|
||||||
return {
|
return {
|
||||||
key: globalThis.Number(assertSet("AverageDefinitions_AveragesEntry.key", object.key)),
|
key: isSet(object.key) ? globalThis.Number(object.key) : 0,
|
||||||
value: AverageDefinitionsEntry.fromJSON(assertSet("AverageDefinitions_AveragesEntry.value", object.value)),
|
value: isSet(object.value) ? AverageDefinitionsEntry.fromJSON(object.value) : undefined,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
|
||||||
toJSON(message: AverageDefinitions_AveragesEntry): unknown {
|
toJSON(message: AverageDefinitions_AveragesEntry): unknown {
|
||||||
const obj: any = {};
|
const obj: any = {};
|
||||||
if (message.key !== undefined) {
|
if (message.key !== 0) {
|
||||||
obj.key = Math.round(message.key);
|
obj.key = Math.round(message.key);
|
||||||
}
|
}
|
||||||
if (message.value !== undefined) {
|
if (message.value !== undefined) {
|
||||||
@@ -251,18 +254,13 @@ export const AverageDefinitions_AveragesEntry: MessageFns<AverageDefinitions_Ave
|
|||||||
message.key = object.key ?? 0;
|
message.key = object.key ?? 0;
|
||||||
message.value = (object.value !== undefined && object.value !== null)
|
message.value = (object.value !== undefined && object.value !== null)
|
||||||
? AverageDefinitionsEntry.fromPartial(object.value)
|
? AverageDefinitionsEntry.fromPartial(object.value)
|
||||||
: createBaseAverageDefinitionsEntry();
|
: undefined;
|
||||||
return message;
|
return message;
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
export function createBaseAverageDefinitionsEntry(): AverageDefinitionsEntry {
|
function createBaseAverageDefinitionsEntry(): AverageDefinitionsEntry {
|
||||||
return {
|
return { mu: undefined, sigma: undefined, r: undefined, samples: undefined };
|
||||||
mu: createBaseAverageDefinitionsAllStats(),
|
|
||||||
sigma: createBaseAverageDefinitionsAllStats(),
|
|
||||||
r: createBaseAverageDefinitionsAllStats(),
|
|
||||||
samples: createBaseSamples(),
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export const AverageDefinitionsEntry: MessageFns<AverageDefinitionsEntry> = {
|
export const AverageDefinitionsEntry: MessageFns<AverageDefinitionsEntry> = {
|
||||||
@@ -284,7 +282,7 @@ export const AverageDefinitionsEntry: MessageFns<AverageDefinitionsEntry> = {
|
|||||||
|
|
||||||
decode(input: BinaryReader | Uint8Array, length?: number): AverageDefinitionsEntry {
|
decode(input: BinaryReader | Uint8Array, length?: number): AverageDefinitionsEntry {
|
||||||
const reader = input instanceof BinaryReader ? input : new BinaryReader(input);
|
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();
|
const message = createBaseAverageDefinitionsEntry();
|
||||||
while (reader.pos < end) {
|
while (reader.pos < end) {
|
||||||
const tag = reader.uint32();
|
const tag = reader.uint32();
|
||||||
@@ -332,10 +330,10 @@ export const AverageDefinitionsEntry: MessageFns<AverageDefinitionsEntry> = {
|
|||||||
|
|
||||||
fromJSON(object: any): AverageDefinitionsEntry {
|
fromJSON(object: any): AverageDefinitionsEntry {
|
||||||
return {
|
return {
|
||||||
mu: AverageDefinitionsAllStats.fromJSON(assertSet("AverageDefinitionsEntry.mu", object.mu)),
|
mu: isSet(object.mu) ? AverageDefinitionsAllStats.fromJSON(object.mu) : undefined,
|
||||||
sigma: AverageDefinitionsAllStats.fromJSON(assertSet("AverageDefinitionsEntry.sigma", object.sigma)),
|
sigma: isSet(object.sigma) ? AverageDefinitionsAllStats.fromJSON(object.sigma) : undefined,
|
||||||
r: AverageDefinitionsAllStats.fromJSON(assertSet("AverageDefinitionsEntry.r", object.r)),
|
r: isSet(object.r) ? AverageDefinitionsAllStats.fromJSON(object.r) : undefined,
|
||||||
samples: Samples.fromJSON(assertSet("AverageDefinitionsEntry.samples", object.samples)),
|
samples: isSet(object.samples) ? Samples.fromJSON(object.samples) : undefined,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
|
||||||
@@ -363,21 +361,21 @@ export const AverageDefinitionsEntry: MessageFns<AverageDefinitionsEntry> = {
|
|||||||
const message = createBaseAverageDefinitionsEntry();
|
const message = createBaseAverageDefinitionsEntry();
|
||||||
message.mu = (object.mu !== undefined && object.mu !== null)
|
message.mu = (object.mu !== undefined && object.mu !== null)
|
||||||
? AverageDefinitionsAllStats.fromPartial(object.mu)
|
? AverageDefinitionsAllStats.fromPartial(object.mu)
|
||||||
: createBaseAverageDefinitionsAllStats();
|
: undefined;
|
||||||
message.sigma = (object.sigma !== undefined && object.sigma !== null)
|
message.sigma = (object.sigma !== undefined && object.sigma !== null)
|
||||||
? AverageDefinitionsAllStats.fromPartial(object.sigma)
|
? AverageDefinitionsAllStats.fromPartial(object.sigma)
|
||||||
: createBaseAverageDefinitionsAllStats();
|
: undefined;
|
||||||
message.r = (object.r !== undefined && object.r !== null)
|
message.r = (object.r !== undefined && object.r !== null)
|
||||||
? AverageDefinitionsAllStats.fromPartial(object.r)
|
? AverageDefinitionsAllStats.fromPartial(object.r)
|
||||||
: createBaseAverageDefinitionsAllStats();
|
: undefined;
|
||||||
message.samples = (object.samples !== undefined && object.samples !== null)
|
message.samples = (object.samples !== undefined && object.samples !== null)
|
||||||
? Samples.fromPartial(object.samples)
|
? Samples.fromPartial(object.samples)
|
||||||
: createBaseSamples();
|
: undefined;
|
||||||
return message;
|
return message;
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
export function createBaseAverageDefinitionsAllStats(): AverageDefinitionsAllStats {
|
function createBaseAverageDefinitionsAllStats(): AverageDefinitionsAllStats {
|
||||||
return {
|
return {
|
||||||
battles: 0,
|
battles: 0,
|
||||||
capture_points: 0,
|
capture_points: 0,
|
||||||
@@ -461,7 +459,7 @@ export const AverageDefinitionsAllStats: MessageFns<AverageDefinitionsAllStats>
|
|||||||
|
|
||||||
decode(input: BinaryReader | Uint8Array, length?: number): AverageDefinitionsAllStats {
|
decode(input: BinaryReader | Uint8Array, length?: number): AverageDefinitionsAllStats {
|
||||||
const reader = input instanceof BinaryReader ? input : new BinaryReader(input);
|
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();
|
const message = createBaseAverageDefinitionsAllStats();
|
||||||
while (reader.pos < end) {
|
while (reader.pos < end) {
|
||||||
const tag = reader.uint32();
|
const tag = reader.uint32();
|
||||||
@@ -621,34 +619,60 @@ export const AverageDefinitionsAllStats: MessageFns<AverageDefinitionsAllStats>
|
|||||||
|
|
||||||
fromJSON(object: any): AverageDefinitionsAllStats {
|
fromJSON(object: any): AverageDefinitionsAllStats {
|
||||||
return {
|
return {
|
||||||
battles: globalThis.Number(assertSet("AverageDefinitionsAllStats.battles", object.battles)),
|
battles: isSet(object.battles) ? globalThis.Number(object.battles) : 0,
|
||||||
capture_points: globalThis.Number(assertSet("AverageDefinitionsAllStats.capture_points", object.capture_points)),
|
capture_points: isSet(object.capturePoints)
|
||||||
damage_dealt: globalThis.Number(assertSet("AverageDefinitionsAllStats.damage_dealt", object.damage_dealt)),
|
? globalThis.Number(object.capturePoints)
|
||||||
damage_received: globalThis.Number(
|
: isSet(object.capture_points)
|
||||||
assertSet("AverageDefinitionsAllStats.damage_received", object.damage_received),
|
? globalThis.Number(object.capture_points)
|
||||||
),
|
: 0,
|
||||||
dropped_capture_points: globalThis.Number(
|
damage_dealt: isSet(object.damageDealt)
|
||||||
assertSet("AverageDefinitionsAllStats.dropped_capture_points", object.dropped_capture_points),
|
? globalThis.Number(object.damageDealt)
|
||||||
),
|
: isSet(object.damage_dealt)
|
||||||
frags: globalThis.Number(assertSet("AverageDefinitionsAllStats.frags", object.frags)),
|
? globalThis.Number(object.damage_dealt)
|
||||||
frags8p: globalThis.Number(assertSet("AverageDefinitionsAllStats.frags8p", object.frags8p)),
|
: 0,
|
||||||
hits: globalThis.Number(assertSet("AverageDefinitionsAllStats.hits", object.hits)),
|
damage_received: isSet(object.damageReceived)
|
||||||
losses: globalThis.Number(assertSet("AverageDefinitionsAllStats.losses", object.losses)),
|
? globalThis.Number(object.damageReceived)
|
||||||
max_frags: globalThis.Number(assertSet("AverageDefinitionsAllStats.max_frags", object.max_frags)),
|
: isSet(object.damage_received)
|
||||||
max_xp: globalThis.Number(assertSet("AverageDefinitionsAllStats.max_xp", object.max_xp)),
|
? globalThis.Number(object.damage_received)
|
||||||
shots: globalThis.Number(assertSet("AverageDefinitionsAllStats.shots", object.shots)),
|
: 0,
|
||||||
spotted: globalThis.Number(assertSet("AverageDefinitionsAllStats.spotted", object.spotted)),
|
dropped_capture_points: isSet(object.droppedCapturePoints)
|
||||||
survived_battles: globalThis.Number(
|
? globalThis.Number(object.droppedCapturePoints)
|
||||||
assertSet("AverageDefinitionsAllStats.survived_battles", object.survived_battles),
|
: isSet(object.dropped_capture_points)
|
||||||
),
|
? globalThis.Number(object.dropped_capture_points)
|
||||||
win_and_survived: globalThis.Number(
|
: 0,
|
||||||
assertSet("AverageDefinitionsAllStats.win_and_survived", object.win_and_survived),
|
frags: isSet(object.frags) ? globalThis.Number(object.frags) : 0,
|
||||||
),
|
frags8p: isSet(object.frags8p) ? globalThis.Number(object.frags8p) : 0,
|
||||||
wins: globalThis.Number(assertSet("AverageDefinitionsAllStats.wins", object.wins)),
|
hits: isSet(object.hits) ? globalThis.Number(object.hits) : 0,
|
||||||
xp: globalThis.Number(assertSet("AverageDefinitionsAllStats.xp", object.xp)),
|
losses: isSet(object.losses) ? globalThis.Number(object.losses) : 0,
|
||||||
battle_life_time: globalThis.Number(
|
max_frags: isSet(object.maxFrags)
|
||||||
assertSet("AverageDefinitionsAllStats.battle_life_time", object.battle_life_time),
|
? 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;
|
obj.battles = message.battles;
|
||||||
}
|
}
|
||||||
if (message.capture_points !== 0) {
|
if (message.capture_points !== 0) {
|
||||||
obj.capture_points = message.capture_points;
|
obj.capturePoints = message.capture_points;
|
||||||
}
|
}
|
||||||
if (message.damage_dealt !== 0) {
|
if (message.damage_dealt !== 0) {
|
||||||
obj.damage_dealt = message.damage_dealt;
|
obj.damageDealt = message.damage_dealt;
|
||||||
}
|
}
|
||||||
if (message.damage_received !== 0) {
|
if (message.damage_received !== 0) {
|
||||||
obj.damage_received = message.damage_received;
|
obj.damageReceived = message.damage_received;
|
||||||
}
|
}
|
||||||
if (message.dropped_capture_points !== 0) {
|
if (message.dropped_capture_points !== 0) {
|
||||||
obj.dropped_capture_points = message.dropped_capture_points;
|
obj.droppedCapturePoints = message.dropped_capture_points;
|
||||||
}
|
}
|
||||||
if (message.frags !== 0) {
|
if (message.frags !== 0) {
|
||||||
obj.frags = message.frags;
|
obj.frags = message.frags;
|
||||||
@@ -682,10 +706,10 @@ export const AverageDefinitionsAllStats: MessageFns<AverageDefinitionsAllStats>
|
|||||||
obj.losses = message.losses;
|
obj.losses = message.losses;
|
||||||
}
|
}
|
||||||
if (message.max_frags !== 0) {
|
if (message.max_frags !== 0) {
|
||||||
obj.max_frags = message.max_frags;
|
obj.maxFrags = message.max_frags;
|
||||||
}
|
}
|
||||||
if (message.max_xp !== 0) {
|
if (message.max_xp !== 0) {
|
||||||
obj.max_xp = message.max_xp;
|
obj.maxXp = message.max_xp;
|
||||||
}
|
}
|
||||||
if (message.shots !== 0) {
|
if (message.shots !== 0) {
|
||||||
obj.shots = message.shots;
|
obj.shots = message.shots;
|
||||||
@@ -694,10 +718,10 @@ export const AverageDefinitionsAllStats: MessageFns<AverageDefinitionsAllStats>
|
|||||||
obj.spotted = message.spotted;
|
obj.spotted = message.spotted;
|
||||||
}
|
}
|
||||||
if (message.survived_battles !== 0) {
|
if (message.survived_battles !== 0) {
|
||||||
obj.survived_battles = message.survived_battles;
|
obj.survivedBattles = message.survived_battles;
|
||||||
}
|
}
|
||||||
if (message.win_and_survived !== 0) {
|
if (message.win_and_survived !== 0) {
|
||||||
obj.win_and_survived = message.win_and_survived;
|
obj.winAndSurvived = message.win_and_survived;
|
||||||
}
|
}
|
||||||
if (message.wins !== 0) {
|
if (message.wins !== 0) {
|
||||||
obj.wins = message.wins;
|
obj.wins = message.wins;
|
||||||
@@ -706,7 +730,7 @@ export const AverageDefinitionsAllStats: MessageFns<AverageDefinitionsAllStats>
|
|||||||
obj.xp = message.xp;
|
obj.xp = message.xp;
|
||||||
}
|
}
|
||||||
if (message.battle_life_time !== 0) {
|
if (message.battle_life_time !== 0) {
|
||||||
obj.battle_life_time = message.battle_life_time;
|
obj.battleLifeTime = message.battle_life_time;
|
||||||
}
|
}
|
||||||
return obj;
|
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 };
|
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 {
|
decode(input: BinaryReader | Uint8Array, length?: number): Samples {
|
||||||
const reader = input instanceof BinaryReader ? input : new BinaryReader(input);
|
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();
|
const message = createBaseSamples();
|
||||||
while (reader.pos < end) {
|
while (reader.pos < end) {
|
||||||
const tag = reader.uint32();
|
const tag = reader.uint32();
|
||||||
@@ -842,35 +866,39 @@ export const Samples: MessageFns<Samples> = {
|
|||||||
|
|
||||||
fromJSON(object: any): Samples {
|
fromJSON(object: any): Samples {
|
||||||
return {
|
return {
|
||||||
d_1: globalThis.Number(assertSet("Samples.d_1", object.d_1)),
|
d_1: isSet(object.d1) ? globalThis.Number(object.d1) : isSet(object.d_1) ? globalThis.Number(object.d_1) : 0,
|
||||||
d_7: globalThis.Number(assertSet("Samples.d_7", object.d_7)),
|
d_7: isSet(object.d7) ? globalThis.Number(object.d7) : isSet(object.d_7) ? globalThis.Number(object.d_7) : 0,
|
||||||
d_30: globalThis.Number(assertSet("Samples.d_30", object.d_30)),
|
d_30: isSet(object.d30) ? globalThis.Number(object.d30) : isSet(object.d_30) ? globalThis.Number(object.d_30) : 0,
|
||||||
d_60: globalThis.Number(assertSet("Samples.d_60", object.d_60)),
|
d_60: isSet(object.d60) ? globalThis.Number(object.d60) : isSet(object.d_60) ? globalThis.Number(object.d_60) : 0,
|
||||||
d_90: globalThis.Number(assertSet("Samples.d_90", object.d_90)),
|
d_90: isSet(object.d90) ? globalThis.Number(object.d90) : isSet(object.d_90) ? globalThis.Number(object.d_90) : 0,
|
||||||
d_120: globalThis.Number(assertSet("Samples.d_120", object.d_120)),
|
d_120: isSet(object.d120)
|
||||||
total: globalThis.Number(assertSet("Samples.total", object.total)),
|
? 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 {
|
toJSON(message: Samples): unknown {
|
||||||
const obj: any = {};
|
const obj: any = {};
|
||||||
if (message.d_1 !== 0) {
|
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) {
|
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) {
|
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) {
|
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) {
|
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) {
|
if (message.d_120 !== 0) {
|
||||||
obj.d_120 = Math.round(message.d_120);
|
obj.d120 = Math.round(message.d_120);
|
||||||
}
|
}
|
||||||
if (message.total !== 0) {
|
if (message.total !== 0) {
|
||||||
obj.total = Math.round(message.total);
|
obj.total = Math.round(message.total);
|
||||||
@@ -926,14 +954,6 @@ function isSet(value: any): boolean {
|
|||||||
return value !== null && value !== undefined;
|
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> {
|
export interface MessageFns<T> {
|
||||||
encode(message: T, writer?: BinaryWriter): BinaryWriter;
|
encode(message: T, writer?: BinaryWriter): BinaryWriter;
|
||||||
decode(input: BinaryReader | Uint8Array, length?: number): T;
|
decode(input: BinaryReader | Uint8Array, length?: number): T;
|
||||||
|
|||||||
@@ -2,15 +2,15 @@ syntax = "proto2";
|
|||||||
|
|
||||||
package blitzkit;
|
package blitzkit;
|
||||||
|
|
||||||
import "packages/core/src/protos/i18n.proto";
|
import "i18n.proto";
|
||||||
|
|
||||||
message CamouflageDefinitions {
|
message CamouflageDefinitions {
|
||||||
map<uint32, Camouflage> camouflages = 1;
|
map<uint32, Camouflage> camouflages = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
message Camouflage {
|
message Camouflage {
|
||||||
required uint32 id = 1;
|
required uint32 id = 1;
|
||||||
required I18nString name = 2;
|
required I18nString name = 2;
|
||||||
optional I18nString tank_name = 3;
|
optional I18nString tank_name = 3;
|
||||||
optional I18nString tank_name_full = 4;
|
optional I18nString tank_name_full = 4;
|
||||||
}
|
}
|
||||||
@@ -1,14 +1,14 @@
|
|||||||
// Code generated by protoc-gen-ts_proto. DO NOT EDIT.
|
// Code generated by protoc-gen-ts_proto. DO NOT EDIT.
|
||||||
// versions:
|
// versions:
|
||||||
// protoc-gen-ts_proto v2.2.2
|
// protoc-gen-ts_proto v2.11.2
|
||||||
// protoc v5.28.2
|
// protoc v5.28.2
|
||||||
// source: packages/core/src/protos/camouflage_definitions.proto
|
// source: camouflage_definitions.proto
|
||||||
|
|
||||||
/* eslint-disable */
|
/* eslint-disable */
|
||||||
import { BinaryReader, BinaryWriter } from '@bufbuild/protobuf/wire';
|
import { BinaryReader, BinaryWriter } from "@bufbuild/protobuf/wire";
|
||||||
import { createBaseI18nString, I18nString } from './i18n';
|
import { I18nString } from "./i18n";
|
||||||
|
|
||||||
export const protobufPackage = 'blitzkit';
|
export const protobufPackage = "blitzkit";
|
||||||
|
|
||||||
export interface CamouflageDefinitions {
|
export interface CamouflageDefinitions {
|
||||||
camouflages: { [key: number]: Camouflage };
|
camouflages: { [key: number]: Camouflage };
|
||||||
@@ -21,36 +21,26 @@ export interface CamouflageDefinitions_CamouflagesEntry {
|
|||||||
|
|
||||||
export interface Camouflage {
|
export interface Camouflage {
|
||||||
id: number;
|
id: number;
|
||||||
name: I18nString;
|
name: I18nString | undefined;
|
||||||
tank_name?: I18nString;
|
tank_name?: I18nString | undefined;
|
||||||
tank_name_full?: I18nString;
|
tank_name_full?: I18nString | undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function createBaseCamouflageDefinitions(): CamouflageDefinitions {
|
function createBaseCamouflageDefinitions(): CamouflageDefinitions {
|
||||||
return { camouflages: {} };
|
return { camouflages: {} };
|
||||||
}
|
}
|
||||||
|
|
||||||
export const CamouflageDefinitions: MessageFns<CamouflageDefinitions> = {
|
export const CamouflageDefinitions: MessageFns<CamouflageDefinitions> = {
|
||||||
encode(
|
encode(message: CamouflageDefinitions, writer: BinaryWriter = new BinaryWriter()): BinaryWriter {
|
||||||
message: CamouflageDefinitions,
|
globalThis.Object.entries(message.camouflages).forEach(([key, value]: [string, Camouflage]) => {
|
||||||
writer: BinaryWriter = new BinaryWriter(),
|
CamouflageDefinitions_CamouflagesEntry.encode({ key: key as any, value }, writer.uint32(10).fork()).join();
|
||||||
): BinaryWriter {
|
|
||||||
Object.entries(message.camouflages).forEach(([key, value]) => {
|
|
||||||
CamouflageDefinitions_CamouflagesEntry.encode(
|
|
||||||
{ key: key as any, value },
|
|
||||||
writer.uint32(10).fork(),
|
|
||||||
).join();
|
|
||||||
});
|
});
|
||||||
return writer;
|
return writer;
|
||||||
},
|
},
|
||||||
|
|
||||||
decode(
|
decode(input: BinaryReader | Uint8Array, length?: number): CamouflageDefinitions {
|
||||||
input: BinaryReader | Uint8Array,
|
const reader = input instanceof BinaryReader ? input : new BinaryReader(input);
|
||||||
length?: number,
|
const end = length === undefined ? reader.len : reader.pos + length;
|
||||||
): CamouflageDefinitions {
|
|
||||||
const reader =
|
|
||||||
input instanceof BinaryReader ? input : new BinaryReader(input);
|
|
||||||
let end = length === undefined ? reader.len : reader.pos + length;
|
|
||||||
const message = createBaseCamouflageDefinitions();
|
const message = createBaseCamouflageDefinitions();
|
||||||
while (reader.pos < end) {
|
while (reader.pos < end) {
|
||||||
const tag = reader.uint32();
|
const tag = reader.uint32();
|
||||||
@@ -60,10 +50,7 @@ export const CamouflageDefinitions: MessageFns<CamouflageDefinitions> = {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
const entry1 = CamouflageDefinitions_CamouflagesEntry.decode(
|
const entry1 = CamouflageDefinitions_CamouflagesEntry.decode(reader, reader.uint32());
|
||||||
reader,
|
|
||||||
reader.uint32(),
|
|
||||||
);
|
|
||||||
if (entry1.value !== undefined) {
|
if (entry1.value !== undefined) {
|
||||||
message.camouflages[entry1.key] = entry1.value;
|
message.camouflages[entry1.key] = entry1.value;
|
||||||
}
|
}
|
||||||
@@ -81,12 +68,13 @@ export const CamouflageDefinitions: MessageFns<CamouflageDefinitions> = {
|
|||||||
fromJSON(object: any): CamouflageDefinitions {
|
fromJSON(object: any): CamouflageDefinitions {
|
||||||
return {
|
return {
|
||||||
camouflages: isObject(object.camouflages)
|
camouflages: isObject(object.camouflages)
|
||||||
? Object.entries(object.camouflages).reduce<{
|
? (globalThis.Object.entries(object.camouflages) as [string, any][]).reduce(
|
||||||
[key: number]: Camouflage;
|
(acc: { [key: number]: Camouflage }, [key, value]: [string, any]) => {
|
||||||
}>((acc, [key, value]) => {
|
|
||||||
acc[globalThis.Number(key)] = Camouflage.fromJSON(value);
|
acc[globalThis.Number(key)] = Camouflage.fromJSON(value);
|
||||||
return acc;
|
return acc;
|
||||||
}, {})
|
},
|
||||||
|
{},
|
||||||
|
)
|
||||||
: {},
|
: {},
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
@@ -94,7 +82,7 @@ export const CamouflageDefinitions: MessageFns<CamouflageDefinitions> = {
|
|||||||
toJSON(message: CamouflageDefinitions): unknown {
|
toJSON(message: CamouflageDefinitions): unknown {
|
||||||
const obj: any = {};
|
const obj: any = {};
|
||||||
if (message.camouflages) {
|
if (message.camouflages) {
|
||||||
const entries = Object.entries(message.camouflages);
|
const entries = globalThis.Object.entries(message.camouflages) as [string, Camouflage][];
|
||||||
if (entries.length > 0) {
|
if (entries.length > 0) {
|
||||||
obj.camouflages = {};
|
obj.camouflages = {};
|
||||||
entries.forEach(([k, v]) => {
|
entries.forEach(([k, v]) => {
|
||||||
@@ -105,141 +93,112 @@ export const CamouflageDefinitions: MessageFns<CamouflageDefinitions> = {
|
|||||||
return obj;
|
return obj;
|
||||||
},
|
},
|
||||||
|
|
||||||
create<I extends Exact<DeepPartial<CamouflageDefinitions>, I>>(
|
create<I extends Exact<DeepPartial<CamouflageDefinitions>, I>>(base?: I): CamouflageDefinitions {
|
||||||
base?: I,
|
|
||||||
): CamouflageDefinitions {
|
|
||||||
return CamouflageDefinitions.fromPartial(base ?? ({} as any));
|
return CamouflageDefinitions.fromPartial(base ?? ({} as any));
|
||||||
},
|
},
|
||||||
fromPartial<I extends Exact<DeepPartial<CamouflageDefinitions>, I>>(
|
fromPartial<I extends Exact<DeepPartial<CamouflageDefinitions>, I>>(object: I): CamouflageDefinitions {
|
||||||
object: I,
|
|
||||||
): CamouflageDefinitions {
|
|
||||||
const message = createBaseCamouflageDefinitions();
|
const message = createBaseCamouflageDefinitions();
|
||||||
message.camouflages = Object.entries(object.camouflages ?? {}).reduce<{
|
message.camouflages = (globalThis.Object.entries(object.camouflages ?? {}) as [string, Camouflage][]).reduce(
|
||||||
[key: number]: Camouflage;
|
(acc: { [key: number]: Camouflage }, [key, value]: [string, Camouflage]) => {
|
||||||
}>((acc, [key, value]) => {
|
if (value !== undefined) {
|
||||||
if (value !== undefined) {
|
acc[globalThis.Number(key)] = Camouflage.fromPartial(value);
|
||||||
acc[globalThis.Number(key)] = Camouflage.fromPartial(value);
|
}
|
||||||
}
|
return acc;
|
||||||
return acc;
|
},
|
||||||
}, {});
|
{},
|
||||||
|
);
|
||||||
return message;
|
return message;
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
export function createBaseCamouflageDefinitions_CamouflagesEntry(): CamouflageDefinitions_CamouflagesEntry {
|
function createBaseCamouflageDefinitions_CamouflagesEntry(): CamouflageDefinitions_CamouflagesEntry {
|
||||||
return { key: 0, value: createBaseCamouflage() };
|
return { key: 0, value: undefined };
|
||||||
}
|
}
|
||||||
|
|
||||||
export const CamouflageDefinitions_CamouflagesEntry: MessageFns<CamouflageDefinitions_CamouflagesEntry> =
|
export const CamouflageDefinitions_CamouflagesEntry: MessageFns<CamouflageDefinitions_CamouflagesEntry> = {
|
||||||
{
|
encode(message: CamouflageDefinitions_CamouflagesEntry, writer: BinaryWriter = new BinaryWriter()): BinaryWriter {
|
||||||
encode(
|
if (message.key !== 0) {
|
||||||
message: CamouflageDefinitions_CamouflagesEntry,
|
writer.uint32(8).uint32(message.key);
|
||||||
writer: BinaryWriter = new BinaryWriter(),
|
}
|
||||||
): BinaryWriter {
|
if (message.value !== undefined) {
|
||||||
if (message.key !== undefined) {
|
Camouflage.encode(message.value, writer.uint32(18).fork()).join();
|
||||||
writer.uint32(8).uint32(message.key);
|
}
|
||||||
}
|
return writer;
|
||||||
if (message.value !== undefined) {
|
},
|
||||||
Camouflage.encode(message.value, writer.uint32(18).fork()).join();
|
|
||||||
}
|
|
||||||
return writer;
|
|
||||||
},
|
|
||||||
|
|
||||||
decode(
|
decode(input: BinaryReader | Uint8Array, length?: number): CamouflageDefinitions_CamouflagesEntry {
|
||||||
input: BinaryReader | Uint8Array,
|
const reader = input instanceof BinaryReader ? input : new BinaryReader(input);
|
||||||
length?: number,
|
const end = length === undefined ? reader.len : reader.pos + length;
|
||||||
): CamouflageDefinitions_CamouflagesEntry {
|
const message = createBaseCamouflageDefinitions_CamouflagesEntry();
|
||||||
const reader =
|
while (reader.pos < end) {
|
||||||
input instanceof BinaryReader ? input : new BinaryReader(input);
|
const tag = reader.uint32();
|
||||||
let end = length === undefined ? reader.len : reader.pos + length;
|
switch (tag >>> 3) {
|
||||||
const message = createBaseCamouflageDefinitions_CamouflagesEntry();
|
case 1: {
|
||||||
while (reader.pos < end) {
|
if (tag !== 8) {
|
||||||
const tag = reader.uint32();
|
break;
|
||||||
switch (tag >>> 3) {
|
|
||||||
case 1: {
|
|
||||||
if (tag !== 8) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
message.key = reader.uint32();
|
|
||||||
continue;
|
|
||||||
}
|
}
|
||||||
case 2: {
|
|
||||||
if (tag !== 18) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
message.value = Camouflage.decode(reader, reader.uint32());
|
message.key = reader.uint32();
|
||||||
continue;
|
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;
|
if ((tag & 7) === 4 || tag === 0) {
|
||||||
},
|
break;
|
||||||
|
|
||||||
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 (message.value !== undefined) {
|
reader.skip(tag & 7);
|
||||||
obj.value = Camouflage.toJSON(message.value);
|
}
|
||||||
}
|
return message;
|
||||||
return obj;
|
},
|
||||||
},
|
|
||||||
|
|
||||||
create<
|
fromJSON(object: any): CamouflageDefinitions_CamouflagesEntry {
|
||||||
I extends Exact<DeepPartial<CamouflageDefinitions_CamouflagesEntry>, I>,
|
return {
|
||||||
>(base?: I): CamouflageDefinitions_CamouflagesEntry {
|
key: isSet(object.key) ? globalThis.Number(object.key) : 0,
|
||||||
return CamouflageDefinitions_CamouflagesEntry.fromPartial(
|
value: isSet(object.value) ? Camouflage.fromJSON(object.value) : undefined,
|
||||||
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;
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
export function createBaseCamouflage(): Camouflage {
|
toJSON(message: CamouflageDefinitions_CamouflagesEntry): unknown {
|
||||||
return {
|
const obj: any = {};
|
||||||
id: 0,
|
if (message.key !== 0) {
|
||||||
name: createBaseI18nString(),
|
obj.key = Math.round(message.key);
|
||||||
tank_name: undefined,
|
}
|
||||||
tank_name_full: undefined,
|
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> = {
|
export const Camouflage: MessageFns<Camouflage> = {
|
||||||
encode(
|
encode(message: Camouflage, writer: BinaryWriter = new BinaryWriter()): BinaryWriter {
|
||||||
message: Camouflage,
|
|
||||||
writer: BinaryWriter = new BinaryWriter(),
|
|
||||||
): BinaryWriter {
|
|
||||||
if (message.id !== 0) {
|
if (message.id !== 0) {
|
||||||
writer.uint32(8).uint32(message.id);
|
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();
|
I18nString.encode(message.tank_name, writer.uint32(26).fork()).join();
|
||||||
}
|
}
|
||||||
if (message.tank_name_full !== undefined) {
|
if (message.tank_name_full !== undefined) {
|
||||||
I18nString.encode(
|
I18nString.encode(message.tank_name_full, writer.uint32(34).fork()).join();
|
||||||
message.tank_name_full,
|
|
||||||
writer.uint32(34).fork(),
|
|
||||||
).join();
|
|
||||||
}
|
}
|
||||||
return writer;
|
return writer;
|
||||||
},
|
},
|
||||||
|
|
||||||
decode(input: BinaryReader | Uint8Array, length?: number): Camouflage {
|
decode(input: BinaryReader | Uint8Array, length?: number): Camouflage {
|
||||||
const reader =
|
const reader = input instanceof BinaryReader ? input : new BinaryReader(input);
|
||||||
input instanceof BinaryReader ? input : new BinaryReader(input);
|
const end = length === undefined ? reader.len : reader.pos + length;
|
||||||
let end = length === undefined ? reader.len : reader.pos + length;
|
|
||||||
const message = createBaseCamouflage();
|
const message = createBaseCamouflage();
|
||||||
while (reader.pos < end) {
|
while (reader.pos < end) {
|
||||||
const tag = reader.uint32();
|
const tag = reader.uint32();
|
||||||
@@ -309,12 +264,16 @@ export const Camouflage: MessageFns<Camouflage> = {
|
|||||||
|
|
||||||
fromJSON(object: any): Camouflage {
|
fromJSON(object: any): Camouflage {
|
||||||
return {
|
return {
|
||||||
id: globalThis.Number(assertSet('Camouflage.id', object.id)),
|
id: isSet(object.id) ? globalThis.Number(object.id) : 0,
|
||||||
name: I18nString.fromJSON(assertSet('Camouflage.name', object.name)),
|
name: isSet(object.name) ? I18nString.fromJSON(object.name) : undefined,
|
||||||
tank_name: isSet(object.tank_name)
|
tank_name: isSet(object.tankName)
|
||||||
|
? I18nString.fromJSON(object.tankName)
|
||||||
|
: isSet(object.tank_name)
|
||||||
? I18nString.fromJSON(object.tank_name)
|
? I18nString.fromJSON(object.tank_name)
|
||||||
: undefined,
|
: 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)
|
? I18nString.fromJSON(object.tank_name_full)
|
||||||
: undefined,
|
: undefined,
|
||||||
};
|
};
|
||||||
@@ -329,10 +288,10 @@ export const Camouflage: MessageFns<Camouflage> = {
|
|||||||
obj.name = I18nString.toJSON(message.name);
|
obj.name = I18nString.toJSON(message.name);
|
||||||
}
|
}
|
||||||
if (message.tank_name !== undefined) {
|
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) {
|
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;
|
return obj;
|
||||||
},
|
},
|
||||||
@@ -340,71 +299,43 @@ export const Camouflage: MessageFns<Camouflage> = {
|
|||||||
create<I extends Exact<DeepPartial<Camouflage>, I>>(base?: I): Camouflage {
|
create<I extends Exact<DeepPartial<Camouflage>, I>>(base?: I): Camouflage {
|
||||||
return Camouflage.fromPartial(base ?? ({} as any));
|
return Camouflage.fromPartial(base ?? ({} as any));
|
||||||
},
|
},
|
||||||
fromPartial<I extends Exact<DeepPartial<Camouflage>, I>>(
|
fromPartial<I extends Exact<DeepPartial<Camouflage>, I>>(object: I): Camouflage {
|
||||||
object: I,
|
|
||||||
): Camouflage {
|
|
||||||
const message = createBaseCamouflage();
|
const message = createBaseCamouflage();
|
||||||
message.id = object.id ?? 0;
|
message.id = object.id ?? 0;
|
||||||
message.name =
|
message.name = (object.name !== undefined && object.name !== null)
|
||||||
object.name !== undefined && object.name !== null
|
? I18nString.fromPartial(object.name)
|
||||||
? I18nString.fromPartial(object.name)
|
: undefined;
|
||||||
: createBaseI18nString();
|
message.tank_name = (object.tank_name !== undefined && object.tank_name !== null)
|
||||||
message.tank_name =
|
? I18nString.fromPartial(object.tank_name)
|
||||||
object.tank_name !== undefined && object.tank_name !== null
|
: undefined;
|
||||||
? I18nString.fromPartial(object.tank_name)
|
message.tank_name_full = (object.tank_name_full !== undefined && object.tank_name_full !== null)
|
||||||
: undefined;
|
? I18nString.fromPartial(object.tank_name_full)
|
||||||
message.tank_name_full =
|
: undefined;
|
||||||
object.tank_name_full !== undefined && object.tank_name_full !== null
|
|
||||||
? I18nString.fromPartial(object.tank_name_full)
|
|
||||||
: undefined;
|
|
||||||
return message;
|
return message;
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
type Builtin =
|
type Builtin = Date | Function | Uint8Array | string | number | boolean | undefined;
|
||||||
| Date
|
|
||||||
| Function
|
|
||||||
| Uint8Array
|
|
||||||
| string
|
|
||||||
| number
|
|
||||||
| boolean
|
|
||||||
| undefined;
|
|
||||||
|
|
||||||
export type DeepPartial<T> = T extends Builtin
|
export type DeepPartial<T> = T extends Builtin ? T
|
||||||
? T
|
: T extends globalThis.Array<infer U> ? globalThis.Array<DeepPartial<U>>
|
||||||
: T extends globalThis.Array<infer U>
|
: T extends ReadonlyArray<infer U> ? ReadonlyArray<DeepPartial<U>>
|
||||||
? globalThis.Array<DeepPartial<U>>
|
: T extends { $case: string; value: unknown } ? { $case: T["$case"]; value?: DeepPartial<T["value"]> }
|
||||||
: T extends ReadonlyArray<infer U>
|
: T extends {} ? { [K in keyof T]?: DeepPartial<T[K]> }
|
||||||
? ReadonlyArray<DeepPartial<U>>
|
: Partial<T>;
|
||||||
: 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;
|
type KeysOfUnion<T> = T extends T ? keyof T : never;
|
||||||
export type Exact<P, I extends P> = P extends Builtin
|
export type Exact<P, I extends P> = P extends Builtin ? P
|
||||||
? P
|
: P & { [K in keyof P]: Exact<P[K], I[K]> } & { [K in Exclude<keyof I, KeysOfUnion<P>>]: never };
|
||||||
: P & { [K in keyof P]: Exact<P[K], I[K]> } & {
|
|
||||||
[K in Exclude<keyof I, KeysOfUnion<P>>]: never;
|
|
||||||
};
|
|
||||||
|
|
||||||
function isObject(value: any): boolean {
|
function isObject(value: any): boolean {
|
||||||
return typeof value === 'object' && value !== null;
|
return typeof value === "object" && value !== null;
|
||||||
}
|
}
|
||||||
|
|
||||||
function isSet(value: any): boolean {
|
function isSet(value: any): boolean {
|
||||||
return value !== null && value !== undefined;
|
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> {
|
export interface MessageFns<T> {
|
||||||
encode(message: T, writer?: BinaryWriter): BinaryWriter;
|
encode(message: T, writer?: BinaryWriter): BinaryWriter;
|
||||||
decode(input: BinaryReader | Uint8Array, length?: number): T;
|
decode(input: BinaryReader | Uint8Array, length?: number): T;
|
||||||
|
|||||||
@@ -2,28 +2,28 @@ syntax = "proto2";
|
|||||||
|
|
||||||
package blitzkit;
|
package blitzkit;
|
||||||
|
|
||||||
import "packages/core/src/protos/i18n.proto";
|
import "i18n.proto";
|
||||||
|
|
||||||
message ConsumableDefinitions {
|
message ConsumableDefinitions {
|
||||||
map<uint32, Consumable> consumables = 1;
|
map<uint32, Consumable> consumables = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
message Consumable {
|
message Consumable {
|
||||||
required uint32 id = 1;
|
required uint32 id = 1;
|
||||||
required I18nString name = 2;
|
required I18nString name = 2;
|
||||||
required uint32 cooldown = 3;
|
required uint32 cooldown = 3;
|
||||||
optional float duration = 4;
|
optional float duration = 4;
|
||||||
required bool game_mode_exclusive = 5;
|
required bool game_mode_exclusive = 5;
|
||||||
repeated ConsumableTankFilter include = 6;
|
repeated ConsumableTankFilter include = 6;
|
||||||
repeated ConsumableTankFilter exclude = 7;
|
repeated ConsumableTankFilter exclude = 7;
|
||||||
}
|
}
|
||||||
|
|
||||||
message ConsumableTankFilter {
|
message ConsumableTankFilter {
|
||||||
oneof filter_type {
|
oneof filter_type {
|
||||||
ConsumableTankTierFilter tiers = 1;
|
ConsumableTankTierFilter tiers = 1;
|
||||||
ConsumableTankIdsFilter ids = 2;
|
ConsumableTankIdsFilter ids = 2;
|
||||||
ConsumableTankCategoryFilter categories = 3;
|
ConsumableTankCategoryFilter categories = 3;
|
||||||
ConsumableTankNationFilter nations = 4;
|
ConsumableTankNationFilter nations = 4;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,24 +1,24 @@
|
|||||||
// Code generated by protoc-gen-ts_proto. DO NOT EDIT.
|
// Code generated by protoc-gen-ts_proto. DO NOT EDIT.
|
||||||
// versions:
|
// versions:
|
||||||
// protoc-gen-ts_proto v2.2.2
|
// protoc-gen-ts_proto v2.11.2
|
||||||
// protoc v5.28.2
|
// protoc v5.28.2
|
||||||
// source: packages/core/src/protos/consumable_definitions.proto
|
// source: consumable_definitions.proto
|
||||||
|
|
||||||
/* eslint-disable */
|
/* eslint-disable */
|
||||||
import { BinaryReader, BinaryWriter } from "@bufbuild/protobuf/wire";
|
import { BinaryReader, BinaryWriter } from "@bufbuild/protobuf/wire";
|
||||||
import { createBaseI18nString, I18nString } from "./i18n";
|
import { I18nString } from "./i18n";
|
||||||
|
|
||||||
export const protobufPackage = "blitzkit";
|
export const protobufPackage = "blitzkit";
|
||||||
|
|
||||||
export enum ConsumableTankCategoryFilterCategory {
|
export enum ConsumableTankCategoryFilterCategory {
|
||||||
CLIP = 0,
|
CONSUMABLE_TANK_CATEGORY_FILTER_CATEGORY_CLIP = 0,
|
||||||
}
|
}
|
||||||
|
|
||||||
export function consumableTankCategoryFilterCategoryFromJSON(object: any): ConsumableTankCategoryFilterCategory {
|
export function consumableTankCategoryFilterCategoryFromJSON(object: any): ConsumableTankCategoryFilterCategory {
|
||||||
switch (object) {
|
switch (object) {
|
||||||
case 0:
|
case 0:
|
||||||
case "CONSUMABLE_TANK_CATEGORY_FILTER_CATEGORY_CLIP":
|
case "CONSUMABLE_TANK_CATEGORY_FILTER_CATEGORY_CLIP":
|
||||||
return ConsumableTankCategoryFilterCategory.CLIP;
|
return ConsumableTankCategoryFilterCategory.CONSUMABLE_TANK_CATEGORY_FILTER_CATEGORY_CLIP;
|
||||||
default:
|
default:
|
||||||
throw new globalThis.Error(
|
throw new globalThis.Error(
|
||||||
"Unrecognized enum value " + object + " for enum ConsumableTankCategoryFilterCategory",
|
"Unrecognized enum value " + object + " for enum ConsumableTankCategoryFilterCategory",
|
||||||
@@ -28,7 +28,7 @@ export function consumableTankCategoryFilterCategoryFromJSON(object: any): Consu
|
|||||||
|
|
||||||
export function consumableTankCategoryFilterCategoryToJSON(object: ConsumableTankCategoryFilterCategory): string {
|
export function consumableTankCategoryFilterCategoryToJSON(object: ConsumableTankCategoryFilterCategory): string {
|
||||||
switch (object) {
|
switch (object) {
|
||||||
case ConsumableTankCategoryFilterCategory.CLIP:
|
case ConsumableTankCategoryFilterCategory.CONSUMABLE_TANK_CATEGORY_FILTER_CATEGORY_CLIP:
|
||||||
return "CONSUMABLE_TANK_CATEGORY_FILTER_CATEGORY_CLIP";
|
return "CONSUMABLE_TANK_CATEGORY_FILTER_CATEGORY_CLIP";
|
||||||
default:
|
default:
|
||||||
throw new globalThis.Error(
|
throw new globalThis.Error(
|
||||||
@@ -48,7 +48,7 @@ export interface ConsumableDefinitions_ConsumablesEntry {
|
|||||||
|
|
||||||
export interface Consumable {
|
export interface Consumable {
|
||||||
id: number;
|
id: number;
|
||||||
name: I18nString;
|
name: I18nString | undefined;
|
||||||
cooldown: number;
|
cooldown: number;
|
||||||
duration?: number | undefined;
|
duration?: number | undefined;
|
||||||
game_mode_exclusive: boolean;
|
game_mode_exclusive: boolean;
|
||||||
@@ -82,13 +82,13 @@ export interface ConsumableTankNationFilter {
|
|||||||
nations: string[];
|
nations: string[];
|
||||||
}
|
}
|
||||||
|
|
||||||
export function createBaseConsumableDefinitions(): ConsumableDefinitions {
|
function createBaseConsumableDefinitions(): ConsumableDefinitions {
|
||||||
return { consumables: {} };
|
return { consumables: {} };
|
||||||
}
|
}
|
||||||
|
|
||||||
export const ConsumableDefinitions: MessageFns<ConsumableDefinitions> = {
|
export const ConsumableDefinitions: MessageFns<ConsumableDefinitions> = {
|
||||||
encode(message: ConsumableDefinitions, writer: BinaryWriter = new BinaryWriter()): BinaryWriter {
|
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();
|
ConsumableDefinitions_ConsumablesEntry.encode({ key: key as any, value }, writer.uint32(10).fork()).join();
|
||||||
});
|
});
|
||||||
return writer;
|
return writer;
|
||||||
@@ -96,7 +96,7 @@ export const ConsumableDefinitions: MessageFns<ConsumableDefinitions> = {
|
|||||||
|
|
||||||
decode(input: BinaryReader | Uint8Array, length?: number): ConsumableDefinitions {
|
decode(input: BinaryReader | Uint8Array, length?: number): ConsumableDefinitions {
|
||||||
const reader = input instanceof BinaryReader ? input : new BinaryReader(input);
|
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();
|
const message = createBaseConsumableDefinitions();
|
||||||
while (reader.pos < end) {
|
while (reader.pos < end) {
|
||||||
const tag = reader.uint32();
|
const tag = reader.uint32();
|
||||||
@@ -124,10 +124,13 @@ export const ConsumableDefinitions: MessageFns<ConsumableDefinitions> = {
|
|||||||
fromJSON(object: any): ConsumableDefinitions {
|
fromJSON(object: any): ConsumableDefinitions {
|
||||||
return {
|
return {
|
||||||
consumables: isObject(object.consumables)
|
consumables: isObject(object.consumables)
|
||||||
? Object.entries(object.consumables).reduce<{ [key: number]: Consumable }>((acc, [key, value]) => {
|
? (globalThis.Object.entries(object.consumables) as [string, any][]).reduce(
|
||||||
acc[globalThis.Number(key)] = Consumable.fromJSON(value);
|
(acc: { [key: number]: Consumable }, [key, value]: [string, any]) => {
|
||||||
return acc;
|
acc[globalThis.Number(key)] = Consumable.fromJSON(value);
|
||||||
}, {})
|
return acc;
|
||||||
|
},
|
||||||
|
{},
|
||||||
|
)
|
||||||
: {},
|
: {},
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
@@ -135,7 +138,7 @@ export const ConsumableDefinitions: MessageFns<ConsumableDefinitions> = {
|
|||||||
toJSON(message: ConsumableDefinitions): unknown {
|
toJSON(message: ConsumableDefinitions): unknown {
|
||||||
const obj: any = {};
|
const obj: any = {};
|
||||||
if (message.consumables) {
|
if (message.consumables) {
|
||||||
const entries = Object.entries(message.consumables);
|
const entries = globalThis.Object.entries(message.consumables) as [string, Consumable][];
|
||||||
if (entries.length > 0) {
|
if (entries.length > 0) {
|
||||||
obj.consumables = {};
|
obj.consumables = {};
|
||||||
entries.forEach(([k, v]) => {
|
entries.forEach(([k, v]) => {
|
||||||
@@ -151,8 +154,8 @@ export const ConsumableDefinitions: MessageFns<ConsumableDefinitions> = {
|
|||||||
},
|
},
|
||||||
fromPartial<I extends Exact<DeepPartial<ConsumableDefinitions>, I>>(object: I): ConsumableDefinitions {
|
fromPartial<I extends Exact<DeepPartial<ConsumableDefinitions>, I>>(object: I): ConsumableDefinitions {
|
||||||
const message = createBaseConsumableDefinitions();
|
const message = createBaseConsumableDefinitions();
|
||||||
message.consumables = Object.entries(object.consumables ?? {}).reduce<{ [key: number]: Consumable }>(
|
message.consumables = (globalThis.Object.entries(object.consumables ?? {}) as [string, Consumable][]).reduce(
|
||||||
(acc, [key, value]) => {
|
(acc: { [key: number]: Consumable }, [key, value]: [string, Consumable]) => {
|
||||||
if (value !== undefined) {
|
if (value !== undefined) {
|
||||||
acc[globalThis.Number(key)] = Consumable.fromPartial(value);
|
acc[globalThis.Number(key)] = Consumable.fromPartial(value);
|
||||||
}
|
}
|
||||||
@@ -164,13 +167,13 @@ export const ConsumableDefinitions: MessageFns<ConsumableDefinitions> = {
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
export function createBaseConsumableDefinitions_ConsumablesEntry(): ConsumableDefinitions_ConsumablesEntry {
|
function createBaseConsumableDefinitions_ConsumablesEntry(): ConsumableDefinitions_ConsumablesEntry {
|
||||||
return { key: 0, value: createBaseConsumable() };
|
return { key: 0, value: undefined };
|
||||||
}
|
}
|
||||||
|
|
||||||
export const ConsumableDefinitions_ConsumablesEntry: MessageFns<ConsumableDefinitions_ConsumablesEntry> = {
|
export const ConsumableDefinitions_ConsumablesEntry: MessageFns<ConsumableDefinitions_ConsumablesEntry> = {
|
||||||
encode(message: ConsumableDefinitions_ConsumablesEntry, writer: BinaryWriter = new BinaryWriter()): BinaryWriter {
|
encode(message: ConsumableDefinitions_ConsumablesEntry, writer: BinaryWriter = new BinaryWriter()): BinaryWriter {
|
||||||
if (message.key !== undefined) {
|
if (message.key !== 0) {
|
||||||
writer.uint32(8).uint32(message.key);
|
writer.uint32(8).uint32(message.key);
|
||||||
}
|
}
|
||||||
if (message.value !== undefined) {
|
if (message.value !== undefined) {
|
||||||
@@ -181,7 +184,7 @@ export const ConsumableDefinitions_ConsumablesEntry: MessageFns<ConsumableDefini
|
|||||||
|
|
||||||
decode(input: BinaryReader | Uint8Array, length?: number): ConsumableDefinitions_ConsumablesEntry {
|
decode(input: BinaryReader | Uint8Array, length?: number): ConsumableDefinitions_ConsumablesEntry {
|
||||||
const reader = input instanceof BinaryReader ? input : new BinaryReader(input);
|
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();
|
const message = createBaseConsumableDefinitions_ConsumablesEntry();
|
||||||
while (reader.pos < end) {
|
while (reader.pos < end) {
|
||||||
const tag = reader.uint32();
|
const tag = reader.uint32();
|
||||||
@@ -213,14 +216,14 @@ export const ConsumableDefinitions_ConsumablesEntry: MessageFns<ConsumableDefini
|
|||||||
|
|
||||||
fromJSON(object: any): ConsumableDefinitions_ConsumablesEntry {
|
fromJSON(object: any): ConsumableDefinitions_ConsumablesEntry {
|
||||||
return {
|
return {
|
||||||
key: globalThis.Number(assertSet("ConsumableDefinitions_ConsumablesEntry.key", object.key)),
|
key: isSet(object.key) ? globalThis.Number(object.key) : 0,
|
||||||
value: Consumable.fromJSON(assertSet("ConsumableDefinitions_ConsumablesEntry.value", object.value)),
|
value: isSet(object.value) ? Consumable.fromJSON(object.value) : undefined,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
|
||||||
toJSON(message: ConsumableDefinitions_ConsumablesEntry): unknown {
|
toJSON(message: ConsumableDefinitions_ConsumablesEntry): unknown {
|
||||||
const obj: any = {};
|
const obj: any = {};
|
||||||
if (message.key !== undefined) {
|
if (message.key !== 0) {
|
||||||
obj.key = Math.round(message.key);
|
obj.key = Math.round(message.key);
|
||||||
}
|
}
|
||||||
if (message.value !== undefined) {
|
if (message.value !== undefined) {
|
||||||
@@ -241,21 +244,13 @@ export const ConsumableDefinitions_ConsumablesEntry: MessageFns<ConsumableDefini
|
|||||||
message.key = object.key ?? 0;
|
message.key = object.key ?? 0;
|
||||||
message.value = (object.value !== undefined && object.value !== null)
|
message.value = (object.value !== undefined && object.value !== null)
|
||||||
? Consumable.fromPartial(object.value)
|
? Consumable.fromPartial(object.value)
|
||||||
: createBaseConsumable();
|
: undefined;
|
||||||
return message;
|
return message;
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
export function createBaseConsumable(): Consumable {
|
function createBaseConsumable(): Consumable {
|
||||||
return {
|
return { id: 0, name: undefined, cooldown: 0, duration: 0, game_mode_exclusive: false, include: [], exclude: [] };
|
||||||
id: 0,
|
|
||||||
name: createBaseI18nString(),
|
|
||||||
cooldown: 0,
|
|
||||||
duration: undefined,
|
|
||||||
game_mode_exclusive: false,
|
|
||||||
include: [],
|
|
||||||
exclude: [],
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export const Consumable: MessageFns<Consumable> = {
|
export const Consumable: MessageFns<Consumable> = {
|
||||||
@@ -269,7 +264,7 @@ export const Consumable: MessageFns<Consumable> = {
|
|||||||
if (message.cooldown !== 0) {
|
if (message.cooldown !== 0) {
|
||||||
writer.uint32(24).uint32(message.cooldown);
|
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);
|
writer.uint32(37).float(message.duration);
|
||||||
}
|
}
|
||||||
if (message.game_mode_exclusive !== false) {
|
if (message.game_mode_exclusive !== false) {
|
||||||
@@ -286,7 +281,7 @@ export const Consumable: MessageFns<Consumable> = {
|
|||||||
|
|
||||||
decode(input: BinaryReader | Uint8Array, length?: number): Consumable {
|
decode(input: BinaryReader | Uint8Array, length?: number): Consumable {
|
||||||
const reader = input instanceof BinaryReader ? input : new BinaryReader(input);
|
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();
|
const message = createBaseConsumable();
|
||||||
while (reader.pos < end) {
|
while (reader.pos < end) {
|
||||||
const tag = reader.uint32();
|
const tag = reader.uint32();
|
||||||
@@ -358,11 +353,15 @@ export const Consumable: MessageFns<Consumable> = {
|
|||||||
|
|
||||||
fromJSON(object: any): Consumable {
|
fromJSON(object: any): Consumable {
|
||||||
return {
|
return {
|
||||||
id: globalThis.Number(assertSet("Consumable.id", object.id)),
|
id: isSet(object.id) ? globalThis.Number(object.id) : 0,
|
||||||
name: I18nString.fromJSON(assertSet("Consumable.name", object.name)),
|
name: isSet(object.name) ? I18nString.fromJSON(object.name) : undefined,
|
||||||
cooldown: globalThis.Number(assertSet("Consumable.cooldown", object.cooldown)),
|
cooldown: isSet(object.cooldown) ? globalThis.Number(object.cooldown) : 0,
|
||||||
duration: isSet(object.duration) ? globalThis.Number(object.duration) : undefined,
|
duration: isSet(object.duration) ? globalThis.Number(object.duration) : 0,
|
||||||
game_mode_exclusive: globalThis.Boolean(assertSet("Consumable.game_mode_exclusive", object.game_mode_exclusive)),
|
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)
|
include: globalThis.Array.isArray(object?.include)
|
||||||
? object.include.map((e: any) => ConsumableTankFilter.fromJSON(e))
|
? object.include.map((e: any) => ConsumableTankFilter.fromJSON(e))
|
||||||
: [],
|
: [],
|
||||||
@@ -383,11 +382,11 @@ export const Consumable: MessageFns<Consumable> = {
|
|||||||
if (message.cooldown !== 0) {
|
if (message.cooldown !== 0) {
|
||||||
obj.cooldown = Math.round(message.cooldown);
|
obj.cooldown = Math.round(message.cooldown);
|
||||||
}
|
}
|
||||||
if (message.duration !== undefined && message.duration !== undefined) {
|
if (message.duration !== undefined && message.duration !== 0) {
|
||||||
obj.duration = message.duration;
|
obj.duration = message.duration;
|
||||||
}
|
}
|
||||||
if (message.game_mode_exclusive !== false) {
|
if (message.game_mode_exclusive !== false) {
|
||||||
obj.game_mode_exclusive = message.game_mode_exclusive;
|
obj.gameModeExclusive = message.game_mode_exclusive;
|
||||||
}
|
}
|
||||||
if (message.include?.length) {
|
if (message.include?.length) {
|
||||||
obj.include = message.include.map((e) => ConsumableTankFilter.toJSON(e));
|
obj.include = message.include.map((e) => ConsumableTankFilter.toJSON(e));
|
||||||
@@ -406,9 +405,9 @@ export const Consumable: MessageFns<Consumable> = {
|
|||||||
message.id = object.id ?? 0;
|
message.id = object.id ?? 0;
|
||||||
message.name = (object.name !== undefined && object.name !== null)
|
message.name = (object.name !== undefined && object.name !== null)
|
||||||
? I18nString.fromPartial(object.name)
|
? I18nString.fromPartial(object.name)
|
||||||
: createBaseI18nString();
|
: undefined;
|
||||||
message.cooldown = object.cooldown ?? 0;
|
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.game_mode_exclusive = object.game_mode_exclusive ?? false;
|
||||||
message.include = object.include?.map((e) => ConsumableTankFilter.fromPartial(e)) || [];
|
message.include = object.include?.map((e) => ConsumableTankFilter.fromPartial(e)) || [];
|
||||||
message.exclude = object.exclude?.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 };
|
return { filter_type: undefined };
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -441,7 +440,7 @@ export const ConsumableTankFilter: MessageFns<ConsumableTankFilter> = {
|
|||||||
|
|
||||||
decode(input: BinaryReader | Uint8Array, length?: number): ConsumableTankFilter {
|
decode(input: BinaryReader | Uint8Array, length?: number): ConsumableTankFilter {
|
||||||
const reader = input instanceof BinaryReader ? input : new BinaryReader(input);
|
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();
|
const message = createBaseConsumableTankFilter();
|
||||||
while (reader.pos < end) {
|
while (reader.pos < end) {
|
||||||
const tag = reader.uint32();
|
const tag = reader.uint32();
|
||||||
@@ -508,14 +507,11 @@ export const ConsumableTankFilter: MessageFns<ConsumableTankFilter> = {
|
|||||||
const obj: any = {};
|
const obj: any = {};
|
||||||
if (message.filter_type?.$case === "tiers") {
|
if (message.filter_type?.$case === "tiers") {
|
||||||
obj.tiers = ConsumableTankTierFilter.toJSON(message.filter_type.value);
|
obj.tiers = ConsumableTankTierFilter.toJSON(message.filter_type.value);
|
||||||
}
|
} else if (message.filter_type?.$case === "ids") {
|
||||||
if (message.filter_type?.$case === "ids") {
|
|
||||||
obj.ids = ConsumableTankIdsFilter.toJSON(message.filter_type.value);
|
obj.ids = ConsumableTankIdsFilter.toJSON(message.filter_type.value);
|
||||||
}
|
} else if (message.filter_type?.$case === "categories") {
|
||||||
if (message.filter_type?.$case === "categories") {
|
|
||||||
obj.categories = ConsumableTankCategoryFilter.toJSON(message.filter_type.value);
|
obj.categories = ConsumableTankCategoryFilter.toJSON(message.filter_type.value);
|
||||||
}
|
} else if (message.filter_type?.$case === "nations") {
|
||||||
if (message.filter_type?.$case === "nations") {
|
|
||||||
obj.nations = ConsumableTankNationFilter.toJSON(message.filter_type.value);
|
obj.nations = ConsumableTankNationFilter.toJSON(message.filter_type.value);
|
||||||
}
|
}
|
||||||
return obj;
|
return obj;
|
||||||
@@ -526,45 +522,46 @@ export const ConsumableTankFilter: MessageFns<ConsumableTankFilter> = {
|
|||||||
},
|
},
|
||||||
fromPartial<I extends Exact<DeepPartial<ConsumableTankFilter>, I>>(object: I): ConsumableTankFilter {
|
fromPartial<I extends Exact<DeepPartial<ConsumableTankFilter>, I>>(object: I): ConsumableTankFilter {
|
||||||
const message = createBaseConsumableTankFilter();
|
const message = createBaseConsumableTankFilter();
|
||||||
if (
|
switch (object.filter_type?.$case) {
|
||||||
object.filter_type?.$case === "tiers" &&
|
case "tiers": {
|
||||||
object.filter_type?.value !== undefined &&
|
if (object.filter_type?.value !== undefined && object.filter_type?.value !== null) {
|
||||||
object.filter_type?.value !== null
|
message.filter_type = {
|
||||||
) {
|
$case: "tiers",
|
||||||
message.filter_type = { $case: "tiers", value: ConsumableTankTierFilter.fromPartial(object.filter_type.value) };
|
value: ConsumableTankTierFilter.fromPartial(object.filter_type.value),
|
||||||
}
|
};
|
||||||
if (
|
}
|
||||||
object.filter_type?.$case === "ids" &&
|
break;
|
||||||
object.filter_type?.value !== undefined &&
|
}
|
||||||
object.filter_type?.value !== null
|
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) };
|
message.filter_type = { $case: "ids", value: ConsumableTankIdsFilter.fromPartial(object.filter_type.value) };
|
||||||
}
|
}
|
||||||
if (
|
break;
|
||||||
object.filter_type?.$case === "categories" &&
|
}
|
||||||
object.filter_type?.value !== undefined &&
|
case "categories": {
|
||||||
object.filter_type?.value !== null
|
if (object.filter_type?.value !== undefined && object.filter_type?.value !== null) {
|
||||||
) {
|
message.filter_type = {
|
||||||
message.filter_type = {
|
$case: "categories",
|
||||||
$case: "categories",
|
value: ConsumableTankCategoryFilter.fromPartial(object.filter_type.value),
|
||||||
value: ConsumableTankCategoryFilter.fromPartial(object.filter_type.value),
|
};
|
||||||
};
|
}
|
||||||
}
|
break;
|
||||||
if (
|
}
|
||||||
object.filter_type?.$case === "nations" &&
|
case "nations": {
|
||||||
object.filter_type?.value !== undefined &&
|
if (object.filter_type?.value !== undefined && object.filter_type?.value !== null) {
|
||||||
object.filter_type?.value !== null
|
message.filter_type = {
|
||||||
) {
|
$case: "nations",
|
||||||
message.filter_type = {
|
value: ConsumableTankNationFilter.fromPartial(object.filter_type.value),
|
||||||
$case: "nations",
|
};
|
||||||
value: ConsumableTankNationFilter.fromPartial(object.filter_type.value),
|
}
|
||||||
};
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return message;
|
return message;
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
export function createBaseConsumableTankTierFilter(): ConsumableTankTierFilter {
|
function createBaseConsumableTankTierFilter(): ConsumableTankTierFilter {
|
||||||
return { min: 0, max: 0 };
|
return { min: 0, max: 0 };
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -581,7 +578,7 @@ export const ConsumableTankTierFilter: MessageFns<ConsumableTankTierFilter> = {
|
|||||||
|
|
||||||
decode(input: BinaryReader | Uint8Array, length?: number): ConsumableTankTierFilter {
|
decode(input: BinaryReader | Uint8Array, length?: number): ConsumableTankTierFilter {
|
||||||
const reader = input instanceof BinaryReader ? input : new BinaryReader(input);
|
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();
|
const message = createBaseConsumableTankTierFilter();
|
||||||
while (reader.pos < end) {
|
while (reader.pos < end) {
|
||||||
const tag = reader.uint32();
|
const tag = reader.uint32();
|
||||||
@@ -613,8 +610,8 @@ export const ConsumableTankTierFilter: MessageFns<ConsumableTankTierFilter> = {
|
|||||||
|
|
||||||
fromJSON(object: any): ConsumableTankTierFilter {
|
fromJSON(object: any): ConsumableTankTierFilter {
|
||||||
return {
|
return {
|
||||||
min: globalThis.Number(assertSet("ConsumableTankTierFilter.min", object.min)),
|
min: isSet(object.min) ? globalThis.Number(object.min) : 0,
|
||||||
max: globalThis.Number(assertSet("ConsumableTankTierFilter.max", object.max)),
|
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: [] };
|
return { ids: [] };
|
||||||
}
|
}
|
||||||
|
|
||||||
export const ConsumableTankIdsFilter: MessageFns<ConsumableTankIdsFilter> = {
|
export const ConsumableTankIdsFilter: MessageFns<ConsumableTankIdsFilter> = {
|
||||||
encode(message: ConsumableTankIdsFilter, writer: BinaryWriter = new BinaryWriter()): BinaryWriter {
|
encode(message: ConsumableTankIdsFilter, writer: BinaryWriter = new BinaryWriter()): BinaryWriter {
|
||||||
writer.uint32(10).fork();
|
|
||||||
for (const v of message.ids) {
|
for (const v of message.ids) {
|
||||||
writer.uint32(v);
|
writer.uint32(8).uint32(v!);
|
||||||
}
|
}
|
||||||
writer.join();
|
|
||||||
return writer;
|
return writer;
|
||||||
},
|
},
|
||||||
|
|
||||||
decode(input: BinaryReader | Uint8Array, length?: number): ConsumableTankIdsFilter {
|
decode(input: BinaryReader | Uint8Array, length?: number): ConsumableTankIdsFilter {
|
||||||
const reader = input instanceof BinaryReader ? input : new BinaryReader(input);
|
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();
|
const message = createBaseConsumableTankIdsFilter();
|
||||||
while (reader.pos < end) {
|
while (reader.pos < end) {
|
||||||
const tag = reader.uint32();
|
const tag = reader.uint32();
|
||||||
@@ -710,23 +705,21 @@ export const ConsumableTankIdsFilter: MessageFns<ConsumableTankIdsFilter> = {
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
export function createBaseConsumableTankCategoryFilter(): ConsumableTankCategoryFilter {
|
function createBaseConsumableTankCategoryFilter(): ConsumableTankCategoryFilter {
|
||||||
return { categories: [] };
|
return { categories: [] };
|
||||||
}
|
}
|
||||||
|
|
||||||
export const ConsumableTankCategoryFilter: MessageFns<ConsumableTankCategoryFilter> = {
|
export const ConsumableTankCategoryFilter: MessageFns<ConsumableTankCategoryFilter> = {
|
||||||
encode(message: ConsumableTankCategoryFilter, writer: BinaryWriter = new BinaryWriter()): BinaryWriter {
|
encode(message: ConsumableTankCategoryFilter, writer: BinaryWriter = new BinaryWriter()): BinaryWriter {
|
||||||
writer.uint32(10).fork();
|
|
||||||
for (const v of message.categories) {
|
for (const v of message.categories) {
|
||||||
writer.int32(v);
|
writer.uint32(8).int32(v!);
|
||||||
}
|
}
|
||||||
writer.join();
|
|
||||||
return writer;
|
return writer;
|
||||||
},
|
},
|
||||||
|
|
||||||
decode(input: BinaryReader | Uint8Array, length?: number): ConsumableTankCategoryFilter {
|
decode(input: BinaryReader | Uint8Array, length?: number): ConsumableTankCategoryFilter {
|
||||||
const reader = input instanceof BinaryReader ? input : new BinaryReader(input);
|
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();
|
const message = createBaseConsumableTankCategoryFilter();
|
||||||
while (reader.pos < end) {
|
while (reader.pos < end) {
|
||||||
const tag = reader.uint32();
|
const tag = reader.uint32();
|
||||||
@@ -784,7 +777,7 @@ export const ConsumableTankCategoryFilter: MessageFns<ConsumableTankCategoryFilt
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
export function createBaseConsumableTankNationFilter(): ConsumableTankNationFilter {
|
function createBaseConsumableTankNationFilter(): ConsumableTankNationFilter {
|
||||||
return { nations: [] };
|
return { nations: [] };
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -798,7 +791,7 @@ export const ConsumableTankNationFilter: MessageFns<ConsumableTankNationFilter>
|
|||||||
|
|
||||||
decode(input: BinaryReader | Uint8Array, length?: number): ConsumableTankNationFilter {
|
decode(input: BinaryReader | Uint8Array, length?: number): ConsumableTankNationFilter {
|
||||||
const reader = input instanceof BinaryReader ? input : new BinaryReader(input);
|
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();
|
const message = createBaseConsumableTankNationFilter();
|
||||||
while (reader.pos < end) {
|
while (reader.pos < end) {
|
||||||
const tag = reader.uint32();
|
const tag = reader.uint32();
|
||||||
@@ -865,14 +858,6 @@ function isSet(value: any): boolean {
|
|||||||
return value !== null && value !== undefined;
|
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> {
|
export interface MessageFns<T> {
|
||||||
encode(message: T, writer?: BinaryWriter): BinaryWriter;
|
encode(message: T, writer?: BinaryWriter): BinaryWriter;
|
||||||
decode(input: BinaryReader | Uint8Array, length?: number): T;
|
decode(input: BinaryReader | Uint8Array, length?: number): T;
|
||||||
|
|||||||
@@ -2,15 +2,15 @@ syntax = "proto2";
|
|||||||
|
|
||||||
package blitzkit;
|
package blitzkit;
|
||||||
|
|
||||||
import "packages/core/src/protos/i18n.proto";
|
import "i18n.proto";
|
||||||
|
|
||||||
message EquipmentDefinitions {
|
message EquipmentDefinitions {
|
||||||
map<string, EquipmentPreset> presets = 1;
|
map<string, EquipmentPreset> presets = 1;
|
||||||
map<uint32, Equipment> equipments = 2;
|
map<uint32, Equipment> equipments = 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
message Equipment {
|
message Equipment {
|
||||||
required I18nString name = 1;
|
required I18nString name = 1;
|
||||||
required I18nString description = 2;
|
required I18nString description = 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -19,6 +19,6 @@ message EquipmentPreset {
|
|||||||
}
|
}
|
||||||
|
|
||||||
message EquipmentSlot {
|
message EquipmentSlot {
|
||||||
required uint32 left = 1;
|
required uint32 left = 1;
|
||||||
required uint32 right = 2;
|
required uint32 right = 2;
|
||||||
}
|
}
|
||||||
@@ -1,12 +1,12 @@
|
|||||||
// Code generated by protoc-gen-ts_proto. DO NOT EDIT.
|
// Code generated by protoc-gen-ts_proto. DO NOT EDIT.
|
||||||
// versions:
|
// versions:
|
||||||
// protoc-gen-ts_proto v2.2.2
|
// protoc-gen-ts_proto v2.11.2
|
||||||
// protoc v5.28.2
|
// protoc v5.28.2
|
||||||
// source: packages/core/src/protos/equipment_definitions.proto
|
// source: equipment_definitions.proto
|
||||||
|
|
||||||
/* eslint-disable */
|
/* eslint-disable */
|
||||||
import { BinaryReader, BinaryWriter } from "@bufbuild/protobuf/wire";
|
import { BinaryReader, BinaryWriter } from "@bufbuild/protobuf/wire";
|
||||||
import { createBaseI18nString, I18nString } from "./i18n";
|
import { I18nString } from "./i18n";
|
||||||
|
|
||||||
export const protobufPackage = "blitzkit";
|
export const protobufPackage = "blitzkit";
|
||||||
|
|
||||||
@@ -26,8 +26,8 @@ export interface EquipmentDefinitions_EquipmentsEntry {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export interface Equipment {
|
export interface Equipment {
|
||||||
name: I18nString;
|
name: I18nString | undefined;
|
||||||
description: I18nString;
|
description: I18nString | undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface EquipmentPreset {
|
export interface EquipmentPreset {
|
||||||
@@ -39,16 +39,16 @@ export interface EquipmentSlot {
|
|||||||
right: number;
|
right: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function createBaseEquipmentDefinitions(): EquipmentDefinitions {
|
function createBaseEquipmentDefinitions(): EquipmentDefinitions {
|
||||||
return { presets: {}, equipments: {} };
|
return { presets: {}, equipments: {} };
|
||||||
}
|
}
|
||||||
|
|
||||||
export const EquipmentDefinitions: MessageFns<EquipmentDefinitions> = {
|
export const EquipmentDefinitions: MessageFns<EquipmentDefinitions> = {
|
||||||
encode(message: EquipmentDefinitions, writer: BinaryWriter = new BinaryWriter()): BinaryWriter {
|
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();
|
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();
|
EquipmentDefinitions_EquipmentsEntry.encode({ key: key as any, value }, writer.uint32(18).fork()).join();
|
||||||
});
|
});
|
||||||
return writer;
|
return writer;
|
||||||
@@ -56,7 +56,7 @@ export const EquipmentDefinitions: MessageFns<EquipmentDefinitions> = {
|
|||||||
|
|
||||||
decode(input: BinaryReader | Uint8Array, length?: number): EquipmentDefinitions {
|
decode(input: BinaryReader | Uint8Array, length?: number): EquipmentDefinitions {
|
||||||
const reader = input instanceof BinaryReader ? input : new BinaryReader(input);
|
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();
|
const message = createBaseEquipmentDefinitions();
|
||||||
while (reader.pos < end) {
|
while (reader.pos < end) {
|
||||||
const tag = reader.uint32();
|
const tag = reader.uint32();
|
||||||
@@ -95,16 +95,22 @@ export const EquipmentDefinitions: MessageFns<EquipmentDefinitions> = {
|
|||||||
fromJSON(object: any): EquipmentDefinitions {
|
fromJSON(object: any): EquipmentDefinitions {
|
||||||
return {
|
return {
|
||||||
presets: isObject(object.presets)
|
presets: isObject(object.presets)
|
||||||
? Object.entries(object.presets).reduce<{ [key: string]: EquipmentPreset }>((acc, [key, value]) => {
|
? (globalThis.Object.entries(object.presets) as [string, any][]).reduce(
|
||||||
acc[key] = EquipmentPreset.fromJSON(value);
|
(acc: { [key: string]: EquipmentPreset }, [key, value]: [string, any]) => {
|
||||||
return acc;
|
acc[key] = EquipmentPreset.fromJSON(value);
|
||||||
}, {})
|
return acc;
|
||||||
|
},
|
||||||
|
{},
|
||||||
|
)
|
||||||
: {},
|
: {},
|
||||||
equipments: isObject(object.equipments)
|
equipments: isObject(object.equipments)
|
||||||
? Object.entries(object.equipments).reduce<{ [key: number]: Equipment }>((acc, [key, value]) => {
|
? (globalThis.Object.entries(object.equipments) as [string, any][]).reduce(
|
||||||
acc[globalThis.Number(key)] = Equipment.fromJSON(value);
|
(acc: { [key: number]: Equipment }, [key, value]: [string, any]) => {
|
||||||
return acc;
|
acc[globalThis.Number(key)] = Equipment.fromJSON(value);
|
||||||
}, {})
|
return acc;
|
||||||
|
},
|
||||||
|
{},
|
||||||
|
)
|
||||||
: {},
|
: {},
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
@@ -112,7 +118,7 @@ export const EquipmentDefinitions: MessageFns<EquipmentDefinitions> = {
|
|||||||
toJSON(message: EquipmentDefinitions): unknown {
|
toJSON(message: EquipmentDefinitions): unknown {
|
||||||
const obj: any = {};
|
const obj: any = {};
|
||||||
if (message.presets) {
|
if (message.presets) {
|
||||||
const entries = Object.entries(message.presets);
|
const entries = globalThis.Object.entries(message.presets) as [string, EquipmentPreset][];
|
||||||
if (entries.length > 0) {
|
if (entries.length > 0) {
|
||||||
obj.presets = {};
|
obj.presets = {};
|
||||||
entries.forEach(([k, v]) => {
|
entries.forEach(([k, v]) => {
|
||||||
@@ -121,7 +127,7 @@ export const EquipmentDefinitions: MessageFns<EquipmentDefinitions> = {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (message.equipments) {
|
if (message.equipments) {
|
||||||
const entries = Object.entries(message.equipments);
|
const entries = globalThis.Object.entries(message.equipments) as [string, Equipment][];
|
||||||
if (entries.length > 0) {
|
if (entries.length > 0) {
|
||||||
obj.equipments = {};
|
obj.equipments = {};
|
||||||
entries.forEach(([k, v]) => {
|
entries.forEach(([k, v]) => {
|
||||||
@@ -137,8 +143,8 @@ export const EquipmentDefinitions: MessageFns<EquipmentDefinitions> = {
|
|||||||
},
|
},
|
||||||
fromPartial<I extends Exact<DeepPartial<EquipmentDefinitions>, I>>(object: I): EquipmentDefinitions {
|
fromPartial<I extends Exact<DeepPartial<EquipmentDefinitions>, I>>(object: I): EquipmentDefinitions {
|
||||||
const message = createBaseEquipmentDefinitions();
|
const message = createBaseEquipmentDefinitions();
|
||||||
message.presets = Object.entries(object.presets ?? {}).reduce<{ [key: string]: EquipmentPreset }>(
|
message.presets = (globalThis.Object.entries(object.presets ?? {}) as [string, EquipmentPreset][]).reduce(
|
||||||
(acc, [key, value]) => {
|
(acc: { [key: string]: EquipmentPreset }, [key, value]: [string, EquipmentPreset]) => {
|
||||||
if (value !== undefined) {
|
if (value !== undefined) {
|
||||||
acc[key] = EquipmentPreset.fromPartial(value);
|
acc[key] = EquipmentPreset.fromPartial(value);
|
||||||
}
|
}
|
||||||
@@ -146,8 +152,8 @@ export const EquipmentDefinitions: MessageFns<EquipmentDefinitions> = {
|
|||||||
},
|
},
|
||||||
{},
|
{},
|
||||||
);
|
);
|
||||||
message.equipments = Object.entries(object.equipments ?? {}).reduce<{ [key: number]: Equipment }>(
|
message.equipments = (globalThis.Object.entries(object.equipments ?? {}) as [string, Equipment][]).reduce(
|
||||||
(acc, [key, value]) => {
|
(acc: { [key: number]: Equipment }, [key, value]: [string, Equipment]) => {
|
||||||
if (value !== undefined) {
|
if (value !== undefined) {
|
||||||
acc[globalThis.Number(key)] = Equipment.fromPartial(value);
|
acc[globalThis.Number(key)] = Equipment.fromPartial(value);
|
||||||
}
|
}
|
||||||
@@ -159,13 +165,13 @@ export const EquipmentDefinitions: MessageFns<EquipmentDefinitions> = {
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
export function createBaseEquipmentDefinitions_PresetsEntry(): EquipmentDefinitions_PresetsEntry {
|
function createBaseEquipmentDefinitions_PresetsEntry(): EquipmentDefinitions_PresetsEntry {
|
||||||
return { key: "", value: createBaseEquipmentPreset() };
|
return { key: "", value: undefined };
|
||||||
}
|
}
|
||||||
|
|
||||||
export const EquipmentDefinitions_PresetsEntry: MessageFns<EquipmentDefinitions_PresetsEntry> = {
|
export const EquipmentDefinitions_PresetsEntry: MessageFns<EquipmentDefinitions_PresetsEntry> = {
|
||||||
encode(message: EquipmentDefinitions_PresetsEntry, writer: BinaryWriter = new BinaryWriter()): BinaryWriter {
|
encode(message: EquipmentDefinitions_PresetsEntry, writer: BinaryWriter = new BinaryWriter()): BinaryWriter {
|
||||||
if (message.key !== undefined) {
|
if (message.key !== "") {
|
||||||
writer.uint32(10).string(message.key);
|
writer.uint32(10).string(message.key);
|
||||||
}
|
}
|
||||||
if (message.value !== undefined) {
|
if (message.value !== undefined) {
|
||||||
@@ -176,7 +182,7 @@ export const EquipmentDefinitions_PresetsEntry: MessageFns<EquipmentDefinitions_
|
|||||||
|
|
||||||
decode(input: BinaryReader | Uint8Array, length?: number): EquipmentDefinitions_PresetsEntry {
|
decode(input: BinaryReader | Uint8Array, length?: number): EquipmentDefinitions_PresetsEntry {
|
||||||
const reader = input instanceof BinaryReader ? input : new BinaryReader(input);
|
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();
|
const message = createBaseEquipmentDefinitions_PresetsEntry();
|
||||||
while (reader.pos < end) {
|
while (reader.pos < end) {
|
||||||
const tag = reader.uint32();
|
const tag = reader.uint32();
|
||||||
@@ -208,14 +214,14 @@ export const EquipmentDefinitions_PresetsEntry: MessageFns<EquipmentDefinitions_
|
|||||||
|
|
||||||
fromJSON(object: any): EquipmentDefinitions_PresetsEntry {
|
fromJSON(object: any): EquipmentDefinitions_PresetsEntry {
|
||||||
return {
|
return {
|
||||||
key: globalThis.String(assertSet("EquipmentDefinitions_PresetsEntry.key", object.key)),
|
key: isSet(object.key) ? globalThis.String(object.key) : "",
|
||||||
value: EquipmentPreset.fromJSON(assertSet("EquipmentDefinitions_PresetsEntry.value", object.value)),
|
value: isSet(object.value) ? EquipmentPreset.fromJSON(object.value) : undefined,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
|
||||||
toJSON(message: EquipmentDefinitions_PresetsEntry): unknown {
|
toJSON(message: EquipmentDefinitions_PresetsEntry): unknown {
|
||||||
const obj: any = {};
|
const obj: any = {};
|
||||||
if (message.key !== undefined) {
|
if (message.key !== "") {
|
||||||
obj.key = message.key;
|
obj.key = message.key;
|
||||||
}
|
}
|
||||||
if (message.value !== undefined) {
|
if (message.value !== undefined) {
|
||||||
@@ -236,18 +242,18 @@ export const EquipmentDefinitions_PresetsEntry: MessageFns<EquipmentDefinitions_
|
|||||||
message.key = object.key ?? "";
|
message.key = object.key ?? "";
|
||||||
message.value = (object.value !== undefined && object.value !== null)
|
message.value = (object.value !== undefined && object.value !== null)
|
||||||
? EquipmentPreset.fromPartial(object.value)
|
? EquipmentPreset.fromPartial(object.value)
|
||||||
: createBaseEquipmentPreset();
|
: undefined;
|
||||||
return message;
|
return message;
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
export function createBaseEquipmentDefinitions_EquipmentsEntry(): EquipmentDefinitions_EquipmentsEntry {
|
function createBaseEquipmentDefinitions_EquipmentsEntry(): EquipmentDefinitions_EquipmentsEntry {
|
||||||
return { key: 0, value: createBaseEquipment() };
|
return { key: 0, value: undefined };
|
||||||
}
|
}
|
||||||
|
|
||||||
export const EquipmentDefinitions_EquipmentsEntry: MessageFns<EquipmentDefinitions_EquipmentsEntry> = {
|
export const EquipmentDefinitions_EquipmentsEntry: MessageFns<EquipmentDefinitions_EquipmentsEntry> = {
|
||||||
encode(message: EquipmentDefinitions_EquipmentsEntry, writer: BinaryWriter = new BinaryWriter()): BinaryWriter {
|
encode(message: EquipmentDefinitions_EquipmentsEntry, writer: BinaryWriter = new BinaryWriter()): BinaryWriter {
|
||||||
if (message.key !== undefined) {
|
if (message.key !== 0) {
|
||||||
writer.uint32(8).uint32(message.key);
|
writer.uint32(8).uint32(message.key);
|
||||||
}
|
}
|
||||||
if (message.value !== undefined) {
|
if (message.value !== undefined) {
|
||||||
@@ -258,7 +264,7 @@ export const EquipmentDefinitions_EquipmentsEntry: MessageFns<EquipmentDefinitio
|
|||||||
|
|
||||||
decode(input: BinaryReader | Uint8Array, length?: number): EquipmentDefinitions_EquipmentsEntry {
|
decode(input: BinaryReader | Uint8Array, length?: number): EquipmentDefinitions_EquipmentsEntry {
|
||||||
const reader = input instanceof BinaryReader ? input : new BinaryReader(input);
|
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();
|
const message = createBaseEquipmentDefinitions_EquipmentsEntry();
|
||||||
while (reader.pos < end) {
|
while (reader.pos < end) {
|
||||||
const tag = reader.uint32();
|
const tag = reader.uint32();
|
||||||
@@ -290,14 +296,14 @@ export const EquipmentDefinitions_EquipmentsEntry: MessageFns<EquipmentDefinitio
|
|||||||
|
|
||||||
fromJSON(object: any): EquipmentDefinitions_EquipmentsEntry {
|
fromJSON(object: any): EquipmentDefinitions_EquipmentsEntry {
|
||||||
return {
|
return {
|
||||||
key: globalThis.Number(assertSet("EquipmentDefinitions_EquipmentsEntry.key", object.key)),
|
key: isSet(object.key) ? globalThis.Number(object.key) : 0,
|
||||||
value: Equipment.fromJSON(assertSet("EquipmentDefinitions_EquipmentsEntry.value", object.value)),
|
value: isSet(object.value) ? Equipment.fromJSON(object.value) : undefined,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
|
||||||
toJSON(message: EquipmentDefinitions_EquipmentsEntry): unknown {
|
toJSON(message: EquipmentDefinitions_EquipmentsEntry): unknown {
|
||||||
const obj: any = {};
|
const obj: any = {};
|
||||||
if (message.key !== undefined) {
|
if (message.key !== 0) {
|
||||||
obj.key = Math.round(message.key);
|
obj.key = Math.round(message.key);
|
||||||
}
|
}
|
||||||
if (message.value !== undefined) {
|
if (message.value !== undefined) {
|
||||||
@@ -318,13 +324,13 @@ export const EquipmentDefinitions_EquipmentsEntry: MessageFns<EquipmentDefinitio
|
|||||||
message.key = object.key ?? 0;
|
message.key = object.key ?? 0;
|
||||||
message.value = (object.value !== undefined && object.value !== null)
|
message.value = (object.value !== undefined && object.value !== null)
|
||||||
? Equipment.fromPartial(object.value)
|
? Equipment.fromPartial(object.value)
|
||||||
: createBaseEquipment();
|
: undefined;
|
||||||
return message;
|
return message;
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
export function createBaseEquipment(): Equipment {
|
function createBaseEquipment(): Equipment {
|
||||||
return { name: createBaseI18nString(), description: createBaseI18nString() };
|
return { name: undefined, description: undefined };
|
||||||
}
|
}
|
||||||
|
|
||||||
export const Equipment: MessageFns<Equipment> = {
|
export const Equipment: MessageFns<Equipment> = {
|
||||||
@@ -340,7 +346,7 @@ export const Equipment: MessageFns<Equipment> = {
|
|||||||
|
|
||||||
decode(input: BinaryReader | Uint8Array, length?: number): Equipment {
|
decode(input: BinaryReader | Uint8Array, length?: number): Equipment {
|
||||||
const reader = input instanceof BinaryReader ? input : new BinaryReader(input);
|
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();
|
const message = createBaseEquipment();
|
||||||
while (reader.pos < end) {
|
while (reader.pos < end) {
|
||||||
const tag = reader.uint32();
|
const tag = reader.uint32();
|
||||||
@@ -372,8 +378,8 @@ export const Equipment: MessageFns<Equipment> = {
|
|||||||
|
|
||||||
fromJSON(object: any): Equipment {
|
fromJSON(object: any): Equipment {
|
||||||
return {
|
return {
|
||||||
name: I18nString.fromJSON(assertSet("Equipment.name", object.name)),
|
name: isSet(object.name) ? I18nString.fromJSON(object.name) : undefined,
|
||||||
description: I18nString.fromJSON(assertSet("Equipment.description", object.description)),
|
description: isSet(object.description) ? I18nString.fromJSON(object.description) : undefined,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
|
||||||
@@ -395,15 +401,15 @@ export const Equipment: MessageFns<Equipment> = {
|
|||||||
const message = createBaseEquipment();
|
const message = createBaseEquipment();
|
||||||
message.name = (object.name !== undefined && object.name !== null)
|
message.name = (object.name !== undefined && object.name !== null)
|
||||||
? I18nString.fromPartial(object.name)
|
? I18nString.fromPartial(object.name)
|
||||||
: createBaseI18nString();
|
: undefined;
|
||||||
message.description = (object.description !== undefined && object.description !== null)
|
message.description = (object.description !== undefined && object.description !== null)
|
||||||
? I18nString.fromPartial(object.description)
|
? I18nString.fromPartial(object.description)
|
||||||
: createBaseI18nString();
|
: undefined;
|
||||||
return message;
|
return message;
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
export function createBaseEquipmentPreset(): EquipmentPreset {
|
function createBaseEquipmentPreset(): EquipmentPreset {
|
||||||
return { slots: [] };
|
return { slots: [] };
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -417,7 +423,7 @@ export const EquipmentPreset: MessageFns<EquipmentPreset> = {
|
|||||||
|
|
||||||
decode(input: BinaryReader | Uint8Array, length?: number): EquipmentPreset {
|
decode(input: BinaryReader | Uint8Array, length?: number): EquipmentPreset {
|
||||||
const reader = input instanceof BinaryReader ? input : new BinaryReader(input);
|
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();
|
const message = createBaseEquipmentPreset();
|
||||||
while (reader.pos < end) {
|
while (reader.pos < end) {
|
||||||
const tag = reader.uint32();
|
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 };
|
return { left: 0, right: 0 };
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -480,7 +486,7 @@ export const EquipmentSlot: MessageFns<EquipmentSlot> = {
|
|||||||
|
|
||||||
decode(input: BinaryReader | Uint8Array, length?: number): EquipmentSlot {
|
decode(input: BinaryReader | Uint8Array, length?: number): EquipmentSlot {
|
||||||
const reader = input instanceof BinaryReader ? input : new BinaryReader(input);
|
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();
|
const message = createBaseEquipmentSlot();
|
||||||
while (reader.pos < end) {
|
while (reader.pos < end) {
|
||||||
const tag = reader.uint32();
|
const tag = reader.uint32();
|
||||||
@@ -512,8 +518,8 @@ export const EquipmentSlot: MessageFns<EquipmentSlot> = {
|
|||||||
|
|
||||||
fromJSON(object: any): EquipmentSlot {
|
fromJSON(object: any): EquipmentSlot {
|
||||||
return {
|
return {
|
||||||
left: globalThis.Number(assertSet("EquipmentSlot.left", object.left)),
|
left: isSet(object.left) ? globalThis.Number(object.left) : 0,
|
||||||
right: globalThis.Number(assertSet("EquipmentSlot.right", object.right)),
|
right: isSet(object.right) ? globalThis.Number(object.right) : 0,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
|
||||||
@@ -560,14 +566,6 @@ function isSet(value: any): boolean {
|
|||||||
return value !== null && value !== undefined;
|
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> {
|
export interface MessageFns<T> {
|
||||||
encode(message: T, writer?: BinaryWriter): BinaryWriter;
|
encode(message: T, writer?: BinaryWriter): BinaryWriter;
|
||||||
decode(input: BinaryReader | Uint8Array, length?: number): T;
|
decode(input: BinaryReader | Uint8Array, length?: number): T;
|
||||||
|
|||||||
@@ -2,14 +2,14 @@ syntax = "proto2";
|
|||||||
|
|
||||||
package blitzkit;
|
package blitzkit;
|
||||||
|
|
||||||
import "packages/core/src/protos/i18n.proto";
|
import "i18n.proto";
|
||||||
|
|
||||||
message Gallery {
|
message Gallery {
|
||||||
repeated Avatar avatars = 1;
|
repeated Avatar avatars = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
message Avatar {
|
message Avatar {
|
||||||
required string id = 1;
|
required string id = 1;
|
||||||
required I18nString name = 2;
|
required I18nString name = 2;
|
||||||
required string extension = 3;
|
required string extension = 3;
|
||||||
}
|
}
|
||||||
@@ -1,12 +1,12 @@
|
|||||||
// Code generated by protoc-gen-ts_proto. DO NOT EDIT.
|
// Code generated by protoc-gen-ts_proto. DO NOT EDIT.
|
||||||
// versions:
|
// versions:
|
||||||
// protoc-gen-ts_proto v2.2.2
|
// protoc-gen-ts_proto v2.11.2
|
||||||
// protoc v5.28.2
|
// protoc v5.28.2
|
||||||
// source: packages/core/src/protos/gallery.proto
|
// source: gallery.proto
|
||||||
|
|
||||||
/* eslint-disable */
|
/* eslint-disable */
|
||||||
import { BinaryReader, BinaryWriter } from "@bufbuild/protobuf/wire";
|
import { BinaryReader, BinaryWriter } from "@bufbuild/protobuf/wire";
|
||||||
import { createBaseI18nString, I18nString } from "./i18n";
|
import { I18nString } from "./i18n";
|
||||||
|
|
||||||
export const protobufPackage = "blitzkit";
|
export const protobufPackage = "blitzkit";
|
||||||
|
|
||||||
@@ -16,11 +16,11 @@ export interface Gallery {
|
|||||||
|
|
||||||
export interface Avatar {
|
export interface Avatar {
|
||||||
id: string;
|
id: string;
|
||||||
name: I18nString;
|
name: I18nString | undefined;
|
||||||
extension: string;
|
extension: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function createBaseGallery(): Gallery {
|
function createBaseGallery(): Gallery {
|
||||||
return { avatars: [] };
|
return { avatars: [] };
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -34,7 +34,7 @@ export const Gallery: MessageFns<Gallery> = {
|
|||||||
|
|
||||||
decode(input: BinaryReader | Uint8Array, length?: number): Gallery {
|
decode(input: BinaryReader | Uint8Array, length?: number): Gallery {
|
||||||
const reader = input instanceof BinaryReader ? input : new BinaryReader(input);
|
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();
|
const message = createBaseGallery();
|
||||||
while (reader.pos < end) {
|
while (reader.pos < end) {
|
||||||
const tag = reader.uint32();
|
const tag = reader.uint32();
|
||||||
@@ -80,8 +80,8 @@ export const Gallery: MessageFns<Gallery> = {
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
export function createBaseAvatar(): Avatar {
|
function createBaseAvatar(): Avatar {
|
||||||
return { id: "", name: createBaseI18nString(), extension: "" };
|
return { id: "", name: undefined, extension: "" };
|
||||||
}
|
}
|
||||||
|
|
||||||
export const Avatar: MessageFns<Avatar> = {
|
export const Avatar: MessageFns<Avatar> = {
|
||||||
@@ -100,7 +100,7 @@ export const Avatar: MessageFns<Avatar> = {
|
|||||||
|
|
||||||
decode(input: BinaryReader | Uint8Array, length?: number): Avatar {
|
decode(input: BinaryReader | Uint8Array, length?: number): Avatar {
|
||||||
const reader = input instanceof BinaryReader ? input : new BinaryReader(input);
|
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();
|
const message = createBaseAvatar();
|
||||||
while (reader.pos < end) {
|
while (reader.pos < end) {
|
||||||
const tag = reader.uint32();
|
const tag = reader.uint32();
|
||||||
@@ -140,9 +140,9 @@ export const Avatar: MessageFns<Avatar> = {
|
|||||||
|
|
||||||
fromJSON(object: any): Avatar {
|
fromJSON(object: any): Avatar {
|
||||||
return {
|
return {
|
||||||
id: globalThis.String(assertSet("Avatar.id", object.id)),
|
id: isSet(object.id) ? globalThis.String(object.id) : "",
|
||||||
name: I18nString.fromJSON(assertSet("Avatar.name", object.name)),
|
name: isSet(object.name) ? I18nString.fromJSON(object.name) : undefined,
|
||||||
extension: globalThis.String(assertSet("Avatar.extension", object.extension)),
|
extension: isSet(object.extension) ? globalThis.String(object.extension) : "",
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
|
||||||
@@ -168,7 +168,7 @@ export const Avatar: MessageFns<Avatar> = {
|
|||||||
message.id = object.id ?? "";
|
message.id = object.id ?? "";
|
||||||
message.name = (object.name !== undefined && object.name !== null)
|
message.name = (object.name !== undefined && object.name !== null)
|
||||||
? I18nString.fromPartial(object.name)
|
? I18nString.fromPartial(object.name)
|
||||||
: createBaseI18nString();
|
: undefined;
|
||||||
message.extension = object.extension ?? "";
|
message.extension = object.extension ?? "";
|
||||||
return message;
|
return message;
|
||||||
},
|
},
|
||||||
@@ -191,14 +191,6 @@ function isSet(value: any): boolean {
|
|||||||
return value !== null && value !== undefined;
|
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> {
|
export interface MessageFns<T> {
|
||||||
encode(message: T, writer?: BinaryWriter): BinaryWriter;
|
encode(message: T, writer?: BinaryWriter): BinaryWriter;
|
||||||
decode(input: BinaryReader | Uint8Array, length?: number): T;
|
decode(input: BinaryReader | Uint8Array, length?: number): T;
|
||||||
|
|||||||
@@ -2,13 +2,13 @@ syntax = "proto2";
|
|||||||
|
|
||||||
package blitzkit;
|
package blitzkit;
|
||||||
|
|
||||||
import "packages/core/src/protos/i18n.proto";
|
import "i18n.proto";
|
||||||
|
|
||||||
message GameDefinitions {
|
message GameDefinitions {
|
||||||
required string version = 1;
|
required string version = 1;
|
||||||
repeated string nations = 2;
|
repeated string nations = 2;
|
||||||
map<uint32, GameMode> gameModes = 3;
|
map<uint32, GameMode> gameModes = 3;
|
||||||
map<uint32, GameModeRole> roles = 4;
|
map<uint32, GameModeRole> roles = 4;
|
||||||
}
|
}
|
||||||
|
|
||||||
message GameMode {
|
message GameMode {
|
||||||
@@ -16,6 +16,6 @@ message GameMode {
|
|||||||
}
|
}
|
||||||
|
|
||||||
message GameModeRole {
|
message GameModeRole {
|
||||||
repeated uint32 provisions = 1;
|
repeated uint32 provisions = 1;
|
||||||
repeated uint32 consumables = 2;
|
repeated uint32 consumables = 2;
|
||||||
}
|
}
|
||||||
@@ -1,12 +1,12 @@
|
|||||||
// Code generated by protoc-gen-ts_proto. DO NOT EDIT.
|
// Code generated by protoc-gen-ts_proto. DO NOT EDIT.
|
||||||
// versions:
|
// versions:
|
||||||
// protoc-gen-ts_proto v2.2.2
|
// protoc-gen-ts_proto v2.11.2
|
||||||
// protoc v5.28.2
|
// protoc v5.28.2
|
||||||
// source: packages/core/src/protos/game_definitions.proto
|
// source: game_definitions.proto
|
||||||
|
|
||||||
/* eslint-disable */
|
/* eslint-disable */
|
||||||
import { BinaryReader, BinaryWriter } from "@bufbuild/protobuf/wire";
|
import { BinaryReader, BinaryWriter } from "@bufbuild/protobuf/wire";
|
||||||
import { createBaseI18nString, I18nString } from "./i18n";
|
import { I18nString } from "./i18n";
|
||||||
|
|
||||||
export const protobufPackage = "blitzkit";
|
export const protobufPackage = "blitzkit";
|
||||||
|
|
||||||
@@ -28,7 +28,7 @@ export interface GameDefinitions_RolesEntry {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export interface GameMode {
|
export interface GameMode {
|
||||||
name: I18nString;
|
name: I18nString | undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface GameModeRole {
|
export interface GameModeRole {
|
||||||
@@ -36,7 +36,7 @@ export interface GameModeRole {
|
|||||||
consumables: number[];
|
consumables: number[];
|
||||||
}
|
}
|
||||||
|
|
||||||
export function createBaseGameDefinitions(): GameDefinitions {
|
function createBaseGameDefinitions(): GameDefinitions {
|
||||||
return { version: "", nations: [], gameModes: {}, roles: {} };
|
return { version: "", nations: [], gameModes: {}, roles: {} };
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -48,10 +48,10 @@ export const GameDefinitions: MessageFns<GameDefinitions> = {
|
|||||||
for (const v of message.nations) {
|
for (const v of message.nations) {
|
||||||
writer.uint32(18).string(v!);
|
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();
|
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();
|
GameDefinitions_RolesEntry.encode({ key: key as any, value }, writer.uint32(34).fork()).join();
|
||||||
});
|
});
|
||||||
return writer;
|
return writer;
|
||||||
@@ -59,7 +59,7 @@ export const GameDefinitions: MessageFns<GameDefinitions> = {
|
|||||||
|
|
||||||
decode(input: BinaryReader | Uint8Array, length?: number): GameDefinitions {
|
decode(input: BinaryReader | Uint8Array, length?: number): GameDefinitions {
|
||||||
const reader = input instanceof BinaryReader ? input : new BinaryReader(input);
|
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();
|
const message = createBaseGameDefinitions();
|
||||||
while (reader.pos < end) {
|
while (reader.pos < end) {
|
||||||
const tag = reader.uint32();
|
const tag = reader.uint32();
|
||||||
@@ -113,19 +113,25 @@ export const GameDefinitions: MessageFns<GameDefinitions> = {
|
|||||||
|
|
||||||
fromJSON(object: any): GameDefinitions {
|
fromJSON(object: any): GameDefinitions {
|
||||||
return {
|
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)) : [],
|
nations: globalThis.Array.isArray(object?.nations) ? object.nations.map((e: any) => globalThis.String(e)) : [],
|
||||||
gameModes: isObject(object.gameModes)
|
gameModes: isObject(object.gameModes)
|
||||||
? Object.entries(object.gameModes).reduce<{ [key: number]: GameMode }>((acc, [key, value]) => {
|
? (globalThis.Object.entries(object.gameModes) as [string, any][]).reduce(
|
||||||
acc[globalThis.Number(key)] = GameMode.fromJSON(value);
|
(acc: { [key: number]: GameMode }, [key, value]: [string, any]) => {
|
||||||
return acc;
|
acc[globalThis.Number(key)] = GameMode.fromJSON(value);
|
||||||
}, {})
|
return acc;
|
||||||
|
},
|
||||||
|
{},
|
||||||
|
)
|
||||||
: {},
|
: {},
|
||||||
roles: isObject(object.roles)
|
roles: isObject(object.roles)
|
||||||
? Object.entries(object.roles).reduce<{ [key: number]: GameModeRole }>((acc, [key, value]) => {
|
? (globalThis.Object.entries(object.roles) as [string, any][]).reduce(
|
||||||
acc[globalThis.Number(key)] = GameModeRole.fromJSON(value);
|
(acc: { [key: number]: GameModeRole }, [key, value]: [string, any]) => {
|
||||||
return acc;
|
acc[globalThis.Number(key)] = GameModeRole.fromJSON(value);
|
||||||
}, {})
|
return acc;
|
||||||
|
},
|
||||||
|
{},
|
||||||
|
)
|
||||||
: {},
|
: {},
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
@@ -139,7 +145,7 @@ export const GameDefinitions: MessageFns<GameDefinitions> = {
|
|||||||
obj.nations = message.nations;
|
obj.nations = message.nations;
|
||||||
}
|
}
|
||||||
if (message.gameModes) {
|
if (message.gameModes) {
|
||||||
const entries = Object.entries(message.gameModes);
|
const entries = globalThis.Object.entries(message.gameModes) as [string, GameMode][];
|
||||||
if (entries.length > 0) {
|
if (entries.length > 0) {
|
||||||
obj.gameModes = {};
|
obj.gameModes = {};
|
||||||
entries.forEach(([k, v]) => {
|
entries.forEach(([k, v]) => {
|
||||||
@@ -148,7 +154,7 @@ export const GameDefinitions: MessageFns<GameDefinitions> = {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (message.roles) {
|
if (message.roles) {
|
||||||
const entries = Object.entries(message.roles);
|
const entries = globalThis.Object.entries(message.roles) as [string, GameModeRole][];
|
||||||
if (entries.length > 0) {
|
if (entries.length > 0) {
|
||||||
obj.roles = {};
|
obj.roles = {};
|
||||||
entries.forEach(([k, v]) => {
|
entries.forEach(([k, v]) => {
|
||||||
@@ -166,8 +172,8 @@ export const GameDefinitions: MessageFns<GameDefinitions> = {
|
|||||||
const message = createBaseGameDefinitions();
|
const message = createBaseGameDefinitions();
|
||||||
message.version = object.version ?? "";
|
message.version = object.version ?? "";
|
||||||
message.nations = object.nations?.map((e) => e) || [];
|
message.nations = object.nations?.map((e) => e) || [];
|
||||||
message.gameModes = Object.entries(object.gameModes ?? {}).reduce<{ [key: number]: GameMode }>(
|
message.gameModes = (globalThis.Object.entries(object.gameModes ?? {}) as [string, GameMode][]).reduce(
|
||||||
(acc, [key, value]) => {
|
(acc: { [key: number]: GameMode }, [key, value]: [string, GameMode]) => {
|
||||||
if (value !== undefined) {
|
if (value !== undefined) {
|
||||||
acc[globalThis.Number(key)] = GameMode.fromPartial(value);
|
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]) => {
|
message.roles = (globalThis.Object.entries(object.roles ?? {}) as [string, GameModeRole][]).reduce(
|
||||||
if (value !== undefined) {
|
(acc: { [key: number]: GameModeRole }, [key, value]: [string, GameModeRole]) => {
|
||||||
acc[globalThis.Number(key)] = GameModeRole.fromPartial(value);
|
if (value !== undefined) {
|
||||||
}
|
acc[globalThis.Number(key)] = GameModeRole.fromPartial(value);
|
||||||
return acc;
|
}
|
||||||
}, {});
|
return acc;
|
||||||
|
},
|
||||||
|
{},
|
||||||
|
);
|
||||||
return message;
|
return message;
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
export function createBaseGameDefinitions_GameModesEntry(): GameDefinitions_GameModesEntry {
|
function createBaseGameDefinitions_GameModesEntry(): GameDefinitions_GameModesEntry {
|
||||||
return { key: 0, value: createBaseGameMode() };
|
return { key: 0, value: undefined };
|
||||||
}
|
}
|
||||||
|
|
||||||
export const GameDefinitions_GameModesEntry: MessageFns<GameDefinitions_GameModesEntry> = {
|
export const GameDefinitions_GameModesEntry: MessageFns<GameDefinitions_GameModesEntry> = {
|
||||||
encode(message: GameDefinitions_GameModesEntry, writer: BinaryWriter = new BinaryWriter()): BinaryWriter {
|
encode(message: GameDefinitions_GameModesEntry, writer: BinaryWriter = new BinaryWriter()): BinaryWriter {
|
||||||
if (message.key !== undefined) {
|
if (message.key !== 0) {
|
||||||
writer.uint32(8).uint32(message.key);
|
writer.uint32(8).uint32(message.key);
|
||||||
}
|
}
|
||||||
if (message.value !== undefined) {
|
if (message.value !== undefined) {
|
||||||
@@ -202,7 +211,7 @@ export const GameDefinitions_GameModesEntry: MessageFns<GameDefinitions_GameMode
|
|||||||
|
|
||||||
decode(input: BinaryReader | Uint8Array, length?: number): GameDefinitions_GameModesEntry {
|
decode(input: BinaryReader | Uint8Array, length?: number): GameDefinitions_GameModesEntry {
|
||||||
const reader = input instanceof BinaryReader ? input : new BinaryReader(input);
|
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();
|
const message = createBaseGameDefinitions_GameModesEntry();
|
||||||
while (reader.pos < end) {
|
while (reader.pos < end) {
|
||||||
const tag = reader.uint32();
|
const tag = reader.uint32();
|
||||||
@@ -234,14 +243,14 @@ export const GameDefinitions_GameModesEntry: MessageFns<GameDefinitions_GameMode
|
|||||||
|
|
||||||
fromJSON(object: any): GameDefinitions_GameModesEntry {
|
fromJSON(object: any): GameDefinitions_GameModesEntry {
|
||||||
return {
|
return {
|
||||||
key: globalThis.Number(assertSet("GameDefinitions_GameModesEntry.key", object.key)),
|
key: isSet(object.key) ? globalThis.Number(object.key) : 0,
|
||||||
value: GameMode.fromJSON(assertSet("GameDefinitions_GameModesEntry.value", object.value)),
|
value: isSet(object.value) ? GameMode.fromJSON(object.value) : undefined,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
|
||||||
toJSON(message: GameDefinitions_GameModesEntry): unknown {
|
toJSON(message: GameDefinitions_GameModesEntry): unknown {
|
||||||
const obj: any = {};
|
const obj: any = {};
|
||||||
if (message.key !== undefined) {
|
if (message.key !== 0) {
|
||||||
obj.key = Math.round(message.key);
|
obj.key = Math.round(message.key);
|
||||||
}
|
}
|
||||||
if (message.value !== undefined) {
|
if (message.value !== undefined) {
|
||||||
@@ -260,18 +269,18 @@ export const GameDefinitions_GameModesEntry: MessageFns<GameDefinitions_GameMode
|
|||||||
message.key = object.key ?? 0;
|
message.key = object.key ?? 0;
|
||||||
message.value = (object.value !== undefined && object.value !== null)
|
message.value = (object.value !== undefined && object.value !== null)
|
||||||
? GameMode.fromPartial(object.value)
|
? GameMode.fromPartial(object.value)
|
||||||
: createBaseGameMode();
|
: undefined;
|
||||||
return message;
|
return message;
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
export function createBaseGameDefinitions_RolesEntry(): GameDefinitions_RolesEntry {
|
function createBaseGameDefinitions_RolesEntry(): GameDefinitions_RolesEntry {
|
||||||
return { key: 0, value: createBaseGameModeRole() };
|
return { key: 0, value: undefined };
|
||||||
}
|
}
|
||||||
|
|
||||||
export const GameDefinitions_RolesEntry: MessageFns<GameDefinitions_RolesEntry> = {
|
export const GameDefinitions_RolesEntry: MessageFns<GameDefinitions_RolesEntry> = {
|
||||||
encode(message: GameDefinitions_RolesEntry, writer: BinaryWriter = new BinaryWriter()): BinaryWriter {
|
encode(message: GameDefinitions_RolesEntry, writer: BinaryWriter = new BinaryWriter()): BinaryWriter {
|
||||||
if (message.key !== undefined) {
|
if (message.key !== 0) {
|
||||||
writer.uint32(8).uint32(message.key);
|
writer.uint32(8).uint32(message.key);
|
||||||
}
|
}
|
||||||
if (message.value !== undefined) {
|
if (message.value !== undefined) {
|
||||||
@@ -282,7 +291,7 @@ export const GameDefinitions_RolesEntry: MessageFns<GameDefinitions_RolesEntry>
|
|||||||
|
|
||||||
decode(input: BinaryReader | Uint8Array, length?: number): GameDefinitions_RolesEntry {
|
decode(input: BinaryReader | Uint8Array, length?: number): GameDefinitions_RolesEntry {
|
||||||
const reader = input instanceof BinaryReader ? input : new BinaryReader(input);
|
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();
|
const message = createBaseGameDefinitions_RolesEntry();
|
||||||
while (reader.pos < end) {
|
while (reader.pos < end) {
|
||||||
const tag = reader.uint32();
|
const tag = reader.uint32();
|
||||||
@@ -314,14 +323,14 @@ export const GameDefinitions_RolesEntry: MessageFns<GameDefinitions_RolesEntry>
|
|||||||
|
|
||||||
fromJSON(object: any): GameDefinitions_RolesEntry {
|
fromJSON(object: any): GameDefinitions_RolesEntry {
|
||||||
return {
|
return {
|
||||||
key: globalThis.Number(assertSet("GameDefinitions_RolesEntry.key", object.key)),
|
key: isSet(object.key) ? globalThis.Number(object.key) : 0,
|
||||||
value: GameModeRole.fromJSON(assertSet("GameDefinitions_RolesEntry.value", object.value)),
|
value: isSet(object.value) ? GameModeRole.fromJSON(object.value) : undefined,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
|
||||||
toJSON(message: GameDefinitions_RolesEntry): unknown {
|
toJSON(message: GameDefinitions_RolesEntry): unknown {
|
||||||
const obj: any = {};
|
const obj: any = {};
|
||||||
if (message.key !== undefined) {
|
if (message.key !== 0) {
|
||||||
obj.key = Math.round(message.key);
|
obj.key = Math.round(message.key);
|
||||||
}
|
}
|
||||||
if (message.value !== undefined) {
|
if (message.value !== undefined) {
|
||||||
@@ -338,13 +347,13 @@ export const GameDefinitions_RolesEntry: MessageFns<GameDefinitions_RolesEntry>
|
|||||||
message.key = object.key ?? 0;
|
message.key = object.key ?? 0;
|
||||||
message.value = (object.value !== undefined && object.value !== null)
|
message.value = (object.value !== undefined && object.value !== null)
|
||||||
? GameModeRole.fromPartial(object.value)
|
? GameModeRole.fromPartial(object.value)
|
||||||
: createBaseGameModeRole();
|
: undefined;
|
||||||
return message;
|
return message;
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
export function createBaseGameMode(): GameMode {
|
function createBaseGameMode(): GameMode {
|
||||||
return { name: createBaseI18nString() };
|
return { name: undefined };
|
||||||
}
|
}
|
||||||
|
|
||||||
export const GameMode: MessageFns<GameMode> = {
|
export const GameMode: MessageFns<GameMode> = {
|
||||||
@@ -357,7 +366,7 @@ export const GameMode: MessageFns<GameMode> = {
|
|||||||
|
|
||||||
decode(input: BinaryReader | Uint8Array, length?: number): GameMode {
|
decode(input: BinaryReader | Uint8Array, length?: number): GameMode {
|
||||||
const reader = input instanceof BinaryReader ? input : new BinaryReader(input);
|
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();
|
const message = createBaseGameMode();
|
||||||
while (reader.pos < end) {
|
while (reader.pos < end) {
|
||||||
const tag = reader.uint32();
|
const tag = reader.uint32();
|
||||||
@@ -380,7 +389,7 @@ export const GameMode: MessageFns<GameMode> = {
|
|||||||
},
|
},
|
||||||
|
|
||||||
fromJSON(object: any): 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 {
|
toJSON(message: GameMode): unknown {
|
||||||
@@ -398,33 +407,29 @@ export const GameMode: MessageFns<GameMode> = {
|
|||||||
const message = createBaseGameMode();
|
const message = createBaseGameMode();
|
||||||
message.name = (object.name !== undefined && object.name !== null)
|
message.name = (object.name !== undefined && object.name !== null)
|
||||||
? I18nString.fromPartial(object.name)
|
? I18nString.fromPartial(object.name)
|
||||||
: createBaseI18nString();
|
: undefined;
|
||||||
return message;
|
return message;
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
export function createBaseGameModeRole(): GameModeRole {
|
function createBaseGameModeRole(): GameModeRole {
|
||||||
return { provisions: [], consumables: [] };
|
return { provisions: [], consumables: [] };
|
||||||
}
|
}
|
||||||
|
|
||||||
export const GameModeRole: MessageFns<GameModeRole> = {
|
export const GameModeRole: MessageFns<GameModeRole> = {
|
||||||
encode(message: GameModeRole, writer: BinaryWriter = new BinaryWriter()): BinaryWriter {
|
encode(message: GameModeRole, writer: BinaryWriter = new BinaryWriter()): BinaryWriter {
|
||||||
writer.uint32(10).fork();
|
|
||||||
for (const v of message.provisions) {
|
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) {
|
for (const v of message.consumables) {
|
||||||
writer.uint32(v);
|
writer.uint32(16).uint32(v!);
|
||||||
}
|
}
|
||||||
writer.join();
|
|
||||||
return writer;
|
return writer;
|
||||||
},
|
},
|
||||||
|
|
||||||
decode(input: BinaryReader | Uint8Array, length?: number): GameModeRole {
|
decode(input: BinaryReader | Uint8Array, length?: number): GameModeRole {
|
||||||
const reader = input instanceof BinaryReader ? input : new BinaryReader(input);
|
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();
|
const message = createBaseGameModeRole();
|
||||||
while (reader.pos < end) {
|
while (reader.pos < end) {
|
||||||
const tag = reader.uint32();
|
const tag = reader.uint32();
|
||||||
@@ -528,14 +533,6 @@ function isSet(value: any): boolean {
|
|||||||
return value !== null && value !== undefined;
|
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> {
|
export interface MessageFns<T> {
|
||||||
encode(message: T, writer?: BinaryWriter): BinaryWriter;
|
encode(message: T, writer?: BinaryWriter): BinaryWriter;
|
||||||
decode(input: BinaryReader | Uint8Array, length?: number): T;
|
decode(input: BinaryReader | Uint8Array, length?: number): T;
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
// Code generated by protoc-gen-ts_proto. DO NOT EDIT.
|
// Code generated by protoc-gen-ts_proto. DO NOT EDIT.
|
||||||
// versions:
|
// versions:
|
||||||
// protoc-gen-ts_proto v2.2.2
|
// protoc-gen-ts_proto v2.11.2
|
||||||
// protoc v5.28.2
|
// protoc v5.28.2
|
||||||
// source: packages/core/src/protos/i18n.proto
|
// source: i18n.proto
|
||||||
|
|
||||||
/* eslint-disable */
|
/* eslint-disable */
|
||||||
import { BinaryReader, BinaryWriter } from "@bufbuild/protobuf/wire";
|
import { BinaryReader, BinaryWriter } from "@bufbuild/protobuf/wire";
|
||||||
@@ -18,13 +18,13 @@ export interface I18nString_LocalesEntry {
|
|||||||
value: string;
|
value: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function createBaseI18nString(): I18nString {
|
function createBaseI18nString(): I18nString {
|
||||||
return { locales: {} };
|
return { locales: {} };
|
||||||
}
|
}
|
||||||
|
|
||||||
export const I18nString: MessageFns<I18nString> = {
|
export const I18nString: MessageFns<I18nString> = {
|
||||||
encode(message: I18nString, writer: BinaryWriter = new BinaryWriter()): BinaryWriter {
|
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();
|
I18nString_LocalesEntry.encode({ key: key as any, value }, writer.uint32(10).fork()).join();
|
||||||
});
|
});
|
||||||
return writer;
|
return writer;
|
||||||
@@ -32,7 +32,7 @@ export const I18nString: MessageFns<I18nString> = {
|
|||||||
|
|
||||||
decode(input: BinaryReader | Uint8Array, length?: number): I18nString {
|
decode(input: BinaryReader | Uint8Array, length?: number): I18nString {
|
||||||
const reader = input instanceof BinaryReader ? input : new BinaryReader(input);
|
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();
|
const message = createBaseI18nString();
|
||||||
while (reader.pos < end) {
|
while (reader.pos < end) {
|
||||||
const tag = reader.uint32();
|
const tag = reader.uint32();
|
||||||
@@ -60,10 +60,13 @@ export const I18nString: MessageFns<I18nString> = {
|
|||||||
fromJSON(object: any): I18nString {
|
fromJSON(object: any): I18nString {
|
||||||
return {
|
return {
|
||||||
locales: isObject(object.locales)
|
locales: isObject(object.locales)
|
||||||
? Object.entries(object.locales).reduce<{ [key: string]: string }>((acc, [key, value]) => {
|
? (globalThis.Object.entries(object.locales) as [string, any][]).reduce(
|
||||||
acc[key] = String(value);
|
(acc: { [key: string]: string }, [key, value]: [string, any]) => {
|
||||||
return acc;
|
acc[key] = globalThis.String(value);
|
||||||
}, {})
|
return acc;
|
||||||
|
},
|
||||||
|
{},
|
||||||
|
)
|
||||||
: {},
|
: {},
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
@@ -71,7 +74,7 @@ export const I18nString: MessageFns<I18nString> = {
|
|||||||
toJSON(message: I18nString): unknown {
|
toJSON(message: I18nString): unknown {
|
||||||
const obj: any = {};
|
const obj: any = {};
|
||||||
if (message.locales) {
|
if (message.locales) {
|
||||||
const entries = Object.entries(message.locales);
|
const entries = globalThis.Object.entries(message.locales) as [string, string][];
|
||||||
if (entries.length > 0) {
|
if (entries.length > 0) {
|
||||||
obj.locales = {};
|
obj.locales = {};
|
||||||
entries.forEach(([k, v]) => {
|
entries.forEach(([k, v]) => {
|
||||||
@@ -87,26 +90,29 @@ export const I18nString: MessageFns<I18nString> = {
|
|||||||
},
|
},
|
||||||
fromPartial<I extends Exact<DeepPartial<I18nString>, I>>(object: I): I18nString {
|
fromPartial<I extends Exact<DeepPartial<I18nString>, I>>(object: I): I18nString {
|
||||||
const message = createBaseI18nString();
|
const message = createBaseI18nString();
|
||||||
message.locales = Object.entries(object.locales ?? {}).reduce<{ [key: string]: string }>((acc, [key, value]) => {
|
message.locales = (globalThis.Object.entries(object.locales ?? {}) as [string, string][]).reduce(
|
||||||
if (value !== undefined) {
|
(acc: { [key: string]: string }, [key, value]: [string, string]) => {
|
||||||
acc[key] = globalThis.String(value);
|
if (value !== undefined) {
|
||||||
}
|
acc[key] = globalThis.String(value);
|
||||||
return acc;
|
}
|
||||||
}, {});
|
return acc;
|
||||||
|
},
|
||||||
|
{},
|
||||||
|
);
|
||||||
return message;
|
return message;
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
export function createBaseI18nString_LocalesEntry(): I18nString_LocalesEntry {
|
function createBaseI18nString_LocalesEntry(): I18nString_LocalesEntry {
|
||||||
return { key: "", value: "" };
|
return { key: "", value: "" };
|
||||||
}
|
}
|
||||||
|
|
||||||
export const I18nString_LocalesEntry: MessageFns<I18nString_LocalesEntry> = {
|
export const I18nString_LocalesEntry: MessageFns<I18nString_LocalesEntry> = {
|
||||||
encode(message: I18nString_LocalesEntry, writer: BinaryWriter = new BinaryWriter()): BinaryWriter {
|
encode(message: I18nString_LocalesEntry, writer: BinaryWriter = new BinaryWriter()): BinaryWriter {
|
||||||
if (message.key !== undefined) {
|
if (message.key !== "") {
|
||||||
writer.uint32(10).string(message.key);
|
writer.uint32(10).string(message.key);
|
||||||
}
|
}
|
||||||
if (message.value !== undefined) {
|
if (message.value !== "") {
|
||||||
writer.uint32(18).string(message.value);
|
writer.uint32(18).string(message.value);
|
||||||
}
|
}
|
||||||
return writer;
|
return writer;
|
||||||
@@ -114,7 +120,7 @@ export const I18nString_LocalesEntry: MessageFns<I18nString_LocalesEntry> = {
|
|||||||
|
|
||||||
decode(input: BinaryReader | Uint8Array, length?: number): I18nString_LocalesEntry {
|
decode(input: BinaryReader | Uint8Array, length?: number): I18nString_LocalesEntry {
|
||||||
const reader = input instanceof BinaryReader ? input : new BinaryReader(input);
|
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();
|
const message = createBaseI18nString_LocalesEntry();
|
||||||
while (reader.pos < end) {
|
while (reader.pos < end) {
|
||||||
const tag = reader.uint32();
|
const tag = reader.uint32();
|
||||||
@@ -146,17 +152,17 @@ export const I18nString_LocalesEntry: MessageFns<I18nString_LocalesEntry> = {
|
|||||||
|
|
||||||
fromJSON(object: any): I18nString_LocalesEntry {
|
fromJSON(object: any): I18nString_LocalesEntry {
|
||||||
return {
|
return {
|
||||||
key: globalThis.String(assertSet("I18nString_LocalesEntry.key", object.key)),
|
key: isSet(object.key) ? globalThis.String(object.key) : "",
|
||||||
value: globalThis.String(assertSet("I18nString_LocalesEntry.value", object.value)),
|
value: isSet(object.value) ? globalThis.String(object.value) : "",
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
|
||||||
toJSON(message: I18nString_LocalesEntry): unknown {
|
toJSON(message: I18nString_LocalesEntry): unknown {
|
||||||
const obj: any = {};
|
const obj: any = {};
|
||||||
if (message.key !== undefined) {
|
if (message.key !== "") {
|
||||||
obj.key = message.key;
|
obj.key = message.key;
|
||||||
}
|
}
|
||||||
if (message.value !== undefined) {
|
if (message.value !== "") {
|
||||||
obj.value = message.value;
|
obj.value = message.value;
|
||||||
}
|
}
|
||||||
return obj;
|
return obj;
|
||||||
@@ -194,14 +200,6 @@ function isSet(value: any): boolean {
|
|||||||
return value !== null && value !== undefined;
|
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> {
|
export interface MessageFns<T> {
|
||||||
encode(message: T, writer?: BinaryWriter): BinaryWriter;
|
encode(message: T, writer?: BinaryWriter): BinaryWriter;
|
||||||
decode(input: BinaryReader | Uint8Array, length?: number): T;
|
decode(input: BinaryReader | Uint8Array, length?: number): T;
|
||||||
|
|||||||
@@ -1,16 +1,16 @@
|
|||||||
// @ts-nocheck
|
// @ts-nocheck
|
||||||
export * from './average_definitions.ts';
|
export * from "./average_definitions.ts";
|
||||||
export * from './camouflage_definitions.ts';
|
export * from "./camouflage_definitions.ts";
|
||||||
export * from './consumable_definitions.ts';
|
export * from "./consumable_definitions.ts";
|
||||||
export * from './equipment_definitions.ts';
|
export * from "./equipment_definitions.ts";
|
||||||
export * from './gallery.ts';
|
export * from "./gallery.ts";
|
||||||
export * from './game_definitions.ts';
|
export * from "./game_definitions.ts";
|
||||||
export * from './i18n.ts';
|
export * from "./i18n.ts";
|
||||||
export * from './map_definitions.ts';
|
export * from "./map_definitions.ts";
|
||||||
export * from './model_definitions.ts';
|
export * from "./model_definitions.ts";
|
||||||
export * from './popular_tanks.ts';
|
export * from "./popular_tanks.ts";
|
||||||
export * from './provision_definitions.ts';
|
export * from "./provision_definitions.ts";
|
||||||
export * from './rating_leaderboard.ts';
|
export * from "./rating_leaderboard.ts";
|
||||||
export * from './reviews.ts';
|
export * from "./reviews.ts";
|
||||||
export * from './skill_definitions.ts';
|
export * from "./skill_definitions.ts";
|
||||||
export * from './tank_definitions.ts';
|
export * from "./tank_definitions.ts";
|
||||||
@@ -2,13 +2,13 @@ syntax = "proto2";
|
|||||||
|
|
||||||
package blitzkit;
|
package blitzkit;
|
||||||
|
|
||||||
import "packages/core/src/protos/i18n.proto";
|
import "i18n.proto";
|
||||||
|
|
||||||
message MapDefinitions {
|
message MapDefinitions {
|
||||||
map<int32, MapDefinition> maps = 1;
|
map<int32, MapDefinition> maps = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
message MapDefinition {
|
message MapDefinition {
|
||||||
required uint32 id = 1;
|
required uint32 id = 1;
|
||||||
required I18nString name = 2;
|
required I18nString name = 2;
|
||||||
}
|
}
|
||||||
@@ -1,12 +1,12 @@
|
|||||||
// Code generated by protoc-gen-ts_proto. DO NOT EDIT.
|
// Code generated by protoc-gen-ts_proto. DO NOT EDIT.
|
||||||
// versions:
|
// versions:
|
||||||
// protoc-gen-ts_proto v2.2.2
|
// protoc-gen-ts_proto v2.11.2
|
||||||
// protoc v5.28.2
|
// protoc v5.28.2
|
||||||
// source: packages/core/src/protos/map_definitions.proto
|
// source: map_definitions.proto
|
||||||
|
|
||||||
/* eslint-disable */
|
/* eslint-disable */
|
||||||
import { BinaryReader, BinaryWriter } from "@bufbuild/protobuf/wire";
|
import { BinaryReader, BinaryWriter } from "@bufbuild/protobuf/wire";
|
||||||
import { createBaseI18nString, I18nString } from "./i18n";
|
import { I18nString } from "./i18n";
|
||||||
|
|
||||||
export const protobufPackage = "blitzkit";
|
export const protobufPackage = "blitzkit";
|
||||||
|
|
||||||
@@ -21,16 +21,16 @@ export interface MapDefinitions_MapsEntry {
|
|||||||
|
|
||||||
export interface MapDefinition {
|
export interface MapDefinition {
|
||||||
id: number;
|
id: number;
|
||||||
name: I18nString;
|
name: I18nString | undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function createBaseMapDefinitions(): MapDefinitions {
|
function createBaseMapDefinitions(): MapDefinitions {
|
||||||
return { maps: {} };
|
return { maps: {} };
|
||||||
}
|
}
|
||||||
|
|
||||||
export const MapDefinitions: MessageFns<MapDefinitions> = {
|
export const MapDefinitions: MessageFns<MapDefinitions> = {
|
||||||
encode(message: MapDefinitions, writer: BinaryWriter = new BinaryWriter()): BinaryWriter {
|
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();
|
MapDefinitions_MapsEntry.encode({ key: key as any, value }, writer.uint32(10).fork()).join();
|
||||||
});
|
});
|
||||||
return writer;
|
return writer;
|
||||||
@@ -38,7 +38,7 @@ export const MapDefinitions: MessageFns<MapDefinitions> = {
|
|||||||
|
|
||||||
decode(input: BinaryReader | Uint8Array, length?: number): MapDefinitions {
|
decode(input: BinaryReader | Uint8Array, length?: number): MapDefinitions {
|
||||||
const reader = input instanceof BinaryReader ? input : new BinaryReader(input);
|
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();
|
const message = createBaseMapDefinitions();
|
||||||
while (reader.pos < end) {
|
while (reader.pos < end) {
|
||||||
const tag = reader.uint32();
|
const tag = reader.uint32();
|
||||||
@@ -66,10 +66,13 @@ export const MapDefinitions: MessageFns<MapDefinitions> = {
|
|||||||
fromJSON(object: any): MapDefinitions {
|
fromJSON(object: any): MapDefinitions {
|
||||||
return {
|
return {
|
||||||
maps: isObject(object.maps)
|
maps: isObject(object.maps)
|
||||||
? Object.entries(object.maps).reduce<{ [key: number]: MapDefinition }>((acc, [key, value]) => {
|
? (globalThis.Object.entries(object.maps) as [string, any][]).reduce(
|
||||||
acc[globalThis.Number(key)] = MapDefinition.fromJSON(value);
|
(acc: { [key: number]: MapDefinition }, [key, value]: [string, any]) => {
|
||||||
return acc;
|
acc[globalThis.Number(key)] = MapDefinition.fromJSON(value);
|
||||||
}, {})
|
return acc;
|
||||||
|
},
|
||||||
|
{},
|
||||||
|
)
|
||||||
: {},
|
: {},
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
@@ -77,7 +80,7 @@ export const MapDefinitions: MessageFns<MapDefinitions> = {
|
|||||||
toJSON(message: MapDefinitions): unknown {
|
toJSON(message: MapDefinitions): unknown {
|
||||||
const obj: any = {};
|
const obj: any = {};
|
||||||
if (message.maps) {
|
if (message.maps) {
|
||||||
const entries = Object.entries(message.maps);
|
const entries = globalThis.Object.entries(message.maps) as [string, MapDefinition][];
|
||||||
if (entries.length > 0) {
|
if (entries.length > 0) {
|
||||||
obj.maps = {};
|
obj.maps = {};
|
||||||
entries.forEach(([k, v]) => {
|
entries.forEach(([k, v]) => {
|
||||||
@@ -93,23 +96,26 @@ export const MapDefinitions: MessageFns<MapDefinitions> = {
|
|||||||
},
|
},
|
||||||
fromPartial<I extends Exact<DeepPartial<MapDefinitions>, I>>(object: I): MapDefinitions {
|
fromPartial<I extends Exact<DeepPartial<MapDefinitions>, I>>(object: I): MapDefinitions {
|
||||||
const message = createBaseMapDefinitions();
|
const message = createBaseMapDefinitions();
|
||||||
message.maps = Object.entries(object.maps ?? {}).reduce<{ [key: number]: MapDefinition }>((acc, [key, value]) => {
|
message.maps = (globalThis.Object.entries(object.maps ?? {}) as [string, MapDefinition][]).reduce(
|
||||||
if (value !== undefined) {
|
(acc: { [key: number]: MapDefinition }, [key, value]: [string, MapDefinition]) => {
|
||||||
acc[globalThis.Number(key)] = MapDefinition.fromPartial(value);
|
if (value !== undefined) {
|
||||||
}
|
acc[globalThis.Number(key)] = MapDefinition.fromPartial(value);
|
||||||
return acc;
|
}
|
||||||
}, {});
|
return acc;
|
||||||
|
},
|
||||||
|
{},
|
||||||
|
);
|
||||||
return message;
|
return message;
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
export function createBaseMapDefinitions_MapsEntry(): MapDefinitions_MapsEntry {
|
function createBaseMapDefinitions_MapsEntry(): MapDefinitions_MapsEntry {
|
||||||
return { key: 0, value: createBaseMapDefinition() };
|
return { key: 0, value: undefined };
|
||||||
}
|
}
|
||||||
|
|
||||||
export const MapDefinitions_MapsEntry: MessageFns<MapDefinitions_MapsEntry> = {
|
export const MapDefinitions_MapsEntry: MessageFns<MapDefinitions_MapsEntry> = {
|
||||||
encode(message: MapDefinitions_MapsEntry, writer: BinaryWriter = new BinaryWriter()): BinaryWriter {
|
encode(message: MapDefinitions_MapsEntry, writer: BinaryWriter = new BinaryWriter()): BinaryWriter {
|
||||||
if (message.key !== undefined) {
|
if (message.key !== 0) {
|
||||||
writer.uint32(8).int32(message.key);
|
writer.uint32(8).int32(message.key);
|
||||||
}
|
}
|
||||||
if (message.value !== undefined) {
|
if (message.value !== undefined) {
|
||||||
@@ -120,7 +126,7 @@ export const MapDefinitions_MapsEntry: MessageFns<MapDefinitions_MapsEntry> = {
|
|||||||
|
|
||||||
decode(input: BinaryReader | Uint8Array, length?: number): MapDefinitions_MapsEntry {
|
decode(input: BinaryReader | Uint8Array, length?: number): MapDefinitions_MapsEntry {
|
||||||
const reader = input instanceof BinaryReader ? input : new BinaryReader(input);
|
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();
|
const message = createBaseMapDefinitions_MapsEntry();
|
||||||
while (reader.pos < end) {
|
while (reader.pos < end) {
|
||||||
const tag = reader.uint32();
|
const tag = reader.uint32();
|
||||||
@@ -152,14 +158,14 @@ export const MapDefinitions_MapsEntry: MessageFns<MapDefinitions_MapsEntry> = {
|
|||||||
|
|
||||||
fromJSON(object: any): MapDefinitions_MapsEntry {
|
fromJSON(object: any): MapDefinitions_MapsEntry {
|
||||||
return {
|
return {
|
||||||
key: globalThis.Number(assertSet("MapDefinitions_MapsEntry.key", object.key)),
|
key: isSet(object.key) ? globalThis.Number(object.key) : 0,
|
||||||
value: MapDefinition.fromJSON(assertSet("MapDefinitions_MapsEntry.value", object.value)),
|
value: isSet(object.value) ? MapDefinition.fromJSON(object.value) : undefined,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
|
||||||
toJSON(message: MapDefinitions_MapsEntry): unknown {
|
toJSON(message: MapDefinitions_MapsEntry): unknown {
|
||||||
const obj: any = {};
|
const obj: any = {};
|
||||||
if (message.key !== undefined) {
|
if (message.key !== 0) {
|
||||||
obj.key = Math.round(message.key);
|
obj.key = Math.round(message.key);
|
||||||
}
|
}
|
||||||
if (message.value !== undefined) {
|
if (message.value !== undefined) {
|
||||||
@@ -176,13 +182,13 @@ export const MapDefinitions_MapsEntry: MessageFns<MapDefinitions_MapsEntry> = {
|
|||||||
message.key = object.key ?? 0;
|
message.key = object.key ?? 0;
|
||||||
message.value = (object.value !== undefined && object.value !== null)
|
message.value = (object.value !== undefined && object.value !== null)
|
||||||
? MapDefinition.fromPartial(object.value)
|
? MapDefinition.fromPartial(object.value)
|
||||||
: createBaseMapDefinition();
|
: undefined;
|
||||||
return message;
|
return message;
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
export function createBaseMapDefinition(): MapDefinition {
|
function createBaseMapDefinition(): MapDefinition {
|
||||||
return { id: 0, name: createBaseI18nString() };
|
return { id: 0, name: undefined };
|
||||||
}
|
}
|
||||||
|
|
||||||
export const MapDefinition: MessageFns<MapDefinition> = {
|
export const MapDefinition: MessageFns<MapDefinition> = {
|
||||||
@@ -198,7 +204,7 @@ export const MapDefinition: MessageFns<MapDefinition> = {
|
|||||||
|
|
||||||
decode(input: BinaryReader | Uint8Array, length?: number): MapDefinition {
|
decode(input: BinaryReader | Uint8Array, length?: number): MapDefinition {
|
||||||
const reader = input instanceof BinaryReader ? input : new BinaryReader(input);
|
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();
|
const message = createBaseMapDefinition();
|
||||||
while (reader.pos < end) {
|
while (reader.pos < end) {
|
||||||
const tag = reader.uint32();
|
const tag = reader.uint32();
|
||||||
@@ -230,8 +236,8 @@ export const MapDefinition: MessageFns<MapDefinition> = {
|
|||||||
|
|
||||||
fromJSON(object: any): MapDefinition {
|
fromJSON(object: any): MapDefinition {
|
||||||
return {
|
return {
|
||||||
id: globalThis.Number(assertSet("MapDefinition.id", object.id)),
|
id: isSet(object.id) ? globalThis.Number(object.id) : 0,
|
||||||
name: I18nString.fromJSON(assertSet("MapDefinition.name", object.name)),
|
name: isSet(object.name) ? I18nString.fromJSON(object.name) : undefined,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
|
||||||
@@ -254,7 +260,7 @@ export const MapDefinition: MessageFns<MapDefinition> = {
|
|||||||
message.id = object.id ?? 0;
|
message.id = object.id ?? 0;
|
||||||
message.name = (object.name !== undefined && object.name !== null)
|
message.name = (object.name !== undefined && object.name !== null)
|
||||||
? I18nString.fromPartial(object.name)
|
? I18nString.fromPartial(object.name)
|
||||||
: createBaseI18nString();
|
: undefined;
|
||||||
return message;
|
return message;
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
@@ -280,14 +286,6 @@ function isSet(value: any): boolean {
|
|||||||
return value !== null && value !== undefined;
|
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> {
|
export interface MessageFns<T> {
|
||||||
encode(message: T, writer?: BinaryWriter): BinaryWriter;
|
encode(message: T, writer?: BinaryWriter): BinaryWriter;
|
||||||
decode(input: BinaryReader | Uint8Array, length?: number): T;
|
decode(input: BinaryReader | Uint8Array, length?: number): T;
|
||||||
|
|||||||
@@ -7,17 +7,17 @@ message ModelDefinitions {
|
|||||||
}
|
}
|
||||||
|
|
||||||
message ModelDefinition {
|
message ModelDefinition {
|
||||||
required Armor armor = 1;
|
required Armor armor = 1;
|
||||||
required Vector3 turret_origin = 2;
|
required Vector3 turret_origin = 2;
|
||||||
optional InitialTurretRotation initial_turret_rotation = 3;
|
optional InitialTurretRotation initial_turret_rotation = 3;
|
||||||
map<uint32, TurretModelDefinition> turrets = 4;
|
map<uint32, TurretModelDefinition> turrets = 4;
|
||||||
map<uint32, TrackModelDefinition> tracks = 5;
|
map<uint32, TrackModelDefinition> tracks = 5;
|
||||||
required BoundingBox bounding_box = 6;
|
required BoundingBox bounding_box = 6;
|
||||||
}
|
}
|
||||||
|
|
||||||
message Armor {
|
message Armor {
|
||||||
map<uint32, float> thickness = 1;
|
map<uint32, float> thickness = 1;
|
||||||
repeated uint32 spaced = 2;
|
repeated uint32 spaced = 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
message Vector3 {
|
message Vector3 {
|
||||||
@@ -27,18 +27,18 @@ message Vector3 {
|
|||||||
}
|
}
|
||||||
|
|
||||||
message InitialTurretRotation {
|
message InitialTurretRotation {
|
||||||
required float yaw = 1;
|
required float yaw = 1;
|
||||||
required float pitch = 2;
|
required float pitch = 2;
|
||||||
required float roll = 3;
|
required float roll = 3;
|
||||||
}
|
}
|
||||||
|
|
||||||
message TurretModelDefinition {
|
message TurretModelDefinition {
|
||||||
required BoundingBox bounding_box = 1;
|
required BoundingBox bounding_box = 1;
|
||||||
required Armor armor = 2;
|
required Armor armor = 2;
|
||||||
required uint32 model_id = 3;
|
required uint32 model_id = 3;
|
||||||
required Vector3 gun_origin = 4;
|
required Vector3 gun_origin = 4;
|
||||||
map<uint32, GunModelDefinition> guns = 5;
|
map<uint32, GunModelDefinition> guns = 5;
|
||||||
optional YawLimits yaw = 6;
|
optional YawLimits yaw = 6;
|
||||||
}
|
}
|
||||||
|
|
||||||
message YawLimits {
|
message YawLimits {
|
||||||
@@ -52,28 +52,28 @@ message BoundingBox {
|
|||||||
}
|
}
|
||||||
|
|
||||||
message TrackModelDefinition {
|
message TrackModelDefinition {
|
||||||
required float thickness = 1;
|
required float thickness = 1;
|
||||||
required Vector3 origin = 2;
|
required Vector3 origin = 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
message GunModelDefinition {
|
message GunModelDefinition {
|
||||||
required Armor armor = 1;
|
required Armor armor = 1;
|
||||||
required float thickness = 2;
|
required float thickness = 2;
|
||||||
required uint32 model_id = 3;
|
required uint32 model_id = 3;
|
||||||
required PitchLimits pitch = 4;
|
required PitchLimits pitch = 4;
|
||||||
optional float mask = 5;
|
optional float mask = 5;
|
||||||
}
|
}
|
||||||
|
|
||||||
message PitchLimits {
|
message PitchLimits {
|
||||||
required float min = 1;
|
required float min = 1;
|
||||||
required float max = 2;
|
required float max = 2;
|
||||||
optional PitchLimitsExtrema front = 3;
|
optional PitchLimitsExtrema front = 3;
|
||||||
optional PitchLimitsExtrema back = 4;
|
optional PitchLimitsExtrema back = 4;
|
||||||
optional float transition = 5;
|
optional float transition = 5;
|
||||||
}
|
}
|
||||||
|
|
||||||
message PitchLimitsExtrema {
|
message PitchLimitsExtrema {
|
||||||
required float min = 1;
|
required float min = 1;
|
||||||
required float max = 2;
|
required float max = 2;
|
||||||
required float range = 3;
|
required float range = 3;
|
||||||
}
|
}
|
||||||
File diff suppressed because it is too large.
Load diff
@@ -7,6 +7,6 @@ message PopularTanks {
|
|||||||
}
|
}
|
||||||
|
|
||||||
message PopularTank {
|
message PopularTank {
|
||||||
required uint32 id = 1;
|
required uint32 id = 1;
|
||||||
required uint32 views = 2; // views in the last 7 days
|
required uint32 views = 2; // views in the last 7 days
|
||||||
}
|
}
|
||||||
@@ -1,8 +1,8 @@
|
|||||||
// Code generated by protoc-gen-ts_proto. DO NOT EDIT.
|
// Code generated by protoc-gen-ts_proto. DO NOT EDIT.
|
||||||
// versions:
|
// versions:
|
||||||
// protoc-gen-ts_proto v2.2.2
|
// protoc-gen-ts_proto v2.11.2
|
||||||
// protoc v5.28.2
|
// protoc v5.28.2
|
||||||
// source: packages/core/src/protos/popular_tanks.proto
|
// source: popular_tanks.proto
|
||||||
|
|
||||||
/* eslint-disable */
|
/* eslint-disable */
|
||||||
import { BinaryReader, BinaryWriter } from "@bufbuild/protobuf/wire";
|
import { BinaryReader, BinaryWriter } from "@bufbuild/protobuf/wire";
|
||||||
@@ -19,7 +19,7 @@ export interface PopularTank {
|
|||||||
views: number;
|
views: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function createBasePopularTanks(): PopularTanks {
|
function createBasePopularTanks(): PopularTanks {
|
||||||
return { tanks: [] };
|
return { tanks: [] };
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -33,7 +33,7 @@ export const PopularTanks: MessageFns<PopularTanks> = {
|
|||||||
|
|
||||||
decode(input: BinaryReader | Uint8Array, length?: number): PopularTanks {
|
decode(input: BinaryReader | Uint8Array, length?: number): PopularTanks {
|
||||||
const reader = input instanceof BinaryReader ? input : new BinaryReader(input);
|
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();
|
const message = createBasePopularTanks();
|
||||||
while (reader.pos < end) {
|
while (reader.pos < end) {
|
||||||
const tag = reader.uint32();
|
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 };
|
return { id: 0, views: 0 };
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -96,7 +96,7 @@ export const PopularTank: MessageFns<PopularTank> = {
|
|||||||
|
|
||||||
decode(input: BinaryReader | Uint8Array, length?: number): PopularTank {
|
decode(input: BinaryReader | Uint8Array, length?: number): PopularTank {
|
||||||
const reader = input instanceof BinaryReader ? input : new BinaryReader(input);
|
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();
|
const message = createBasePopularTank();
|
||||||
while (reader.pos < end) {
|
while (reader.pos < end) {
|
||||||
const tag = reader.uint32();
|
const tag = reader.uint32();
|
||||||
@@ -128,8 +128,8 @@ export const PopularTank: MessageFns<PopularTank> = {
|
|||||||
|
|
||||||
fromJSON(object: any): PopularTank {
|
fromJSON(object: any): PopularTank {
|
||||||
return {
|
return {
|
||||||
id: globalThis.Number(assertSet("PopularTank.id", object.id)),
|
id: isSet(object.id) ? globalThis.Number(object.id) : 0,
|
||||||
views: globalThis.Number(assertSet("PopularTank.views", object.views)),
|
views: isSet(object.views) ? globalThis.Number(object.views) : 0,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
|
||||||
@@ -172,14 +172,6 @@ function isSet(value: any): boolean {
|
|||||||
return value !== null && value !== undefined;
|
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> {
|
export interface MessageFns<T> {
|
||||||
encode(message: T, writer?: BinaryWriter): BinaryWriter;
|
encode(message: T, writer?: BinaryWriter): BinaryWriter;
|
||||||
decode(input: BinaryReader | Uint8Array, length?: number): T;
|
decode(input: BinaryReader | Uint8Array, length?: number): T;
|
||||||
|
|||||||
@@ -2,18 +2,18 @@ syntax = "proto2";
|
|||||||
|
|
||||||
package blitzkit;
|
package blitzkit;
|
||||||
|
|
||||||
import "packages/core/src/protos/consumable_definitions.proto";
|
import "consumable_definitions.proto";
|
||||||
import "packages/core/src/protos/i18n.proto";
|
import "i18n.proto";
|
||||||
|
|
||||||
message ProvisionDefinitions {
|
message ProvisionDefinitions {
|
||||||
map<uint32, Provision> provisions = 1;
|
map<uint32, Provision> provisions = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
message Provision {
|
message Provision {
|
||||||
required uint32 id = 1;
|
required uint32 id = 1;
|
||||||
required I18nString name = 2;
|
required I18nString name = 2;
|
||||||
optional float crew = 3;
|
optional float crew = 3;
|
||||||
required bool game_mode_exclusive = 5;
|
required bool game_mode_exclusive = 5;
|
||||||
repeated ConsumableTankFilter include = 6;
|
repeated ConsumableTankFilter include = 6;
|
||||||
repeated ConsumableTankFilter exclude = 7;
|
repeated ConsumableTankFilter exclude = 7;
|
||||||
}
|
}
|
||||||
@@ -1,13 +1,13 @@
|
|||||||
// Code generated by protoc-gen-ts_proto. DO NOT EDIT.
|
// Code generated by protoc-gen-ts_proto. DO NOT EDIT.
|
||||||
// versions:
|
// versions:
|
||||||
// protoc-gen-ts_proto v2.2.2
|
// protoc-gen-ts_proto v2.11.2
|
||||||
// protoc v5.28.2
|
// protoc v5.28.2
|
||||||
// source: packages/core/src/protos/provision_definitions.proto
|
// source: provision_definitions.proto
|
||||||
|
|
||||||
/* eslint-disable */
|
/* eslint-disable */
|
||||||
import { BinaryReader, BinaryWriter } from "@bufbuild/protobuf/wire";
|
import { BinaryReader, BinaryWriter } from "@bufbuild/protobuf/wire";
|
||||||
import { ConsumableTankFilter } from "./consumable_definitions";
|
import { ConsumableTankFilter } from "./consumable_definitions";
|
||||||
import { createBaseI18nString, I18nString } from "./i18n";
|
import { I18nString } from "./i18n";
|
||||||
|
|
||||||
export const protobufPackage = "blitzkit";
|
export const protobufPackage = "blitzkit";
|
||||||
|
|
||||||
@@ -22,20 +22,20 @@ export interface ProvisionDefinitions_ProvisionsEntry {
|
|||||||
|
|
||||||
export interface Provision {
|
export interface Provision {
|
||||||
id: number;
|
id: number;
|
||||||
name: I18nString;
|
name: I18nString | undefined;
|
||||||
crew?: number | undefined;
|
crew?: number | undefined;
|
||||||
game_mode_exclusive: boolean;
|
game_mode_exclusive: boolean;
|
||||||
include: ConsumableTankFilter[];
|
include: ConsumableTankFilter[];
|
||||||
exclude: ConsumableTankFilter[];
|
exclude: ConsumableTankFilter[];
|
||||||
}
|
}
|
||||||
|
|
||||||
export function createBaseProvisionDefinitions(): ProvisionDefinitions {
|
function createBaseProvisionDefinitions(): ProvisionDefinitions {
|
||||||
return { provisions: {} };
|
return { provisions: {} };
|
||||||
}
|
}
|
||||||
|
|
||||||
export const ProvisionDefinitions: MessageFns<ProvisionDefinitions> = {
|
export const ProvisionDefinitions: MessageFns<ProvisionDefinitions> = {
|
||||||
encode(message: ProvisionDefinitions, writer: BinaryWriter = new BinaryWriter()): BinaryWriter {
|
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();
|
ProvisionDefinitions_ProvisionsEntry.encode({ key: key as any, value }, writer.uint32(10).fork()).join();
|
||||||
});
|
});
|
||||||
return writer;
|
return writer;
|
||||||
@@ -43,7 +43,7 @@ export const ProvisionDefinitions: MessageFns<ProvisionDefinitions> = {
|
|||||||
|
|
||||||
decode(input: BinaryReader | Uint8Array, length?: number): ProvisionDefinitions {
|
decode(input: BinaryReader | Uint8Array, length?: number): ProvisionDefinitions {
|
||||||
const reader = input instanceof BinaryReader ? input : new BinaryReader(input);
|
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();
|
const message = createBaseProvisionDefinitions();
|
||||||
while (reader.pos < end) {
|
while (reader.pos < end) {
|
||||||
const tag = reader.uint32();
|
const tag = reader.uint32();
|
||||||
@@ -71,10 +71,13 @@ export const ProvisionDefinitions: MessageFns<ProvisionDefinitions> = {
|
|||||||
fromJSON(object: any): ProvisionDefinitions {
|
fromJSON(object: any): ProvisionDefinitions {
|
||||||
return {
|
return {
|
||||||
provisions: isObject(object.provisions)
|
provisions: isObject(object.provisions)
|
||||||
? Object.entries(object.provisions).reduce<{ [key: number]: Provision }>((acc, [key, value]) => {
|
? (globalThis.Object.entries(object.provisions) as [string, any][]).reduce(
|
||||||
acc[globalThis.Number(key)] = Provision.fromJSON(value);
|
(acc: { [key: number]: Provision }, [key, value]: [string, any]) => {
|
||||||
return acc;
|
acc[globalThis.Number(key)] = Provision.fromJSON(value);
|
||||||
}, {})
|
return acc;
|
||||||
|
},
|
||||||
|
{},
|
||||||
|
)
|
||||||
: {},
|
: {},
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
@@ -82,7 +85,7 @@ export const ProvisionDefinitions: MessageFns<ProvisionDefinitions> = {
|
|||||||
toJSON(message: ProvisionDefinitions): unknown {
|
toJSON(message: ProvisionDefinitions): unknown {
|
||||||
const obj: any = {};
|
const obj: any = {};
|
||||||
if (message.provisions) {
|
if (message.provisions) {
|
||||||
const entries = Object.entries(message.provisions);
|
const entries = globalThis.Object.entries(message.provisions) as [string, Provision][];
|
||||||
if (entries.length > 0) {
|
if (entries.length > 0) {
|
||||||
obj.provisions = {};
|
obj.provisions = {};
|
||||||
entries.forEach(([k, v]) => {
|
entries.forEach(([k, v]) => {
|
||||||
@@ -98,8 +101,8 @@ export const ProvisionDefinitions: MessageFns<ProvisionDefinitions> = {
|
|||||||
},
|
},
|
||||||
fromPartial<I extends Exact<DeepPartial<ProvisionDefinitions>, I>>(object: I): ProvisionDefinitions {
|
fromPartial<I extends Exact<DeepPartial<ProvisionDefinitions>, I>>(object: I): ProvisionDefinitions {
|
||||||
const message = createBaseProvisionDefinitions();
|
const message = createBaseProvisionDefinitions();
|
||||||
message.provisions = Object.entries(object.provisions ?? {}).reduce<{ [key: number]: Provision }>(
|
message.provisions = (globalThis.Object.entries(object.provisions ?? {}) as [string, Provision][]).reduce(
|
||||||
(acc, [key, value]) => {
|
(acc: { [key: number]: Provision }, [key, value]: [string, Provision]) => {
|
||||||
if (value !== undefined) {
|
if (value !== undefined) {
|
||||||
acc[globalThis.Number(key)] = Provision.fromPartial(value);
|
acc[globalThis.Number(key)] = Provision.fromPartial(value);
|
||||||
}
|
}
|
||||||
@@ -111,13 +114,13 @@ export const ProvisionDefinitions: MessageFns<ProvisionDefinitions> = {
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
export function createBaseProvisionDefinitions_ProvisionsEntry(): ProvisionDefinitions_ProvisionsEntry {
|
function createBaseProvisionDefinitions_ProvisionsEntry(): ProvisionDefinitions_ProvisionsEntry {
|
||||||
return { key: 0, value: createBaseProvision() };
|
return { key: 0, value: undefined };
|
||||||
}
|
}
|
||||||
|
|
||||||
export const ProvisionDefinitions_ProvisionsEntry: MessageFns<ProvisionDefinitions_ProvisionsEntry> = {
|
export const ProvisionDefinitions_ProvisionsEntry: MessageFns<ProvisionDefinitions_ProvisionsEntry> = {
|
||||||
encode(message: ProvisionDefinitions_ProvisionsEntry, writer: BinaryWriter = new BinaryWriter()): BinaryWriter {
|
encode(message: ProvisionDefinitions_ProvisionsEntry, writer: BinaryWriter = new BinaryWriter()): BinaryWriter {
|
||||||
if (message.key !== undefined) {
|
if (message.key !== 0) {
|
||||||
writer.uint32(8).uint32(message.key);
|
writer.uint32(8).uint32(message.key);
|
||||||
}
|
}
|
||||||
if (message.value !== undefined) {
|
if (message.value !== undefined) {
|
||||||
@@ -128,7 +131,7 @@ export const ProvisionDefinitions_ProvisionsEntry: MessageFns<ProvisionDefinitio
|
|||||||
|
|
||||||
decode(input: BinaryReader | Uint8Array, length?: number): ProvisionDefinitions_ProvisionsEntry {
|
decode(input: BinaryReader | Uint8Array, length?: number): ProvisionDefinitions_ProvisionsEntry {
|
||||||
const reader = input instanceof BinaryReader ? input : new BinaryReader(input);
|
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();
|
const message = createBaseProvisionDefinitions_ProvisionsEntry();
|
||||||
while (reader.pos < end) {
|
while (reader.pos < end) {
|
||||||
const tag = reader.uint32();
|
const tag = reader.uint32();
|
||||||
@@ -160,14 +163,14 @@ export const ProvisionDefinitions_ProvisionsEntry: MessageFns<ProvisionDefinitio
|
|||||||
|
|
||||||
fromJSON(object: any): ProvisionDefinitions_ProvisionsEntry {
|
fromJSON(object: any): ProvisionDefinitions_ProvisionsEntry {
|
||||||
return {
|
return {
|
||||||
key: globalThis.Number(assertSet("ProvisionDefinitions_ProvisionsEntry.key", object.key)),
|
key: isSet(object.key) ? globalThis.Number(object.key) : 0,
|
||||||
value: Provision.fromJSON(assertSet("ProvisionDefinitions_ProvisionsEntry.value", object.value)),
|
value: isSet(object.value) ? Provision.fromJSON(object.value) : undefined,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
|
||||||
toJSON(message: ProvisionDefinitions_ProvisionsEntry): unknown {
|
toJSON(message: ProvisionDefinitions_ProvisionsEntry): unknown {
|
||||||
const obj: any = {};
|
const obj: any = {};
|
||||||
if (message.key !== undefined) {
|
if (message.key !== 0) {
|
||||||
obj.key = Math.round(message.key);
|
obj.key = Math.round(message.key);
|
||||||
}
|
}
|
||||||
if (message.value !== undefined) {
|
if (message.value !== undefined) {
|
||||||
@@ -188,13 +191,13 @@ export const ProvisionDefinitions_ProvisionsEntry: MessageFns<ProvisionDefinitio
|
|||||||
message.key = object.key ?? 0;
|
message.key = object.key ?? 0;
|
||||||
message.value = (object.value !== undefined && object.value !== null)
|
message.value = (object.value !== undefined && object.value !== null)
|
||||||
? Provision.fromPartial(object.value)
|
? Provision.fromPartial(object.value)
|
||||||
: createBaseProvision();
|
: undefined;
|
||||||
return message;
|
return message;
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
export function createBaseProvision(): Provision {
|
function createBaseProvision(): Provision {
|
||||||
return { id: 0, name: createBaseI18nString(), crew: undefined, game_mode_exclusive: false, include: [], exclude: [] };
|
return { id: 0, name: undefined, crew: 0, game_mode_exclusive: false, include: [], exclude: [] };
|
||||||
}
|
}
|
||||||
|
|
||||||
export const Provision: MessageFns<Provision> = {
|
export const Provision: MessageFns<Provision> = {
|
||||||
@@ -205,7 +208,7 @@ export const Provision: MessageFns<Provision> = {
|
|||||||
if (message.name !== undefined) {
|
if (message.name !== undefined) {
|
||||||
I18nString.encode(message.name, writer.uint32(18).fork()).join();
|
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);
|
writer.uint32(29).float(message.crew);
|
||||||
}
|
}
|
||||||
if (message.game_mode_exclusive !== false) {
|
if (message.game_mode_exclusive !== false) {
|
||||||
@@ -222,7 +225,7 @@ export const Provision: MessageFns<Provision> = {
|
|||||||
|
|
||||||
decode(input: BinaryReader | Uint8Array, length?: number): Provision {
|
decode(input: BinaryReader | Uint8Array, length?: number): Provision {
|
||||||
const reader = input instanceof BinaryReader ? input : new BinaryReader(input);
|
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();
|
const message = createBaseProvision();
|
||||||
while (reader.pos < end) {
|
while (reader.pos < end) {
|
||||||
const tag = reader.uint32();
|
const tag = reader.uint32();
|
||||||
@@ -286,10 +289,14 @@ export const Provision: MessageFns<Provision> = {
|
|||||||
|
|
||||||
fromJSON(object: any): Provision {
|
fromJSON(object: any): Provision {
|
||||||
return {
|
return {
|
||||||
id: globalThis.Number(assertSet("Provision.id", object.id)),
|
id: isSet(object.id) ? globalThis.Number(object.id) : 0,
|
||||||
name: I18nString.fromJSON(assertSet("Provision.name", object.name)),
|
name: isSet(object.name) ? I18nString.fromJSON(object.name) : undefined,
|
||||||
crew: isSet(object.crew) ? globalThis.Number(object.crew) : undefined,
|
crew: isSet(object.crew) ? globalThis.Number(object.crew) : 0,
|
||||||
game_mode_exclusive: globalThis.Boolean(assertSet("Provision.game_mode_exclusive", object.game_mode_exclusive)),
|
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)
|
include: globalThis.Array.isArray(object?.include)
|
||||||
? object.include.map((e: any) => ConsumableTankFilter.fromJSON(e))
|
? object.include.map((e: any) => ConsumableTankFilter.fromJSON(e))
|
||||||
: [],
|
: [],
|
||||||
@@ -307,11 +314,11 @@ export const Provision: MessageFns<Provision> = {
|
|||||||
if (message.name !== undefined) {
|
if (message.name !== undefined) {
|
||||||
obj.name = I18nString.toJSON(message.name);
|
obj.name = I18nString.toJSON(message.name);
|
||||||
}
|
}
|
||||||
if (message.crew !== undefined && message.crew !== undefined) {
|
if (message.crew !== undefined && message.crew !== 0) {
|
||||||
obj.crew = message.crew;
|
obj.crew = message.crew;
|
||||||
}
|
}
|
||||||
if (message.game_mode_exclusive !== false) {
|
if (message.game_mode_exclusive !== false) {
|
||||||
obj.game_mode_exclusive = message.game_mode_exclusive;
|
obj.gameModeExclusive = message.game_mode_exclusive;
|
||||||
}
|
}
|
||||||
if (message.include?.length) {
|
if (message.include?.length) {
|
||||||
obj.include = message.include.map((e) => ConsumableTankFilter.toJSON(e));
|
obj.include = message.include.map((e) => ConsumableTankFilter.toJSON(e));
|
||||||
@@ -330,8 +337,8 @@ export const Provision: MessageFns<Provision> = {
|
|||||||
message.id = object.id ?? 0;
|
message.id = object.id ?? 0;
|
||||||
message.name = (object.name !== undefined && object.name !== null)
|
message.name = (object.name !== undefined && object.name !== null)
|
||||||
? I18nString.fromPartial(object.name)
|
? I18nString.fromPartial(object.name)
|
||||||
: createBaseI18nString();
|
: undefined;
|
||||||
message.crew = object.crew ?? undefined;
|
message.crew = object.crew ?? 0;
|
||||||
message.game_mode_exclusive = object.game_mode_exclusive ?? false;
|
message.game_mode_exclusive = object.game_mode_exclusive ?? false;
|
||||||
message.include = object.include?.map((e) => ConsumableTankFilter.fromPartial(e)) || [];
|
message.include = object.include?.map((e) => ConsumableTankFilter.fromPartial(e)) || [];
|
||||||
message.exclude = object.exclude?.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;
|
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> {
|
export interface MessageFns<T> {
|
||||||
encode(message: T, writer?: BinaryWriter): BinaryWriter;
|
encode(message: T, writer?: BinaryWriter): BinaryWriter;
|
||||||
decode(input: BinaryReader | Uint8Array, length?: number): T;
|
decode(input: BinaryReader | Uint8Array, length?: number): T;
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ message RatingLeaderboardV1 {
|
|||||||
}
|
}
|
||||||
|
|
||||||
message RatingLeaderboardEntryV1 {
|
message RatingLeaderboardEntryV1 {
|
||||||
required uint32 id = 1;
|
required uint32 id = 1;
|
||||||
required uint32 score = 2;
|
required uint32 score = 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -23,11 +23,11 @@ message RatingLeaderboardV2 {
|
|||||||
}
|
}
|
||||||
|
|
||||||
message RatingLeaderboardEntryV2 {
|
message RatingLeaderboardEntryV2 {
|
||||||
required uint32 id = 1;
|
required uint32 id = 1;
|
||||||
required uint32 score = 2;
|
required uint32 score = 2;
|
||||||
required uint32 battles = 3;
|
required uint32 battles = 3;
|
||||||
required uint32 wins = 4;
|
required uint32 wins = 4;
|
||||||
required uint32 survived = 5;
|
required uint32 survived = 5;
|
||||||
required uint32 damage = 6;
|
required uint32 damage = 6;
|
||||||
required uint32 kills = 7;
|
required uint32 kills = 7;
|
||||||
}
|
}
|
||||||
@@ -1,8 +1,8 @@
|
|||||||
// Code generated by protoc-gen-ts_proto. DO NOT EDIT.
|
// Code generated by protoc-gen-ts_proto. DO NOT EDIT.
|
||||||
// versions:
|
// versions:
|
||||||
// protoc-gen-ts_proto v2.2.2
|
// protoc-gen-ts_proto v2.11.2
|
||||||
// protoc v5.28.2
|
// protoc v5.28.2
|
||||||
// source: packages/core/src/protos/rating_leaderboard.proto
|
// source: rating_leaderboard.proto
|
||||||
|
|
||||||
/* eslint-disable */
|
/* eslint-disable */
|
||||||
import { BinaryReader, BinaryWriter } from "@bufbuild/protobuf/wire";
|
import { BinaryReader, BinaryWriter } from "@bufbuild/protobuf/wire";
|
||||||
@@ -36,7 +36,7 @@ export interface RatingLeaderboardEntryV2 {
|
|||||||
kills: number;
|
kills: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function createBaseRatingLeaderboard(): RatingLeaderboard {
|
function createBaseRatingLeaderboard(): RatingLeaderboard {
|
||||||
return { version: undefined };
|
return { version: undefined };
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -55,7 +55,7 @@ export const RatingLeaderboard: MessageFns<RatingLeaderboard> = {
|
|||||||
|
|
||||||
decode(input: BinaryReader | Uint8Array, length?: number): RatingLeaderboard {
|
decode(input: BinaryReader | Uint8Array, length?: number): RatingLeaderboard {
|
||||||
const reader = input instanceof BinaryReader ? input : new BinaryReader(input);
|
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();
|
const message = createBaseRatingLeaderboard();
|
||||||
while (reader.pos < end) {
|
while (reader.pos < end) {
|
||||||
const tag = reader.uint32();
|
const tag = reader.uint32();
|
||||||
@@ -99,8 +99,7 @@ export const RatingLeaderboard: MessageFns<RatingLeaderboard> = {
|
|||||||
const obj: any = {};
|
const obj: any = {};
|
||||||
if (message.version?.$case === "v1") {
|
if (message.version?.$case === "v1") {
|
||||||
obj.v1 = RatingLeaderboardV1.toJSON(message.version.value);
|
obj.v1 = RatingLeaderboardV1.toJSON(message.version.value);
|
||||||
}
|
} else if (message.version?.$case === "v2") {
|
||||||
if (message.version?.$case === "v2") {
|
|
||||||
obj.v2 = RatingLeaderboardV2.toJSON(message.version.value);
|
obj.v2 = RatingLeaderboardV2.toJSON(message.version.value);
|
||||||
}
|
}
|
||||||
return obj;
|
return obj;
|
||||||
@@ -111,17 +110,25 @@ export const RatingLeaderboard: MessageFns<RatingLeaderboard> = {
|
|||||||
},
|
},
|
||||||
fromPartial<I extends Exact<DeepPartial<RatingLeaderboard>, I>>(object: I): RatingLeaderboard {
|
fromPartial<I extends Exact<DeepPartial<RatingLeaderboard>, I>>(object: I): RatingLeaderboard {
|
||||||
const message = createBaseRatingLeaderboard();
|
const message = createBaseRatingLeaderboard();
|
||||||
if (object.version?.$case === "v1" && object.version?.value !== undefined && object.version?.value !== null) {
|
switch (object.version?.$case) {
|
||||||
message.version = { $case: "v1", value: RatingLeaderboardV1.fromPartial(object.version.value) };
|
case "v1": {
|
||||||
}
|
if (object.version?.value !== undefined && object.version?.value !== null) {
|
||||||
if (object.version?.$case === "v2" && object.version?.value !== undefined && object.version?.value !== null) {
|
message.version = { $case: "v1", value: RatingLeaderboardV1.fromPartial(object.version.value) };
|
||||||
message.version = { $case: "v2", value: RatingLeaderboardV2.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;
|
return message;
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
export function createBaseRatingLeaderboardV1(): RatingLeaderboardV1 {
|
function createBaseRatingLeaderboardV1(): RatingLeaderboardV1 {
|
||||||
return { entries: [] };
|
return { entries: [] };
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -135,7 +142,7 @@ export const RatingLeaderboardV1: MessageFns<RatingLeaderboardV1> = {
|
|||||||
|
|
||||||
decode(input: BinaryReader | Uint8Array, length?: number): RatingLeaderboardV1 {
|
decode(input: BinaryReader | Uint8Array, length?: number): RatingLeaderboardV1 {
|
||||||
const reader = input instanceof BinaryReader ? input : new BinaryReader(input);
|
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();
|
const message = createBaseRatingLeaderboardV1();
|
||||||
while (reader.pos < end) {
|
while (reader.pos < end) {
|
||||||
const tag = reader.uint32();
|
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 };
|
return { id: 0, score: 0 };
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -200,7 +207,7 @@ export const RatingLeaderboardEntryV1: MessageFns<RatingLeaderboardEntryV1> = {
|
|||||||
|
|
||||||
decode(input: BinaryReader | Uint8Array, length?: number): RatingLeaderboardEntryV1 {
|
decode(input: BinaryReader | Uint8Array, length?: number): RatingLeaderboardEntryV1 {
|
||||||
const reader = input instanceof BinaryReader ? input : new BinaryReader(input);
|
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();
|
const message = createBaseRatingLeaderboardEntryV1();
|
||||||
while (reader.pos < end) {
|
while (reader.pos < end) {
|
||||||
const tag = reader.uint32();
|
const tag = reader.uint32();
|
||||||
@@ -232,8 +239,8 @@ export const RatingLeaderboardEntryV1: MessageFns<RatingLeaderboardEntryV1> = {
|
|||||||
|
|
||||||
fromJSON(object: any): RatingLeaderboardEntryV1 {
|
fromJSON(object: any): RatingLeaderboardEntryV1 {
|
||||||
return {
|
return {
|
||||||
id: globalThis.Number(assertSet("RatingLeaderboardEntryV1.id", object.id)),
|
id: isSet(object.id) ? globalThis.Number(object.id) : 0,
|
||||||
score: globalThis.Number(assertSet("RatingLeaderboardEntryV1.score", object.score)),
|
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: [] };
|
return { entries: [] };
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -273,7 +280,7 @@ export const RatingLeaderboardV2: MessageFns<RatingLeaderboardV2> = {
|
|||||||
|
|
||||||
decode(input: BinaryReader | Uint8Array, length?: number): RatingLeaderboardV2 {
|
decode(input: BinaryReader | Uint8Array, length?: number): RatingLeaderboardV2 {
|
||||||
const reader = input instanceof BinaryReader ? input : new BinaryReader(input);
|
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();
|
const message = createBaseRatingLeaderboardV2();
|
||||||
while (reader.pos < end) {
|
while (reader.pos < end) {
|
||||||
const tag = reader.uint32();
|
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 };
|
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 {
|
decode(input: BinaryReader | Uint8Array, length?: number): RatingLeaderboardEntryV2 {
|
||||||
const reader = input instanceof BinaryReader ? input : new BinaryReader(input);
|
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();
|
const message = createBaseRatingLeaderboardEntryV2();
|
||||||
while (reader.pos < end) {
|
while (reader.pos < end) {
|
||||||
const tag = reader.uint32();
|
const tag = reader.uint32();
|
||||||
@@ -425,13 +432,13 @@ export const RatingLeaderboardEntryV2: MessageFns<RatingLeaderboardEntryV2> = {
|
|||||||
|
|
||||||
fromJSON(object: any): RatingLeaderboardEntryV2 {
|
fromJSON(object: any): RatingLeaderboardEntryV2 {
|
||||||
return {
|
return {
|
||||||
id: globalThis.Number(assertSet("RatingLeaderboardEntryV2.id", object.id)),
|
id: isSet(object.id) ? globalThis.Number(object.id) : 0,
|
||||||
score: globalThis.Number(assertSet("RatingLeaderboardEntryV2.score", object.score)),
|
score: isSet(object.score) ? globalThis.Number(object.score) : 0,
|
||||||
battles: globalThis.Number(assertSet("RatingLeaderboardEntryV2.battles", object.battles)),
|
battles: isSet(object.battles) ? globalThis.Number(object.battles) : 0,
|
||||||
wins: globalThis.Number(assertSet("RatingLeaderboardEntryV2.wins", object.wins)),
|
wins: isSet(object.wins) ? globalThis.Number(object.wins) : 0,
|
||||||
survived: globalThis.Number(assertSet("RatingLeaderboardEntryV2.survived", object.survived)),
|
survived: isSet(object.survived) ? globalThis.Number(object.survived) : 0,
|
||||||
damage: globalThis.Number(assertSet("RatingLeaderboardEntryV2.damage", object.damage)),
|
damage: isSet(object.damage) ? globalThis.Number(object.damage) : 0,
|
||||||
kills: globalThis.Number(assertSet("RatingLeaderboardEntryV2.kills", object.kills)),
|
kills: isSet(object.kills) ? globalThis.Number(object.kills) : 0,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
|
||||||
@@ -494,14 +501,6 @@ function isSet(value: any): boolean {
|
|||||||
return value !== null && value !== undefined;
|
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> {
|
export interface MessageFns<T> {
|
||||||
encode(message: T, writer?: BinaryWriter): BinaryWriter;
|
encode(message: T, writer?: BinaryWriter): BinaryWriter;
|
||||||
decode(input: BinaryReader | Uint8Array, length?: number): T;
|
decode(input: BinaryReader | Uint8Array, length?: number): T;
|
||||||
|
|||||||
@@ -8,10 +8,10 @@ message Reviews {
|
|||||||
|
|
||||||
message Review {
|
message Review {
|
||||||
required float last_updated = 1;
|
required float last_updated = 1;
|
||||||
repeated Video videos = 2;
|
repeated Video videos = 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
message Video {
|
message Video {
|
||||||
required string id = 1;
|
required string id = 1;
|
||||||
required string author = 2;
|
required string author = 2;
|
||||||
}
|
}
|
||||||
@@ -1,8 +1,8 @@
|
|||||||
// Code generated by protoc-gen-ts_proto. DO NOT EDIT.
|
// Code generated by protoc-gen-ts_proto. DO NOT EDIT.
|
||||||
// versions:
|
// versions:
|
||||||
// protoc-gen-ts_proto v2.2.2
|
// protoc-gen-ts_proto v2.11.2
|
||||||
// protoc v5.28.2
|
// protoc v5.28.2
|
||||||
// source: packages/core/src/protos/reviews.proto
|
// source: reviews.proto
|
||||||
|
|
||||||
/* eslint-disable */
|
/* eslint-disable */
|
||||||
import { BinaryReader, BinaryWriter } from "@bufbuild/protobuf/wire";
|
import { BinaryReader, BinaryWriter } from "@bufbuild/protobuf/wire";
|
||||||
@@ -28,13 +28,13 @@ export interface Video {
|
|||||||
author: string;
|
author: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function createBaseReviews(): Reviews {
|
function createBaseReviews(): Reviews {
|
||||||
return { reviews: {} };
|
return { reviews: {} };
|
||||||
}
|
}
|
||||||
|
|
||||||
export const Reviews: MessageFns<Reviews> = {
|
export const Reviews: MessageFns<Reviews> = {
|
||||||
encode(message: Reviews, writer: BinaryWriter = new BinaryWriter()): BinaryWriter {
|
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();
|
Reviews_ReviewsEntry.encode({ key: key as any, value }, writer.uint32(10).fork()).join();
|
||||||
});
|
});
|
||||||
return writer;
|
return writer;
|
||||||
@@ -42,7 +42,7 @@ export const Reviews: MessageFns<Reviews> = {
|
|||||||
|
|
||||||
decode(input: BinaryReader | Uint8Array, length?: number): Reviews {
|
decode(input: BinaryReader | Uint8Array, length?: number): Reviews {
|
||||||
const reader = input instanceof BinaryReader ? input : new BinaryReader(input);
|
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();
|
const message = createBaseReviews();
|
||||||
while (reader.pos < end) {
|
while (reader.pos < end) {
|
||||||
const tag = reader.uint32();
|
const tag = reader.uint32();
|
||||||
@@ -70,10 +70,13 @@ export const Reviews: MessageFns<Reviews> = {
|
|||||||
fromJSON(object: any): Reviews {
|
fromJSON(object: any): Reviews {
|
||||||
return {
|
return {
|
||||||
reviews: isObject(object.reviews)
|
reviews: isObject(object.reviews)
|
||||||
? Object.entries(object.reviews).reduce<{ [key: number]: Review }>((acc, [key, value]) => {
|
? (globalThis.Object.entries(object.reviews) as [string, any][]).reduce(
|
||||||
acc[globalThis.Number(key)] = Review.fromJSON(value);
|
(acc: { [key: number]: Review }, [key, value]: [string, any]) => {
|
||||||
return acc;
|
acc[globalThis.Number(key)] = Review.fromJSON(value);
|
||||||
}, {})
|
return acc;
|
||||||
|
},
|
||||||
|
{},
|
||||||
|
)
|
||||||
: {},
|
: {},
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
@@ -81,7 +84,7 @@ export const Reviews: MessageFns<Reviews> = {
|
|||||||
toJSON(message: Reviews): unknown {
|
toJSON(message: Reviews): unknown {
|
||||||
const obj: any = {};
|
const obj: any = {};
|
||||||
if (message.reviews) {
|
if (message.reviews) {
|
||||||
const entries = Object.entries(message.reviews);
|
const entries = globalThis.Object.entries(message.reviews) as [string, Review][];
|
||||||
if (entries.length > 0) {
|
if (entries.length > 0) {
|
||||||
obj.reviews = {};
|
obj.reviews = {};
|
||||||
entries.forEach(([k, v]) => {
|
entries.forEach(([k, v]) => {
|
||||||
@@ -97,23 +100,26 @@ export const Reviews: MessageFns<Reviews> = {
|
|||||||
},
|
},
|
||||||
fromPartial<I extends Exact<DeepPartial<Reviews>, I>>(object: I): Reviews {
|
fromPartial<I extends Exact<DeepPartial<Reviews>, I>>(object: I): Reviews {
|
||||||
const message = createBaseReviews();
|
const message = createBaseReviews();
|
||||||
message.reviews = Object.entries(object.reviews ?? {}).reduce<{ [key: number]: Review }>((acc, [key, value]) => {
|
message.reviews = (globalThis.Object.entries(object.reviews ?? {}) as [string, Review][]).reduce(
|
||||||
if (value !== undefined) {
|
(acc: { [key: number]: Review }, [key, value]: [string, Review]) => {
|
||||||
acc[globalThis.Number(key)] = Review.fromPartial(value);
|
if (value !== undefined) {
|
||||||
}
|
acc[globalThis.Number(key)] = Review.fromPartial(value);
|
||||||
return acc;
|
}
|
||||||
}, {});
|
return acc;
|
||||||
|
},
|
||||||
|
{},
|
||||||
|
);
|
||||||
return message;
|
return message;
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
export function createBaseReviews_ReviewsEntry(): Reviews_ReviewsEntry {
|
function createBaseReviews_ReviewsEntry(): Reviews_ReviewsEntry {
|
||||||
return { key: 0, value: createBaseReview() };
|
return { key: 0, value: undefined };
|
||||||
}
|
}
|
||||||
|
|
||||||
export const Reviews_ReviewsEntry: MessageFns<Reviews_ReviewsEntry> = {
|
export const Reviews_ReviewsEntry: MessageFns<Reviews_ReviewsEntry> = {
|
||||||
encode(message: Reviews_ReviewsEntry, writer: BinaryWriter = new BinaryWriter()): BinaryWriter {
|
encode(message: Reviews_ReviewsEntry, writer: BinaryWriter = new BinaryWriter()): BinaryWriter {
|
||||||
if (message.key !== undefined) {
|
if (message.key !== 0) {
|
||||||
writer.uint32(8).uint32(message.key);
|
writer.uint32(8).uint32(message.key);
|
||||||
}
|
}
|
||||||
if (message.value !== undefined) {
|
if (message.value !== undefined) {
|
||||||
@@ -124,7 +130,7 @@ export const Reviews_ReviewsEntry: MessageFns<Reviews_ReviewsEntry> = {
|
|||||||
|
|
||||||
decode(input: BinaryReader | Uint8Array, length?: number): Reviews_ReviewsEntry {
|
decode(input: BinaryReader | Uint8Array, length?: number): Reviews_ReviewsEntry {
|
||||||
const reader = input instanceof BinaryReader ? input : new BinaryReader(input);
|
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();
|
const message = createBaseReviews_ReviewsEntry();
|
||||||
while (reader.pos < end) {
|
while (reader.pos < end) {
|
||||||
const tag = reader.uint32();
|
const tag = reader.uint32();
|
||||||
@@ -156,14 +162,14 @@ export const Reviews_ReviewsEntry: MessageFns<Reviews_ReviewsEntry> = {
|
|||||||
|
|
||||||
fromJSON(object: any): Reviews_ReviewsEntry {
|
fromJSON(object: any): Reviews_ReviewsEntry {
|
||||||
return {
|
return {
|
||||||
key: globalThis.Number(assertSet("Reviews_ReviewsEntry.key", object.key)),
|
key: isSet(object.key) ? globalThis.Number(object.key) : 0,
|
||||||
value: Review.fromJSON(assertSet("Reviews_ReviewsEntry.value", object.value)),
|
value: isSet(object.value) ? Review.fromJSON(object.value) : undefined,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
|
||||||
toJSON(message: Reviews_ReviewsEntry): unknown {
|
toJSON(message: Reviews_ReviewsEntry): unknown {
|
||||||
const obj: any = {};
|
const obj: any = {};
|
||||||
if (message.key !== undefined) {
|
if (message.key !== 0) {
|
||||||
obj.key = Math.round(message.key);
|
obj.key = Math.round(message.key);
|
||||||
}
|
}
|
||||||
if (message.value !== undefined) {
|
if (message.value !== undefined) {
|
||||||
@@ -180,12 +186,12 @@ export const Reviews_ReviewsEntry: MessageFns<Reviews_ReviewsEntry> = {
|
|||||||
message.key = object.key ?? 0;
|
message.key = object.key ?? 0;
|
||||||
message.value = (object.value !== undefined && object.value !== null)
|
message.value = (object.value !== undefined && object.value !== null)
|
||||||
? Review.fromPartial(object.value)
|
? Review.fromPartial(object.value)
|
||||||
: createBaseReview();
|
: undefined;
|
||||||
return message;
|
return message;
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
export function createBaseReview(): Review {
|
function createBaseReview(): Review {
|
||||||
return { last_updated: 0, videos: [] };
|
return { last_updated: 0, videos: [] };
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -202,7 +208,7 @@ export const Review: MessageFns<Review> = {
|
|||||||
|
|
||||||
decode(input: BinaryReader | Uint8Array, length?: number): Review {
|
decode(input: BinaryReader | Uint8Array, length?: number): Review {
|
||||||
const reader = input instanceof BinaryReader ? input : new BinaryReader(input);
|
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();
|
const message = createBaseReview();
|
||||||
while (reader.pos < end) {
|
while (reader.pos < end) {
|
||||||
const tag = reader.uint32();
|
const tag = reader.uint32();
|
||||||
@@ -234,7 +240,11 @@ export const Review: MessageFns<Review> = {
|
|||||||
|
|
||||||
fromJSON(object: any): Review {
|
fromJSON(object: any): Review {
|
||||||
return {
|
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)) : [],
|
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 {
|
toJSON(message: Review): unknown {
|
||||||
const obj: any = {};
|
const obj: any = {};
|
||||||
if (message.last_updated !== 0) {
|
if (message.last_updated !== 0) {
|
||||||
obj.last_updated = message.last_updated;
|
obj.lastUpdated = message.last_updated;
|
||||||
}
|
}
|
||||||
if (message.videos?.length) {
|
if (message.videos?.length) {
|
||||||
obj.videos = message.videos.map((e) => Video.toJSON(e));
|
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: "" };
|
return { id: "", author: "" };
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -278,7 +288,7 @@ export const Video: MessageFns<Video> = {
|
|||||||
|
|
||||||
decode(input: BinaryReader | Uint8Array, length?: number): Video {
|
decode(input: BinaryReader | Uint8Array, length?: number): Video {
|
||||||
const reader = input instanceof BinaryReader ? input : new BinaryReader(input);
|
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();
|
const message = createBaseVideo();
|
||||||
while (reader.pos < end) {
|
while (reader.pos < end) {
|
||||||
const tag = reader.uint32();
|
const tag = reader.uint32();
|
||||||
@@ -310,8 +320,8 @@ export const Video: MessageFns<Video> = {
|
|||||||
|
|
||||||
fromJSON(object: any): Video {
|
fromJSON(object: any): Video {
|
||||||
return {
|
return {
|
||||||
id: globalThis.String(assertSet("Video.id", object.id)),
|
id: isSet(object.id) ? globalThis.String(object.id) : "",
|
||||||
author: globalThis.String(assertSet("Video.author", object.author)),
|
author: isSet(object.author) ? globalThis.String(object.author) : "",
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
|
||||||
@@ -358,14 +368,6 @@ function isSet(value: any): boolean {
|
|||||||
return value !== null && value !== undefined;
|
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> {
|
export interface MessageFns<T> {
|
||||||
encode(message: T, writer?: BinaryWriter): BinaryWriter;
|
encode(message: T, writer?: BinaryWriter): BinaryWriter;
|
||||||
decode(input: BinaryReader | Uint8Array, length?: number): T;
|
decode(input: BinaryReader | Uint8Array, length?: number): T;
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
// Code generated by protoc-gen-ts_proto. DO NOT EDIT.
|
// Code generated by protoc-gen-ts_proto. DO NOT EDIT.
|
||||||
// versions:
|
// versions:
|
||||||
// protoc-gen-ts_proto v2.2.2
|
// protoc-gen-ts_proto v2.11.2
|
||||||
// protoc v5.28.2
|
// protoc v5.28.2
|
||||||
// source: packages/core/src/protos/skill_definitions.proto
|
// source: skill_definitions.proto
|
||||||
|
|
||||||
/* eslint-disable */
|
/* eslint-disable */
|
||||||
import { BinaryReader, BinaryWriter } from "@bufbuild/protobuf/wire";
|
import { BinaryReader, BinaryWriter } from "@bufbuild/protobuf/wire";
|
||||||
@@ -23,13 +23,13 @@ export interface Skill {
|
|||||||
skills: string[];
|
skills: string[];
|
||||||
}
|
}
|
||||||
|
|
||||||
export function createBaseSkillDefinitions(): SkillDefinitions {
|
function createBaseSkillDefinitions(): SkillDefinitions {
|
||||||
return { classes: {} };
|
return { classes: {} };
|
||||||
}
|
}
|
||||||
|
|
||||||
export const SkillDefinitions: MessageFns<SkillDefinitions> = {
|
export const SkillDefinitions: MessageFns<SkillDefinitions> = {
|
||||||
encode(message: SkillDefinitions, writer: BinaryWriter = new BinaryWriter()): BinaryWriter {
|
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();
|
SkillDefinitions_ClassesEntry.encode({ key: key as any, value }, writer.uint32(10).fork()).join();
|
||||||
});
|
});
|
||||||
return writer;
|
return writer;
|
||||||
@@ -37,7 +37,7 @@ export const SkillDefinitions: MessageFns<SkillDefinitions> = {
|
|||||||
|
|
||||||
decode(input: BinaryReader | Uint8Array, length?: number): SkillDefinitions {
|
decode(input: BinaryReader | Uint8Array, length?: number): SkillDefinitions {
|
||||||
const reader = input instanceof BinaryReader ? input : new BinaryReader(input);
|
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();
|
const message = createBaseSkillDefinitions();
|
||||||
while (reader.pos < end) {
|
while (reader.pos < end) {
|
||||||
const tag = reader.uint32();
|
const tag = reader.uint32();
|
||||||
@@ -65,10 +65,13 @@ export const SkillDefinitions: MessageFns<SkillDefinitions> = {
|
|||||||
fromJSON(object: any): SkillDefinitions {
|
fromJSON(object: any): SkillDefinitions {
|
||||||
return {
|
return {
|
||||||
classes: isObject(object.classes)
|
classes: isObject(object.classes)
|
||||||
? Object.entries(object.classes).reduce<{ [key: number]: Skill }>((acc, [key, value]) => {
|
? (globalThis.Object.entries(object.classes) as [string, any][]).reduce(
|
||||||
acc[globalThis.Number(key)] = Skill.fromJSON(value);
|
(acc: { [key: number]: Skill }, [key, value]: [string, any]) => {
|
||||||
return acc;
|
acc[globalThis.Number(key)] = Skill.fromJSON(value);
|
||||||
}, {})
|
return acc;
|
||||||
|
},
|
||||||
|
{},
|
||||||
|
)
|
||||||
: {},
|
: {},
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
@@ -76,7 +79,7 @@ export const SkillDefinitions: MessageFns<SkillDefinitions> = {
|
|||||||
toJSON(message: SkillDefinitions): unknown {
|
toJSON(message: SkillDefinitions): unknown {
|
||||||
const obj: any = {};
|
const obj: any = {};
|
||||||
if (message.classes) {
|
if (message.classes) {
|
||||||
const entries = Object.entries(message.classes);
|
const entries = globalThis.Object.entries(message.classes) as [string, Skill][];
|
||||||
if (entries.length > 0) {
|
if (entries.length > 0) {
|
||||||
obj.classes = {};
|
obj.classes = {};
|
||||||
entries.forEach(([k, v]) => {
|
entries.forEach(([k, v]) => {
|
||||||
@@ -92,23 +95,26 @@ export const SkillDefinitions: MessageFns<SkillDefinitions> = {
|
|||||||
},
|
},
|
||||||
fromPartial<I extends Exact<DeepPartial<SkillDefinitions>, I>>(object: I): SkillDefinitions {
|
fromPartial<I extends Exact<DeepPartial<SkillDefinitions>, I>>(object: I): SkillDefinitions {
|
||||||
const message = createBaseSkillDefinitions();
|
const message = createBaseSkillDefinitions();
|
||||||
message.classes = Object.entries(object.classes ?? {}).reduce<{ [key: number]: Skill }>((acc, [key, value]) => {
|
message.classes = (globalThis.Object.entries(object.classes ?? {}) as [string, Skill][]).reduce(
|
||||||
if (value !== undefined) {
|
(acc: { [key: number]: Skill }, [key, value]: [string, Skill]) => {
|
||||||
acc[globalThis.Number(key)] = Skill.fromPartial(value);
|
if (value !== undefined) {
|
||||||
}
|
acc[globalThis.Number(key)] = Skill.fromPartial(value);
|
||||||
return acc;
|
}
|
||||||
}, {});
|
return acc;
|
||||||
|
},
|
||||||
|
{},
|
||||||
|
);
|
||||||
return message;
|
return message;
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
export function createBaseSkillDefinitions_ClassesEntry(): SkillDefinitions_ClassesEntry {
|
function createBaseSkillDefinitions_ClassesEntry(): SkillDefinitions_ClassesEntry {
|
||||||
return { key: 0, value: createBaseSkill() };
|
return { key: 0, value: undefined };
|
||||||
}
|
}
|
||||||
|
|
||||||
export const SkillDefinitions_ClassesEntry: MessageFns<SkillDefinitions_ClassesEntry> = {
|
export const SkillDefinitions_ClassesEntry: MessageFns<SkillDefinitions_ClassesEntry> = {
|
||||||
encode(message: SkillDefinitions_ClassesEntry, writer: BinaryWriter = new BinaryWriter()): BinaryWriter {
|
encode(message: SkillDefinitions_ClassesEntry, writer: BinaryWriter = new BinaryWriter()): BinaryWriter {
|
||||||
if (message.key !== undefined) {
|
if (message.key !== 0) {
|
||||||
writer.uint32(8).uint32(message.key);
|
writer.uint32(8).uint32(message.key);
|
||||||
}
|
}
|
||||||
if (message.value !== undefined) {
|
if (message.value !== undefined) {
|
||||||
@@ -119,7 +125,7 @@ export const SkillDefinitions_ClassesEntry: MessageFns<SkillDefinitions_ClassesE
|
|||||||
|
|
||||||
decode(input: BinaryReader | Uint8Array, length?: number): SkillDefinitions_ClassesEntry {
|
decode(input: BinaryReader | Uint8Array, length?: number): SkillDefinitions_ClassesEntry {
|
||||||
const reader = input instanceof BinaryReader ? input : new BinaryReader(input);
|
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();
|
const message = createBaseSkillDefinitions_ClassesEntry();
|
||||||
while (reader.pos < end) {
|
while (reader.pos < end) {
|
||||||
const tag = reader.uint32();
|
const tag = reader.uint32();
|
||||||
@@ -151,14 +157,14 @@ export const SkillDefinitions_ClassesEntry: MessageFns<SkillDefinitions_ClassesE
|
|||||||
|
|
||||||
fromJSON(object: any): SkillDefinitions_ClassesEntry {
|
fromJSON(object: any): SkillDefinitions_ClassesEntry {
|
||||||
return {
|
return {
|
||||||
key: globalThis.Number(assertSet("SkillDefinitions_ClassesEntry.key", object.key)),
|
key: isSet(object.key) ? globalThis.Number(object.key) : 0,
|
||||||
value: Skill.fromJSON(assertSet("SkillDefinitions_ClassesEntry.value", object.value)),
|
value: isSet(object.value) ? Skill.fromJSON(object.value) : undefined,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
|
||||||
toJSON(message: SkillDefinitions_ClassesEntry): unknown {
|
toJSON(message: SkillDefinitions_ClassesEntry): unknown {
|
||||||
const obj: any = {};
|
const obj: any = {};
|
||||||
if (message.key !== undefined) {
|
if (message.key !== 0) {
|
||||||
obj.key = Math.round(message.key);
|
obj.key = Math.round(message.key);
|
||||||
}
|
}
|
||||||
if (message.value !== undefined) {
|
if (message.value !== undefined) {
|
||||||
@@ -175,14 +181,12 @@ export const SkillDefinitions_ClassesEntry: MessageFns<SkillDefinitions_ClassesE
|
|||||||
): SkillDefinitions_ClassesEntry {
|
): SkillDefinitions_ClassesEntry {
|
||||||
const message = createBaseSkillDefinitions_ClassesEntry();
|
const message = createBaseSkillDefinitions_ClassesEntry();
|
||||||
message.key = object.key ?? 0;
|
message.key = object.key ?? 0;
|
||||||
message.value = (object.value !== undefined && object.value !== null)
|
message.value = (object.value !== undefined && object.value !== null) ? Skill.fromPartial(object.value) : undefined;
|
||||||
? Skill.fromPartial(object.value)
|
|
||||||
: createBaseSkill();
|
|
||||||
return message;
|
return message;
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
export function createBaseSkill(): Skill {
|
function createBaseSkill(): Skill {
|
||||||
return { skills: [] };
|
return { skills: [] };
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -196,7 +200,7 @@ export const Skill: MessageFns<Skill> = {
|
|||||||
|
|
||||||
decode(input: BinaryReader | Uint8Array, length?: number): Skill {
|
decode(input: BinaryReader | Uint8Array, length?: number): Skill {
|
||||||
const reader = input instanceof BinaryReader ? input : new BinaryReader(input);
|
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();
|
const message = createBaseSkill();
|
||||||
while (reader.pos < end) {
|
while (reader.pos < end) {
|
||||||
const tag = reader.uint32();
|
const tag = reader.uint32();
|
||||||
@@ -263,14 +267,6 @@ function isSet(value: any): boolean {
|
|||||||
return value !== null && value !== undefined;
|
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> {
|
export interface MessageFns<T> {
|
||||||
encode(message: T, writer?: BinaryWriter): BinaryWriter;
|
encode(message: T, writer?: BinaryWriter): BinaryWriter;
|
||||||
decode(input: BinaryReader | Uint8Array, length?: number): T;
|
decode(input: BinaryReader | Uint8Array, length?: number): T;
|
||||||
|
|||||||
@@ -2,48 +2,58 @@ syntax = "proto2";
|
|||||||
|
|
||||||
package blitzkit;
|
package blitzkit;
|
||||||
|
|
||||||
import "packages/core/src/protos/i18n.proto";
|
import "i18n.proto";
|
||||||
|
|
||||||
message TankDefinitions {
|
message TankDefinitions {
|
||||||
map<uint32, TankDefinition> tanks = 1;
|
map<uint32, TankDefinition> tanks = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
message TankDefinition {
|
message TankDefinition {
|
||||||
required uint32 id = 1;
|
required uint32 id = 1;
|
||||||
required string slug = 2;
|
required string slug = 2;
|
||||||
map<uint32, uint32> roles = 3;
|
map<uint32, uint32> roles = 3;
|
||||||
required bool fixed_camouflage = 5;
|
required bool fixed_camouflage = 5;
|
||||||
repeated int32 camouflages = 6;
|
repeated int32 camouflages = 6;
|
||||||
repeated int32 ancestors = 7;
|
repeated int32 ancestors = 7;
|
||||||
repeated int32 successors = 8;
|
repeated int32 successors = 8;
|
||||||
repeated Crew crew = 9;
|
repeated Crew crew = 9;
|
||||||
required uint32 health = 10;
|
required uint32 health = 10;
|
||||||
required string nation = 11;
|
required string nation = 11;
|
||||||
required I18nString name = 12;
|
required I18nString name = 12;
|
||||||
required TankType type = 13;
|
required TankType type = 13;
|
||||||
required uint32 max_consumables = 14;
|
required uint32 max_consumables = 14;
|
||||||
required uint32 max_provisions = 15;
|
required uint32 max_provisions = 15;
|
||||||
required uint32 tier = 16;
|
required uint32 tier = 16;
|
||||||
required TankClass class = 17;
|
required TankClass class = 17;
|
||||||
required bool testing = 18;
|
required bool testing = 18;
|
||||||
required bool deprecated = 19;
|
required bool deprecated = 19;
|
||||||
repeated TurretDefinition turrets = 20;
|
repeated TurretDefinition turrets = 20;
|
||||||
repeated EngineDefinition engines = 21;
|
repeated EngineDefinition engines = 21;
|
||||||
repeated TrackDefinition tracks = 22;
|
repeated TrackDefinition tracks = 22;
|
||||||
required TankPrice price = 23;
|
required TankPrice price = 23;
|
||||||
optional ResearchCost research_cost = 24;
|
optional ResearchCost research_cost = 24;
|
||||||
required float speed_forwards = 25;
|
required float speed_forwards = 25;
|
||||||
required float speed_backwards = 26;
|
required float speed_backwards = 26;
|
||||||
required float camouflage_still = 27;
|
required float camouflage_still = 27;
|
||||||
required float camouflage_moving = 28;
|
required float camouflage_moving = 28;
|
||||||
required float camouflage_onFire = 29;
|
required float camouflage_on_fire = 29;
|
||||||
required string equipment_preset = 30;
|
required string equipment_preset = 30;
|
||||||
required uint32 weight = 31;
|
required uint32 weight = 31;
|
||||||
|
required string dev_name = 32;
|
||||||
|
optional Equalizer equalizer = 33;
|
||||||
|
}
|
||||||
|
|
||||||
|
message Equalizer {
|
||||||
|
required float health = 1;
|
||||||
|
required float penetration = 2;
|
||||||
|
required float module_health = 3;
|
||||||
|
required float damage = 4;
|
||||||
|
required float armor = 5;
|
||||||
}
|
}
|
||||||
|
|
||||||
message ResearchCost {
|
message ResearchCost {
|
||||||
oneof research_cost_type {
|
oneof research_cost_type {
|
||||||
uint32 xp = 1;
|
uint32 xp = 1;
|
||||||
ResearchCostSeasonalTokens seasonal_tokens = 2;
|
ResearchCostSeasonalTokens seasonal_tokens = 2;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -55,77 +65,77 @@ message ResearchCostSeasonalTokens {
|
|||||||
|
|
||||||
enum TankPriceType {
|
enum TankPriceType {
|
||||||
TANK_PRICE_TYPE_CREDITS = 0;
|
TANK_PRICE_TYPE_CREDITS = 0;
|
||||||
TANK_PRICE_TYPE_GOLD = 1;
|
TANK_PRICE_TYPE_GOLD = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
message TankPrice {
|
message TankPrice {
|
||||||
required TankPriceType type = 1;
|
required TankPriceType type = 1;
|
||||||
required uint32 value = 2;
|
required uint32 value = 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
message TrackDefinition {
|
message TrackDefinition {
|
||||||
required uint32 id = 1;
|
required uint32 id = 1;
|
||||||
required uint32 tier = 2;
|
required uint32 tier = 2;
|
||||||
required I18nString name = 3;
|
required I18nString name = 3;
|
||||||
required uint32 weight = 4;
|
required uint32 weight = 4;
|
||||||
required float traverse_speed = 5;
|
required float traverse_speed = 5;
|
||||||
optional ResearchCost research_cost = 6;
|
optional ResearchCost research_cost = 6;
|
||||||
required float dispersion_move = 7;
|
required float dispersion_move = 7;
|
||||||
required float dispersion_traverse = 8;
|
required float dispersion_traverse = 8;
|
||||||
required float resistance_hard = 9;
|
required float resistance_hard = 9;
|
||||||
required float resistance_medium = 10;
|
required float resistance_medium = 10;
|
||||||
required float resistance_soft = 11;
|
required float resistance_soft = 11;
|
||||||
repeated Unlock unlocks = 12;
|
repeated Unlock unlocks = 12;
|
||||||
}
|
}
|
||||||
|
|
||||||
message EngineDefinition {
|
message EngineDefinition {
|
||||||
required uint32 id = 1;
|
required uint32 id = 1;
|
||||||
required I18nString name = 2;
|
required I18nString name = 2;
|
||||||
optional ResearchCost research_cost = 3;
|
optional ResearchCost research_cost = 3;
|
||||||
required uint32 tier = 4;
|
required uint32 tier = 4;
|
||||||
required float fire_chance = 5;
|
required float fire_chance = 5;
|
||||||
required uint32 power = 6;
|
required uint32 power = 6;
|
||||||
required uint32 weight = 7;
|
required uint32 weight = 7;
|
||||||
repeated Unlock unlocks = 8;
|
repeated Unlock unlocks = 8;
|
||||||
}
|
}
|
||||||
|
|
||||||
message TurretDefinition {
|
message TurretDefinition {
|
||||||
required uint32 id = 1;
|
required uint32 id = 1;
|
||||||
required uint32 health = 2;
|
required uint32 health = 2;
|
||||||
required uint32 view_range = 3;
|
required uint32 view_range = 3;
|
||||||
required float traverse_speed = 4;
|
required float traverse_speed = 4;
|
||||||
optional ResearchCost research_cost = 5;
|
optional ResearchCost research_cost = 5;
|
||||||
required I18nString name = 6;
|
required I18nString name = 6;
|
||||||
required uint32 tier = 7;
|
required uint32 tier = 7;
|
||||||
required uint32 weight = 8;
|
required uint32 weight = 8;
|
||||||
repeated GunDefinition guns = 9;
|
repeated GunDefinition guns = 9;
|
||||||
repeated Unlock unlocks = 10;
|
repeated Unlock unlocks = 10;
|
||||||
}
|
}
|
||||||
|
|
||||||
message GunDefinition {
|
message GunDefinition {
|
||||||
oneof gun_type {
|
oneof gun_type {
|
||||||
GunDefinitionRegular regular = 1;
|
GunDefinitionRegular regular = 1;
|
||||||
GunDefinitionAutoLoader auto_loader = 2;
|
GunDefinitionAutoLoader auto_loader = 2;
|
||||||
GunDefinitionAutoReloader auto_reloader = 3;
|
GunDefinitionAutoReloader auto_reloader = 3;
|
||||||
}
|
}
|
||||||
|
|
||||||
required uint32 id = 4;
|
required uint32 id = 4;
|
||||||
required float rotation_speed = 5;
|
required float rotation_speed = 5;
|
||||||
optional ResearchCost research_cost = 6;
|
optional ResearchCost research_cost = 6;
|
||||||
required uint32 weight = 7;
|
required uint32 weight = 7;
|
||||||
required I18nString name = 8;
|
required I18nString name = 8;
|
||||||
required uint32 tier = 9;
|
required uint32 tier = 9;
|
||||||
repeated ShellDefinition shells = 10;
|
repeated ShellDefinition shells = 10;
|
||||||
required float camouflage_loss = 11;
|
required float camouflage_loss = 11;
|
||||||
required float aim_time = 12;
|
required float aim_time = 12;
|
||||||
required float dispersion_base = 13;
|
required float dispersion_base = 13;
|
||||||
required float dispersion_traverse = 14;
|
required float dispersion_traverse = 14;
|
||||||
required float dispersion_shot = 15;
|
required float dispersion_shot = 15;
|
||||||
required float dispersion_damaged = 16;
|
required float dispersion_damaged = 16;
|
||||||
repeated Unlock unlocks = 17;
|
repeated Unlock unlocks = 17;
|
||||||
required uint32 shell_capacity = 18;
|
required uint32 shell_capacity = 18;
|
||||||
optional AssaultRanges assault_ranges = 19;
|
optional AssaultRanges assault_ranges = 19;
|
||||||
optional Burst burst = 20;
|
optional Burst burst = 20;
|
||||||
}
|
}
|
||||||
|
|
||||||
message GunDefinitionRegular {
|
message GunDefinitionRegular {
|
||||||
@@ -134,101 +144,101 @@ message GunDefinitionRegular {
|
|||||||
|
|
||||||
message GunDefinitionAutoLoader {
|
message GunDefinitionAutoLoader {
|
||||||
required float clip_reload = 1;
|
required float clip_reload = 1;
|
||||||
required float intra_clip = 2;
|
required float intra_clip = 2;
|
||||||
required float shell_count = 3;
|
required float shell_count = 3;
|
||||||
}
|
}
|
||||||
|
|
||||||
message Burst {
|
message Burst {
|
||||||
required uint32 count = 1;
|
required uint32 count = 1;
|
||||||
required float interval = 2;
|
required float interval = 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
message GunDefinitionAutoReloader {
|
message GunDefinitionAutoReloader {
|
||||||
repeated float shell_reloads = 1;
|
repeated float shell_reloads = 1;
|
||||||
required float intra_clip = 2;
|
required float intra_clip = 2;
|
||||||
required float shell_count = 3;
|
required float shell_count = 3;
|
||||||
}
|
}
|
||||||
|
|
||||||
message AssaultRanges {
|
message AssaultRanges {
|
||||||
repeated AssaultRange ranges = 1;
|
repeated AssaultRange ranges = 1;
|
||||||
repeated ShellType types = 2;
|
repeated ShellType types = 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
message AssaultRange {
|
message AssaultRange {
|
||||||
required float distance = 1;
|
required float distance = 1;
|
||||||
required float factor = 2;
|
required float factor = 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
message ShellDefinition {
|
message ShellDefinition {
|
||||||
required uint32 id = 1;
|
required uint32 id = 1;
|
||||||
required I18nString name = 2;
|
required I18nString name = 2;
|
||||||
required uint32 velocity = 3;
|
required uint32 velocity = 3;
|
||||||
required uint32 armor_damage = 4;
|
required uint32 armor_damage = 4;
|
||||||
required uint32 module_damage = 5;
|
required uint32 module_damage = 5;
|
||||||
required float caliber = 6;
|
required float caliber = 6;
|
||||||
required string icon = 7;
|
required string icon = 7;
|
||||||
required ShellPenetration penetration = 8;
|
required ShellPenetration penetration = 8;
|
||||||
required ShellType type = 9;
|
required ShellType type = 9;
|
||||||
optional float normalization = 10;
|
optional float normalization = 10;
|
||||||
optional float ricochet = 11;
|
optional float ricochet = 11;
|
||||||
optional float explosion_radius = 12;
|
optional float explosion_radius = 12;
|
||||||
required uint32 range = 13;
|
required uint32 range = 13;
|
||||||
}
|
}
|
||||||
|
|
||||||
enum ShellType {
|
enum ShellType {
|
||||||
SHELL_TYPE_AP = 0;
|
SHELL_TYPE_AP = 0;
|
||||||
SHELL_TYPE_APCR = 1;
|
SHELL_TYPE_APCR = 1;
|
||||||
SHELL_TYPE_HEAT = 2;
|
SHELL_TYPE_HEAT = 2;
|
||||||
SHELL_TYPE_HE = 3;
|
SHELL_TYPE_HE = 3;
|
||||||
}
|
}
|
||||||
|
|
||||||
message ShellPenetration {
|
message ShellPenetration {
|
||||||
required float near = 1;
|
required float near = 1;
|
||||||
required float far = 2;
|
required float far = 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
message Unlock {
|
message Unlock {
|
||||||
required int32 id = 1;
|
required int32 id = 1;
|
||||||
required ModuleType type = 2;
|
required ModuleType type = 2;
|
||||||
required UnlockCost cost = 3;
|
required UnlockCost cost = 3;
|
||||||
}
|
}
|
||||||
|
|
||||||
message UnlockCost {
|
message UnlockCost {
|
||||||
required string type = 1;
|
required string type = 1;
|
||||||
required int32 value = 2;
|
required int32 value = 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
enum ModuleType {
|
enum ModuleType {
|
||||||
MODULE_TYPE_VEHICLE = 0;
|
MODULE_TYPE_VEHICLE = 0;
|
||||||
MODULE_TYPE_ENGINE = 1;
|
MODULE_TYPE_ENGINE = 1;
|
||||||
MODULE_TYPE_TRACKS = 2;
|
MODULE_TYPE_TRACKS = 2;
|
||||||
MODULE_TYPE_TURRET = 3;
|
MODULE_TYPE_TURRET = 3;
|
||||||
MODULE_TYPE_GUN = 4;
|
MODULE_TYPE_GUN = 4;
|
||||||
}
|
}
|
||||||
|
|
||||||
enum TankClass {
|
enum TankClass {
|
||||||
TANK_CLASS_LIGHT = 0;
|
TANK_CLASS_LIGHT = 0;
|
||||||
TANK_CLASS_MEDIUM = 1;
|
TANK_CLASS_MEDIUM = 1;
|
||||||
TANK_CLASS_HEAVY = 2;
|
TANK_CLASS_HEAVY = 2;
|
||||||
TANK_CLASS_TANK_DESTROYER = 3;
|
TANK_CLASS_TANK_DESTROYER = 3;
|
||||||
}
|
}
|
||||||
|
|
||||||
enum TankType {
|
enum TankType {
|
||||||
TANK_TYPE_RESEARCHABLE = 0;
|
TANK_TYPE_RESEARCHABLE = 0;
|
||||||
TANK_TYPE_PREMIUM = 1;
|
TANK_TYPE_PREMIUM = 1;
|
||||||
TANK_TYPE_COLLECTOR = 2;
|
TANK_TYPE_COLLECTOR = 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
message Crew {
|
message Crew {
|
||||||
required CrewType type = 1;
|
required CrewType type = 1;
|
||||||
required uint32 count = 2;
|
required uint32 count = 2;
|
||||||
repeated CrewType substitute = 3;
|
repeated CrewType substitute = 3;
|
||||||
}
|
}
|
||||||
|
|
||||||
enum CrewType {
|
enum CrewType {
|
||||||
CREW_TYPE_COMMANDER = 0;
|
CREW_TYPE_COMMANDER = 0;
|
||||||
CREW_TYPE_RADIOMAN = 1;
|
CREW_TYPE_RADIOMAN = 1;
|
||||||
CREW_TYPE_GUNNER = 2;
|
CREW_TYPE_GUNNER = 2;
|
||||||
CREW_TYPE_DRIVER = 3;
|
CREW_TYPE_DRIVER = 3;
|
||||||
CREW_TYPE_LOADER = 4;
|
CREW_TYPE_LOADER = 4;
|
||||||
}
|
}
|
||||||
File diff suppressed because it is too large.
Load diff
@@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"test": {
|
"test": {
|
||||||
"default": "",
|
"default": "test",
|
||||||
"long": ".",
|
"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."
|
"fox": "Szybki brązowy lis przeskoczył nad leniwym psem."
|
||||||
},
|
},
|
||||||
"common": {
|
"common": {
|
||||||
@@ -17,9 +17,9 @@
|
|||||||
"plus": "+{value}"
|
"plus": "+{value}"
|
||||||
},
|
},
|
||||||
"gun_types": {
|
"gun_types": {
|
||||||
"auto_loader": "Auto loader",
|
"auto_loader": "Samo ładowacz",
|
||||||
"auto_reloader": "Automatyczne przeładowanie",
|
"auto_reloader": "Automatyczne przeładowanie",
|
||||||
"regular": ""
|
"regular": "Regular"
|
||||||
},
|
},
|
||||||
"shells": {
|
"shells": {
|
||||||
"ap": "AP",
|
"ap": "AP",
|
||||||
@@ -28,18 +28,18 @@
|
|||||||
"he": "OB"
|
"he": "OB"
|
||||||
},
|
},
|
||||||
"player_count_period": {
|
"player_count_period": {
|
||||||
"total": "Total",
|
"total": "Łącznie",
|
||||||
"d_120": "Past 120 days",
|
"d_120": "Powyżej 120 dni",
|
||||||
"d_90": "Past 90 days",
|
"d_90": "Powyżej 90 dni",
|
||||||
"d_60": "Past 60 days",
|
"d_60": "Powyżej 60 dni",
|
||||||
"d_30": "Past month",
|
"d_30": "W ciągu miesiąca",
|
||||||
"d_7": "W minionym tygodniu",
|
"d_7": "W minionym tygodniu",
|
||||||
"d_1": "Yesterday"
|
"d_1": "Wczoraj"
|
||||||
},
|
},
|
||||||
"branches": {
|
"branches": {
|
||||||
"local": "dev",
|
"local": "dev",
|
||||||
"dev": "beta",
|
"dev": "beta",
|
||||||
"opentest": "opentest",
|
"opentest": "otwarty test",
|
||||||
"preview": "podgląd"
|
"preview": "podgląd"
|
||||||
},
|
},
|
||||||
"locales": {
|
"locales": {
|
||||||
@@ -80,45 +80,45 @@
|
|||||||
},
|
},
|
||||||
"nations": {
|
"nations": {
|
||||||
"ussr": "ZSRR",
|
"ussr": "ZSRR",
|
||||||
"germany": "Germany",
|
"germany": "Niemcy",
|
||||||
"usa": "U.S.A.",
|
"usa": "Stany Zjednoczone.",
|
||||||
"china": "Chiny",
|
"china": "Chiny",
|
||||||
"uk": "Wielka Brytania",
|
"uk": "Wielka Brytania",
|
||||||
"france": "France",
|
"france": "Francja",
|
||||||
"japan": "Japan",
|
"japan": "Japonia",
|
||||||
"european": "Nacja Europejska",
|
"european": "Nacja Europejska",
|
||||||
"other": "Nacja Hybrydowa"
|
"other": "Nacja Hybrydowa"
|
||||||
},
|
},
|
||||||
"nations_adjectives": {
|
"nations_adjectives": {
|
||||||
"ussr": "ZSRR",
|
"ussr": "ZSRR",
|
||||||
"germany": "German",
|
"germany": "Niemcy",
|
||||||
"usa": "Amerykański",
|
"usa": "Amerykański",
|
||||||
"china": "Chiński",
|
"china": "Chiński",
|
||||||
"uk": "Wielkiej Brytanii",
|
"uk": "Wielkiej Brytanii",
|
||||||
"france": "Francuski",
|
"france": "Francuski",
|
||||||
"japan": "Japoński",
|
"japan": "Japoński",
|
||||||
"european": "European",
|
"european": "Europa",
|
||||||
"other": "Hybrid"
|
"other": "Hybryda"
|
||||||
},
|
},
|
||||||
"tank_class_short": {
|
"tank_class_short": {
|
||||||
"-1": "unrecognized",
|
"-1": "unrecognized",
|
||||||
"0": "Light",
|
"0": "Lekki",
|
||||||
"1": "Medium",
|
"1": "Średni",
|
||||||
"2": "Heavy",
|
"2": "Ciężki",
|
||||||
"3": "TD"
|
"3": "TD"
|
||||||
},
|
},
|
||||||
"tank_class_short_plural_lowercase": {
|
"tank_class_short_plural_lowercase": {
|
||||||
"0": "lights",
|
"0": "lekkie",
|
||||||
"1": "mediums",
|
"1": "średnie",
|
||||||
"2": "heavies",
|
"2": "ciężkie",
|
||||||
"3": "TDs"
|
"3": "TDs"
|
||||||
},
|
},
|
||||||
"tank_class_medium": {
|
"tank_class_medium": {
|
||||||
"-1": "unrecognized",
|
"-1": "unrecognized",
|
||||||
"0": "Lekki",
|
"0": "Lekki",
|
||||||
"1": "Medium",
|
"1": "Średni",
|
||||||
"2": "Heavy",
|
"2": "Ciężki",
|
||||||
"3": "Tank destroyer"
|
"3": "Niszczyciel czołgów"
|
||||||
},
|
},
|
||||||
"tree_type": {
|
"tree_type": {
|
||||||
"-1": "unrecognized",
|
"-1": "unrecognized",
|
||||||
@@ -210,7 +210,7 @@
|
|||||||
"good": "Dobrze",
|
"good": "Dobrze",
|
||||||
"very_good": "Bardzo dobrze",
|
"very_good": "Bardzo dobrze",
|
||||||
"great": "Świetne",
|
"great": "Świetne",
|
||||||
"unicum": "Unikalny ",
|
"unicum": "Unikalny",
|
||||||
"super_unicum": "Bardzo unikalny"
|
"super_unicum": "Bardzo unikalny"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -236,7 +236,7 @@
|
|||||||
"description": "Kariera"
|
"description": "Kariera"
|
||||||
},
|
},
|
||||||
"custom": {
|
"custom": {
|
||||||
"name": "Niestandardowy",
|
"name": "custom",
|
||||||
"description": "Zakres niestandardowy",
|
"description": "Zakres niestandardowy",
|
||||||
"options": {
|
"options": {
|
||||||
"start": {
|
"start": {
|
||||||
@@ -856,7 +856,7 @@
|
|||||||
"hull": "Hull",
|
"hull": "Hull",
|
||||||
"turret": "Turret",
|
"turret": "Turret",
|
||||||
"hard": "Hard",
|
"hard": "Hard",
|
||||||
"medium": "Medium",
|
"medium": "Średni",
|
||||||
"soft": "Soft",
|
"soft": "Soft",
|
||||||
"effective": "Effective"
|
"effective": "Effective"
|
||||||
},
|
},
|
||||||
@@ -1066,19 +1066,19 @@
|
|||||||
"speedBackwards": "Backwards",
|
"speedBackwards": "Backwards",
|
||||||
"hardTerrainCoefficient": "Hard",
|
"hardTerrainCoefficient": "Hard",
|
||||||
"hardTerrainCoefficientRaw": "Hard",
|
"hardTerrainCoefficientRaw": "Hard",
|
||||||
"mediumTerrainCoefficient": "Medium",
|
"mediumTerrainCoefficient": "Średni",
|
||||||
"mediumTerrainCoefficientRaw": "Medium",
|
"mediumTerrainCoefficientRaw": "Średni",
|
||||||
"softTerrainCoefficient": "Soft",
|
"softTerrainCoefficient": "Soft",
|
||||||
"softTerrainCoefficientRaw": "Soft",
|
"softTerrainCoefficientRaw": "Soft",
|
||||||
"enginePower": "Engine power",
|
"enginePower": "Engine power",
|
||||||
"powerToWeightRatioHardTerrain": "Hard",
|
"powerToWeightRatioHardTerrain": "Hard",
|
||||||
"powerToWeightRatioMediumTerrain": "Medium",
|
"powerToWeightRatioMediumTerrain": "Średni",
|
||||||
"powerToWeightRatioSoftTerrain": "Soft",
|
"powerToWeightRatioSoftTerrain": "Soft",
|
||||||
"weight": "Weight",
|
"weight": "Weight",
|
||||||
"turretTraverseSpeed": "Turret traverse speed",
|
"turretTraverseSpeed": "Turret traverse speed",
|
||||||
"gunTraverseSpeed": "Gun traverse speed",
|
"gunTraverseSpeed": "Gun traverse speed",
|
||||||
"hullTraverseHardTerrain": "Hard",
|
"hullTraverseHardTerrain": "Hard",
|
||||||
"hullTraverseMediumTerrain": "Medium",
|
"hullTraverseMediumTerrain": "Średni",
|
||||||
"hullTraverseSoftTerrain": "Soft",
|
"hullTraverseSoftTerrain": "Soft",
|
||||||
"health": "Health",
|
"health": "Health",
|
||||||
"fireChance": "Fire chance",
|
"fireChance": "Fire chance",
|
||||||
@@ -1181,7 +1181,7 @@
|
|||||||
"table": {
|
"table": {
|
||||||
"tanks": {
|
"tanks": {
|
||||||
"header": "Tank",
|
"header": "Tank",
|
||||||
"total": "Total"
|
"total": "Łącznie"
|
||||||
},
|
},
|
||||||
"stats": {
|
"stats": {
|
||||||
"winrate": "Śr. wygranych",
|
"winrate": "Śr. wygranych",
|
||||||
@@ -1239,7 +1239,7 @@
|
|||||||
},
|
},
|
||||||
"table": {
|
"table": {
|
||||||
"tank": "Tank",
|
"tank": "Tank",
|
||||||
"total": "Total",
|
"total": "Łącznie",
|
||||||
"remove": "Remove"
|
"remove": "Remove"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -86,8 +86,8 @@
|
|||||||
"uk": "英国",
|
"uk": "英国",
|
||||||
"france": "法国",
|
"france": "法国",
|
||||||
"japan": "日本",
|
"japan": "日本",
|
||||||
"european": "欧洲国家",
|
"european": "欧盟 (E系)",
|
||||||
"other": "混合型国家"
|
"other": "X系"
|
||||||
},
|
},
|
||||||
"nations_adjectives": {
|
"nations_adjectives": {
|
||||||
"ussr": "苏联",
|
"ussr": "苏联",
|
||||||
@@ -97,34 +97,34 @@
|
|||||||
"uk": "英国",
|
"uk": "英国",
|
||||||
"france": "法国",
|
"france": "法国",
|
||||||
"japan": "日本",
|
"japan": "日本",
|
||||||
"european": "欧洲国家",
|
"european": "欧盟 (E系)",
|
||||||
"other": "混合型国家"
|
"other": "X系"
|
||||||
},
|
},
|
||||||
"tank_class_short": {
|
"tank_class_short": {
|
||||||
"-1": "未识别",
|
"-1": "未识别",
|
||||||
"0": "轻型坦克",
|
"0": "轻型坦克",
|
||||||
"1": "中型坦克",
|
"1": "中型坦克",
|
||||||
"2": "重型战车",
|
"2": "重型战车",
|
||||||
"3": "驱逐战车"
|
"3": "坦克歼击车"
|
||||||
},
|
},
|
||||||
"tank_class_short_plural_lowercase": {
|
"tank_class_short_plural_lowercase": {
|
||||||
"0": "轻型战车",
|
"0": "轻型坦克",
|
||||||
"1": "中型战车",
|
"1": "中型坦克",
|
||||||
"2": "重型战车",
|
"2": "重型坦克",
|
||||||
"3": "驱逐战车"
|
"3": "坦克歼击车"
|
||||||
},
|
},
|
||||||
"tank_class_medium": {
|
"tank_class_medium": {
|
||||||
"-1": "未识别",
|
"-1": "未识别",
|
||||||
"0": "轻型战车",
|
"0": "轻型坦克",
|
||||||
"1": "中型战车",
|
"1": "中型坦克",
|
||||||
"2": "重型战车",
|
"2": "重型坦克",
|
||||||
"3": "驱逐战车"
|
"3": "坦克歼击车"
|
||||||
},
|
},
|
||||||
"tree_type": {
|
"tree_type": {
|
||||||
"-1": "未识别",
|
"-1": "未识别",
|
||||||
"0": "科技树",
|
"0": "科技树",
|
||||||
"1": "加值战车",
|
"1": "金币车",
|
||||||
"2": "收藏家战车"
|
"2": "收藏车"
|
||||||
},
|
},
|
||||||
"regions": {
|
"regions": {
|
||||||
"normal": {
|
"normal": {
|
||||||
@@ -140,8 +140,8 @@
|
|||||||
},
|
},
|
||||||
"leagues": {
|
"leagues": {
|
||||||
"diamond": "钻石",
|
"diamond": "钻石",
|
||||||
"platinum": "白金",
|
"platinum": "铂金",
|
||||||
"gold": "黃金",
|
"gold": "黄金",
|
||||||
"silver": "白银",
|
"silver": "白银",
|
||||||
"bronze": "青铜"
|
"bronze": "青铜"
|
||||||
},
|
},
|
||||||
@@ -210,7 +210,7 @@
|
|||||||
"good": "好",
|
"good": "好",
|
||||||
"very_good": "非常好",
|
"very_good": "非常好",
|
||||||
"great": "很好",
|
"great": "很好",
|
||||||
"unicum": "極品",
|
"unicum": "极品",
|
||||||
"super_unicum": "超强势玩家"
|
"super_unicum": "超强势玩家"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -256,7 +256,7 @@
|
|||||||
"description": "公会名称或标签"
|
"description": "公会名称或标签"
|
||||||
},
|
},
|
||||||
"tank": {
|
"tank": {
|
||||||
"name": "战车",
|
"name": "坦克",
|
||||||
"description": "要获取战绩的坦克"
|
"description": "要获取战绩的坦克"
|
||||||
},
|
},
|
||||||
"username": {
|
"username": {
|
||||||
@@ -269,8 +269,8 @@
|
|||||||
"description": "国别"
|
"description": "国别"
|
||||||
},
|
},
|
||||||
"class": {
|
"class": {
|
||||||
"name": "战车车型",
|
"name": "坦克车型",
|
||||||
"description": "战车车型"
|
"description": "坦克车型"
|
||||||
},
|
},
|
||||||
"type": {
|
"type": {
|
||||||
"name": "战车类型",
|
"name": "战车类型",
|
||||||
@@ -320,7 +320,7 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"commands": {
|
"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.",
|
"dead": "# 统计指令现已停用\nBlitzKit Discord 机器人此前依赖 BlitzStars 获取周期性的统计数据。由于 BlitzStars 已启用严格的 Cloudflare 防护,导致 BlitzKit 无法继续使用其 API。这已导致以下指令失效:\n/统计\n/今日\n/损坏\n/演变\n/完整统计\n请使用 [Aftermath](<https://amth.one/invite>) \n作为完全独立于 BlitzStars 的替代方案。由 BlitzKit 托管的统计指令将在近期内恢复。",
|
||||||
"replay": {
|
"replay": {
|
||||||
"name": "回放",
|
"name": "回放",
|
||||||
"description": "显示重播结果",
|
"description": "显示重播结果",
|
||||||
@@ -427,8 +427,8 @@
|
|||||||
"description": "玩家数据统计"
|
"description": "玩家数据统计"
|
||||||
},
|
},
|
||||||
"tank": {
|
"tank": {
|
||||||
"name": "战车",
|
"name": "坦克",
|
||||||
"description": "战车数据统计"
|
"description": "坦克数据统计"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -564,15 +564,15 @@
|
|||||||
},
|
},
|
||||||
"today": {
|
"today": {
|
||||||
"name": "今日",
|
"name": "今日",
|
||||||
"description": "今天玩过的战车和统计资料"
|
"description": "今天玩过的坦克和统计数据"
|
||||||
},
|
},
|
||||||
"stats": {
|
"stats": {
|
||||||
"name": "统计资料",
|
"name": "统计资料",
|
||||||
"description": "一段时间内的快速统计"
|
"description": "一段时间内的快速统计"
|
||||||
},
|
},
|
||||||
"owned_tanks": {
|
"owned_tanks": {
|
||||||
"name": "已拥有的战车",
|
"name": "已拥有的坦克",
|
||||||
"description": "显示该阶级中所有您已拥有的战车",
|
"description": "在一个等级中显示所有已拥有的坦克",
|
||||||
"body": {
|
"body": {
|
||||||
"title": "# {name} 所拥有的 {tier} 阶坦克\n\n"
|
"title": "# {name} 所拥有的 {tier} 阶坦克\n\n"
|
||||||
}
|
}
|
||||||
@@ -585,7 +585,7 @@
|
|||||||
"view_channels": "查看频道:需要找到重新整理按钮使用的讯息",
|
"view_channels": "查看频道:需要找到重新整理按钮使用的讯息",
|
||||||
"read_message_history": "读取消息历史: 需要找到消息以刷新",
|
"read_message_history": "读取消息历史: 需要找到消息以刷新",
|
||||||
"attach_files": "附加文件:需要将图像添加到基于图像的命令",
|
"attach_files": "附加文件:需要将图像添加到基于图像的命令",
|
||||||
"external_emojis": "外部表情符号:需要添加国家旗帜和战车类别"
|
"external_emojis": "外部表情:需要添加国家旗帜和坦克等级表情"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"ping": {
|
"ping": {
|
||||||
@@ -602,7 +602,7 @@
|
|||||||
},
|
},
|
||||||
"wotb": {
|
"wotb": {
|
||||||
"name": "战车世界闪击战",
|
"name": "战车世界闪击战",
|
||||||
"description": "测试战车世界闪击战的ping值(延迟值)"
|
"description": "测试坦克世界闪击战的ping值(延迟值)"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -673,7 +673,7 @@
|
|||||||
"search_bar_hint": "搜寻战车……",
|
"search_bar_hint": "搜寻战车……",
|
||||||
"recent": "最近查看的",
|
"recent": "最近查看的",
|
||||||
"select_all": "全选",
|
"select_all": "全选",
|
||||||
"count_singular": "1辆战车",
|
"count_singular": "1 辆坦克",
|
||||||
"count_plural": "{count} 辆坦克",
|
"count_plural": "{count} 辆坦克",
|
||||||
"sorting_by": "按 {name} 排序",
|
"sorting_by": "按 {name} 排序",
|
||||||
"clear": "清除",
|
"clear": "清除",
|
||||||
@@ -681,7 +681,7 @@
|
|||||||
"passive": "{name} (被动)",
|
"passive": "{name} (被动)",
|
||||||
"active": "{name} (主动)",
|
"active": "{name} (主动)",
|
||||||
"no_tanks_found": {
|
"no_tanks_found": {
|
||||||
"body": "找不到战车。",
|
"body": "未找到坦克。",
|
||||||
"search_again": "请尝试重新搜索。",
|
"search_again": "请尝试重新搜索。",
|
||||||
"clear_filters": "请尝试清除筛选。"
|
"clear_filters": "请尝试清除筛选。"
|
||||||
},
|
},
|
||||||
@@ -695,11 +695,11 @@
|
|||||||
"survivability.volume": "体积",
|
"survivability.volume": "体积",
|
||||||
"survivability.length": "长度",
|
"survivability.length": "长度",
|
||||||
"fire.dpm": "标准炮弹 每分钟伤害血量",
|
"fire.dpm": "标准炮弹 每分钟伤害血量",
|
||||||
"fire.dpmPremium": "加值炮弹 每分钟伤害血量",
|
"fire.dpmPremium": "金币炮弹 每分钟伤害值",
|
||||||
"fire.reload": "装填时间",
|
"fire.reload": "装填时间",
|
||||||
"fire.caliber": "口径",
|
"fire.caliber": "口径",
|
||||||
"fire.standardPenetration": "标准炮弹穿透力",
|
"fire.standardPenetration": "标准炮弹穿透力",
|
||||||
"fire.premiumPenetration": "加值炮弹穿透力",
|
"fire.premiumPenetration": "金币炮弹穿透力",
|
||||||
"fire.tertiaryPenetration": "第三种炮弹穿透力",
|
"fire.tertiaryPenetration": "第三种炮弹穿透力",
|
||||||
"fire.damage": "炮弹伤害值",
|
"fire.damage": "炮弹伤害值",
|
||||||
"fire.moduleDamage": "模组伤害值",
|
"fire.moduleDamage": "模组伤害值",
|
||||||
@@ -750,8 +750,8 @@
|
|||||||
"dismiss": "取消"
|
"dismiss": "取消"
|
||||||
},
|
},
|
||||||
"discord": {
|
"discord": {
|
||||||
"join_short": "加入超級酷的人群!",
|
"join_short": "加入超级酷的人群!",
|
||||||
"join_long": "加入我們的Discord社群,和超酷的人一起聊天!",
|
"join_long": "加入我们的Discord社群,和超酷的人一起聊天!",
|
||||||
"action": "Discord"
|
"action": "Discord"
|
||||||
},
|
},
|
||||||
"hero": {
|
"hero": {
|
||||||
@@ -765,7 +765,7 @@
|
|||||||
"title": "其他酷炫的项目"
|
"title": "其他酷炫的项目"
|
||||||
},
|
},
|
||||||
"help_translate": "请帮忙将 {name} 翻译成 {language}!",
|
"help_translate": "请帮忙将 {name} 翻译成 {language}!",
|
||||||
"seo_description": "战车世界闪击战 全方位工具"
|
"seo_description": "坦克世界闪击战 全方位工具"
|
||||||
},
|
},
|
||||||
"docs": {
|
"docs": {
|
||||||
"patches": {
|
"patches": {
|
||||||
@@ -800,7 +800,7 @@
|
|||||||
"proceed": "继续操作"
|
"proceed": "继续操作"
|
||||||
},
|
},
|
||||||
"generate": "创建游玩列表",
|
"generate": "创建游玩列表",
|
||||||
"name": "遊玩列表",
|
"name": "游玩列表",
|
||||||
"description": "坦克游玩列表生成器",
|
"description": "坦克游玩列表生成器",
|
||||||
"seo_description": "想不到在坦克世界闪击战玩什么? 使用BlitzKit 游玩列表来获得建议!",
|
"seo_description": "想不到在坦克世界闪击战玩什么? 使用BlitzKit 游玩列表来获得建议!",
|
||||||
"button": "生成",
|
"button": "生成",
|
||||||
@@ -961,7 +961,7 @@
|
|||||||
"type": "战车类型",
|
"type": "战车类型",
|
||||||
"dev_id": "开发参数:ID",
|
"dev_id": "开发参数:ID",
|
||||||
"purchase": "购买价格",
|
"purchase": "购买价格",
|
||||||
"restoration": "恢复战车价格",
|
"restoration": "恢复坦克价格",
|
||||||
"sale": "出售价格",
|
"sale": "出售价格",
|
||||||
"research": "研发所需经验"
|
"research": "研发所需经验"
|
||||||
},
|
},
|
||||||
@@ -1056,10 +1056,10 @@
|
|||||||
"dispersionGunDamaged": "主炮损坏时",
|
"dispersionGunDamaged": "主炮损坏时",
|
||||||
"gunDepression": "俯角",
|
"gunDepression": "俯角",
|
||||||
"gunElevation": "仰角",
|
"gunElevation": "仰角",
|
||||||
"gunFrontalDepression": "车辆前部俯角",
|
"gunFrontalDepression": "车体前部俯角",
|
||||||
"gunFrontalElevation": "车辆前部仰角",
|
"gunFrontalElevation": "车体前部仰角",
|
||||||
"gunRearDepression": "车辆後部俯角",
|
"gunRearDepression": "车体后部俯角",
|
||||||
"gunRearElevation": "车辆後部仰角",
|
"gunRearElevation": "车体后部仰角",
|
||||||
"azimuthLeft": "左射界",
|
"azimuthLeft": "左射界",
|
||||||
"azimuthRight": "右射界",
|
"azimuthRight": "右射界",
|
||||||
"speedForwards": "最高前进速度",
|
"speedForwards": "最高前进速度",
|
||||||
@@ -1259,7 +1259,7 @@
|
|||||||
"description": "用于串流的嵌入",
|
"description": "用于串流的嵌入",
|
||||||
"seo_description": "创建具有极高自订化的《坦克世界:闪击战》串流嵌入功能",
|
"seo_description": "创建具有极高自订化的《坦克世界:闪击战》串流嵌入功能",
|
||||||
"coming_soon": "更多嵌入功能即将推出。",
|
"coming_soon": "更多嵌入功能即将推出。",
|
||||||
"suggest": "建议与想法",
|
"suggest": "建议与想法。",
|
||||||
"preview": {
|
"preview": {
|
||||||
"title": "示例预览",
|
"title": "示例预览",
|
||||||
"upload": "上传测试背景"
|
"upload": "上传测试背景"
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
import {
|
import {
|
||||||
AverageDefinitions,
|
AverageDefinitions,
|
||||||
|
AverageDefinitionsAllStats,
|
||||||
AverageDefinitionsEntry,
|
AverageDefinitionsEntry,
|
||||||
type AverageDefinitionsManifest,
|
type AverageDefinitionsManifest,
|
||||||
type IndividualTankStats,
|
type IndividualTankStats,
|
||||||
@@ -30,9 +31,6 @@ type OptionalSecondLevel<T> = {
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
type AverageDefinitionsEntrySubPartial =
|
|
||||||
OptionalSecondLevel<AverageDefinitionsEntry>;
|
|
||||||
|
|
||||||
const MINUTE = 60 * 1000;
|
const MINUTE = 60 * 1000;
|
||||||
const HOUR = 60 * MINUTE;
|
const HOUR = 60 * MINUTE;
|
||||||
const DAY = 24 * HOUR;
|
const DAY = 24 * HOUR;
|
||||||
@@ -47,15 +45,15 @@ const preDiscoveredIds = await fetchPreDiscoveredIds();
|
|||||||
const playerIds: Record<Region, number[][]> = {
|
const playerIds: Record<Region, number[][]> = {
|
||||||
asia: chunk(
|
asia: chunk(
|
||||||
preDiscoveredIds.filter((id) => idToRegion(id) === "asia"),
|
preDiscoveredIds.filter((id) => idToRegion(id) === "asia"),
|
||||||
PLAYER_IDS_PER_CALL
|
PLAYER_IDS_PER_CALL,
|
||||||
),
|
),
|
||||||
com: chunk(
|
com: chunk(
|
||||||
preDiscoveredIds.filter((id) => idToRegion(id) === "com"),
|
preDiscoveredIds.filter((id) => idToRegion(id) === "com"),
|
||||||
PLAYER_IDS_PER_CALL
|
PLAYER_IDS_PER_CALL,
|
||||||
),
|
),
|
||||||
eu: chunk(
|
eu: chunk(
|
||||||
preDiscoveredIds.filter((id) => idToRegion(id) === "eu"),
|
preDiscoveredIds.filter((id) => idToRegion(id) === "eu"),
|
||||||
PLAYER_IDS_PER_CALL
|
PLAYER_IDS_PER_CALL,
|
||||||
),
|
),
|
||||||
};
|
};
|
||||||
let regionIndex = 0;
|
let regionIndex = 0;
|
||||||
@@ -71,7 +69,7 @@ times(THREADS, async () => {
|
|||||||
const regionIds = playerIds[region];
|
const regionIds = playerIds[region];
|
||||||
const [ids] = regionIds.splice(
|
const [ids] = regionIds.splice(
|
||||||
Math.floor(Math.random() * regionIds.length),
|
Math.floor(Math.random() * regionIds.length),
|
||||||
1
|
1,
|
||||||
);
|
);
|
||||||
const accountInfo = await getAccountInfo(region, ids, undefined, {
|
const accountInfo = await getAccountInfo(region, ids, undefined, {
|
||||||
fields: "last_battle_time,statistics.all.battles",
|
fields: "last_battle_time,statistics.all.battles",
|
||||||
@@ -104,8 +102,8 @@ times(THREADS, async () => {
|
|||||||
filteredIds.map((id) =>
|
filteredIds.map((id) =>
|
||||||
getTankStats(region, id, {
|
getTankStats(region, id, {
|
||||||
fields: "last_battle_time,battle_life_time,all,tank_id",
|
fields: "last_battle_time,battle_life_time,all,tank_id",
|
||||||
})
|
}),
|
||||||
)
|
),
|
||||||
);
|
);
|
||||||
|
|
||||||
players.forEach((tanks) => {
|
players.forEach((tanks) => {
|
||||||
@@ -114,7 +112,7 @@ times(THREADS, async () => {
|
|||||||
|
|
||||||
if (!tankIds.includes(tank.tank_id)) {
|
if (!tankIds.includes(tank.tank_id)) {
|
||||||
console.log(
|
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);
|
tankIds.push(tank.tank_id);
|
||||||
tanksSorted[tank.tank_id] = [];
|
tanksSorted[tank.tank_id] = [];
|
||||||
@@ -140,7 +138,7 @@ async function postWork() {
|
|||||||
console.log(
|
console.log(
|
||||||
`Generating statistics based on ${samples.d_120.toLocaleString()} players (${samples.total.toLocaleString()} checked in total) and ${
|
`Generating statistics based on ${samples.d_120.toLocaleString()} players (${samples.total.toLocaleString()} checked in total) and ${
|
||||||
tankIds.length
|
tankIds.length
|
||||||
} tanks...`
|
} tanks...`,
|
||||||
);
|
);
|
||||||
|
|
||||||
using uploader = new AssetUploader("averages");
|
using uploader = new AssetUploader("averages");
|
||||||
@@ -152,7 +150,12 @@ async function postWork() {
|
|||||||
// (tank) => Date.now() - tank.last_battle_time * 1000 <= MAX_ACTIVITY_TIME,
|
// (tank) => Date.now() - tank.last_battle_time * 1000 <= MAX_ACTIVITY_TIME,
|
||||||
// );
|
// );
|
||||||
const tanks = tanksSortedEntry;
|
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: {},
|
mu: {},
|
||||||
sigma: {},
|
sigma: {},
|
||||||
r: {},
|
r: {},
|
||||||
@@ -162,13 +165,13 @@ async function postWork() {
|
|||||||
tanks.forEach((tank) => {
|
tanks.forEach((tank) => {
|
||||||
const timeSinceLastActivity = Date.now() - tank.last_battle_time * 1000;
|
const timeSinceLastActivity = Date.now() - tank.last_battle_time * 1000;
|
||||||
|
|
||||||
entry.samples.total++;
|
entry.samples!.total++;
|
||||||
if (timeSinceLastActivity <= 120 * DAY) entry.samples.d_120++;
|
if (timeSinceLastActivity <= 120 * DAY) entry.samples!.d_120++;
|
||||||
if (timeSinceLastActivity <= 90 * DAY) entry.samples.d_90++;
|
if (timeSinceLastActivity <= 90 * DAY) entry.samples!.d_90++;
|
||||||
if (timeSinceLastActivity <= 60 * DAY) entry.samples.d_60++;
|
if (timeSinceLastActivity <= 60 * DAY) entry.samples!.d_60++;
|
||||||
if (timeSinceLastActivity <= 30 * DAY) entry.samples.d_30++;
|
if (timeSinceLastActivity <= 30 * DAY) entry.samples!.d_30++;
|
||||||
if (timeSinceLastActivity <= 7 * DAY) entry.samples.d_7++;
|
if (timeSinceLastActivity <= 7 * DAY) entry.samples!.d_7++;
|
||||||
if (timeSinceLastActivity <= 1 * DAY) entry.samples.d_1++;
|
if (timeSinceLastActivity <= 1 * DAY) entry.samples!.d_1++;
|
||||||
});
|
});
|
||||||
|
|
||||||
const dataWY = tanks.map((tank) => ({
|
const dataWY = tanks.map((tank) => ({
|
||||||
@@ -191,7 +194,7 @@ async function postWork() {
|
|||||||
function sum(slicer: (data: DataPoint) => number) {
|
function sum(slicer: (data: DataPoint) => number) {
|
||||||
return data.reduce(
|
return data.reduce(
|
||||||
(accumulator, data) => accumulator + slicer(data),
|
(accumulator, data) => accumulator + slicer(data),
|
||||||
0
|
0,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -6,13 +6,15 @@ export async function boosterIcons() {
|
|||||||
console.log("Building booster icons...");
|
console.log("Building booster icons...");
|
||||||
|
|
||||||
const uploader = new AssetUploader("booster icons");
|
const uploader = new AssetUploader("booster icons");
|
||||||
const boosterFiles = vfs
|
const boosterFiles = await vfs
|
||||||
.dir("Data/Gfx/Shared/boosters")
|
.dir("Data/Gfx/Shared/boosters")
|
||||||
.filter(
|
.then((files) =>
|
||||||
(file) => !file.includes("@2x.txt") && !file.startsWith("texture0")
|
files.filter(
|
||||||
|
(file) => !file.includes("@2x.txt") && !file.startsWith("texture0"),
|
||||||
|
),
|
||||||
);
|
);
|
||||||
const image = sharp(
|
const image = sharp(
|
||||||
await vfs.file(`Data/Gfx/Shared/boosters/texture0.packed.webp`)
|
await vfs.file(`Data/Gfx/Shared/boosters/texture0.packed.webp`),
|
||||||
);
|
);
|
||||||
|
|
||||||
for (const file of boosterFiles) {
|
for (const file of boosterFiles) {
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ export async function camouflageIcons() {
|
|||||||
|
|
||||||
using uploader = new AssetUploader("camo icons");
|
using uploader = new AssetUploader("camo icons");
|
||||||
const content = await vfs.file(
|
const content = await vfs.file(
|
||||||
`Data/Gfx/UI/Hangar/IconCamouflage.packed.webp`
|
`Data/Gfx/UI/Hangar/IconCamouflage.packed.webp`,
|
||||||
);
|
);
|
||||||
|
|
||||||
await uploader.add({ content, path: "icons/camo.webp" });
|
await uploader.add({ content, path: "icons/camo.webp" });
|
||||||
|
|||||||
@@ -1,10 +1,12 @@
|
|||||||
import { assertSecret } from "@blitzkit/core";
|
import { assertSecret } from "@blitzkit/core";
|
||||||
import { AbstractVFS } from "../core/vfs/abstract";
|
import { AbstractVFS } from "../core/vfs/abstract";
|
||||||
|
import { LocalVFS } from "../core/vfs/local";
|
||||||
import { SteamVFS } from "../core/vfs/steam";
|
import { SteamVFS } from "../core/vfs/steam";
|
||||||
import { ZipVFS } from "../core/vfs/zip";
|
import { ZipVFS } from "../core/vfs/zip";
|
||||||
|
|
||||||
const steamPattern = /steam:(\d+)\/(\d+)/;
|
const steamPattern = /steam:(\d+)\/(\d+)/;
|
||||||
const zipPattern = /zip:(.+)/;
|
const zipPattern = /zip:(.+)/;
|
||||||
|
const localePattern = /local:"?(.+)"?/;
|
||||||
|
|
||||||
const source = Bun.argv
|
const source = Bun.argv
|
||||||
.find((arg) => arg.startsWith("--source="))
|
.find((arg) => arg.startsWith("--source="))
|
||||||
@@ -21,11 +23,14 @@ if (!source) {
|
|||||||
assertSecret(import.meta.env.STEAM_USERNAME),
|
assertSecret(import.meta.env.STEAM_USERNAME),
|
||||||
assertSecret(import.meta.env.STEAM_PASSWORD),
|
assertSecret(import.meta.env.STEAM_PASSWORD),
|
||||||
app,
|
app,
|
||||||
depot
|
depot,
|
||||||
).init();
|
).init();
|
||||||
} else if (zipPattern.test(source)) {
|
} else if (zipPattern.test(source)) {
|
||||||
const [, url] = source.match(zipPattern)!;
|
const [, url] = source.match(zipPattern)!;
|
||||||
resolved = await new ZipVFS(url).init();
|
resolved = await new ZipVFS(url).init();
|
||||||
|
} else if (localePattern.test(source)) {
|
||||||
|
const [, path] = source.match(localePattern)!;
|
||||||
|
resolved = await new LocalVFS(path).init();
|
||||||
} else {
|
} else {
|
||||||
throw new Error("No valid source specified");
|
throw new Error("No valid source specified");
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -18,26 +18,20 @@ export async function consumableProvisionIcons() {
|
|||||||
|
|
||||||
using uploader = new AssetUploader("consumable and provision icons");
|
using uploader = new AssetUploader("consumable and provision icons");
|
||||||
const styles = [
|
const styles = [
|
||||||
|
"UI/Styles/Lobby/Inventory/InventoryNormalStyles.yaml",
|
||||||
"UI/Styles/Lobby/Inventory/Event/InventoryBigStyles.yaml",
|
"UI/Styles/Lobby/Inventory/Event/InventoryBigStyles.yaml",
|
||||||
"UI/Styles/Lobby/Inventory/Event/InventoryNormalStyles.yaml",
|
"UI/Styles/Lobby/Inventory/Event/InventoryNormalStyles.yaml",
|
||||||
"UI/Styles/Lobby/Inventory/InventoryNormalStyles.yaml",
|
|
||||||
"UI/Screens3/Lobby/Inventory/Equipment/EquipmentItemImage.style.yaml",
|
"UI/Screens3/Lobby/Inventory/Equipment/EquipmentItemImage.style.yaml",
|
||||||
"UI/Screens/Battle/Styles/BattleEquipmentStyles.yaml",
|
"UI/Screens/Battle/Styles/BattleEquipmentStyles.yaml",
|
||||||
];
|
];
|
||||||
const styleSheets = await Promise.all(
|
const styleSheets = await Promise.all(
|
||||||
styles.map(async (path) =>
|
styles.map(async (path) =>
|
||||||
Object.values(
|
Object.values((await vfs.yaml<Mappings>(`Data/${path}`)).StyleSheets),
|
||||||
(
|
),
|
||||||
await vfs.yaml<Mappings>(`Data/${path}`)
|
|
||||||
).StyleSheets
|
|
||||||
)
|
|
||||||
)
|
|
||||||
).then((array) => array.flat());
|
).then((array) => array.flat());
|
||||||
|
|
||||||
for (const match of (
|
for (const match of (
|
||||||
await vfs.text(
|
await vfs.text(`Data/XML/item_defs/vehicles/common/consumables/list.xml`)
|
||||||
`Data/XML/item_defs/vehicles/common/consumables/list.xml`
|
|
||||||
)
|
|
||||||
).matchAll(listItemsPattern)) {
|
).matchAll(listItemsPattern)) {
|
||||||
const consumablesCommon = await vfs.xml<{
|
const consumablesCommon = await vfs.xml<{
|
||||||
root: ConsumablesCommon;
|
root: ConsumablesCommon;
|
||||||
@@ -46,13 +40,13 @@ export async function consumableProvisionIcons() {
|
|||||||
for (const consumable of Object.values(consumablesCommon.root)) {
|
for (const consumable of Object.values(consumablesCommon.root)) {
|
||||||
const styleSheet = styleSheets.find((styleSheet) =>
|
const styleSheet = styleSheets.find((styleSheet) =>
|
||||||
styleSheet.selectors.some((selector) =>
|
styleSheet.selectors.some((selector) =>
|
||||||
selector.includes(`${consumable.icon} `)
|
selector.includes(`${consumable.icon} `),
|
||||||
)
|
),
|
||||||
);
|
);
|
||||||
|
|
||||||
if (!styleSheet) {
|
if (!styleSheet) {
|
||||||
console.warn(
|
console.warn(
|
||||||
`No style sheet found for consumable ${consumable.icon}; skipping...`
|
`No style sheet found for consumable ${consumable.icon}; skipping...`,
|
||||||
);
|
);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@@ -62,10 +56,8 @@ export async function consumableProvisionIcons() {
|
|||||||
.replace(".psd", "")
|
.replace(".psd", "")
|
||||||
.replace(".txt", "");
|
.replace(".txt", "");
|
||||||
|
|
||||||
if (vfs.resolve(`Data/${configPath}.packed.webp`)) {
|
if (await vfs.resolve(`Data/${configPath}.packed.webp`)) {
|
||||||
const image = sharp(
|
const image = sharp(await vfs.file(`Data/${configPath}.packed.webp`));
|
||||||
await vfs.file(`Data/${configPath}.packed.webp`)
|
|
||||||
);
|
|
||||||
const content = await image.trim({ threshold: 100 }).toBuffer();
|
const content = await image.trim({ threshold: 100 }).toBuffer();
|
||||||
|
|
||||||
await uploader.add({
|
await uploader.add({
|
||||||
@@ -78,8 +70,8 @@ export async function consumableProvisionIcons() {
|
|||||||
`${`Data/${configPath}`
|
`${`Data/${configPath}`
|
||||||
.split("/")
|
.split("/")
|
||||||
.slice(0, -1)
|
.slice(0, -1)
|
||||||
.join("/")}/texture0.packed.webp`
|
.join("/")}/texture0.packed.webp`,
|
||||||
)
|
),
|
||||||
);
|
);
|
||||||
const sizes = (await vfs.text(`Data/${configPath}.txt`))
|
const sizes = (await vfs.text(`Data/${configPath}.txt`))
|
||||||
.split("\n")[4]
|
.split("\n")[4]
|
||||||
@@ -104,9 +96,7 @@ export async function consumableProvisionIcons() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
for (const match of (
|
for (const match of (
|
||||||
await vfs.text(
|
await vfs.text(`Data/XML/item_defs/vehicles/common/provisions/list.xml`)
|
||||||
`Data/XML/item_defs/vehicles/common/provisions/list.xml`
|
|
||||||
)
|
|
||||||
).matchAll(listItemsPattern)) {
|
).matchAll(listItemsPattern)) {
|
||||||
const provisionsCommon = await vfs.xml<{
|
const provisionsCommon = await vfs.xml<{
|
||||||
root: ProvisionsCommon;
|
root: ProvisionsCommon;
|
||||||
@@ -115,13 +105,13 @@ export async function consumableProvisionIcons() {
|
|||||||
for (const provision of Object.values(provisionsCommon.root)) {
|
for (const provision of Object.values(provisionsCommon.root)) {
|
||||||
const styleSheet = styleSheets.find((styleSheet) =>
|
const styleSheet = styleSheets.find((styleSheet) =>
|
||||||
styleSheet.selectors.some((selector) =>
|
styleSheet.selectors.some((selector) =>
|
||||||
selector.includes(`${provision.icon} `)
|
selector.includes(`${provision.icon} `),
|
||||||
)
|
),
|
||||||
);
|
);
|
||||||
|
|
||||||
if (!styleSheet) {
|
if (!styleSheet) {
|
||||||
console.warn(
|
console.warn(
|
||||||
`No style sheet found for provision ${provision.icon}; skipping...`
|
`No style sheet found for provision ${provision.icon}; skipping...`,
|
||||||
);
|
);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@@ -131,10 +121,8 @@ export async function consumableProvisionIcons() {
|
|||||||
.replace(".psd", "")
|
.replace(".psd", "")
|
||||||
.replace(".txt", "");
|
.replace(".txt", "");
|
||||||
|
|
||||||
if (vfs.resolve(`Data/${configPath}.packed.webp`)) {
|
if (await vfs.resolve(`Data/${configPath}.packed.webp`)) {
|
||||||
const image = sharp(
|
const image = sharp(await vfs.file(`Data/${configPath}.packed.webp`));
|
||||||
await vfs.file(`Data/${configPath}.packed.webp`)
|
|
||||||
);
|
|
||||||
const content = await image.trim({ threshold: 100 }).toBuffer();
|
const content = await image.trim({ threshold: 100 }).toBuffer();
|
||||||
|
|
||||||
await uploader.add({
|
await uploader.add({
|
||||||
@@ -147,8 +135,8 @@ export async function consumableProvisionIcons() {
|
|||||||
`${`Data/${configPath}`
|
`${`Data/${configPath}`
|
||||||
.split("/")
|
.split("/")
|
||||||
.slice(0, -1)
|
.slice(0, -1)
|
||||||
.join("/")}/texture0.packed.webp`
|
.join("/")}/texture0.packed.webp`,
|
||||||
)
|
),
|
||||||
);
|
);
|
||||||
const sizes = (await vfs.text(`Data/${configPath}.txt`))
|
const sizes = (await vfs.text(`Data/${configPath}.txt`))
|
||||||
.split("\n")[4]
|
.split("\n")[4]
|
||||||
|
|||||||
@@ -20,7 +20,7 @@ export async function currencies() {
|
|||||||
|
|
||||||
for (const [file, name] of ICONS) {
|
for (const [file, name] of ICONS) {
|
||||||
const content = await sharp(
|
const content = await sharp(
|
||||||
await vfs.file(`Data/Gfx/Lobby/currency/${file}`)
|
await vfs.file(`Data/Gfx/Lobby/currency/${file}`),
|
||||||
)
|
)
|
||||||
.trim()
|
.trim()
|
||||||
.toBuffer();
|
.toBuffer();
|
||||||
@@ -36,14 +36,14 @@ export async function currencies() {
|
|||||||
.then((glossary) =>
|
.then((glossary) =>
|
||||||
Object.values(glossary)
|
Object.values(glossary)
|
||||||
.entries()
|
.entries()
|
||||||
.filter(([key]) => /^prx_season_\d+$/.test(`${key}`))
|
.filter(([key]) => /^prx_season_\d+$/.test(`${key}`)),
|
||||||
);
|
);
|
||||||
|
|
||||||
for (const [key, item] of glossary) {
|
for (const [key, item] of glossary) {
|
||||||
if (item.image_url === null) throw new Error(`No image_url for ${key}`);
|
if (item.image_url === null) throw new Error(`No image_url for ${key}`);
|
||||||
|
|
||||||
const imageRaw = await fetch(item.image_url).then((response) =>
|
const imageRaw = await fetch(item.image_url).then((response) =>
|
||||||
response.arrayBuffer()
|
response.arrayBuffer(),
|
||||||
);
|
);
|
||||||
const content = await sharp(imageRaw)
|
const content = await sharp(imageRaw)
|
||||||
.trim({
|
.trim({
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ import {
|
|||||||
ConsumableTankCategoryFilterCategory,
|
ConsumableTankCategoryFilterCategory,
|
||||||
Crew,
|
Crew,
|
||||||
CrewType,
|
CrewType,
|
||||||
|
Equalizer,
|
||||||
EquipmentDefinitions,
|
EquipmentDefinitions,
|
||||||
EquipmentSlot,
|
EquipmentSlot,
|
||||||
GameDefinitions,
|
GameDefinitions,
|
||||||
@@ -32,6 +33,7 @@ import {
|
|||||||
} from "@blitzkit/core";
|
} from "@blitzkit/core";
|
||||||
import { SUPPORTED_LOCALE_BLITZ_MAP } from "@blitzkit/i18n";
|
import { SUPPORTED_LOCALE_BLITZ_MAP } from "@blitzkit/i18n";
|
||||||
import locales from "@blitzkit/i18n/locales.json";
|
import locales from "@blitzkit/i18n/locales.json";
|
||||||
|
import { readFile } from "fs/promises";
|
||||||
import { deburr } from "lodash-es";
|
import { deburr } from "lodash-es";
|
||||||
import { parse as parsePath } from "path";
|
import { parse as parsePath } from "path";
|
||||||
import type { Vector3Tuple } from "three";
|
import type { Vector3Tuple } from "three";
|
||||||
@@ -81,16 +83,16 @@ const blitzTankFilterDefinitionCategoryToBlitzkit: Record<
|
|||||||
BlitzTankFilterDefinitionCategory,
|
BlitzTankFilterDefinitionCategory,
|
||||||
ConsumableTankCategoryFilterCategory
|
ConsumableTankCategoryFilterCategory
|
||||||
> = {
|
> = {
|
||||||
clip: ConsumableTankCategoryFilterCategory.CLIP,
|
clip: ConsumableTankCategoryFilterCategory.CONSUMABLE_TANK_CATEGORY_FILTER_CATEGORY_CLIP,
|
||||||
};
|
};
|
||||||
function vector3TupleToBlitzkit(tuple: Vector3Tuple) {
|
function vector3TupleToBlitzkit(tuple: Vector3Tuple) {
|
||||||
return { x: tuple[0], y: tuple[1], z: tuple[2] } satisfies Vector3;
|
return { x: tuple[0], y: tuple[1], z: tuple[2] } satisfies Vector3;
|
||||||
}
|
}
|
||||||
const blitzTankClassToBlitzkit: Record<BlitzTankClass, TankClass> = {
|
const blitzTankClassToBlitzkit: Record<BlitzTankClass, TankClass> = {
|
||||||
lightTank: TankClass.LIGHT,
|
lightTank: TankClass.TANK_CLASS_LIGHT,
|
||||||
"AT-SPG": TankClass.TANK_DESTROYER,
|
"AT-SPG": TankClass.TANK_CLASS_TANK_DESTROYER,
|
||||||
heavyTank: TankClass.HEAVY,
|
heavyTank: TankClass.TANK_CLASS_HEAVY,
|
||||||
mediumTank: TankClass.MEDIUM,
|
mediumTank: TankClass.TANK_CLASS_MEDIUM,
|
||||||
};
|
};
|
||||||
export interface BlitzStrings {
|
export interface BlitzStrings {
|
||||||
[key: string]: string;
|
[key: string]: string;
|
||||||
@@ -135,7 +137,7 @@ export interface ChassisDefinitionsList {
|
|||||||
}
|
}
|
||||||
type VehicleDefinitionArmor = Record<
|
type VehicleDefinitionArmor = Record<
|
||||||
string,
|
string,
|
||||||
number | { vehicleDamageFactor: 0; "#text": number }
|
number | { vehicleDamageFactor: 0; "#text": number } | number[]
|
||||||
>;
|
>;
|
||||||
interface UnlocksInner {
|
interface UnlocksInner {
|
||||||
cost: number | string;
|
cost: number | string;
|
||||||
@@ -149,18 +151,18 @@ type BlitzModuleType = {
|
|||||||
type UnlocksListing = BlitzModuleType | undefined;
|
type UnlocksListing = BlitzModuleType | undefined;
|
||||||
type BlitzCrewType = "commander" | "radioman" | "gunner" | "driver" | "loader";
|
type BlitzCrewType = "commander" | "radioman" | "gunner" | "driver" | "loader";
|
||||||
const blitzCrewTypeToBlitzkit: Record<BlitzCrewType, CrewType> = {
|
const blitzCrewTypeToBlitzkit: Record<BlitzCrewType, CrewType> = {
|
||||||
commander: CrewType.COMMANDER,
|
commander: CrewType.CREW_TYPE_COMMANDER,
|
||||||
driver: CrewType.DRIVER,
|
driver: CrewType.CREW_TYPE_DRIVER,
|
||||||
gunner: CrewType.GUNNER,
|
gunner: CrewType.CREW_TYPE_GUNNER,
|
||||||
loader: CrewType.LOADER,
|
loader: CrewType.CREW_TYPE_LOADER,
|
||||||
radioman: CrewType.RADIOMAN,
|
radioman: CrewType.CREW_TYPE_RADIOMAN,
|
||||||
};
|
};
|
||||||
const blitzkitCrewTypeToBlitz: Record<CrewType, BlitzCrewType> = {
|
const blitzkitCrewTypeToBlitz: Record<CrewType, BlitzCrewType> = {
|
||||||
[CrewType.COMMANDER]: "commander",
|
[CrewType.CREW_TYPE_COMMANDER]: "commander",
|
||||||
[CrewType.DRIVER]: "driver",
|
[CrewType.CREW_TYPE_DRIVER]: "driver",
|
||||||
[CrewType.GUNNER]: "gunner",
|
[CrewType.CREW_TYPE_GUNNER]: "gunner",
|
||||||
[CrewType.LOADER]: "loader",
|
[CrewType.CREW_TYPE_LOADER]: "loader",
|
||||||
[CrewType.RADIOMAN]: "radioman",
|
[CrewType.CREW_TYPE_RADIOMAN]: "radioman",
|
||||||
};
|
};
|
||||||
interface VehicleDefinitions {
|
interface VehicleDefinitions {
|
||||||
invisibility: {
|
invisibility: {
|
||||||
@@ -298,7 +300,7 @@ interface VehicleDefinitions {
|
|||||||
type: "default";
|
type: "default";
|
||||||
enabled: false;
|
enabled: false;
|
||||||
factorsModifiers: "";
|
factorsModifiers: "";
|
||||||
}
|
},
|
||||||
];
|
];
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
@@ -517,20 +519,36 @@ type CombatRolesYaml = Record<
|
|||||||
>;
|
>;
|
||||||
|
|
||||||
const blitzShellKindToBlitzkit: Record<ShellKind, ShellType> = {
|
const blitzShellKindToBlitzkit: Record<ShellKind, ShellType> = {
|
||||||
ARMOR_PIERCING: ShellType.AP,
|
ARMOR_PIERCING: ShellType.SHELL_TYPE_AP,
|
||||||
ARMOR_PIERCING_CR: ShellType.APCR,
|
ARMOR_PIERCING_CR: ShellType.SHELL_TYPE_APCR,
|
||||||
HIGH_EXPLOSIVE: ShellType.HE,
|
HIGH_EXPLOSIVE: ShellType.SHELL_TYPE_HE,
|
||||||
HOLLOW_CHARGE: ShellType.HEAT,
|
HOLLOW_CHARGE: ShellType.SHELL_TYPE_HEAT,
|
||||||
};
|
};
|
||||||
export const botPattern = /^.+((tutorial_bot(\d+)?)|(TU))$/;
|
export const botPattern = /^.+((tutorial_bot(\d+)?)|(TU))$/;
|
||||||
const blitzModuleTypeToBlitzkit: Record<keyof BlitzModuleType, ModuleType> = {
|
const blitzModuleTypeToBlitzkit: Record<keyof BlitzModuleType, ModuleType> = {
|
||||||
chassis: ModuleType.TRACKS,
|
chassis: ModuleType.MODULE_TYPE_TRACKS,
|
||||||
engine: ModuleType.ENGINE,
|
engine: ModuleType.MODULE_TYPE_ENGINE,
|
||||||
gun: ModuleType.GUN,
|
gun: ModuleType.MODULE_TYPE_GUN,
|
||||||
turret: ModuleType.TURRET,
|
turret: ModuleType.MODULE_TYPE_TURRET,
|
||||||
vehicle: ModuleType.VEHICLE,
|
vehicle: ModuleType.MODULE_TYPE_VEHICLE,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
function assignArmor(
|
||||||
|
raw: VehicleDefinitionArmor[string],
|
||||||
|
id: number,
|
||||||
|
armor: Armor,
|
||||||
|
) {
|
||||||
|
if (typeof raw === "number") {
|
||||||
|
armor.thickness[id] = raw;
|
||||||
|
} else if (Array.isArray(raw)) {
|
||||||
|
armor.thickness[id] = raw.at(-1)!;
|
||||||
|
} else {
|
||||||
|
if (!armor.spaced) armor.spaced = [];
|
||||||
|
armor.thickness[id] = raw["#text"];
|
||||||
|
armor.spaced.push(id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
export async function definitions() {
|
export async function definitions() {
|
||||||
console.log("Building definitions...");
|
console.log("Building definitions...");
|
||||||
|
|
||||||
@@ -555,18 +573,18 @@ export async function definitions() {
|
|||||||
const provisionDefinitions: ProvisionDefinitions = { provisions: {} };
|
const provisionDefinitions: ProvisionDefinitions = { provisions: {} };
|
||||||
const skillDefinitions: SkillDefinitions = {
|
const skillDefinitions: SkillDefinitions = {
|
||||||
classes: {
|
classes: {
|
||||||
[TankClass.LIGHT]: { skills: [] },
|
[TankClass.TANK_CLASS_LIGHT]: { skills: [] },
|
||||||
[TankClass.MEDIUM]: { skills: [] },
|
[TankClass.TANK_CLASS_MEDIUM]: { skills: [] },
|
||||||
[TankClass.HEAVY]: { skills: [] },
|
[TankClass.TANK_CLASS_HEAVY]: { skills: [] },
|
||||||
[TankClass.TANK_DESTROYER]: { skills: [] },
|
[TankClass.TANK_CLASS_TANK_DESTROYER]: { skills: [] },
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
const nations = vfs
|
const nations = await vfs
|
||||||
.dir("Data/XML/item_defs/vehicles")
|
.dir("Data/XML/item_defs/vehicles")
|
||||||
.filter((nation) => nation !== "common");
|
.then((files) => files.filter((nation) => nation !== "common"));
|
||||||
const tankStringIdMap: Record<string, number> = {};
|
const tankStringIdMap: Record<string, number> = {};
|
||||||
const optionalDevices = await vfs.xml<{ root: OptionalDevices }>(
|
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>> = {};
|
const stringsI18n: Record<string, Record<string, string>> = {};
|
||||||
|
|
||||||
@@ -574,12 +592,12 @@ export async function definitions() {
|
|||||||
locales.supported.map(async ({ locale }) => {
|
locales.supported.map(async ({ locale }) => {
|
||||||
const blitzLocale = SUPPORTED_LOCALE_BLITZ_MAP[locale];
|
const blitzLocale = SUPPORTED_LOCALE_BLITZ_MAP[locale];
|
||||||
const cache = await fetch(
|
const cache = await fetch(
|
||||||
`https://stufficons.wgcdn.co/localizations/${blitzLocale}.yaml`
|
`https://stufficons.wgcdn.co/localizations/${blitzLocale}.yaml`,
|
||||||
)
|
)
|
||||||
.then((response) => response.text())
|
.then((response) => response.text())
|
||||||
.then((string) => parseYaml(string) as BlitzStrings);
|
.then((string) => parseYaml(string) as BlitzStrings);
|
||||||
const preInstalled = await vfs.yaml<BlitzStrings>(
|
const preInstalled = await vfs.yaml<BlitzStrings>(
|
||||||
`Data/Strings/${blitzLocale}.yaml`
|
`Data/Strings/${blitzLocale}.yaml`,
|
||||||
);
|
);
|
||||||
|
|
||||||
stringsI18n[locale] = {
|
stringsI18n[locale] = {
|
||||||
@@ -588,7 +606,7 @@ export async function definitions() {
|
|||||||
};
|
};
|
||||||
|
|
||||||
console.log(`Loaded strings for ${locale}`);
|
console.log(`Loaded strings for ${locale}`);
|
||||||
})
|
}),
|
||||||
);
|
);
|
||||||
|
|
||||||
function getString(name: string) {
|
function getString(name: string) {
|
||||||
@@ -627,9 +645,9 @@ export async function definitions() {
|
|||||||
consumables,
|
consumables,
|
||||||
(
|
(
|
||||||
await vfs.xml<{ root: ConsumablesCommon }>(
|
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 +660,57 @@ export async function definitions() {
|
|||||||
provisions,
|
provisions,
|
||||||
(
|
(
|
||||||
await vfs.xml<{ root: ConsumablesCommon }>(
|
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 }>(
|
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 maps = await vfs.yaml<Maps>(`Data/maps.yaml`);
|
||||||
const tankXps = new Map<number, ResearchCost>();
|
const tankXps = new Map<number, ResearchCost>();
|
||||||
const camouflagesXml = await vfs.xml<{ root: CamouflagesXML }>(
|
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>(
|
const camouflagesYaml = await vfs.yaml<CamouflagesYaml>(
|
||||||
`Data/camouflages.yaml`
|
`Data/camouflages.yaml`,
|
||||||
);
|
);
|
||||||
const camouflagesXmlEntries = Object.entries(camouflagesXml.root.camouflages);
|
const camouflagesXmlEntries = Object.entries(camouflagesXml.root.camouflages);
|
||||||
const squadBattleTypeStyles = await vfs.yaml<SquadBattleTypeStyles>(
|
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>(
|
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 gameModeNativeNames: Record<string, number> = {};
|
||||||
const combatRoles = await vfs.yaml<CombatRolesYaml>(
|
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 consumableNativeNames: Record<string, number> = {};
|
||||||
const provisionNativeNames: Record<string, number> = {};
|
const provisionNativeNames: Record<string, number> = {};
|
||||||
|
let equalizerDefinitions: string[][];
|
||||||
|
|
||||||
|
if (
|
||||||
|
await vfs.resolve("Data/XML/item_defs/vehicles/common/tier_equializer.csv")
|
||||||
|
) {
|
||||||
|
equalizerDefinitions = await vfs.csv(
|
||||||
|
`Data/XML/item_defs/vehicles/common/tier_equializer.csv`,
|
||||||
|
{ delimiter: ";" },
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
const stubEqualizerDefinitions = await readFile("stub/equalizer.csv").then(
|
||||||
|
(buffer) => buffer.toString(),
|
||||||
|
);
|
||||||
|
|
||||||
|
equalizerDefinitions = await vfs._csv(stubEqualizerDefinitions, {
|
||||||
|
delimiter: ";",
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
for (const match of squadBattleTypeStyles.Prototypes[0].components.UIDataLocalBindingsComponent.data[1][2].matchAll(
|
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 id = Number(match[1]);
|
||||||
const name = getString(match[2]);
|
const name = getString(match[2]);
|
||||||
@@ -686,7 +722,7 @@ export async function definitions() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
for (const match of gameTypeSelectorStyles.Prototypes[0].components.UIDataLocalBindingsComponent.data[1][2].matchAll(
|
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]) => {
|
Object.entries(gameModeNativeNames).forEach(([key, value]) => {
|
||||||
if (key.toLowerCase() === match[2].toLowerCase()) {
|
if (key.toLowerCase() === match[2].toLowerCase()) {
|
||||||
@@ -720,7 +756,7 @@ export async function definitions() {
|
|||||||
|
|
||||||
for (const nation of nations) {
|
for (const nation of nations) {
|
||||||
const tankList = await vfs.xml<{ root: VehicleDefinitionList }>(
|
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) {
|
for (const tankKey in tankList.root) {
|
||||||
@@ -761,7 +797,7 @@ export async function definitions() {
|
|||||||
console.warn(
|
console.warn(
|
||||||
`Multiple tanks share slug ${slug}: ${requesters
|
`Multiple tanks share slug ${slug}: ${requesters
|
||||||
.map(({ key }) => key)
|
.map(({ key }) => key)
|
||||||
.join(", ")}`
|
.join(", ")}`,
|
||||||
);
|
);
|
||||||
|
|
||||||
if (requesters.length !== 2) {
|
if (requesters.length !== 2) {
|
||||||
@@ -791,7 +827,7 @@ export async function definitions() {
|
|||||||
|
|
||||||
if (canonical === undefined) {
|
if (canonical === undefined) {
|
||||||
throw new Error(
|
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 +840,7 @@ export async function definitions() {
|
|||||||
|
|
||||||
for (const nation of nations) {
|
for (const nation of nations) {
|
||||||
const tankList = await vfs.xml<{ root: VehicleDefinitionList }>(
|
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<{
|
const turretList = await vfs.xml<{
|
||||||
root: TurretDefinitionsList;
|
root: TurretDefinitionsList;
|
||||||
@@ -857,7 +893,7 @@ export async function definitions() {
|
|||||||
: Number(item.cost.split(":")[1]),
|
: Number(item.cost.split(":")[1]),
|
||||||
},
|
},
|
||||||
} satisfies Unlock;
|
} satisfies Unlock;
|
||||||
})
|
}),
|
||||||
)
|
)
|
||||||
.flat();
|
.flat();
|
||||||
}
|
}
|
||||||
@@ -872,10 +908,10 @@ export async function definitions() {
|
|||||||
const tank = tankList.root[tankKey];
|
const tank = tankList.root[tankKey];
|
||||||
let tankPrice: TankPrice;
|
let tankPrice: TankPrice;
|
||||||
const tankDefinition = await vfs.xml<{ root: VehicleDefinitions }>(
|
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>(
|
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
|
const turretOrigin = tankDefinition.root.hull.turretPositions.turret
|
||||||
.split(" ")
|
.split(" ")
|
||||||
@@ -890,23 +926,23 @@ export async function definitions() {
|
|||||||
|
|
||||||
if (slug === undefined) {
|
if (slug === undefined) {
|
||||||
throw new Error(
|
throw new Error(
|
||||||
`Could not find slug for ${nation}/${tankKey} (${tankId})`
|
`Could not find slug for ${nation}/${tankKey} (${tankId})`,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (tank.sellPrice) {
|
if (tank.sellPrice) {
|
||||||
tankPrice = {
|
tankPrice = {
|
||||||
type: TankPriceType.GOLD,
|
type: TankPriceType.TANK_PRICE_TYPE_GOLD,
|
||||||
value: tank.sellPrice["#text"] * 2,
|
value: tank.sellPrice["#text"] * 2,
|
||||||
};
|
};
|
||||||
} else if (typeof tank.price === "number") {
|
} else if (typeof tank.price === "number") {
|
||||||
tankPrice = {
|
tankPrice = {
|
||||||
type: TankPriceType.CREDITS,
|
type: TankPriceType.TANK_PRICE_TYPE_CREDITS,
|
||||||
value: tank.price,
|
value: tank.price,
|
||||||
};
|
};
|
||||||
} else {
|
} else {
|
||||||
tankPrice = {
|
tankPrice = {
|
||||||
type: TankPriceType.CREDITS,
|
type: TankPriceType.TANK_PRICE_TYPE_CREDITS,
|
||||||
value: tank.price["#text"] * 400,
|
value: tank.price["#text"] * 400,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@@ -923,13 +959,7 @@ export async function definitions() {
|
|||||||
const armorId = parseInt(armorIdString);
|
const armorId = parseInt(armorIdString);
|
||||||
const armorRaw = tankDefinition.root.hull.armor[name];
|
const armorRaw = tankDefinition.root.hull.armor[name];
|
||||||
|
|
||||||
if (typeof armorRaw === "number") {
|
assignArmor(armorRaw, armorId, hullArmor);
|
||||||
hullArmor.thickness[armorId] = armorRaw;
|
|
||||||
} else {
|
|
||||||
if (!hullArmor.spaced) hullArmor.spaced = [];
|
|
||||||
hullArmor.thickness[armorId] = armorRaw["#text"];
|
|
||||||
hullArmor.spaced.push(armorId);
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
const crew: Crew[] = [];
|
const crew: Crew[] = [];
|
||||||
const fixedCamouflage = tankTags.includes("eventCamouflage_user");
|
const fixedCamouflage = tankTags.includes("eventCamouflage_user");
|
||||||
@@ -938,7 +968,7 @@ export async function definitions() {
|
|||||||
Object.entries(tankDefinition.root.crew).forEach(([crewKey, value]) => {
|
Object.entries(tankDefinition.root.crew).forEach(([crewKey, value]) => {
|
||||||
let entry: Crew;
|
let entry: Crew;
|
||||||
const index = crew.findIndex(
|
const index = crew.findIndex(
|
||||||
({ type }) => blitzkitCrewTypeToBlitz[type] === crewKey
|
({ type }) => blitzkitCrewTypeToBlitz[type] === crewKey,
|
||||||
);
|
);
|
||||||
if (index === -1) {
|
if (index === -1) {
|
||||||
if (crewKey === "#text") return;
|
if (crewKey === "#text") return;
|
||||||
@@ -988,10 +1018,23 @@ export async function definitions() {
|
|||||||
})
|
})
|
||||||
.map(([, camo]) => camo.id);
|
.map(([, camo]) => camo.id);
|
||||||
|
|
||||||
|
let equalizerEntry = equalizerDefinitions.find(
|
||||||
|
(line) => line[0] === `${nation}:${tankKey}`,
|
||||||
|
);
|
||||||
|
|
||||||
|
let equalizer: Equalizer | undefined;
|
||||||
|
|
||||||
|
if (equalizerEntry) {
|
||||||
|
const [health, penetration, module_health, damage, armor] =
|
||||||
|
equalizerEntry?.slice(1).map(Number);
|
||||||
|
equalizer = { health, penetration, module_health, damage, armor };
|
||||||
|
}
|
||||||
|
|
||||||
tankDefinitions.tanks[tankId] = {
|
tankDefinitions.tanks[tankId] = {
|
||||||
ancestors: [],
|
ancestors: [],
|
||||||
successors: [],
|
successors: [],
|
||||||
id: tankId,
|
id: tankId,
|
||||||
|
dev_name: tankKey,
|
||||||
roles: {},
|
roles: {},
|
||||||
camouflages: camouflages,
|
camouflages: camouflages,
|
||||||
fixed_camouflage: fixedCamouflage,
|
fixed_camouflage: fixedCamouflage,
|
||||||
@@ -1011,10 +1054,10 @@ export async function definitions() {
|
|||||||
slug,
|
slug,
|
||||||
nation,
|
nation,
|
||||||
type: tankTags.includes("collectible")
|
type: tankTags.includes("collectible")
|
||||||
? TankType.COLLECTOR
|
? TankType.TANK_TYPE_COLLECTOR
|
||||||
: (typeof tank.price === "number" ? false : "gold" in tank.price)
|
: (typeof tank.price === "number" ? false : "gold" in tank.price)
|
||||||
? TankType.PREMIUM
|
? TankType.TANK_TYPE_PREMIUM
|
||||||
: TankType.RESEARCHABLE,
|
: TankType.TANK_TYPE_RESEARCHABLE,
|
||||||
tier: tank.level,
|
tier: tank.level,
|
||||||
class: blitzTankClassToBlitzkit[tankTags[0] as BlitzTankClass],
|
class: blitzTankClassToBlitzkit[tankTags[0] as BlitzTankClass],
|
||||||
testing: tankTags.includes("testTank"),
|
testing: tankTags.includes("testTank"),
|
||||||
@@ -1022,21 +1065,22 @@ export async function definitions() {
|
|||||||
price: tankPrice,
|
price: tankPrice,
|
||||||
camouflage_still: tankDefinition.root.invisibility.still,
|
camouflage_still: tankDefinition.root.invisibility.still,
|
||||||
camouflage_moving: tankDefinition.root.invisibility.moving,
|
camouflage_moving: tankDefinition.root.invisibility.moving,
|
||||||
camouflage_onFire: tankDefinition.root.invisibility.firePenalty,
|
camouflage_on_fire: tankDefinition.root.invisibility.firePenalty,
|
||||||
turrets: [],
|
turrets: [],
|
||||||
engines: [],
|
engines: [],
|
||||||
tracks: [],
|
tracks: [],
|
||||||
|
equalizer,
|
||||||
};
|
};
|
||||||
|
|
||||||
if (tank.combatRole) {
|
if (tank.combatRole) {
|
||||||
Object.entries(tank.combatRole).forEach(([gameMode, role]) => {
|
Object.entries(tank.combatRole).forEach(([gameMode, role]) => {
|
||||||
const id = Object.entries(gameModeNativeNames).find(
|
const id = Object.entries(gameModeNativeNames).find(
|
||||||
([key]) => key.toLowerCase() === gameMode.toLowerCase()
|
([key]) => key.toLowerCase() === gameMode.toLowerCase(),
|
||||||
)?.[1];
|
)?.[1];
|
||||||
|
|
||||||
if (id === undefined) {
|
if (id === undefined) {
|
||||||
throw new Error(
|
throw new Error(
|
||||||
`Unknown game mode in tank ${tankKey}: ${gameMode}`
|
`Unknown game mode in tank ${tankKey}: ${gameMode}`,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1118,7 +1162,7 @@ export async function definitions() {
|
|||||||
(turretKey, turretIndex) => {
|
(turretKey, turretIndex) => {
|
||||||
const turret = tankDefinition.root.turrets0[turretKey];
|
const turret = tankDefinition.root.turrets0[turretKey];
|
||||||
const turretModel = Number(
|
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 turretId = toUniqueId(nation, turretList.root.ids[turretKey]);
|
||||||
const turretYaw = (
|
const turretYaw = (
|
||||||
@@ -1150,13 +1194,7 @@ export async function definitions() {
|
|||||||
const armorId = parseInt(armorIdString);
|
const armorId = parseInt(armorIdString);
|
||||||
const armorRaw = turret.armor[name];
|
const armorRaw = turret.armor[name];
|
||||||
|
|
||||||
if (typeof armorRaw === "number") {
|
assignArmor(armorRaw, armorId, turretArmor);
|
||||||
turretArmor.thickness[armorId] = armorRaw;
|
|
||||||
} else {
|
|
||||||
if (!turretArmor.spaced) turretArmor.spaced = [];
|
|
||||||
turretArmor.thickness[armorId] = armorRaw["#text"];
|
|
||||||
turretArmor.spaced.push(armorId);
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
|
|
||||||
turret.userString;
|
turret.userString;
|
||||||
@@ -1186,12 +1224,12 @@ export async function definitions() {
|
|||||||
min: vector3TupleToBlitzkit(
|
min: vector3TupleToBlitzkit(
|
||||||
tankParameters.collision[
|
tankParameters.collision[
|
||||||
parsePath(turret.hitTester.collisionModel).name.toLowerCase()
|
parsePath(turret.hitTester.collisionModel).name.toLowerCase()
|
||||||
].bbox.min
|
].bbox.min,
|
||||||
),
|
),
|
||||||
max: vector3TupleToBlitzkit(
|
max: vector3TupleToBlitzkit(
|
||||||
tankParameters.collision[
|
tankParameters.collision[
|
||||||
parsePath(turret.hitTester.collisionModel).name.toLowerCase()
|
parsePath(turret.hitTester.collisionModel).name.toLowerCase()
|
||||||
].bbox.max
|
].bbox.max,
|
||||||
),
|
),
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
@@ -1209,7 +1247,7 @@ export async function definitions() {
|
|||||||
.split(" ")
|
.split(" ")
|
||||||
.map(Number) as [number, number];
|
.map(Number) as [number, number];
|
||||||
const gunModel = Number(
|
const gunModel = Number(
|
||||||
parsePath(gun.models.undamaged).name.split("_")[1]
|
parsePath(gun.models.undamaged).name.split("_")[1],
|
||||||
);
|
);
|
||||||
const gunName = getString(gunListEntry.userString);
|
const gunName = getString(gunListEntry.userString);
|
||||||
const gunType =
|
const gunType =
|
||||||
@@ -1287,13 +1325,8 @@ export async function definitions() {
|
|||||||
}
|
}
|
||||||
const armorId = parseInt(armorIdString);
|
const armorId = parseInt(armorIdString);
|
||||||
const armorRaw = gun.armor[name];
|
const armorRaw = gun.armor[name];
|
||||||
if (typeof armorRaw === "number") {
|
|
||||||
gunArmor.thickness[armorId] = armorRaw;
|
assignArmor(armorRaw, armorId, gunArmor);
|
||||||
} else {
|
|
||||||
if (!gunArmor.spaced) gunArmor.spaced = [];
|
|
||||||
gunArmor.thickness[armorId] = armorRaw["#text"];
|
|
||||||
gunArmor.spaced.push(armorId);
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
|
|
||||||
tankDefinitions.tanks[tankId].turrets[turretIndex].guns.push({
|
tankDefinitions.tanks[tankId].turrets[turretIndex].guns.push({
|
||||||
@@ -1332,24 +1365,24 @@ export async function definitions() {
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
: gunType === "autoReloader"
|
: gunType === "autoReloader"
|
||||||
? {
|
? {
|
||||||
$case: "auto_reloader",
|
$case: "auto_reloader",
|
||||||
value: {
|
value: {
|
||||||
intra_clip: 60 / gun.clip!.rate,
|
intra_clip: 60 / gun.clip!.rate,
|
||||||
shell_count: gunClipCount,
|
shell_count: gunClipCount,
|
||||||
shell_reloads: gun
|
shell_reloads: gun
|
||||||
.pumpGunReloadTimes!.split(" ")
|
.pumpGunReloadTimes!.split(" ")
|
||||||
.map(Number),
|
.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);
|
} satisfies GunDefinition);
|
||||||
|
|
||||||
modelDefinitions.models[tankId].turrets[turretId].guns[gunId] = {
|
modelDefinitions.models[tankId].turrets[turretId].guns[gunId] = {
|
||||||
@@ -1360,8 +1393,8 @@ export async function definitions() {
|
|||||||
gun.armor.gun === undefined
|
gun.armor.gun === undefined
|
||||||
? 0
|
? 0
|
||||||
: typeof gun.armor.gun === "number"
|
: typeof gun.armor.gun === "number"
|
||||||
? gun.armor.gun
|
? gun.armor.gun
|
||||||
: gun.armor.gun["#text"],
|
: gun.armor.gun["#text"],
|
||||||
pitch: {
|
pitch: {
|
||||||
min: gunPitch[0],
|
min: gunPitch[0],
|
||||||
max: gunPitch[1],
|
max: gunPitch[1],
|
||||||
@@ -1408,7 +1441,7 @@ export async function definitions() {
|
|||||||
type: blitzShellKindToBlitzkit[shell.kind],
|
type: blitzShellKindToBlitzkit[shell.kind],
|
||||||
explosion_radius:
|
explosion_radius:
|
||||||
shell.kind === "HIGH_EXPLOSIVE"
|
shell.kind === "HIGH_EXPLOSIVE"
|
||||||
? shell.explosionRadius ?? 0
|
? (shell.explosionRadius ?? 0)
|
||||||
: undefined,
|
: undefined,
|
||||||
icon: shell.icon,
|
icon: shell.icon,
|
||||||
penetration: {
|
penetration: {
|
||||||
@@ -1419,7 +1452,7 @@ export async function definitions() {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
totalUnlocks.forEach((unlocks) => {
|
totalUnlocks.forEach((unlocks) => {
|
||||||
@@ -1447,7 +1480,7 @@ export async function definitions() {
|
|||||||
case "gun": {
|
case "gun": {
|
||||||
gunXps.set(
|
gunXps.set(
|
||||||
toUniqueId(nation, gunList.root.ids[vehicle["#text"]]),
|
toUniqueId(nation, gunList.root.ids[vehicle["#text"]]),
|
||||||
parseResearchCost(vehicle.cost)
|
parseResearchCost(vehicle.cost),
|
||||||
);
|
);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -1455,7 +1488,7 @@ export async function definitions() {
|
|||||||
case "turret": {
|
case "turret": {
|
||||||
turretXps.set(
|
turretXps.set(
|
||||||
toUniqueId(nation, turretList.root.ids[vehicle["#text"]]),
|
toUniqueId(nation, turretList.root.ids[vehicle["#text"]]),
|
||||||
parseResearchCost(vehicle.cost)
|
parseResearchCost(vehicle.cost),
|
||||||
);
|
);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -1463,7 +1496,7 @@ export async function definitions() {
|
|||||||
case "engine": {
|
case "engine": {
|
||||||
engineXps.set(
|
engineXps.set(
|
||||||
toUniqueId(nation, enginesList.root.ids[vehicle["#text"]]),
|
toUniqueId(nation, enginesList.root.ids[vehicle["#text"]]),
|
||||||
parseResearchCost(vehicle.cost)
|
parseResearchCost(vehicle.cost),
|
||||||
);
|
);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -1471,7 +1504,7 @@ export async function definitions() {
|
|||||||
case "chassis": {
|
case "chassis": {
|
||||||
trackXps.set(
|
trackXps.set(
|
||||||
toUniqueId(nation, chassisList.root.ids[vehicle["#text"]]),
|
toUniqueId(nation, chassisList.root.ids[vehicle["#text"]]),
|
||||||
parseResearchCost(vehicle.cost)
|
parseResearchCost(vehicle.cost),
|
||||||
);
|
);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -1518,7 +1551,7 @@ export async function definitions() {
|
|||||||
name: getString(optionalDeviceEntry.userString),
|
name: getString(optionalDeviceEntry.userString),
|
||||||
description: getString(optionalDeviceEntry.description),
|
description: getString(optionalDeviceEntry.description),
|
||||||
};
|
};
|
||||||
}
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
Object.entries(optionalDeviceSlots.root.presets).forEach(
|
Object.entries(optionalDeviceSlots.root.presets).forEach(
|
||||||
@@ -1537,7 +1570,7 @@ export async function definitions() {
|
|||||||
})
|
})
|
||||||
.flat(),
|
.flat(),
|
||||||
};
|
};
|
||||||
}
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
Object.entries(consumables).forEach(([key, consumable]) => {
|
Object.entries(consumables).forEach(([key, consumable]) => {
|
||||||
@@ -1620,7 +1653,7 @@ export async function definitions() {
|
|||||||
(item) =>
|
(item) =>
|
||||||
blitzTankFilterDefinitionCategoryToBlitzkit[
|
blitzTankFilterDefinitionCategoryToBlitzkit[
|
||||||
item as BlitzTankFilterDefinitionCategory
|
item as BlitzTankFilterDefinitionCategory
|
||||||
]
|
],
|
||||||
),
|
),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@@ -1718,7 +1751,7 @@ export async function definitions() {
|
|||||||
(item) =>
|
(item) =>
|
||||||
blitzTankFilterDefinitionCategoryToBlitzkit[
|
blitzTankFilterDefinitionCategoryToBlitzkit[
|
||||||
item as BlitzTankFilterDefinitionCategory
|
item as BlitzTankFilterDefinitionCategory
|
||||||
]
|
],
|
||||||
),
|
),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@@ -1749,11 +1782,11 @@ export async function definitions() {
|
|||||||
value.default_abilities.forEach((ability) => {
|
value.default_abilities.forEach((ability) => {
|
||||||
if (ability in consumableNativeNames) {
|
if (ability in consumableNativeNames) {
|
||||||
gameDefinitions.roles[value.id].consumables.push(
|
gameDefinitions.roles[value.id].consumables.push(
|
||||||
consumableNativeNames[ability]
|
consumableNativeNames[ability],
|
||||||
);
|
);
|
||||||
} else if (ability in provisionNativeNames) {
|
} else if (ability in provisionNativeNames) {
|
||||||
gameDefinitions.roles[value.id].provisions.push(
|
gameDefinitions.roles[value.id].provisions.push(
|
||||||
provisionNativeNames[ability]
|
provisionNativeNames[ability],
|
||||||
);
|
);
|
||||||
} else throw new Error(`Unknown ability ${ability}`);
|
} else throw new Error(`Unknown ability ${ability}`);
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -17,15 +17,15 @@ export async function equipmentIcons() {
|
|||||||
|
|
||||||
using uploader = new AssetUploader("equipment icons");
|
using uploader = new AssetUploader("equipment icons");
|
||||||
const optionalDevices = await vfs.xml<{ root: OptionalDevices }>(
|
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 mappings = await vfs.yaml<Mappings>(
|
const mappings = await vfs.yaml<Mappings>(
|
||||||
`Data/UI/Screens3/Lobby/Inventory/OptionalDevices/OptionalDevicesItemImage.style.yaml`
|
`Data/UI/Screens3/Lobby/Inventory/OptionalDevices/OptionalDevicesItemImage.style.yaml`,
|
||||||
);
|
);
|
||||||
const image = sharp(
|
const image = sharp(
|
||||||
await vfs.file(
|
await vfs.file(
|
||||||
`Data/Gfx/UI/InventoryIcons/Big/OptionalDevices/texture0.packed.webp`
|
`Data/Gfx/UI/InventoryIcons/Big/OptionalDevices/texture0.packed.webp`,
|
||||||
)
|
),
|
||||||
);
|
);
|
||||||
|
|
||||||
for (const optionalDeviceKey in optionalDevices.root) {
|
for (const optionalDeviceKey in optionalDevices.root) {
|
||||||
@@ -35,8 +35,8 @@ export async function equipmentIcons() {
|
|||||||
|
|
||||||
const mapping = mappings.StyleSheets.find((mapping) =>
|
const mapping = mappings.StyleSheets.find((mapping) =>
|
||||||
mapping.selectors.includes(
|
mapping.selectors.includes(
|
||||||
`.optional_device_item.${optionalDevice.icon} #Img`
|
`.optional_device_item.${optionalDevice.icon} #Img`,
|
||||||
)
|
),
|
||||||
);
|
);
|
||||||
|
|
||||||
if (!mapping) {
|
if (!mapping) {
|
||||||
@@ -49,9 +49,7 @@ export async function equipmentIcons() {
|
|||||||
|
|
||||||
if (configPath.startsWith("Gfx/Lobby")) {
|
if (configPath.startsWith("Gfx/Lobby")) {
|
||||||
const configPathWebp = configPath.replace(".txt", "");
|
const configPathWebp = configPath.replace(".txt", "");
|
||||||
const image = sharp(
|
const image = sharp(await vfs.file(`Data/${configPathWebp}.packed.webp`));
|
||||||
await vfs.file(`Data/${configPathWebp}.packed.webp`)
|
|
||||||
);
|
|
||||||
const content = await image.trim().toBuffer();
|
const content = await image.trim().toBuffer();
|
||||||
|
|
||||||
await uploader.add({
|
await uploader.add({
|
||||||
|
|||||||
@@ -6,20 +6,32 @@ export async function flags() {
|
|||||||
console.log("Building flags...");
|
console.log("Building flags...");
|
||||||
|
|
||||||
using uploader = new AssetUploader("flags");
|
using uploader = new AssetUploader("flags");
|
||||||
const circleFiles = vfs.dir(`Data/Gfx/Lobby/flags`).filter(
|
const circleFiles = await vfs
|
||||||
(flag) =>
|
.dir(`Data/Gfx/Lobby/flags`)
|
||||||
flag.startsWith("flag_profile-stat_") &&
|
.then((files) =>
|
||||||
!flag.endsWith("@2x.packed.webp")
|
files.filter(
|
||||||
|
(flag) =>
|
||||||
|
flag.startsWith("flag_profile-stat_") &&
|
||||||
|
!flag.endsWith("@2x.packed.webp"),
|
||||||
|
),
|
||||||
);
|
);
|
||||||
const scratchedFiles = vfs.dir(`Data/Gfx/Lobby/flags`).filter(
|
const scratchedFiles = await vfs
|
||||||
|
.dir(`Data/Gfx/Lobby/flags`)
|
||||||
|
.then((files) =>
|
||||||
|
files.filter(
|
||||||
(flag) =>
|
(flag) =>
|
||||||
flag.startsWith("flag_tutor-tank_") &&
|
flag.startsWith("flag_tutor-tank_") &&
|
||||||
!flag.endsWith("@2x.packed.webp")
|
!flag.endsWith("@2x.packed.webp"),
|
||||||
)
|
),
|
||||||
const fadedFiles = vfs.dir(`Data/Gfx/Lobby/flags`).filter(
|
);
|
||||||
(flag) =>
|
const fadedFiles = await vfs
|
||||||
flag.startsWith("flag_filter_") && flag.endsWith("@2x.packed.webp")
|
.dir(`Data/Gfx/Lobby/flags`)
|
||||||
)
|
.then((files) =>
|
||||||
|
files.filter(
|
||||||
|
(flag) =>
|
||||||
|
flag.startsWith("flag_filter_") && flag.endsWith("@2x.packed.webp"),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
|
||||||
for (const flag of circleFiles) {
|
for (const flag of circleFiles) {
|
||||||
const image = sharp(await vfs.file(`Data/Gfx/Lobby/flags/${flag}`));
|
const image = sharp(await vfs.file(`Data/Gfx/Lobby/flags/${flag}`));
|
||||||
@@ -43,9 +55,7 @@ export async function flags() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
for (const flag of fadedFiles) {
|
for (const flag of fadedFiles) {
|
||||||
const content = await sharp(
|
const content = await sharp(await vfs.file(`Data/Gfx/Lobby/flags/${flag}`))
|
||||||
await vfs.file(`Data/Gfx/Lobby/flags/${flag}`)
|
|
||||||
)
|
|
||||||
.trim({
|
.trim({
|
||||||
threshold: 100,
|
threshold: 100,
|
||||||
background: { r: 0, g: 0, b: 0, alpha: 0 },
|
background: { r: 0, g: 0, b: 0, alpha: 0 },
|
||||||
|
|||||||
@@ -8,35 +8,33 @@ export async function gameModeBanners() {
|
|||||||
|
|
||||||
using uploader = new AssetUploader("game mode banners");
|
using uploader = new AssetUploader("game mode banners");
|
||||||
const gameTypeSelectorStyles = await vfs.yaml<SquadBattleTypeStyles>(
|
const gameTypeSelectorStyles = await vfs.yaml<SquadBattleTypeStyles>(
|
||||||
`Data/UI/Screens/Lobby/Hangar/GameTypeSelector.yaml`
|
`Data/UI/Screens/Lobby/Hangar/GameTypeSelector.yaml`,
|
||||||
);
|
);
|
||||||
const squadBattleTypeStyles = await vfs.yaml<SquadBattleTypeStyles>(
|
const squadBattleTypeStyles = await vfs.yaml<SquadBattleTypeStyles>(
|
||||||
`Data/UI/Screens3/Lobby/Hangar/Squad/SquadBattleType.yaml`
|
`Data/UI/Screens3/Lobby/Hangar/Squad/SquadBattleType.yaml`,
|
||||||
);
|
);
|
||||||
const bannerMatches: { name: string; path: string }[] = [];
|
const bannerMatches: { name: string; path: string }[] = [];
|
||||||
|
|
||||||
for (const match of gameTypeSelectorStyles.Prototypes[0].components.UIDataLocalBindingsComponent.data[1][2].matchAll(
|
for (const match of gameTypeSelectorStyles.Prototypes[0].components.UIDataLocalBindingsComponent.data[1][2].matchAll(
|
||||||
/eGameMode\.([a-zA-Z]+) -> "~res:([^"]+)"/g
|
/eGameMode\.([a-zA-Z]+) -> "~res:([^"]+)"/g,
|
||||||
)) {
|
)) {
|
||||||
bannerMatches.push({ name: match[1], path: match[2] });
|
bannerMatches.push({ name: match[1], path: match[2] });
|
||||||
}
|
}
|
||||||
|
|
||||||
for (const match of squadBattleTypeStyles.Prototypes[0].components.UIDataLocalBindingsComponent.data[1][2].matchAll(
|
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 id = Number(match[1]);
|
||||||
const name = match[2];
|
const name = match[2];
|
||||||
let path = bannerMatches.find(
|
let path = bannerMatches.find(
|
||||||
(bannerMatch) => bannerMatch.name.toLowerCase() === name.toLowerCase()
|
(bannerMatch) => bannerMatch.name.toLowerCase() === name.toLowerCase(),
|
||||||
)?.path;
|
)?.path;
|
||||||
|
|
||||||
if (path === undefined) {
|
if (path === undefined) {
|
||||||
path = `/Gfx/UI/Hangar/GameTypes/battle-type_${name.toLowerCase()}`;
|
path = `/Gfx/UI/Hangar/GameTypes/battle-type_${name.toLowerCase()}`;
|
||||||
}
|
}
|
||||||
|
|
||||||
const content = await sharp(
|
const content = await sharp(await vfs.file(`Data${path}.packed.webp`))
|
||||||
await vfs.file(`Data${path}.packed.webp`)
|
|
||||||
)
|
|
||||||
.trim({ background: { r: 0, g: 0, b: 0, alpha: 0 } })
|
.trim({ background: { r: 0, g: 0, b: 0, alpha: 0 } })
|
||||||
.toBuffer();
|
.toBuffer();
|
||||||
|
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ export async function glossary() {
|
|||||||
const glossary = await fetchGlossary(supported.blitz ?? supported.locale);
|
const glossary = await fetchGlossary(supported.blitz ?? supported.locale);
|
||||||
|
|
||||||
console.log(
|
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) {
|
for (const key in glossary) {
|
||||||
@@ -30,7 +30,7 @@ export async function glossary() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (key in avatars) {
|
if (key in avatars) {
|
||||||
avatars[key].avatar.name.locales[supported.locale] =
|
avatars[key].avatar.name!.locales[supported.locale] =
|
||||||
glossaryEntry.title;
|
glossaryEntry.title;
|
||||||
} else {
|
} else {
|
||||||
const extension = extname(glossaryEntry.image_url);
|
const extension = extname(glossaryEntry.image_url);
|
||||||
@@ -45,7 +45,7 @@ export async function glossary() {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
}),
|
||||||
);
|
);
|
||||||
|
|
||||||
const gallery: Gallery = { avatars: [] };
|
const gallery: Gallery = { avatars: [] };
|
||||||
@@ -53,12 +53,12 @@ export async function glossary() {
|
|||||||
|
|
||||||
const bar = new ProgressBar(
|
const bar = new ProgressBar(
|
||||||
`Fetching avatars of ${totalCount} things :bar`,
|
`Fetching avatars of ${totalCount} things :bar`,
|
||||||
totalCount
|
totalCount,
|
||||||
);
|
);
|
||||||
|
|
||||||
await Promise.all(
|
await Promise.all(
|
||||||
Object.entries(avatars).map(async ([key, { url, avatar }]) => {
|
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`);
|
console.warn(`Avatar ${key} has no ${locales.default} name`);
|
||||||
bar.tick();
|
bar.tick();
|
||||||
|
|
||||||
@@ -77,7 +77,7 @@ export async function glossary() {
|
|||||||
});
|
});
|
||||||
|
|
||||||
bar.tick();
|
bar.tick();
|
||||||
})
|
}),
|
||||||
);
|
);
|
||||||
|
|
||||||
await uploader.add({
|
await uploader.add({
|
||||||
|
|||||||
@@ -8,11 +8,13 @@ export async function migration() {
|
|||||||
|
|
||||||
using uploader = new AssetUploader("migration map");
|
using uploader = new AssetUploader("migration map");
|
||||||
const map: Record<string, number> = {};
|
const map: Record<string, number> = {};
|
||||||
const nations = vfs.dir(`Data/XML/item_defs/vehicles`).filter((nation) => nation !== "common");
|
const nations = await vfs
|
||||||
|
.dir(`Data/XML/item_defs/vehicles`)
|
||||||
|
.then((files) => files.filter((nation) => nation !== "common"));
|
||||||
|
|
||||||
for (const nation of nations) {
|
for (const nation of nations) {
|
||||||
const tankList = await vfs.xml<{ root: VehicleDefinitionList }>(
|
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) {
|
for (const tankKey in tankList.root) {
|
||||||
|
|||||||
@@ -6,15 +6,20 @@ export async function moduleIcons() {
|
|||||||
console.log("Building module icons...");
|
console.log("Building module icons...");
|
||||||
|
|
||||||
using uploader = new AssetUploader("module icons");
|
using uploader = new AssetUploader("module icons");
|
||||||
const files = vfs.dir(`Data/Gfx/UI/ModulesTechTree`).filter(
|
const files = await vfs
|
||||||
(file) => !file.endsWith("@2x.packed.webp") && file.startsWith("vehicle")
|
.dir(`Data/Gfx/UI/ModulesTechTree`)
|
||||||
)
|
.then((files) =>
|
||||||
|
files.filter(
|
||||||
|
(file) =>
|
||||||
|
!file.endsWith("@2x.packed.webp") && file.startsWith("vehicle"),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
|
||||||
for (const file of files) {
|
for (const file of files) {
|
||||||
const nameRaw = file.match(/vehicle(.+)\.packed\.webp/)![1];
|
const nameRaw = file.match(/vehicle(.+)\.packed\.webp/)![1];
|
||||||
const name = nameRaw[0].toLowerCase() + nameRaw.slice(1);
|
const name = nameRaw[0].toLowerCase() + nameRaw.slice(1);
|
||||||
const content = await sharp(
|
const content = await sharp(
|
||||||
await vfs.file(`Data/Gfx/UI/ModulesTechTree/${file}`)
|
await vfs.file(`Data/Gfx/UI/ModulesTechTree/${file}`),
|
||||||
)
|
)
|
||||||
.trim()
|
.trim()
|
||||||
.toBuffer();
|
.toBuffer();
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ export async function popularTanks() {
|
|||||||
const analytics = google.analyticsdata({ version: "v1beta", auth });
|
const analytics = google.analyticsdata({ version: "v1beta", auth });
|
||||||
const report = await analytics.properties.runReport({
|
const report = await analytics.properties.runReport({
|
||||||
property: `properties/${assertSecret(
|
property: `properties/${assertSecret(
|
||||||
import.meta.env.PUBLIC_GOOGLE_ANALYTICS_PROPERTY_ID
|
import.meta.env.PUBLIC_GOOGLE_ANALYTICS_PROPERTY_ID,
|
||||||
)}`,
|
)}`,
|
||||||
requestBody: {
|
requestBody: {
|
||||||
dateRanges: [{ startDate: "7daysAgo", endDate: "today" }],
|
dateRanges: [{ startDate: "7daysAgo", endDate: "today" }],
|
||||||
@@ -47,13 +47,13 @@ export async function popularTanks() {
|
|||||||
row.dimensionValues[0].value &&
|
row.dimensionValues[0].value &&
|
||||||
row.dimensionValues[0].value !== "/tanks/" &&
|
row.dimensionValues[0].value !== "/tanks/" &&
|
||||||
row.metricValues &&
|
row.metricValues &&
|
||||||
row.metricValues[0].value
|
row.metricValues[0].value,
|
||||||
)
|
)
|
||||||
.map((row) => ({
|
.map((row) => ({
|
||||||
id: Number(
|
id: Number(
|
||||||
row.dimensionValues![0].value!.match(
|
row.dimensionValues![0].value!.match(
|
||||||
/\/tools\/tankopedia\/(\d+)\/?/
|
/\/tools\/tankopedia\/(\d+)\/?/,
|
||||||
)?.[1]
|
)?.[1],
|
||||||
),
|
),
|
||||||
views: Number(row.metricValues![0].value!),
|
views: Number(row.metricValues![0].value!),
|
||||||
}))
|
}))
|
||||||
|
|||||||
@@ -8,19 +8,17 @@ export async function shellIcons() {
|
|||||||
using uploader = new AssetUploader("shell icons");
|
using uploader = new AssetUploader("shell icons");
|
||||||
const image = sharp(
|
const image = sharp(
|
||||||
await vfs.file(
|
await vfs.file(
|
||||||
`Data/Gfx/Shared/tank-supply/ammunition/big/texture0.packed.webp`
|
`Data/Gfx/Shared/tank-supply/ammunition/big/texture0.packed.webp`,
|
||||||
)
|
),
|
||||||
);
|
);
|
||||||
const files = vfs.dir(
|
const files = await vfs
|
||||||
`Data/Gfx/Shared/tank-supply/ammunition/big`
|
.dir(`Data/Gfx/Shared/tank-supply/ammunition/big`)
|
||||||
).filter((file) => file.endsWith("_l.txt"))
|
.then((files) => files.filter((file) => file.endsWith("_l.txt")));
|
||||||
|
|
||||||
for (const file of files) {
|
for (const file of files) {
|
||||||
const name = file.match(/(.+)_l\.txt/)![1];
|
const name = file.match(/(.+)_l\.txt/)![1];
|
||||||
const sizes = (
|
const sizes = (
|
||||||
await vfs.text(
|
await vfs.text(`Data/Gfx/Shared/tank-supply/ammunition/big/${file}`)
|
||||||
`Data/Gfx/Shared/tank-supply/ammunition/big/${file}`
|
|
||||||
)
|
|
||||||
)
|
)
|
||||||
.split("\n")[4]
|
.split("\n")[4]
|
||||||
.split(" ")
|
.split(" ")
|
||||||
|
|||||||
@@ -26,7 +26,7 @@ export async function skillIcons() {
|
|||||||
console.log("Building skill icons...");
|
console.log("Building skill icons...");
|
||||||
|
|
||||||
const avatar = await vfs.xml<{ root: Avatar }>(
|
const avatar = await vfs.xml<{ root: Avatar }>(
|
||||||
`Data/XML/item_defs/tankmen/avatar.xml`
|
`Data/XML/item_defs/tankmen/avatar.xml`,
|
||||||
);
|
);
|
||||||
const uploader = new AssetUploader("skill icons");
|
const uploader = new AssetUploader("skill icons");
|
||||||
|
|
||||||
|
|||||||
@@ -10,11 +10,13 @@ export async function tankArmors() {
|
|||||||
|
|
||||||
using uploader = new AssetUploader("tank armors");
|
using uploader = new AssetUploader("tank armors");
|
||||||
const nodeIO = new NodeIO();
|
const nodeIO = new NodeIO();
|
||||||
const nations = vfs.dir(`Data/XML/item_defs/vehicles`).filter((nation) => nation !== "common");
|
const nations = await vfs
|
||||||
|
.dir(`Data/XML/item_defs/vehicles`)
|
||||||
|
.then((files) => files.filter((nation) => nation !== "common"));
|
||||||
|
|
||||||
for (const nation of nations) {
|
for (const nation of nations) {
|
||||||
const tanks = await vfs.xml<{ root: VehicleDefinitionList }>(
|
const tanks = 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 tanks.root) {
|
for (const tankKey in tanks.root) {
|
||||||
|
|||||||
@@ -41,11 +41,13 @@ export async function tankIcons() {
|
|||||||
console.log("Building tank icons...");
|
console.log("Building tank icons...");
|
||||||
|
|
||||||
using uploader = new AssetUploader("tank icons");
|
using uploader = new AssetUploader("tank icons");
|
||||||
const nations = vfs.dir(`Data/XML/item_defs/vehicles`).filter((nation) => nation !== "common")
|
const nations = await vfs
|
||||||
|
.dir(`Data/XML/item_defs/vehicles`)
|
||||||
|
.then((files) => files.filter((nation) => nation !== "common"));
|
||||||
|
|
||||||
for (const nation of nations) {
|
for (const nation of nations) {
|
||||||
const tanks = await vfs.xml<{ root: VehicleDefinitionList }>(
|
const tanks = 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 tanks.root) {
|
for (const tankKey in tanks.root) {
|
||||||
@@ -57,7 +59,7 @@ export async function tankIcons() {
|
|||||||
const id = (nationVehicleId << 8) + (NATION_IDS[nation] << 4) + 1;
|
const id = (nationVehicleId << 8) + (NATION_IDS[nation] << 4) + 1;
|
||||||
|
|
||||||
const parameters = await vfs.yaml<TankParameters>(
|
const parameters = await vfs.yaml<TankParameters>(
|
||||||
`Data/3d/Tanks/Parameters/${nation}/${tankKey}.yaml`
|
`Data/3d/Tanks/Parameters/${nation}/${tankKey}.yaml`,
|
||||||
);
|
);
|
||||||
const smallPath = `Data/${parameters.resourcesPath.smallIconPath
|
const smallPath = `Data/${parameters.resourcesPath.smallIconPath
|
||||||
.replace(/~res:\//, "")
|
.replace(/~res:\//, "")
|
||||||
|
|||||||
@@ -12,9 +12,9 @@ export async function tankModels() {
|
|||||||
|
|
||||||
using uploader = new AssetUploader("tank models");
|
using uploader = new AssetUploader("tank models");
|
||||||
const nodeIO = new NodeIO().registerExtensions(ALL_EXTENSIONS);
|
const nodeIO = new NodeIO().registerExtensions(ALL_EXTENSIONS);
|
||||||
const nations = vfs
|
const nations = await vfs
|
||||||
.dir(`Data/XML/item_defs/vehicles`)
|
.dir(`Data/XML/item_defs/vehicles`)
|
||||||
.filter((nation) => nation !== "common");
|
.then((files) => files.filter((nation) => nation !== "common"));
|
||||||
|
|
||||||
for (const nationIndex in nations) {
|
for (const nationIndex in nations) {
|
||||||
const nation = nations[nationIndex];
|
const nation = nations[nationIndex];
|
||||||
@@ -41,4 +41,4 @@ export async function tankModels() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
await uploader.flush();
|
await uploader.flush();
|
||||||
}
|
}
|
||||||
@@ -170,6 +170,7 @@ export async function extractModel(vfs: AbstractVFS, path: string) {
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case "TransformComponent": {
|
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.setTranslation(component["tc.localTranslation"]);
|
||||||
node.setRotation(component["tc.localRotation"]);
|
node.setRotation(component["tc.localRotation"]);
|
||||||
node.setScale(component["tc.localScale"]);
|
node.setScale(component["tc.localScale"]);
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ import { vfs } from "../../../buildAssets/constants";
|
|||||||
|
|
||||||
export async function readTexture(path: string) {
|
export async function readTexture(path: string) {
|
||||||
const ddsTexturePath = path.replace(".tex", ".dx11.dds");
|
const ddsTexturePath = path.replace(".tex", ".dx11.dds");
|
||||||
const isDds = vfs.resolve(ddsTexturePath);
|
const isDds = await vfs.resolve(ddsTexturePath);
|
||||||
const resolvedTexturePath = isDds
|
const resolvedTexturePath = isDds
|
||||||
? ddsTexturePath
|
? ddsTexturePath
|
||||||
: ddsTexturePath.replace(".dds", ".pvr");
|
: ddsTexturePath.replace(".dds", ".pvr");
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import { crc32 } from 'crc';
|
import { crc32 } from "crc";
|
||||||
import { compressBlock } from 'lz4js';
|
import { compressBlock } from "lz4js";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Thanks Maddoxkkm! Modernized heavily.
|
* Thanks Maddoxkkm! Modernized heavily.
|
||||||
@@ -14,7 +14,7 @@ export function writeDVPL(buffer: Buffer) {
|
|||||||
destination,
|
destination,
|
||||||
0,
|
0,
|
||||||
source.length,
|
source.length,
|
||||||
0,
|
[0],
|
||||||
);
|
);
|
||||||
let output = Buffer.from(destination);
|
let output = Buffer.from(destination);
|
||||||
|
|
||||||
@@ -58,7 +58,7 @@ function toDVPLFooter(
|
|||||||
result.writeUInt32LE(compressedSize, 4);
|
result.writeUInt32LE(compressedSize, 4);
|
||||||
result.writeUInt32LE(crc32, 8);
|
result.writeUInt32LE(crc32, 8);
|
||||||
result.writeUInt32LE(type, 12);
|
result.writeUInt32LE(type, 12);
|
||||||
result.write('DVPL', 16, 4, 'utf8');
|
result.write("DVPL", 16, 4, "utf8");
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
@@ -43,7 +43,7 @@ export class AssetUploader {
|
|||||||
|
|
||||||
constructor(public message: string) {
|
constructor(public message: string) {
|
||||||
[this.owner, this.repo] = assertSecret(
|
[this.owner, this.repo] = assertSecret(
|
||||||
import.meta.env.PUBLIC_ASSET_REPO
|
import.meta.env.PUBLIC_ASSET_REPO,
|
||||||
).split("/");
|
).split("/");
|
||||||
this.branch = assertSecret(import.meta.env.PUBLIC_ASSET_BRANCH);
|
this.branch = assertSecret(import.meta.env.PUBLIC_ASSET_BRANCH);
|
||||||
}
|
}
|
||||||
@@ -52,7 +52,7 @@ export class AssetUploader {
|
|||||||
const blobPath = `${this.owner}/${this.repo}/${this.branch}/${change.path}`;
|
const blobPath = `${this.owner}/${this.repo}/${this.branch}/${change.path}`;
|
||||||
const response = await fetch(
|
const response = await fetch(
|
||||||
`https://raw.githubusercontent.com/${blobPath}`,
|
`https://raw.githubusercontent.com/${blobPath}`,
|
||||||
{ headers: { "Accept-Encoding": "identity" } }
|
{ headers: { "Accept-Encoding": "identity" } },
|
||||||
);
|
);
|
||||||
let diff: { change: number; status: DiffStatus };
|
let diff: { change: number; status: DiffStatus };
|
||||||
|
|
||||||
@@ -71,7 +71,7 @@ export class AssetUploader {
|
|||||||
} else if (response.status === 200) {
|
} else if (response.status === 200) {
|
||||||
if (
|
if (
|
||||||
this.heuristicFormats.some((format) =>
|
this.heuristicFormats.some((format) =>
|
||||||
change.path.endsWith(`.${format}`)
|
change.path.endsWith(`.${format}`),
|
||||||
)
|
)
|
||||||
) {
|
) {
|
||||||
/**
|
/**
|
||||||
@@ -94,7 +94,7 @@ export class AssetUploader {
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
throw new Error(
|
throw new Error(
|
||||||
`Unexpected status code ${response.status} for ${change.path}`
|
`Unexpected status code ${response.status} for ${change.path}`,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -104,7 +104,7 @@ export class AssetUploader {
|
|||||||
console.log(
|
console.log(
|
||||||
`${diff.status === DiffStatus.New ? "🟢" : "🟡"} (${
|
`${diff.status === DiffStatus.New ? "🟢" : "🟡"} (${
|
||||||
diff.change > 0 ? "+" : ""
|
diff.change > 0 ? "+" : ""
|
||||||
}${diff.change.toLocaleString()}B) ${change.path}`
|
}${diff.change.toLocaleString()}B) ${change.path}`,
|
||||||
);
|
);
|
||||||
|
|
||||||
// flush BEFORE going over limit
|
// flush BEFORE going over limit
|
||||||
@@ -160,8 +160,8 @@ export class AssetUploader {
|
|||||||
await new Promise((resolve) =>
|
await new Promise((resolve) =>
|
||||||
setTimeout(
|
setTimeout(
|
||||||
resolve,
|
resolve,
|
||||||
Math.max(0, this.time_between_blobs + (start - end))
|
Math.max(0, this.time_between_blobs + (start - end)),
|
||||||
)
|
),
|
||||||
);
|
);
|
||||||
|
|
||||||
blobs.push({ sha, path: change.path, mode: "100644", type: "blob" });
|
blobs.push({ sha, path: change.path, mode: "100644", type: "blob" });
|
||||||
@@ -170,11 +170,11 @@ export class AssetUploader {
|
|||||||
break;
|
break;
|
||||||
} catch {
|
} catch {
|
||||||
console.warn(
|
console.warn(
|
||||||
` failed ${change.path}; retrying in ${this.time_per_blob}ms...`
|
` failed ${change.path}; retrying in ${this.time_per_blob}ms...`,
|
||||||
);
|
);
|
||||||
|
|
||||||
await new Promise((resolve) =>
|
await new Promise((resolve) =>
|
||||||
setTimeout(resolve, this.time_per_blob)
|
setTimeout(resolve, this.time_per_blob),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -209,7 +209,7 @@ export class AssetUploader {
|
|||||||
[Symbol.dispose]() {
|
[Symbol.dispose]() {
|
||||||
if (this.changes.length > 0) {
|
if (this.changes.length > 0) {
|
||||||
throw new Error(
|
throw new Error(
|
||||||
`${this.changes.length} uncommitted changes. Did you forget to flush?`
|
`${this.changes.length} uncommitted changes. Did you forget to flush?`,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,7 +1,8 @@
|
|||||||
import { readDVPL } from "@blitzkit/core";
|
import { readDVPL } from "@blitzkit/core";
|
||||||
|
import { Options, parse as parseCSV } from "csv-parse/sync";
|
||||||
import { XMLParser } from "fast-xml-parser";
|
import { XMLParser } from "fast-xml-parser";
|
||||||
import { normalize } from "path/posix";
|
import { normalize } from "path/posix";
|
||||||
import { parse } from "yaml";
|
import { parse as parseYaml } from "yaml";
|
||||||
|
|
||||||
export abstract class AbstractVFS {
|
export abstract class AbstractVFS {
|
||||||
textDecoder = new TextDecoder();
|
textDecoder = new TextDecoder();
|
||||||
@@ -11,24 +12,22 @@ export abstract class AbstractVFS {
|
|||||||
|
|
||||||
abstract dispose(): void;
|
abstract dispose(): void;
|
||||||
|
|
||||||
abstract has(path: string): boolean;
|
abstract has(path: string): Promise<boolean>;
|
||||||
|
|
||||||
abstract raw(path: string): Promise<Uint8Array>;
|
abstract raw(path: string): Promise<Uint8Array>;
|
||||||
|
|
||||||
abstract paths(): string[];
|
async resolve(path: string) {
|
||||||
|
|
||||||
resolve(path: string) {
|
|
||||||
const normalized = normalize(path);
|
const normalized = normalize(path);
|
||||||
if (this.has(normalized)) return normalized;
|
if (await this.has(normalized)) return normalized;
|
||||||
|
|
||||||
const dvplPath = `${normalized}.dvpl`;
|
const dvplPath = `${normalized}.dvpl`;
|
||||||
if (this.has(dvplPath)) return dvplPath;
|
if (await this.has(dvplPath)) return dvplPath;
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
assert(path: string) {
|
async assert(path: string) {
|
||||||
const resolved = this.resolve(path);
|
const resolved = await this.resolve(path);
|
||||||
|
|
||||||
if (resolved === null) throw new Error(`File not found: ${path}`);
|
if (resolved === null) throw new Error(`File not found: ${path}`);
|
||||||
|
|
||||||
@@ -36,7 +35,7 @@ export abstract class AbstractVFS {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async file(file: string) {
|
async file(file: string) {
|
||||||
const resolved = this.assert(file);
|
const resolved = await this.assert(file);
|
||||||
const raw = await this.raw(resolved);
|
const raw = await this.raw(resolved);
|
||||||
let buffer = raw;
|
let buffer = raw;
|
||||||
|
|
||||||
@@ -47,21 +46,7 @@ export abstract class AbstractVFS {
|
|||||||
return buffer;
|
return buffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
dir(path: string) {
|
abstract dir(path: string): Promise<string[]>;
|
||||||
const parentSegments = path.split("/").length;
|
|
||||||
const children = new Set<string>();
|
|
||||||
|
|
||||||
for (const child of this.paths()) {
|
|
||||||
if (!child.startsWith(path) || child === path) continue;
|
|
||||||
|
|
||||||
const childSegments = child.split("/");
|
|
||||||
const nextSegment = childSegments[parentSegments];
|
|
||||||
|
|
||||||
children.add(nextSegment);
|
|
||||||
}
|
|
||||||
|
|
||||||
return Array.from(children);
|
|
||||||
}
|
|
||||||
|
|
||||||
async text(path: string) {
|
async text(path: string) {
|
||||||
const file = await this.file(path);
|
const file = await this.file(path);
|
||||||
@@ -70,7 +55,7 @@ export abstract class AbstractVFS {
|
|||||||
|
|
||||||
async yaml<Type>(path: string) {
|
async yaml<Type>(path: string) {
|
||||||
const file = await this.text(path);
|
const file = await this.text(path);
|
||||||
return parse(file) as Type;
|
return parseYaml(file) as Type;
|
||||||
}
|
}
|
||||||
|
|
||||||
async xml<Type>(path: string) {
|
async xml<Type>(path: string) {
|
||||||
@@ -78,6 +63,16 @@ export abstract class AbstractVFS {
|
|||||||
return this.xmlParser.parse(file) as Type;
|
return this.xmlParser.parse(file) as Type;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async _csv(text: string, options: Options = {}) {
|
||||||
|
const parsed = parseCSV(text, options);
|
||||||
|
return parsed;
|
||||||
|
}
|
||||||
|
|
||||||
|
async csv(path: string, options: Options = {}) {
|
||||||
|
const text = await this.text(path);
|
||||||
|
return await this._csv(text, options);
|
||||||
|
}
|
||||||
|
|
||||||
[Symbol.dispose]() {
|
[Symbol.dispose]() {
|
||||||
this.dispose();
|
this.dispose();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,31 @@
|
|||||||
|
import { readdir } from "node:fs/promises";
|
||||||
|
import { AbstractVFS } from "./abstract";
|
||||||
|
|
||||||
|
export class LocalVFS extends AbstractVFS {
|
||||||
|
constructor(private base: string) {
|
||||||
|
super();
|
||||||
|
}
|
||||||
|
|
||||||
|
async init() {
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
async has(path: string) {
|
||||||
|
const file = Bun.file(`${this.base}/${path}`);
|
||||||
|
return await file.exists();
|
||||||
|
}
|
||||||
|
|
||||||
|
async raw(path: string) {
|
||||||
|
const file = Bun.file(`${this.base}/${path}`);
|
||||||
|
const buffer = await file.arrayBuffer();
|
||||||
|
const array = new Uint8Array(buffer);
|
||||||
|
|
||||||
|
return array;
|
||||||
|
}
|
||||||
|
|
||||||
|
async dir(path: string) {
|
||||||
|
return await readdir(`${this.base}/${path}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
dispose() {}
|
||||||
|
}
|
||||||
@@ -38,7 +38,7 @@ export class SteamVFS extends AbstractVFS {
|
|||||||
private username: string,
|
private username: string,
|
||||||
private password: string,
|
private password: string,
|
||||||
private app: number,
|
private app: number,
|
||||||
private depot: number
|
private depot: number,
|
||||||
) {
|
) {
|
||||||
super();
|
super();
|
||||||
}
|
}
|
||||||
@@ -57,13 +57,14 @@ export class SteamVFS extends AbstractVFS {
|
|||||||
this.steam.getManifest(
|
this.steam.getManifest(
|
||||||
this.app,
|
this.app,
|
||||||
this.depot,
|
this.depot,
|
||||||
|
// @ts-expect-error
|
||||||
productInfo.apps[this.app].appinfo.depots[this.depot].manifests.public
|
productInfo.apps[this.app].appinfo.depots[this.depot].manifests.public
|
||||||
.gid,
|
.gid,
|
||||||
"public",
|
"public",
|
||||||
// @ts-expect-error
|
// @ts-expect-error
|
||||||
(_, response) => {
|
(_, response) => {
|
||||||
resolve(response);
|
resolve(response);
|
||||||
}
|
},
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -75,7 +76,7 @@ export class SteamVFS extends AbstractVFS {
|
|||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
has(path: string) {
|
async has(path: string) {
|
||||||
return this.manifest.has(path);
|
return this.manifest.has(path);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -88,8 +89,20 @@ export class SteamVFS extends AbstractVFS {
|
|||||||
return new Uint8Array(downloaded.file);
|
return new Uint8Array(downloaded.file);
|
||||||
}
|
}
|
||||||
|
|
||||||
paths() {
|
async dir(path: string) {
|
||||||
return Array.from(this.manifest.keys());
|
const parentSegments = path.split("/").length;
|
||||||
|
const children = new Set<string>();
|
||||||
|
|
||||||
|
for (const child of this.manifest.keys()) {
|
||||||
|
if (!child.startsWith(path) || child === path) continue;
|
||||||
|
|
||||||
|
const childSegments = child.split("/");
|
||||||
|
const nextSegment = childSegments[parentSegments];
|
||||||
|
|
||||||
|
children.add(nextSegment);
|
||||||
|
}
|
||||||
|
|
||||||
|
return Array.from(children);
|
||||||
}
|
}
|
||||||
|
|
||||||
dispose() {
|
dispose() {
|
||||||
|
|||||||
@@ -5,7 +5,10 @@ import { AbstractVFS } from "./abstract";
|
|||||||
export class ZipVFS extends AbstractVFS {
|
export class ZipVFS extends AbstractVFS {
|
||||||
entries = new Map<string, ZipEntry>();
|
entries = new Map<string, ZipEntry>();
|
||||||
|
|
||||||
constructor(private url: string, private root = "app/") {
|
constructor(
|
||||||
|
private url: string,
|
||||||
|
private root = "app/",
|
||||||
|
) {
|
||||||
super();
|
super();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -21,7 +24,7 @@ export class ZipVFS extends AbstractVFS {
|
|||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
has(path: string) {
|
async has(path: string) {
|
||||||
return this.entries.has(path);
|
return this.entries.has(path);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -30,8 +33,20 @@ export class ZipVFS extends AbstractVFS {
|
|||||||
return new Uint8Array(arrayBuffer);
|
return new Uint8Array(arrayBuffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
paths() {
|
async dir(path: string) {
|
||||||
return Array.from(this.entries.keys());
|
const parentSegments = path.split("/").length;
|
||||||
|
const children = new Set<string>();
|
||||||
|
|
||||||
|
for (const child of this.entries.keys()) {
|
||||||
|
if (!child.startsWith(path) || child === path) continue;
|
||||||
|
|
||||||
|
const childSegments = child.split("/");
|
||||||
|
const nextSegment = childSegments[parentSegments];
|
||||||
|
|
||||||
|
children.add(nextSegment);
|
||||||
|
}
|
||||||
|
|
||||||
|
return Array.from(children);
|
||||||
}
|
}
|
||||||
|
|
||||||
dispose() {}
|
dispose() {}
|
||||||
|
|||||||
@@ -53,7 +53,7 @@ if (newTanks.length > 0) {
|
|||||||
notes += "## New Tanks\n\n";
|
notes += "## New Tanks\n\n";
|
||||||
|
|
||||||
for (const tank of newTanks) {
|
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 += `})\n\n`;
|
notes += `})\n\n`;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -96,49 +96,49 @@ if (changedTanks.length > 0) {
|
|||||||
const previewTankModel = previewModelDefinitions.models[preview.id];
|
const previewTankModel = previewModelDefinitions.models[preview.id];
|
||||||
|
|
||||||
const currentConsumables = Object.values(
|
const currentConsumables = Object.values(
|
||||||
currentConsumableDefinitions.consumables
|
currentConsumableDefinitions.consumables,
|
||||||
).filter((consumable) =>
|
).filter((consumable) =>
|
||||||
checkConsumableProvisionInclusivity(consumable, current, currentGun)
|
checkConsumableProvisionInclusivity(consumable, current, currentGun),
|
||||||
);
|
);
|
||||||
const previewConsumables = Object.values(
|
const previewConsumables = Object.values(
|
||||||
previewConsumableDefinitions.consumables
|
previewConsumableDefinitions.consumables,
|
||||||
).filter((consumable) =>
|
).filter((consumable) =>
|
||||||
checkConsumableProvisionInclusivity(consumable, preview, previewGun)
|
checkConsumableProvisionInclusivity(consumable, preview, previewGun),
|
||||||
);
|
);
|
||||||
const addedConsumables = previewConsumables.filter(
|
const addedConsumables = previewConsumables.filter(
|
||||||
(previewConsumable) =>
|
(previewConsumable) =>
|
||||||
!currentConsumables.some(
|
!currentConsumables.some(
|
||||||
(currentConsumable) => currentConsumable.id === previewConsumable.id
|
(currentConsumable) => currentConsumable.id === previewConsumable.id,
|
||||||
)
|
),
|
||||||
);
|
);
|
||||||
const removedConsumables = currentConsumables.filter(
|
const removedConsumables = currentConsumables.filter(
|
||||||
(currentConsumable) =>
|
(currentConsumable) =>
|
||||||
!previewConsumables.some(
|
!previewConsumables.some(
|
||||||
(previewConsumable) => previewConsumable.id === currentConsumable.id
|
(previewConsumable) => previewConsumable.id === currentConsumable.id,
|
||||||
)
|
),
|
||||||
);
|
);
|
||||||
|
|
||||||
const currentProvisions = availableProvisions(
|
const currentProvisions = availableProvisions(
|
||||||
current,
|
current,
|
||||||
currentGun,
|
currentGun,
|
||||||
currentProvisionDefinitions
|
currentProvisionDefinitions,
|
||||||
);
|
);
|
||||||
const previewProvisions = availableProvisions(
|
const previewProvisions = availableProvisions(
|
||||||
preview,
|
preview,
|
||||||
previewGun,
|
previewGun,
|
||||||
previewProvisionDefinitions
|
previewProvisionDefinitions,
|
||||||
);
|
);
|
||||||
const addedProvisions = previewProvisions.filter(
|
const addedProvisions = previewProvisions.filter(
|
||||||
(previewProvision) =>
|
(previewProvision) =>
|
||||||
!currentProvisions.some(
|
!currentProvisions.some(
|
||||||
(currentProvision) => currentProvision.id === previewProvision.id
|
(currentProvision) => currentProvision.id === previewProvision.id,
|
||||||
)
|
),
|
||||||
);
|
);
|
||||||
const removedProvisions = currentProvisions.filter(
|
const removedProvisions = currentProvisions.filter(
|
||||||
(currentProvision) =>
|
(currentProvision) =>
|
||||||
!previewProvisions.some(
|
!previewProvisions.some(
|
||||||
(previewProvision) => previewProvision.id === currentProvision.id
|
(previewProvision) => previewProvision.id === currentProvision.id,
|
||||||
)
|
),
|
||||||
);
|
);
|
||||||
|
|
||||||
const currentEquipment = currentEquipmentDefinitions.presets[
|
const currentEquipment = currentEquipmentDefinitions.presets[
|
||||||
@@ -155,19 +155,20 @@ if (changedTanks.length > 0) {
|
|||||||
.filter(
|
.filter(
|
||||||
(previewEquipment) =>
|
(previewEquipment) =>
|
||||||
!currentEquipment.some(
|
!currentEquipment.some(
|
||||||
(currentEquipment) => currentEquipment === previewEquipment
|
(currentEquipment) => currentEquipment === previewEquipment,
|
||||||
)
|
),
|
||||||
)
|
)
|
||||||
.map((id) => previewEquipmentDefinitions.equipments[id]);
|
.map((id) => previewEquipmentDefinitions.equipments[id]);
|
||||||
const removedEquipment = currentEquipment
|
const removedEquipment = currentEquipment
|
||||||
.filter(
|
.filter(
|
||||||
(currentEquipment) =>
|
(currentEquipment) =>
|
||||||
!previewEquipment.some(
|
!previewEquipment.some(
|
||||||
(previewEquipment) => previewEquipment === currentEquipment
|
(previewEquipment) => previewEquipment === currentEquipment,
|
||||||
)
|
),
|
||||||
)
|
)
|
||||||
.map((id) => currentEquipmentDefinitions.equipments[id]);
|
.map((id) => currentEquipmentDefinitions.equipments[id]);
|
||||||
|
|
||||||
|
const equalize = false;
|
||||||
const currentCharacteristics = tankCharacteristics(
|
const currentCharacteristics = tankCharacteristics(
|
||||||
{
|
{
|
||||||
tank: current,
|
tank: current,
|
||||||
@@ -184,7 +185,7 @@ if (changedTanks.length > 0) {
|
|||||||
provisions: createDefaultProvisions(
|
provisions: createDefaultProvisions(
|
||||||
current,
|
current,
|
||||||
currentGun,
|
currentGun,
|
||||||
currentProvisionDefinitions
|
currentProvisionDefinitions,
|
||||||
),
|
),
|
||||||
equipmentMatrix: genericDefaultEquipmentMatrix,
|
equipmentMatrix: genericDefaultEquipmentMatrix,
|
||||||
stockEngine: current.engines[0],
|
stockEngine: current.engines[0],
|
||||||
@@ -193,12 +194,13 @@ if (changedTanks.length > 0) {
|
|||||||
stockTurret: current.turrets[0],
|
stockTurret: current.turrets[0],
|
||||||
track: currentTracks,
|
track: currentTracks,
|
||||||
turret: currentTurret,
|
turret: currentTurret,
|
||||||
|
equalize,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
equipmentDefinitions: currentEquipmentDefinitions,
|
equipmentDefinitions: currentEquipmentDefinitions,
|
||||||
provisionDefinitions: currentProvisionDefinitions,
|
provisionDefinitions: currentProvisionDefinitions,
|
||||||
tankModelDefinition: currentTankModel,
|
tankModelDefinition: currentTankModel,
|
||||||
}
|
},
|
||||||
);
|
);
|
||||||
const previewCharacteristics = tankCharacteristics(
|
const previewCharacteristics = tankCharacteristics(
|
||||||
{
|
{
|
||||||
@@ -216,7 +218,7 @@ if (changedTanks.length > 0) {
|
|||||||
provisions: createDefaultProvisions(
|
provisions: createDefaultProvisions(
|
||||||
preview,
|
preview,
|
||||||
previewGun,
|
previewGun,
|
||||||
previewProvisionDefinitions
|
previewProvisionDefinitions,
|
||||||
),
|
),
|
||||||
equipmentMatrix: genericDefaultEquipmentMatrix,
|
equipmentMatrix: genericDefaultEquipmentMatrix,
|
||||||
stockEngine: preview.engines[0],
|
stockEngine: preview.engines[0],
|
||||||
@@ -225,12 +227,13 @@ if (changedTanks.length > 0) {
|
|||||||
stockTurret: preview.turrets[0],
|
stockTurret: preview.turrets[0],
|
||||||
track: previewTracks,
|
track: previewTracks,
|
||||||
turret: previewTurret,
|
turret: previewTurret,
|
||||||
|
equalize,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
equipmentDefinitions: previewEquipmentDefinitions,
|
equipmentDefinitions: previewEquipmentDefinitions,
|
||||||
provisionDefinitions: previewProvisionDefinitions,
|
provisionDefinitions: previewProvisionDefinitions,
|
||||||
tankModelDefinition: previewTankModel,
|
tankModelDefinition: previewTankModel,
|
||||||
}
|
},
|
||||||
);
|
);
|
||||||
const changedCharacteristics: string[] = [];
|
const changedCharacteristics: string[] = [];
|
||||||
|
|
||||||
@@ -244,17 +247,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 += `})\n\n`;
|
notes += `})\n\n`;
|
||||||
|
|
||||||
if (addedConsumables.length + removedConsumables.length > 0) {
|
if (addedConsumables.length + removedConsumables.length > 0) {
|
||||||
notes += `Consumables: `;
|
notes += `Consumables: `;
|
||||||
notes += [
|
notes += [
|
||||||
...addedConsumables.map(
|
...addedConsumables.map(
|
||||||
(consumable) => `🟢 ${consumable.name.locales.en}`
|
(consumable) => `🟢 ${consumable.name!.locales.en}`,
|
||||||
),
|
),
|
||||||
...removedConsumables.map(
|
...removedConsumables.map(
|
||||||
(consumable) => `🔴 ${consumable.name.locales.en}`
|
(consumable) => `🔴 ${consumable.name!.locales.en}`,
|
||||||
),
|
),
|
||||||
].join(", ");
|
].join(", ");
|
||||||
notes += `\n`;
|
notes += `\n`;
|
||||||
@@ -264,10 +267,10 @@ if (changedTanks.length > 0) {
|
|||||||
notes += `Provisions: `;
|
notes += `Provisions: `;
|
||||||
notes += [
|
notes += [
|
||||||
...addedProvisions.map(
|
...addedProvisions.map(
|
||||||
(provision) => `🟢 ${provision.name.locales.en}`
|
(provision) => `🟢 ${provision.name!.locales.en}`,
|
||||||
),
|
),
|
||||||
...removedProvisions.map(
|
...removedProvisions.map(
|
||||||
(provision) => `🔴 ${provision.name.locales.en}`
|
(provision) => `🔴 ${provision.name!.locales.en}`,
|
||||||
),
|
),
|
||||||
].join(", ");
|
].join(", ");
|
||||||
notes += `\n`;
|
notes += `\n`;
|
||||||
@@ -276,9 +279,11 @@ if (changedTanks.length > 0) {
|
|||||||
if (addedEquipment.length + removedEquipment.length > 0) {
|
if (addedEquipment.length + removedEquipment.length > 0) {
|
||||||
notes += `-Equipment: `;
|
notes += `-Equipment: `;
|
||||||
notes += [
|
notes += [
|
||||||
...addedEquipment.map((equipment) => `🟢 ${equipment.name.locales.en}`),
|
...addedEquipment.map(
|
||||||
|
(equipment) => `🟢 ${equipment.name!.locales.en}`,
|
||||||
|
),
|
||||||
...removedEquipment.map(
|
...removedEquipment.map(
|
||||||
(equipment) => `🔴 ${equipment.name.locales.en}`
|
(equipment) => `🔴 ${equipment.name!.locales.en}`,
|
||||||
),
|
),
|
||||||
].join(", ");
|
].join(", ");
|
||||||
notes += `\n`;
|
notes += `\n`;
|
||||||
|
|||||||
@@ -26,8 +26,8 @@ for (const location of TS_PROTO_EXECUTABLE_LOCATIONS) {
|
|||||||
if (!tsProtoExecutableLocation) {
|
if (!tsProtoExecutableLocation) {
|
||||||
throw new Error(
|
throw new Error(
|
||||||
`Could not find ts-proto executable. Checked locations: ${TS_PROTO_EXECUTABLE_LOCATIONS.join(
|
`Could not find ts-proto executable. Checked locations: ${TS_PROTO_EXECUTABLE_LOCATIONS.join(
|
||||||
", "
|
", ",
|
||||||
)}`
|
)}`,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ import {
|
|||||||
Video,
|
Video,
|
||||||
youtubers,
|
youtubers,
|
||||||
} from "@blitzkit/core";
|
} from "@blitzkit/core";
|
||||||
|
import locales from "@blitzkit/i18n/locales.json";
|
||||||
import { google } from "googleapis";
|
import { google } from "googleapis";
|
||||||
import { cloneDeep, uniqBy } from "lodash-es";
|
import { cloneDeep, uniqBy } from "lodash-es";
|
||||||
import { AssetUploader } from "./core/github/assetUploader";
|
import { AssetUploader } from "./core/github/assetUploader";
|
||||||
@@ -42,9 +43,11 @@ for (const tank of tanksSanitized) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
const q = `World of Tanks Blitz ${tank.name!.locales[locales.default]}`;
|
||||||
|
|
||||||
const results = await youtube.search.list({
|
const results = await youtube.search.list({
|
||||||
part: ["snippet"],
|
part: ["snippet"],
|
||||||
q: `World of Tanks Blitz ${tank.name}`,
|
q,
|
||||||
});
|
});
|
||||||
|
|
||||||
if (!results.data.items || results.data.items.length === 0) continue;
|
if (!results.data.items || results.data.items.length === 0) continue;
|
||||||
@@ -54,9 +57,9 @@ for (const tank of tanksSanitized) {
|
|||||||
(item) =>
|
(item) =>
|
||||||
item.snippet?.channelId &&
|
item.snippet?.channelId &&
|
||||||
item.id?.videoId &&
|
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] = {
|
reviews.reviews[tank.id] = {
|
||||||
@@ -66,11 +69,13 @@ for (const tank of tanksSanitized) {
|
|||||||
({
|
({
|
||||||
id: item.id!.videoId!,
|
id: item.id!.videoId!,
|
||||||
author: item.snippet!.channelId!,
|
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));
|
await new Promise((resolve) => setTimeout(resolve, 1000 / 5));
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
|
|||||||
@@ -0,0 +1,619 @@
|
|||||||
|
name;maxHealthFactor;piercingPowerFactor;moduleHealthFactor;damageFactor;armorFactor
|
||||||
|
china:Ch01_Type59;1.3;1.33;1.5;1.29;1.35
|
||||||
|
china:Ch02_Type62;1.5;1.6;1.5;1.27;1.61
|
||||||
|
china:Ch03_WZ-111;1.4;1.17;1.4;1.3;1.35
|
||||||
|
china:Ch04_T34_1;1.5;1.54;1.4;1.3;1.61
|
||||||
|
china:Ch05_T34_2;1.3;1.33;1.5;1.29;1.34
|
||||||
|
china:Ch07_Vickers_MkE_Type_BT26;5.5;5.07;3.3;7.05;8.8
|
||||||
|
china:Ch08_Type97_Chi_Ha;3.7;3.71;2.2;3.13;5.56
|
||||||
|
china:Ch09_M5;2.9;2.91;1.9;2.54;3.47
|
||||||
|
china:Ch10_IS2;1.6;1.44;1.4;1.33;1.61
|
||||||
|
china:Ch11_110;1.4;1.17;1.4;1.29;1.35
|
||||||
|
china:Ch12_111_1_2_3;1.2;1.02;1.4;1.17;1.14
|
||||||
|
china:Ch14_T34_3;1.3;1.37;1.5;1.13;1.17
|
||||||
|
china:Ch15_59_16;1.9;1.77;1.6;1.57;2.24
|
||||||
|
china:Ch15_59_16_BP;1.9;1.7;1.6;1.56;2.24
|
||||||
|
china:Ch16_WZ_131;1.6;1.52;1.5;1.28;1.61
|
||||||
|
china:Ch17_WZ131_1_WZ132;1.4;1.22;1.5;1.29;1.34
|
||||||
|
china:Ch18_WZ-120;1.1;1.09;1.4;1.11;1.17
|
||||||
|
china:Ch20_Type58;1.9;1.88;1.5;1.57;1.86
|
||||||
|
china:Ch21_T34;2.7;2.1;1.7;1.97;2.12
|
||||||
|
china:Ch23_112;1.4;1.17;1.4;1.31;1.35
|
||||||
|
china:Ch24_Type64;1.9;1.86;1.6;1.57;2.35
|
||||||
|
china:Ch26_59_Patton;1.3;1.33;1.5;1.1;1.16
|
||||||
|
china:Ch28_WZ_132A;1.1;1.04;1.5;1.11;1.24
|
||||||
|
china:Ch34_WZ-131G_FT;2.1;1.57;1.4;1.51;1.73
|
||||||
|
china:Ch34_WZ-131G_FT_BP;2.1;1.57;1.4;1.51;2.02
|
||||||
|
china:Ch35_T-34-2G_FT;1.8;1.48;1.4;1.25;1.61
|
||||||
|
china:Ch36_WZ-111-1G_FT;1.6;1.16;1.4;1.25;1.35
|
||||||
|
china:Ch37_WZ-111G_FT;1.2;1.05;1.4;1.15;1.13
|
||||||
|
china:Ch39_WZ120_1G_FT;1.6;1.16;1.4;1.24;1.35
|
||||||
|
china:Ch40_WZ120G_FT;1.1;1.05;1.4;1.08;1.13
|
||||||
|
china:Ch42_M41D;1.7;1.49;1.5;1.24;1.61
|
||||||
|
china:Ch43_WZ-122_2;1.3;1.21;1.5;1.31;1.35
|
||||||
|
china:Ch45_WZ_114;1.2;1.02;1.4;1.19;1.13
|
||||||
|
china:Ch47_BZ_176;1.2;1.03;1.4;1.17;1.13
|
||||||
|
china:Ch49_BZ_68;1.2;1.02;1.4;1.2;1.16
|
||||||
|
china:Ch50_BZ_166;1.4;1.17;1.4;1.3;1.35
|
||||||
|
china:Ch51_BZ_58;1.6;1.46;1.4;1.29;1.62
|
||||||
|
china:Ch56_BZ_74_1;1.2;1.02;1.4;1.16;1.14
|
||||||
|
china:Ch59_BZ58_2;1.2;1.02;1.4;1.19;1.13
|
||||||
|
china:Ch60_Type59_spc;1.3;1.37;1.5;1.32;1.35
|
||||||
|
china:Ch_LT_vz38;4.3;4.29;2.7;3.99;4.88
|
||||||
|
china:Ch_WZ-112v2;1.4;1.17;1.4;1.31;1.35
|
||||||
|
china:Type_58BP;1.9;1.88;1.5;1.57;2.04
|
||||||
|
european:Cz02_T50;1.1;1.03;1.4;1.12;1.19
|
||||||
|
european:Cz05_T34-100;1.5;1.45;1.4;1.29;1.61
|
||||||
|
european:Cz07_TVP_46;1.3;1.12;1.5;1.29;1.35
|
||||||
|
european:Cz08_T-25;1.9;1.83;1.5;1.56;2.02
|
||||||
|
european:Cz08_T-25BP;1.9;1.83;1.5;1.55;2.02
|
||||||
|
european:Cz08_T-25BPS;1.9;1.83;1.5;1.57;2.02
|
||||||
|
european:Cz13_T-27;1.1;1.07;1.4;1.12;1.19
|
||||||
|
european:Cz14_Skoda_T-56;1.4;1.17;1.4;1.33;1.35
|
||||||
|
european:Cz15_Skoda_T-45;1.7;1.44;1.4;1.27;1.61
|
||||||
|
european:Cz16_TNH_T_vz51;1.2;1.02;1.4;1.17;1.15
|
||||||
|
european:Cz18_TNH_105_1000;1.4;1.16;1.4;1.28;1.35
|
||||||
|
european:Cz19_Vz_44_1;1.7;1.43;1.4;1.3;1.61
|
||||||
|
european:Cz20_ShPTK_TVP_100;1.5;1.16;1.4;1.24;1.34
|
||||||
|
european:Cz29_Skoda_P-JS;2.2;1.67;1.4;1.56;1.78
|
||||||
|
european:Cz29_Skoda_P-JS_BP;2.2;1.67;1.4;1.57;1.79
|
||||||
|
european:F01_Vickers_MkF;5.5;5.07;3.3;6.16;8.8
|
||||||
|
european:It09_P43_ter;1.5;1.54;1.4;1.3;1.61
|
||||||
|
european:It10_P43_BD;1.9;1.74;1.5;1.57;1.82
|
||||||
|
european:It10_P43_bis;1.9;1.74;1.5;1.57;1.82
|
||||||
|
european:It10_P43_bis_BP;1.9;1.7;1.5;1.58;1.82
|
||||||
|
european:It116_Carro_d_assalto_P88;1.6;1.33;1.4;1.28;1.61
|
||||||
|
european:It117_ProgettoCC55mod54;1.3;1.13;1.4;1.29;1.35
|
||||||
|
european:It119_ProgettoC50mod66;1.1;1.02;1.4;1.18;1.13
|
||||||
|
european:It12_Prototipo_Standard_B;1.1;1.04;1.4;1.14;1.17
|
||||||
|
european:It13_Progetto_M35_mod_46;1.3;1.33;1.5;1.27;1.35
|
||||||
|
european:It14_P44_Pantera;1.3;1.21;1.5;1.26;1.35
|
||||||
|
european:It15_Semovente_M41;3.2;1.98;1.5;1.97;2.13
|
||||||
|
european:It16_Bassoto;2;1.59;1.4;1.53;1.8
|
||||||
|
european:It17_Semovente_mod_56;1.7;1.4;1.4;1.28;1.62
|
||||||
|
european:It18_Semovente_mod_64;1.4;1.2;1.4;1.24;1.35
|
||||||
|
european:It19_Controcarro_1MK2_Ciclope;1.1;1.05;1.4;1.19;1.13
|
||||||
|
european:It22_Progetto_C45_mod_71;1.3;1.14;1.4;1.23;1.35
|
||||||
|
european:It30_CC_mod_64_Prem;1.4;1.17;1.4;1.25;1.35
|
||||||
|
european:Pl03_PzV_Pudel;1.9;1.57;1.5;1.56;1.92
|
||||||
|
european:Pl05_50TP_Tyszkiewicza;1.2;1.02;1.4;1.18;1.13
|
||||||
|
european:Pl06_10TP;4.3;4.29;2.7;4.28;7.66
|
||||||
|
european:Pl07_14TP;3.6;3.57;2.1;3.12;5.56
|
||||||
|
european:Pl08_50TP_prot;1.2;1.02;1.4;1.17;1.14
|
||||||
|
european:Pl10_40TP_Habicha;2.1;1.64;1.4;1.57;1.83
|
||||||
|
european:Pl119_CS_52_LIS;1.5;1.56;1.4;1.31;1.61
|
||||||
|
european:Pl11_45TP_Habicha;1.6;1.44;1.4;1.3;1.61
|
||||||
|
european:Pl13_53TP_Markowskiego;1.4;1.14;1.4;1.32;1.35
|
||||||
|
european:Pl17_DS_PZlnz;2.6;2.28;1.7;1.95;2.12
|
||||||
|
european:Pl18_BUGI;1.9;1.57;1.5;1.58;1.94
|
||||||
|
european:Pl20_CS_44;1.5;1.54;1.4;1.3;1.61
|
||||||
|
european:Pl22_CS_59;1.1;1.04;1.4;1.1;1.21
|
||||||
|
european:Pl23_CS_53;1.3;1.31;1.5;1.29;1.35
|
||||||
|
european:Pl24_56TP;1.4;1.15;1.4;1.29;1.35
|
||||||
|
european:Pl27_SDP_Wz_66T;1.5;1.17;1.4;1.27;1.35
|
||||||
|
european:Pl28_SDP_Wz_60;1.1;1.05;1.4;1.11;1.12
|
||||||
|
european:Pl30_SDP_Wz58T;1.4;1.16;1.4;1.26;1.35
|
||||||
|
european:Pl31_SDP_Wz_57D;1.7;1.43;1.4;1.28;1.62
|
||||||
|
european:Pl32_SDP_Wz_44;2;1.57;1.4;1.52;1.76
|
||||||
|
european:Pl33_SDP_Wz_40;3.2;2.13;1.5;1.96;2.13
|
||||||
|
european:S02_StrvM42;2.7;2.22;1.7;1.95;2.11
|
||||||
|
european:S04_Lago-I;3.1;2.69;1.9;2.54;2.32
|
||||||
|
european:S07_Strv74BP;1.9;1.67;1.5;1.55;1.9
|
||||||
|
european:S07_Strv_74;1.9;1.67;1.5;1.55;1.9
|
||||||
|
european:S13_Leo;1.5;1.58;1.4;1.3;1.61
|
||||||
|
european:S13_Leo_NY;1.5;1.58;1.4;1.3;1.61
|
||||||
|
european:S17_EMIL_1952E2;1.2;1.02;1.4;1.16;1.12
|
||||||
|
european:S18_EMIL_1951E1;1.3;1.16;1.4;1.29;1.35
|
||||||
|
european:S23_Strv_81;1.3;1.14;1.5;1.26;1.35
|
||||||
|
european:S25_EMIL_51;1.3;1.12;1.4;1.29;1.35
|
||||||
|
european:S26_Lancen_C;1.3;1.22;1.5;1.31;1.35
|
||||||
|
european:S32_Bofors_Tornvagn;1.1;1.02;1.4;1.17;1.12
|
||||||
|
france:AMX38;4.4;4.29;2.7;4.15;5.95
|
||||||
|
france:AMX40;3;2.88;1.9;2.52;3.53
|
||||||
|
france:AMX50_Foch;1.2;1.05;1.4;1.11;1.14
|
||||||
|
france:AMX_12t;1.9;1.64;1.6;1.6;2.02
|
||||||
|
france:AMX_13_75;1.7;1.61;1.5;1.25;1.61
|
||||||
|
france:AMX_13_90;1.4;1.37;1.5;1.29;1.34
|
||||||
|
france:AMX_50_100;1.4;1.12;1.4;1.26;1.35
|
||||||
|
france:AMX_50_120;1.2;1.02;1.4;1.12;1.17
|
||||||
|
france:AMX_AC_Mle1946;1.7;1.45;1.4;1.24;1.61
|
||||||
|
france:AMX_AC_Mle1948;1.5;1.16;1.4;1.24;1.35
|
||||||
|
france:AMX_M4_1945;1.6;1.47;1.4;1.28;1.61
|
||||||
|
france:ARL_44;2.1;1.57;1.4;1.53;1.82
|
||||||
|
france:ARL_44BP;2.1;1.53;1.4;1.58;1.81
|
||||||
|
france:ARL_V39;2;1.59;1.4;1.52;1.82
|
||||||
|
france:Achilles_FR;2.1;1.6;1.4;1.52;1.83
|
||||||
|
france:B1;4.1;2.8;1.6;2.54;3.64
|
||||||
|
france:BDR_G1B;3.2;1.91;1.5;1.95;2.13
|
||||||
|
france:Bat-Chat-25CL;1.1;1.05;1.5;1.1;1.22
|
||||||
|
france:D1;4.3;4.62;2.7;3.8;6.52
|
||||||
|
france:D2;3.7;3.64;2.2;3;5.52
|
||||||
|
france:ELC_AMX;2.8;1.97;2.3;2.31;2.09
|
||||||
|
france:F113_PzV_FR;1.9;1.65;1.5;1.56;1.89
|
||||||
|
france:F114_Projet_4_1;1.1;1.03;1.4;1.09;1.22
|
||||||
|
france:F115_Lorraine_50t;1.2;1.02;1.4;1.13;1.16
|
||||||
|
france:F116_Bat_Chat_Bourrasque;1.3;1.28;1.5;1.31;1.34
|
||||||
|
france:F117_Alt_Proto_AMX_30;1.3;1.15;1.5;1.29;1.35
|
||||||
|
france:F11_Renault_G1R;3.2;2;1.5;1.96;2.12
|
||||||
|
france:F120_Project_Louis;1.1;1.04;1.4;1.12;1.14
|
||||||
|
france:F123_ERAC_105_Proto;1.3;1.22;1.5;1.3;1.35
|
||||||
|
france:F126_AMX_13_M24;1.5;1.58;1.4;1.32;1.62
|
||||||
|
france:F127_ELC_AMX_901_Proto;1.4;1.28;1.5;1.28;1.34
|
||||||
|
france:F140_Sentinelle;1.4;1.15;1.4;1.28;1.35
|
||||||
|
france:F19_Lorraine40t;1.3;1.17;1.5;1.3;1.34
|
||||||
|
france:F19_Lorraine40t_Com;1.3;1.17;1.5;1.29;1.34
|
||||||
|
france:F34_ARL_V39_BP;2.1;1.59;1.4;1.51;1.82
|
||||||
|
france:F68_AMX_Chasseur_de_char_46;1.3;1.17;1.5;1.25;1.33
|
||||||
|
france:F69_AMX_13D;1.4;1.16;1.5;1.28;1.34
|
||||||
|
france:F69_AMX_13_57GF;1.6;1.49;1.5;1.26;1.61
|
||||||
|
france:F71_AMX_30_prototype;1.1;1.06;1.4;1.12;1.19
|
||||||
|
france:F73_M4A1_Revalorise;1.3;1.23;1.5;1.27;1.34
|
||||||
|
france:F74_AMX_M4_1949;1.4;1.12;1.4;1.28;1.35
|
||||||
|
france:F75_Char_de_25t;1.1;1.02;1.5;1.11;1.22
|
||||||
|
france:F84_Somua_SM;1.4;1.12;1.4;1.14;1.14
|
||||||
|
france:F89_Canon_dassaut_105;1.6;1.15;1.4;1.26;1.35
|
||||||
|
france:FCM_36Pak40;4.2;2.95;1.9;3.18;5.52
|
||||||
|
france:FCM_50t;1.3;1.17;1.5;1.25;1.35
|
||||||
|
france:F_AMX-12BP;1.9;1.64;1.6;1.6;2.02
|
||||||
|
france:RenaultFT_AC;5.5;4.37;2.2;4.49;8.51
|
||||||
|
france:RenaultR35;5.5;5.28;3.3;6.76;7.8
|
||||||
|
france:RenaultUE57;4.2;2.79;1.9;2.68;5.95
|
||||||
|
france:S_35CA;3.2;2.07;1.5;1.96;2.11
|
||||||
|
france:Somua_Sau_40;3.7;2.75;1.8;2.54;3.62
|
||||||
|
germany:B-1bis_captured;4.1;2.96;1.6;2.55;3.89
|
||||||
|
germany:DW_II;3.7;2.52;1.6;2.52;3.53
|
||||||
|
germany:DickerMax;2.1;1.57;1.4;1.53;2.02
|
||||||
|
germany:E-25;1.8;1.46;1.4;1.24;1.61
|
||||||
|
germany:E-50;1.1;1.09;1.4;1.1;1.15
|
||||||
|
germany:E-75;1.2;1.02;1.4;1.17;1.14
|
||||||
|
germany:Ferdinand;1.4;1.16;1.4;1.25;1.35
|
||||||
|
germany:G100_Gtraktor_Krupp;4.9;3.31;1.9;3.49;5.75
|
||||||
|
germany:G103_RU_251;1.4;1.3;1.5;1.25;1.33
|
||||||
|
germany:G106_PzKpfwPanther_AusfF;1.3;1.21;1.5;1.26;1.35
|
||||||
|
germany:G109_Steyr_WT;1.8;1.37;1.4;1.27;1.6
|
||||||
|
germany:G110_Mauschen;1.2;1.02;1.4;1.18;1.12
|
||||||
|
germany:G112_JagdPanzer_105;1.2;1.05;1.4;1.04;1.18
|
||||||
|
germany:G113_SP_I_C;1.7;1.49;1.5;1.28;1.58
|
||||||
|
germany:G114_Rheinmetall_Scorpion;1.6;1.16;1.4;1.24;1.33
|
||||||
|
germany:G115_VK10001P;1.4;1.15;1.4;1.33;1.35
|
||||||
|
germany:G118_VK4503;1.7;1.3;1.4;1.27;1.61
|
||||||
|
germany:G119_Panzer58_SH;1.3;1.22;1.5;1.28;1.35
|
||||||
|
germany:G119_Pz58_Mutz;1.3;1.17;1.5;1.26;1.35
|
||||||
|
germany:G120_M41_90;1.4;1.29;1.5;1.26;1.34
|
||||||
|
germany:G126_HWK_12;1.1;1.05;1.5;1.08;1.29
|
||||||
|
germany:G136_Tiger_131;2.1;1.68;1.4;1.55;1.85
|
||||||
|
germany:G138_VK16801P;1.5;1.15;1.4;1.16;1.13
|
||||||
|
germany:G140_HWK_30;1.4;1.27;1.5;1.27;1.34
|
||||||
|
germany:G142_M48RPz;1.3;1.18;1.5;1.27;1.35
|
||||||
|
germany:G147_mPanzer_64;1.7;1.49;1.5;1.29;1.61
|
||||||
|
germany:G148_Elephant;1.4;1.16;1.4;1.21;1.35
|
||||||
|
germany:G154_Kpz_07_RH;1.3;1.15;1.5;1.26;1.35
|
||||||
|
germany:G162_Project_Kpz_07P_E;1.1;1.02;1.4;1.16;1.14
|
||||||
|
germany:G164_Kpz_Pr_68_P;1.3;1.22;1.5;1.3;1.34
|
||||||
|
germany:G165_Erich_Koncept;1.1;1.06;1.4;1.14;1.19
|
||||||
|
germany:G166_LKpz_70_K;1.1;1.02;1.5;1.11;1.32
|
||||||
|
germany:G167_Tiger_Maus;1.2;1.03;1.4;1.11;1.13
|
||||||
|
germany:G168_KJpz_T_III;1.2;1.05;1.4;1.05;1.29
|
||||||
|
germany:G190_VK_1602_Quby;1.4;1.36;1.5;1.25;1.34
|
||||||
|
germany:G20_Marder_II;4.2;3.01;1.9;3.18;5.54
|
||||||
|
germany:G85_Auf_Panther;1.5;1.49;1.5;1.25;1.61
|
||||||
|
germany:G_E-75RT;1.4;1.14;1.4;1.3;1.35
|
||||||
|
germany:G_E-75TS;1.2;1.03;1.4;1.13;1.13
|
||||||
|
germany:G_VK3502_BP;2.1;1.68;1.4;1.57;1.79
|
||||||
|
germany:H39_captured;4.3;5.58;2.7;3.99;6.04
|
||||||
|
germany:Hetzer;3.7;2.6;1.8;2.54;3.47
|
||||||
|
germany:Indien_Panzer;1.3;1.17;1.5;1.25;1.35
|
||||||
|
germany:JagdPanther;1.8;1.37;1.4;1.25;1.62
|
||||||
|
germany:JagdPantherII;1.6;1.16;1.4;1.23;1.35
|
||||||
|
germany:JagdPzIV;2.1;1.58;1.4;1.49;1.8
|
||||||
|
germany:JagdPzIV_AusfBP;2;1.58;1.4;1.49;1.8
|
||||||
|
germany:JagdTiger;1.1;1.05;1.4;1.04;1.12
|
||||||
|
germany:JagdTiger_SdKfz_185;1.4;1.17;1.4;1.21;1.35
|
||||||
|
germany:JagdTiger_SdKfz_185_Snowstorm;1.4;1.33;1.4;1.21;1.35
|
||||||
|
germany:Krupp-38D;2.6;2.22;1.7;1.95;2.12
|
||||||
|
germany:Lowe;1.4;1.11;1.4;1.29;1.35
|
||||||
|
germany:Nashorn;2;1.51;1.4;1.51;2.24
|
||||||
|
germany:Nashorn_BP;2;1.51;1.4;1.5;2.24
|
||||||
|
germany:Panther_II;1.3;1.21;1.5;1.26;1.35
|
||||||
|
germany:Panther_M10;1.5;1.54;1.4;1.26;1.61
|
||||||
|
germany:PanzerJager_I;5.5;4.33;2.2;4.49;8.8
|
||||||
|
germany:Pro_Ag_A;1.1;1.02;1.4;1.1;1.21
|
||||||
|
germany:Pz35t;4.4;4.9;2.7;3.94;6.05
|
||||||
|
germany:Pz38_NA;2.9;2.78;1.9;2.55;3.65
|
||||||
|
germany:Pz38t;3.6;3.88;2.1;3.05;5.58
|
||||||
|
germany:PzII;5.5;5.28;3.3;6.67;6.81
|
||||||
|
germany:PzIII;3.7;3.69;2.2;3.26;5.49
|
||||||
|
germany:PzIII_A;3.7;3.09;2.1;2.98;5.58
|
||||||
|
germany:PzIII_IV;2.7;2.22;1.7;1.95;2.12
|
||||||
|
germany:PzII_J;3.6;5.5;2.1;2.83;5.46
|
||||||
|
germany:PzII_Luchs;2.9;2.94;1.9;2.55;2.2
|
||||||
|
germany:PzIV;2.7;2.22;1.7;1.95;2.13
|
||||||
|
germany:PzIV_Hydro;2.5;2.22;1.7;1.95;2.11
|
||||||
|
germany:PzIV_schmalturm;1.9;1.65;1.5;1.53;1.87
|
||||||
|
germany:PzV;1.5;1.33;1.4;1.26;1.61
|
||||||
|
germany:PzVI;1.7;1.3;1.4;1.28;1.62
|
||||||
|
germany:PzVIB_Tiger_II;1.4;1.14;1.4;1.27;1.35
|
||||||
|
germany:PzVI_AusfBP;2.1;1.68;1.4;1.56;1.79
|
||||||
|
germany:PzVI_Tiger_P;1.7;1.3;1.4;1.28;1.62
|
||||||
|
germany:PzV_PzIV;2.6;2.22;1.7;1.95;2.12
|
||||||
|
germany:Pz_II_AusfG;3.8;2.9;2.1;2.85;5.55
|
||||||
|
germany:Pz_IV_AusfA;3.6;3.2;2.2;4.05;5.74
|
||||||
|
germany:Pz_IV_AusfBT;2.7;2.53;1.7;1.96;2.12
|
||||||
|
germany:Pz_IV_AusfD;3.1;2.43;1.9;2.54;3.09
|
||||||
|
germany:Pz_Sfl_IVc;3;1.61;1.5;1.98;2.08
|
||||||
|
germany:RhB_Waffentrager;1.6;1.26;1.4;1.28;1.33
|
||||||
|
germany:S01_Frankentank;1.7;1.33;1.4;1.37;1.62
|
||||||
|
germany:S35_captured;3.8;2.85;2.1;2.93;5.52
|
||||||
|
germany:StuGIII;3.2;1.93;1.5;1.97;2.12
|
||||||
|
germany:Sturer_Emil;1.8;1.31;1.4;1.28;1.61
|
||||||
|
germany:T-15;3.8;4.72;2.1;2.82;5.55
|
||||||
|
germany:T-25;2.5;2.13;1.7;1.95;2.11
|
||||||
|
germany:VK1602;2.8;2.9;2.3;1.96;2.11
|
||||||
|
germany:VK2801;1.9;1.53;1.6;1.58;1.95
|
||||||
|
germany:VK2801_BP;1.9;1.53;1.6;1.59;1.95
|
||||||
|
germany:VK3001H;3.2;1.75;1.5;1.96;2.13
|
||||||
|
germany:VK3001P;1.9;1.61;1.5;1.57;1.81
|
||||||
|
germany:VK3002DB;1.5;1.58;1.4;1.28;1.61
|
||||||
|
germany:VK3002DB_BP;1.9;1.65;1.5;1.56;1.87
|
||||||
|
germany:VK3002DB_V1;1.9;1.65;1.5;1.56;1.84
|
||||||
|
germany:VK3002M;1.9;1.65;1.5;1.57;1.91
|
||||||
|
germany:VK3601H;2.1;1.64;1.4;1.57;1.78
|
||||||
|
germany:VK4502A;1.3;1.17;1.4;1.29;1.35
|
||||||
|
germany:VK4502P;1.2;1.02;1.4;1.18;1.13
|
||||||
|
germany:Waffentrager_IV;1.2;1.06;1.4;1.12;1.19
|
||||||
|
germany:Waffentrager_IV_CL;1.2;1.05;1.4;1.06;1.19
|
||||||
|
japan:Chi_Ha;3.6;3.8;2.2;3.2;5.54
|
||||||
|
japan:Chi_He;3;2.72;1.9;2.55;3.24
|
||||||
|
japan:Chi_Ni;4.4;4.62;2.5;4.09;6.52
|
||||||
|
japan:Chi_Nu;2.6;2.02;1.7;1.94;2.12
|
||||||
|
japan:Chi_Nu_Kai;2.6;2.02;1.7;1.95;2.11
|
||||||
|
japan:Chi_Ri;1.5;1.58;1.4;1.25;1.61
|
||||||
|
japan:Chi_To;1.9;1.61;1.5;1.55;1.9
|
||||||
|
japan:Firefly_GuP;1.9;1.49;1.5;1.55;2.01
|
||||||
|
japan:G09_Hetzer_GuP;3.7;2.6;1.8;2.54;3.47
|
||||||
|
japan:Ha_Go;5.7;5.36;3.3;5.99;8.2
|
||||||
|
japan:IS-2_GuP;1.6;1.44;1.4;1.33;1.61
|
||||||
|
japan:J21_Ho_Ri;1.2;1.05;1.4;1.11;1.13
|
||||||
|
japan:J22_Ho_Ri_type96;1.5;1.16;1.4;1.25;1.35
|
||||||
|
japan:J23_Chi_To_SPG;1.8;1.37;1.4;1.25;1.62
|
||||||
|
japan:J24_Type_57;1.4;1.16;1.4;1.33;1.35
|
||||||
|
japan:J26_Type_68;1.2;1.02;1.4;1.13;1.13
|
||||||
|
japan:J27_Chi_Se;1.4;1.15;1.4;1.27;1.35
|
||||||
|
japan:J28_Ju_To;1.7;1.41;1.4;1.32;1.62
|
||||||
|
japan:J29_Ju_Nu;2.1;1.73;1.4;1.57;1.8
|
||||||
|
japan:J29_Ju_Nu_BP;2.1;1.73;1.4;1.57;1.8
|
||||||
|
japan:J30_Mitsu_108;3.2;2.37;1.5;1.97;2.13
|
||||||
|
japan:J31_Type_5_Ka_Ri;1.5;1.16;1.4;1.26;1.35
|
||||||
|
japan:J36_Type_63_HT;1.4;1.15;1.4;1.29;1.35
|
||||||
|
japan:J38_Type_95_Ji_Ro;1.5;1.16;1.4;1.22;1.35
|
||||||
|
japan:Ke_Ho;2.9;2.71;1.9;2.55;1
|
||||||
|
japan:Ke_Ni;3.8;4.07;2.1;2.67;5.71
|
||||||
|
japan:Ke_Ni_B;4.5;4.85;2.1;2.14;5.71
|
||||||
|
japan:PzVI_GuP;2.1;1.64;1.4;1.54;1.81
|
||||||
|
japan:Pz_IV_AusfH;2.6;2.22;1.7;1.95;2.12
|
||||||
|
japan:STA_1;1.3;1.15;1.5;1.28;1.34
|
||||||
|
japan:Type_61;1.1;1.02;1.4;1.1;1.24
|
||||||
|
other:AMX_dracula;1.5;1.58;1.4;1.3;1.61
|
||||||
|
other:Akawara;1.3;1.28;1.5;1.28;1.35
|
||||||
|
other:Oth06_Sega_Lupus;1.7;1.44;1.4;1.34;1.62
|
||||||
|
other:Oth08_WH_Vindicator;1.8;1.74;1.4;1.24;1.61
|
||||||
|
other:Oth09_WH_Predator;1.7;1.47;1.4;1.25;1.62
|
||||||
|
other:Oth11_T-55A;1.1;1.1;1.4;1.09;1.16
|
||||||
|
other:Oth12_Sega_Hafen;1.6;1.66;1.4;1.27;1.61
|
||||||
|
other:Oth14_MdM_AshKnight;1.7;1.47;1.4;1.27;1.62
|
||||||
|
other:Oth15_RustCrab;2.6;2.22;1.7;1.96;2.12
|
||||||
|
other:Oth16_KV_TG;1.6;1.76;1.4;1.27;1.61
|
||||||
|
other:Oth17_BDT-5A;2.6;2.22;1.7;1.95;2.12
|
||||||
|
other:Oth18_BDT-5B;1.9;1.85;1.5;1.55;1.94
|
||||||
|
other:Oth19_BDT-5C;1.5;1.66;1.4;1.25;1.61
|
||||||
|
other:Oth20_M4FL10;1.5;1.67;1.4;1.27;1.61
|
||||||
|
other:Oth22_Sega_Vulcan;1.7;1.41;1.4;1.33;1.62
|
||||||
|
other:Oth23_Werewolf;1.6;1.44;1.4;1.33;1.61
|
||||||
|
other:Oth24_StuH_42HW;3.2;2.6;1.5;1.97;2.13
|
||||||
|
other:Oth25_HWT20_FalconFire;1.7;1.47;1.4;1.25;1.62
|
||||||
|
other:Oth26_StrvM42HW;2.7;2.22;1.7;1.96;2.11
|
||||||
|
other:Oth27_M24_AMX;1.9;1.64;1.6;1.6;2.02
|
||||||
|
other:Oth28_Sturmfeur_HW;1.7;1.41;1.4;1.31;1.61
|
||||||
|
other:Oth29_A15HW;2.8;1.83;2.3;1.96;2.12
|
||||||
|
other:Oth30_T54MS;1.3;1.2;1.5;1.3;1.35
|
||||||
|
other:Oth31_T150BP;2.1;1.71;1.4;1.56;1.79
|
||||||
|
other:Oth33_Blizzard_BP;2;1.68;1.6;1.56;2.21
|
||||||
|
other:Oth34_PanzerMummy;1.7;1.39;1.4;1.3;1.61
|
||||||
|
other:Oth35_PanzerMejai;3.2;2.27;1.5;1.95;2.13
|
||||||
|
other:Oth36_Indien_Panzer_S1;1.5;1.56;1.4;1.28;1.61
|
||||||
|
other:Oth37_T26_E4_SuperPershing_S1;1.3;1.25;1.5;1.3;1.35
|
||||||
|
other:Oth38_50TP_Tyszkiewicza_S1;1.1;1.02;1.4;1.17;1.14
|
||||||
|
other:Oth39_T20_S2;1.5;1.62;1.4;1.28;1.61
|
||||||
|
other:Oth40_TVP_46_S2;1.3;1.15;1.5;1.28;1.35
|
||||||
|
other:Oth41_Centurion_Mk3_S2;1.1;1.05;1.4;1.11;1.18
|
||||||
|
other:Oth42_ForestWitch_HW23;1.7;1.42;1.4;1.32;1.61
|
||||||
|
other:Oth44_Charioteer_T;1.6;1.17;1.4;1.27;1.35
|
||||||
|
other:Oth45_Sandstriker;1.4;1.16;1.4;1.33;1.35
|
||||||
|
other:Oth46_Charioteer_S3;1.8;1.37;1.4;1.27;1.61
|
||||||
|
other:Oth47_AMX_13_90_S3;1.4;1.3;1.5;1.28;1.34
|
||||||
|
other:Oth48_EMIL_1951E1_S3;1.1;1.02;1.4;1.15;1.14
|
||||||
|
other:Oth49_TM_04_NT;1.5;1.63;1.4;1.34;1.61
|
||||||
|
other:Oth50_STT;1.6;1.55;1.5;1.28;1.61
|
||||||
|
other:Oth51_FD_24;1.3;1.18;1.5;1.28;1.35
|
||||||
|
other:Oth52_Toxique;1.3;1.32;1.5;1.31;1.35
|
||||||
|
other:Oth53_Rammer;1.6;1.46;1.4;1.31;1.61
|
||||||
|
other:Oth61_Pz_VM_Set;4.1;2.58;1.6;2.54;3.71
|
||||||
|
other:Oth62_Pz_VlD_Set;3.2;1.97;1.5;1.96;2.13
|
||||||
|
other:Oth63_Pz_VllF_Set;2.1;1.64;1.4;1.57;1.84
|
||||||
|
other:Oth64_Pz_VlllK_Set;1.6;1.44;1.4;1.31;1.61
|
||||||
|
other:Oth65_PzVIllM_Tigeom;2.1;1.67;1.4;1.59;1.86
|
||||||
|
other:Oth66_E100ANN_S4;1.7;1.47;1.4;1.33;1.62
|
||||||
|
other:Oth67_FV215b_183ANN_S4;1.5;1.16;1.4;1.24;1.35
|
||||||
|
other:Oth68_KV2ANN_S4;1.2;1.03;1.4;1.23;1.14
|
||||||
|
other:Oth69_Souleater;1.5;1.17;1.4;1.26;1.35
|
||||||
|
other:Oth70_Lightbringer;1.6;1.47;1.4;1.29;1.61
|
||||||
|
other:Oth71_Titan_Strife;1.3;1.16;1.4;1.28;1.35
|
||||||
|
other:Oth72_Hazard_I;1.5;1.57;1.4;1.3;1.61
|
||||||
|
other:Oth73_Nemini;1.4;1.17;1.4;1.31;1.35
|
||||||
|
other:Oth74_Argonaut;1.1;1.05;1.4;1.06;1.18
|
||||||
|
other:Oth75_Braniaq_DM5;1.1;1.06;1.4;1.14;1.18
|
||||||
|
other:Oth76_Destiny;1.2;1.02;1.4;1.17;1.15
|
||||||
|
other:Oth77_Prowler;1.4;1.16;1.4;1.3;1.35
|
||||||
|
other:Oth78_AC_17_P_Sterope;1.2;1.02;1.4;1.13;1.12
|
||||||
|
other:Oth80_AC_16_Celeno;1.2;1.02;1.4;1.13;1.12
|
||||||
|
other:Oth81_AC_15_Taygete;1.4;1.24;1.4;1.33;1.35
|
||||||
|
other:Oth82_AC_14_Pleione;1.4;1.15;1.4;1.29;1.35
|
||||||
|
other:Oth83_AC_13_Merope;1.7;1.4;1.4;1.32;1.61
|
||||||
|
other:Oth84_FVE_Defender;1.1;1.12;1.4;1.16;1.15
|
||||||
|
other:Oth85_Ghoul;1.3;1.36;1.5;1.28;1.35
|
||||||
|
other:Oth86_Survivalist;1.1;1.06;1.4;1.1;1.12
|
||||||
|
other:Oth92_JagdPantherII_Titan;1.4;1.17;1.4;1.24;1.35
|
||||||
|
other:Oth93_Convoyer;1.4;1.16;1.4;1.24;1.35
|
||||||
|
other:Sega_Edelweiss;1.5;1.62;1.4;1.28;1.61
|
||||||
|
other:Sega_Nameless;1.7;1.41;1.4;1.29;1.62
|
||||||
|
other:Strv_74A2;1.9;1.8;1.5;1.54;1.9
|
||||||
|
other:Van_Helsing;1.8;1.59;1.4;1.25;1.61
|
||||||
|
other:WZ-135G_FT;1.8;1.5;1.4;1.3;1.61
|
||||||
|
uk:GB03_Cruiser_Mk_I;4.4;4.9;2.7;3.96;9.12
|
||||||
|
uk:GB04_Valentine;2.9;1.85;1.9;2.53;3.37
|
||||||
|
uk:GB05_Vickers_Medium_Mk_II;6.5;3.84;2.2;3.8;12.37
|
||||||
|
uk:GB06_Vickers_Medium_Mk_III;4.9;3.9;1.9;2.88;5.74
|
||||||
|
uk:GB07_Matilda;4.1;2.83;1.6;2.56;3.64
|
||||||
|
uk:GB08_Churchill_I;3.3;1.8;1.5;1.96;2.13
|
||||||
|
uk:GB09_Churchill_VII;2.1;1.7;1.4;1.54;1.76
|
||||||
|
uk:GB09_Churchill_VII_BP;2.1;1.67;1.4;1.54;1.79
|
||||||
|
uk:GB101_FV1066_Senlac;1.4;1.16;1.5;1.24;1.33
|
||||||
|
uk:GB106_Cobra;1.1;1.05;1.4;1.14;1.16
|
||||||
|
uk:GB108_A46;1.5;1.56;1.5;1.25;1.6
|
||||||
|
uk:GB109_GSOR_1008;1.6;1.16;1.4;1.25;1.34
|
||||||
|
uk:GB109_GSOR_1008_Fearless;1.6;1.18;1.4;1.24;1.34
|
||||||
|
uk:GB10_Black_Prince;1.7;1.47;1.4;1.23;1.62
|
||||||
|
uk:GB110_FV4201_Chieftain_Prototype;1.1;1.02;1.4;1.13;1.15
|
||||||
|
uk:GB111_Charlemagne;1.4;1.13;1.4;1.31;1.35
|
||||||
|
uk:GB112_Caliban;1.4;1.16;1.4;1.45;1.35
|
||||||
|
uk:GB114_Vickers_MBT_Mk3;1.3;1.28;1.5;1.12;1.14
|
||||||
|
uk:GB116_Harry_Hopkins;2.5;1.97;2.3;1.96;2.12
|
||||||
|
uk:GB11_Caernarvon;1.3;1.13;1.4;1.23;1.35
|
||||||
|
uk:GB11_Caernarvon_D;1.4;1.16;1.4;1.3;1.35
|
||||||
|
uk:GB128_Nemesis;1.3;1.29;1.5;1.28;1.35
|
||||||
|
uk:GB12_Conqueror;1.1;1.02;1.4;1.1;1.13
|
||||||
|
uk:GB19_Sherman_Firefly;1.9;1.49;1.5;1.55;2.01
|
||||||
|
uk:GB20_Crusader;2.7;1.83;2.3;1.96;2.11
|
||||||
|
uk:GB21_A27BP;1.9;1.7;1.5;1.55;1.94
|
||||||
|
uk:GB21_Cromwell;1.9;1.7;1.5;1.55;1.94
|
||||||
|
uk:GB22_Comet;1.5;1.58;1.4;1.25;1.61
|
||||||
|
uk:GB23_Centurion;1.3;1.12;1.5;1.25;1.35
|
||||||
|
uk:GB24_Centurion_Mk3;1.1;1.02;1.4;1.14;1.15
|
||||||
|
uk:GB32_Tortoise;1.1;1.05;1.4;1.05;1.11
|
||||||
|
uk:GB35_Sentinel_AC_IV;1.9;1.7;1.5;1.56;1.94
|
||||||
|
uk:GB39_Universal_CarrierQF2;5.5;4.89;2.2;3.99;11.07
|
||||||
|
uk:GB40_Gun_Carrier_BP;2;1.56;1.4;1.52;1.77
|
||||||
|
uk:GB40_Gun_Carrier_Churchill;2.1;1.48;1.4;1.51;1.79
|
||||||
|
uk:GB41_Challenger;1.8;1.35;1.4;1.26;1.61
|
||||||
|
uk:GB42_Valentine_AT;4.3;2.68;1.9;2.43;5.48
|
||||||
|
uk:GB44_Archer_Custom;3.2;1.76;1.5;1.98;2.08
|
||||||
|
uk:GB51_Excelsior;3.2;2.27;1.5;1.97;2.13
|
||||||
|
uk:GB52_FV201_A45;1.7;1.47;1.4;1.24;1.61
|
||||||
|
uk:GB57_Alecto;3.7;2.93;1.8;2.54;1
|
||||||
|
uk:GB58_Cruiser_Mk_III;4.4;4.9;2.5;4.26;6.52
|
||||||
|
uk:GB59_Cruiser_Mk_IV;3.7;3.82;2.2;3.05;5.52
|
||||||
|
uk:GB60_Covenanter;3;3;1.9;2.55;2.68
|
||||||
|
uk:GB63_TOG_II;1.9;1.53;1.4;1.54;1.8
|
||||||
|
uk:GB63_TOG_II_BP;1.9;1.53;1.4;1.57;1.79
|
||||||
|
uk:GB68_Matilda_Black_Prince;2.5;1.96;1.7;1.98;2.12
|
||||||
|
uk:GB69_Cruiser_Mk_II;5.9;5.88;3.3;5.32;8.2
|
||||||
|
uk:GB71_AT_15A;1.7;1.58;1.4;1.22;1.62
|
||||||
|
uk:GB72_AT15;1.4;1.19;1.4;1.19;1.35
|
||||||
|
uk:GB73_AT2;3.2;2.45;1.5;1.97;2.13
|
||||||
|
uk:GB74_AT8;2;1.6;1.4;1.51;1.76
|
||||||
|
uk:GB75_AT7;1.7;1.33;1.4;1.23;1.62
|
||||||
|
uk:GB76_Mk_VIC;4.3;5.58;2.7;4.01;9.12
|
||||||
|
uk:GB80_Charioteer;1.6;1.16;1.4;1.27;1.34
|
||||||
|
uk:GB81_FV4004;1.2;1.05;1.4;1.11;1.2
|
||||||
|
uk:GB85_Cromwell_Berlin;1.9;1.7;1.5;1.55;1.94
|
||||||
|
uk:GB87_Chieftain_T95_turret;1.4;1.17;1.4;1.25;1.35
|
||||||
|
uk:GB93_Caernarvon_AX;1.3;1.13;1.4;1.25;1.35
|
||||||
|
uk:GB94_Centurion_Mk5-1_RAAC;1.3;1.12;1.5;1.28;1.35
|
||||||
|
uk:GB97_Chimera;1.3;1.15;1.5;1.32;1.35
|
||||||
|
uk:GB99_Turtle_Mk1;1.4;1.18;1.4;1.22;1.35
|
||||||
|
uk:GB_Centurion_MkDF;1.3;1.12;1.5;1.29;1.35
|
||||||
|
uk:GB_Churchill_MkVI;2.1;1.73;1.4;1.54;1.77
|
||||||
|
uk:GB_Churchill_MkVIII;2.1;1.64;1.4;1.56;1.79
|
||||||
|
uk:GB_FV301;1.4;1.07;1.5;1.25;1.35
|
||||||
|
uk:GB_Sherman_V;2.6;2.28;1.7;1.96;2.11
|
||||||
|
uk:GB_Vickers_Cruiser;1.1;1;1.5;1.11;1.2
|
||||||
|
uk:Sentinel_AC1;3;2.88;1.9;2.55;3.47
|
||||||
|
usa:A05_M4_105BD;2.7;2.4;1.7;1.96;2.12
|
||||||
|
usa:A100_T49;1.4;1.53;1.5;1.29;1.34
|
||||||
|
usa:A102_T28_concept;1.7;1.47;1.4;1.27;1.62
|
||||||
|
usa:A104_M4A3E8A;1.9;1.88;1.5;1.54;1.84
|
||||||
|
usa:A111_T25_Pilot;1.3;1.27;1.5;1.26;1.35
|
||||||
|
usa:A115_Chrysler_K;1.4;1.16;1.4;1.3;1.35
|
||||||
|
usa:A117_T26E5;1.4;1.15;1.4;1.27;1.35
|
||||||
|
usa:A121_T26E3;1.5;1.54;1.4;1.31;1.61
|
||||||
|
usa:A122_TS-5;1.4;1.15;1.4;1.23;1.35
|
||||||
|
usa:A124_T54E2;1.4;1.15;1.4;1.29;1.35
|
||||||
|
usa:A125_AEP_1;1.1;1.02;1.4;1.15;1.14
|
||||||
|
usa:A130_Super_Hellcat;1.7;1.51;1.4;1.24;1.6
|
||||||
|
usa:A132_T77;1.3;1.15;1.4;1.29;1.35
|
||||||
|
usa:A136_T42;1.5;1.54;1.4;1.29;1.61
|
||||||
|
usa:A140_ASTRON_REX_105;1.3;1.31;1.5;1.31;1.35
|
||||||
|
usa:A141_M-4-Y;1.4;1.16;1.4;1.27;1.35
|
||||||
|
usa:A142_Pawlack_Tank;2.1;1.68;1.4;1.58;1.85
|
||||||
|
usa:A146_TL_7_120;1.1;1.02;1.4;1.14;1.14
|
||||||
|
usa:A150_MBT_B;1.2;1.02;1.4;1.21;1.13
|
||||||
|
usa:A151_TS_60;1.3;1.14;1.4;1.06;1.15
|
||||||
|
usa:A175_ATAC;1.1;1.02;1.5;1.11;1.32
|
||||||
|
usa:A68_T28D;1.4;1.2;1.4;1.28;1.35
|
||||||
|
usa:A77_T6M;3;2.72;1.9;2.52;3.24
|
||||||
|
usa:A94_T37;1.9;1.73;1.6;1.55;2.21
|
||||||
|
usa:A99_T92E1;1.1;1.1;1.5;1.2;1.2
|
||||||
|
usa:M-3-Y;1.4;1.14;1.4;1.28;1.35
|
||||||
|
usa:M-3-Y-Midas;1.4;1.14;1.4;1.28;1.35
|
||||||
|
usa:M-5-Y;1.1;1.02;1.4;1.2;1.14
|
||||||
|
usa:M-7-Y;1.7;1.32;1.4;1.32;1.61
|
||||||
|
usa:M103;1.1;1.02;1.4;1.14;1.13
|
||||||
|
usa:M10_Wolverine;3.2;2.18;1.5;1.96;2.13
|
||||||
|
usa:M18E2BP;1.9;1.65;1.5;1.57;2.02
|
||||||
|
usa:M18_Hellcat;2.1;1.58;1.4;1.51;2.99
|
||||||
|
usa:M22_Locust;3.8;4.23;2.1;3;5.59
|
||||||
|
usa:M24_Chaffee;1.9;1.73;1.6;1.55;2.36
|
||||||
|
usa:M24_Chaffee_BP;1.9;1.73;1.6;1.55;2.36
|
||||||
|
usa:M2_lt;5.5;5.28;3.3;6.76;7.39
|
||||||
|
usa:M2_med;3.6;4.29;2.2;2.93;5.54
|
||||||
|
usa:M36_BP;2.1;1.58;1.4;1.53;1.85
|
||||||
|
usa:M36_Slagger;2.1;1.58;1.4;1.54;1.85
|
||||||
|
usa:M3_Grant;3;2.38;1.9;2.55;3.13
|
||||||
|
usa:M3_Stuart;4.4;4.29;2.7;4.23;5.89
|
||||||
|
usa:M41_Bulldog;1.6;1.49;1.5;1.25;1.61
|
||||||
|
usa:M46_CL;1.1;1.04;1.4;1.08;1.17
|
||||||
|
usa:M46_Patton;1.1;1.08;1.4;1.09;1.17
|
||||||
|
usa:M4A2E4;2.6;2.28;1.7;1.96;2.13
|
||||||
|
usa:M4A3E8_BP;1.9;1.88;1.5;1.55;1.84
|
||||||
|
usa:M4A3E8_Sherman;1.9;1.88;1.5;1.55;1.84
|
||||||
|
usa:M4_Sherman;2.7;1.98;1.7;1.95;2.12
|
||||||
|
usa:M5_Stuart;3.7;3.48;2.1;2.94;5.57
|
||||||
|
usa:M6;2.1;1.6;1.4;1.58;1.8
|
||||||
|
usa:M6A2E1;1.6;1.32;1.4;1.33;1.62
|
||||||
|
usa:M6A2E1_exp;1.4;1.07;1.4;1.33;1.35
|
||||||
|
usa:M6E2BP;2.1;1.6;1.4;1.57;1.77
|
||||||
|
usa:M6E2V2_BP;2.1;1.64;1.4;1.53;1.78
|
||||||
|
usa:M7_med;3.1;2.38;1.9;2.54;2.98
|
||||||
|
usa:M8A1;4;2.73;1.8;2.54;2.87
|
||||||
|
usa:Pershing;1.3;1.33;1.5;1.25;1.35
|
||||||
|
usa:Ram-II;2.5;2.22;1.7;1.97;2.12
|
||||||
|
usa:Sherman_Jumbo;1.9;1.88;1.5;1.56;1.8
|
||||||
|
usa:T14;3.2;2.35;1.5;1.97;2.13
|
||||||
|
usa:T18;5.5;4.48;2.2;4.43;5.65
|
||||||
|
usa:T1_E6;4.4;5;2.7;4.12;8.54
|
||||||
|
usa:T1_hvy;3.3;2;1.5;1.96;2.13
|
||||||
|
usa:T20;1.5;1.54;1.4;1.28;1.61
|
||||||
|
usa:T21;1.9;1.81;1.6;1.57;2.27
|
||||||
|
usa:T21_BP;1.9;1.81;1.6;1.56;2.24
|
||||||
|
usa:T23E3;1.5;1.54;1.4;1.25;1.61
|
||||||
|
usa:T25_2;1.7;1.4;1.4;1.23;1.61
|
||||||
|
usa:T25_AT;1.7;1.44;1.4;1.26;1.61
|
||||||
|
usa:T26_E4_SuperPershing;1.3;1.2;1.5;1.29;1.35
|
||||||
|
usa:T28;1.4;1.16;1.4;1.23;1.35
|
||||||
|
usa:T28_Prototype;1.4;1.16;1.4;1.24;1.35
|
||||||
|
usa:T29;1.7;1.32;1.4;1.31;1.61
|
||||||
|
usa:T2_lt;4.3;5.45;2.7;3.9;8.26
|
||||||
|
usa:T2_med;4.6;5;2.5;4.23;7.11
|
||||||
|
usa:T30;1.1;1.05;1.4;1.12;1.17
|
||||||
|
usa:T32;1.4;1.16;1.4;1.29;1.35
|
||||||
|
usa:T34_hvy;1.3;1.07;1.4;1.3;1.35
|
||||||
|
usa:T34_hvy_Freedom;1.4;1.07;1.4;1.31;1.35
|
||||||
|
usa:T40;4;2.38;1.8;2.54;3.13
|
||||||
|
usa:T49;3.2;2.18;1.5;1.97;2.08
|
||||||
|
usa:T49_Fearless;1.4;1.53;1.5;1.28;1.34
|
||||||
|
usa:T54E1;1.1;1.06;1.4;1.1;1.16
|
||||||
|
usa:T69;1.3;1.33;1.5;1.27;1.35
|
||||||
|
usa:T71;1.6;1.49;1.5;1.27;1.6
|
||||||
|
usa:T7_Combat_Car;4.4;5.58;2.7;4.26;8.54
|
||||||
|
usa:T82;4.1;13.5;1.9;2.78;5.78
|
||||||
|
usa:T95;1.2;1.05;1.4;1.11;1.12
|
||||||
|
usa:T95E2;1.3;1.33;1.5;1.25;1.35
|
||||||
|
ussr:A-20;3.1;2.72;1.9;2.54;3
|
||||||
|
ussr:A-32;3;2.85;1.9;2.52;3.43
|
||||||
|
ussr:AT-1;5.5;3.99;2.2;3.99;8.51
|
||||||
|
ussr:BT-2;4.3;4.71;2.7;4.18;6.52
|
||||||
|
ussr:BT-7;3.6;2.98;2.1;3.06;5.51
|
||||||
|
ussr:BT-SV;3.8;2.86;2.1;3.16;5.58
|
||||||
|
ussr:Churchill_LL;3.2;2.27;1.5;1.97;2.13
|
||||||
|
ussr:GAZ-74b;4;2.48;1.8;2.53;3.05
|
||||||
|
ussr:IS;1.6;1.44;1.4;1.32;1.62
|
||||||
|
ussr:IS-2Sh;1.4;1.15;1.4;1.31;1.35
|
||||||
|
ussr:IS-3;1.4;1.16;1.4;1.3;1.35
|
||||||
|
ussr:IS8;1.2;1.02;1.4;1.12;1.15
|
||||||
|
ussr:ISU-152;1.6;1.13;1.4;1.38;1.35
|
||||||
|
ussr:K-91;1.1;1.02;1.4;1.1;1.12
|
||||||
|
ussr:KV-13;1.5;1.67;1.4;1.26;1.61
|
||||||
|
ussr:KV-1s;2.3;1.6;1.4;1.6;1.82
|
||||||
|
ussr:KV-1s-BP;2.3;1.5;1.4;1.64;1.83
|
||||||
|
ussr:KV-220;3.2;2.27;1.5;1.96;2.13
|
||||||
|
ussr:KV-3;1.7;1.44;1.4;1.33;1.62
|
||||||
|
ussr:KV-5;1.5;1.15;1.4;1.29;1.35
|
||||||
|
ussr:KV1;3.2;2.11;1.5;1.95;2.13
|
||||||
|
ussr:KV2;2.4;2.25;1.4;1.52;1.85
|
||||||
|
ussr:KV4;1.4;1.13;1.4;1.3;1.35
|
||||||
|
ussr:LTP;3.8;2.88;2.1;3.16;5.56
|
||||||
|
ussr:M3_Stuart_LL;3.7;5.04;2.1;2.86;5.51
|
||||||
|
ussr:MS-1obr21;4.3;4.71;2.7;4.18;6.98
|
||||||
|
ussr:MT25;2;1.79;1.6;1.56;2.06
|
||||||
|
ussr:Matilda_II_LL;2.5;2.22;1.7;1.96;2.12
|
||||||
|
ussr:Object252;1.4;1.14;1.4;1.33;1.35
|
||||||
|
ussr:Object252_Fearless;1.4;1.41;1.4;1.33;1.35
|
||||||
|
ussr:Object_704;1.1;1.05;1.4;1.1;1.13
|
||||||
|
ussr:R105_BT_7A;3.8;6.27;2.1;3.86;5.64
|
||||||
|
ussr:R107_LTB;1.6;1.56;1.5;1.28;1.61
|
||||||
|
ussr:R109_T54S;1.4;1.34;1.5;1.29;1.34
|
||||||
|
ussr:R111_ISU130;1.5;1.16;1.4;1.23;1.35
|
||||||
|
ussr:R112_T54_45;1.3;1.37;1.5;1.31;1.35
|
||||||
|
ussr:R113_Object_730;1.4;1.15;1.4;1.31;1.35
|
||||||
|
ussr:R115_IS-3_auto;1.4;1.15;1.4;1.3;1.35
|
||||||
|
ussr:R116_ISU122C_Berlin;1.8;1.45;1.4;1.22;1.62
|
||||||
|
ussr:R127_T44_100_P;1.3;1.33;1.5;1.27;1.35
|
||||||
|
ussr:R131_LTG;1.6;1.61;1.5;1.28;1.61
|
||||||
|
ussr:R134_Object_252U;1.4;1.14;1.4;1.33;1.35
|
||||||
|
ussr:R140_M4A2_Loza;1.9;1.88;1.5;1.55;1.84
|
||||||
|
ussr:R146_STG;1.3;1.33;1.5;1.33;1.35
|
||||||
|
ussr:R154_T-34E-43;2.6;2.22;1.7;1.96;2.11
|
||||||
|
ussr:R158_LT_432;1.4;1.34;1.5;1.28;1.34
|
||||||
|
ussr:R159_SU_130PM;1.6;1.16;1.4;1.26;1.34
|
||||||
|
ussr:R160_object_244;2.1;1.71;1.4;1.55;1.82
|
||||||
|
ussr:R172_Object_752;1.1;1.02;1.4;1.13;1.13
|
||||||
|
ussr:R175_IS_2E;1.6;1.47;1.4;1.31;1.61
|
||||||
|
ussr:R180_Object_274A;1.3;1.31;1.5;1.3;1.35
|
||||||
|
ussr:R181_Object_452K;1.2;1.02;1.4;1.15;1.13
|
||||||
|
ussr:R187_Object_590;1.3;1.32;1.5;1.29;1.35
|
||||||
|
ussr:R192_K_2;1.4;1.12;1.4;1.33;1.35
|
||||||
|
ussr:R194_ST_62_var_2;1.3;1.31;1.5;1.28;1.35
|
||||||
|
ussr:R217_Object_Kust;1.5;1.16;1.4;1.27;1.35
|
||||||
|
ussr:R43_T-70_57;3.8;3.41;2.1;3.43;5.49
|
||||||
|
ussr:R63_ST_IBD;1.2;1.02;1.4;1.17;1.14
|
||||||
|
ussr:R71_IS_2B;1.6;1.44;1.4;1.33;1.61
|
||||||
|
ussr:R98_T44_85;1.5;1.64;1.4;1.26;1.61
|
||||||
|
ussr:R_Object_84;1.1;1.07;1.5;1.12;1.17
|
||||||
|
ussr:ST_I;1.2;1.02;1.4;1.16;1.13
|
||||||
|
ussr:SU-100;2.1;1.57;1.4;1.55;1.81
|
||||||
|
ussr:SU-101;1.5;1.15;1.4;1.26;1.35
|
||||||
|
ussr:SU-152;1.8;2;1.4;1.38;1.61
|
||||||
|
ussr:SU-76;4.2;3.6;1.9;3.18;5.56
|
||||||
|
ussr:SU-85;3.2;1.99;1.5;1.97;2.12
|
||||||
|
ussr:SU100M1;1.7;1.35;1.4;1.25;1.61
|
||||||
|
ussr:SU100Y;2.1;1.53;1.4;1.57;1.89
|
||||||
|
ussr:SU122_44;1.8;1.45;1.4;1.25;1.61
|
||||||
|
ussr:SU122_54;1.2;1.05;1.4;1.03;1.14
|
||||||
|
ussr:SU76I;4.1;3.31;1.9;3.18;5.47
|
||||||
|
ussr:SU_85I;3.1;2.3;1.5;1.98;2.12
|
||||||
|
ussr:T-127;3.8;2.76;2.1;3.16;5.52
|
||||||
|
ussr:T-26;5.5;5.07;3.3;6.16;8.2
|
||||||
|
ussr:T-28;3;2.85;1.9;2.54;3.09
|
||||||
|
ussr:T-34;2.7;2.01;1.7;1.96;2.12
|
||||||
|
ussr:T-34-85;1.9;1.71;1.5;1.58;1.87
|
||||||
|
ussr:T-34-85_Rudy;1.5;1.67;1.4;1.26;1.61
|
||||||
|
ussr:T-34-85_Victory;1.9;1.88;1.5;1.57;1.87
|
||||||
|
ussr:T-43;1.5;1.6;1.4;1.25;1.61
|
||||||
|
ussr:T-44;1.3;1.33;1.5;1.34;1.35
|
||||||
|
ussr:T-46;3.8;4.32;2.1;2.83;5.6
|
||||||
|
ussr:T-54;1.1;1.1;1.4;1.09;1.16
|
||||||
|
ussr:T150;2.1;1.55;1.4;1.59;1.82
|
||||||
|
ussr:T34_85BP;1.9;1.88;1.5;1.57;1.87
|
||||||
|
ussr:T34_85TUR;1.5;1.58;1.4;1.29;1.62
|
||||||
|
ussr:Tetrarch_LL;4.3;3.88;2.7;3.88;8.51
|
||||||
|
ussr:Valentine_LL;2.9;4.55;1.9;2.55;3.42
|
||||||
|
@@ -11,6 +11,7 @@ import { Html } from "@react-three/drei";
|
|||||||
import { useRef } from "react";
|
import { useRef } from "react";
|
||||||
import { radToDeg } from "three/src/math/MathUtils.js";
|
import { radToDeg } from "three/src/math/MathUtils.js";
|
||||||
import { resolveArmorIndex } from "../../../core/blitzkit/resolveArmorIndex";
|
import { resolveArmorIndex } from "../../../core/blitzkit/resolveArmorIndex";
|
||||||
|
import { LocaleProvider, useLocale } from "../../../hooks/useLocale";
|
||||||
import { App } from "../../../stores/app";
|
import { App } from "../../../stores/app";
|
||||||
import { Duel } from "../../../stores/duel";
|
import { Duel } from "../../../stores/duel";
|
||||||
import { Tankopedia } from "../../../stores/tankopedia";
|
import { Tankopedia } from "../../../stores/tankopedia";
|
||||||
@@ -21,6 +22,7 @@ export function ArmorPlateDisplay() {
|
|||||||
const highlightArmor = Tankopedia.use((state) => state.highlightArmor);
|
const highlightArmor = Tankopedia.use((state) => state.highlightArmor);
|
||||||
const developerMode = App.useDeferred((state) => state.developerMode, false);
|
const developerMode = App.useDeferred((state) => state.developerMode, false);
|
||||||
const input = useRef<HTMLInputElement>(null);
|
const input = useRef<HTMLInputElement>(null);
|
||||||
|
const { locale } = useLocale();
|
||||||
|
|
||||||
if (highlightArmor === undefined) return null;
|
if (highlightArmor === undefined) return null;
|
||||||
|
|
||||||
@@ -30,154 +32,164 @@ export function ArmorPlateDisplay() {
|
|||||||
center
|
center
|
||||||
style={{ pointerEvents: highlightArmor.editingPlate ? "auto" : "none" }}
|
style={{ pointerEvents: highlightArmor.editingPlate ? "auto" : "none" }}
|
||||||
>
|
>
|
||||||
<Card
|
<LocaleProvider locale={locale}>
|
||||||
variant="classic"
|
<Card
|
||||||
mb="4"
|
variant="classic"
|
||||||
style={{
|
mb="4"
|
||||||
whiteSpace: "nowrap",
|
style={{
|
||||||
color: highlightArmor.color,
|
whiteSpace: "nowrap",
|
||||||
transform: "translateY(-50%)",
|
color: highlightArmor.color,
|
||||||
}}
|
transform: "translateY(-50%)",
|
||||||
>
|
}}
|
||||||
<Flex direction="column">
|
>
|
||||||
<Text weight="bold">
|
<Flex direction="column">
|
||||||
{layerTypeNames[highlightArmor.type]}{" "}
|
<Text weight="bold">
|
||||||
{highlightArmor.thickness.toFixed(0)}
|
{layerTypeNames[highlightArmor.type]}{" "}
|
||||||
<Text size="1" weight="regular">
|
{highlightArmor.thickness.toFixed(0)}
|
||||||
mm
|
<Text size="1" weight="regular">
|
||||||
</Text>
|
mm
|
||||||
</Text>
|
|
||||||
|
|
||||||
{highlightArmor.type !== ArmorType.External && (
|
|
||||||
<Text size="2" color="gray">
|
|
||||||
{highlightArmor.thicknessAngled.toFixed(0)}
|
|
||||||
<Text size="1">
|
|
||||||
mm {radToDeg(highlightArmor.angle).toFixed(0)}°
|
|
||||||
</Text>
|
</Text>
|
||||||
</Text>
|
</Text>
|
||||||
)}
|
|
||||||
|
|
||||||
{developerMode && (
|
{highlightArmor.type !== ArmorType.External && (
|
||||||
<>
|
<Text size="2" color="gray">
|
||||||
<Text mt="2" color="gray" size="2">
|
{highlightArmor.thicknessAngled.toFixed(0)}
|
||||||
<b>DEV:</b> <Code>{highlightArmor.name}</Code>
|
<Text size="1">
|
||||||
|
mm {radToDeg(highlightArmor.angle).toFixed(0)}°
|
||||||
|
</Text>
|
||||||
</Text>
|
</Text>
|
||||||
</>
|
)}
|
||||||
)}
|
|
||||||
|
|
||||||
{highlightArmor.editingPlate && (
|
{developerMode && (
|
||||||
<Flex gap="2" align="center">
|
<>
|
||||||
<TextField.Root
|
<Text mt="2" color="gray" size="2">
|
||||||
variant="classic"
|
<b>DEV:</b>{" "}
|
||||||
style={{ width: 96 }}
|
<Code variant="soft" highContrast color="gray">
|
||||||
mt="2"
|
{highlightArmor.name}
|
||||||
ref={input}
|
</Code>
|
||||||
key={highlightArmor.name}
|
</Text>
|
||||||
type="number"
|
</>
|
||||||
autoFocus
|
)}
|
||||||
onFocus={(event) => event.target.select()}
|
|
||||||
onKeyDown={(event) => {
|
|
||||||
if (!highlightArmor.editingPlate) return;
|
|
||||||
|
|
||||||
const index = resolveArmorIndex(highlightArmor.name);
|
{highlightArmor.editingPlate && (
|
||||||
|
<Flex gap="2" align="center">
|
||||||
if (index === undefined) return;
|
<TextField.Root
|
||||||
|
variant="classic"
|
||||||
const thickness = event.currentTarget.valueAsNumber;
|
style={{ width: 96 }}
|
||||||
|
mt="2"
|
||||||
if (isNaN(thickness) || thickness < 0) return;
|
ref={input}
|
||||||
|
key={highlightArmor.name}
|
||||||
if (event.key === "Enter") {
|
type="number"
|
||||||
input.current?.blur();
|
autoFocus
|
||||||
|
onFocus={(event) => event.target.select()}
|
||||||
Tankopedia.mutate((draft) => {
|
onKeyDown={(event) => {
|
||||||
draft.highlightArmor = undefined;
|
|
||||||
const { protagonist } = Duel.state;
|
|
||||||
const tank = draft.model;
|
|
||||||
const turret = tank.turrets[protagonist.turret.id];
|
|
||||||
const gun = turret.guns[protagonist.gun.id];
|
|
||||||
const track = tank.tracks[protagonist.track.id];
|
|
||||||
|
|
||||||
if (highlightArmor.name.startsWith("hull_")) {
|
|
||||||
tank.armor.thickness[index] = thickness;
|
|
||||||
} else if (highlightArmor.name.startsWith("turret_")) {
|
|
||||||
turret.armor.thickness[index] = thickness;
|
|
||||||
} else if (highlightArmor.name.startsWith("gun_")) {
|
|
||||||
if (highlightArmor.name.includes("_armor_")) {
|
|
||||||
gun.armor.thickness[index] = thickness;
|
|
||||||
} else {
|
|
||||||
gun.thickness = thickness;
|
|
||||||
}
|
|
||||||
} else if (highlightArmor.name.startsWith("chassis_")) {
|
|
||||||
track.thickness = thickness;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
} else if (event.key === "Escape") {
|
|
||||||
input.current?.blur();
|
|
||||||
Tankopedia.mutate((draft) => {
|
|
||||||
draft.highlightArmor = undefined;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}}
|
|
||||||
onClick={(event) => {
|
|
||||||
event.stopPropagation();
|
|
||||||
event.preventDefault();
|
|
||||||
}}
|
|
||||||
defaultValue={highlightArmor.thickness.toFixed(0)}
|
|
||||||
>
|
|
||||||
<TextField.Slot side="right">mm</TextField.Slot>
|
|
||||||
</TextField.Root>
|
|
||||||
|
|
||||||
<IconButton
|
|
||||||
mt="2"
|
|
||||||
color="red"
|
|
||||||
onClick={() => {
|
|
||||||
Tankopedia.mutate((draft) => {
|
|
||||||
if (!highlightArmor.editingPlate) return;
|
if (!highlightArmor.editingPlate) return;
|
||||||
|
|
||||||
const index = resolveArmorIndex(highlightArmor.name);
|
const index = resolveArmorIndex(highlightArmor.name);
|
||||||
|
|
||||||
if (index === undefined) return;
|
if (index === undefined) return;
|
||||||
|
|
||||||
draft.highlightArmor = undefined;
|
const thickness = event.currentTarget.valueAsNumber;
|
||||||
const initialState = Tankopedia.initial;
|
|
||||||
const { protagonist } = Duel.state;
|
|
||||||
const tank = draft.model;
|
|
||||||
const initialTank = initialState.model;
|
|
||||||
const turret = tank.turrets[protagonist.turret.id];
|
|
||||||
const initialTurret =
|
|
||||||
initialTank.turrets[protagonist.turret.id];
|
|
||||||
const gun = turret.guns[protagonist.gun.id];
|
|
||||||
const initialGun = initialTurret.guns[protagonist.gun.id];
|
|
||||||
const track = tank.tracks[protagonist.track.id];
|
|
||||||
const initialTrack =
|
|
||||||
initialTank.tracks[protagonist.track.id];
|
|
||||||
|
|
||||||
if (highlightArmor.name.startsWith("hull_")) {
|
if (isNaN(thickness) || thickness < 0) return;
|
||||||
tank.armor.thickness[index] =
|
|
||||||
initialTank.armor.thickness[index];
|
if (event.key === "Enter") {
|
||||||
} else if (highlightArmor.name.startsWith("turret_")) {
|
input.current?.blur();
|
||||||
turret.armor.thickness[index] =
|
|
||||||
initialTurret.armor.thickness[index];
|
Tankopedia.mutate((draft) => {
|
||||||
} else if (highlightArmor.name.startsWith("gun_")) {
|
draft.highlightArmor = undefined;
|
||||||
if (highlightArmor.name.includes("_armor_")) {
|
const { protagonist } = Duel.state;
|
||||||
gun.armor.thickness[index] =
|
const tank = draft.model;
|
||||||
initialGun.armor.thickness[index];
|
const turret = tank.turrets[protagonist.turret.id];
|
||||||
} else {
|
const gun = turret.guns[protagonist.gun.id];
|
||||||
gun.thickness = initialGun.thickness;
|
const track = tank.tracks[protagonist.track.id];
|
||||||
}
|
|
||||||
} else if (highlightArmor.name.startsWith("chassis_")) {
|
if (highlightArmor.name.startsWith("hull_")) {
|
||||||
track.thickness = initialTrack.thickness;
|
tank.armor!.thickness[index] = thickness;
|
||||||
|
} else if (
|
||||||
|
highlightArmor.name.startsWith("turret_")
|
||||||
|
) {
|
||||||
|
turret.armor!.thickness[index] = thickness;
|
||||||
|
} else if (highlightArmor.name.startsWith("gun_")) {
|
||||||
|
if (highlightArmor.name.includes("_armor_")) {
|
||||||
|
gun.armor!.thickness[index] = thickness;
|
||||||
|
} else {
|
||||||
|
gun.thickness = thickness;
|
||||||
|
}
|
||||||
|
} else if (
|
||||||
|
highlightArmor.name.startsWith("chassis_")
|
||||||
|
) {
|
||||||
|
track.thickness = thickness;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} else if (event.key === "Escape") {
|
||||||
|
input.current?.blur();
|
||||||
|
Tankopedia.mutate((draft) => {
|
||||||
|
draft.highlightArmor = undefined;
|
||||||
|
});
|
||||||
}
|
}
|
||||||
});
|
}}
|
||||||
}}
|
onClick={(event) => {
|
||||||
>
|
event.stopPropagation();
|
||||||
<ReloadIcon />
|
event.preventDefault();
|
||||||
</IconButton>
|
}}
|
||||||
</Flex>
|
defaultValue={highlightArmor.thickness.toFixed(0)}
|
||||||
)}
|
>
|
||||||
</Flex>
|
<TextField.Slot side="right">mm</TextField.Slot>
|
||||||
</Card>
|
</TextField.Root>
|
||||||
|
|
||||||
|
<IconButton
|
||||||
|
mt="2"
|
||||||
|
color="red"
|
||||||
|
onClick={() => {
|
||||||
|
Tankopedia.mutate((draft) => {
|
||||||
|
if (!highlightArmor.editingPlate) return;
|
||||||
|
|
||||||
|
const index = resolveArmorIndex(highlightArmor.name);
|
||||||
|
|
||||||
|
if (index === undefined) return;
|
||||||
|
|
||||||
|
draft.highlightArmor = undefined;
|
||||||
|
const initialState = Tankopedia.initial;
|
||||||
|
const { protagonist } = Duel.state;
|
||||||
|
const tank = draft.model;
|
||||||
|
const initialTank = initialState.model;
|
||||||
|
const turret = tank.turrets[protagonist.turret.id];
|
||||||
|
const initialTurret =
|
||||||
|
initialTank.turrets[protagonist.turret.id];
|
||||||
|
const gun = turret.guns[protagonist.gun.id];
|
||||||
|
const initialGun =
|
||||||
|
initialTurret.guns[protagonist.gun.id];
|
||||||
|
const track = tank.tracks[protagonist.track.id];
|
||||||
|
const initialTrack =
|
||||||
|
initialTank.tracks[protagonist.track.id];
|
||||||
|
|
||||||
|
if (highlightArmor.name.startsWith("hull_")) {
|
||||||
|
tank.armor!.thickness[index] =
|
||||||
|
initialTank.armor!.thickness[index];
|
||||||
|
} else if (highlightArmor.name.startsWith("turret_")) {
|
||||||
|
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];
|
||||||
|
} else {
|
||||||
|
gun.thickness = initialGun.thickness;
|
||||||
|
}
|
||||||
|
} else if (highlightArmor.name.startsWith("chassis_")) {
|
||||||
|
track.thickness = initialTrack.thickness;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<ReloadIcon />
|
||||||
|
</IconButton>
|
||||||
|
</Flex>
|
||||||
|
)}
|
||||||
|
</Flex>
|
||||||
|
</Card>
|
||||||
|
</LocaleProvider>
|
||||||
</Html>
|
</Html>
|
||||||
</group>
|
</group>
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -24,11 +24,11 @@ export const PrimaryArmorScene = memo(() => {
|
|||||||
const trackModelDefinition = tankModelDefinition.tracks[track.id];
|
const trackModelDefinition = tankModelDefinition.tracks[track.id];
|
||||||
const turretModelDefinition = tankModelDefinition.turrets[turret.id];
|
const turretModelDefinition = tankModelDefinition.turrets[turret.id];
|
||||||
const gunModelDefinition = turretModelDefinition.guns[gun.id];
|
const gunModelDefinition = turretModelDefinition.guns[gun.id];
|
||||||
const hullOrigin = correctZYTuple(trackModelDefinition.origin);
|
const hullOrigin = correctZYTuple(trackModelDefinition.origin!);
|
||||||
const turretOrigin = correctZYTuple(tankModelDefinition.turret_origin);
|
const turretOrigin = correctZYTuple(tankModelDefinition.turret_origin!);
|
||||||
const gunOrigin = correctZYTuple(turretModelDefinition.gun_origin);
|
const gunOrigin = correctZYTuple(turretModelDefinition.gun_origin!);
|
||||||
const isDynamicArmorActive = Duel.use((state) =>
|
const isDynamicArmorActive = Duel.use((state) =>
|
||||||
state.protagonist.consumables.includes(73)
|
state.protagonist.consumables.includes(73),
|
||||||
);
|
);
|
||||||
|
|
||||||
useTankTransform(track, turret, turretContainer, gunContainer);
|
useTankTransform(track, turret, turretContainer, gunContainer);
|
||||||
@@ -41,8 +41,8 @@ export const PrimaryArmorScene = memo(() => {
|
|||||||
const isVisible = isHull;
|
const isVisible = isHull;
|
||||||
const armorId = nameToArmorId(node.name);
|
const armorId = nameToArmorId(node.name);
|
||||||
const { spaced, thickness } = resolveArmor(
|
const { spaced, thickness } = resolveArmor(
|
||||||
tankModelDefinition.armor,
|
tankModelDefinition.armor!,
|
||||||
armorId
|
armorId,
|
||||||
);
|
);
|
||||||
|
|
||||||
if (
|
if (
|
||||||
@@ -69,13 +69,13 @@ export const PrimaryArmorScene = memo(() => {
|
|||||||
const isCurrentTurret = node.name.startsWith(
|
const isCurrentTurret = node.name.startsWith(
|
||||||
`turret_${turretModelDefinition.model_id
|
`turret_${turretModelDefinition.model_id
|
||||||
.toString()
|
.toString()
|
||||||
.padStart(2, "0")}`
|
.padStart(2, "0")}`,
|
||||||
);
|
);
|
||||||
const isVisible = isCurrentTurret;
|
const isVisible = isCurrentTurret;
|
||||||
const armorId = nameToArmorId(node.name);
|
const armorId = nameToArmorId(node.name);
|
||||||
const { spaced, thickness } = resolveArmor(
|
const { spaced, thickness } = resolveArmor(
|
||||||
turretModelDefinition.armor,
|
turretModelDefinition.armor!,
|
||||||
armorId
|
armorId,
|
||||||
);
|
);
|
||||||
|
|
||||||
if (
|
if (
|
||||||
@@ -103,13 +103,13 @@ export const PrimaryArmorScene = memo(() => {
|
|||||||
<group ref={gunContainer}>
|
<group ref={gunContainer}>
|
||||||
{armorNodes.map((node) => {
|
{armorNodes.map((node) => {
|
||||||
const isCurrentGun = node.name.startsWith(
|
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 isVisible = isCurrentGun;
|
||||||
const armorId = nameToArmorId(node.name);
|
const armorId = nameToArmorId(node.name);
|
||||||
const { spaced, thickness } = resolveArmor(
|
const { spaced, thickness } = resolveArmor(
|
||||||
gunModelDefinition.armor,
|
gunModelDefinition.armor!,
|
||||||
armorId
|
armorId,
|
||||||
);
|
);
|
||||||
|
|
||||||
if (
|
if (
|
||||||
|
|||||||
+40
-34
@@ -19,7 +19,7 @@ import {
|
|||||||
import { degToRad } from "three/src/math/MathUtils.js";
|
import { degToRad } from "three/src/math/MathUtils.js";
|
||||||
import { hasEquipment } from "../../../../core/blitzkit/hasEquipment";
|
import { hasEquipment } from "../../../../core/blitzkit/hasEquipment";
|
||||||
import { jsxTree } from "../../../../core/blitzkit/jsxTree";
|
import { jsxTree } from "../../../../core/blitzkit/jsxTree";
|
||||||
import { Duel, type EquipmentMatrix } from "../../../../stores/duel";
|
import { Duel } from "../../../../stores/duel";
|
||||||
import { Tankopedia } from "../../../../stores/tankopedia";
|
import { Tankopedia } from "../../../../stores/tankopedia";
|
||||||
import { TankopediaPersistent } from "../../../../stores/tankopediaPersistent";
|
import { TankopediaPersistent } from "../../../../stores/tankopediaPersistent";
|
||||||
import { transitionEvent } from "../../../Tankopedia/HeroSection/components/TankSandbox/components/Lighting";
|
import { transitionEvent } from "../../../Tankopedia/HeroSection/components/TankSandbox/components/Lighting";
|
||||||
@@ -88,24 +88,18 @@ export function PrimaryArmorSceneComponent({
|
|||||||
|
|
||||||
material.uniforms.caliber.value = shell.caliber;
|
material.uniforms.caliber.value = shell.caliber;
|
||||||
material.uniforms.ricochet.value = degToRad(
|
material.uniforms.ricochet.value = degToRad(
|
||||||
isExplosive(shell.type) ? 90 : shell.ricochet!
|
isExplosive(shell.type) ? 90 : shell.ricochet!,
|
||||||
);
|
);
|
||||||
material.uniforms.normalization.value = degToRad(
|
material.uniforms.normalization.value = degToRad(
|
||||||
shell.normalization ?? 0
|
shell.normalization ?? 0,
|
||||||
);
|
);
|
||||||
material.uniforms.isExplosive.value = isExplosive(shell.type);
|
material.uniforms.isExplosive.value = isExplosive(shell.type);
|
||||||
material.uniforms.canSplash.value = canSplash(shell.type);
|
material.uniforms.canSplash.value = canSplash(shell.type);
|
||||||
material.uniforms.damage.value = shell.armor_damage;
|
material.uniforms.damage.value = shell.armor_damage;
|
||||||
material.uniforms.explosionRadius.value = shell.explosion_radius;
|
material.uniforms.explosionRadius.value = shell.explosion_radius;
|
||||||
|
|
||||||
handleProtagonistEquipmentChange(
|
handleProtagonistEquipmentChange(true);
|
||||||
Duel.state.protagonist.equipmentMatrix,
|
handleAntagonistEquipmentChange(true);
|
||||||
true
|
|
||||||
);
|
|
||||||
handleAntagonistEquipmentChange(
|
|
||||||
Duel.state.antagonist.equipmentMatrix,
|
|
||||||
true
|
|
||||||
);
|
|
||||||
|
|
||||||
invalidate();
|
invalidate();
|
||||||
}
|
}
|
||||||
@@ -122,38 +116,43 @@ export function PrimaryArmorSceneComponent({
|
|||||||
function handleWireframeChange(wireframe: boolean) {
|
function handleWireframeChange(wireframe: boolean) {
|
||||||
material.wireframe = wireframe;
|
material.wireframe = wireframe;
|
||||||
}
|
}
|
||||||
function handleProtagonistEquipmentChange(
|
function handleProtagonistEquipmentChange(noInvalidate = false) {
|
||||||
equipment: EquipmentMatrix,
|
const equipment = Duel.state.protagonist.equipmentMatrix;
|
||||||
noInvalidate = false
|
|
||||||
) {
|
|
||||||
const hasEnhancedArmor = hasEquipment(
|
const hasEnhancedArmor = hasEquipment(
|
||||||
110,
|
110,
|
||||||
Duel.state.protagonist.tank.equipment_preset,
|
Duel.state.protagonist.tank.equipment_preset,
|
||||||
equipment
|
equipment,
|
||||||
);
|
);
|
||||||
material.uniforms.thickness.value = hasEnhancedArmor
|
const equalizer =
|
||||||
? thickness * 1.03
|
(Duel.state.equalize
|
||||||
: thickness;
|
? Duel.state.protagonist.tank.equalizer?.armor
|
||||||
|
: undefined) ?? 1;
|
||||||
|
|
||||||
|
material.uniforms.thickness.value =
|
||||||
|
thickness * (hasEnhancedArmor ? 1.03 : 1) * equalizer;
|
||||||
|
|
||||||
if (!noInvalidate) invalidate();
|
if (!noInvalidate) invalidate();
|
||||||
}
|
}
|
||||||
function handleAntagonistEquipmentChange(
|
function handleAntagonistEquipmentChange(noInvalidate = false) {
|
||||||
equipment: EquipmentMatrix,
|
const equipment = Duel.state.antagonist.equipmentMatrix;
|
||||||
noInvalidate = false
|
|
||||||
) {
|
|
||||||
const tankopediaEphemeral = Tankopedia.state;
|
const tankopediaEphemeral = Tankopedia.state;
|
||||||
const shell =
|
const shell =
|
||||||
tankopediaEphemeral.customShell ?? Duel.state.antagonist.shell;
|
tankopediaEphemeral.customShell ?? Duel.state.antagonist.shell;
|
||||||
const penetration = shell.penetration.near;
|
const penetration = shell.penetration!.near;
|
||||||
const hasCalibratedShells = hasEquipment(
|
const hasCalibratedShells = hasEquipment(
|
||||||
103,
|
103,
|
||||||
Duel.state.antagonist.tank.equipment_preset,
|
Duel.state.antagonist.tank.equipment_preset,
|
||||||
equipment
|
equipment,
|
||||||
);
|
);
|
||||||
|
|
||||||
material.uniforms.penetration.value =
|
material.uniforms.penetration.value =
|
||||||
penetration *
|
penetration *
|
||||||
resolvePenetrationCoefficient(hasCalibratedShells, shell.type);
|
resolvePenetrationCoefficient(
|
||||||
|
hasCalibratedShells,
|
||||||
|
Duel.state.equalize,
|
||||||
|
shell.type,
|
||||||
|
Duel.state.antagonist.tank.equalizer,
|
||||||
|
);
|
||||||
|
|
||||||
if (!noInvalidate) invalidate();
|
if (!noInvalidate) invalidate();
|
||||||
}
|
}
|
||||||
@@ -165,12 +164,12 @@ export function PrimaryArmorSceneComponent({
|
|||||||
handleShellChange();
|
handleShellChange();
|
||||||
handleGreenPenetrationChange(TankopediaPersistent.state.greenPenetration);
|
handleGreenPenetrationChange(TankopediaPersistent.state.greenPenetration);
|
||||||
handleAdvancedHighlightingChange(
|
handleAdvancedHighlightingChange(
|
||||||
TankopediaPersistent.state.advancedHighlighting
|
TankopediaPersistent.state.advancedHighlighting,
|
||||||
);
|
);
|
||||||
handleOpaqueChange(TankopediaPersistent.state.opaque);
|
handleOpaqueChange(TankopediaPersistent.state.opaque);
|
||||||
handleWireframeChange(TankopediaPersistent.state.wireframe);
|
handleWireframeChange(TankopediaPersistent.state.wireframe);
|
||||||
handleProtagonistEquipmentChange(Duel.state.protagonist.equipmentMatrix);
|
handleProtagonistEquipmentChange();
|
||||||
handleAntagonistEquipmentChange(Duel.state.antagonist.equipmentMatrix);
|
handleAntagonistEquipmentChange();
|
||||||
|
|
||||||
transitionEvent.on(handleTransitionEvent);
|
transitionEvent.on(handleTransitionEvent);
|
||||||
|
|
||||||
@@ -179,20 +178,27 @@ export function PrimaryArmorSceneComponent({
|
|||||||
Tankopedia.on((state) => state.customShell, handleShellChange),
|
Tankopedia.on((state) => state.customShell, handleShellChange),
|
||||||
TankopediaPersistent.on(
|
TankopediaPersistent.on(
|
||||||
(state) => state.greenPenetration,
|
(state) => state.greenPenetration,
|
||||||
handleGreenPenetrationChange
|
handleGreenPenetrationChange,
|
||||||
),
|
),
|
||||||
TankopediaPersistent.on(
|
TankopediaPersistent.on(
|
||||||
(state) => state.advancedHighlighting,
|
(state) => state.advancedHighlighting,
|
||||||
handleAdvancedHighlightingChange
|
handleAdvancedHighlightingChange,
|
||||||
),
|
),
|
||||||
TankopediaPersistent.on((state) => state.opaque, handleOpaqueChange),
|
TankopediaPersistent.on((state) => state.opaque, handleOpaqueChange),
|
||||||
Duel.on(
|
Duel.on(
|
||||||
(state) => state.protagonist.equipmentMatrix,
|
(state) => state.protagonist.equipmentMatrix,
|
||||||
(equipment) => handleProtagonistEquipmentChange(equipment)
|
() => handleProtagonistEquipmentChange(),
|
||||||
),
|
),
|
||||||
Duel.on(
|
Duel.on(
|
||||||
(state) => state.antagonist.equipmentMatrix,
|
(state) => state.antagonist.equipmentMatrix,
|
||||||
(equipment) => handleAntagonistEquipmentChange(equipment)
|
() => handleAntagonistEquipmentChange(),
|
||||||
|
),
|
||||||
|
Duel.on(
|
||||||
|
(state) => state.equalize,
|
||||||
|
() => {
|
||||||
|
handleProtagonistEquipmentChange();
|
||||||
|
handleAntagonistEquipmentChange();
|
||||||
|
},
|
||||||
),
|
),
|
||||||
() => transitionEvent.off(handleTransitionEvent),
|
() => transitionEvent.off(handleTransitionEvent),
|
||||||
];
|
];
|
||||||
@@ -204,7 +210,7 @@ export function PrimaryArmorSceneComponent({
|
|||||||
|
|
||||||
useFrame(({ gl, camera }) => {
|
useFrame(({ gl, camera }) => {
|
||||||
gl.getSize(material.uniforms.resolution.value).multiplyScalar(
|
gl.getSize(material.uniforms.resolution.value).multiplyScalar(
|
||||||
gl.getPixelRatio()
|
gl.getPixelRatio(),
|
||||||
);
|
);
|
||||||
material.uniforms.spacedArmorBuffer.value = spacedArmorRenderTarget.texture;
|
material.uniforms.spacedArmorBuffer.value = spacedArmorRenderTarget.texture;
|
||||||
material.uniforms.spacedArmorDepth.value =
|
material.uniforms.spacedArmorDepth.value =
|
||||||
|
|||||||
@@ -52,7 +52,7 @@ export function ShotDisplay() {
|
|||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (shot?.splashRadius !== undefined) {
|
if (shot?.splashRadius !== undefined) {
|
||||||
const outlineGeometry = new BufferGeometry().setFromPoints(
|
const outlineGeometry = new BufferGeometry().setFromPoints(
|
||||||
new Path().absarc(0, 0, 1, 0, Math.PI * 2).getSpacedPoints(50)
|
new Path().absarc(0, 0, 1, 0, Math.PI * 2).getSpacedPoints(50),
|
||||||
);
|
);
|
||||||
const outlineMaterial = new LineDashedMaterial({
|
const outlineMaterial = new LineDashedMaterial({
|
||||||
color: "orange",
|
color: "orange",
|
||||||
@@ -61,7 +61,7 @@ export function ShotDisplay() {
|
|||||||
});
|
});
|
||||||
const outline = new Line(
|
const outline = new Line(
|
||||||
outlineGeometry,
|
outlineGeometry,
|
||||||
outlineMaterial
|
outlineMaterial,
|
||||||
).computeLineDistances();
|
).computeLineDistances();
|
||||||
|
|
||||||
splashRadiusWrapper.current?.add(outline);
|
splashRadiusWrapper.current?.add(outline);
|
||||||
@@ -134,11 +134,11 @@ export function ShotDisplay() {
|
|||||||
const outLength =
|
const outLength =
|
||||||
shot.out && shot.out.layers.length > 0
|
shot.out && shot.out.layers.length > 0
|
||||||
? (shot.in.layers.at(-1) as ShotLayerNonExternal).point.distanceTo(
|
? (shot.in.layers.at(-1) as ShotLayerNonExternal).point.distanceTo(
|
||||||
(shot.out.layers.at(-1) as ShotLayerNonExternal).point
|
(shot.out.layers.at(-1) as ShotLayerNonExternal).point,
|
||||||
)
|
)
|
||||||
: SHOT_DISPLAY_LENGTH_INFINITY;
|
: SHOT_DISPLAY_LENGTH_INFINITY;
|
||||||
const inLast = shot.in.layers.findLast(
|
const inLast = shot.in.layers.findLast(
|
||||||
(layer) => layer.type !== null
|
(layer) => layer.type !== null,
|
||||||
) as ShotLayerNonExternal;
|
) as ShotLayerNonExternal;
|
||||||
const outTitleColor = shot.out
|
const outTitleColor = shot.out
|
||||||
? shotStatusColors[shot.out.status]
|
? shotStatusColors[shot.out.status]
|
||||||
@@ -154,7 +154,7 @@ export function ShotDisplay() {
|
|||||||
position={inLast.point}
|
position={inLast.point}
|
||||||
ref={splashRadiusWrapper}
|
ref={splashRadiusWrapper}
|
||||||
rotation={new Euler().setFromQuaternion(
|
rotation={new Euler().setFromQuaternion(
|
||||||
new Quaternion().setFromUnitVectors(K_HAT, shot.in.surfaceNormal)
|
new Quaternion().setFromUnitVectors(K_HAT, shot.in.surfaceNormal),
|
||||||
)}
|
)}
|
||||||
>
|
>
|
||||||
<mesh>
|
<mesh>
|
||||||
@@ -225,7 +225,7 @@ export function ShotDisplay() {
|
|||||||
<group
|
<group
|
||||||
position={inLast.point}
|
position={inLast.point}
|
||||||
rotation={new Euler().setFromQuaternion(
|
rotation={new Euler().setFromQuaternion(
|
||||||
new Quaternion().setFromUnitVectors(J_HAT, shot.in.surfaceNormal)
|
new Quaternion().setFromUnitVectors(J_HAT, shot.in.surfaceNormal),
|
||||||
)}
|
)}
|
||||||
>
|
>
|
||||||
<mesh position={[0, inLength / 2, 0]} renderOrder={2}>
|
<mesh position={[0, inLength / 2, 0]} renderOrder={2}>
|
||||||
@@ -253,8 +253,8 @@ export function ShotDisplay() {
|
|||||||
rotation={new Euler().setFromQuaternion(
|
rotation={new Euler().setFromQuaternion(
|
||||||
new Quaternion().setFromUnitVectors(
|
new Quaternion().setFromUnitVectors(
|
||||||
J_HAT,
|
J_HAT,
|
||||||
shot.out.surfaceNormal.clone()
|
shot.out.surfaceNormal.clone(),
|
||||||
)
|
),
|
||||||
)}
|
)}
|
||||||
>
|
>
|
||||||
<mesh position={[0, outLength / 2, 0]} renderOrder={2}>
|
<mesh position={[0, outLength / 2, 0]} renderOrder={2}>
|
||||||
|
|||||||
@@ -37,15 +37,15 @@ export const SpacedArmorScene = memo<SpacedArmorSceneProps>(({ scene }) => {
|
|||||||
const trackModelDefinition = tankModelDefinition.tracks[track.id];
|
const trackModelDefinition = tankModelDefinition.tracks[track.id];
|
||||||
const turretModelDefinition = tankModelDefinition.turrets[turret.id];
|
const turretModelDefinition = tankModelDefinition.turrets[turret.id];
|
||||||
const gunModelDefinition = turretModelDefinition.guns[gun.id];
|
const gunModelDefinition = turretModelDefinition.guns[gun.id];
|
||||||
const hullOrigin = correctZYTuple(trackModelDefinition.origin);
|
const hullOrigin = correctZYTuple(trackModelDefinition.origin!);
|
||||||
const turretOrigin = correctZYTuple(tankModelDefinition.turret_origin);
|
const turretOrigin = correctZYTuple(tankModelDefinition.turret_origin!);
|
||||||
const gunOrigin = correctZYTuple(turretModelDefinition.gun_origin);
|
const gunOrigin = correctZYTuple(turretModelDefinition.gun_origin!);
|
||||||
const maskOrigin =
|
const maskOrigin =
|
||||||
gunModelDefinition.mask === undefined
|
gunModelDefinition.mask === undefined
|
||||||
? undefined
|
? undefined
|
||||||
: gunModelDefinition.mask + hullOrigin.y + turretOrigin.y + gunOrigin.y;
|
: gunModelDefinition.mask + hullOrigin.y + turretOrigin.y + gunOrigin.y;
|
||||||
const isDynamicArmorActive = Duel.use((state) =>
|
const isDynamicArmorActive = Duel.use((state) =>
|
||||||
state.protagonist.consumables.includes(73)
|
state.protagonist.consumables.includes(73),
|
||||||
);
|
);
|
||||||
|
|
||||||
useTankTransform(track, turret, turretContainer, gunContainer);
|
useTankTransform(track, turret, turretContainer, gunContainer);
|
||||||
@@ -58,8 +58,8 @@ export const SpacedArmorScene = memo<SpacedArmorSceneProps>(({ scene }) => {
|
|||||||
const isVisible = isHull;
|
const isVisible = isHull;
|
||||||
const armorId = nameToArmorId(node.name);
|
const armorId = nameToArmorId(node.name);
|
||||||
const { spaced, thickness } = resolveArmor(
|
const { spaced, thickness } = resolveArmor(
|
||||||
tankModelDefinition.armor,
|
tankModelDefinition.armor!,
|
||||||
armorId
|
armorId,
|
||||||
);
|
);
|
||||||
|
|
||||||
if (
|
if (
|
||||||
@@ -104,13 +104,13 @@ export const SpacedArmorScene = memo<SpacedArmorSceneProps>(({ scene }) => {
|
|||||||
<group ref={turretContainer}>
|
<group ref={turretContainer}>
|
||||||
{armorNodes.map((node) => {
|
{armorNodes.map((node) => {
|
||||||
const isCurrentTurret = node.name.startsWith(
|
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 isVisible = isCurrentTurret;
|
||||||
const armorId = nameToArmorId(node.name);
|
const armorId = nameToArmorId(node.name);
|
||||||
const { spaced, thickness } = resolveArmor(
|
const { spaced, thickness } = resolveArmor(
|
||||||
turretModelDefinition.armor,
|
turretModelDefinition.armor!,
|
||||||
armorId
|
armorId,
|
||||||
);
|
);
|
||||||
|
|
||||||
if (
|
if (
|
||||||
@@ -139,13 +139,13 @@ export const SpacedArmorScene = memo<SpacedArmorSceneProps>(({ scene }) => {
|
|||||||
<group ref={gunContainer}>
|
<group ref={gunContainer}>
|
||||||
{armorNodes.map((node) => {
|
{armorNodes.map((node) => {
|
||||||
const isCurrentGun = node.name.startsWith(
|
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 isVisible = isCurrentGun;
|
||||||
const armorId = nameToArmorId(node.name);
|
const armorId = nameToArmorId(node.name);
|
||||||
const { spaced, thickness } = resolveArmor(
|
const { spaced, thickness } = resolveArmor(
|
||||||
gunModelDefinition.armor,
|
gunModelDefinition.armor!,
|
||||||
armorId
|
armorId,
|
||||||
);
|
);
|
||||||
|
|
||||||
if (
|
if (
|
||||||
|
|||||||
+38
-15
@@ -10,7 +10,7 @@ import {
|
|||||||
import type { ArmorUserData, ExternalModuleVariant } from "../..";
|
import type { ArmorUserData, ExternalModuleVariant } from "../..";
|
||||||
import { hasEquipment } from "../../../../../../core/blitzkit/hasEquipment";
|
import { hasEquipment } from "../../../../../../core/blitzkit/hasEquipment";
|
||||||
import { jsxTree } from "../../../../../../core/blitzkit/jsxTree";
|
import { jsxTree } from "../../../../../../core/blitzkit/jsxTree";
|
||||||
import { Duel, type EquipmentMatrix } from "../../../../../../stores/duel";
|
import { Duel } from "../../../../../../stores/duel";
|
||||||
import { Tankopedia } from "../../../../../../stores/tankopedia";
|
import { Tankopedia } from "../../../../../../stores/tankopedia";
|
||||||
import { ArmorType } from "../../../SpacedArmorScene";
|
import { ArmorType } from "../../../SpacedArmorScene";
|
||||||
import fragmentShader from "./shaders/fragment.glsl?raw";
|
import fragmentShader from "./shaders/fragment.glsl?raw";
|
||||||
@@ -50,48 +50,71 @@ export function SpacedArmorSubExternal({
|
|||||||
const tankopediaEphemeral = Tankopedia.state;
|
const tankopediaEphemeral = Tankopedia.state;
|
||||||
const shell =
|
const shell =
|
||||||
tankopediaEphemeral.customShell ?? Duel.state.antagonist.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) {
|
function handleProtagonistEquipmentChange() {
|
||||||
|
const equipment = Duel.state.protagonist.equipmentMatrix;
|
||||||
const hasEnhancedArmor = hasEquipment(
|
const hasEnhancedArmor = hasEquipment(
|
||||||
110,
|
110,
|
||||||
Duel.state.protagonist.tank.equipment_preset,
|
Duel.state.protagonist.tank.equipment_preset,
|
||||||
equipment
|
equipment,
|
||||||
);
|
);
|
||||||
material.uniforms.thickness.value = hasEnhancedArmor
|
const equalizer =
|
||||||
? thickness * 1.03
|
(Duel.state.equalize
|
||||||
: thickness;
|
? Duel.state.protagonist.tank.equalizer?.armor
|
||||||
|
: undefined) ?? 1;
|
||||||
|
|
||||||
|
material.uniforms.thickness.value =
|
||||||
|
thickness * (hasEnhancedArmor ? 1.03 : 1) * equalizer;
|
||||||
}
|
}
|
||||||
function handleAntagonistEquipmentChange(equipment: EquipmentMatrix) {
|
function handleAntagonistEquipmentChange() {
|
||||||
|
const equipment = Duel.state.antagonist.equipmentMatrix;
|
||||||
const tankopediaEphemeral = Tankopedia.state;
|
const tankopediaEphemeral = Tankopedia.state;
|
||||||
const shell =
|
const shell =
|
||||||
tankopediaEphemeral.customShell ?? Duel.state.antagonist.shell;
|
tankopediaEphemeral.customShell ?? Duel.state.antagonist.shell;
|
||||||
const penetration = shell.penetration.near;
|
const penetration = shell.penetration!.near;
|
||||||
const hasCalibratedShells = hasEquipment(
|
const hasCalibratedShells = hasEquipment(
|
||||||
103,
|
103,
|
||||||
Duel.state.antagonist.tank.equipment_preset,
|
Duel.state.antagonist.tank.equipment_preset,
|
||||||
equipment
|
equipment,
|
||||||
);
|
);
|
||||||
|
const equalize =
|
||||||
|
(Duel.state.equalize
|
||||||
|
? Duel.state.antagonist.tank.equalizer?.penetration
|
||||||
|
: undefined) ?? 1;
|
||||||
|
|
||||||
material.uniforms.penetration.value =
|
material.uniforms.penetration.value =
|
||||||
penetration *
|
penetration *
|
||||||
resolvePenetrationCoefficient(hasCalibratedShells, shell.type);
|
resolvePenetrationCoefficient(
|
||||||
|
hasCalibratedShells,
|
||||||
|
Duel.state.equalize,
|
||||||
|
shell.type,
|
||||||
|
Duel.state.antagonist.tank.equalizer,
|
||||||
|
) *
|
||||||
|
equalize;
|
||||||
}
|
}
|
||||||
|
|
||||||
handleShellChange();
|
handleShellChange();
|
||||||
handleProtagonistEquipmentChange(Duel.state.protagonist.equipmentMatrix);
|
handleProtagonistEquipmentChange();
|
||||||
handleAntagonistEquipmentChange(Duel.state.antagonist.equipmentMatrix);
|
handleAntagonistEquipmentChange();
|
||||||
|
|
||||||
const unsubscribes = [
|
const unsubscribes = [
|
||||||
Duel.on((state) => state.antagonist.shell, handleShellChange),
|
Duel.on((state) => state.antagonist.shell, handleShellChange),
|
||||||
Tankopedia.on((state) => state.customShell, handleShellChange),
|
Tankopedia.on((state) => state.customShell, handleShellChange),
|
||||||
Duel.on(
|
Duel.on(
|
||||||
(state) => state.protagonist.equipmentMatrix,
|
(state) => state.protagonist.equipmentMatrix,
|
||||||
handleProtagonistEquipmentChange
|
handleProtagonistEquipmentChange,
|
||||||
),
|
),
|
||||||
Duel.on(
|
Duel.on(
|
||||||
(state) => state.antagonist.equipmentMatrix,
|
(state) => state.antagonist.equipmentMatrix,
|
||||||
handleAntagonistEquipmentChange
|
handleAntagonistEquipmentChange,
|
||||||
|
),
|
||||||
|
Duel.on(
|
||||||
|
(state) => state.equalize,
|
||||||
|
() => {
|
||||||
|
handleProtagonistEquipmentChange();
|
||||||
|
handleAntagonistEquipmentChange();
|
||||||
|
},
|
||||||
),
|
),
|
||||||
];
|
];
|
||||||
|
|
||||||
|
|||||||
+40
-17
@@ -10,7 +10,7 @@ import { degToRad } from "three/src/math/MathUtils.js";
|
|||||||
import type { ArmorUserData } from "../..";
|
import type { ArmorUserData } from "../..";
|
||||||
import { hasEquipment } from "../../../../../../core/blitzkit/hasEquipment";
|
import { hasEquipment } from "../../../../../../core/blitzkit/hasEquipment";
|
||||||
import { jsxTree } from "../../../../../../core/blitzkit/jsxTree";
|
import { jsxTree } from "../../../../../../core/blitzkit/jsxTree";
|
||||||
import { Duel, type EquipmentMatrix } from "../../../../../../stores/duel";
|
import { Duel } from "../../../../../../stores/duel";
|
||||||
import { Tankopedia } from "../../../../../../stores/tankopedia";
|
import { Tankopedia } from "../../../../../../stores/tankopedia";
|
||||||
import { ArmorType } from "../../../SpacedArmorScene";
|
import { ArmorType } from "../../../SpacedArmorScene";
|
||||||
import fragmentShader from "./shaders/fragment.glsl?raw";
|
import fragmentShader from "./shaders/fragment.glsl?raw";
|
||||||
@@ -53,55 +53,78 @@ export function SpacedArmorSubSpaced({
|
|||||||
const shell =
|
const shell =
|
||||||
tankopediaEphemeral.customShell ?? Duel.state.antagonist.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.caliber.value = shell.caliber;
|
||||||
material.uniforms.ricochet.value = degToRad(
|
material.uniforms.ricochet.value = degToRad(
|
||||||
isExplosive(shell.type) ? 90 : shell.ricochet!
|
isExplosive(shell.type) ? 90 : shell.ricochet!,
|
||||||
);
|
);
|
||||||
material.uniforms.normalization.value = degToRad(
|
material.uniforms.normalization.value = degToRad(
|
||||||
shell.normalization ?? 0
|
shell.normalization ?? 0,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
function handleProtagonistEquipmentChange(equipment: EquipmentMatrix) {
|
function handleProtagonistEquipmentChange() {
|
||||||
|
const equipment = Duel.state.protagonist.equipmentMatrix;
|
||||||
const hasEnhancedArmor = hasEquipment(
|
const hasEnhancedArmor = hasEquipment(
|
||||||
110,
|
110,
|
||||||
Duel.state.protagonist.tank.equipment_preset,
|
Duel.state.protagonist.tank.equipment_preset,
|
||||||
equipment
|
equipment,
|
||||||
);
|
);
|
||||||
material.uniforms.thickness.value = hasEnhancedArmor
|
const equalizer =
|
||||||
? thickness * 1.03
|
(Duel.state.equalize
|
||||||
: thickness;
|
? Duel.state.protagonist.tank.equalizer?.armor
|
||||||
|
: undefined) ?? 1;
|
||||||
|
|
||||||
|
material.uniforms.thickness.value =
|
||||||
|
thickness * (hasEnhancedArmor ? 1.03 : 1) * equalizer;
|
||||||
}
|
}
|
||||||
function handleAntagonistEquipmentChange(equipment: EquipmentMatrix) {
|
function handleAntagonistEquipmentChange() {
|
||||||
|
const equipment = Duel.state.antagonist.equipmentMatrix;
|
||||||
const tankopediaEphemeral = Tankopedia.state;
|
const tankopediaEphemeral = Tankopedia.state;
|
||||||
const shell =
|
const shell =
|
||||||
tankopediaEphemeral.customShell ?? Duel.state.antagonist.shell;
|
tankopediaEphemeral.customShell ?? Duel.state.antagonist.shell;
|
||||||
const penetration = shell.penetration.near;
|
const penetration = shell.penetration!.near;
|
||||||
const hasCalibratedShells = hasEquipment(
|
const hasCalibratedShells = hasEquipment(
|
||||||
103,
|
103,
|
||||||
Duel.state.antagonist.tank.equipment_preset,
|
Duel.state.antagonist.tank.equipment_preset,
|
||||||
equipment
|
equipment,
|
||||||
);
|
);
|
||||||
|
const equalize =
|
||||||
|
(Duel.state.equalize
|
||||||
|
? Duel.state.antagonist.tank.equalizer?.penetration
|
||||||
|
: undefined) ?? 1;
|
||||||
|
|
||||||
material.uniforms.penetration.value =
|
material.uniforms.penetration.value =
|
||||||
penetration *
|
penetration *
|
||||||
resolvePenetrationCoefficient(hasCalibratedShells, shell.type);
|
resolvePenetrationCoefficient(
|
||||||
|
hasCalibratedShells,
|
||||||
|
Duel.state.equalize,
|
||||||
|
shell.type,
|
||||||
|
Duel.state.antagonist.tank.equalizer,
|
||||||
|
) *
|
||||||
|
equalize;
|
||||||
}
|
}
|
||||||
|
|
||||||
handleShellChange();
|
handleShellChange();
|
||||||
handleProtagonistEquipmentChange(Duel.state.protagonist.equipmentMatrix);
|
handleProtagonistEquipmentChange();
|
||||||
handleAntagonistEquipmentChange(Duel.state.antagonist.equipmentMatrix);
|
handleAntagonistEquipmentChange();
|
||||||
|
|
||||||
const unsubscribes = [
|
const unsubscribes = [
|
||||||
Duel.on((state) => state.antagonist.shell, handleShellChange),
|
Duel.on((state) => state.antagonist.shell, handleShellChange),
|
||||||
Tankopedia.on((state) => state.customShell, handleShellChange),
|
Tankopedia.on((state) => state.customShell, handleShellChange),
|
||||||
Duel.on(
|
Duel.on(
|
||||||
(state) => state.protagonist.equipmentMatrix,
|
(state) => state.protagonist.equipmentMatrix,
|
||||||
handleProtagonistEquipmentChange
|
handleProtagonistEquipmentChange,
|
||||||
),
|
),
|
||||||
Duel.on(
|
Duel.on(
|
||||||
(state) => state.antagonist.equipmentMatrix,
|
(state) => state.antagonist.equipmentMatrix,
|
||||||
handleAntagonistEquipmentChange
|
handleAntagonistEquipmentChange,
|
||||||
|
),
|
||||||
|
Duel.on(
|
||||||
|
(state) => state.equalize,
|
||||||
|
() => {
|
||||||
|
handleProtagonistEquipmentChange();
|
||||||
|
handleAntagonistEquipmentChange();
|
||||||
|
},
|
||||||
),
|
),
|
||||||
];
|
];
|
||||||
|
|
||||||
|
|||||||
+48
-26
@@ -18,6 +18,7 @@ import {
|
|||||||
import { degToRad } from "three/src/math/MathUtils.js";
|
import { degToRad } from "three/src/math/MathUtils.js";
|
||||||
import { hasEquipment } from "../../../../core/blitzkit/hasEquipment";
|
import { hasEquipment } from "../../../../core/blitzkit/hasEquipment";
|
||||||
import { jsxTree } from "../../../../core/blitzkit/jsxTree";
|
import { jsxTree } from "../../../../core/blitzkit/jsxTree";
|
||||||
|
import { defaultEqualizer } from "../../../../core/blitzkit/tankToDuelMember";
|
||||||
import { discardClippingPlane } from "../../../../core/three/discardClippingPlane";
|
import { discardClippingPlane } from "../../../../core/three/discardClippingPlane";
|
||||||
import { Duel } from "../../../../stores/duel";
|
import { Duel } from "../../../../stores/duel";
|
||||||
import {
|
import {
|
||||||
@@ -83,16 +84,25 @@ export function SpacedArmorSceneComponent({
|
|||||||
point: Vector3,
|
point: Vector3,
|
||||||
intersections: Intersection[],
|
intersections: Intersection[],
|
||||||
allowRicochet: boolean,
|
allowRicochet: boolean,
|
||||||
remainingPenetrationInput?: number
|
remainingPenetrationInput?: number,
|
||||||
) => {
|
) => {
|
||||||
const { customShell } = Tankopedia.state;
|
const { customShell } = Tankopedia.state;
|
||||||
const shell = customShell ?? Duel.state.antagonist.shell;
|
const shell = customShell ?? Duel.state.antagonist.shell;
|
||||||
|
const { equalize } = Duel.state;
|
||||||
|
const protagonistEqualizer =
|
||||||
|
(equalize ? Duel.state.protagonist.tank.equalizer : undefined) ??
|
||||||
|
defaultEqualizer;
|
||||||
|
const antagonistEqualizer =
|
||||||
|
(equalize ? Duel.state.antagonist.tank.equalizer : undefined) ??
|
||||||
|
defaultEqualizer;
|
||||||
const cameraNormal = camera.position.clone().sub(point).normalize();
|
const cameraNormal = camera.position.clone().sub(point).normalize();
|
||||||
const shot: Shot = {
|
const shot: Shot = {
|
||||||
splashRadius:
|
splashRadius:
|
||||||
shell.type === ShellType.HE ? shell.explosion_radius : undefined,
|
shell.type === ShellType.SHELL_TYPE_HE
|
||||||
|
? shell.explosion_radius
|
||||||
|
: undefined,
|
||||||
damage: -1,
|
damage: -1,
|
||||||
containsGaps: shell.type === ShellType.HEAT,
|
containsGaps: shell.type === ShellType.SHELL_TYPE_HEAT,
|
||||||
in: {
|
in: {
|
||||||
surfaceNormal: cameraNormal,
|
surfaceNormal: cameraNormal,
|
||||||
layers: [],
|
layers: [],
|
||||||
@@ -103,21 +113,27 @@ export function SpacedArmorSceneComponent({
|
|||||||
const hasCalibratedShells = hasEquipment(
|
const hasCalibratedShells = hasEquipment(
|
||||||
103,
|
103,
|
||||||
Duel.state.antagonist.tank.equipment_preset,
|
Duel.state.antagonist.tank.equipment_preset,
|
||||||
Duel.state.antagonist.equipmentMatrix
|
Duel.state.antagonist.equipmentMatrix,
|
||||||
);
|
);
|
||||||
const hasEnhancedArmor = hasEquipment(
|
const hasEnhancedArmor = hasEquipment(
|
||||||
110,
|
110,
|
||||||
Duel.state.protagonist.tank.equipment_preset,
|
Duel.state.protagonist.tank.equipment_preset,
|
||||||
Duel.state.protagonist.equipmentMatrix
|
Duel.state.protagonist.equipmentMatrix,
|
||||||
);
|
);
|
||||||
const penetration =
|
const penetration =
|
||||||
shell.penetration.near *
|
shell.penetration!.near *
|
||||||
resolvePenetrationCoefficient(hasCalibratedShells, shell.type);
|
resolvePenetrationCoefficient(
|
||||||
const thicknessCoefficient = hasEnhancedArmor ? 1.03 : 1;
|
hasCalibratedShells,
|
||||||
|
equalize,
|
||||||
|
shell.type,
|
||||||
|
antagonistEqualizer,
|
||||||
|
);
|
||||||
|
const thicknessCoefficient =
|
||||||
|
(hasEnhancedArmor ? 1.03 : 1) * protagonistEqualizer.armor;
|
||||||
const filteredIntersections = intersections.filter(
|
const filteredIntersections = intersections.filter(
|
||||||
(intersection) =>
|
(intersection) =>
|
||||||
"type" in intersection.object.userData &&
|
"type" in intersection.object.userData &&
|
||||||
!discardClippingPlane(intersection.object, intersection.point)
|
!discardClippingPlane(intersection.object, intersection.point),
|
||||||
) as unknown as Intersection<Object3D & { userData: ArmorUserData }>[];
|
) as unknown as Intersection<Object3D & { userData: ArmorUserData }>[];
|
||||||
const encounteredExternalModuleVariants: ExternalModuleVariant[] = [];
|
const encounteredExternalModuleVariants: ExternalModuleVariant[] = [];
|
||||||
const noDuplicateIntersections: typeof filteredIntersections = [];
|
const noDuplicateIntersections: typeof filteredIntersections = [];
|
||||||
@@ -126,12 +142,12 @@ export function SpacedArmorSceneComponent({
|
|||||||
if (intersection.object.userData.type === ArmorType.External) {
|
if (intersection.object.userData.type === ArmorType.External) {
|
||||||
if (
|
if (
|
||||||
!encounteredExternalModuleVariants.includes(
|
!encounteredExternalModuleVariants.includes(
|
||||||
intersection.object.userData.variant
|
intersection.object.userData.variant,
|
||||||
)
|
)
|
||||||
) {
|
) {
|
||||||
noDuplicateIntersections.push(intersection);
|
noDuplicateIntersections.push(intersection);
|
||||||
encounteredExternalModuleVariants.push(
|
encounteredExternalModuleVariants.push(
|
||||||
intersection.object.userData.variant
|
intersection.object.userData.variant,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@@ -159,10 +175,10 @@ export function SpacedArmorSceneComponent({
|
|||||||
const surfaceNormal = intersection
|
const surfaceNormal = intersection
|
||||||
.normal!.clone()
|
.normal!.clone()
|
||||||
.applyQuaternion(
|
.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 lastLayer = shot.in.layers.at(-1) as ShotLayerBase;
|
||||||
const distance = lastLayer.point.distanceTo(intersection.point);
|
const distance = lastLayer.point.distanceTo(intersection.point);
|
||||||
remainingPenetration -= 0.5 * remainingPenetration * distance;
|
remainingPenetration -= 0.5 * remainingPenetration * distance;
|
||||||
@@ -181,7 +197,7 @@ export function SpacedArmorSceneComponent({
|
|||||||
const thickness = layer.thickness * thicknessCoefficient;
|
const thickness = layer.thickness * thicknessCoefficient;
|
||||||
remainingPenetration -= thickness;
|
remainingPenetration -= thickness;
|
||||||
const blocked =
|
const blocked =
|
||||||
remainingPenetration <= 0 || shell.type === ShellType.HE;
|
remainingPenetration <= 0 || shell.type === ShellType.SHELL_TYPE_HE;
|
||||||
|
|
||||||
shot.in.layers.push({
|
shot.in.layers.push({
|
||||||
type: ArmorType.External,
|
type: ArmorType.External,
|
||||||
@@ -190,7 +206,7 @@ export function SpacedArmorSceneComponent({
|
|||||||
point: intersection.point,
|
point: intersection.point,
|
||||||
surfaceNormal,
|
surfaceNormal,
|
||||||
status:
|
status:
|
||||||
shell.type === ShellType.HE
|
shell.type === ShellType.SHELL_TYPE_HE
|
||||||
? "blocked"
|
? "blocked"
|
||||||
: blocked
|
: blocked
|
||||||
? "blocked"
|
? "blocked"
|
||||||
@@ -200,7 +216,7 @@ export function SpacedArmorSceneComponent({
|
|||||||
} else {
|
} else {
|
||||||
const thickness = layer.thickness * thicknessCoefficient;
|
const thickness = layer.thickness * thicknessCoefficient;
|
||||||
const ricochet = degToRad(
|
const ricochet = degToRad(
|
||||||
isExplosive(shell.type) ? 90 : shell.ricochet!
|
isExplosive(shell.type) ? 90 : shell.ricochet!,
|
||||||
);
|
);
|
||||||
const angle = surfaceNormal.angleTo(cameraNormal);
|
const angle = surfaceNormal.angleTo(cameraNormal);
|
||||||
|
|
||||||
@@ -241,7 +257,8 @@ export function SpacedArmorSceneComponent({
|
|||||||
point: intersection.point,
|
point: intersection.point,
|
||||||
surfaceNormal: intersection.face!.normal,
|
surfaceNormal: intersection.face!.normal,
|
||||||
status:
|
status:
|
||||||
shell.type === ShellType.HE && layer.type !== ArmorType.Primary
|
shell.type === ShellType.SHELL_TYPE_HE &&
|
||||||
|
layer.type !== ArmorType.Primary
|
||||||
? "blocked"
|
? "blocked"
|
||||||
: blocked
|
: blocked
|
||||||
? "blocked"
|
? "blocked"
|
||||||
@@ -251,7 +268,10 @@ export function SpacedArmorSceneComponent({
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (shell.type !== ShellType.HE && remainingPenetration <= 0) {
|
if (
|
||||||
|
shell.type !== ShellType.SHELL_TYPE_HE &&
|
||||||
|
remainingPenetration <= 0
|
||||||
|
) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -266,7 +286,7 @@ export function SpacedArmorSceneComponent({
|
|||||||
if (!lastLayer || !firstLayer) {
|
if (!lastLayer || !firstLayer) {
|
||||||
return null;
|
return null;
|
||||||
} else {
|
} else {
|
||||||
if (shell.type === ShellType.HE) {
|
if (shell.type === ShellType.SHELL_TYPE_HE) {
|
||||||
const totalSpacedArmorThickness = shot.in.layers.reduce(
|
const totalSpacedArmorThickness = shot.in.layers.reduce(
|
||||||
(acc, layer) => {
|
(acc, layer) => {
|
||||||
if (layer.type === null || layer.type === ArmorType.Primary) {
|
if (layer.type === null || layer.type === ArmorType.Primary) {
|
||||||
@@ -279,10 +299,10 @@ export function SpacedArmorSceneComponent({
|
|||||||
|
|
||||||
return acc + layer.thicknessAngled;
|
return acc + layer.thicknessAngled;
|
||||||
},
|
},
|
||||||
0
|
0,
|
||||||
);
|
);
|
||||||
const distanceFromSpacedArmor = firstLayer.point.distanceTo(
|
const distanceFromSpacedArmor = firstLayer.point.distanceTo(
|
||||||
lastLayer.point
|
lastLayer.point,
|
||||||
);
|
);
|
||||||
const finalDamage = Math.max(
|
const finalDamage = Math.max(
|
||||||
0,
|
0,
|
||||||
@@ -291,7 +311,7 @@ export function SpacedArmorSceneComponent({
|
|||||||
(1 - distanceFromSpacedArmor / shell.explosion_radius!) -
|
(1 - distanceFromSpacedArmor / shell.explosion_radius!) -
|
||||||
1.1 *
|
1.1 *
|
||||||
(lastLayer.thicknessAngled +
|
(lastLayer.thicknessAngled +
|
||||||
Math.min(penetration, totalSpacedArmorThickness))
|
Math.min(penetration, totalSpacedArmorThickness)),
|
||||||
);
|
);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -328,20 +348,20 @@ export function SpacedArmorSceneComponent({
|
|||||||
.sub(
|
.sub(
|
||||||
lastLayer.surfaceNormal
|
lastLayer.surfaceNormal
|
||||||
.clone()
|
.clone()
|
||||||
.multiplyScalar(2 * shellNormal.dot(lastLayer.surfaceNormal))
|
.multiplyScalar(2 * shellNormal.dot(lastLayer.surfaceNormal)),
|
||||||
);
|
);
|
||||||
|
|
||||||
caster.set(lastLayer.point, ricochetNormal);
|
caster.set(lastLayer.point, ricochetNormal);
|
||||||
|
|
||||||
const ricochetIntersections = caster.intersectObjects(
|
const ricochetIntersections = caster.intersectObjects(
|
||||||
props.scene.children,
|
props.scene.children,
|
||||||
true
|
true,
|
||||||
);
|
);
|
||||||
const outShot = shoot(
|
const outShot = shoot(
|
||||||
lastLayer.point,
|
lastLayer.point,
|
||||||
ricochetIntersections,
|
ricochetIntersections,
|
||||||
false,
|
false,
|
||||||
remainingPenetration
|
remainingPenetration,
|
||||||
);
|
);
|
||||||
|
|
||||||
shot.in.status = "ricochet";
|
shot.in.status = "ricochet";
|
||||||
@@ -361,9 +381,11 @@ export function SpacedArmorSceneComponent({
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
shot.damage *= antagonistEqualizer.damage;
|
||||||
|
|
||||||
return shot;
|
return shot;
|
||||||
},
|
},
|
||||||
[camera]
|
[camera],
|
||||||
);
|
);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
|||||||
@@ -43,9 +43,9 @@ export const StaticArmor = memo<ArmorSceneProps>(({ thicknessRange }) => {
|
|||||||
const trackModelDefinition = tankModelDefinition.tracks[track.id];
|
const trackModelDefinition = tankModelDefinition.tracks[track.id];
|
||||||
const turretModelDefinition = tankModelDefinition.turrets[turret.id];
|
const turretModelDefinition = tankModelDefinition.turrets[turret.id];
|
||||||
const gunModelDefinition = turretModelDefinition.guns[gun.id];
|
const gunModelDefinition = turretModelDefinition.guns[gun.id];
|
||||||
const hullOrigin = correctZYTuple(trackModelDefinition.origin);
|
const hullOrigin = correctZYTuple(trackModelDefinition.origin!);
|
||||||
const turretOrigin = correctZYTuple(tankModelDefinition.turret_origin);
|
const turretOrigin = correctZYTuple(tankModelDefinition.turret_origin!);
|
||||||
const gunOrigin = correctZYTuple(turretModelDefinition.gun_origin);
|
const gunOrigin = correctZYTuple(turretModelDefinition.gun_origin!);
|
||||||
const canvas = useThree((state) => state.gl.domElement);
|
const canvas = useThree((state) => state.gl.domElement);
|
||||||
|
|
||||||
const maskOrigin =
|
const maskOrigin =
|
||||||
@@ -53,16 +53,16 @@ export const StaticArmor = memo<ArmorSceneProps>(({ thicknessRange }) => {
|
|||||||
? undefined
|
? undefined
|
||||||
: gunModelDefinition.mask + hullOrigin.y + turretOrigin.y + gunOrigin.y;
|
: gunModelDefinition.mask + hullOrigin.y + turretOrigin.y + gunOrigin.y;
|
||||||
const showPrimaryArmor = TankopediaPersistent.use(
|
const showPrimaryArmor = TankopediaPersistent.use(
|
||||||
(state) => state.showPrimaryArmor
|
(state) => state.showPrimaryArmor,
|
||||||
);
|
);
|
||||||
const showSpacedArmor = TankopediaPersistent.use(
|
const showSpacedArmor = TankopediaPersistent.use(
|
||||||
(state) => state.showSpacedArmor
|
(state) => state.showSpacedArmor,
|
||||||
);
|
);
|
||||||
const showExternalModules = TankopediaPersistent.use(
|
const showExternalModules = TankopediaPersistent.use(
|
||||||
(state) => state.showExternalModules
|
(state) => state.showExternalModules,
|
||||||
);
|
);
|
||||||
const isDynamicArmorActive = Duel.use((state) =>
|
const isDynamicArmorActive = Duel.use((state) =>
|
||||||
state.protagonist.consumables.includes(73)
|
state.protagonist.consumables.includes(73),
|
||||||
);
|
);
|
||||||
|
|
||||||
useTankTransform(track, turret, turretContainer, gunContainer);
|
useTankTransform(track, turret, turretContainer, gunContainer);
|
||||||
@@ -75,8 +75,8 @@ export const StaticArmor = memo<ArmorSceneProps>(({ thicknessRange }) => {
|
|||||||
const isVisible = isHull;
|
const isVisible = isHull;
|
||||||
const armorId = nameToArmorId(node.name);
|
const armorId = nameToArmorId(node.name);
|
||||||
const { spaced, thickness } = resolveArmor(
|
const { spaced, thickness } = resolveArmor(
|
||||||
tankModelDefinition.armor,
|
tankModelDefinition.armor!,
|
||||||
armorId
|
armorId,
|
||||||
);
|
);
|
||||||
|
|
||||||
if (
|
if (
|
||||||
@@ -127,13 +127,13 @@ export const StaticArmor = memo<ArmorSceneProps>(({ thicknessRange }) => {
|
|||||||
<group ref={turretContainer}>
|
<group ref={turretContainer}>
|
||||||
{armorNodes.map((node) => {
|
{armorNodes.map((node) => {
|
||||||
const isCurrentTurret = node.name.startsWith(
|
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 isVisible = isCurrentTurret;
|
||||||
const armorId = nameToArmorId(node.name);
|
const armorId = nameToArmorId(node.name);
|
||||||
const { spaced, thickness } = resolveArmor(
|
const { spaced, thickness } = resolveArmor(
|
||||||
turretModelDefinition.armor,
|
turretModelDefinition.armor!,
|
||||||
armorId
|
armorId,
|
||||||
);
|
);
|
||||||
|
|
||||||
if (
|
if (
|
||||||
@@ -168,12 +168,12 @@ export const StaticArmor = memo<ArmorSceneProps>(({ thicknessRange }) => {
|
|||||||
const hasImprovedVerticalStabilizer = hasEquipment(
|
const hasImprovedVerticalStabilizer = hasEquipment(
|
||||||
122,
|
122,
|
||||||
Duel.state.protagonist.tank.equipment_preset,
|
Duel.state.protagonist.tank.equipment_preset,
|
||||||
Duel.state.protagonist.equipmentMatrix
|
Duel.state.protagonist.equipmentMatrix,
|
||||||
);
|
);
|
||||||
const hasDownImprovedVerticalStabilizer = hasEquipment(
|
const hasDownImprovedVerticalStabilizer = hasEquipment(
|
||||||
124,
|
124,
|
||||||
Duel.state.protagonist.tank.equipment_preset,
|
Duel.state.protagonist.tank.equipment_preset,
|
||||||
Duel.state.protagonist.equipmentMatrix
|
Duel.state.protagonist.equipmentMatrix,
|
||||||
);
|
);
|
||||||
const boundingRect = canvas.getBoundingClientRect();
|
const boundingRect = canvas.getBoundingClientRect();
|
||||||
|
|
||||||
@@ -184,10 +184,10 @@ export const StaticArmor = memo<ArmorSceneProps>(({ thicknessRange }) => {
|
|||||||
modelTransformEvent.last!.pitch,
|
modelTransformEvent.last!.pitch,
|
||||||
modelTransformEvent.last!.yaw +
|
modelTransformEvent.last!.yaw +
|
||||||
delta.x * (Math.PI / boundingRect.width),
|
delta.x * (Math.PI / boundingRect.width),
|
||||||
gunModelDefinition.pitch,
|
gunModelDefinition.pitch!,
|
||||||
turretModelDefinition.yaw,
|
turretModelDefinition.yaw,
|
||||||
hasImprovedVerticalStabilizer,
|
hasImprovedVerticalStabilizer,
|
||||||
hasDownImprovedVerticalStabilizer
|
hasDownImprovedVerticalStabilizer,
|
||||||
);
|
);
|
||||||
modelTransformEvent.dispatch({ pitch, yaw });
|
modelTransformEvent.dispatch({ pitch, yaw });
|
||||||
}
|
}
|
||||||
@@ -216,13 +216,13 @@ export const StaticArmor = memo<ArmorSceneProps>(({ thicknessRange }) => {
|
|||||||
<group ref={gunContainer}>
|
<group ref={gunContainer}>
|
||||||
{armorNodes.map((node) => {
|
{armorNodes.map((node) => {
|
||||||
const isCurrentGun = node.name.startsWith(
|
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 isVisible = isCurrentGun;
|
||||||
const armorId = nameToArmorId(node.name);
|
const armorId = nameToArmorId(node.name);
|
||||||
const { spaced, thickness } = resolveArmor(
|
const { spaced, thickness } = resolveArmor(
|
||||||
gunModelDefinition.armor,
|
gunModelDefinition.armor!,
|
||||||
armorId
|
armorId,
|
||||||
);
|
);
|
||||||
|
|
||||||
if (
|
if (
|
||||||
@@ -256,12 +256,12 @@ export const StaticArmor = memo<ArmorSceneProps>(({ thicknessRange }) => {
|
|||||||
const hasImprovedVerticalStabilizer = hasEquipment(
|
const hasImprovedVerticalStabilizer = hasEquipment(
|
||||||
122,
|
122,
|
||||||
Duel.state.protagonist.tank.equipment_preset,
|
Duel.state.protagonist.tank.equipment_preset,
|
||||||
Duel.state.protagonist.equipmentMatrix
|
Duel.state.protagonist.equipmentMatrix,
|
||||||
);
|
);
|
||||||
const hasDownImprovedVerticalStabilizer = hasEquipment(
|
const hasDownImprovedVerticalStabilizer = hasEquipment(
|
||||||
124,
|
124,
|
||||||
Duel.state.protagonist.tank.equipment_preset,
|
Duel.state.protagonist.tank.equipment_preset,
|
||||||
Duel.state.protagonist.equipmentMatrix
|
Duel.state.protagonist.equipmentMatrix,
|
||||||
);
|
);
|
||||||
const boundingRect = canvas.getBoundingClientRect();
|
const boundingRect = canvas.getBoundingClientRect();
|
||||||
delta.set(event.clientX, event.clientY).sub(position);
|
delta.set(event.clientX, event.clientY).sub(position);
|
||||||
@@ -272,10 +272,10 @@ export const StaticArmor = memo<ArmorSceneProps>(({ thicknessRange }) => {
|
|||||||
delta.y * (Math.PI / boundingRect.height),
|
delta.y * (Math.PI / boundingRect.height),
|
||||||
modelTransformEvent.last!.yaw +
|
modelTransformEvent.last!.yaw +
|
||||||
delta.x * (Math.PI / boundingRect.width),
|
delta.x * (Math.PI / boundingRect.width),
|
||||||
gunModelDefinition.pitch,
|
gunModelDefinition.pitch!,
|
||||||
turretModelDefinition.yaw,
|
turretModelDefinition.yaw,
|
||||||
hasImprovedVerticalStabilizer,
|
hasImprovedVerticalStabilizer,
|
||||||
hasDownImprovedVerticalStabilizer
|
hasDownImprovedVerticalStabilizer,
|
||||||
);
|
);
|
||||||
modelTransformEvent.dispatch({ pitch, yaw });
|
modelTransformEvent.dispatch({ pitch, yaw });
|
||||||
}
|
}
|
||||||
@@ -332,12 +332,12 @@ export const StaticArmor = memo<ArmorSceneProps>(({ thicknessRange }) => {
|
|||||||
const hasImprovedVerticalStabilizer = hasEquipment(
|
const hasImprovedVerticalStabilizer = hasEquipment(
|
||||||
122,
|
122,
|
||||||
Duel.state.protagonist.tank.equipment_preset,
|
Duel.state.protagonist.tank.equipment_preset,
|
||||||
Duel.state.protagonist.equipmentMatrix
|
Duel.state.protagonist.equipmentMatrix,
|
||||||
);
|
);
|
||||||
const hasDownImprovedVerticalStabilizer = hasEquipment(
|
const hasDownImprovedVerticalStabilizer = hasEquipment(
|
||||||
124,
|
124,
|
||||||
Duel.state.protagonist.tank.equipment_preset,
|
Duel.state.protagonist.tank.equipment_preset,
|
||||||
Duel.state.protagonist.equipmentMatrix
|
Duel.state.protagonist.equipmentMatrix,
|
||||||
);
|
);
|
||||||
const boundingRect = canvas.getBoundingClientRect();
|
const boundingRect = canvas.getBoundingClientRect();
|
||||||
delta.set(event.clientX, event.clientY).sub(position);
|
delta.set(event.clientX, event.clientY).sub(position);
|
||||||
@@ -348,10 +348,10 @@ export const StaticArmor = memo<ArmorSceneProps>(({ thicknessRange }) => {
|
|||||||
delta.y * (Math.PI / boundingRect.height),
|
delta.y * (Math.PI / boundingRect.height),
|
||||||
modelTransformEvent.last!.yaw +
|
modelTransformEvent.last!.yaw +
|
||||||
delta.x * (Math.PI / boundingRect.width),
|
delta.x * (Math.PI / boundingRect.width),
|
||||||
gunModelDefinition.pitch,
|
gunModelDefinition.pitch!,
|
||||||
turretModelDefinition.yaw,
|
turretModelDefinition.yaw,
|
||||||
hasImprovedVerticalStabilizer,
|
hasImprovedVerticalStabilizer,
|
||||||
hasDownImprovedVerticalStabilizer
|
hasDownImprovedVerticalStabilizer,
|
||||||
);
|
);
|
||||||
modelTransformEvent.dispatch({ pitch, yaw });
|
modelTransformEvent.dispatch({ pitch, yaw });
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -22,7 +22,10 @@ import {
|
|||||||
modelTransformEvent,
|
modelTransformEvent,
|
||||||
type ModelTransformEventData,
|
type ModelTransformEventData,
|
||||||
} from "../../../core/blitzkit/modelTransform";
|
} from "../../../core/blitzkit/modelTransform";
|
||||||
|
import { defaultEqualizer } from "../../../core/blitzkit/tankToDuelMember";
|
||||||
import { discardClippingPlane } from "../../../core/three/discardClippingPlane";
|
import { discardClippingPlane } from "../../../core/three/discardClippingPlane";
|
||||||
|
import { useEquipment } from "../../../hooks/useEquipment";
|
||||||
|
import { Duel } from "../../../stores/duel";
|
||||||
import { Tankopedia } from "../../../stores/tankopedia";
|
import { Tankopedia } from "../../../stores/tankopedia";
|
||||||
import { transitionEvent } from "../../Tankopedia/HeroSection/components/TankSandbox/components/Lighting";
|
import { transitionEvent } from "../../Tankopedia/HeroSection/components/TankSandbox/components/Lighting";
|
||||||
import { ArmorType } from "./SpacedArmorScene";
|
import { ArmorType } from "./SpacedArmorScene";
|
||||||
@@ -64,46 +67,68 @@ const externalModuleColor = new Color(192 / 255, 192 / 255, 192 / 255);
|
|||||||
|
|
||||||
export function StaticArmorSceneComponent({
|
export function StaticArmorSceneComponent({
|
||||||
name,
|
name,
|
||||||
thickness,
|
thickness: thicknessRaw,
|
||||||
thicknessRange,
|
thicknessRange,
|
||||||
node,
|
node,
|
||||||
onPointerDown,
|
onPointerDown,
|
||||||
...props
|
...props
|
||||||
}: StaticArmorSceneComponentProps) {
|
}: StaticArmorSceneComponentProps) {
|
||||||
const camera = useThree((state) => state.camera);
|
const camera = useThree((state) => state.camera);
|
||||||
|
const hasEnhancedArmor = useEquipment(110);
|
||||||
|
const tank = Duel.use((state) => state.protagonist.tank);
|
||||||
|
const equalize = Duel.use((state) => state.equalize);
|
||||||
|
const equalizer = (equalize ? tank.equalizer : undefined) ?? defaultEqualizer;
|
||||||
|
const thicknessCoefficient = (hasEnhancedArmor ? 1.03 : 1) * equalizer.armor;
|
||||||
|
const thickness = thicknessRaw * thicknessCoefficient;
|
||||||
const x = thickness / thicknessRange.value;
|
const x = thickness / thicknessRange.value;
|
||||||
const xClamped = clamp(x, 0, 1);
|
const xClamped = clamp(x, 0, 1);
|
||||||
let color: Color;
|
const color = useMemo(() => {
|
||||||
let opacity: number;
|
switch (props.type) {
|
||||||
let depthWrite = true;
|
case ArmorType.Primary: {
|
||||||
|
if (x > 1) {
|
||||||
switch (props.type) {
|
return new Color(clamp(2 - x, 0.5, 1), 0, 0);
|
||||||
case ArmorType.Primary:
|
} else {
|
||||||
if (x > 1) {
|
return new Color(-((1 - x) ** 2) + 1, -(x ** 2) + 1, 0);
|
||||||
color = new Color(clamp(2 - x, 0.5, 1), 0, 0);
|
}
|
||||||
} else {
|
|
||||||
color = new Color(-((1 - x) ** 2) + 1, -(x ** 2) + 1, 0);
|
|
||||||
}
|
}
|
||||||
opacity = 1;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case ArmorType.Spaced:
|
case ArmorType.Spaced: {
|
||||||
color = new Color(
|
return new Color(
|
||||||
clamp(1 - (7 / 8) * xClamped, 0, 1),
|
clamp(1 - (7 / 8) * xClamped, 0, 1),
|
||||||
0,
|
0,
|
||||||
clamp(1 - (1 / 8) * xClamped, 0, 1),
|
clamp(1 - (1 / 8) * xClamped, 0, 1),
|
||||||
);
|
);
|
||||||
opacity = clamp(x + 1 / 2, 0, 1);
|
}
|
||||||
break;
|
|
||||||
|
|
||||||
case ArmorType.External:
|
case ArmorType.External: {
|
||||||
color = externalModuleColor;
|
return externalModuleColor;
|
||||||
opacity = 1 / 8;
|
}
|
||||||
depthWrite = false;
|
}
|
||||||
break;
|
}, [props.type, xClamped]);
|
||||||
}
|
const opacity = useMemo(() => {
|
||||||
|
switch (props.type) {
|
||||||
|
case ArmorType.Primary:
|
||||||
|
return 1;
|
||||||
|
|
||||||
opacity = clamp(opacity, 0, 1);
|
case ArmorType.Spaced:
|
||||||
|
return clamp(x + 1 / 2, 0, 1);
|
||||||
|
|
||||||
|
case ArmorType.External:
|
||||||
|
return 1 / 8;
|
||||||
|
}
|
||||||
|
}, [props.type, x]);
|
||||||
|
const depthWrite = useMemo(() => {
|
||||||
|
switch (props.type) {
|
||||||
|
case ArmorType.Primary:
|
||||||
|
return true;
|
||||||
|
|
||||||
|
case ArmorType.Spaced:
|
||||||
|
return true;
|
||||||
|
|
||||||
|
case ArmorType.External:
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}, [props.type]);
|
||||||
|
|
||||||
const surfaceMaterial = useMemo(
|
const surfaceMaterial = useMemo(
|
||||||
() =>
|
() =>
|
||||||
@@ -115,7 +140,7 @@ export function StaticArmorSceneComponent({
|
|||||||
opacity: 0,
|
opacity: 0,
|
||||||
userData: { opacity0: opacity },
|
userData: { opacity0: opacity },
|
||||||
}),
|
}),
|
||||||
[thickness],
|
[hasEnhancedArmor, equalize],
|
||||||
);
|
);
|
||||||
const outlineMaterial = useMemo(
|
const outlineMaterial = useMemo(
|
||||||
() =>
|
() =>
|
||||||
@@ -126,7 +151,7 @@ export function StaticArmorSceneComponent({
|
|||||||
opacity: 0,
|
opacity: 0,
|
||||||
transparent: true,
|
transparent: true,
|
||||||
}),
|
}),
|
||||||
[thickness],
|
[hasEnhancedArmor, equalize],
|
||||||
);
|
);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
@@ -229,7 +254,7 @@ export function StaticArmorSceneComponent({
|
|||||||
return () => {
|
return () => {
|
||||||
unsubscribes.forEach((unsubscribe) => unsubscribe());
|
unsubscribes.forEach((unsubscribe) => unsubscribe());
|
||||||
};
|
};
|
||||||
}, [thickness]);
|
}, [hasEnhancedArmor, equalize]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
|
|||||||
@@ -1,16 +1,16 @@
|
|||||||
import { TankClass } from '@blitzkit/core';
|
import { TankClass } from "@blitzkit/core";
|
||||||
import type { ComponentProps, ReactNode } from 'react';
|
import type { ComponentProps, ReactNode } from "react";
|
||||||
import { ClassHeavy } from './components/ClassHeavy';
|
import { ClassHeavy } from "./components/ClassHeavy";
|
||||||
import { ClassLight } from './components/ClassLight';
|
import { ClassLight } from "./components/ClassLight";
|
||||||
import { ClassMedium } from './components/ClassMedium';
|
import { ClassMedium } from "./components/ClassMedium";
|
||||||
import { ClassTankDestroyer } from './components/ClassTankDestroyer';
|
import { ClassTankDestroyer } from "./components/ClassTankDestroyer";
|
||||||
|
|
||||||
export const classIcons: Record<
|
export const classIcons: Record<
|
||||||
TankClass,
|
TankClass,
|
||||||
(props: ComponentProps<'svg'>) => ReactNode
|
(props: ComponentProps<"svg">) => ReactNode
|
||||||
> = {
|
> = {
|
||||||
[TankClass.TANK_DESTROYER]: ClassTankDestroyer,
|
[TankClass.TANK_CLASS_TANK_DESTROYER]: ClassTankDestroyer,
|
||||||
[TankClass.HEAVY]: ClassHeavy,
|
[TankClass.TANK_CLASS_HEAVY]: ClassHeavy,
|
||||||
[TankClass.LIGHT]: ClassLight,
|
[TankClass.TANK_CLASS_LIGHT]: ClassLight,
|
||||||
[TankClass.MEDIUM]: ClassMedium,
|
[TankClass.TANK_CLASS_MEDIUM]: ClassMedium,
|
||||||
};
|
};
|
||||||
@@ -15,7 +15,7 @@ interface BodyProps {
|
|||||||
export function Body({ stats }: BodyProps) {
|
export function Body({ stats }: BodyProps) {
|
||||||
const members = CompareEphemeral.use((state) => state.members);
|
const members = CompareEphemeral.use((state) => state.members);
|
||||||
const hasNonRegularGun = members.some(
|
const hasNonRegularGun = members.some(
|
||||||
({ gun }) => gun.gun_type!.$case !== "regular"
|
({ gun }) => gun.gun_type!.$case !== "regular",
|
||||||
);
|
);
|
||||||
const { unwrap, strings } = useLocale();
|
const { unwrap, strings } = useLocale();
|
||||||
|
|
||||||
@@ -55,7 +55,7 @@ export function Body({ stats }: BodyProps) {
|
|||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<img
|
<img
|
||||||
alt={unwrap(thisShell.name)}
|
alt={unwrap(thisShell.name!)}
|
||||||
width={16}
|
width={16}
|
||||||
height={16}
|
height={16}
|
||||||
src={asset(`icons/shells/${thisShell.icon}.webp`)}
|
src={asset(`icons/shells/${thisShell.icon}.webp`)}
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ import { StickyRowHeaderCell } from "../StickyRowHeaderCell";
|
|||||||
|
|
||||||
type CompareRowProps = {
|
type CompareRowProps = {
|
||||||
display?: (
|
display?: (
|
||||||
member: Awaited<TankCharacteristics>
|
member: Awaited<TankCharacteristics>,
|
||||||
) => number | string | undefined;
|
) => number | string | undefined;
|
||||||
deltaType?: CompareCellDirection;
|
deltaType?: CompareCellDirection;
|
||||||
decimals?: number;
|
decimals?: number;
|
||||||
@@ -46,7 +46,7 @@ export function CompareRow({
|
|||||||
const values = stats.map((stat) =>
|
const values = stats.map((stat) =>
|
||||||
typeof props.value === "function"
|
typeof props.value === "function"
|
||||||
? props.value(stat)!
|
? props.value(stat)!
|
||||||
: (stat[props.value] as number)
|
: (stat[props.value] as number),
|
||||||
);
|
);
|
||||||
const id = useRef(Math.random());
|
const id = useRef(Math.random());
|
||||||
const name =
|
const name =
|
||||||
@@ -56,10 +56,10 @@ export function CompareRow({
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<Table.Row>
|
<Table.Row>
|
||||||
<StickyRowHeaderCell>
|
<StickyRowHeaderCell left="-1.25rem">
|
||||||
<Flex
|
<Flex
|
||||||
align="center"
|
align="center"
|
||||||
style={{ whiteSpace: "nowrap" }}
|
maxWidth={{ initial: "6rem", sm: "unset" }}
|
||||||
gap={indent ? { initial: "4", sm: "6" } : { initial: "1", sm: "2" }}
|
gap={indent ? { initial: "4", sm: "6" } : { initial: "1", sm: "2" }}
|
||||||
>
|
>
|
||||||
<IconButton
|
<IconButton
|
||||||
@@ -111,8 +111,8 @@ export function CompareRow({
|
|||||||
const resolvedDisplayValue = display
|
const resolvedDisplayValue = display
|
||||||
? display(stats[index])
|
? display(stats[index])
|
||||||
: decimals === undefined
|
: decimals === undefined
|
||||||
? value
|
? value
|
||||||
: value?.toFixed(decimals);
|
: value?.toFixed(decimals);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<CompareCell
|
<CompareCell
|
||||||
@@ -145,8 +145,8 @@ export function CompareRow({
|
|||||||
deltaNominalDisplay
|
deltaNominalDisplay
|
||||||
? deltaNominalDisplay(delta)
|
? deltaNominalDisplay(delta)
|
||||||
: decimals === undefined
|
: decimals === undefined
|
||||||
? delta
|
? delta
|
||||||
: delta.toFixed(decimals)
|
: delta.toFixed(decimals)
|
||||||
}`}
|
}`}
|
||||||
)
|
)
|
||||||
</Text>
|
</Text>
|
||||||
@@ -156,7 +156,7 @@ export function CompareRow({
|
|||||||
<Text color="gray">
|
<Text color="gray">
|
||||||
(
|
(
|
||||||
{`${deltaPercentage > 0 ? "+" : ""}${Math.round(
|
{`${deltaPercentage > 0 ? "+" : ""}${Math.round(
|
||||||
deltaPercentage * 100
|
deltaPercentage * 100,
|
||||||
)}%`}
|
)}%`}
|
||||||
)
|
)
|
||||||
</Text>
|
</Text>
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import { Heading, Table } from '@radix-ui/themes';
|
import { Heading, Table } from "@radix-ui/themes";
|
||||||
import { times } from 'lodash-es';
|
import { times } from "lodash-es";
|
||||||
import { CompareEphemeral } from '../../stores/compareEphemeral';
|
import { CompareEphemeral } from "../../stores/compareEphemeral";
|
||||||
import { StickyColumnHeaderCell } from '../StickyColumnHeaderCell';
|
import { StickyColumnHeaderCell } from "../StickyColumnHeaderCell";
|
||||||
|
|
||||||
export function CompareSectionTitle({ children }: { children: string }) {
|
export function CompareSectionTitle({ children }: { children: string }) {
|
||||||
const memberCount = CompareEphemeral.use((state) => state.members.length);
|
const memberCount = CompareEphemeral.use((state) => state.members.length);
|
||||||
|
|||||||
@@ -1,7 +1,15 @@
|
|||||||
import { asset, availableProvisions, permanentSkills } from "@blitzkit/core";
|
import { asset, availableProvisions, permanentSkills } from "@blitzkit/core";
|
||||||
import { checkConsumableProvisionInclusivity } from "@blitzkit/core/src/blitzkit/checkConsumableProvisionInclusivity";
|
import { checkConsumableProvisionInclusivity } from "@blitzkit/core/src/blitzkit/checkConsumableProvisionInclusivity";
|
||||||
import { ComponentPlaceholderIcon } from "@radix-ui/react-icons";
|
import { ComponentPlaceholderIcon } from "@radix-ui/react-icons";
|
||||||
import { Button, Flex, IconButton, Popover, Table } from "@radix-ui/themes";
|
import {
|
||||||
|
Button,
|
||||||
|
Flex,
|
||||||
|
IconButton,
|
||||||
|
Popover,
|
||||||
|
Switch,
|
||||||
|
Table,
|
||||||
|
Text,
|
||||||
|
} from "@radix-ui/themes";
|
||||||
import { times } from "lodash-es";
|
import { times } from "lodash-es";
|
||||||
import { awaitableConsumableDefinitions } from "../../core/awaitables/consumableDefinitions";
|
import { awaitableConsumableDefinitions } from "../../core/awaitables/consumableDefinitions";
|
||||||
import { awaitableEquipmentDefinitions } from "../../core/awaitables/equipmentDefinitions";
|
import { awaitableEquipmentDefinitions } from "../../core/awaitables/equipmentDefinitions";
|
||||||
@@ -44,6 +52,7 @@ export function CompareTable({ stats }: CompareTableProps) {
|
|||||||
const crewSkills = CompareEphemeral.use((state) => state.crewSkills);
|
const crewSkills = CompareEphemeral.use((state) => state.crewSkills);
|
||||||
const members = CompareEphemeral.use((state) => state.members);
|
const members = CompareEphemeral.use((state) => state.members);
|
||||||
const { unwrap, strings } = useLocale();
|
const { unwrap, strings } = useLocale();
|
||||||
|
const equalize = CompareEphemeral.use((state) => state.equalize);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<StickyTableRoot
|
<StickyTableRoot
|
||||||
@@ -80,10 +89,12 @@ export function CompareTable({ stats }: CompareTableProps) {
|
|||||||
<Table.Row>
|
<Table.Row>
|
||||||
<Table.Cell style={{ height: "100%" }}>
|
<Table.Cell style={{ height: "100%" }}>
|
||||||
<Flex
|
<Flex
|
||||||
|
gap="2"
|
||||||
style={{
|
style={{
|
||||||
width: "100%",
|
width: "100%",
|
||||||
height: "100%",
|
height: "100%",
|
||||||
}}
|
}}
|
||||||
|
direction="column"
|
||||||
align="center"
|
align="center"
|
||||||
justify="center"
|
justify="center"
|
||||||
>
|
>
|
||||||
@@ -105,13 +116,13 @@ export function CompareTable({ stats }: CompareTableProps) {
|
|||||||
crewSkills[skill] === 0
|
crewSkills[skill] === 0
|
||||||
? Var("gray-11")
|
? Var("gray-11")
|
||||||
: permanentSkills.includes(skill)
|
: permanentSkills.includes(skill)
|
||||||
? Var("crimson-11")
|
? Var("crimson-11")
|
||||||
: Var("amber-11"),
|
: Var("amber-11"),
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
))}
|
))}
|
||||||
</Flex>
|
</Flex>
|
||||||
)
|
),
|
||||||
)}
|
)}
|
||||||
</Flex>
|
</Flex>
|
||||||
</Button>
|
</Button>
|
||||||
@@ -155,6 +166,21 @@ export function CompareTable({ stats }: CompareTableProps) {
|
|||||||
</Flex>
|
</Flex>
|
||||||
</Popover.Content>
|
</Popover.Content>
|
||||||
</Popover.Root>
|
</Popover.Root>
|
||||||
|
|
||||||
|
<Flex align="center" gap="1">
|
||||||
|
<Text>
|
||||||
|
{strings.website.tools.compare.table.skills.equalize}
|
||||||
|
</Text>
|
||||||
|
<Switch
|
||||||
|
size="1"
|
||||||
|
checked={equalize}
|
||||||
|
onCheckedChange={(checked) => {
|
||||||
|
CompareEphemeral.mutate((draft) => {
|
||||||
|
draft.equalize = checked;
|
||||||
|
});
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
</Flex>
|
||||||
</Flex>
|
</Flex>
|
||||||
</Table.Cell>
|
</Table.Cell>
|
||||||
|
|
||||||
@@ -173,19 +199,19 @@ export function CompareTable({ stats }: CompareTableProps) {
|
|||||||
consumables,
|
consumables,
|
||||||
camouflage,
|
camouflage,
|
||||||
},
|
},
|
||||||
index
|
index,
|
||||||
) => {
|
) => {
|
||||||
const equipmentPreset =
|
const equipmentPreset =
|
||||||
equipmentDefinitions.presets[tank.equipment_preset];
|
equipmentDefinitions.presets[tank.equipment_preset];
|
||||||
const provisionsList = availableProvisions(
|
const provisionsList = availableProvisions(
|
||||||
tank,
|
tank,
|
||||||
gun,
|
gun,
|
||||||
provisionDefinitions
|
provisionDefinitions,
|
||||||
);
|
);
|
||||||
const consumablesList = Object.values(
|
const consumablesList = Object.values(
|
||||||
consumableDefinitions.consumables
|
consumableDefinitions.consumables,
|
||||||
).filter((consumable) =>
|
).filter((consumable) =>
|
||||||
checkConsumableProvisionInclusivity(consumable, tank, gun)
|
checkConsumableProvisionInclusivity(consumable, tank, gun),
|
||||||
);
|
);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
@@ -294,11 +320,11 @@ export function CompareTable({ stats }: CompareTableProps) {
|
|||||||
<img
|
<img
|
||||||
alt={unwrap(
|
alt={unwrap(
|
||||||
provisionDefinitions.provisions[provision]
|
provisionDefinitions.provisions[provision]
|
||||||
.name
|
.name!,
|
||||||
)}
|
)}
|
||||||
key={provision}
|
key={provision}
|
||||||
src={asset(
|
src={asset(
|
||||||
`/icons/provisions/${provision}.webp`
|
`/icons/provisions/${provision}.webp`,
|
||||||
)}
|
)}
|
||||||
style={{
|
style={{
|
||||||
left: "50%",
|
left: "50%",
|
||||||
@@ -335,7 +361,7 @@ export function CompareTable({ stats }: CompareTableProps) {
|
|||||||
<Popover.Content>
|
<Popover.Content>
|
||||||
<ProvisionsManager
|
<ProvisionsManager
|
||||||
provisions={provisionsList.map(
|
provisions={provisionsList.map(
|
||||||
(provision) => provision.id
|
(provision) => provision.id,
|
||||||
)}
|
)}
|
||||||
selected={provisions}
|
selected={provisions}
|
||||||
disabled={tank.max_provisions === provisions.length}
|
disabled={tank.max_provisions === provisions.length}
|
||||||
@@ -452,7 +478,7 @@ export function CompareTable({ stats }: CompareTableProps) {
|
|||||||
CompareEphemeral.mutate((draft) => {
|
CompareEphemeral.mutate((draft) => {
|
||||||
draft.members[index].equipmentMatrix = times(
|
draft.members[index].equipmentMatrix = times(
|
||||||
3,
|
3,
|
||||||
() => times(3, () => 0)
|
() => times(3, () => 0),
|
||||||
) as EquipmentMatrix;
|
) as EquipmentMatrix;
|
||||||
draft.sorting = undefined;
|
draft.sorting = undefined;
|
||||||
});
|
});
|
||||||
@@ -501,11 +527,11 @@ export function CompareTable({ stats }: CompareTableProps) {
|
|||||||
alt={unwrap(
|
alt={unwrap(
|
||||||
consumableDefinitions.consumables[
|
consumableDefinitions.consumables[
|
||||||
consumable
|
consumable
|
||||||
].name
|
].name!,
|
||||||
)}
|
)}
|
||||||
key={consumable}
|
key={consumable}
|
||||||
src={asset(
|
src={asset(
|
||||||
`/icons/consumables/${consumable}.webp`
|
`/icons/consumables/${consumable}.webp`,
|
||||||
)}
|
)}
|
||||||
style={{
|
style={{
|
||||||
left: "50%",
|
left: "50%",
|
||||||
@@ -610,7 +636,7 @@ export function CompareTable({ stats }: CompareTableProps) {
|
|||||||
</Flex>
|
</Flex>
|
||||||
</Table.Cell>
|
</Table.Cell>
|
||||||
);
|
);
|
||||||
}
|
},
|
||||||
)}
|
)}
|
||||||
</Table.Row>
|
</Table.Row>
|
||||||
</Table.Body>
|
</Table.Body>
|
||||||
|
|||||||
@@ -55,7 +55,7 @@ export function TankCard({ index, tank }: TankCardProps) {
|
|||||||
};
|
};
|
||||||
});
|
});
|
||||||
const closest = distances.reduce((a, b) =>
|
const closest = distances.reduce((a, b) =>
|
||||||
a.distance < b.distance ? a : b
|
a.distance < b.distance ? a : b,
|
||||||
);
|
);
|
||||||
|
|
||||||
dropIndex = closest.index;
|
dropIndex = closest.index;
|
||||||
@@ -85,8 +85,8 @@ export function TankCard({ index, tank }: TankCardProps) {
|
|||||||
CompareEphemeral.mutate((draft) => {
|
CompareEphemeral.mutate((draft) => {
|
||||||
const fromIndex = index;
|
const fromIndex = index;
|
||||||
const toIndex = dropIndex > index ? dropIndex - 1 : dropIndex;
|
const toIndex = dropIndex > index ? dropIndex - 1 : dropIndex;
|
||||||
|
|
||||||
const member = draft.members[fromIndex];
|
const member = draft.members[fromIndex];
|
||||||
|
|
||||||
draft.members.splice(fromIndex, 1);
|
draft.members.splice(fromIndex, 1);
|
||||||
draft.members.splice(toIndex, 0, member);
|
draft.members.splice(toIndex, 0, member);
|
||||||
});
|
});
|
||||||
@@ -99,7 +99,7 @@ export function TankCard({ index, tank }: TankCardProps) {
|
|||||||
return () => {
|
return () => {
|
||||||
draggable.current?.removeEventListener("pointerdown", handlePointerDown);
|
draggable.current?.removeEventListener("pointerdown", handlePointerDown);
|
||||||
};
|
};
|
||||||
}, []);
|
}, [index]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<StickyColumnHeaderCell width="0">
|
<StickyColumnHeaderCell width="0">
|
||||||
@@ -119,7 +119,7 @@ export function TankCard({ index, tank }: TankCardProps) {
|
|||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<img
|
<img
|
||||||
alt={unwrap(tank.name)}
|
alt={unwrap(tank.name!)}
|
||||||
src={tankIcon(tank.id)}
|
src={tankIcon(tank.id)}
|
||||||
width={64}
|
width={64}
|
||||||
height={64}
|
height={64}
|
||||||
@@ -137,11 +137,10 @@ export function TankCard({ index, tank }: TankCardProps) {
|
|||||||
textOverflow: "ellipsis",
|
textOverflow: "ellipsis",
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
{unwrap(tank.name)}
|
{unwrap(tank.name!)}
|
||||||
</Text>
|
</Text>
|
||||||
</Flex>
|
</Flex>
|
||||||
</Flex>
|
</Flex>
|
||||||
|
|
||||||
<InsertionMarker index={index + 1} />
|
<InsertionMarker index={index + 1} />
|
||||||
</StickyColumnHeaderCell>
|
</StickyColumnHeaderCell>
|
||||||
);
|
);
|
||||||
|
|||||||
Loaded 100 of 164 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user