mirror of
https://github.com/blitzkit/blitzkit.git
synced 2026-10-28 21:19:52 +01:00
Compare commits
183
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
5234c4d5c3 | ||
|
|
0848833568 | ||
|
|
d858a498cc | ||
|
|
7b81a59788 | ||
|
|
e6d3bff381 | ||
|
|
58e91f0af7 | ||
|
|
137488bd0a | ||
|
|
92fd8b4457 | ||
|
|
7829c206e9 | ||
|
|
5872028678 | ||
|
|
a0cb819805 | ||
|
|
d714bfe57e | ||
|
|
1c35cd4128 | ||
|
|
0bdd1b1dca | ||
|
|
b621790244 | ||
|
|
0f08f4beee | ||
|
|
799ea30bcb | ||
|
|
dedb90d404 | ||
|
|
6eafbc87e7 | ||
|
|
f84460d637 | ||
|
|
917d6affea | ||
|
|
cb2d795461 | ||
|
|
6e934e0ff1 | ||
|
|
375adadbe5 | ||
|
|
082a756f1b | ||
|
|
9fc8a8e2a2 | ||
|
|
1413475679 | ||
|
|
86504e685e | ||
|
|
9df81044d1 | ||
|
|
c5fd7591ea | ||
|
|
cd8e43f945 | ||
|
|
8df112aab4 | ||
|
|
94c04ce102 | ||
|
|
3a170202ca | ||
|
|
46937693a0 | ||
|
|
b391d0b036 | ||
|
|
1061e003f7 | ||
|
|
a2b573abca | ||
|
|
4571d141e6 | ||
|
|
d70225b03c | ||
|
|
dc6c528167 | ||
|
|
b4d5d4c16e | ||
|
|
f2f6d4ff49 | ||
|
|
cdbb7647f0 | ||
|
|
41e40de791 | ||
|
|
c85cd36818 | ||
|
|
5d2c63fed9 | ||
|
|
cead140855 | ||
|
|
63a0143d4f | ||
|
|
19f22993f1 | ||
|
|
b2eb74914f | ||
|
|
05572918b1 | ||
|
|
1cc8b26b16 | ||
|
|
a8e8d20cf1 | ||
|
|
55deb30607 | ||
|
|
03b8b89a17 | ||
|
|
3e421c7eb7 | ||
|
|
fc27caabdc | ||
|
|
3d35fae5ce | ||
|
|
f6dfc4f176 | ||
|
|
fdbbe2f356 | ||
|
|
cdf2aee43f | ||
|
|
56933ddfac | ||
|
|
1df2e818be | ||
|
|
1e4d00ea34 | ||
|
|
1bde50e0a3 | ||
|
|
88290ec1ab | ||
|
|
e8325df832 | ||
|
|
394f28e6ed | ||
|
|
f5f170bcca | ||
|
|
2ffe3fc006 | ||
|
|
406d70b5b7 | ||
|
|
f801e81c8b | ||
|
|
a0e1d8cee0 | ||
|
|
a9a870c3e6 | ||
|
|
3d061a78de | ||
|
|
a188a01244 | ||
|
|
0828722876 | ||
|
|
0ccd9e45d8 | ||
|
|
2f745a16d1 | ||
|
|
100c7391fb | ||
|
|
4f42a31f53 | ||
|
|
0b2e322112 | ||
|
|
042a1afa74 | ||
|
|
3edf4a25be | ||
|
|
43237c2aee | ||
|
|
2fffdc3ef5 | ||
|
|
76e748f0ed | ||
|
|
c353119962 | ||
|
|
5fa4d3b242 | ||
|
|
068e0e26b0 | ||
|
|
f6ca77f8c8 | ||
|
|
4c7eda81ca | ||
|
|
3948af9e39 | ||
|
|
aec30e1944 | ||
|
|
4205b16769 | ||
|
|
4d13803b0c | ||
|
|
b950ac1318 | ||
|
|
1920be28d8 | ||
|
|
8b00772958 | ||
|
|
e2e38dc4b3 | ||
|
|
455f1be041 | ||
|
|
3e37368038 | ||
|
|
4b86e20a13 | ||
|
|
d9a14924eb | ||
|
|
7d9d322405 | ||
|
|
5365044017 | ||
|
|
069edf0847 | ||
|
|
2cdcf95822 | ||
|
|
e43231aa97 | ||
|
|
0df2acd5e6 | ||
|
|
3f0b3f190a | ||
|
|
504f143ff7 | ||
|
|
7cfc30c7a1 | ||
|
|
f3ed687f00 | ||
|
|
e37575148c | ||
|
|
2df9979f08 | ||
|
|
c8ce26d6a7 | ||
|
|
898fd4bbf6 | ||
|
|
744f7195dd | ||
|
|
bc4f51846d | ||
|
|
ab8dc131b8 | ||
|
|
684d33071e | ||
|
|
146e68fc53 | ||
|
|
655b87d876 | ||
|
|
71caa2f703 | ||
|
|
99c95a4c15 | ||
|
|
93632a7073 | ||
|
|
297265822b | ||
|
|
a7f799b5b6 | ||
|
|
b176ec6c96 | ||
|
|
1a008a4852 | ||
|
|
145de2bbbc | ||
|
|
77c516a6eb | ||
|
|
6835004945 | ||
|
|
e36823c159 | ||
|
|
ec6ac128f2 | ||
|
|
d80f47a6c8 | ||
|
|
3a9af7505f | ||
|
|
34ee954502 | ||
|
|
b9878a05a1 | ||
|
|
e9412bc404 | ||
|
|
6755115c8a | ||
|
|
e8ed4615fe | ||
|
|
c55f4c311f | ||
|
|
e063970c58 | ||
|
|
fdf8580f5f | ||
|
|
cffd37c6f1 | ||
|
|
7419b3f29e | ||
|
|
e2f50871ec | ||
|
|
bdea9fdab3 | ||
|
|
ae793c1c28 | ||
|
|
3d912036a7 | ||
|
|
1866077a82 | ||
|
|
8345f99603 | ||
|
|
2ab576a37c | ||
|
|
5b9ff7acb3 | ||
|
|
4cdb712013 | ||
|
|
e6fcfdb514 | ||
|
|
9df1800e10 | ||
|
|
95ba925d27 | ||
|
|
41882ddf23 | ||
|
|
fe9b543a75 | ||
|
|
191843f972 | ||
|
|
c1fde44809 | ||
|
|
1a3517e035 | ||
|
|
afec6d9851 | ||
|
|
e3f2fd70ad | ||
|
|
5adbec25c4 | ||
|
|
4ff8d77460 | ||
|
|
22faa6d294 | ||
|
|
a2abfa7f85 | ||
|
|
7b93b12fcb | ||
|
|
ed252d5dfe | ||
|
|
c365993541 | ||
|
|
30f9475208 | ||
|
|
454c526666 | ||
|
|
e67970d2b9 | ||
|
|
0f1c03d1e5 | ||
|
|
8394f2ec1e | ||
|
|
f14e73d811 | ||
|
|
23e00b4199 | ||
|
|
427b189a34 |
No files matched your search
@@ -73,10 +73,14 @@ jobs:
|
||||
with:
|
||||
repo-token: ${{ secrets.GH_TOKEN }}
|
||||
- uses: oven-sh/setup-bun@v2
|
||||
|
||||
- run: bun run setup
|
||||
|
||||
- name: AppArmor hack
|
||||
run: echo 0 | sudo tee /proc/sys/kernel/apparmor_restrict_unprivileged_userns
|
||||
|
||||
- name: Install patches
|
||||
run: bun run setup:patches --source=${{ github.event.inputs.asset_source || 'steam:444200/444202' }}
|
||||
|
||||
- name: Build assets
|
||||
run: bun run build:assets --all-targets --source=${{ github.event.inputs.asset_source || 'steam:444200/444202' }}
|
||||
@@ -28,7 +28,7 @@ jobs:
|
||||
run: bun run build:bot
|
||||
|
||||
- name: Archive build
|
||||
uses: actions/upload-artifact@v5
|
||||
uses: actions/upload-artifact@v7
|
||||
with:
|
||||
name: bot
|
||||
path: dist/bot
|
||||
@@ -1,13 +1,7 @@
|
||||
name: Host
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: main
|
||||
schedule:
|
||||
- cron: "0 */5 * * *"
|
||||
workflow_dispatch:
|
||||
release:
|
||||
types: [created, published, released, edited]
|
||||
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-${{ github.ref }}
|
||||
|
||||
@@ -46,14 +46,14 @@ jobs:
|
||||
- uses: arduino/setup-protoc@v3
|
||||
with:
|
||||
repo-token: ${{ secrets.GH_TOKEN }}
|
||||
- uses: actions/configure-pages@v5
|
||||
- uses: actions/configure-pages@v6
|
||||
- run: bun run setup
|
||||
|
||||
- name: Build website
|
||||
run: bun run build:website
|
||||
|
||||
- name: Upload artifact
|
||||
uses: actions/upload-pages-artifact@v4
|
||||
uses: actions/upload-pages-artifact@v5
|
||||
with:
|
||||
path: dist/website
|
||||
|
||||
@@ -69,4 +69,4 @@ jobs:
|
||||
steps:
|
||||
- name: Deploy to GitHub Pages
|
||||
id: deployment
|
||||
uses: actions/deploy-pages@v4
|
||||
uses: actions/deploy-pages@v5
|
||||
@@ -6,6 +6,7 @@
|
||||
"name": "blitzkit",
|
||||
"dependencies": {
|
||||
"@prisma/client": "^6.18.0",
|
||||
"lz4js": "^0.2.0",
|
||||
"prisma": "^6.18.0",
|
||||
"sharp": "^0.34.5",
|
||||
"typescript": "^5.9.3",
|
||||
@@ -78,7 +79,6 @@
|
||||
"dotenv": "^17.2.2",
|
||||
"fast-xml-parser": "^5.3.2",
|
||||
"lodash-es": "^4.17.21",
|
||||
"lz4js": "^0.2.0",
|
||||
"pickleparser": "^0.2.1",
|
||||
"protobufjs": "^7.5.4",
|
||||
"three": "^0.180.0",
|
||||
@@ -118,7 +118,6 @@
|
||||
"fast-xml-parser": "^5.2.5",
|
||||
"googleapis": "^162.0.0",
|
||||
"lodash-es": "^4.17.21",
|
||||
"lz4js": "^0.2.0",
|
||||
"progress": "^2.0.3",
|
||||
"puppeteer": "^24.22.3",
|
||||
"sharp": "^0.34.4",
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
{
|
||||
"words": [
|
||||
"Tankopedia"
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
# BlitzKit 1.29.15
|
||||
|
||||
## Fixes
|
||||
|
||||
- Tanks now use alpha clipping to render translucency, fixing a lot of "ghostly" looking tanks
|
||||
@@ -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
|
||||
@@ -0,0 +1,12 @@
|
||||
# BlitzKit 1.30.2
|
||||
|
||||
Thank you to [GonnaHetzMe](https://github.com/karelpak1) for your contributions this update.
|
||||
|
||||
## Fixes
|
||||
|
||||
- [GonnaHetzMe] Tungsten shells are now properly cropped
|
||||
- Equalizer no longer gives insanely high penetration values
|
||||
- The tank reveal animation no longer repeats when you scroll away and back to the tank sandbox
|
||||
- [GonnaHetzMe] The RHM. Pzw.'s turret no longer has the floating plate
|
||||
- Please give BlitzKit up to 1 hour to update the model
|
||||
- [GonnaHetzMe] Tanks with inclined turret rings like the Minotauro now display the correct pitch in the tank sandbox inputs
|
||||
@@ -0,0 +1,18 @@
|
||||
# BlitzKit 1.30.3
|
||||
|
||||
Thank you to [GonnaHetzMe](https://github.com/karelpak1) for your contributions this update.
|
||||
|
||||
## Features
|
||||
|
||||
- [GonnaHetzMe] Added tooltips to the module selector in Tankopedia
|
||||
|
||||
## Fixes
|
||||
|
||||
- Added aggressive re-rendering for the Guess mini-game's score readout to make inspect-element harder
|
||||
- Removed tank visual and collision model caching
|
||||
- Guesser once again breaks streaks if not all tiers are selected
|
||||
- BlitzKit now properly unloads tank models from memory when visually hidden in Guesser
|
||||
- [GonnaHetzMe] Tanks with complex transparency like the Herdbreaker once again handle opacity correctly
|
||||
- [GonnaHetzMe] Pieces of tank models that have transparency now handle culling properly (they're visible from both sides)
|
||||
- [GonnaHetzMe] Tanks with "cardboard" textures have been fixed, thanks to better PVR file parsing
|
||||
- [GonnaHetzMe] Tank icons are now scaled correctly so small tanks are now properly zoomed out in contrast to bigger ones
|
||||
@@ -0,0 +1,5 @@
|
||||
# BlitzKit 1.30.4
|
||||
|
||||
## Fixes
|
||||
|
||||
- BlitzKit now correctly implements minor WoTB updates
|
||||
@@ -0,0 +1,8 @@
|
||||
# BlitzKit 1.30.5
|
||||
|
||||
## Features
|
||||
|
||||
- Reduced the amount of code that executes for every rendered frame, hopefully improving performance
|
||||
- Reduced the number of lights by 20% to decrease the amount of shadow calculations
|
||||
- Decreased the ground size by 80% for an equal reduction in shadow texture sizes
|
||||
- Added the ability for BlitzKit to dismount the components that handled the intro lighting animation when not animating, reducing checks running every frame
|
||||
@@ -0,0 +1,7 @@
|
||||
# BlitzKit 1.30.6
|
||||
|
||||
## Fixes
|
||||
|
||||
- Tanks no longer "randomly" appear dark in Tankopedia and Mixer
|
||||
- The ground is now as dark as other modes when Static Armor is selected in Tankopedia
|
||||
- Fixed some naming issues with the "equal" icon, improving performance a tiny tiny bit
|
||||
@@ -0,0 +1,20 @@
|
||||
# BlitzKit 1.30.7
|
||||
|
||||
Thank you to [Mark Greene](https://github.com/Hitjack007) for your contributions this update.
|
||||
|
||||
## Features
|
||||
|
||||
- Dragging items in the Tier List now automatically scrolls the screen if you reach the top/bottom edge of the screen
|
||||
|
||||
## Fixes
|
||||
|
||||
- [Mark Greene] Clicking on the armor multiple times with HE no longer crashes BlitzKit
|
||||
- [Mark Greene] Ricochets that later intersect with external modules no longer falsely claim a successful damaging penetration
|
||||
- The lighting animation no longer stops prematurely when BlitzKit is unfocused
|
||||
- The spot light angle has been increased to more evenly light up larger tanks
|
||||
- BlitzKit once again uses soft shadows, reducing the pixelated shadows
|
||||
- Fixed the weird patterns that formed on the tracks of tanks under self-shadows
|
||||
- Increased the floor size and light decay to create the illusion that the floor is infinite
|
||||
- [Mark Greene] Safari no longer crashes when unloading textures for unloaded tanks
|
||||
- The gun depression transition between two constraints (like often behind tanks) now uses a gentler zoned and can never be 0
|
||||
- [Mark Greene] Armor plate names in Static Armor are now properly capitalized in English and translated to other languages
|
||||
+4
-3
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "blitzkit",
|
||||
"version": "1.29.14",
|
||||
"version": "1.30.7",
|
||||
"license": "BlitzKit License",
|
||||
"private": true,
|
||||
"scripts": {
|
||||
@@ -21,7 +21,7 @@
|
||||
"dev": "bun run dev:website",
|
||||
"dev:api": "bun --filter=@blitzkit/api run dev",
|
||||
"setup:depotdownloader": "bun --filter=@blitzkit/scripts run setup:depotdownloader",
|
||||
"setup:patches": "bun --filter=@blitzkit/scripts run setup:patches",
|
||||
"setup:patches": "mkdir -p packages/closed/node_modules && ln -sf ../../../node_modules/lz4js packages/closed/node_modules/lz4js && cd packages/scripts && bun run setup:patches",
|
||||
"start:website": "bun --filter=@blitzkit/website run start",
|
||||
"host:docs": "vitepress preview docs",
|
||||
"lint": "tsc",
|
||||
@@ -35,7 +35,7 @@
|
||||
"build:reviews": "cd packages/scripts && bun build:reviews",
|
||||
"build:ids": "cd packages/scripts && bun build:ids",
|
||||
"prunestrings": "cd packages/scripts && bun prunestrings",
|
||||
"setup": "bun install && bun run build:prisma && bun run build:protos && bun run build:proxyclient",
|
||||
"setup": "bun install && bun run build:prisma",
|
||||
"patchnotes": "cd packages/scripts && bun run patchnotes"
|
||||
},
|
||||
"type": "module",
|
||||
@@ -44,6 +44,7 @@
|
||||
],
|
||||
"dependencies": {
|
||||
"@prisma/client": "^6.18.0",
|
||||
"lz4js": "^0.2.0",
|
||||
"prisma": "^6.18.0",
|
||||
"sharp": "^0.34.5",
|
||||
"typescript": "^5.9.3"
|
||||
|
||||
@@ -43,7 +43,7 @@ export const ownedTanksCommand = new Promise<CommandRegistry>((resolve) => {
|
||||
tankStats.map(async (tankData) => ({
|
||||
tankDefinitions: (await tankDefinitions).tanks[tankData.tank_id]!,
|
||||
id: tankData.tank_id,
|
||||
}))
|
||||
})),
|
||||
)
|
||||
).filter((tank) => tank.tankDefinitions?.tier === tier);
|
||||
const groupedTanks: Record<string, TankDefinition[]> = {};
|
||||
@@ -69,16 +69,16 @@ export const ownedTanksCommand = new Promise<CommandRegistry>((resolve) => {
|
||||
.filter((tank) => tank.tier === tier)
|
||||
.sort(
|
||||
(a, b) =>
|
||||
TANK_CLASSES.indexOf(a.class) - TANK_CLASSES.indexOf(b.class)
|
||||
TANK_CLASSES.indexOf(a.class) - TANK_CLASSES.indexOf(b.class),
|
||||
)
|
||||
.sort(
|
||||
(a, b) =>
|
||||
awaitedGameDefinitions.nations.indexOf(a.nation) -
|
||||
awaitedGameDefinitions.nations.indexOf(b.nation)
|
||||
awaitedGameDefinitions.nations.indexOf(b.nation),
|
||||
)
|
||||
.map(
|
||||
(tank) =>
|
||||
`[${flags[tank.nation]} ${markdownEscape(unwrap(tank.name))}](<https://blitzkit.app/tanks/${tank.slug}>)`
|
||||
`[${flags[tank.nation]} ${markdownEscape(unwrap(tank.name!))}](<https://blitzkit.app/tanks/${tank.slug}>)`,
|
||||
);
|
||||
const lines = [title, ...tankList];
|
||||
|
||||
|
||||
@@ -280,7 +280,7 @@ async function playerListing(
|
||||
}}
|
||||
>
|
||||
<img
|
||||
alt={unwrap(tank.name)}
|
||||
alt={unwrap(tank.name!)}
|
||||
src={await iconPng(tankIcon(tank.id))}
|
||||
style={{
|
||||
width: 32,
|
||||
@@ -317,7 +317,7 @@ async function playerListing(
|
||||
fontSize: 16,
|
||||
}}
|
||||
>
|
||||
{unwrap(tank.name)}
|
||||
{unwrap(tank.name!)}
|
||||
</span>
|
||||
</div>
|
||||
|
||||
|
||||
@@ -35,49 +35,49 @@ export const researchCommand = new Promise<CommandRegistry>((resolve) => {
|
||||
command: createLocalizedCommand("research")
|
||||
.addStringOption((option) =>
|
||||
option
|
||||
.setName(strings.bot.commands.research.options.target_tank.name)
|
||||
.setName(strings.bot.commands.research.options.target_tank.name!)
|
||||
.setNameLocalizations(
|
||||
localizationObject(
|
||||
(strings) =>
|
||||
strings.bot.commands.research.options.target_tank.name,
|
||||
undefined,
|
||||
true
|
||||
)
|
||||
true,
|
||||
),
|
||||
)
|
||||
.setDescription(
|
||||
strings.bot.commands.research.options.target_tank.description
|
||||
strings.bot.commands.research.options.target_tank.description,
|
||||
)
|
||||
.setDescriptionLocalizations(
|
||||
localizationObject(
|
||||
(strings) =>
|
||||
strings.bot.commands.research.options.target_tank.description
|
||||
)
|
||||
strings.bot.commands.research.options.target_tank.description,
|
||||
),
|
||||
)
|
||||
.setAutocomplete(true)
|
||||
.setRequired(true)
|
||||
.setRequired(true),
|
||||
)
|
||||
.addStringOption((option) =>
|
||||
option
|
||||
.setName(strings.bot.commands.research.options.starting_tank.name)
|
||||
.setName(strings.bot.commands.research.options.starting_tank.name!)
|
||||
.setNameLocalizations(
|
||||
localizationObject(
|
||||
(strings) =>
|
||||
strings.bot.commands.research.options.starting_tank.name,
|
||||
undefined,
|
||||
true
|
||||
)
|
||||
true,
|
||||
),
|
||||
)
|
||||
.setDescription(
|
||||
strings.bot.commands.research.options.starting_tank.description
|
||||
strings.bot.commands.research.options.starting_tank.description,
|
||||
)
|
||||
.setDescriptionLocalizations(
|
||||
localizationObject(
|
||||
(strings) =>
|
||||
strings.bot.commands.research.options.starting_tank.description
|
||||
)
|
||||
strings.bot.commands.research.options.starting_tank.description,
|
||||
),
|
||||
)
|
||||
.setAutocomplete(true)
|
||||
.setRequired(false)
|
||||
.setRequired(false),
|
||||
)
|
||||
.addStringOption(addUsernameChoices),
|
||||
|
||||
@@ -87,7 +87,7 @@ export const researchCommand = new Promise<CommandRegistry>((resolve) => {
|
||||
const targetTankId = await resolveTankId(
|
||||
interaction.options.getString("target-tank", true),
|
||||
interaction.locale,
|
||||
true
|
||||
true,
|
||||
);
|
||||
const startingTankRaw = interaction.options.getString("starting-tank");
|
||||
const targetTank = awaitedTankDefinitions.tanks[targetTankId];
|
||||
@@ -99,13 +99,13 @@ export const researchCommand = new Promise<CommandRegistry>((resolve) => {
|
||||
startingTankId = await resolveTankId(
|
||||
startingTankRaw,
|
||||
interaction.locale,
|
||||
true
|
||||
true,
|
||||
);
|
||||
|
||||
if (targetTankId === startingTankId) {
|
||||
return literals(
|
||||
strings.bot.commands.research.errors.start_end_equal,
|
||||
{ tank: escapeMarkdown(unwrap(targetTank.name)) }
|
||||
{ tank: escapeMarkdown(unwrap(targettank.name!)) },
|
||||
);
|
||||
}
|
||||
|
||||
@@ -113,8 +113,8 @@ export const researchCommand = new Promise<CommandRegistry>((resolve) => {
|
||||
|
||||
if (startingTank.tier > targetTank.tier) {
|
||||
return literals(strings.bot.commands.research.errors.unordered, {
|
||||
tank_1: escapeMarkdown(unwrap(startingTank.name)),
|
||||
tank_2: escapeMarkdown(unwrap(targetTank.name)),
|
||||
tank_1: escapeMarkdown(unwrap(startingtank.name!)),
|
||||
tank_2: escapeMarkdown(unwrap(targettank.name!)),
|
||||
});
|
||||
}
|
||||
|
||||
@@ -122,21 +122,21 @@ export const researchCommand = new Promise<CommandRegistry>((resolve) => {
|
||||
return literals(
|
||||
strings.bot.commands.research.errors.tanks_not_on_line,
|
||||
{
|
||||
tank_1: escapeMarkdown(unwrap(targetTank.name)),
|
||||
tank_2: escapeMarkdown(unwrap(startingTank.name)),
|
||||
}
|
||||
tank_1: escapeMarkdown(unwrap(targettank.name!)),
|
||||
tank_2: escapeMarkdown(unwrap(startingtank.name!)),
|
||||
},
|
||||
);
|
||||
}
|
||||
} else {
|
||||
if (targetTank.type !== TankType.RESEARCHABLE) {
|
||||
if (targetTank.type !== TankType.TANK_TYPE_RESEARCHABLE) {
|
||||
return literals(strings.bot.commands.research.errors.non_tech_tree, {
|
||||
tank: escapeMarkdown(unwrap(targetTank.name)),
|
||||
tank: escapeMarkdown(unwrap(targettank.name!)),
|
||||
});
|
||||
}
|
||||
|
||||
if (targetTank.tier === 1) {
|
||||
return literals(strings.bot.commands.research.errors.tier_1, {
|
||||
tank: escapeMarkdown(unwrap(targetTank.name)),
|
||||
tank: escapeMarkdown(unwrap(targettank.name!)),
|
||||
});
|
||||
}
|
||||
|
||||
@@ -149,14 +149,14 @@ export const researchCommand = new Promise<CommandRegistry>((resolve) => {
|
||||
if (tankStats.some(({ tank_id }) => tank_id === targetTankId)) {
|
||||
return literals(
|
||||
strings.bot.commands.research.errors.already_researched,
|
||||
{ tank: escapeMarkdown(unwrap(targetTank.name)) }
|
||||
{ tank: escapeMarkdown(unwrap(targettank.name!)) },
|
||||
);
|
||||
}
|
||||
|
||||
const foundAncestor = targetTankAncestry.find(
|
||||
(id) =>
|
||||
awaitedTankDefinitions.tanks[id].tier === 1 ||
|
||||
tankStats.some(({ tank_id }) => tank_id === id)
|
||||
tankStats.some(({ tank_id }) => tank_id === id),
|
||||
);
|
||||
|
||||
if (foundAncestor === undefined) {
|
||||
@@ -168,7 +168,7 @@ export const researchCommand = new Promise<CommandRegistry>((resolve) => {
|
||||
|
||||
const techTreeLine = await buildTechTreeLine(
|
||||
startingTankId,
|
||||
targetTankId
|
||||
targetTankId,
|
||||
);
|
||||
|
||||
const line = [...techTreeLine, startingTankId].reverse();
|
||||
@@ -190,7 +190,7 @@ export const researchCommand = new Promise<CommandRegistry>((resolve) => {
|
||||
) {
|
||||
turretXps.set(
|
||||
turret.id,
|
||||
turret.research_cost.research_cost_type!.value
|
||||
turret.research_cost.research_cost_type!.value,
|
||||
);
|
||||
}
|
||||
|
||||
@@ -211,7 +211,7 @@ export const researchCommand = new Promise<CommandRegistry>((resolve) => {
|
||||
) {
|
||||
engineXps.set(
|
||||
engine.id,
|
||||
engine.research_cost.research_cost_type!.value
|
||||
engine.research_cost.research_cost_type!.value,
|
||||
);
|
||||
}
|
||||
});
|
||||
@@ -223,7 +223,7 @@ export const researchCommand = new Promise<CommandRegistry>((resolve) => {
|
||||
) {
|
||||
trackXps.set(
|
||||
track.id,
|
||||
track.research_cost.research_cost_type!.value
|
||||
track.research_cost.research_cost_type!.value,
|
||||
);
|
||||
}
|
||||
});
|
||||
@@ -245,13 +245,13 @@ export const researchCommand = new Promise<CommandRegistry>((resolve) => {
|
||||
return {
|
||||
research: tank.research_cost!.research_cost_type!.value as number,
|
||||
upgrades: moduleXp,
|
||||
purchase: tank.price.value,
|
||||
purchase: tank.price!.value,
|
||||
equipment: equipmentPriceMatrix[tank.tier].reduce(
|
||||
(a, b) => a + 3 * b,
|
||||
0
|
||||
0,
|
||||
),
|
||||
};
|
||||
})
|
||||
}),
|
||||
);
|
||||
|
||||
const image = (
|
||||
@@ -456,7 +456,7 @@ export const researchCommand = new Promise<CommandRegistry>((resolve) => {
|
||||
}}
|
||||
>
|
||||
<img
|
||||
alt={unwrap(tank.name)}
|
||||
alt={unwrap(tank.name!)}
|
||||
src={TANK_ICONS[tank.class]}
|
||||
width={16}
|
||||
height={16}
|
||||
@@ -467,7 +467,7 @@ export const researchCommand = new Promise<CommandRegistry>((resolve) => {
|
||||
color: theme.colors.textHighContrast,
|
||||
}}
|
||||
>
|
||||
{unwrap(tank.name)}
|
||||
{unwrap(tank.name!)}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
@@ -505,9 +505,9 @@ export const researchCommand = new Promise<CommandRegistry>((resolve) => {
|
||||
strings.bot.commands.research.body.research,
|
||||
{
|
||||
cost: costs[index].research?.toLocaleString(
|
||||
interaction.locale
|
||||
interaction.locale,
|
||||
),
|
||||
}
|
||||
},
|
||||
)}
|
||||
</span>
|
||||
</div>
|
||||
@@ -523,7 +523,7 @@ export const researchCommand = new Promise<CommandRegistry>((resolve) => {
|
||||
<img
|
||||
alt="Free XP icon"
|
||||
src={await iconPng(
|
||||
asset("icons/currencies/free-xp.webp")
|
||||
asset("icons/currencies/free-xp.webp"),
|
||||
)}
|
||||
width={16}
|
||||
height={16}
|
||||
@@ -536,7 +536,7 @@ export const researchCommand = new Promise<CommandRegistry>((resolve) => {
|
||||
>
|
||||
{literals(
|
||||
strings.bot.commands.research.body.upgrades,
|
||||
{ cost: costs[index].upgrades.toLocaleString() }
|
||||
{ cost: costs[index].upgrades.toLocaleString() },
|
||||
)}
|
||||
</span>
|
||||
</div>
|
||||
@@ -552,7 +552,7 @@ export const researchCommand = new Promise<CommandRegistry>((resolve) => {
|
||||
<img
|
||||
alt="Silver icon"
|
||||
src={await iconPng(
|
||||
asset("icons/currencies/silver.webp")
|
||||
asset("icons/currencies/silver.webp"),
|
||||
)}
|
||||
width={16}
|
||||
height={16}
|
||||
@@ -567,9 +567,9 @@ export const researchCommand = new Promise<CommandRegistry>((resolve) => {
|
||||
strings.bot.commands.research.body.purchase,
|
||||
{
|
||||
cost: costs[index].purchase.toLocaleString(
|
||||
interaction.locale
|
||||
interaction.locale,
|
||||
),
|
||||
}
|
||||
},
|
||||
)}
|
||||
</span>
|
||||
</div>
|
||||
@@ -584,7 +584,7 @@ export const researchCommand = new Promise<CommandRegistry>((resolve) => {
|
||||
<img
|
||||
alt="Silver icon"
|
||||
src={await iconPng(
|
||||
asset("icons/currencies/silver.webp")
|
||||
asset("icons/currencies/silver.webp"),
|
||||
)}
|
||||
width={16}
|
||||
height={16}
|
||||
@@ -599,16 +599,16 @@ export const researchCommand = new Promise<CommandRegistry>((resolve) => {
|
||||
strings.bot.commands.research.body.equipment,
|
||||
{
|
||||
cost: costs[index].equipment.toLocaleString(
|
||||
interaction.locale
|
||||
interaction.locale,
|
||||
),
|
||||
}
|
||||
},
|
||||
)}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
})
|
||||
}),
|
||||
)}
|
||||
</div>
|
||||
</CommandWrapper>
|
||||
|
||||
@@ -3,14 +3,14 @@ import {
|
||||
TankClass,
|
||||
TankType,
|
||||
TREE_TYPE_ICONS,
|
||||
} from '@blitzkit/core';
|
||||
import { createColors } from 'bepaint';
|
||||
} from "@blitzkit/core";
|
||||
import { createColors } from "bepaint";
|
||||
import {
|
||||
type AccentColor,
|
||||
type GrayColor,
|
||||
PALETTES,
|
||||
} from '../../../core/radix/radixColors';
|
||||
import { RowStat } from './RowStat';
|
||||
} from "../../../core/radix/radixColors";
|
||||
import { RowStat } from "./RowStat";
|
||||
|
||||
export interface RowStatItem {
|
||||
title: string;
|
||||
@@ -21,7 +21,7 @@ export interface RowStatItem {
|
||||
}
|
||||
|
||||
interface RowProps {
|
||||
displayType?: 'tank' | 'summary';
|
||||
displayType?: "tank" | "summary";
|
||||
naked?: boolean;
|
||||
title: string;
|
||||
minimized?: boolean;
|
||||
@@ -32,7 +32,7 @@ interface RowProps {
|
||||
}
|
||||
|
||||
export function Row({
|
||||
color = 'slate',
|
||||
color = "slate",
|
||||
stats,
|
||||
title,
|
||||
minimized,
|
||||
@@ -49,20 +49,20 @@ export function Row({
|
||||
className="session-tracker-row"
|
||||
style={{
|
||||
maxWidth: naked ? 600 : Infinity,
|
||||
display: 'flex',
|
||||
flexDirection: 'column',
|
||||
display: "flex",
|
||||
flexDirection: "column",
|
||||
borderRadius: 4,
|
||||
backgroundColor: naked
|
||||
? `${theme.appBackground2}c0`
|
||||
: theme.appBackground2,
|
||||
overflow: 'hidden',
|
||||
overflow: "hidden",
|
||||
}}
|
||||
>
|
||||
<div
|
||||
style={{
|
||||
display: 'flex',
|
||||
alignItems: 'center',
|
||||
justifyContent: 'center',
|
||||
display: "flex",
|
||||
alignItems: "center",
|
||||
justifyContent: "center",
|
||||
padding: 8,
|
||||
gap: 4,
|
||||
backgroundColor: naked
|
||||
@@ -70,10 +70,14 @@ export function Row({
|
||||
: theme.componentInteractive,
|
||||
}}
|
||||
>
|
||||
{displayType === 'tank' && tankClass !== undefined && (
|
||||
{displayType === "tank" && tankClass !== undefined && (
|
||||
<img
|
||||
alt={TankClass[tankClass]}
|
||||
src={TREE_TYPE_ICONS[type ?? TankType.RESEARCHABLE][tankClass]}
|
||||
src={
|
||||
TREE_TYPE_ICONS[type ?? TankType.TANK_TYPE_RESEARCHABLE][
|
||||
tankClass
|
||||
]
|
||||
}
|
||||
style={{ width: 16, height: 16 }}
|
||||
/>
|
||||
)}
|
||||
@@ -81,10 +85,10 @@ export function Row({
|
||||
<span
|
||||
style={{
|
||||
color:
|
||||
displayType === 'tank'
|
||||
? type === TankType.COLLECTOR
|
||||
displayType === "tank"
|
||||
? type === TankType.TANK_TYPE_COLLECTOR
|
||||
? theme.textLowContrast_blue
|
||||
: type === TankType.PREMIUM
|
||||
: type === TankType.TANK_TYPE_PREMIUM
|
||||
? theme.textLowContrast_amber
|
||||
: theme.textHighContrast
|
||||
: theme.textLowContrast,
|
||||
@@ -98,7 +102,7 @@ export function Row({
|
||||
|
||||
<div
|
||||
style={{
|
||||
display: 'flex',
|
||||
display: "flex",
|
||||
paddingTop: 8,
|
||||
paddingBottom: 8,
|
||||
}}
|
||||
@@ -109,8 +113,8 @@ export function Row({
|
||||
<RowStat
|
||||
minimized={minimized}
|
||||
key={index}
|
||||
name={`${row.title} • ${row.career ?? '--'}`}
|
||||
value={row.current ?? '--'}
|
||||
name={`${row.title} • ${row.career ?? "--"}`}
|
||||
value={row.current ?? "--"}
|
||||
delta={row.delta}
|
||||
percentile={row.percentile}
|
||||
/>
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { TankClass, TankType, TREE_TYPE_ICONS } from '@blitzkit/core';
|
||||
import { theme } from '../../../../stitches.config';
|
||||
import { TankClass, TankType, TREE_TYPE_ICONS } from "@blitzkit/core";
|
||||
import { theme } from "../../../../stitches.config";
|
||||
|
||||
export interface ItemProps {
|
||||
tankClass?: TankClass;
|
||||
@@ -8,9 +8,9 @@ export interface ItemProps {
|
||||
}
|
||||
|
||||
const TREE_TYPE_COLOR = {
|
||||
[TankType.RESEARCHABLE]: '',
|
||||
[TankType.PREMIUM]: '_amber',
|
||||
[TankType.COLLECTOR]: '_blue',
|
||||
[TankType.TANK_TYPE_RESEARCHABLE]: "",
|
||||
[TankType.TANK_TYPE_PREMIUM]: "_amber",
|
||||
[TankType.TANK_TYPE_COLLECTOR]: "_blue",
|
||||
} as const;
|
||||
|
||||
export function Item({
|
||||
@@ -21,12 +21,12 @@ export function Item({
|
||||
return (
|
||||
<div
|
||||
style={{
|
||||
display: 'flex',
|
||||
display: "flex",
|
||||
height: 32,
|
||||
paddingLeft: 8,
|
||||
paddingRight: 8,
|
||||
overflow: 'hidden',
|
||||
alignItems: 'center',
|
||||
overflow: "hidden",
|
||||
alignItems: "center",
|
||||
borderRadius: 4,
|
||||
backgroundColor:
|
||||
theme.colors[`componentInteractive${TREE_TYPE_COLOR[treeType]}`],
|
||||
@@ -34,12 +34,12 @@ export function Item({
|
||||
>
|
||||
<div
|
||||
style={{
|
||||
display: 'flex',
|
||||
display: "flex",
|
||||
gap: 4,
|
||||
flex: 1,
|
||||
alignItems: 'center',
|
||||
justifyContent: 'flex-start',
|
||||
overflow: 'hidden',
|
||||
alignItems: "center",
|
||||
justifyContent: "flex-start",
|
||||
overflow: "hidden",
|
||||
}}
|
||||
>
|
||||
{tankType && (
|
||||
@@ -52,7 +52,7 @@ export function Item({
|
||||
<span
|
||||
style={{
|
||||
fontSize: 16,
|
||||
whiteSpace: 'nowrap',
|
||||
whiteSpace: "nowrap",
|
||||
color: theme.colors[`textLowContrast${TREE_TYPE_COLOR[treeType]}`],
|
||||
}}
|
||||
>
|
||||
|
||||
@@ -6,21 +6,21 @@ import { translator } from "../localization/translator";
|
||||
|
||||
export async function filtersToDescription(
|
||||
{ nation, tier, type, class: tankClass, tank }: StatFilters,
|
||||
locale: Locale
|
||||
locale: Locale,
|
||||
) {
|
||||
const { strings, bkLocale } = translator(locale);
|
||||
const awaitedTankDefinitions = await fetchTankDefinitions();
|
||||
const info: string[] = [];
|
||||
|
||||
// TODO: somehow localize tank names?
|
||||
if (tank) return awaitedTankDefinitions.tanks[tank].name.locales[bkLocale];
|
||||
if (tank) return awaitedTankDefinitions.tanks[tank].name!.locales[bkLocale];
|
||||
if (nation)
|
||||
info.push((strings.common.nations as Record<string, string>)[nation]);
|
||||
if (tier) {
|
||||
info.push(
|
||||
literals(strings.bot.common.filters.tier, {
|
||||
tier: TIER_ROMAN_NUMERALS[tier],
|
||||
})
|
||||
}),
|
||||
);
|
||||
}
|
||||
if (tankClass) info.push(strings.common.tank_class_short[tankClass]);
|
||||
|
||||
@@ -34,12 +34,12 @@ export async function filterStats(
|
||||
(filters.tier === undefined || entry.tier === filters.tier) &&
|
||||
(filters.class === undefined || entry.class === filters.class) &&
|
||||
(filters.type === undefined ||
|
||||
(filters.type === TankType.COLLECTOR &&
|
||||
entry.type === TankType.COLLECTOR) ||
|
||||
(filters.type === TankType.PREMIUM &&
|
||||
entry.type === TankType.PREMIUM) ||
|
||||
(filters.type === TankType.RESEARCHABLE &&
|
||||
entry.type === TankType.RESEARCHABLE)) &&
|
||||
(filters.type === TankType.TANK_TYPE_COLLECTOR &&
|
||||
entry.type === TankType.TANK_TYPE_COLLECTOR) ||
|
||||
(filters.type === TankType.TANK_TYPE_PREMIUM &&
|
||||
entry.type === TankType.TANK_TYPE_PREMIUM) ||
|
||||
(filters.type === TankType.TANK_TYPE_RESEARCHABLE &&
|
||||
entry.type === TankType.TANK_TYPE_RESEARCHABLE)) &&
|
||||
(filters.tank === undefined || entry.id === filters.tank)
|
||||
);
|
||||
});
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
import { Locale, SlashCommandStringOption } from 'discord.js';
|
||||
import { translator } from '../localization/translator';
|
||||
import { localizationObject } from './localizationObject';
|
||||
import { Locale, SlashCommandStringOption } from "discord.js";
|
||||
import { translator } from "../localization/translator";
|
||||
import { localizationObject } from "./localizationObject";
|
||||
|
||||
export function addTankChoices(option: SlashCommandStringOption) {
|
||||
const { strings } = translator(Locale.EnglishUS);
|
||||
|
||||
return option
|
||||
.setName(strings.bot.common.options.tank.name)
|
||||
.setName(strings.bot.common.options.tank.name!)
|
||||
.setNameLocalizations(
|
||||
localizationObject(
|
||||
(strings) => strings.bot.common.options.tank.name,
|
||||
|
||||
@@ -13,13 +13,13 @@ import {
|
||||
} from "./autocompleteClan/constants";
|
||||
|
||||
export const tankNamesTechTreeOnly = fetchTankNames().then((names) =>
|
||||
names.filter((tank) => tank.treeType === TankType.RESEARCHABLE)
|
||||
names.filter((tank) => tank.treeType === TankType.TANK_TYPE_RESEARCHABLE),
|
||||
);
|
||||
|
||||
export async function autocompleteTanks(
|
||||
interaction: AutocompleteInteraction<CacheType>,
|
||||
techTreeOnly = false,
|
||||
fields = ["tank"]
|
||||
fields = ["tank"],
|
||||
) {
|
||||
const { unwrap } = translator(interaction.locale);
|
||||
const focusedOption = interaction.options.getFocused(true);
|
||||
@@ -31,7 +31,7 @@ export async function autocompleteTanks(
|
||||
go(
|
||||
focusedOption.value,
|
||||
await (techTreeOnly ? tankNamesTechTreeOnly : tankNames),
|
||||
{ keys: SEARCH_KEYS, limit: 10 }
|
||||
{ keys: SEARCH_KEYS, limit: 10 },
|
||||
).map(async (item) => {
|
||||
let name = unwrap(item.obj.searchableName);
|
||||
|
||||
@@ -42,7 +42,7 @@ export async function autocompleteTanks(
|
||||
0,
|
||||
unwrap(item.obj.searchableName).length -
|
||||
overSize -
|
||||
OVERFLOW_SUFFIX.length
|
||||
OVERFLOW_SUFFIX.length,
|
||||
)}${OVERFLOW_SUFFIX}`;
|
||||
}
|
||||
|
||||
@@ -50,8 +50,8 @@ export async function autocompleteTanks(
|
||||
name,
|
||||
value: `${item.obj.id}`,
|
||||
} satisfies ApplicationCommandOptionChoiceData<string>;
|
||||
})
|
||||
}),
|
||||
)
|
||||
: []
|
||||
: [],
|
||||
);
|
||||
}
|
||||
+1
-1
Submodule packages/closed updated: 5b4a85d503...f89f0e0772.
@@ -19,7 +19,6 @@
|
||||
"dotenv": "^17.2.2",
|
||||
"fast-xml-parser": "^5.3.2",
|
||||
"lodash-es": "^4.17.21",
|
||||
"lz4js": "^0.2.0",
|
||||
"pickleparser": "^0.2.1",
|
||||
"protobufjs": "^7.5.4",
|
||||
"three": "^0.180.0",
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
import { ShellDefinition, ShellType } from "../protos";
|
||||
|
||||
export function canSplash(type: ShellDefinition["type"]): type is ShellType.HE {
|
||||
return type === ShellType.HE;
|
||||
export function canSplash(
|
||||
type: ShellDefinition["type"],
|
||||
): type is ShellType.SHELL_TYPE_HE {
|
||||
return type === ShellType.SHELL_TYPE_HE;
|
||||
}
|
||||
@@ -2,22 +2,22 @@ import { TankClass, TankType } from "../protos";
|
||||
import type { BlitzStats } from "../statistics";
|
||||
|
||||
export const TANK_TYPES = [
|
||||
TankType.RESEARCHABLE,
|
||||
TankType.PREMIUM,
|
||||
TankType.COLLECTOR,
|
||||
TankType.TANK_TYPE_RESEARCHABLE,
|
||||
TankType.TANK_TYPE_PREMIUM,
|
||||
TankType.TANK_TYPE_COLLECTOR,
|
||||
];
|
||||
|
||||
export const TANK_TYPE_COMMAND_NAMES = {
|
||||
[TankType.RESEARCHABLE]: "researchable",
|
||||
[TankType.PREMIUM]: "premium",
|
||||
[TankType.COLLECTOR]: "collector",
|
||||
[TankType.TANK_TYPE_RESEARCHABLE]: "researchable",
|
||||
[TankType.TANK_TYPE_PREMIUM]: "premium",
|
||||
[TankType.TANK_TYPE_COLLECTOR]: "collector",
|
||||
};
|
||||
|
||||
export const TANK_CLASSES = [
|
||||
TankClass.LIGHT,
|
||||
TankClass.MEDIUM,
|
||||
TankClass.HEAVY,
|
||||
TankClass.TANK_DESTROYER,
|
||||
TankClass.TANK_CLASS_LIGHT,
|
||||
TankClass.TANK_CLASS_MEDIUM,
|
||||
TankClass.TANK_CLASS_HEAVY,
|
||||
TankClass.TANK_CLASS_TANK_DESTROYER,
|
||||
];
|
||||
|
||||
export const emptyAllStats: BlitzStats = {
|
||||
|
||||
@@ -9,7 +9,7 @@ import {
|
||||
export function checkConsumableProvisionInclusivity(
|
||||
consumableProvision: Consumable | Provision,
|
||||
tank: TankDefinition,
|
||||
gun: GunDefinition
|
||||
gun: GunDefinition,
|
||||
) {
|
||||
const included = consumableProvision.include?.every((rule) => {
|
||||
switch (rule.filter_type!.$case) {
|
||||
@@ -46,7 +46,7 @@ export function checkConsumableProvisionInclusivity(
|
||||
case "categories":
|
||||
return rule.filter_type!.value.categories.some((category) => {
|
||||
switch (category) {
|
||||
case ConsumableTankCategoryFilterCategory.CLIP:
|
||||
case ConsumableTankCategoryFilterCategory.CONSUMABLE_TANK_CATEGORY_FILTER_CATEGORY_CLIP:
|
||||
return gun.gun_type!.$case !== "regular";
|
||||
}
|
||||
});
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { ShellDefinition, ShellType } from "../protos";
|
||||
|
||||
export function isExplosive(
|
||||
type: ShellDefinition["type"]
|
||||
): type is ShellType.HEAT | ShellType.HE {
|
||||
return type === ShellType.HEAT || type === ShellType.HE;
|
||||
type: ShellDefinition["type"],
|
||||
): type is ShellType.SHELL_TYPE_HEAT | ShellType.SHELL_TYPE_HE {
|
||||
return type === ShellType.SHELL_TYPE_HEAT || type === ShellType.SHELL_TYPE_HE;
|
||||
}
|
||||
@@ -2,27 +2,27 @@ import { TANK_CLASSES } from "../blitz/constants";
|
||||
import { GameDefinitions, TankDefinition, TankType } from "../protos";
|
||||
|
||||
const treeTypeOrder = [
|
||||
TankType.RESEARCHABLE,
|
||||
TankType.PREMIUM,
|
||||
TankType.COLLECTOR,
|
||||
TankType.TANK_TYPE_RESEARCHABLE,
|
||||
TankType.TANK_TYPE_PREMIUM,
|
||||
TankType.TANK_TYPE_COLLECTOR,
|
||||
];
|
||||
|
||||
export function metaSortTank(
|
||||
tanks: TankDefinition[],
|
||||
gameDefinitions: GameDefinitions
|
||||
gameDefinitions: GameDefinitions,
|
||||
) {
|
||||
return tanks
|
||||
.sort((a, b) => b.tier - a.tier)
|
||||
.sort(
|
||||
(a, b) => treeTypeOrder.indexOf(b.type) - treeTypeOrder.indexOf(a.type)
|
||||
(a, b) => treeTypeOrder.indexOf(b.type) - treeTypeOrder.indexOf(a.type),
|
||||
)
|
||||
.sort(
|
||||
(a, b) => TANK_CLASSES.indexOf(b.class) - TANK_CLASSES.indexOf(a.class)
|
||||
(a, b) => TANK_CLASSES.indexOf(b.class) - TANK_CLASSES.indexOf(a.class),
|
||||
)
|
||||
.sort(
|
||||
(a, b) =>
|
||||
gameDefinitions.nations.indexOf(b.nation) -
|
||||
gameDefinitions.nations.indexOf(a.nation)
|
||||
gameDefinitions.nations.indexOf(a.nation),
|
||||
)
|
||||
.sort((a, b) => a.tier - b.tier);
|
||||
}
|
||||
@@ -2,8 +2,8 @@ import { BoundingBox, Vector3 } from "../protos";
|
||||
|
||||
export function normalizeBoundingBox(boundingBox: BoundingBox) {
|
||||
return {
|
||||
x: boundingBox.max.x - boundingBox.min.x,
|
||||
y: boundingBox.max.y - boundingBox.min.y,
|
||||
z: boundingBox.max.z - boundingBox.min.z,
|
||||
x: boundingBox.max!.x - boundingBox.min!.x,
|
||||
y: boundingBox.max!.y - boundingBox.min!.y,
|
||||
z: boundingBox.max!.z - boundingBox.min!.z,
|
||||
} satisfies Vector3;
|
||||
}
|
||||
@@ -1,16 +1,21 @@
|
||||
import { ShellType } from '../protos';
|
||||
import { Equalizer, ShellType } from "../protos";
|
||||
|
||||
export function resolvePenetrationCoefficient(
|
||||
calibratedShells: boolean,
|
||||
equalize: boolean,
|
||||
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
|
||||
? 1.08
|
||||
: type === ShellType.APCR
|
||||
? 1.05
|
||||
: type === ShellType.HEAT
|
||||
? 1.13
|
||||
: 1.08;
|
||||
return calibrated * equalizer;
|
||||
}
|
||||
@@ -1,74 +1,74 @@
|
||||
import { times } from 'lodash-es';
|
||||
import { CrewType, ShellType, TankClass, TankType } from '../../protos';
|
||||
import { times } from "lodash-es";
|
||||
import { CrewType, ShellType, TankClass, TankType } from "../../protos";
|
||||
|
||||
export const SHELL_NAMES: Record<ShellType, string> = {
|
||||
[ShellType.AP]: 'AP',
|
||||
[ShellType.APCR]: 'APCR',
|
||||
[ShellType.HEAT]: 'HEAT',
|
||||
[ShellType.HE]: 'HE',
|
||||
[ShellType.SHELL_TYPE_AP]: "AP",
|
||||
[ShellType.SHELL_TYPE_APCR]: "APCR",
|
||||
[ShellType.SHELL_TYPE_HEAT]: "HEAT",
|
||||
[ShellType.SHELL_TYPE_HE]: "HE",
|
||||
};
|
||||
export const CREW_MEMBER_NAMES = {
|
||||
[CrewType.COMMANDER]: 'commander',
|
||||
[CrewType.DRIVER]: 'driver',
|
||||
[CrewType.GUNNER]: 'gunner',
|
||||
[CrewType.LOADER]: 'loader',
|
||||
[CrewType.RADIOMAN]: 'radioman',
|
||||
[CrewType.CREW_TYPE_COMMANDER]: "commander",
|
||||
[CrewType.CREW_TYPE_DRIVER]: "driver",
|
||||
[CrewType.CREW_TYPE_GUNNER]: "gunner",
|
||||
[CrewType.CREW_TYPE_LOADER]: "loader",
|
||||
[CrewType.CREW_TYPE_RADIOMAN]: "radioman",
|
||||
} as const;
|
||||
|
||||
/**
|
||||
* @deprecated use svg
|
||||
*/
|
||||
export const TANK_ICONS: Record<TankClass, string> = {
|
||||
[TankClass.TANK_DESTROYER]: 'https://i.imgur.com/BIHSEH0.png',
|
||||
[TankClass.LIGHT]: 'https://i.imgur.com/CSNha5V.png',
|
||||
[TankClass.MEDIUM]: 'https://i.imgur.com/wvf3ltm.png',
|
||||
[TankClass.HEAVY]: 'https://i.imgur.com/ECeqlZa.png',
|
||||
[TankClass.TANK_CLASS_TANK_DESTROYER]: "https://i.imgur.com/BIHSEH0.png",
|
||||
[TankClass.TANK_CLASS_LIGHT]: "https://i.imgur.com/CSNha5V.png",
|
||||
[TankClass.TANK_CLASS_MEDIUM]: "https://i.imgur.com/wvf3ltm.png",
|
||||
[TankClass.TANK_CLASS_HEAVY]: "https://i.imgur.com/ECeqlZa.png",
|
||||
};
|
||||
/**
|
||||
* @deprecated use svg
|
||||
*/
|
||||
export const TANK_ICONS_PREMIUM: Record<TankClass, string> = {
|
||||
[TankClass.TANK_DESTROYER]: 'https://i.imgur.com/TCu3EdR.png',
|
||||
[TankClass.LIGHT]: 'https://i.imgur.com/zdkpTRb.png',
|
||||
[TankClass.MEDIUM]: 'https://i.imgur.com/3z7eHX6.png',
|
||||
[TankClass.HEAVY]: 'https://i.imgur.com/P3vbmyA.png',
|
||||
[TankClass.TANK_CLASS_TANK_DESTROYER]: "https://i.imgur.com/TCu3EdR.png",
|
||||
[TankClass.TANK_CLASS_LIGHT]: "https://i.imgur.com/zdkpTRb.png",
|
||||
[TankClass.TANK_CLASS_MEDIUM]: "https://i.imgur.com/3z7eHX6.png",
|
||||
[TankClass.TANK_CLASS_HEAVY]: "https://i.imgur.com/P3vbmyA.png",
|
||||
};
|
||||
/**
|
||||
* @deprecated use svg
|
||||
*/
|
||||
export const TANK_ICONS_COLLECTOR: Record<TankClass, string> = {
|
||||
[TankClass.TANK_DESTROYER]: 'https://i.imgur.com/WTjeirB.png',
|
||||
[TankClass.LIGHT]: 'https://i.imgur.com/EwhtKkU.png',
|
||||
[TankClass.MEDIUM]: 'https://i.imgur.com/u8YDMBh.png',
|
||||
[TankClass.HEAVY]: 'https://i.imgur.com/8xRf3nc.png',
|
||||
[TankClass.TANK_CLASS_TANK_DESTROYER]: "https://i.imgur.com/WTjeirB.png",
|
||||
[TankClass.TANK_CLASS_LIGHT]: "https://i.imgur.com/EwhtKkU.png",
|
||||
[TankClass.TANK_CLASS_MEDIUM]: "https://i.imgur.com/u8YDMBh.png",
|
||||
[TankClass.TANK_CLASS_HEAVY]: "https://i.imgur.com/8xRf3nc.png",
|
||||
};
|
||||
export const TIERS = times(10, (index) => index + 1);
|
||||
export const TIER_ROMAN_NUMERALS: Record<number, string> = {
|
||||
1: 'I',
|
||||
2: 'II',
|
||||
3: 'III',
|
||||
4: 'IV',
|
||||
5: 'V',
|
||||
6: 'VI',
|
||||
7: 'VII',
|
||||
8: 'VIII',
|
||||
9: 'IX',
|
||||
10: 'X',
|
||||
1: "I",
|
||||
2: "II",
|
||||
3: "III",
|
||||
4: "IV",
|
||||
5: "V",
|
||||
6: "VI",
|
||||
7: "VII",
|
||||
8: "VIII",
|
||||
9: "IX",
|
||||
10: "X",
|
||||
};
|
||||
|
||||
export const flags: Record<string, string> = {
|
||||
ussr: '<:ussr:1218421042033197197>',
|
||||
germany: '🇩🇪',
|
||||
usa: '🇺🇸',
|
||||
china: '🇨🇳',
|
||||
uk: '🇬🇧',
|
||||
france: '🇫🇷',
|
||||
japan: '🇯🇵',
|
||||
european: '🇪🇺',
|
||||
other: '<:other:1218421572243558482>',
|
||||
ussr: "<:ussr:1218421042033197197>",
|
||||
germany: "🇩🇪",
|
||||
usa: "🇺🇸",
|
||||
china: "🇨🇳",
|
||||
uk: "🇬🇧",
|
||||
france: "🇫🇷",
|
||||
japan: "🇯🇵",
|
||||
european: "🇪🇺",
|
||||
other: "<:other:1218421572243558482>",
|
||||
};
|
||||
export const TREE_TYPE_ICONS: Record<TankType, Record<TankClass, string>> = {
|
||||
[TankType.RESEARCHABLE]: TANK_ICONS,
|
||||
[TankType.PREMIUM]: TANK_ICONS_PREMIUM,
|
||||
[TankType.COLLECTOR]: TANK_ICONS_COLLECTOR,
|
||||
[TankType.TANK_TYPE_RESEARCHABLE]: TANK_ICONS,
|
||||
[TankType.TANK_TYPE_PREMIUM]: TANK_ICONS_PREMIUM,
|
||||
[TankType.TANK_TYPE_COLLECTOR]: TANK_ICONS_COLLECTOR,
|
||||
};
|
||||
@@ -15,7 +15,7 @@ export async function fetchTankNames() {
|
||||
tankDefinitionsArray.map(async (tank) => {
|
||||
const searchableNameDeburr: I18nString = { locales: {} };
|
||||
|
||||
Object.entries(tank.name).forEach(([key, value]) => {
|
||||
Object.entries(tank.name!).forEach(([key, value]) => {
|
||||
searchableNameDeburr.locales[key] = deburr(value);
|
||||
});
|
||||
|
||||
@@ -28,8 +28,8 @@ export async function fetchTankNames() {
|
||||
?.map((id) =>
|
||||
locales.supported.map(
|
||||
({ locale }) =>
|
||||
camouflageDefinitions.camouflages[id]?.name.locales[locale]
|
||||
)
|
||||
camouflageDefinitions.camouflages[id]?.name!.locales[locale],
|
||||
),
|
||||
)
|
||||
.flat()
|
||||
.filter(Boolean)
|
||||
@@ -37,7 +37,7 @@ export async function fetchTankNames() {
|
||||
.join(" "),
|
||||
treeType: tank.type,
|
||||
};
|
||||
})
|
||||
}),
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -3,14 +3,14 @@ import { BoundingBox } from "../protos";
|
||||
export function unionBoundingBox(a: BoundingBox, b: BoundingBox) {
|
||||
return {
|
||||
min: {
|
||||
x: Math.min(a.min.x, b.min.x),
|
||||
y: Math.min(a.min.y, b.min.y),
|
||||
z: Math.min(a.min.z, b.min.z),
|
||||
x: Math.min(a.min!.x, b.min!.x),
|
||||
y: Math.min(a.min!.y, b.min!.y),
|
||||
z: Math.min(a.min!.z, b.min!.z),
|
||||
},
|
||||
max: {
|
||||
x: Math.max(a.max.x, b.max.x),
|
||||
y: Math.max(a.max.y, b.max.y),
|
||||
z: Math.max(a.max.z, b.max.z),
|
||||
x: Math.max(a.max!.x, b.max!.x),
|
||||
y: Math.max(a.max!.y, b.max!.y),
|
||||
z: Math.max(a.max!.z, b.max!.z),
|
||||
},
|
||||
} satisfies BoundingBox;
|
||||
}
|
||||
@@ -4,44 +4,44 @@ package blitzkit;
|
||||
|
||||
message AverageDefinitions {
|
||||
map<uint32, AverageDefinitionsEntry> averages = 1;
|
||||
required Samples samples = 2;
|
||||
required uint64 time = 3;
|
||||
required Samples samples = 2;
|
||||
required uint64 time = 3;
|
||||
}
|
||||
|
||||
message AverageDefinitionsEntry {
|
||||
required AverageDefinitionsAllStats mu = 1;
|
||||
required AverageDefinitionsAllStats sigma = 2;
|
||||
required AverageDefinitionsAllStats r = 3;
|
||||
required Samples samples = 4;
|
||||
required AverageDefinitionsAllStats mu = 1;
|
||||
required AverageDefinitionsAllStats sigma = 2;
|
||||
required AverageDefinitionsAllStats r = 3;
|
||||
required Samples samples = 4;
|
||||
}
|
||||
|
||||
message AverageDefinitionsAllStats {
|
||||
required float battles = 1;
|
||||
required float capture_points = 2;
|
||||
required float damage_dealt = 3;
|
||||
required float damage_received = 4;
|
||||
required float battles = 1;
|
||||
required float capture_points = 2;
|
||||
required float damage_dealt = 3;
|
||||
required float damage_received = 4;
|
||||
required float dropped_capture_points = 5;
|
||||
required float frags = 6;
|
||||
required float frags8p = 7;
|
||||
required float hits = 8;
|
||||
required float losses = 9;
|
||||
required float max_frags = 10;
|
||||
required float max_xp = 11;
|
||||
required float shots = 12;
|
||||
required float spotted = 13;
|
||||
required float survived_battles = 14;
|
||||
required float win_and_survived = 15;
|
||||
required float wins = 16;
|
||||
required float xp = 17;
|
||||
required float battle_life_time = 18;
|
||||
required float frags = 6;
|
||||
required float frags8p = 7;
|
||||
required float hits = 8;
|
||||
required float losses = 9;
|
||||
required float max_frags = 10;
|
||||
required float max_xp = 11;
|
||||
required float shots = 12;
|
||||
required float spotted = 13;
|
||||
required float survived_battles = 14;
|
||||
required float win_and_survived = 15;
|
||||
required float wins = 16;
|
||||
required float xp = 17;
|
||||
required float battle_life_time = 18;
|
||||
}
|
||||
|
||||
message Samples {
|
||||
required uint32 d_1 = 1;
|
||||
required uint32 d_7 = 2;
|
||||
required uint32 d_30 = 3;
|
||||
required uint32 d_60 = 4;
|
||||
required uint32 d_90 = 5;
|
||||
required uint32 d_1 = 1;
|
||||
required uint32 d_7 = 2;
|
||||
required uint32 d_30 = 3;
|
||||
required uint32 d_60 = 4;
|
||||
required uint32 d_90 = 5;
|
||||
required uint32 d_120 = 6;
|
||||
required uint32 total = 7;
|
||||
}
|
||||
@@ -1,8 +1,8 @@
|
||||
// Code generated by protoc-gen-ts_proto. DO NOT EDIT.
|
||||
// versions:
|
||||
// protoc-gen-ts_proto v2.2.2
|
||||
// protoc-gen-ts_proto v2.11.2
|
||||
// protoc v5.28.2
|
||||
// source: packages/core/src/protos/average_definitions.proto
|
||||
// source: average_definitions.proto
|
||||
|
||||
/* eslint-disable */
|
||||
import { BinaryReader, BinaryWriter } from "@bufbuild/protobuf/wire";
|
||||
@@ -11,7 +11,7 @@ export const protobufPackage = "blitzkit";
|
||||
|
||||
export interface AverageDefinitions {
|
||||
averages: { [key: number]: AverageDefinitionsEntry };
|
||||
samples: Samples;
|
||||
samples: Samples | undefined;
|
||||
time: number;
|
||||
}
|
||||
|
||||
@@ -21,10 +21,10 @@ export interface AverageDefinitions_AveragesEntry {
|
||||
}
|
||||
|
||||
export interface AverageDefinitionsEntry {
|
||||
mu: AverageDefinitionsAllStats;
|
||||
sigma: AverageDefinitionsAllStats;
|
||||
r: AverageDefinitionsAllStats;
|
||||
samples: Samples;
|
||||
mu: AverageDefinitionsAllStats | undefined;
|
||||
sigma: AverageDefinitionsAllStats | undefined;
|
||||
r: AverageDefinitionsAllStats | undefined;
|
||||
samples: Samples | undefined;
|
||||
}
|
||||
|
||||
export interface AverageDefinitionsAllStats {
|
||||
@@ -58,13 +58,13 @@ export interface Samples {
|
||||
total: number;
|
||||
}
|
||||
|
||||
export function createBaseAverageDefinitions(): AverageDefinitions {
|
||||
return { averages: {}, samples: createBaseSamples(), time: 0 };
|
||||
function createBaseAverageDefinitions(): AverageDefinitions {
|
||||
return { averages: {}, samples: undefined, time: 0 };
|
||||
}
|
||||
|
||||
export const AverageDefinitions: MessageFns<AverageDefinitions> = {
|
||||
encode(message: AverageDefinitions, writer: BinaryWriter = new BinaryWriter()): BinaryWriter {
|
||||
Object.entries(message.averages).forEach(([key, value]) => {
|
||||
globalThis.Object.entries(message.averages).forEach(([key, value]: [string, AverageDefinitionsEntry]) => {
|
||||
AverageDefinitions_AveragesEntry.encode({ key: key as any, value }, writer.uint32(10).fork()).join();
|
||||
});
|
||||
if (message.samples !== undefined) {
|
||||
@@ -78,7 +78,7 @@ export const AverageDefinitions: MessageFns<AverageDefinitions> = {
|
||||
|
||||
decode(input: BinaryReader | Uint8Array, length?: number): AverageDefinitions {
|
||||
const reader = input instanceof BinaryReader ? input : new BinaryReader(input);
|
||||
let end = length === undefined ? reader.len : reader.pos + length;
|
||||
const end = length === undefined ? reader.len : reader.pos + length;
|
||||
const message = createBaseAverageDefinitions();
|
||||
while (reader.pos < end) {
|
||||
const tag = reader.uint32();
|
||||
@@ -122,20 +122,23 @@ export const AverageDefinitions: MessageFns<AverageDefinitions> = {
|
||||
fromJSON(object: any): AverageDefinitions {
|
||||
return {
|
||||
averages: isObject(object.averages)
|
||||
? Object.entries(object.averages).reduce<{ [key: number]: AverageDefinitionsEntry }>((acc, [key, value]) => {
|
||||
acc[globalThis.Number(key)] = AverageDefinitionsEntry.fromJSON(value);
|
||||
return acc;
|
||||
}, {})
|
||||
? (globalThis.Object.entries(object.averages) as [string, any][]).reduce(
|
||||
(acc: { [key: number]: AverageDefinitionsEntry }, [key, value]: [string, any]) => {
|
||||
acc[globalThis.Number(key)] = AverageDefinitionsEntry.fromJSON(value);
|
||||
return acc;
|
||||
},
|
||||
{},
|
||||
)
|
||||
: {},
|
||||
samples: Samples.fromJSON(assertSet("AverageDefinitions.samples", object.samples)),
|
||||
time: globalThis.Number(assertSet("AverageDefinitions.time", object.time)),
|
||||
samples: isSet(object.samples) ? Samples.fromJSON(object.samples) : undefined,
|
||||
time: isSet(object.time) ? globalThis.Number(object.time) : 0,
|
||||
};
|
||||
},
|
||||
|
||||
toJSON(message: AverageDefinitions): unknown {
|
||||
const obj: any = {};
|
||||
if (message.averages) {
|
||||
const entries = Object.entries(message.averages);
|
||||
const entries = globalThis.Object.entries(message.averages) as [string, AverageDefinitionsEntry][];
|
||||
if (entries.length > 0) {
|
||||
obj.averages = {};
|
||||
entries.forEach(([k, v]) => {
|
||||
@@ -157,8 +160,8 @@ export const AverageDefinitions: MessageFns<AverageDefinitions> = {
|
||||
},
|
||||
fromPartial<I extends Exact<DeepPartial<AverageDefinitions>, I>>(object: I): AverageDefinitions {
|
||||
const message = createBaseAverageDefinitions();
|
||||
message.averages = Object.entries(object.averages ?? {}).reduce<{ [key: number]: AverageDefinitionsEntry }>(
|
||||
(acc, [key, value]) => {
|
||||
message.averages = (globalThis.Object.entries(object.averages ?? {}) as [string, AverageDefinitionsEntry][]).reduce(
|
||||
(acc: { [key: number]: AverageDefinitionsEntry }, [key, value]: [string, AverageDefinitionsEntry]) => {
|
||||
if (value !== undefined) {
|
||||
acc[globalThis.Number(key)] = AverageDefinitionsEntry.fromPartial(value);
|
||||
}
|
||||
@@ -168,19 +171,19 @@ export const AverageDefinitions: MessageFns<AverageDefinitions> = {
|
||||
);
|
||||
message.samples = (object.samples !== undefined && object.samples !== null)
|
||||
? Samples.fromPartial(object.samples)
|
||||
: createBaseSamples();
|
||||
: undefined;
|
||||
message.time = object.time ?? 0;
|
||||
return message;
|
||||
},
|
||||
};
|
||||
|
||||
export function createBaseAverageDefinitions_AveragesEntry(): AverageDefinitions_AveragesEntry {
|
||||
return { key: 0, value: createBaseAverageDefinitionsEntry() };
|
||||
function createBaseAverageDefinitions_AveragesEntry(): AverageDefinitions_AveragesEntry {
|
||||
return { key: 0, value: undefined };
|
||||
}
|
||||
|
||||
export const AverageDefinitions_AveragesEntry: MessageFns<AverageDefinitions_AveragesEntry> = {
|
||||
encode(message: AverageDefinitions_AveragesEntry, writer: BinaryWriter = new BinaryWriter()): BinaryWriter {
|
||||
if (message.key !== undefined) {
|
||||
if (message.key !== 0) {
|
||||
writer.uint32(8).uint32(message.key);
|
||||
}
|
||||
if (message.value !== undefined) {
|
||||
@@ -191,7 +194,7 @@ export const AverageDefinitions_AveragesEntry: MessageFns<AverageDefinitions_Ave
|
||||
|
||||
decode(input: BinaryReader | Uint8Array, length?: number): AverageDefinitions_AveragesEntry {
|
||||
const reader = input instanceof BinaryReader ? input : new BinaryReader(input);
|
||||
let end = length === undefined ? reader.len : reader.pos + length;
|
||||
const end = length === undefined ? reader.len : reader.pos + length;
|
||||
const message = createBaseAverageDefinitions_AveragesEntry();
|
||||
while (reader.pos < end) {
|
||||
const tag = reader.uint32();
|
||||
@@ -223,14 +226,14 @@ export const AverageDefinitions_AveragesEntry: MessageFns<AverageDefinitions_Ave
|
||||
|
||||
fromJSON(object: any): AverageDefinitions_AveragesEntry {
|
||||
return {
|
||||
key: globalThis.Number(assertSet("AverageDefinitions_AveragesEntry.key", object.key)),
|
||||
value: AverageDefinitionsEntry.fromJSON(assertSet("AverageDefinitions_AveragesEntry.value", object.value)),
|
||||
key: isSet(object.key) ? globalThis.Number(object.key) : 0,
|
||||
value: isSet(object.value) ? AverageDefinitionsEntry.fromJSON(object.value) : undefined,
|
||||
};
|
||||
},
|
||||
|
||||
toJSON(message: AverageDefinitions_AveragesEntry): unknown {
|
||||
const obj: any = {};
|
||||
if (message.key !== undefined) {
|
||||
if (message.key !== 0) {
|
||||
obj.key = Math.round(message.key);
|
||||
}
|
||||
if (message.value !== undefined) {
|
||||
@@ -251,18 +254,13 @@ export const AverageDefinitions_AveragesEntry: MessageFns<AverageDefinitions_Ave
|
||||
message.key = object.key ?? 0;
|
||||
message.value = (object.value !== undefined && object.value !== null)
|
||||
? AverageDefinitionsEntry.fromPartial(object.value)
|
||||
: createBaseAverageDefinitionsEntry();
|
||||
: undefined;
|
||||
return message;
|
||||
},
|
||||
};
|
||||
|
||||
export function createBaseAverageDefinitionsEntry(): AverageDefinitionsEntry {
|
||||
return {
|
||||
mu: createBaseAverageDefinitionsAllStats(),
|
||||
sigma: createBaseAverageDefinitionsAllStats(),
|
||||
r: createBaseAverageDefinitionsAllStats(),
|
||||
samples: createBaseSamples(),
|
||||
};
|
||||
function createBaseAverageDefinitionsEntry(): AverageDefinitionsEntry {
|
||||
return { mu: undefined, sigma: undefined, r: undefined, samples: undefined };
|
||||
}
|
||||
|
||||
export const AverageDefinitionsEntry: MessageFns<AverageDefinitionsEntry> = {
|
||||
@@ -284,7 +282,7 @@ export const AverageDefinitionsEntry: MessageFns<AverageDefinitionsEntry> = {
|
||||
|
||||
decode(input: BinaryReader | Uint8Array, length?: number): AverageDefinitionsEntry {
|
||||
const reader = input instanceof BinaryReader ? input : new BinaryReader(input);
|
||||
let end = length === undefined ? reader.len : reader.pos + length;
|
||||
const end = length === undefined ? reader.len : reader.pos + length;
|
||||
const message = createBaseAverageDefinitionsEntry();
|
||||
while (reader.pos < end) {
|
||||
const tag = reader.uint32();
|
||||
@@ -332,10 +330,10 @@ export const AverageDefinitionsEntry: MessageFns<AverageDefinitionsEntry> = {
|
||||
|
||||
fromJSON(object: any): AverageDefinitionsEntry {
|
||||
return {
|
||||
mu: AverageDefinitionsAllStats.fromJSON(assertSet("AverageDefinitionsEntry.mu", object.mu)),
|
||||
sigma: AverageDefinitionsAllStats.fromJSON(assertSet("AverageDefinitionsEntry.sigma", object.sigma)),
|
||||
r: AverageDefinitionsAllStats.fromJSON(assertSet("AverageDefinitionsEntry.r", object.r)),
|
||||
samples: Samples.fromJSON(assertSet("AverageDefinitionsEntry.samples", object.samples)),
|
||||
mu: isSet(object.mu) ? AverageDefinitionsAllStats.fromJSON(object.mu) : undefined,
|
||||
sigma: isSet(object.sigma) ? AverageDefinitionsAllStats.fromJSON(object.sigma) : undefined,
|
||||
r: isSet(object.r) ? AverageDefinitionsAllStats.fromJSON(object.r) : undefined,
|
||||
samples: isSet(object.samples) ? Samples.fromJSON(object.samples) : undefined,
|
||||
};
|
||||
},
|
||||
|
||||
@@ -363,21 +361,21 @@ export const AverageDefinitionsEntry: MessageFns<AverageDefinitionsEntry> = {
|
||||
const message = createBaseAverageDefinitionsEntry();
|
||||
message.mu = (object.mu !== undefined && object.mu !== null)
|
||||
? AverageDefinitionsAllStats.fromPartial(object.mu)
|
||||
: createBaseAverageDefinitionsAllStats();
|
||||
: undefined;
|
||||
message.sigma = (object.sigma !== undefined && object.sigma !== null)
|
||||
? AverageDefinitionsAllStats.fromPartial(object.sigma)
|
||||
: createBaseAverageDefinitionsAllStats();
|
||||
: undefined;
|
||||
message.r = (object.r !== undefined && object.r !== null)
|
||||
? AverageDefinitionsAllStats.fromPartial(object.r)
|
||||
: createBaseAverageDefinitionsAllStats();
|
||||
: undefined;
|
||||
message.samples = (object.samples !== undefined && object.samples !== null)
|
||||
? Samples.fromPartial(object.samples)
|
||||
: createBaseSamples();
|
||||
: undefined;
|
||||
return message;
|
||||
},
|
||||
};
|
||||
|
||||
export function createBaseAverageDefinitionsAllStats(): AverageDefinitionsAllStats {
|
||||
function createBaseAverageDefinitionsAllStats(): AverageDefinitionsAllStats {
|
||||
return {
|
||||
battles: 0,
|
||||
capture_points: 0,
|
||||
@@ -461,7 +459,7 @@ export const AverageDefinitionsAllStats: MessageFns<AverageDefinitionsAllStats>
|
||||
|
||||
decode(input: BinaryReader | Uint8Array, length?: number): AverageDefinitionsAllStats {
|
||||
const reader = input instanceof BinaryReader ? input : new BinaryReader(input);
|
||||
let end = length === undefined ? reader.len : reader.pos + length;
|
||||
const end = length === undefined ? reader.len : reader.pos + length;
|
||||
const message = createBaseAverageDefinitionsAllStats();
|
||||
while (reader.pos < end) {
|
||||
const tag = reader.uint32();
|
||||
@@ -621,34 +619,60 @@ export const AverageDefinitionsAllStats: MessageFns<AverageDefinitionsAllStats>
|
||||
|
||||
fromJSON(object: any): AverageDefinitionsAllStats {
|
||||
return {
|
||||
battles: globalThis.Number(assertSet("AverageDefinitionsAllStats.battles", object.battles)),
|
||||
capture_points: globalThis.Number(assertSet("AverageDefinitionsAllStats.capture_points", object.capture_points)),
|
||||
damage_dealt: globalThis.Number(assertSet("AverageDefinitionsAllStats.damage_dealt", object.damage_dealt)),
|
||||
damage_received: globalThis.Number(
|
||||
assertSet("AverageDefinitionsAllStats.damage_received", object.damage_received),
|
||||
),
|
||||
dropped_capture_points: globalThis.Number(
|
||||
assertSet("AverageDefinitionsAllStats.dropped_capture_points", object.dropped_capture_points),
|
||||
),
|
||||
frags: globalThis.Number(assertSet("AverageDefinitionsAllStats.frags", object.frags)),
|
||||
frags8p: globalThis.Number(assertSet("AverageDefinitionsAllStats.frags8p", object.frags8p)),
|
||||
hits: globalThis.Number(assertSet("AverageDefinitionsAllStats.hits", object.hits)),
|
||||
losses: globalThis.Number(assertSet("AverageDefinitionsAllStats.losses", object.losses)),
|
||||
max_frags: globalThis.Number(assertSet("AverageDefinitionsAllStats.max_frags", object.max_frags)),
|
||||
max_xp: globalThis.Number(assertSet("AverageDefinitionsAllStats.max_xp", object.max_xp)),
|
||||
shots: globalThis.Number(assertSet("AverageDefinitionsAllStats.shots", object.shots)),
|
||||
spotted: globalThis.Number(assertSet("AverageDefinitionsAllStats.spotted", object.spotted)),
|
||||
survived_battles: globalThis.Number(
|
||||
assertSet("AverageDefinitionsAllStats.survived_battles", object.survived_battles),
|
||||
),
|
||||
win_and_survived: globalThis.Number(
|
||||
assertSet("AverageDefinitionsAllStats.win_and_survived", object.win_and_survived),
|
||||
),
|
||||
wins: globalThis.Number(assertSet("AverageDefinitionsAllStats.wins", object.wins)),
|
||||
xp: globalThis.Number(assertSet("AverageDefinitionsAllStats.xp", object.xp)),
|
||||
battle_life_time: globalThis.Number(
|
||||
assertSet("AverageDefinitionsAllStats.battle_life_time", object.battle_life_time),
|
||||
),
|
||||
battles: isSet(object.battles) ? globalThis.Number(object.battles) : 0,
|
||||
capture_points: isSet(object.capturePoints)
|
||||
? globalThis.Number(object.capturePoints)
|
||||
: isSet(object.capture_points)
|
||||
? globalThis.Number(object.capture_points)
|
||||
: 0,
|
||||
damage_dealt: isSet(object.damageDealt)
|
||||
? globalThis.Number(object.damageDealt)
|
||||
: isSet(object.damage_dealt)
|
||||
? globalThis.Number(object.damage_dealt)
|
||||
: 0,
|
||||
damage_received: isSet(object.damageReceived)
|
||||
? globalThis.Number(object.damageReceived)
|
||||
: isSet(object.damage_received)
|
||||
? globalThis.Number(object.damage_received)
|
||||
: 0,
|
||||
dropped_capture_points: isSet(object.droppedCapturePoints)
|
||||
? globalThis.Number(object.droppedCapturePoints)
|
||||
: isSet(object.dropped_capture_points)
|
||||
? globalThis.Number(object.dropped_capture_points)
|
||||
: 0,
|
||||
frags: isSet(object.frags) ? globalThis.Number(object.frags) : 0,
|
||||
frags8p: isSet(object.frags8p) ? globalThis.Number(object.frags8p) : 0,
|
||||
hits: isSet(object.hits) ? globalThis.Number(object.hits) : 0,
|
||||
losses: isSet(object.losses) ? globalThis.Number(object.losses) : 0,
|
||||
max_frags: isSet(object.maxFrags)
|
||||
? globalThis.Number(object.maxFrags)
|
||||
: isSet(object.max_frags)
|
||||
? globalThis.Number(object.max_frags)
|
||||
: 0,
|
||||
max_xp: isSet(object.maxXp)
|
||||
? globalThis.Number(object.maxXp)
|
||||
: isSet(object.max_xp)
|
||||
? globalThis.Number(object.max_xp)
|
||||
: 0,
|
||||
shots: isSet(object.shots) ? globalThis.Number(object.shots) : 0,
|
||||
spotted: isSet(object.spotted) ? globalThis.Number(object.spotted) : 0,
|
||||
survived_battles: isSet(object.survivedBattles)
|
||||
? globalThis.Number(object.survivedBattles)
|
||||
: isSet(object.survived_battles)
|
||||
? globalThis.Number(object.survived_battles)
|
||||
: 0,
|
||||
win_and_survived: isSet(object.winAndSurvived)
|
||||
? globalThis.Number(object.winAndSurvived)
|
||||
: isSet(object.win_and_survived)
|
||||
? globalThis.Number(object.win_and_survived)
|
||||
: 0,
|
||||
wins: isSet(object.wins) ? globalThis.Number(object.wins) : 0,
|
||||
xp: isSet(object.xp) ? globalThis.Number(object.xp) : 0,
|
||||
battle_life_time: isSet(object.battleLifeTime)
|
||||
? globalThis.Number(object.battleLifeTime)
|
||||
: isSet(object.battle_life_time)
|
||||
? globalThis.Number(object.battle_life_time)
|
||||
: 0,
|
||||
};
|
||||
},
|
||||
|
||||
@@ -658,16 +682,16 @@ export const AverageDefinitionsAllStats: MessageFns<AverageDefinitionsAllStats>
|
||||
obj.battles = message.battles;
|
||||
}
|
||||
if (message.capture_points !== 0) {
|
||||
obj.capture_points = message.capture_points;
|
||||
obj.capturePoints = message.capture_points;
|
||||
}
|
||||
if (message.damage_dealt !== 0) {
|
||||
obj.damage_dealt = message.damage_dealt;
|
||||
obj.damageDealt = message.damage_dealt;
|
||||
}
|
||||
if (message.damage_received !== 0) {
|
||||
obj.damage_received = message.damage_received;
|
||||
obj.damageReceived = message.damage_received;
|
||||
}
|
||||
if (message.dropped_capture_points !== 0) {
|
||||
obj.dropped_capture_points = message.dropped_capture_points;
|
||||
obj.droppedCapturePoints = message.dropped_capture_points;
|
||||
}
|
||||
if (message.frags !== 0) {
|
||||
obj.frags = message.frags;
|
||||
@@ -682,10 +706,10 @@ export const AverageDefinitionsAllStats: MessageFns<AverageDefinitionsAllStats>
|
||||
obj.losses = message.losses;
|
||||
}
|
||||
if (message.max_frags !== 0) {
|
||||
obj.max_frags = message.max_frags;
|
||||
obj.maxFrags = message.max_frags;
|
||||
}
|
||||
if (message.max_xp !== 0) {
|
||||
obj.max_xp = message.max_xp;
|
||||
obj.maxXp = message.max_xp;
|
||||
}
|
||||
if (message.shots !== 0) {
|
||||
obj.shots = message.shots;
|
||||
@@ -694,10 +718,10 @@ export const AverageDefinitionsAllStats: MessageFns<AverageDefinitionsAllStats>
|
||||
obj.spotted = message.spotted;
|
||||
}
|
||||
if (message.survived_battles !== 0) {
|
||||
obj.survived_battles = message.survived_battles;
|
||||
obj.survivedBattles = message.survived_battles;
|
||||
}
|
||||
if (message.win_and_survived !== 0) {
|
||||
obj.win_and_survived = message.win_and_survived;
|
||||
obj.winAndSurvived = message.win_and_survived;
|
||||
}
|
||||
if (message.wins !== 0) {
|
||||
obj.wins = message.wins;
|
||||
@@ -706,7 +730,7 @@ export const AverageDefinitionsAllStats: MessageFns<AverageDefinitionsAllStats>
|
||||
obj.xp = message.xp;
|
||||
}
|
||||
if (message.battle_life_time !== 0) {
|
||||
obj.battle_life_time = message.battle_life_time;
|
||||
obj.battleLifeTime = message.battle_life_time;
|
||||
}
|
||||
return obj;
|
||||
},
|
||||
@@ -738,7 +762,7 @@ export const AverageDefinitionsAllStats: MessageFns<AverageDefinitionsAllStats>
|
||||
},
|
||||
};
|
||||
|
||||
export function createBaseSamples(): Samples {
|
||||
function createBaseSamples(): Samples {
|
||||
return { d_1: 0, d_7: 0, d_30: 0, d_60: 0, d_90: 0, d_120: 0, total: 0 };
|
||||
}
|
||||
|
||||
@@ -770,7 +794,7 @@ export const Samples: MessageFns<Samples> = {
|
||||
|
||||
decode(input: BinaryReader | Uint8Array, length?: number): Samples {
|
||||
const reader = input instanceof BinaryReader ? input : new BinaryReader(input);
|
||||
let end = length === undefined ? reader.len : reader.pos + length;
|
||||
const end = length === undefined ? reader.len : reader.pos + length;
|
||||
const message = createBaseSamples();
|
||||
while (reader.pos < end) {
|
||||
const tag = reader.uint32();
|
||||
@@ -842,35 +866,39 @@ export const Samples: MessageFns<Samples> = {
|
||||
|
||||
fromJSON(object: any): Samples {
|
||||
return {
|
||||
d_1: globalThis.Number(assertSet("Samples.d_1", object.d_1)),
|
||||
d_7: globalThis.Number(assertSet("Samples.d_7", object.d_7)),
|
||||
d_30: globalThis.Number(assertSet("Samples.d_30", object.d_30)),
|
||||
d_60: globalThis.Number(assertSet("Samples.d_60", object.d_60)),
|
||||
d_90: globalThis.Number(assertSet("Samples.d_90", object.d_90)),
|
||||
d_120: globalThis.Number(assertSet("Samples.d_120", object.d_120)),
|
||||
total: globalThis.Number(assertSet("Samples.total", object.total)),
|
||||
d_1: isSet(object.d1) ? globalThis.Number(object.d1) : isSet(object.d_1) ? globalThis.Number(object.d_1) : 0,
|
||||
d_7: isSet(object.d7) ? globalThis.Number(object.d7) : isSet(object.d_7) ? globalThis.Number(object.d_7) : 0,
|
||||
d_30: isSet(object.d30) ? globalThis.Number(object.d30) : isSet(object.d_30) ? globalThis.Number(object.d_30) : 0,
|
||||
d_60: isSet(object.d60) ? globalThis.Number(object.d60) : isSet(object.d_60) ? globalThis.Number(object.d_60) : 0,
|
||||
d_90: isSet(object.d90) ? globalThis.Number(object.d90) : isSet(object.d_90) ? globalThis.Number(object.d_90) : 0,
|
||||
d_120: isSet(object.d120)
|
||||
? globalThis.Number(object.d120)
|
||||
: isSet(object.d_120)
|
||||
? globalThis.Number(object.d_120)
|
||||
: 0,
|
||||
total: isSet(object.total) ? globalThis.Number(object.total) : 0,
|
||||
};
|
||||
},
|
||||
|
||||
toJSON(message: Samples): unknown {
|
||||
const obj: any = {};
|
||||
if (message.d_1 !== 0) {
|
||||
obj.d_1 = Math.round(message.d_1);
|
||||
obj.d1 = Math.round(message.d_1);
|
||||
}
|
||||
if (message.d_7 !== 0) {
|
||||
obj.d_7 = Math.round(message.d_7);
|
||||
obj.d7 = Math.round(message.d_7);
|
||||
}
|
||||
if (message.d_30 !== 0) {
|
||||
obj.d_30 = Math.round(message.d_30);
|
||||
obj.d30 = Math.round(message.d_30);
|
||||
}
|
||||
if (message.d_60 !== 0) {
|
||||
obj.d_60 = Math.round(message.d_60);
|
||||
obj.d60 = Math.round(message.d_60);
|
||||
}
|
||||
if (message.d_90 !== 0) {
|
||||
obj.d_90 = Math.round(message.d_90);
|
||||
obj.d90 = Math.round(message.d_90);
|
||||
}
|
||||
if (message.d_120 !== 0) {
|
||||
obj.d_120 = Math.round(message.d_120);
|
||||
obj.d120 = Math.round(message.d_120);
|
||||
}
|
||||
if (message.total !== 0) {
|
||||
obj.total = Math.round(message.total);
|
||||
@@ -926,14 +954,6 @@ function isSet(value: any): boolean {
|
||||
return value !== null && value !== undefined;
|
||||
}
|
||||
|
||||
function assertSet<T>(field: string, value: T | undefined): T {
|
||||
if (!isSet(value)) {
|
||||
throw new TypeError(`Required field ${field} is not set`);
|
||||
}
|
||||
|
||||
return value as T;
|
||||
}
|
||||
|
||||
export interface MessageFns<T> {
|
||||
encode(message: T, writer?: BinaryWriter): BinaryWriter;
|
||||
decode(input: BinaryReader | Uint8Array, length?: number): T;
|
||||
|
||||
@@ -2,15 +2,15 @@ syntax = "proto2";
|
||||
|
||||
package blitzkit;
|
||||
|
||||
import "packages/core/src/protos/i18n.proto";
|
||||
import "i18n.proto";
|
||||
|
||||
message CamouflageDefinitions {
|
||||
map<uint32, Camouflage> camouflages = 1;
|
||||
}
|
||||
|
||||
message Camouflage {
|
||||
required uint32 id = 1;
|
||||
required I18nString name = 2;
|
||||
optional I18nString tank_name = 3;
|
||||
required uint32 id = 1;
|
||||
required I18nString name = 2;
|
||||
optional I18nString tank_name = 3;
|
||||
optional I18nString tank_name_full = 4;
|
||||
}
|
||||
@@ -1,14 +1,14 @@
|
||||
// Code generated by protoc-gen-ts_proto. DO NOT EDIT.
|
||||
// versions:
|
||||
// protoc-gen-ts_proto v2.2.2
|
||||
// protoc-gen-ts_proto v2.11.2
|
||||
// protoc v5.28.2
|
||||
// source: packages/core/src/protos/camouflage_definitions.proto
|
||||
// source: camouflage_definitions.proto
|
||||
|
||||
/* eslint-disable */
|
||||
import { BinaryReader, BinaryWriter } from '@bufbuild/protobuf/wire';
|
||||
import { createBaseI18nString, I18nString } from './i18n';
|
||||
import { BinaryReader, BinaryWriter } from "@bufbuild/protobuf/wire";
|
||||
import { I18nString } from "./i18n";
|
||||
|
||||
export const protobufPackage = 'blitzkit';
|
||||
export const protobufPackage = "blitzkit";
|
||||
|
||||
export interface CamouflageDefinitions {
|
||||
camouflages: { [key: number]: Camouflage };
|
||||
@@ -21,36 +21,26 @@ export interface CamouflageDefinitions_CamouflagesEntry {
|
||||
|
||||
export interface Camouflage {
|
||||
id: number;
|
||||
name: I18nString;
|
||||
tank_name?: I18nString;
|
||||
tank_name_full?: I18nString;
|
||||
name: I18nString | undefined;
|
||||
tank_name?: I18nString | undefined;
|
||||
tank_name_full?: I18nString | undefined;
|
||||
}
|
||||
|
||||
export function createBaseCamouflageDefinitions(): CamouflageDefinitions {
|
||||
function createBaseCamouflageDefinitions(): CamouflageDefinitions {
|
||||
return { camouflages: {} };
|
||||
}
|
||||
|
||||
export const CamouflageDefinitions: MessageFns<CamouflageDefinitions> = {
|
||||
encode(
|
||||
message: CamouflageDefinitions,
|
||||
writer: BinaryWriter = new BinaryWriter(),
|
||||
): BinaryWriter {
|
||||
Object.entries(message.camouflages).forEach(([key, value]) => {
|
||||
CamouflageDefinitions_CamouflagesEntry.encode(
|
||||
{ key: key as any, value },
|
||||
writer.uint32(10).fork(),
|
||||
).join();
|
||||
encode(message: CamouflageDefinitions, writer: BinaryWriter = new BinaryWriter()): BinaryWriter {
|
||||
globalThis.Object.entries(message.camouflages).forEach(([key, value]: [string, Camouflage]) => {
|
||||
CamouflageDefinitions_CamouflagesEntry.encode({ key: key as any, value }, writer.uint32(10).fork()).join();
|
||||
});
|
||||
return writer;
|
||||
},
|
||||
|
||||
decode(
|
||||
input: BinaryReader | Uint8Array,
|
||||
length?: number,
|
||||
): CamouflageDefinitions {
|
||||
const reader =
|
||||
input instanceof BinaryReader ? input : new BinaryReader(input);
|
||||
let end = length === undefined ? reader.len : reader.pos + length;
|
||||
decode(input: BinaryReader | Uint8Array, length?: number): CamouflageDefinitions {
|
||||
const reader = input instanceof BinaryReader ? input : new BinaryReader(input);
|
||||
const end = length === undefined ? reader.len : reader.pos + length;
|
||||
const message = createBaseCamouflageDefinitions();
|
||||
while (reader.pos < end) {
|
||||
const tag = reader.uint32();
|
||||
@@ -60,10 +50,7 @@ export const CamouflageDefinitions: MessageFns<CamouflageDefinitions> = {
|
||||
break;
|
||||
}
|
||||
|
||||
const entry1 = CamouflageDefinitions_CamouflagesEntry.decode(
|
||||
reader,
|
||||
reader.uint32(),
|
||||
);
|
||||
const entry1 = CamouflageDefinitions_CamouflagesEntry.decode(reader, reader.uint32());
|
||||
if (entry1.value !== undefined) {
|
||||
message.camouflages[entry1.key] = entry1.value;
|
||||
}
|
||||
@@ -81,12 +68,13 @@ export const CamouflageDefinitions: MessageFns<CamouflageDefinitions> = {
|
||||
fromJSON(object: any): CamouflageDefinitions {
|
||||
return {
|
||||
camouflages: isObject(object.camouflages)
|
||||
? Object.entries(object.camouflages).reduce<{
|
||||
[key: number]: Camouflage;
|
||||
}>((acc, [key, value]) => {
|
||||
? (globalThis.Object.entries(object.camouflages) as [string, any][]).reduce(
|
||||
(acc: { [key: number]: Camouflage }, [key, value]: [string, any]) => {
|
||||
acc[globalThis.Number(key)] = Camouflage.fromJSON(value);
|
||||
return acc;
|
||||
}, {})
|
||||
},
|
||||
{},
|
||||
)
|
||||
: {},
|
||||
};
|
||||
},
|
||||
@@ -94,7 +82,7 @@ export const CamouflageDefinitions: MessageFns<CamouflageDefinitions> = {
|
||||
toJSON(message: CamouflageDefinitions): unknown {
|
||||
const obj: any = {};
|
||||
if (message.camouflages) {
|
||||
const entries = Object.entries(message.camouflages);
|
||||
const entries = globalThis.Object.entries(message.camouflages) as [string, Camouflage][];
|
||||
if (entries.length > 0) {
|
||||
obj.camouflages = {};
|
||||
entries.forEach(([k, v]) => {
|
||||
@@ -105,141 +93,112 @@ export const CamouflageDefinitions: MessageFns<CamouflageDefinitions> = {
|
||||
return obj;
|
||||
},
|
||||
|
||||
create<I extends Exact<DeepPartial<CamouflageDefinitions>, I>>(
|
||||
base?: I,
|
||||
): CamouflageDefinitions {
|
||||
create<I extends Exact<DeepPartial<CamouflageDefinitions>, I>>(base?: I): CamouflageDefinitions {
|
||||
return CamouflageDefinitions.fromPartial(base ?? ({} as any));
|
||||
},
|
||||
fromPartial<I extends Exact<DeepPartial<CamouflageDefinitions>, I>>(
|
||||
object: I,
|
||||
): CamouflageDefinitions {
|
||||
fromPartial<I extends Exact<DeepPartial<CamouflageDefinitions>, I>>(object: I): CamouflageDefinitions {
|
||||
const message = createBaseCamouflageDefinitions();
|
||||
message.camouflages = Object.entries(object.camouflages ?? {}).reduce<{
|
||||
[key: number]: Camouflage;
|
||||
}>((acc, [key, value]) => {
|
||||
if (value !== undefined) {
|
||||
acc[globalThis.Number(key)] = Camouflage.fromPartial(value);
|
||||
}
|
||||
return acc;
|
||||
}, {});
|
||||
message.camouflages = (globalThis.Object.entries(object.camouflages ?? {}) as [string, Camouflage][]).reduce(
|
||||
(acc: { [key: number]: Camouflage }, [key, value]: [string, Camouflage]) => {
|
||||
if (value !== undefined) {
|
||||
acc[globalThis.Number(key)] = Camouflage.fromPartial(value);
|
||||
}
|
||||
return acc;
|
||||
},
|
||||
{},
|
||||
);
|
||||
return message;
|
||||
},
|
||||
};
|
||||
|
||||
export function createBaseCamouflageDefinitions_CamouflagesEntry(): CamouflageDefinitions_CamouflagesEntry {
|
||||
return { key: 0, value: createBaseCamouflage() };
|
||||
function createBaseCamouflageDefinitions_CamouflagesEntry(): CamouflageDefinitions_CamouflagesEntry {
|
||||
return { key: 0, value: undefined };
|
||||
}
|
||||
|
||||
export const CamouflageDefinitions_CamouflagesEntry: MessageFns<CamouflageDefinitions_CamouflagesEntry> =
|
||||
{
|
||||
encode(
|
||||
message: CamouflageDefinitions_CamouflagesEntry,
|
||||
writer: BinaryWriter = new BinaryWriter(),
|
||||
): BinaryWriter {
|
||||
if (message.key !== undefined) {
|
||||
writer.uint32(8).uint32(message.key);
|
||||
}
|
||||
if (message.value !== undefined) {
|
||||
Camouflage.encode(message.value, writer.uint32(18).fork()).join();
|
||||
}
|
||||
return writer;
|
||||
},
|
||||
export const CamouflageDefinitions_CamouflagesEntry: MessageFns<CamouflageDefinitions_CamouflagesEntry> = {
|
||||
encode(message: CamouflageDefinitions_CamouflagesEntry, writer: BinaryWriter = new BinaryWriter()): BinaryWriter {
|
||||
if (message.key !== 0) {
|
||||
writer.uint32(8).uint32(message.key);
|
||||
}
|
||||
if (message.value !== undefined) {
|
||||
Camouflage.encode(message.value, writer.uint32(18).fork()).join();
|
||||
}
|
||||
return writer;
|
||||
},
|
||||
|
||||
decode(
|
||||
input: BinaryReader | Uint8Array,
|
||||
length?: number,
|
||||
): CamouflageDefinitions_CamouflagesEntry {
|
||||
const reader =
|
||||
input instanceof BinaryReader ? input : new BinaryReader(input);
|
||||
let end = length === undefined ? reader.len : reader.pos + length;
|
||||
const message = createBaseCamouflageDefinitions_CamouflagesEntry();
|
||||
while (reader.pos < end) {
|
||||
const tag = reader.uint32();
|
||||
switch (tag >>> 3) {
|
||||
case 1: {
|
||||
if (tag !== 8) {
|
||||
break;
|
||||
}
|
||||
|
||||
message.key = reader.uint32();
|
||||
continue;
|
||||
decode(input: BinaryReader | Uint8Array, length?: number): CamouflageDefinitions_CamouflagesEntry {
|
||||
const reader = input instanceof BinaryReader ? input : new BinaryReader(input);
|
||||
const end = length === undefined ? reader.len : reader.pos + length;
|
||||
const message = createBaseCamouflageDefinitions_CamouflagesEntry();
|
||||
while (reader.pos < end) {
|
||||
const tag = reader.uint32();
|
||||
switch (tag >>> 3) {
|
||||
case 1: {
|
||||
if (tag !== 8) {
|
||||
break;
|
||||
}
|
||||
case 2: {
|
||||
if (tag !== 18) {
|
||||
break;
|
||||
}
|
||||
|
||||
message.value = Camouflage.decode(reader, reader.uint32());
|
||||
continue;
|
||||
message.key = reader.uint32();
|
||||
continue;
|
||||
}
|
||||
case 2: {
|
||||
if (tag !== 18) {
|
||||
break;
|
||||
}
|
||||
|
||||
message.value = Camouflage.decode(reader, reader.uint32());
|
||||
continue;
|
||||
}
|
||||
if ((tag & 7) === 4 || tag === 0) {
|
||||
break;
|
||||
}
|
||||
reader.skip(tag & 7);
|
||||
}
|
||||
return message;
|
||||
},
|
||||
|
||||
fromJSON(object: any): CamouflageDefinitions_CamouflagesEntry {
|
||||
return {
|
||||
key: globalThis.Number(
|
||||
assertSet('CamouflageDefinitions_CamouflagesEntry.key', object.key),
|
||||
),
|
||||
value: Camouflage.fromJSON(
|
||||
assertSet(
|
||||
'CamouflageDefinitions_CamouflagesEntry.value',
|
||||
object.value,
|
||||
),
|
||||
),
|
||||
};
|
||||
},
|
||||
|
||||
toJSON(message: CamouflageDefinitions_CamouflagesEntry): unknown {
|
||||
const obj: any = {};
|
||||
if (message.key !== undefined) {
|
||||
obj.key = Math.round(message.key);
|
||||
if ((tag & 7) === 4 || tag === 0) {
|
||||
break;
|
||||
}
|
||||
if (message.value !== undefined) {
|
||||
obj.value = Camouflage.toJSON(message.value);
|
||||
}
|
||||
return obj;
|
||||
},
|
||||
reader.skip(tag & 7);
|
||||
}
|
||||
return message;
|
||||
},
|
||||
|
||||
create<
|
||||
I extends Exact<DeepPartial<CamouflageDefinitions_CamouflagesEntry>, I>,
|
||||
>(base?: I): CamouflageDefinitions_CamouflagesEntry {
|
||||
return CamouflageDefinitions_CamouflagesEntry.fromPartial(
|
||||
base ?? ({} as any),
|
||||
);
|
||||
},
|
||||
fromPartial<
|
||||
I extends Exact<DeepPartial<CamouflageDefinitions_CamouflagesEntry>, I>,
|
||||
>(object: I): CamouflageDefinitions_CamouflagesEntry {
|
||||
const message = createBaseCamouflageDefinitions_CamouflagesEntry();
|
||||
message.key = object.key ?? 0;
|
||||
message.value =
|
||||
object.value !== undefined && object.value !== null
|
||||
? Camouflage.fromPartial(object.value)
|
||||
: createBaseCamouflage();
|
||||
return message;
|
||||
},
|
||||
};
|
||||
fromJSON(object: any): CamouflageDefinitions_CamouflagesEntry {
|
||||
return {
|
||||
key: isSet(object.key) ? globalThis.Number(object.key) : 0,
|
||||
value: isSet(object.value) ? Camouflage.fromJSON(object.value) : undefined,
|
||||
};
|
||||
},
|
||||
|
||||
export function createBaseCamouflage(): Camouflage {
|
||||
return {
|
||||
id: 0,
|
||||
name: createBaseI18nString(),
|
||||
tank_name: undefined,
|
||||
tank_name_full: undefined,
|
||||
};
|
||||
toJSON(message: CamouflageDefinitions_CamouflagesEntry): unknown {
|
||||
const obj: any = {};
|
||||
if (message.key !== 0) {
|
||||
obj.key = Math.round(message.key);
|
||||
}
|
||||
if (message.value !== undefined) {
|
||||
obj.value = Camouflage.toJSON(message.value);
|
||||
}
|
||||
return obj;
|
||||
},
|
||||
|
||||
create<I extends Exact<DeepPartial<CamouflageDefinitions_CamouflagesEntry>, I>>(
|
||||
base?: I,
|
||||
): CamouflageDefinitions_CamouflagesEntry {
|
||||
return CamouflageDefinitions_CamouflagesEntry.fromPartial(base ?? ({} as any));
|
||||
},
|
||||
fromPartial<I extends Exact<DeepPartial<CamouflageDefinitions_CamouflagesEntry>, I>>(
|
||||
object: I,
|
||||
): CamouflageDefinitions_CamouflagesEntry {
|
||||
const message = createBaseCamouflageDefinitions_CamouflagesEntry();
|
||||
message.key = object.key ?? 0;
|
||||
message.value = (object.value !== undefined && object.value !== null)
|
||||
? Camouflage.fromPartial(object.value)
|
||||
: undefined;
|
||||
return message;
|
||||
},
|
||||
};
|
||||
|
||||
function createBaseCamouflage(): Camouflage {
|
||||
return { id: 0, name: undefined, tank_name: undefined, tank_name_full: undefined };
|
||||
}
|
||||
|
||||
export const Camouflage: MessageFns<Camouflage> = {
|
||||
encode(
|
||||
message: Camouflage,
|
||||
writer: BinaryWriter = new BinaryWriter(),
|
||||
): BinaryWriter {
|
||||
encode(message: Camouflage, writer: BinaryWriter = new BinaryWriter()): BinaryWriter {
|
||||
if (message.id !== 0) {
|
||||
writer.uint32(8).uint32(message.id);
|
||||
}
|
||||
@@ -250,18 +209,14 @@ export const Camouflage: MessageFns<Camouflage> = {
|
||||
I18nString.encode(message.tank_name, writer.uint32(26).fork()).join();
|
||||
}
|
||||
if (message.tank_name_full !== undefined) {
|
||||
I18nString.encode(
|
||||
message.tank_name_full,
|
||||
writer.uint32(34).fork(),
|
||||
).join();
|
||||
I18nString.encode(message.tank_name_full, writer.uint32(34).fork()).join();
|
||||
}
|
||||
return writer;
|
||||
},
|
||||
|
||||
decode(input: BinaryReader | Uint8Array, length?: number): Camouflage {
|
||||
const reader =
|
||||
input instanceof BinaryReader ? input : new BinaryReader(input);
|
||||
let end = length === undefined ? reader.len : reader.pos + length;
|
||||
const reader = input instanceof BinaryReader ? input : new BinaryReader(input);
|
||||
const end = length === undefined ? reader.len : reader.pos + length;
|
||||
const message = createBaseCamouflage();
|
||||
while (reader.pos < end) {
|
||||
const tag = reader.uint32();
|
||||
@@ -309,12 +264,16 @@ export const Camouflage: MessageFns<Camouflage> = {
|
||||
|
||||
fromJSON(object: any): Camouflage {
|
||||
return {
|
||||
id: globalThis.Number(assertSet('Camouflage.id', object.id)),
|
||||
name: I18nString.fromJSON(assertSet('Camouflage.name', object.name)),
|
||||
tank_name: isSet(object.tank_name)
|
||||
id: isSet(object.id) ? globalThis.Number(object.id) : 0,
|
||||
name: isSet(object.name) ? I18nString.fromJSON(object.name) : undefined,
|
||||
tank_name: isSet(object.tankName)
|
||||
? I18nString.fromJSON(object.tankName)
|
||||
: isSet(object.tank_name)
|
||||
? I18nString.fromJSON(object.tank_name)
|
||||
: undefined,
|
||||
tank_name_full: isSet(object.tank_name_full)
|
||||
tank_name_full: isSet(object.tankNameFull)
|
||||
? I18nString.fromJSON(object.tankNameFull)
|
||||
: isSet(object.tank_name_full)
|
||||
? I18nString.fromJSON(object.tank_name_full)
|
||||
: undefined,
|
||||
};
|
||||
@@ -329,10 +288,10 @@ export const Camouflage: MessageFns<Camouflage> = {
|
||||
obj.name = I18nString.toJSON(message.name);
|
||||
}
|
||||
if (message.tank_name !== undefined) {
|
||||
obj.tank_name = I18nString.toJSON(message.tank_name);
|
||||
obj.tankName = I18nString.toJSON(message.tank_name);
|
||||
}
|
||||
if (message.tank_name_full !== undefined) {
|
||||
obj.tank_name_full = I18nString.toJSON(message.tank_name_full);
|
||||
obj.tankNameFull = I18nString.toJSON(message.tank_name_full);
|
||||
}
|
||||
return obj;
|
||||
},
|
||||
@@ -340,71 +299,43 @@ export const Camouflage: MessageFns<Camouflage> = {
|
||||
create<I extends Exact<DeepPartial<Camouflage>, I>>(base?: I): Camouflage {
|
||||
return Camouflage.fromPartial(base ?? ({} as any));
|
||||
},
|
||||
fromPartial<I extends Exact<DeepPartial<Camouflage>, I>>(
|
||||
object: I,
|
||||
): Camouflage {
|
||||
fromPartial<I extends Exact<DeepPartial<Camouflage>, I>>(object: I): Camouflage {
|
||||
const message = createBaseCamouflage();
|
||||
message.id = object.id ?? 0;
|
||||
message.name =
|
||||
object.name !== undefined && object.name !== null
|
||||
? I18nString.fromPartial(object.name)
|
||||
: createBaseI18nString();
|
||||
message.tank_name =
|
||||
object.tank_name !== undefined && object.tank_name !== null
|
||||
? I18nString.fromPartial(object.tank_name)
|
||||
: undefined;
|
||||
message.tank_name_full =
|
||||
object.tank_name_full !== undefined && object.tank_name_full !== null
|
||||
? I18nString.fromPartial(object.tank_name_full)
|
||||
: undefined;
|
||||
message.name = (object.name !== undefined && object.name !== null)
|
||||
? I18nString.fromPartial(object.name)
|
||||
: undefined;
|
||||
message.tank_name = (object.tank_name !== undefined && object.tank_name !== null)
|
||||
? I18nString.fromPartial(object.tank_name)
|
||||
: undefined;
|
||||
message.tank_name_full = (object.tank_name_full !== undefined && object.tank_name_full !== null)
|
||||
? I18nString.fromPartial(object.tank_name_full)
|
||||
: undefined;
|
||||
return message;
|
||||
},
|
||||
};
|
||||
|
||||
type Builtin =
|
||||
| Date
|
||||
| Function
|
||||
| Uint8Array
|
||||
| string
|
||||
| number
|
||||
| boolean
|
||||
| undefined;
|
||||
type Builtin = Date | Function | Uint8Array | string | number | boolean | undefined;
|
||||
|
||||
export type DeepPartial<T> = T extends Builtin
|
||||
? T
|
||||
: T extends globalThis.Array<infer U>
|
||||
? globalThis.Array<DeepPartial<U>>
|
||||
: T extends ReadonlyArray<infer U>
|
||||
? ReadonlyArray<DeepPartial<U>>
|
||||
: T extends { $case: string; value: unknown }
|
||||
? { $case: T['$case']; value?: DeepPartial<T['value']> }
|
||||
: T extends {}
|
||||
? { [K in keyof T]?: DeepPartial<T[K]> }
|
||||
: Partial<T>;
|
||||
export type DeepPartial<T> = T extends Builtin ? T
|
||||
: T extends globalThis.Array<infer U> ? globalThis.Array<DeepPartial<U>>
|
||||
: T extends ReadonlyArray<infer U> ? ReadonlyArray<DeepPartial<U>>
|
||||
: T extends { $case: string; value: unknown } ? { $case: T["$case"]; value?: DeepPartial<T["value"]> }
|
||||
: T extends {} ? { [K in keyof T]?: DeepPartial<T[K]> }
|
||||
: Partial<T>;
|
||||
|
||||
type KeysOfUnion<T> = T extends T ? keyof T : never;
|
||||
export type Exact<P, I extends P> = P extends Builtin
|
||||
? P
|
||||
: P & { [K in keyof P]: Exact<P[K], I[K]> } & {
|
||||
[K in Exclude<keyof I, KeysOfUnion<P>>]: never;
|
||||
};
|
||||
export type Exact<P, I extends P> = P extends Builtin ? P
|
||||
: P & { [K in keyof P]: Exact<P[K], I[K]> } & { [K in Exclude<keyof I, KeysOfUnion<P>>]: never };
|
||||
|
||||
function isObject(value: any): boolean {
|
||||
return typeof value === 'object' && value !== null;
|
||||
return typeof value === "object" && value !== null;
|
||||
}
|
||||
|
||||
function isSet(value: any): boolean {
|
||||
return value !== null && value !== undefined;
|
||||
}
|
||||
|
||||
function assertSet<T>(field: string, value: T | undefined): T {
|
||||
if (!isSet(value)) {
|
||||
throw new TypeError(`Required field ${field} is not set`);
|
||||
}
|
||||
|
||||
return value as T;
|
||||
}
|
||||
|
||||
export interface MessageFns<T> {
|
||||
encode(message: T, writer?: BinaryWriter): BinaryWriter;
|
||||
decode(input: BinaryReader | Uint8Array, length?: number): T;
|
||||
|
||||
@@ -2,28 +2,28 @@ syntax = "proto2";
|
||||
|
||||
package blitzkit;
|
||||
|
||||
import "packages/core/src/protos/i18n.proto";
|
||||
import "i18n.proto";
|
||||
|
||||
message ConsumableDefinitions {
|
||||
map<uint32, Consumable> consumables = 1;
|
||||
}
|
||||
|
||||
message Consumable {
|
||||
required uint32 id = 1;
|
||||
required I18nString name = 2;
|
||||
required uint32 cooldown = 3;
|
||||
optional float duration = 4;
|
||||
required bool game_mode_exclusive = 5;
|
||||
repeated ConsumableTankFilter include = 6;
|
||||
repeated ConsumableTankFilter exclude = 7;
|
||||
required uint32 id = 1;
|
||||
required I18nString name = 2;
|
||||
required uint32 cooldown = 3;
|
||||
optional float duration = 4;
|
||||
required bool game_mode_exclusive = 5;
|
||||
repeated ConsumableTankFilter include = 6;
|
||||
repeated ConsumableTankFilter exclude = 7;
|
||||
}
|
||||
|
||||
message ConsumableTankFilter {
|
||||
oneof filter_type {
|
||||
ConsumableTankTierFilter tiers = 1;
|
||||
ConsumableTankIdsFilter ids = 2;
|
||||
ConsumableTankTierFilter tiers = 1;
|
||||
ConsumableTankIdsFilter ids = 2;
|
||||
ConsumableTankCategoryFilter categories = 3;
|
||||
ConsumableTankNationFilter nations = 4;
|
||||
ConsumableTankNationFilter nations = 4;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,24 +1,24 @@
|
||||
// Code generated by protoc-gen-ts_proto. DO NOT EDIT.
|
||||
// versions:
|
||||
// protoc-gen-ts_proto v2.2.2
|
||||
// protoc-gen-ts_proto v2.11.2
|
||||
// protoc v5.28.2
|
||||
// source: packages/core/src/protos/consumable_definitions.proto
|
||||
// source: consumable_definitions.proto
|
||||
|
||||
/* eslint-disable */
|
||||
import { BinaryReader, BinaryWriter } from "@bufbuild/protobuf/wire";
|
||||
import { createBaseI18nString, I18nString } from "./i18n";
|
||||
import { I18nString } from "./i18n";
|
||||
|
||||
export const protobufPackage = "blitzkit";
|
||||
|
||||
export enum ConsumableTankCategoryFilterCategory {
|
||||
CLIP = 0,
|
||||
CONSUMABLE_TANK_CATEGORY_FILTER_CATEGORY_CLIP = 0,
|
||||
}
|
||||
|
||||
export function consumableTankCategoryFilterCategoryFromJSON(object: any): ConsumableTankCategoryFilterCategory {
|
||||
switch (object) {
|
||||
case 0:
|
||||
case "CONSUMABLE_TANK_CATEGORY_FILTER_CATEGORY_CLIP":
|
||||
return ConsumableTankCategoryFilterCategory.CLIP;
|
||||
return ConsumableTankCategoryFilterCategory.CONSUMABLE_TANK_CATEGORY_FILTER_CATEGORY_CLIP;
|
||||
default:
|
||||
throw new globalThis.Error(
|
||||
"Unrecognized enum value " + object + " for enum ConsumableTankCategoryFilterCategory",
|
||||
@@ -28,7 +28,7 @@ export function consumableTankCategoryFilterCategoryFromJSON(object: any): Consu
|
||||
|
||||
export function consumableTankCategoryFilterCategoryToJSON(object: ConsumableTankCategoryFilterCategory): string {
|
||||
switch (object) {
|
||||
case ConsumableTankCategoryFilterCategory.CLIP:
|
||||
case ConsumableTankCategoryFilterCategory.CONSUMABLE_TANK_CATEGORY_FILTER_CATEGORY_CLIP:
|
||||
return "CONSUMABLE_TANK_CATEGORY_FILTER_CATEGORY_CLIP";
|
||||
default:
|
||||
throw new globalThis.Error(
|
||||
@@ -48,7 +48,7 @@ export interface ConsumableDefinitions_ConsumablesEntry {
|
||||
|
||||
export interface Consumable {
|
||||
id: number;
|
||||
name: I18nString;
|
||||
name: I18nString | undefined;
|
||||
cooldown: number;
|
||||
duration?: number | undefined;
|
||||
game_mode_exclusive: boolean;
|
||||
@@ -82,13 +82,13 @@ export interface ConsumableTankNationFilter {
|
||||
nations: string[];
|
||||
}
|
||||
|
||||
export function createBaseConsumableDefinitions(): ConsumableDefinitions {
|
||||
function createBaseConsumableDefinitions(): ConsumableDefinitions {
|
||||
return { consumables: {} };
|
||||
}
|
||||
|
||||
export const ConsumableDefinitions: MessageFns<ConsumableDefinitions> = {
|
||||
encode(message: ConsumableDefinitions, writer: BinaryWriter = new BinaryWriter()): BinaryWriter {
|
||||
Object.entries(message.consumables).forEach(([key, value]) => {
|
||||
globalThis.Object.entries(message.consumables).forEach(([key, value]: [string, Consumable]) => {
|
||||
ConsumableDefinitions_ConsumablesEntry.encode({ key: key as any, value }, writer.uint32(10).fork()).join();
|
||||
});
|
||||
return writer;
|
||||
@@ -96,7 +96,7 @@ export const ConsumableDefinitions: MessageFns<ConsumableDefinitions> = {
|
||||
|
||||
decode(input: BinaryReader | Uint8Array, length?: number): ConsumableDefinitions {
|
||||
const reader = input instanceof BinaryReader ? input : new BinaryReader(input);
|
||||
let end = length === undefined ? reader.len : reader.pos + length;
|
||||
const end = length === undefined ? reader.len : reader.pos + length;
|
||||
const message = createBaseConsumableDefinitions();
|
||||
while (reader.pos < end) {
|
||||
const tag = reader.uint32();
|
||||
@@ -124,10 +124,13 @@ export const ConsumableDefinitions: MessageFns<ConsumableDefinitions> = {
|
||||
fromJSON(object: any): ConsumableDefinitions {
|
||||
return {
|
||||
consumables: isObject(object.consumables)
|
||||
? Object.entries(object.consumables).reduce<{ [key: number]: Consumable }>((acc, [key, value]) => {
|
||||
acc[globalThis.Number(key)] = Consumable.fromJSON(value);
|
||||
return acc;
|
||||
}, {})
|
||||
? (globalThis.Object.entries(object.consumables) as [string, any][]).reduce(
|
||||
(acc: { [key: number]: Consumable }, [key, value]: [string, any]) => {
|
||||
acc[globalThis.Number(key)] = Consumable.fromJSON(value);
|
||||
return acc;
|
||||
},
|
||||
{},
|
||||
)
|
||||
: {},
|
||||
};
|
||||
},
|
||||
@@ -135,7 +138,7 @@ export const ConsumableDefinitions: MessageFns<ConsumableDefinitions> = {
|
||||
toJSON(message: ConsumableDefinitions): unknown {
|
||||
const obj: any = {};
|
||||
if (message.consumables) {
|
||||
const entries = Object.entries(message.consumables);
|
||||
const entries = globalThis.Object.entries(message.consumables) as [string, Consumable][];
|
||||
if (entries.length > 0) {
|
||||
obj.consumables = {};
|
||||
entries.forEach(([k, v]) => {
|
||||
@@ -151,8 +154,8 @@ export const ConsumableDefinitions: MessageFns<ConsumableDefinitions> = {
|
||||
},
|
||||
fromPartial<I extends Exact<DeepPartial<ConsumableDefinitions>, I>>(object: I): ConsumableDefinitions {
|
||||
const message = createBaseConsumableDefinitions();
|
||||
message.consumables = Object.entries(object.consumables ?? {}).reduce<{ [key: number]: Consumable }>(
|
||||
(acc, [key, value]) => {
|
||||
message.consumables = (globalThis.Object.entries(object.consumables ?? {}) as [string, Consumable][]).reduce(
|
||||
(acc: { [key: number]: Consumable }, [key, value]: [string, Consumable]) => {
|
||||
if (value !== undefined) {
|
||||
acc[globalThis.Number(key)] = Consumable.fromPartial(value);
|
||||
}
|
||||
@@ -164,13 +167,13 @@ export const ConsumableDefinitions: MessageFns<ConsumableDefinitions> = {
|
||||
},
|
||||
};
|
||||
|
||||
export function createBaseConsumableDefinitions_ConsumablesEntry(): ConsumableDefinitions_ConsumablesEntry {
|
||||
return { key: 0, value: createBaseConsumable() };
|
||||
function createBaseConsumableDefinitions_ConsumablesEntry(): ConsumableDefinitions_ConsumablesEntry {
|
||||
return { key: 0, value: undefined };
|
||||
}
|
||||
|
||||
export const ConsumableDefinitions_ConsumablesEntry: MessageFns<ConsumableDefinitions_ConsumablesEntry> = {
|
||||
encode(message: ConsumableDefinitions_ConsumablesEntry, writer: BinaryWriter = new BinaryWriter()): BinaryWriter {
|
||||
if (message.key !== undefined) {
|
||||
if (message.key !== 0) {
|
||||
writer.uint32(8).uint32(message.key);
|
||||
}
|
||||
if (message.value !== undefined) {
|
||||
@@ -181,7 +184,7 @@ export const ConsumableDefinitions_ConsumablesEntry: MessageFns<ConsumableDefini
|
||||
|
||||
decode(input: BinaryReader | Uint8Array, length?: number): ConsumableDefinitions_ConsumablesEntry {
|
||||
const reader = input instanceof BinaryReader ? input : new BinaryReader(input);
|
||||
let end = length === undefined ? reader.len : reader.pos + length;
|
||||
const end = length === undefined ? reader.len : reader.pos + length;
|
||||
const message = createBaseConsumableDefinitions_ConsumablesEntry();
|
||||
while (reader.pos < end) {
|
||||
const tag = reader.uint32();
|
||||
@@ -213,14 +216,14 @@ export const ConsumableDefinitions_ConsumablesEntry: MessageFns<ConsumableDefini
|
||||
|
||||
fromJSON(object: any): ConsumableDefinitions_ConsumablesEntry {
|
||||
return {
|
||||
key: globalThis.Number(assertSet("ConsumableDefinitions_ConsumablesEntry.key", object.key)),
|
||||
value: Consumable.fromJSON(assertSet("ConsumableDefinitions_ConsumablesEntry.value", object.value)),
|
||||
key: isSet(object.key) ? globalThis.Number(object.key) : 0,
|
||||
value: isSet(object.value) ? Consumable.fromJSON(object.value) : undefined,
|
||||
};
|
||||
},
|
||||
|
||||
toJSON(message: ConsumableDefinitions_ConsumablesEntry): unknown {
|
||||
const obj: any = {};
|
||||
if (message.key !== undefined) {
|
||||
if (message.key !== 0) {
|
||||
obj.key = Math.round(message.key);
|
||||
}
|
||||
if (message.value !== undefined) {
|
||||
@@ -241,21 +244,13 @@ export const ConsumableDefinitions_ConsumablesEntry: MessageFns<ConsumableDefini
|
||||
message.key = object.key ?? 0;
|
||||
message.value = (object.value !== undefined && object.value !== null)
|
||||
? Consumable.fromPartial(object.value)
|
||||
: createBaseConsumable();
|
||||
: undefined;
|
||||
return message;
|
||||
},
|
||||
};
|
||||
|
||||
export function createBaseConsumable(): Consumable {
|
||||
return {
|
||||
id: 0,
|
||||
name: createBaseI18nString(),
|
||||
cooldown: 0,
|
||||
duration: undefined,
|
||||
game_mode_exclusive: false,
|
||||
include: [],
|
||||
exclude: [],
|
||||
};
|
||||
function createBaseConsumable(): Consumable {
|
||||
return { id: 0, name: undefined, cooldown: 0, duration: 0, game_mode_exclusive: false, include: [], exclude: [] };
|
||||
}
|
||||
|
||||
export const Consumable: MessageFns<Consumable> = {
|
||||
@@ -269,7 +264,7 @@ export const Consumable: MessageFns<Consumable> = {
|
||||
if (message.cooldown !== 0) {
|
||||
writer.uint32(24).uint32(message.cooldown);
|
||||
}
|
||||
if (message.duration !== undefined && message.duration !== undefined) {
|
||||
if (message.duration !== undefined && message.duration !== 0) {
|
||||
writer.uint32(37).float(message.duration);
|
||||
}
|
||||
if (message.game_mode_exclusive !== false) {
|
||||
@@ -286,7 +281,7 @@ export const Consumable: MessageFns<Consumable> = {
|
||||
|
||||
decode(input: BinaryReader | Uint8Array, length?: number): Consumable {
|
||||
const reader = input instanceof BinaryReader ? input : new BinaryReader(input);
|
||||
let end = length === undefined ? reader.len : reader.pos + length;
|
||||
const end = length === undefined ? reader.len : reader.pos + length;
|
||||
const message = createBaseConsumable();
|
||||
while (reader.pos < end) {
|
||||
const tag = reader.uint32();
|
||||
@@ -358,11 +353,15 @@ export const Consumable: MessageFns<Consumable> = {
|
||||
|
||||
fromJSON(object: any): Consumable {
|
||||
return {
|
||||
id: globalThis.Number(assertSet("Consumable.id", object.id)),
|
||||
name: I18nString.fromJSON(assertSet("Consumable.name", object.name)),
|
||||
cooldown: globalThis.Number(assertSet("Consumable.cooldown", object.cooldown)),
|
||||
duration: isSet(object.duration) ? globalThis.Number(object.duration) : undefined,
|
||||
game_mode_exclusive: globalThis.Boolean(assertSet("Consumable.game_mode_exclusive", object.game_mode_exclusive)),
|
||||
id: isSet(object.id) ? globalThis.Number(object.id) : 0,
|
||||
name: isSet(object.name) ? I18nString.fromJSON(object.name) : undefined,
|
||||
cooldown: isSet(object.cooldown) ? globalThis.Number(object.cooldown) : 0,
|
||||
duration: isSet(object.duration) ? globalThis.Number(object.duration) : 0,
|
||||
game_mode_exclusive: isSet(object.gameModeExclusive)
|
||||
? globalThis.Boolean(object.gameModeExclusive)
|
||||
: isSet(object.game_mode_exclusive)
|
||||
? globalThis.Boolean(object.game_mode_exclusive)
|
||||
: false,
|
||||
include: globalThis.Array.isArray(object?.include)
|
||||
? object.include.map((e: any) => ConsumableTankFilter.fromJSON(e))
|
||||
: [],
|
||||
@@ -383,11 +382,11 @@ export const Consumable: MessageFns<Consumable> = {
|
||||
if (message.cooldown !== 0) {
|
||||
obj.cooldown = Math.round(message.cooldown);
|
||||
}
|
||||
if (message.duration !== undefined && message.duration !== undefined) {
|
||||
if (message.duration !== undefined && message.duration !== 0) {
|
||||
obj.duration = message.duration;
|
||||
}
|
||||
if (message.game_mode_exclusive !== false) {
|
||||
obj.game_mode_exclusive = message.game_mode_exclusive;
|
||||
obj.gameModeExclusive = message.game_mode_exclusive;
|
||||
}
|
||||
if (message.include?.length) {
|
||||
obj.include = message.include.map((e) => ConsumableTankFilter.toJSON(e));
|
||||
@@ -406,9 +405,9 @@ export const Consumable: MessageFns<Consumable> = {
|
||||
message.id = object.id ?? 0;
|
||||
message.name = (object.name !== undefined && object.name !== null)
|
||||
? I18nString.fromPartial(object.name)
|
||||
: createBaseI18nString();
|
||||
: undefined;
|
||||
message.cooldown = object.cooldown ?? 0;
|
||||
message.duration = object.duration ?? undefined;
|
||||
message.duration = object.duration ?? 0;
|
||||
message.game_mode_exclusive = object.game_mode_exclusive ?? false;
|
||||
message.include = object.include?.map((e) => ConsumableTankFilter.fromPartial(e)) || [];
|
||||
message.exclude = object.exclude?.map((e) => ConsumableTankFilter.fromPartial(e)) || [];
|
||||
@@ -416,7 +415,7 @@ export const Consumable: MessageFns<Consumable> = {
|
||||
},
|
||||
};
|
||||
|
||||
export function createBaseConsumableTankFilter(): ConsumableTankFilter {
|
||||
function createBaseConsumableTankFilter(): ConsumableTankFilter {
|
||||
return { filter_type: undefined };
|
||||
}
|
||||
|
||||
@@ -441,7 +440,7 @@ export const ConsumableTankFilter: MessageFns<ConsumableTankFilter> = {
|
||||
|
||||
decode(input: BinaryReader | Uint8Array, length?: number): ConsumableTankFilter {
|
||||
const reader = input instanceof BinaryReader ? input : new BinaryReader(input);
|
||||
let end = length === undefined ? reader.len : reader.pos + length;
|
||||
const end = length === undefined ? reader.len : reader.pos + length;
|
||||
const message = createBaseConsumableTankFilter();
|
||||
while (reader.pos < end) {
|
||||
const tag = reader.uint32();
|
||||
@@ -508,14 +507,11 @@ export const ConsumableTankFilter: MessageFns<ConsumableTankFilter> = {
|
||||
const obj: any = {};
|
||||
if (message.filter_type?.$case === "tiers") {
|
||||
obj.tiers = ConsumableTankTierFilter.toJSON(message.filter_type.value);
|
||||
}
|
||||
if (message.filter_type?.$case === "ids") {
|
||||
} else if (message.filter_type?.$case === "ids") {
|
||||
obj.ids = ConsumableTankIdsFilter.toJSON(message.filter_type.value);
|
||||
}
|
||||
if (message.filter_type?.$case === "categories") {
|
||||
} else if (message.filter_type?.$case === "categories") {
|
||||
obj.categories = ConsumableTankCategoryFilter.toJSON(message.filter_type.value);
|
||||
}
|
||||
if (message.filter_type?.$case === "nations") {
|
||||
} else if (message.filter_type?.$case === "nations") {
|
||||
obj.nations = ConsumableTankNationFilter.toJSON(message.filter_type.value);
|
||||
}
|
||||
return obj;
|
||||
@@ -526,45 +522,46 @@ export const ConsumableTankFilter: MessageFns<ConsumableTankFilter> = {
|
||||
},
|
||||
fromPartial<I extends Exact<DeepPartial<ConsumableTankFilter>, I>>(object: I): ConsumableTankFilter {
|
||||
const message = createBaseConsumableTankFilter();
|
||||
if (
|
||||
object.filter_type?.$case === "tiers" &&
|
||||
object.filter_type?.value !== undefined &&
|
||||
object.filter_type?.value !== null
|
||||
) {
|
||||
message.filter_type = { $case: "tiers", value: ConsumableTankTierFilter.fromPartial(object.filter_type.value) };
|
||||
}
|
||||
if (
|
||||
object.filter_type?.$case === "ids" &&
|
||||
object.filter_type?.value !== undefined &&
|
||||
object.filter_type?.value !== null
|
||||
) {
|
||||
message.filter_type = { $case: "ids", value: ConsumableTankIdsFilter.fromPartial(object.filter_type.value) };
|
||||
}
|
||||
if (
|
||||
object.filter_type?.$case === "categories" &&
|
||||
object.filter_type?.value !== undefined &&
|
||||
object.filter_type?.value !== null
|
||||
) {
|
||||
message.filter_type = {
|
||||
$case: "categories",
|
||||
value: ConsumableTankCategoryFilter.fromPartial(object.filter_type.value),
|
||||
};
|
||||
}
|
||||
if (
|
||||
object.filter_type?.$case === "nations" &&
|
||||
object.filter_type?.value !== undefined &&
|
||||
object.filter_type?.value !== null
|
||||
) {
|
||||
message.filter_type = {
|
||||
$case: "nations",
|
||||
value: ConsumableTankNationFilter.fromPartial(object.filter_type.value),
|
||||
};
|
||||
switch (object.filter_type?.$case) {
|
||||
case "tiers": {
|
||||
if (object.filter_type?.value !== undefined && object.filter_type?.value !== null) {
|
||||
message.filter_type = {
|
||||
$case: "tiers",
|
||||
value: ConsumableTankTierFilter.fromPartial(object.filter_type.value),
|
||||
};
|
||||
}
|
||||
break;
|
||||
}
|
||||
case "ids": {
|
||||
if (object.filter_type?.value !== undefined && object.filter_type?.value !== null) {
|
||||
message.filter_type = { $case: "ids", value: ConsumableTankIdsFilter.fromPartial(object.filter_type.value) };
|
||||
}
|
||||
break;
|
||||
}
|
||||
case "categories": {
|
||||
if (object.filter_type?.value !== undefined && object.filter_type?.value !== null) {
|
||||
message.filter_type = {
|
||||
$case: "categories",
|
||||
value: ConsumableTankCategoryFilter.fromPartial(object.filter_type.value),
|
||||
};
|
||||
}
|
||||
break;
|
||||
}
|
||||
case "nations": {
|
||||
if (object.filter_type?.value !== undefined && object.filter_type?.value !== null) {
|
||||
message.filter_type = {
|
||||
$case: "nations",
|
||||
value: ConsumableTankNationFilter.fromPartial(object.filter_type.value),
|
||||
};
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
return message;
|
||||
},
|
||||
};
|
||||
|
||||
export function createBaseConsumableTankTierFilter(): ConsumableTankTierFilter {
|
||||
function createBaseConsumableTankTierFilter(): ConsumableTankTierFilter {
|
||||
return { min: 0, max: 0 };
|
||||
}
|
||||
|
||||
@@ -581,7 +578,7 @@ export const ConsumableTankTierFilter: MessageFns<ConsumableTankTierFilter> = {
|
||||
|
||||
decode(input: BinaryReader | Uint8Array, length?: number): ConsumableTankTierFilter {
|
||||
const reader = input instanceof BinaryReader ? input : new BinaryReader(input);
|
||||
let end = length === undefined ? reader.len : reader.pos + length;
|
||||
const end = length === undefined ? reader.len : reader.pos + length;
|
||||
const message = createBaseConsumableTankTierFilter();
|
||||
while (reader.pos < end) {
|
||||
const tag = reader.uint32();
|
||||
@@ -613,8 +610,8 @@ export const ConsumableTankTierFilter: MessageFns<ConsumableTankTierFilter> = {
|
||||
|
||||
fromJSON(object: any): ConsumableTankTierFilter {
|
||||
return {
|
||||
min: globalThis.Number(assertSet("ConsumableTankTierFilter.min", object.min)),
|
||||
max: globalThis.Number(assertSet("ConsumableTankTierFilter.max", object.max)),
|
||||
min: isSet(object.min) ? globalThis.Number(object.min) : 0,
|
||||
max: isSet(object.max) ? globalThis.Number(object.max) : 0,
|
||||
};
|
||||
},
|
||||
|
||||
@@ -640,23 +637,21 @@ export const ConsumableTankTierFilter: MessageFns<ConsumableTankTierFilter> = {
|
||||
},
|
||||
};
|
||||
|
||||
export function createBaseConsumableTankIdsFilter(): ConsumableTankIdsFilter {
|
||||
function createBaseConsumableTankIdsFilter(): ConsumableTankIdsFilter {
|
||||
return { ids: [] };
|
||||
}
|
||||
|
||||
export const ConsumableTankIdsFilter: MessageFns<ConsumableTankIdsFilter> = {
|
||||
encode(message: ConsumableTankIdsFilter, writer: BinaryWriter = new BinaryWriter()): BinaryWriter {
|
||||
writer.uint32(10).fork();
|
||||
for (const v of message.ids) {
|
||||
writer.uint32(v);
|
||||
writer.uint32(8).uint32(v!);
|
||||
}
|
||||
writer.join();
|
||||
return writer;
|
||||
},
|
||||
|
||||
decode(input: BinaryReader | Uint8Array, length?: number): ConsumableTankIdsFilter {
|
||||
const reader = input instanceof BinaryReader ? input : new BinaryReader(input);
|
||||
let end = length === undefined ? reader.len : reader.pos + length;
|
||||
const end = length === undefined ? reader.len : reader.pos + length;
|
||||
const message = createBaseConsumableTankIdsFilter();
|
||||
while (reader.pos < end) {
|
||||
const tag = reader.uint32();
|
||||
@@ -710,23 +705,21 @@ export const ConsumableTankIdsFilter: MessageFns<ConsumableTankIdsFilter> = {
|
||||
},
|
||||
};
|
||||
|
||||
export function createBaseConsumableTankCategoryFilter(): ConsumableTankCategoryFilter {
|
||||
function createBaseConsumableTankCategoryFilter(): ConsumableTankCategoryFilter {
|
||||
return { categories: [] };
|
||||
}
|
||||
|
||||
export const ConsumableTankCategoryFilter: MessageFns<ConsumableTankCategoryFilter> = {
|
||||
encode(message: ConsumableTankCategoryFilter, writer: BinaryWriter = new BinaryWriter()): BinaryWriter {
|
||||
writer.uint32(10).fork();
|
||||
for (const v of message.categories) {
|
||||
writer.int32(v);
|
||||
writer.uint32(8).int32(v!);
|
||||
}
|
||||
writer.join();
|
||||
return writer;
|
||||
},
|
||||
|
||||
decode(input: BinaryReader | Uint8Array, length?: number): ConsumableTankCategoryFilter {
|
||||
const reader = input instanceof BinaryReader ? input : new BinaryReader(input);
|
||||
let end = length === undefined ? reader.len : reader.pos + length;
|
||||
const end = length === undefined ? reader.len : reader.pos + length;
|
||||
const message = createBaseConsumableTankCategoryFilter();
|
||||
while (reader.pos < end) {
|
||||
const tag = reader.uint32();
|
||||
@@ -784,7 +777,7 @@ export const ConsumableTankCategoryFilter: MessageFns<ConsumableTankCategoryFilt
|
||||
},
|
||||
};
|
||||
|
||||
export function createBaseConsumableTankNationFilter(): ConsumableTankNationFilter {
|
||||
function createBaseConsumableTankNationFilter(): ConsumableTankNationFilter {
|
||||
return { nations: [] };
|
||||
}
|
||||
|
||||
@@ -798,7 +791,7 @@ export const ConsumableTankNationFilter: MessageFns<ConsumableTankNationFilter>
|
||||
|
||||
decode(input: BinaryReader | Uint8Array, length?: number): ConsumableTankNationFilter {
|
||||
const reader = input instanceof BinaryReader ? input : new BinaryReader(input);
|
||||
let end = length === undefined ? reader.len : reader.pos + length;
|
||||
const end = length === undefined ? reader.len : reader.pos + length;
|
||||
const message = createBaseConsumableTankNationFilter();
|
||||
while (reader.pos < end) {
|
||||
const tag = reader.uint32();
|
||||
@@ -865,14 +858,6 @@ function isSet(value: any): boolean {
|
||||
return value !== null && value !== undefined;
|
||||
}
|
||||
|
||||
function assertSet<T>(field: string, value: T | undefined): T {
|
||||
if (!isSet(value)) {
|
||||
throw new TypeError(`Required field ${field} is not set`);
|
||||
}
|
||||
|
||||
return value as T;
|
||||
}
|
||||
|
||||
export interface MessageFns<T> {
|
||||
encode(message: T, writer?: BinaryWriter): BinaryWriter;
|
||||
decode(input: BinaryReader | Uint8Array, length?: number): T;
|
||||
|
||||
@@ -2,15 +2,15 @@ syntax = "proto2";
|
||||
|
||||
package blitzkit;
|
||||
|
||||
import "packages/core/src/protos/i18n.proto";
|
||||
import "i18n.proto";
|
||||
|
||||
message EquipmentDefinitions {
|
||||
map<string, EquipmentPreset> presets = 1;
|
||||
map<uint32, Equipment> equipments = 2;
|
||||
map<string, EquipmentPreset> presets = 1;
|
||||
map<uint32, Equipment> equipments = 2;
|
||||
}
|
||||
|
||||
message Equipment {
|
||||
required I18nString name = 1;
|
||||
required I18nString name = 1;
|
||||
required I18nString description = 2;
|
||||
}
|
||||
|
||||
@@ -19,6 +19,6 @@ message EquipmentPreset {
|
||||
}
|
||||
|
||||
message EquipmentSlot {
|
||||
required uint32 left = 1;
|
||||
required uint32 left = 1;
|
||||
required uint32 right = 2;
|
||||
}
|
||||
@@ -1,12 +1,12 @@
|
||||
// Code generated by protoc-gen-ts_proto. DO NOT EDIT.
|
||||
// versions:
|
||||
// protoc-gen-ts_proto v2.2.2
|
||||
// protoc-gen-ts_proto v2.11.2
|
||||
// protoc v5.28.2
|
||||
// source: packages/core/src/protos/equipment_definitions.proto
|
||||
// source: equipment_definitions.proto
|
||||
|
||||
/* eslint-disable */
|
||||
import { BinaryReader, BinaryWriter } from "@bufbuild/protobuf/wire";
|
||||
import { createBaseI18nString, I18nString } from "./i18n";
|
||||
import { I18nString } from "./i18n";
|
||||
|
||||
export const protobufPackage = "blitzkit";
|
||||
|
||||
@@ -26,8 +26,8 @@ export interface EquipmentDefinitions_EquipmentsEntry {
|
||||
}
|
||||
|
||||
export interface Equipment {
|
||||
name: I18nString;
|
||||
description: I18nString;
|
||||
name: I18nString | undefined;
|
||||
description: I18nString | undefined;
|
||||
}
|
||||
|
||||
export interface EquipmentPreset {
|
||||
@@ -39,16 +39,16 @@ export interface EquipmentSlot {
|
||||
right: number;
|
||||
}
|
||||
|
||||
export function createBaseEquipmentDefinitions(): EquipmentDefinitions {
|
||||
function createBaseEquipmentDefinitions(): EquipmentDefinitions {
|
||||
return { presets: {}, equipments: {} };
|
||||
}
|
||||
|
||||
export const EquipmentDefinitions: MessageFns<EquipmentDefinitions> = {
|
||||
encode(message: EquipmentDefinitions, writer: BinaryWriter = new BinaryWriter()): BinaryWriter {
|
||||
Object.entries(message.presets).forEach(([key, value]) => {
|
||||
globalThis.Object.entries(message.presets).forEach(([key, value]: [string, EquipmentPreset]) => {
|
||||
EquipmentDefinitions_PresetsEntry.encode({ key: key as any, value }, writer.uint32(10).fork()).join();
|
||||
});
|
||||
Object.entries(message.equipments).forEach(([key, value]) => {
|
||||
globalThis.Object.entries(message.equipments).forEach(([key, value]: [string, Equipment]) => {
|
||||
EquipmentDefinitions_EquipmentsEntry.encode({ key: key as any, value }, writer.uint32(18).fork()).join();
|
||||
});
|
||||
return writer;
|
||||
@@ -56,7 +56,7 @@ export const EquipmentDefinitions: MessageFns<EquipmentDefinitions> = {
|
||||
|
||||
decode(input: BinaryReader | Uint8Array, length?: number): EquipmentDefinitions {
|
||||
const reader = input instanceof BinaryReader ? input : new BinaryReader(input);
|
||||
let end = length === undefined ? reader.len : reader.pos + length;
|
||||
const end = length === undefined ? reader.len : reader.pos + length;
|
||||
const message = createBaseEquipmentDefinitions();
|
||||
while (reader.pos < end) {
|
||||
const tag = reader.uint32();
|
||||
@@ -95,16 +95,22 @@ export const EquipmentDefinitions: MessageFns<EquipmentDefinitions> = {
|
||||
fromJSON(object: any): EquipmentDefinitions {
|
||||
return {
|
||||
presets: isObject(object.presets)
|
||||
? Object.entries(object.presets).reduce<{ [key: string]: EquipmentPreset }>((acc, [key, value]) => {
|
||||
acc[key] = EquipmentPreset.fromJSON(value);
|
||||
return acc;
|
||||
}, {})
|
||||
? (globalThis.Object.entries(object.presets) as [string, any][]).reduce(
|
||||
(acc: { [key: string]: EquipmentPreset }, [key, value]: [string, any]) => {
|
||||
acc[key] = EquipmentPreset.fromJSON(value);
|
||||
return acc;
|
||||
},
|
||||
{},
|
||||
)
|
||||
: {},
|
||||
equipments: isObject(object.equipments)
|
||||
? Object.entries(object.equipments).reduce<{ [key: number]: Equipment }>((acc, [key, value]) => {
|
||||
acc[globalThis.Number(key)] = Equipment.fromJSON(value);
|
||||
return acc;
|
||||
}, {})
|
||||
? (globalThis.Object.entries(object.equipments) as [string, any][]).reduce(
|
||||
(acc: { [key: number]: Equipment }, [key, value]: [string, any]) => {
|
||||
acc[globalThis.Number(key)] = Equipment.fromJSON(value);
|
||||
return acc;
|
||||
},
|
||||
{},
|
||||
)
|
||||
: {},
|
||||
};
|
||||
},
|
||||
@@ -112,7 +118,7 @@ export const EquipmentDefinitions: MessageFns<EquipmentDefinitions> = {
|
||||
toJSON(message: EquipmentDefinitions): unknown {
|
||||
const obj: any = {};
|
||||
if (message.presets) {
|
||||
const entries = Object.entries(message.presets);
|
||||
const entries = globalThis.Object.entries(message.presets) as [string, EquipmentPreset][];
|
||||
if (entries.length > 0) {
|
||||
obj.presets = {};
|
||||
entries.forEach(([k, v]) => {
|
||||
@@ -121,7 +127,7 @@ export const EquipmentDefinitions: MessageFns<EquipmentDefinitions> = {
|
||||
}
|
||||
}
|
||||
if (message.equipments) {
|
||||
const entries = Object.entries(message.equipments);
|
||||
const entries = globalThis.Object.entries(message.equipments) as [string, Equipment][];
|
||||
if (entries.length > 0) {
|
||||
obj.equipments = {};
|
||||
entries.forEach(([k, v]) => {
|
||||
@@ -137,8 +143,8 @@ export const EquipmentDefinitions: MessageFns<EquipmentDefinitions> = {
|
||||
},
|
||||
fromPartial<I extends Exact<DeepPartial<EquipmentDefinitions>, I>>(object: I): EquipmentDefinitions {
|
||||
const message = createBaseEquipmentDefinitions();
|
||||
message.presets = Object.entries(object.presets ?? {}).reduce<{ [key: string]: EquipmentPreset }>(
|
||||
(acc, [key, value]) => {
|
||||
message.presets = (globalThis.Object.entries(object.presets ?? {}) as [string, EquipmentPreset][]).reduce(
|
||||
(acc: { [key: string]: EquipmentPreset }, [key, value]: [string, EquipmentPreset]) => {
|
||||
if (value !== undefined) {
|
||||
acc[key] = EquipmentPreset.fromPartial(value);
|
||||
}
|
||||
@@ -146,8 +152,8 @@ export const EquipmentDefinitions: MessageFns<EquipmentDefinitions> = {
|
||||
},
|
||||
{},
|
||||
);
|
||||
message.equipments = Object.entries(object.equipments ?? {}).reduce<{ [key: number]: Equipment }>(
|
||||
(acc, [key, value]) => {
|
||||
message.equipments = (globalThis.Object.entries(object.equipments ?? {}) as [string, Equipment][]).reduce(
|
||||
(acc: { [key: number]: Equipment }, [key, value]: [string, Equipment]) => {
|
||||
if (value !== undefined) {
|
||||
acc[globalThis.Number(key)] = Equipment.fromPartial(value);
|
||||
}
|
||||
@@ -159,13 +165,13 @@ export const EquipmentDefinitions: MessageFns<EquipmentDefinitions> = {
|
||||
},
|
||||
};
|
||||
|
||||
export function createBaseEquipmentDefinitions_PresetsEntry(): EquipmentDefinitions_PresetsEntry {
|
||||
return { key: "", value: createBaseEquipmentPreset() };
|
||||
function createBaseEquipmentDefinitions_PresetsEntry(): EquipmentDefinitions_PresetsEntry {
|
||||
return { key: "", value: undefined };
|
||||
}
|
||||
|
||||
export const EquipmentDefinitions_PresetsEntry: MessageFns<EquipmentDefinitions_PresetsEntry> = {
|
||||
encode(message: EquipmentDefinitions_PresetsEntry, writer: BinaryWriter = new BinaryWriter()): BinaryWriter {
|
||||
if (message.key !== undefined) {
|
||||
if (message.key !== "") {
|
||||
writer.uint32(10).string(message.key);
|
||||
}
|
||||
if (message.value !== undefined) {
|
||||
@@ -176,7 +182,7 @@ export const EquipmentDefinitions_PresetsEntry: MessageFns<EquipmentDefinitions_
|
||||
|
||||
decode(input: BinaryReader | Uint8Array, length?: number): EquipmentDefinitions_PresetsEntry {
|
||||
const reader = input instanceof BinaryReader ? input : new BinaryReader(input);
|
||||
let end = length === undefined ? reader.len : reader.pos + length;
|
||||
const end = length === undefined ? reader.len : reader.pos + length;
|
||||
const message = createBaseEquipmentDefinitions_PresetsEntry();
|
||||
while (reader.pos < end) {
|
||||
const tag = reader.uint32();
|
||||
@@ -208,14 +214,14 @@ export const EquipmentDefinitions_PresetsEntry: MessageFns<EquipmentDefinitions_
|
||||
|
||||
fromJSON(object: any): EquipmentDefinitions_PresetsEntry {
|
||||
return {
|
||||
key: globalThis.String(assertSet("EquipmentDefinitions_PresetsEntry.key", object.key)),
|
||||
value: EquipmentPreset.fromJSON(assertSet("EquipmentDefinitions_PresetsEntry.value", object.value)),
|
||||
key: isSet(object.key) ? globalThis.String(object.key) : "",
|
||||
value: isSet(object.value) ? EquipmentPreset.fromJSON(object.value) : undefined,
|
||||
};
|
||||
},
|
||||
|
||||
toJSON(message: EquipmentDefinitions_PresetsEntry): unknown {
|
||||
const obj: any = {};
|
||||
if (message.key !== undefined) {
|
||||
if (message.key !== "") {
|
||||
obj.key = message.key;
|
||||
}
|
||||
if (message.value !== undefined) {
|
||||
@@ -236,18 +242,18 @@ export const EquipmentDefinitions_PresetsEntry: MessageFns<EquipmentDefinitions_
|
||||
message.key = object.key ?? "";
|
||||
message.value = (object.value !== undefined && object.value !== null)
|
||||
? EquipmentPreset.fromPartial(object.value)
|
||||
: createBaseEquipmentPreset();
|
||||
: undefined;
|
||||
return message;
|
||||
},
|
||||
};
|
||||
|
||||
export function createBaseEquipmentDefinitions_EquipmentsEntry(): EquipmentDefinitions_EquipmentsEntry {
|
||||
return { key: 0, value: createBaseEquipment() };
|
||||
function createBaseEquipmentDefinitions_EquipmentsEntry(): EquipmentDefinitions_EquipmentsEntry {
|
||||
return { key: 0, value: undefined };
|
||||
}
|
||||
|
||||
export const EquipmentDefinitions_EquipmentsEntry: MessageFns<EquipmentDefinitions_EquipmentsEntry> = {
|
||||
encode(message: EquipmentDefinitions_EquipmentsEntry, writer: BinaryWriter = new BinaryWriter()): BinaryWriter {
|
||||
if (message.key !== undefined) {
|
||||
if (message.key !== 0) {
|
||||
writer.uint32(8).uint32(message.key);
|
||||
}
|
||||
if (message.value !== undefined) {
|
||||
@@ -258,7 +264,7 @@ export const EquipmentDefinitions_EquipmentsEntry: MessageFns<EquipmentDefinitio
|
||||
|
||||
decode(input: BinaryReader | Uint8Array, length?: number): EquipmentDefinitions_EquipmentsEntry {
|
||||
const reader = input instanceof BinaryReader ? input : new BinaryReader(input);
|
||||
let end = length === undefined ? reader.len : reader.pos + length;
|
||||
const end = length === undefined ? reader.len : reader.pos + length;
|
||||
const message = createBaseEquipmentDefinitions_EquipmentsEntry();
|
||||
while (reader.pos < end) {
|
||||
const tag = reader.uint32();
|
||||
@@ -290,14 +296,14 @@ export const EquipmentDefinitions_EquipmentsEntry: MessageFns<EquipmentDefinitio
|
||||
|
||||
fromJSON(object: any): EquipmentDefinitions_EquipmentsEntry {
|
||||
return {
|
||||
key: globalThis.Number(assertSet("EquipmentDefinitions_EquipmentsEntry.key", object.key)),
|
||||
value: Equipment.fromJSON(assertSet("EquipmentDefinitions_EquipmentsEntry.value", object.value)),
|
||||
key: isSet(object.key) ? globalThis.Number(object.key) : 0,
|
||||
value: isSet(object.value) ? Equipment.fromJSON(object.value) : undefined,
|
||||
};
|
||||
},
|
||||
|
||||
toJSON(message: EquipmentDefinitions_EquipmentsEntry): unknown {
|
||||
const obj: any = {};
|
||||
if (message.key !== undefined) {
|
||||
if (message.key !== 0) {
|
||||
obj.key = Math.round(message.key);
|
||||
}
|
||||
if (message.value !== undefined) {
|
||||
@@ -318,13 +324,13 @@ export const EquipmentDefinitions_EquipmentsEntry: MessageFns<EquipmentDefinitio
|
||||
message.key = object.key ?? 0;
|
||||
message.value = (object.value !== undefined && object.value !== null)
|
||||
? Equipment.fromPartial(object.value)
|
||||
: createBaseEquipment();
|
||||
: undefined;
|
||||
return message;
|
||||
},
|
||||
};
|
||||
|
||||
export function createBaseEquipment(): Equipment {
|
||||
return { name: createBaseI18nString(), description: createBaseI18nString() };
|
||||
function createBaseEquipment(): Equipment {
|
||||
return { name: undefined, description: undefined };
|
||||
}
|
||||
|
||||
export const Equipment: MessageFns<Equipment> = {
|
||||
@@ -340,7 +346,7 @@ export const Equipment: MessageFns<Equipment> = {
|
||||
|
||||
decode(input: BinaryReader | Uint8Array, length?: number): Equipment {
|
||||
const reader = input instanceof BinaryReader ? input : new BinaryReader(input);
|
||||
let end = length === undefined ? reader.len : reader.pos + length;
|
||||
const end = length === undefined ? reader.len : reader.pos + length;
|
||||
const message = createBaseEquipment();
|
||||
while (reader.pos < end) {
|
||||
const tag = reader.uint32();
|
||||
@@ -372,8 +378,8 @@ export const Equipment: MessageFns<Equipment> = {
|
||||
|
||||
fromJSON(object: any): Equipment {
|
||||
return {
|
||||
name: I18nString.fromJSON(assertSet("Equipment.name", object.name)),
|
||||
description: I18nString.fromJSON(assertSet("Equipment.description", object.description)),
|
||||
name: isSet(object.name) ? I18nString.fromJSON(object.name) : undefined,
|
||||
description: isSet(object.description) ? I18nString.fromJSON(object.description) : undefined,
|
||||
};
|
||||
},
|
||||
|
||||
@@ -395,15 +401,15 @@ export const Equipment: MessageFns<Equipment> = {
|
||||
const message = createBaseEquipment();
|
||||
message.name = (object.name !== undefined && object.name !== null)
|
||||
? I18nString.fromPartial(object.name)
|
||||
: createBaseI18nString();
|
||||
: undefined;
|
||||
message.description = (object.description !== undefined && object.description !== null)
|
||||
? I18nString.fromPartial(object.description)
|
||||
: createBaseI18nString();
|
||||
: undefined;
|
||||
return message;
|
||||
},
|
||||
};
|
||||
|
||||
export function createBaseEquipmentPreset(): EquipmentPreset {
|
||||
function createBaseEquipmentPreset(): EquipmentPreset {
|
||||
return { slots: [] };
|
||||
}
|
||||
|
||||
@@ -417,7 +423,7 @@ export const EquipmentPreset: MessageFns<EquipmentPreset> = {
|
||||
|
||||
decode(input: BinaryReader | Uint8Array, length?: number): EquipmentPreset {
|
||||
const reader = input instanceof BinaryReader ? input : new BinaryReader(input);
|
||||
let end = length === undefined ? reader.len : reader.pos + length;
|
||||
const end = length === undefined ? reader.len : reader.pos + length;
|
||||
const message = createBaseEquipmentPreset();
|
||||
while (reader.pos < end) {
|
||||
const tag = reader.uint32();
|
||||
@@ -463,7 +469,7 @@ export const EquipmentPreset: MessageFns<EquipmentPreset> = {
|
||||
},
|
||||
};
|
||||
|
||||
export function createBaseEquipmentSlot(): EquipmentSlot {
|
||||
function createBaseEquipmentSlot(): EquipmentSlot {
|
||||
return { left: 0, right: 0 };
|
||||
}
|
||||
|
||||
@@ -480,7 +486,7 @@ export const EquipmentSlot: MessageFns<EquipmentSlot> = {
|
||||
|
||||
decode(input: BinaryReader | Uint8Array, length?: number): EquipmentSlot {
|
||||
const reader = input instanceof BinaryReader ? input : new BinaryReader(input);
|
||||
let end = length === undefined ? reader.len : reader.pos + length;
|
||||
const end = length === undefined ? reader.len : reader.pos + length;
|
||||
const message = createBaseEquipmentSlot();
|
||||
while (reader.pos < end) {
|
||||
const tag = reader.uint32();
|
||||
@@ -512,8 +518,8 @@ export const EquipmentSlot: MessageFns<EquipmentSlot> = {
|
||||
|
||||
fromJSON(object: any): EquipmentSlot {
|
||||
return {
|
||||
left: globalThis.Number(assertSet("EquipmentSlot.left", object.left)),
|
||||
right: globalThis.Number(assertSet("EquipmentSlot.right", object.right)),
|
||||
left: isSet(object.left) ? globalThis.Number(object.left) : 0,
|
||||
right: isSet(object.right) ? globalThis.Number(object.right) : 0,
|
||||
};
|
||||
},
|
||||
|
||||
@@ -560,14 +566,6 @@ function isSet(value: any): boolean {
|
||||
return value !== null && value !== undefined;
|
||||
}
|
||||
|
||||
function assertSet<T>(field: string, value: T | undefined): T {
|
||||
if (!isSet(value)) {
|
||||
throw new TypeError(`Required field ${field} is not set`);
|
||||
}
|
||||
|
||||
return value as T;
|
||||
}
|
||||
|
||||
export interface MessageFns<T> {
|
||||
encode(message: T, writer?: BinaryWriter): BinaryWriter;
|
||||
decode(input: BinaryReader | Uint8Array, length?: number): T;
|
||||
|
||||
@@ -2,14 +2,14 @@ syntax = "proto2";
|
||||
|
||||
package blitzkit;
|
||||
|
||||
import "packages/core/src/protos/i18n.proto";
|
||||
import "i18n.proto";
|
||||
|
||||
message Gallery {
|
||||
repeated Avatar avatars = 1;
|
||||
}
|
||||
|
||||
message Avatar {
|
||||
required string id = 1;
|
||||
required I18nString name = 2;
|
||||
required string extension = 3;
|
||||
required string id = 1;
|
||||
required I18nString name = 2;
|
||||
required string extension = 3;
|
||||
}
|
||||
@@ -1,12 +1,12 @@
|
||||
// Code generated by protoc-gen-ts_proto. DO NOT EDIT.
|
||||
// versions:
|
||||
// protoc-gen-ts_proto v2.2.2
|
||||
// protoc-gen-ts_proto v2.11.2
|
||||
// protoc v5.28.2
|
||||
// source: packages/core/src/protos/gallery.proto
|
||||
// source: gallery.proto
|
||||
|
||||
/* eslint-disable */
|
||||
import { BinaryReader, BinaryWriter } from "@bufbuild/protobuf/wire";
|
||||
import { createBaseI18nString, I18nString } from "./i18n";
|
||||
import { I18nString } from "./i18n";
|
||||
|
||||
export const protobufPackage = "blitzkit";
|
||||
|
||||
@@ -16,11 +16,11 @@ export interface Gallery {
|
||||
|
||||
export interface Avatar {
|
||||
id: string;
|
||||
name: I18nString;
|
||||
name: I18nString | undefined;
|
||||
extension: string;
|
||||
}
|
||||
|
||||
export function createBaseGallery(): Gallery {
|
||||
function createBaseGallery(): Gallery {
|
||||
return { avatars: [] };
|
||||
}
|
||||
|
||||
@@ -34,7 +34,7 @@ export const Gallery: MessageFns<Gallery> = {
|
||||
|
||||
decode(input: BinaryReader | Uint8Array, length?: number): Gallery {
|
||||
const reader = input instanceof BinaryReader ? input : new BinaryReader(input);
|
||||
let end = length === undefined ? reader.len : reader.pos + length;
|
||||
const end = length === undefined ? reader.len : reader.pos + length;
|
||||
const message = createBaseGallery();
|
||||
while (reader.pos < end) {
|
||||
const tag = reader.uint32();
|
||||
@@ -80,8 +80,8 @@ export const Gallery: MessageFns<Gallery> = {
|
||||
},
|
||||
};
|
||||
|
||||
export function createBaseAvatar(): Avatar {
|
||||
return { id: "", name: createBaseI18nString(), extension: "" };
|
||||
function createBaseAvatar(): Avatar {
|
||||
return { id: "", name: undefined, extension: "" };
|
||||
}
|
||||
|
||||
export const Avatar: MessageFns<Avatar> = {
|
||||
@@ -100,7 +100,7 @@ export const Avatar: MessageFns<Avatar> = {
|
||||
|
||||
decode(input: BinaryReader | Uint8Array, length?: number): Avatar {
|
||||
const reader = input instanceof BinaryReader ? input : new BinaryReader(input);
|
||||
let end = length === undefined ? reader.len : reader.pos + length;
|
||||
const end = length === undefined ? reader.len : reader.pos + length;
|
||||
const message = createBaseAvatar();
|
||||
while (reader.pos < end) {
|
||||
const tag = reader.uint32();
|
||||
@@ -140,9 +140,9 @@ export const Avatar: MessageFns<Avatar> = {
|
||||
|
||||
fromJSON(object: any): Avatar {
|
||||
return {
|
||||
id: globalThis.String(assertSet("Avatar.id", object.id)),
|
||||
name: I18nString.fromJSON(assertSet("Avatar.name", object.name)),
|
||||
extension: globalThis.String(assertSet("Avatar.extension", object.extension)),
|
||||
id: isSet(object.id) ? globalThis.String(object.id) : "",
|
||||
name: isSet(object.name) ? I18nString.fromJSON(object.name) : undefined,
|
||||
extension: isSet(object.extension) ? globalThis.String(object.extension) : "",
|
||||
};
|
||||
},
|
||||
|
||||
@@ -168,7 +168,7 @@ export const Avatar: MessageFns<Avatar> = {
|
||||
message.id = object.id ?? "";
|
||||
message.name = (object.name !== undefined && object.name !== null)
|
||||
? I18nString.fromPartial(object.name)
|
||||
: createBaseI18nString();
|
||||
: undefined;
|
||||
message.extension = object.extension ?? "";
|
||||
return message;
|
||||
},
|
||||
@@ -191,14 +191,6 @@ function isSet(value: any): boolean {
|
||||
return value !== null && value !== undefined;
|
||||
}
|
||||
|
||||
function assertSet<T>(field: string, value: T | undefined): T {
|
||||
if (!isSet(value)) {
|
||||
throw new TypeError(`Required field ${field} is not set`);
|
||||
}
|
||||
|
||||
return value as T;
|
||||
}
|
||||
|
||||
export interface MessageFns<T> {
|
||||
encode(message: T, writer?: BinaryWriter): BinaryWriter;
|
||||
decode(input: BinaryReader | Uint8Array, length?: number): T;
|
||||
|
||||
@@ -2,13 +2,13 @@ syntax = "proto2";
|
||||
|
||||
package blitzkit;
|
||||
|
||||
import "packages/core/src/protos/i18n.proto";
|
||||
import "i18n.proto";
|
||||
|
||||
message GameDefinitions {
|
||||
required string version = 1;
|
||||
repeated string nations = 2;
|
||||
map<uint32, GameMode> gameModes = 3;
|
||||
map<uint32, GameModeRole> roles = 4;
|
||||
required string version = 1;
|
||||
repeated string nations = 2;
|
||||
map<uint32, GameMode> gameModes = 3;
|
||||
map<uint32, GameModeRole> roles = 4;
|
||||
}
|
||||
|
||||
message GameMode {
|
||||
@@ -16,6 +16,6 @@ message GameMode {
|
||||
}
|
||||
|
||||
message GameModeRole {
|
||||
repeated uint32 provisions = 1;
|
||||
repeated uint32 provisions = 1;
|
||||
repeated uint32 consumables = 2;
|
||||
}
|
||||
@@ -1,12 +1,12 @@
|
||||
// Code generated by protoc-gen-ts_proto. DO NOT EDIT.
|
||||
// versions:
|
||||
// protoc-gen-ts_proto v2.2.2
|
||||
// protoc-gen-ts_proto v2.11.2
|
||||
// protoc v5.28.2
|
||||
// source: packages/core/src/protos/game_definitions.proto
|
||||
// source: game_definitions.proto
|
||||
|
||||
/* eslint-disable */
|
||||
import { BinaryReader, BinaryWriter } from "@bufbuild/protobuf/wire";
|
||||
import { createBaseI18nString, I18nString } from "./i18n";
|
||||
import { I18nString } from "./i18n";
|
||||
|
||||
export const protobufPackage = "blitzkit";
|
||||
|
||||
@@ -28,7 +28,7 @@ export interface GameDefinitions_RolesEntry {
|
||||
}
|
||||
|
||||
export interface GameMode {
|
||||
name: I18nString;
|
||||
name: I18nString | undefined;
|
||||
}
|
||||
|
||||
export interface GameModeRole {
|
||||
@@ -36,7 +36,7 @@ export interface GameModeRole {
|
||||
consumables: number[];
|
||||
}
|
||||
|
||||
export function createBaseGameDefinitions(): GameDefinitions {
|
||||
function createBaseGameDefinitions(): GameDefinitions {
|
||||
return { version: "", nations: [], gameModes: {}, roles: {} };
|
||||
}
|
||||
|
||||
@@ -48,10 +48,10 @@ export const GameDefinitions: MessageFns<GameDefinitions> = {
|
||||
for (const v of message.nations) {
|
||||
writer.uint32(18).string(v!);
|
||||
}
|
||||
Object.entries(message.gameModes).forEach(([key, value]) => {
|
||||
globalThis.Object.entries(message.gameModes).forEach(([key, value]: [string, GameMode]) => {
|
||||
GameDefinitions_GameModesEntry.encode({ key: key as any, value }, writer.uint32(26).fork()).join();
|
||||
});
|
||||
Object.entries(message.roles).forEach(([key, value]) => {
|
||||
globalThis.Object.entries(message.roles).forEach(([key, value]: [string, GameModeRole]) => {
|
||||
GameDefinitions_RolesEntry.encode({ key: key as any, value }, writer.uint32(34).fork()).join();
|
||||
});
|
||||
return writer;
|
||||
@@ -59,7 +59,7 @@ export const GameDefinitions: MessageFns<GameDefinitions> = {
|
||||
|
||||
decode(input: BinaryReader | Uint8Array, length?: number): GameDefinitions {
|
||||
const reader = input instanceof BinaryReader ? input : new BinaryReader(input);
|
||||
let end = length === undefined ? reader.len : reader.pos + length;
|
||||
const end = length === undefined ? reader.len : reader.pos + length;
|
||||
const message = createBaseGameDefinitions();
|
||||
while (reader.pos < end) {
|
||||
const tag = reader.uint32();
|
||||
@@ -113,19 +113,25 @@ export const GameDefinitions: MessageFns<GameDefinitions> = {
|
||||
|
||||
fromJSON(object: any): GameDefinitions {
|
||||
return {
|
||||
version: globalThis.String(assertSet("GameDefinitions.version", object.version)),
|
||||
version: isSet(object.version) ? globalThis.String(object.version) : "",
|
||||
nations: globalThis.Array.isArray(object?.nations) ? object.nations.map((e: any) => globalThis.String(e)) : [],
|
||||
gameModes: isObject(object.gameModes)
|
||||
? Object.entries(object.gameModes).reduce<{ [key: number]: GameMode }>((acc, [key, value]) => {
|
||||
acc[globalThis.Number(key)] = GameMode.fromJSON(value);
|
||||
return acc;
|
||||
}, {})
|
||||
? (globalThis.Object.entries(object.gameModes) as [string, any][]).reduce(
|
||||
(acc: { [key: number]: GameMode }, [key, value]: [string, any]) => {
|
||||
acc[globalThis.Number(key)] = GameMode.fromJSON(value);
|
||||
return acc;
|
||||
},
|
||||
{},
|
||||
)
|
||||
: {},
|
||||
roles: isObject(object.roles)
|
||||
? Object.entries(object.roles).reduce<{ [key: number]: GameModeRole }>((acc, [key, value]) => {
|
||||
acc[globalThis.Number(key)] = GameModeRole.fromJSON(value);
|
||||
return acc;
|
||||
}, {})
|
||||
? (globalThis.Object.entries(object.roles) as [string, any][]).reduce(
|
||||
(acc: { [key: number]: GameModeRole }, [key, value]: [string, any]) => {
|
||||
acc[globalThis.Number(key)] = GameModeRole.fromJSON(value);
|
||||
return acc;
|
||||
},
|
||||
{},
|
||||
)
|
||||
: {},
|
||||
};
|
||||
},
|
||||
@@ -139,7 +145,7 @@ export const GameDefinitions: MessageFns<GameDefinitions> = {
|
||||
obj.nations = message.nations;
|
||||
}
|
||||
if (message.gameModes) {
|
||||
const entries = Object.entries(message.gameModes);
|
||||
const entries = globalThis.Object.entries(message.gameModes) as [string, GameMode][];
|
||||
if (entries.length > 0) {
|
||||
obj.gameModes = {};
|
||||
entries.forEach(([k, v]) => {
|
||||
@@ -148,7 +154,7 @@ export const GameDefinitions: MessageFns<GameDefinitions> = {
|
||||
}
|
||||
}
|
||||
if (message.roles) {
|
||||
const entries = Object.entries(message.roles);
|
||||
const entries = globalThis.Object.entries(message.roles) as [string, GameModeRole][];
|
||||
if (entries.length > 0) {
|
||||
obj.roles = {};
|
||||
entries.forEach(([k, v]) => {
|
||||
@@ -166,8 +172,8 @@ export const GameDefinitions: MessageFns<GameDefinitions> = {
|
||||
const message = createBaseGameDefinitions();
|
||||
message.version = object.version ?? "";
|
||||
message.nations = object.nations?.map((e) => e) || [];
|
||||
message.gameModes = Object.entries(object.gameModes ?? {}).reduce<{ [key: number]: GameMode }>(
|
||||
(acc, [key, value]) => {
|
||||
message.gameModes = (globalThis.Object.entries(object.gameModes ?? {}) as [string, GameMode][]).reduce(
|
||||
(acc: { [key: number]: GameMode }, [key, value]: [string, GameMode]) => {
|
||||
if (value !== undefined) {
|
||||
acc[globalThis.Number(key)] = GameMode.fromPartial(value);
|
||||
}
|
||||
@@ -175,23 +181,26 @@ export const GameDefinitions: MessageFns<GameDefinitions> = {
|
||||
},
|
||||
{},
|
||||
);
|
||||
message.roles = Object.entries(object.roles ?? {}).reduce<{ [key: number]: GameModeRole }>((acc, [key, value]) => {
|
||||
if (value !== undefined) {
|
||||
acc[globalThis.Number(key)] = GameModeRole.fromPartial(value);
|
||||
}
|
||||
return acc;
|
||||
}, {});
|
||||
message.roles = (globalThis.Object.entries(object.roles ?? {}) as [string, GameModeRole][]).reduce(
|
||||
(acc: { [key: number]: GameModeRole }, [key, value]: [string, GameModeRole]) => {
|
||||
if (value !== undefined) {
|
||||
acc[globalThis.Number(key)] = GameModeRole.fromPartial(value);
|
||||
}
|
||||
return acc;
|
||||
},
|
||||
{},
|
||||
);
|
||||
return message;
|
||||
},
|
||||
};
|
||||
|
||||
export function createBaseGameDefinitions_GameModesEntry(): GameDefinitions_GameModesEntry {
|
||||
return { key: 0, value: createBaseGameMode() };
|
||||
function createBaseGameDefinitions_GameModesEntry(): GameDefinitions_GameModesEntry {
|
||||
return { key: 0, value: undefined };
|
||||
}
|
||||
|
||||
export const GameDefinitions_GameModesEntry: MessageFns<GameDefinitions_GameModesEntry> = {
|
||||
encode(message: GameDefinitions_GameModesEntry, writer: BinaryWriter = new BinaryWriter()): BinaryWriter {
|
||||
if (message.key !== undefined) {
|
||||
if (message.key !== 0) {
|
||||
writer.uint32(8).uint32(message.key);
|
||||
}
|
||||
if (message.value !== undefined) {
|
||||
@@ -202,7 +211,7 @@ export const GameDefinitions_GameModesEntry: MessageFns<GameDefinitions_GameMode
|
||||
|
||||
decode(input: BinaryReader | Uint8Array, length?: number): GameDefinitions_GameModesEntry {
|
||||
const reader = input instanceof BinaryReader ? input : new BinaryReader(input);
|
||||
let end = length === undefined ? reader.len : reader.pos + length;
|
||||
const end = length === undefined ? reader.len : reader.pos + length;
|
||||
const message = createBaseGameDefinitions_GameModesEntry();
|
||||
while (reader.pos < end) {
|
||||
const tag = reader.uint32();
|
||||
@@ -234,14 +243,14 @@ export const GameDefinitions_GameModesEntry: MessageFns<GameDefinitions_GameMode
|
||||
|
||||
fromJSON(object: any): GameDefinitions_GameModesEntry {
|
||||
return {
|
||||
key: globalThis.Number(assertSet("GameDefinitions_GameModesEntry.key", object.key)),
|
||||
value: GameMode.fromJSON(assertSet("GameDefinitions_GameModesEntry.value", object.value)),
|
||||
key: isSet(object.key) ? globalThis.Number(object.key) : 0,
|
||||
value: isSet(object.value) ? GameMode.fromJSON(object.value) : undefined,
|
||||
};
|
||||
},
|
||||
|
||||
toJSON(message: GameDefinitions_GameModesEntry): unknown {
|
||||
const obj: any = {};
|
||||
if (message.key !== undefined) {
|
||||
if (message.key !== 0) {
|
||||
obj.key = Math.round(message.key);
|
||||
}
|
||||
if (message.value !== undefined) {
|
||||
@@ -260,18 +269,18 @@ export const GameDefinitions_GameModesEntry: MessageFns<GameDefinitions_GameMode
|
||||
message.key = object.key ?? 0;
|
||||
message.value = (object.value !== undefined && object.value !== null)
|
||||
? GameMode.fromPartial(object.value)
|
||||
: createBaseGameMode();
|
||||
: undefined;
|
||||
return message;
|
||||
},
|
||||
};
|
||||
|
||||
export function createBaseGameDefinitions_RolesEntry(): GameDefinitions_RolesEntry {
|
||||
return { key: 0, value: createBaseGameModeRole() };
|
||||
function createBaseGameDefinitions_RolesEntry(): GameDefinitions_RolesEntry {
|
||||
return { key: 0, value: undefined };
|
||||
}
|
||||
|
||||
export const GameDefinitions_RolesEntry: MessageFns<GameDefinitions_RolesEntry> = {
|
||||
encode(message: GameDefinitions_RolesEntry, writer: BinaryWriter = new BinaryWriter()): BinaryWriter {
|
||||
if (message.key !== undefined) {
|
||||
if (message.key !== 0) {
|
||||
writer.uint32(8).uint32(message.key);
|
||||
}
|
||||
if (message.value !== undefined) {
|
||||
@@ -282,7 +291,7 @@ export const GameDefinitions_RolesEntry: MessageFns<GameDefinitions_RolesEntry>
|
||||
|
||||
decode(input: BinaryReader | Uint8Array, length?: number): GameDefinitions_RolesEntry {
|
||||
const reader = input instanceof BinaryReader ? input : new BinaryReader(input);
|
||||
let end = length === undefined ? reader.len : reader.pos + length;
|
||||
const end = length === undefined ? reader.len : reader.pos + length;
|
||||
const message = createBaseGameDefinitions_RolesEntry();
|
||||
while (reader.pos < end) {
|
||||
const tag = reader.uint32();
|
||||
@@ -314,14 +323,14 @@ export const GameDefinitions_RolesEntry: MessageFns<GameDefinitions_RolesEntry>
|
||||
|
||||
fromJSON(object: any): GameDefinitions_RolesEntry {
|
||||
return {
|
||||
key: globalThis.Number(assertSet("GameDefinitions_RolesEntry.key", object.key)),
|
||||
value: GameModeRole.fromJSON(assertSet("GameDefinitions_RolesEntry.value", object.value)),
|
||||
key: isSet(object.key) ? globalThis.Number(object.key) : 0,
|
||||
value: isSet(object.value) ? GameModeRole.fromJSON(object.value) : undefined,
|
||||
};
|
||||
},
|
||||
|
||||
toJSON(message: GameDefinitions_RolesEntry): unknown {
|
||||
const obj: any = {};
|
||||
if (message.key !== undefined) {
|
||||
if (message.key !== 0) {
|
||||
obj.key = Math.round(message.key);
|
||||
}
|
||||
if (message.value !== undefined) {
|
||||
@@ -338,13 +347,13 @@ export const GameDefinitions_RolesEntry: MessageFns<GameDefinitions_RolesEntry>
|
||||
message.key = object.key ?? 0;
|
||||
message.value = (object.value !== undefined && object.value !== null)
|
||||
? GameModeRole.fromPartial(object.value)
|
||||
: createBaseGameModeRole();
|
||||
: undefined;
|
||||
return message;
|
||||
},
|
||||
};
|
||||
|
||||
export function createBaseGameMode(): GameMode {
|
||||
return { name: createBaseI18nString() };
|
||||
function createBaseGameMode(): GameMode {
|
||||
return { name: undefined };
|
||||
}
|
||||
|
||||
export const GameMode: MessageFns<GameMode> = {
|
||||
@@ -357,7 +366,7 @@ export const GameMode: MessageFns<GameMode> = {
|
||||
|
||||
decode(input: BinaryReader | Uint8Array, length?: number): GameMode {
|
||||
const reader = input instanceof BinaryReader ? input : new BinaryReader(input);
|
||||
let end = length === undefined ? reader.len : reader.pos + length;
|
||||
const end = length === undefined ? reader.len : reader.pos + length;
|
||||
const message = createBaseGameMode();
|
||||
while (reader.pos < end) {
|
||||
const tag = reader.uint32();
|
||||
@@ -380,7 +389,7 @@ export const GameMode: MessageFns<GameMode> = {
|
||||
},
|
||||
|
||||
fromJSON(object: any): GameMode {
|
||||
return { name: I18nString.fromJSON(assertSet("GameMode.name", object.name)) };
|
||||
return { name: isSet(object.name) ? I18nString.fromJSON(object.name) : undefined };
|
||||
},
|
||||
|
||||
toJSON(message: GameMode): unknown {
|
||||
@@ -398,33 +407,29 @@ export const GameMode: MessageFns<GameMode> = {
|
||||
const message = createBaseGameMode();
|
||||
message.name = (object.name !== undefined && object.name !== null)
|
||||
? I18nString.fromPartial(object.name)
|
||||
: createBaseI18nString();
|
||||
: undefined;
|
||||
return message;
|
||||
},
|
||||
};
|
||||
|
||||
export function createBaseGameModeRole(): GameModeRole {
|
||||
function createBaseGameModeRole(): GameModeRole {
|
||||
return { provisions: [], consumables: [] };
|
||||
}
|
||||
|
||||
export const GameModeRole: MessageFns<GameModeRole> = {
|
||||
encode(message: GameModeRole, writer: BinaryWriter = new BinaryWriter()): BinaryWriter {
|
||||
writer.uint32(10).fork();
|
||||
for (const v of message.provisions) {
|
||||
writer.uint32(v);
|
||||
writer.uint32(8).uint32(v!);
|
||||
}
|
||||
writer.join();
|
||||
writer.uint32(18).fork();
|
||||
for (const v of message.consumables) {
|
||||
writer.uint32(v);
|
||||
writer.uint32(16).uint32(v!);
|
||||
}
|
||||
writer.join();
|
||||
return writer;
|
||||
},
|
||||
|
||||
decode(input: BinaryReader | Uint8Array, length?: number): GameModeRole {
|
||||
const reader = input instanceof BinaryReader ? input : new BinaryReader(input);
|
||||
let end = length === undefined ? reader.len : reader.pos + length;
|
||||
const end = length === undefined ? reader.len : reader.pos + length;
|
||||
const message = createBaseGameModeRole();
|
||||
while (reader.pos < end) {
|
||||
const tag = reader.uint32();
|
||||
@@ -528,14 +533,6 @@ function isSet(value: any): boolean {
|
||||
return value !== null && value !== undefined;
|
||||
}
|
||||
|
||||
function assertSet<T>(field: string, value: T | undefined): T {
|
||||
if (!isSet(value)) {
|
||||
throw new TypeError(`Required field ${field} is not set`);
|
||||
}
|
||||
|
||||
return value as T;
|
||||
}
|
||||
|
||||
export interface MessageFns<T> {
|
||||
encode(message: T, writer?: BinaryWriter): BinaryWriter;
|
||||
decode(input: BinaryReader | Uint8Array, length?: number): T;
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
// Code generated by protoc-gen-ts_proto. DO NOT EDIT.
|
||||
// versions:
|
||||
// protoc-gen-ts_proto v2.2.2
|
||||
// protoc-gen-ts_proto v2.11.2
|
||||
// protoc v5.28.2
|
||||
// source: packages/core/src/protos/i18n.proto
|
||||
// source: i18n.proto
|
||||
|
||||
/* eslint-disable */
|
||||
import { BinaryReader, BinaryWriter } from "@bufbuild/protobuf/wire";
|
||||
@@ -18,13 +18,13 @@ export interface I18nString_LocalesEntry {
|
||||
value: string;
|
||||
}
|
||||
|
||||
export function createBaseI18nString(): I18nString {
|
||||
function createBaseI18nString(): I18nString {
|
||||
return { locales: {} };
|
||||
}
|
||||
|
||||
export const I18nString: MessageFns<I18nString> = {
|
||||
encode(message: I18nString, writer: BinaryWriter = new BinaryWriter()): BinaryWriter {
|
||||
Object.entries(message.locales).forEach(([key, value]) => {
|
||||
globalThis.Object.entries(message.locales).forEach(([key, value]: [string, string]) => {
|
||||
I18nString_LocalesEntry.encode({ key: key as any, value }, writer.uint32(10).fork()).join();
|
||||
});
|
||||
return writer;
|
||||
@@ -32,7 +32,7 @@ export const I18nString: MessageFns<I18nString> = {
|
||||
|
||||
decode(input: BinaryReader | Uint8Array, length?: number): I18nString {
|
||||
const reader = input instanceof BinaryReader ? input : new BinaryReader(input);
|
||||
let end = length === undefined ? reader.len : reader.pos + length;
|
||||
const end = length === undefined ? reader.len : reader.pos + length;
|
||||
const message = createBaseI18nString();
|
||||
while (reader.pos < end) {
|
||||
const tag = reader.uint32();
|
||||
@@ -60,10 +60,13 @@ export const I18nString: MessageFns<I18nString> = {
|
||||
fromJSON(object: any): I18nString {
|
||||
return {
|
||||
locales: isObject(object.locales)
|
||||
? Object.entries(object.locales).reduce<{ [key: string]: string }>((acc, [key, value]) => {
|
||||
acc[key] = String(value);
|
||||
return acc;
|
||||
}, {})
|
||||
? (globalThis.Object.entries(object.locales) as [string, any][]).reduce(
|
||||
(acc: { [key: string]: string }, [key, value]: [string, any]) => {
|
||||
acc[key] = globalThis.String(value);
|
||||
return acc;
|
||||
},
|
||||
{},
|
||||
)
|
||||
: {},
|
||||
};
|
||||
},
|
||||
@@ -71,7 +74,7 @@ export const I18nString: MessageFns<I18nString> = {
|
||||
toJSON(message: I18nString): unknown {
|
||||
const obj: any = {};
|
||||
if (message.locales) {
|
||||
const entries = Object.entries(message.locales);
|
||||
const entries = globalThis.Object.entries(message.locales) as [string, string][];
|
||||
if (entries.length > 0) {
|
||||
obj.locales = {};
|
||||
entries.forEach(([k, v]) => {
|
||||
@@ -87,26 +90,29 @@ export const I18nString: MessageFns<I18nString> = {
|
||||
},
|
||||
fromPartial<I extends Exact<DeepPartial<I18nString>, I>>(object: I): I18nString {
|
||||
const message = createBaseI18nString();
|
||||
message.locales = Object.entries(object.locales ?? {}).reduce<{ [key: string]: string }>((acc, [key, value]) => {
|
||||
if (value !== undefined) {
|
||||
acc[key] = globalThis.String(value);
|
||||
}
|
||||
return acc;
|
||||
}, {});
|
||||
message.locales = (globalThis.Object.entries(object.locales ?? {}) as [string, string][]).reduce(
|
||||
(acc: { [key: string]: string }, [key, value]: [string, string]) => {
|
||||
if (value !== undefined) {
|
||||
acc[key] = globalThis.String(value);
|
||||
}
|
||||
return acc;
|
||||
},
|
||||
{},
|
||||
);
|
||||
return message;
|
||||
},
|
||||
};
|
||||
|
||||
export function createBaseI18nString_LocalesEntry(): I18nString_LocalesEntry {
|
||||
function createBaseI18nString_LocalesEntry(): I18nString_LocalesEntry {
|
||||
return { key: "", value: "" };
|
||||
}
|
||||
|
||||
export const I18nString_LocalesEntry: MessageFns<I18nString_LocalesEntry> = {
|
||||
encode(message: I18nString_LocalesEntry, writer: BinaryWriter = new BinaryWriter()): BinaryWriter {
|
||||
if (message.key !== undefined) {
|
||||
if (message.key !== "") {
|
||||
writer.uint32(10).string(message.key);
|
||||
}
|
||||
if (message.value !== undefined) {
|
||||
if (message.value !== "") {
|
||||
writer.uint32(18).string(message.value);
|
||||
}
|
||||
return writer;
|
||||
@@ -114,7 +120,7 @@ export const I18nString_LocalesEntry: MessageFns<I18nString_LocalesEntry> = {
|
||||
|
||||
decode(input: BinaryReader | Uint8Array, length?: number): I18nString_LocalesEntry {
|
||||
const reader = input instanceof BinaryReader ? input : new BinaryReader(input);
|
||||
let end = length === undefined ? reader.len : reader.pos + length;
|
||||
const end = length === undefined ? reader.len : reader.pos + length;
|
||||
const message = createBaseI18nString_LocalesEntry();
|
||||
while (reader.pos < end) {
|
||||
const tag = reader.uint32();
|
||||
@@ -146,17 +152,17 @@ export const I18nString_LocalesEntry: MessageFns<I18nString_LocalesEntry> = {
|
||||
|
||||
fromJSON(object: any): I18nString_LocalesEntry {
|
||||
return {
|
||||
key: globalThis.String(assertSet("I18nString_LocalesEntry.key", object.key)),
|
||||
value: globalThis.String(assertSet("I18nString_LocalesEntry.value", object.value)),
|
||||
key: isSet(object.key) ? globalThis.String(object.key) : "",
|
||||
value: isSet(object.value) ? globalThis.String(object.value) : "",
|
||||
};
|
||||
},
|
||||
|
||||
toJSON(message: I18nString_LocalesEntry): unknown {
|
||||
const obj: any = {};
|
||||
if (message.key !== undefined) {
|
||||
if (message.key !== "") {
|
||||
obj.key = message.key;
|
||||
}
|
||||
if (message.value !== undefined) {
|
||||
if (message.value !== "") {
|
||||
obj.value = message.value;
|
||||
}
|
||||
return obj;
|
||||
@@ -194,14 +200,6 @@ function isSet(value: any): boolean {
|
||||
return value !== null && value !== undefined;
|
||||
}
|
||||
|
||||
function assertSet<T>(field: string, value: T | undefined): T {
|
||||
if (!isSet(value)) {
|
||||
throw new TypeError(`Required field ${field} is not set`);
|
||||
}
|
||||
|
||||
return value as T;
|
||||
}
|
||||
|
||||
export interface MessageFns<T> {
|
||||
encode(message: T, writer?: BinaryWriter): BinaryWriter;
|
||||
decode(input: BinaryReader | Uint8Array, length?: number): T;
|
||||
|
||||
@@ -1,16 +1,16 @@
|
||||
// @ts-nocheck
|
||||
export * from './average_definitions.ts';
|
||||
export * from './camouflage_definitions.ts';
|
||||
export * from './consumable_definitions.ts';
|
||||
export * from './equipment_definitions.ts';
|
||||
export * from './gallery.ts';
|
||||
export * from './game_definitions.ts';
|
||||
export * from './i18n.ts';
|
||||
export * from './map_definitions.ts';
|
||||
export * from './model_definitions.ts';
|
||||
export * from './popular_tanks.ts';
|
||||
export * from './provision_definitions.ts';
|
||||
export * from './rating_leaderboard.ts';
|
||||
export * from './reviews.ts';
|
||||
export * from './skill_definitions.ts';
|
||||
export * from './tank_definitions.ts';
|
||||
export * from "./average_definitions.ts";
|
||||
export * from "./camouflage_definitions.ts";
|
||||
export * from "./consumable_definitions.ts";
|
||||
export * from "./equipment_definitions.ts";
|
||||
export * from "./gallery.ts";
|
||||
export * from "./game_definitions.ts";
|
||||
export * from "./i18n.ts";
|
||||
export * from "./map_definitions.ts";
|
||||
export * from "./model_definitions.ts";
|
||||
export * from "./popular_tanks.ts";
|
||||
export * from "./provision_definitions.ts";
|
||||
export * from "./rating_leaderboard.ts";
|
||||
export * from "./reviews.ts";
|
||||
export * from "./skill_definitions.ts";
|
||||
export * from "./tank_definitions.ts";
|
||||
@@ -2,13 +2,13 @@ syntax = "proto2";
|
||||
|
||||
package blitzkit;
|
||||
|
||||
import "packages/core/src/protos/i18n.proto";
|
||||
import "i18n.proto";
|
||||
|
||||
message MapDefinitions {
|
||||
map<int32, MapDefinition> maps = 1;
|
||||
}
|
||||
|
||||
message MapDefinition {
|
||||
required uint32 id = 1;
|
||||
required uint32 id = 1;
|
||||
required I18nString name = 2;
|
||||
}
|
||||
@@ -1,12 +1,12 @@
|
||||
// Code generated by protoc-gen-ts_proto. DO NOT EDIT.
|
||||
// versions:
|
||||
// protoc-gen-ts_proto v2.2.2
|
||||
// protoc-gen-ts_proto v2.11.2
|
||||
// protoc v5.28.2
|
||||
// source: packages/core/src/protos/map_definitions.proto
|
||||
// source: map_definitions.proto
|
||||
|
||||
/* eslint-disable */
|
||||
import { BinaryReader, BinaryWriter } from "@bufbuild/protobuf/wire";
|
||||
import { createBaseI18nString, I18nString } from "./i18n";
|
||||
import { I18nString } from "./i18n";
|
||||
|
||||
export const protobufPackage = "blitzkit";
|
||||
|
||||
@@ -21,16 +21,16 @@ export interface MapDefinitions_MapsEntry {
|
||||
|
||||
export interface MapDefinition {
|
||||
id: number;
|
||||
name: I18nString;
|
||||
name: I18nString | undefined;
|
||||
}
|
||||
|
||||
export function createBaseMapDefinitions(): MapDefinitions {
|
||||
function createBaseMapDefinitions(): MapDefinitions {
|
||||
return { maps: {} };
|
||||
}
|
||||
|
||||
export const MapDefinitions: MessageFns<MapDefinitions> = {
|
||||
encode(message: MapDefinitions, writer: BinaryWriter = new BinaryWriter()): BinaryWriter {
|
||||
Object.entries(message.maps).forEach(([key, value]) => {
|
||||
globalThis.Object.entries(message.maps).forEach(([key, value]: [string, MapDefinition]) => {
|
||||
MapDefinitions_MapsEntry.encode({ key: key as any, value }, writer.uint32(10).fork()).join();
|
||||
});
|
||||
return writer;
|
||||
@@ -38,7 +38,7 @@ export const MapDefinitions: MessageFns<MapDefinitions> = {
|
||||
|
||||
decode(input: BinaryReader | Uint8Array, length?: number): MapDefinitions {
|
||||
const reader = input instanceof BinaryReader ? input : new BinaryReader(input);
|
||||
let end = length === undefined ? reader.len : reader.pos + length;
|
||||
const end = length === undefined ? reader.len : reader.pos + length;
|
||||
const message = createBaseMapDefinitions();
|
||||
while (reader.pos < end) {
|
||||
const tag = reader.uint32();
|
||||
@@ -66,10 +66,13 @@ export const MapDefinitions: MessageFns<MapDefinitions> = {
|
||||
fromJSON(object: any): MapDefinitions {
|
||||
return {
|
||||
maps: isObject(object.maps)
|
||||
? Object.entries(object.maps).reduce<{ [key: number]: MapDefinition }>((acc, [key, value]) => {
|
||||
acc[globalThis.Number(key)] = MapDefinition.fromJSON(value);
|
||||
return acc;
|
||||
}, {})
|
||||
? (globalThis.Object.entries(object.maps) as [string, any][]).reduce(
|
||||
(acc: { [key: number]: MapDefinition }, [key, value]: [string, any]) => {
|
||||
acc[globalThis.Number(key)] = MapDefinition.fromJSON(value);
|
||||
return acc;
|
||||
},
|
||||
{},
|
||||
)
|
||||
: {},
|
||||
};
|
||||
},
|
||||
@@ -77,7 +80,7 @@ export const MapDefinitions: MessageFns<MapDefinitions> = {
|
||||
toJSON(message: MapDefinitions): unknown {
|
||||
const obj: any = {};
|
||||
if (message.maps) {
|
||||
const entries = Object.entries(message.maps);
|
||||
const entries = globalThis.Object.entries(message.maps) as [string, MapDefinition][];
|
||||
if (entries.length > 0) {
|
||||
obj.maps = {};
|
||||
entries.forEach(([k, v]) => {
|
||||
@@ -93,23 +96,26 @@ export const MapDefinitions: MessageFns<MapDefinitions> = {
|
||||
},
|
||||
fromPartial<I extends Exact<DeepPartial<MapDefinitions>, I>>(object: I): MapDefinitions {
|
||||
const message = createBaseMapDefinitions();
|
||||
message.maps = Object.entries(object.maps ?? {}).reduce<{ [key: number]: MapDefinition }>((acc, [key, value]) => {
|
||||
if (value !== undefined) {
|
||||
acc[globalThis.Number(key)] = MapDefinition.fromPartial(value);
|
||||
}
|
||||
return acc;
|
||||
}, {});
|
||||
message.maps = (globalThis.Object.entries(object.maps ?? {}) as [string, MapDefinition][]).reduce(
|
||||
(acc: { [key: number]: MapDefinition }, [key, value]: [string, MapDefinition]) => {
|
||||
if (value !== undefined) {
|
||||
acc[globalThis.Number(key)] = MapDefinition.fromPartial(value);
|
||||
}
|
||||
return acc;
|
||||
},
|
||||
{},
|
||||
);
|
||||
return message;
|
||||
},
|
||||
};
|
||||
|
||||
export function createBaseMapDefinitions_MapsEntry(): MapDefinitions_MapsEntry {
|
||||
return { key: 0, value: createBaseMapDefinition() };
|
||||
function createBaseMapDefinitions_MapsEntry(): MapDefinitions_MapsEntry {
|
||||
return { key: 0, value: undefined };
|
||||
}
|
||||
|
||||
export const MapDefinitions_MapsEntry: MessageFns<MapDefinitions_MapsEntry> = {
|
||||
encode(message: MapDefinitions_MapsEntry, writer: BinaryWriter = new BinaryWriter()): BinaryWriter {
|
||||
if (message.key !== undefined) {
|
||||
if (message.key !== 0) {
|
||||
writer.uint32(8).int32(message.key);
|
||||
}
|
||||
if (message.value !== undefined) {
|
||||
@@ -120,7 +126,7 @@ export const MapDefinitions_MapsEntry: MessageFns<MapDefinitions_MapsEntry> = {
|
||||
|
||||
decode(input: BinaryReader | Uint8Array, length?: number): MapDefinitions_MapsEntry {
|
||||
const reader = input instanceof BinaryReader ? input : new BinaryReader(input);
|
||||
let end = length === undefined ? reader.len : reader.pos + length;
|
||||
const end = length === undefined ? reader.len : reader.pos + length;
|
||||
const message = createBaseMapDefinitions_MapsEntry();
|
||||
while (reader.pos < end) {
|
||||
const tag = reader.uint32();
|
||||
@@ -152,14 +158,14 @@ export const MapDefinitions_MapsEntry: MessageFns<MapDefinitions_MapsEntry> = {
|
||||
|
||||
fromJSON(object: any): MapDefinitions_MapsEntry {
|
||||
return {
|
||||
key: globalThis.Number(assertSet("MapDefinitions_MapsEntry.key", object.key)),
|
||||
value: MapDefinition.fromJSON(assertSet("MapDefinitions_MapsEntry.value", object.value)),
|
||||
key: isSet(object.key) ? globalThis.Number(object.key) : 0,
|
||||
value: isSet(object.value) ? MapDefinition.fromJSON(object.value) : undefined,
|
||||
};
|
||||
},
|
||||
|
||||
toJSON(message: MapDefinitions_MapsEntry): unknown {
|
||||
const obj: any = {};
|
||||
if (message.key !== undefined) {
|
||||
if (message.key !== 0) {
|
||||
obj.key = Math.round(message.key);
|
||||
}
|
||||
if (message.value !== undefined) {
|
||||
@@ -176,13 +182,13 @@ export const MapDefinitions_MapsEntry: MessageFns<MapDefinitions_MapsEntry> = {
|
||||
message.key = object.key ?? 0;
|
||||
message.value = (object.value !== undefined && object.value !== null)
|
||||
? MapDefinition.fromPartial(object.value)
|
||||
: createBaseMapDefinition();
|
||||
: undefined;
|
||||
return message;
|
||||
},
|
||||
};
|
||||
|
||||
export function createBaseMapDefinition(): MapDefinition {
|
||||
return { id: 0, name: createBaseI18nString() };
|
||||
function createBaseMapDefinition(): MapDefinition {
|
||||
return { id: 0, name: undefined };
|
||||
}
|
||||
|
||||
export const MapDefinition: MessageFns<MapDefinition> = {
|
||||
@@ -198,7 +204,7 @@ export const MapDefinition: MessageFns<MapDefinition> = {
|
||||
|
||||
decode(input: BinaryReader | Uint8Array, length?: number): MapDefinition {
|
||||
const reader = input instanceof BinaryReader ? input : new BinaryReader(input);
|
||||
let end = length === undefined ? reader.len : reader.pos + length;
|
||||
const end = length === undefined ? reader.len : reader.pos + length;
|
||||
const message = createBaseMapDefinition();
|
||||
while (reader.pos < end) {
|
||||
const tag = reader.uint32();
|
||||
@@ -230,8 +236,8 @@ export const MapDefinition: MessageFns<MapDefinition> = {
|
||||
|
||||
fromJSON(object: any): MapDefinition {
|
||||
return {
|
||||
id: globalThis.Number(assertSet("MapDefinition.id", object.id)),
|
||||
name: I18nString.fromJSON(assertSet("MapDefinition.name", object.name)),
|
||||
id: isSet(object.id) ? globalThis.Number(object.id) : 0,
|
||||
name: isSet(object.name) ? I18nString.fromJSON(object.name) : undefined,
|
||||
};
|
||||
},
|
||||
|
||||
@@ -254,7 +260,7 @@ export const MapDefinition: MessageFns<MapDefinition> = {
|
||||
message.id = object.id ?? 0;
|
||||
message.name = (object.name !== undefined && object.name !== null)
|
||||
? I18nString.fromPartial(object.name)
|
||||
: createBaseI18nString();
|
||||
: undefined;
|
||||
return message;
|
||||
},
|
||||
};
|
||||
@@ -280,14 +286,6 @@ function isSet(value: any): boolean {
|
||||
return value !== null && value !== undefined;
|
||||
}
|
||||
|
||||
function assertSet<T>(field: string, value: T | undefined): T {
|
||||
if (!isSet(value)) {
|
||||
throw new TypeError(`Required field ${field} is not set`);
|
||||
}
|
||||
|
||||
return value as T;
|
||||
}
|
||||
|
||||
export interface MessageFns<T> {
|
||||
encode(message: T, writer?: BinaryWriter): BinaryWriter;
|
||||
decode(input: BinaryReader | Uint8Array, length?: number): T;
|
||||
|
||||
@@ -7,17 +7,17 @@ message ModelDefinitions {
|
||||
}
|
||||
|
||||
message ModelDefinition {
|
||||
required Armor armor = 1;
|
||||
required Vector3 turret_origin = 2;
|
||||
optional InitialTurretRotation initial_turret_rotation = 3;
|
||||
map<uint32, TurretModelDefinition> turrets = 4;
|
||||
map<uint32, TrackModelDefinition> tracks = 5;
|
||||
required BoundingBox bounding_box = 6;
|
||||
required Armor armor = 1;
|
||||
required Vector3 turret_origin = 2;
|
||||
optional InitialTurretRotation initial_turret_rotation = 3;
|
||||
map<uint32, TurretModelDefinition> turrets = 4;
|
||||
map<uint32, TrackModelDefinition> tracks = 5;
|
||||
required BoundingBox bounding_box = 6;
|
||||
}
|
||||
|
||||
message Armor {
|
||||
map<uint32, float> thickness = 1;
|
||||
repeated uint32 spaced = 2;
|
||||
repeated uint32 spaced = 2;
|
||||
}
|
||||
|
||||
message Vector3 {
|
||||
@@ -27,18 +27,18 @@ message Vector3 {
|
||||
}
|
||||
|
||||
message InitialTurretRotation {
|
||||
required float yaw = 1;
|
||||
required float yaw = 1;
|
||||
required float pitch = 2;
|
||||
required float roll = 3;
|
||||
required float roll = 3;
|
||||
}
|
||||
|
||||
message TurretModelDefinition {
|
||||
required BoundingBox bounding_box = 1;
|
||||
required Armor armor = 2;
|
||||
required uint32 model_id = 3;
|
||||
required Vector3 gun_origin = 4;
|
||||
map<uint32, GunModelDefinition> guns = 5;
|
||||
optional YawLimits yaw = 6;
|
||||
required BoundingBox bounding_box = 1;
|
||||
required Armor armor = 2;
|
||||
required uint32 model_id = 3;
|
||||
required Vector3 gun_origin = 4;
|
||||
map<uint32, GunModelDefinition> guns = 5;
|
||||
optional YawLimits yaw = 6;
|
||||
}
|
||||
|
||||
message YawLimits {
|
||||
@@ -52,28 +52,28 @@ message BoundingBox {
|
||||
}
|
||||
|
||||
message TrackModelDefinition {
|
||||
required float thickness = 1;
|
||||
required Vector3 origin = 2;
|
||||
required float thickness = 1;
|
||||
required Vector3 origin = 2;
|
||||
}
|
||||
|
||||
message GunModelDefinition {
|
||||
required Armor armor = 1;
|
||||
required float thickness = 2;
|
||||
required uint32 model_id = 3;
|
||||
required PitchLimits pitch = 4;
|
||||
optional float mask = 5;
|
||||
required Armor armor = 1;
|
||||
required float thickness = 2;
|
||||
required uint32 model_id = 3;
|
||||
required PitchLimits pitch = 4;
|
||||
optional float mask = 5;
|
||||
}
|
||||
|
||||
message PitchLimits {
|
||||
required float min = 1;
|
||||
required float max = 2;
|
||||
optional PitchLimitsExtrema front = 3;
|
||||
optional PitchLimitsExtrema back = 4;
|
||||
optional float transition = 5;
|
||||
required float min = 1;
|
||||
required float max = 2;
|
||||
optional PitchLimitsExtrema front = 3;
|
||||
optional PitchLimitsExtrema back = 4;
|
||||
optional float transition = 5;
|
||||
}
|
||||
|
||||
message PitchLimitsExtrema {
|
||||
required float min = 1;
|
||||
required float max = 2;
|
||||
required float min = 1;
|
||||
required float max = 2;
|
||||
required float range = 3;
|
||||
}
|
||||
File diff suppressed because it is too large.
Load diff
@@ -7,6 +7,6 @@ message PopularTanks {
|
||||
}
|
||||
|
||||
message PopularTank {
|
||||
required uint32 id = 1;
|
||||
required uint32 id = 1;
|
||||
required uint32 views = 2; // views in the last 7 days
|
||||
}
|
||||
@@ -1,8 +1,8 @@
|
||||
// Code generated by protoc-gen-ts_proto. DO NOT EDIT.
|
||||
// versions:
|
||||
// protoc-gen-ts_proto v2.2.2
|
||||
// protoc-gen-ts_proto v2.11.2
|
||||
// protoc v5.28.2
|
||||
// source: packages/core/src/protos/popular_tanks.proto
|
||||
// source: popular_tanks.proto
|
||||
|
||||
/* eslint-disable */
|
||||
import { BinaryReader, BinaryWriter } from "@bufbuild/protobuf/wire";
|
||||
@@ -19,7 +19,7 @@ export interface PopularTank {
|
||||
views: number;
|
||||
}
|
||||
|
||||
export function createBasePopularTanks(): PopularTanks {
|
||||
function createBasePopularTanks(): PopularTanks {
|
||||
return { tanks: [] };
|
||||
}
|
||||
|
||||
@@ -33,7 +33,7 @@ export const PopularTanks: MessageFns<PopularTanks> = {
|
||||
|
||||
decode(input: BinaryReader | Uint8Array, length?: number): PopularTanks {
|
||||
const reader = input instanceof BinaryReader ? input : new BinaryReader(input);
|
||||
let end = length === undefined ? reader.len : reader.pos + length;
|
||||
const end = length === undefined ? reader.len : reader.pos + length;
|
||||
const message = createBasePopularTanks();
|
||||
while (reader.pos < end) {
|
||||
const tag = reader.uint32();
|
||||
@@ -79,7 +79,7 @@ export const PopularTanks: MessageFns<PopularTanks> = {
|
||||
},
|
||||
};
|
||||
|
||||
export function createBasePopularTank(): PopularTank {
|
||||
function createBasePopularTank(): PopularTank {
|
||||
return { id: 0, views: 0 };
|
||||
}
|
||||
|
||||
@@ -96,7 +96,7 @@ export const PopularTank: MessageFns<PopularTank> = {
|
||||
|
||||
decode(input: BinaryReader | Uint8Array, length?: number): PopularTank {
|
||||
const reader = input instanceof BinaryReader ? input : new BinaryReader(input);
|
||||
let end = length === undefined ? reader.len : reader.pos + length;
|
||||
const end = length === undefined ? reader.len : reader.pos + length;
|
||||
const message = createBasePopularTank();
|
||||
while (reader.pos < end) {
|
||||
const tag = reader.uint32();
|
||||
@@ -128,8 +128,8 @@ export const PopularTank: MessageFns<PopularTank> = {
|
||||
|
||||
fromJSON(object: any): PopularTank {
|
||||
return {
|
||||
id: globalThis.Number(assertSet("PopularTank.id", object.id)),
|
||||
views: globalThis.Number(assertSet("PopularTank.views", object.views)),
|
||||
id: isSet(object.id) ? globalThis.Number(object.id) : 0,
|
||||
views: isSet(object.views) ? globalThis.Number(object.views) : 0,
|
||||
};
|
||||
},
|
||||
|
||||
@@ -172,14 +172,6 @@ function isSet(value: any): boolean {
|
||||
return value !== null && value !== undefined;
|
||||
}
|
||||
|
||||
function assertSet<T>(field: string, value: T | undefined): T {
|
||||
if (!isSet(value)) {
|
||||
throw new TypeError(`Required field ${field} is not set`);
|
||||
}
|
||||
|
||||
return value as T;
|
||||
}
|
||||
|
||||
export interface MessageFns<T> {
|
||||
encode(message: T, writer?: BinaryWriter): BinaryWriter;
|
||||
decode(input: BinaryReader | Uint8Array, length?: number): T;
|
||||
|
||||
@@ -2,18 +2,18 @@ syntax = "proto2";
|
||||
|
||||
package blitzkit;
|
||||
|
||||
import "packages/core/src/protos/consumable_definitions.proto";
|
||||
import "packages/core/src/protos/i18n.proto";
|
||||
import "consumable_definitions.proto";
|
||||
import "i18n.proto";
|
||||
|
||||
message ProvisionDefinitions {
|
||||
map<uint32, Provision> provisions = 1;
|
||||
}
|
||||
|
||||
message Provision {
|
||||
required uint32 id = 1;
|
||||
required I18nString name = 2;
|
||||
optional float crew = 3;
|
||||
required bool game_mode_exclusive = 5;
|
||||
repeated ConsumableTankFilter include = 6;
|
||||
repeated ConsumableTankFilter exclude = 7;
|
||||
required uint32 id = 1;
|
||||
required I18nString name = 2;
|
||||
optional float crew = 3;
|
||||
required bool game_mode_exclusive = 5;
|
||||
repeated ConsumableTankFilter include = 6;
|
||||
repeated ConsumableTankFilter exclude = 7;
|
||||
}
|
||||
@@ -1,13 +1,13 @@
|
||||
// Code generated by protoc-gen-ts_proto. DO NOT EDIT.
|
||||
// versions:
|
||||
// protoc-gen-ts_proto v2.2.2
|
||||
// protoc-gen-ts_proto v2.11.2
|
||||
// protoc v5.28.2
|
||||
// source: packages/core/src/protos/provision_definitions.proto
|
||||
// source: provision_definitions.proto
|
||||
|
||||
/* eslint-disable */
|
||||
import { BinaryReader, BinaryWriter } from "@bufbuild/protobuf/wire";
|
||||
import { ConsumableTankFilter } from "./consumable_definitions";
|
||||
import { createBaseI18nString, I18nString } from "./i18n";
|
||||
import { I18nString } from "./i18n";
|
||||
|
||||
export const protobufPackage = "blitzkit";
|
||||
|
||||
@@ -22,20 +22,20 @@ export interface ProvisionDefinitions_ProvisionsEntry {
|
||||
|
||||
export interface Provision {
|
||||
id: number;
|
||||
name: I18nString;
|
||||
name: I18nString | undefined;
|
||||
crew?: number | undefined;
|
||||
game_mode_exclusive: boolean;
|
||||
include: ConsumableTankFilter[];
|
||||
exclude: ConsumableTankFilter[];
|
||||
}
|
||||
|
||||
export function createBaseProvisionDefinitions(): ProvisionDefinitions {
|
||||
function createBaseProvisionDefinitions(): ProvisionDefinitions {
|
||||
return { provisions: {} };
|
||||
}
|
||||
|
||||
export const ProvisionDefinitions: MessageFns<ProvisionDefinitions> = {
|
||||
encode(message: ProvisionDefinitions, writer: BinaryWriter = new BinaryWriter()): BinaryWriter {
|
||||
Object.entries(message.provisions).forEach(([key, value]) => {
|
||||
globalThis.Object.entries(message.provisions).forEach(([key, value]: [string, Provision]) => {
|
||||
ProvisionDefinitions_ProvisionsEntry.encode({ key: key as any, value }, writer.uint32(10).fork()).join();
|
||||
});
|
||||
return writer;
|
||||
@@ -43,7 +43,7 @@ export const ProvisionDefinitions: MessageFns<ProvisionDefinitions> = {
|
||||
|
||||
decode(input: BinaryReader | Uint8Array, length?: number): ProvisionDefinitions {
|
||||
const reader = input instanceof BinaryReader ? input : new BinaryReader(input);
|
||||
let end = length === undefined ? reader.len : reader.pos + length;
|
||||
const end = length === undefined ? reader.len : reader.pos + length;
|
||||
const message = createBaseProvisionDefinitions();
|
||||
while (reader.pos < end) {
|
||||
const tag = reader.uint32();
|
||||
@@ -71,10 +71,13 @@ export const ProvisionDefinitions: MessageFns<ProvisionDefinitions> = {
|
||||
fromJSON(object: any): ProvisionDefinitions {
|
||||
return {
|
||||
provisions: isObject(object.provisions)
|
||||
? Object.entries(object.provisions).reduce<{ [key: number]: Provision }>((acc, [key, value]) => {
|
||||
acc[globalThis.Number(key)] = Provision.fromJSON(value);
|
||||
return acc;
|
||||
}, {})
|
||||
? (globalThis.Object.entries(object.provisions) as [string, any][]).reduce(
|
||||
(acc: { [key: number]: Provision }, [key, value]: [string, any]) => {
|
||||
acc[globalThis.Number(key)] = Provision.fromJSON(value);
|
||||
return acc;
|
||||
},
|
||||
{},
|
||||
)
|
||||
: {},
|
||||
};
|
||||
},
|
||||
@@ -82,7 +85,7 @@ export const ProvisionDefinitions: MessageFns<ProvisionDefinitions> = {
|
||||
toJSON(message: ProvisionDefinitions): unknown {
|
||||
const obj: any = {};
|
||||
if (message.provisions) {
|
||||
const entries = Object.entries(message.provisions);
|
||||
const entries = globalThis.Object.entries(message.provisions) as [string, Provision][];
|
||||
if (entries.length > 0) {
|
||||
obj.provisions = {};
|
||||
entries.forEach(([k, v]) => {
|
||||
@@ -98,8 +101,8 @@ export const ProvisionDefinitions: MessageFns<ProvisionDefinitions> = {
|
||||
},
|
||||
fromPartial<I extends Exact<DeepPartial<ProvisionDefinitions>, I>>(object: I): ProvisionDefinitions {
|
||||
const message = createBaseProvisionDefinitions();
|
||||
message.provisions = Object.entries(object.provisions ?? {}).reduce<{ [key: number]: Provision }>(
|
||||
(acc, [key, value]) => {
|
||||
message.provisions = (globalThis.Object.entries(object.provisions ?? {}) as [string, Provision][]).reduce(
|
||||
(acc: { [key: number]: Provision }, [key, value]: [string, Provision]) => {
|
||||
if (value !== undefined) {
|
||||
acc[globalThis.Number(key)] = Provision.fromPartial(value);
|
||||
}
|
||||
@@ -111,13 +114,13 @@ export const ProvisionDefinitions: MessageFns<ProvisionDefinitions> = {
|
||||
},
|
||||
};
|
||||
|
||||
export function createBaseProvisionDefinitions_ProvisionsEntry(): ProvisionDefinitions_ProvisionsEntry {
|
||||
return { key: 0, value: createBaseProvision() };
|
||||
function createBaseProvisionDefinitions_ProvisionsEntry(): ProvisionDefinitions_ProvisionsEntry {
|
||||
return { key: 0, value: undefined };
|
||||
}
|
||||
|
||||
export const ProvisionDefinitions_ProvisionsEntry: MessageFns<ProvisionDefinitions_ProvisionsEntry> = {
|
||||
encode(message: ProvisionDefinitions_ProvisionsEntry, writer: BinaryWriter = new BinaryWriter()): BinaryWriter {
|
||||
if (message.key !== undefined) {
|
||||
if (message.key !== 0) {
|
||||
writer.uint32(8).uint32(message.key);
|
||||
}
|
||||
if (message.value !== undefined) {
|
||||
@@ -128,7 +131,7 @@ export const ProvisionDefinitions_ProvisionsEntry: MessageFns<ProvisionDefinitio
|
||||
|
||||
decode(input: BinaryReader | Uint8Array, length?: number): ProvisionDefinitions_ProvisionsEntry {
|
||||
const reader = input instanceof BinaryReader ? input : new BinaryReader(input);
|
||||
let end = length === undefined ? reader.len : reader.pos + length;
|
||||
const end = length === undefined ? reader.len : reader.pos + length;
|
||||
const message = createBaseProvisionDefinitions_ProvisionsEntry();
|
||||
while (reader.pos < end) {
|
||||
const tag = reader.uint32();
|
||||
@@ -160,14 +163,14 @@ export const ProvisionDefinitions_ProvisionsEntry: MessageFns<ProvisionDefinitio
|
||||
|
||||
fromJSON(object: any): ProvisionDefinitions_ProvisionsEntry {
|
||||
return {
|
||||
key: globalThis.Number(assertSet("ProvisionDefinitions_ProvisionsEntry.key", object.key)),
|
||||
value: Provision.fromJSON(assertSet("ProvisionDefinitions_ProvisionsEntry.value", object.value)),
|
||||
key: isSet(object.key) ? globalThis.Number(object.key) : 0,
|
||||
value: isSet(object.value) ? Provision.fromJSON(object.value) : undefined,
|
||||
};
|
||||
},
|
||||
|
||||
toJSON(message: ProvisionDefinitions_ProvisionsEntry): unknown {
|
||||
const obj: any = {};
|
||||
if (message.key !== undefined) {
|
||||
if (message.key !== 0) {
|
||||
obj.key = Math.round(message.key);
|
||||
}
|
||||
if (message.value !== undefined) {
|
||||
@@ -188,13 +191,13 @@ export const ProvisionDefinitions_ProvisionsEntry: MessageFns<ProvisionDefinitio
|
||||
message.key = object.key ?? 0;
|
||||
message.value = (object.value !== undefined && object.value !== null)
|
||||
? Provision.fromPartial(object.value)
|
||||
: createBaseProvision();
|
||||
: undefined;
|
||||
return message;
|
||||
},
|
||||
};
|
||||
|
||||
export function createBaseProvision(): Provision {
|
||||
return { id: 0, name: createBaseI18nString(), crew: undefined, game_mode_exclusive: false, include: [], exclude: [] };
|
||||
function createBaseProvision(): Provision {
|
||||
return { id: 0, name: undefined, crew: 0, game_mode_exclusive: false, include: [], exclude: [] };
|
||||
}
|
||||
|
||||
export const Provision: MessageFns<Provision> = {
|
||||
@@ -205,7 +208,7 @@ export const Provision: MessageFns<Provision> = {
|
||||
if (message.name !== undefined) {
|
||||
I18nString.encode(message.name, writer.uint32(18).fork()).join();
|
||||
}
|
||||
if (message.crew !== undefined && message.crew !== undefined) {
|
||||
if (message.crew !== undefined && message.crew !== 0) {
|
||||
writer.uint32(29).float(message.crew);
|
||||
}
|
||||
if (message.game_mode_exclusive !== false) {
|
||||
@@ -222,7 +225,7 @@ export const Provision: MessageFns<Provision> = {
|
||||
|
||||
decode(input: BinaryReader | Uint8Array, length?: number): Provision {
|
||||
const reader = input instanceof BinaryReader ? input : new BinaryReader(input);
|
||||
let end = length === undefined ? reader.len : reader.pos + length;
|
||||
const end = length === undefined ? reader.len : reader.pos + length;
|
||||
const message = createBaseProvision();
|
||||
while (reader.pos < end) {
|
||||
const tag = reader.uint32();
|
||||
@@ -286,10 +289,14 @@ export const Provision: MessageFns<Provision> = {
|
||||
|
||||
fromJSON(object: any): Provision {
|
||||
return {
|
||||
id: globalThis.Number(assertSet("Provision.id", object.id)),
|
||||
name: I18nString.fromJSON(assertSet("Provision.name", object.name)),
|
||||
crew: isSet(object.crew) ? globalThis.Number(object.crew) : undefined,
|
||||
game_mode_exclusive: globalThis.Boolean(assertSet("Provision.game_mode_exclusive", object.game_mode_exclusive)),
|
||||
id: isSet(object.id) ? globalThis.Number(object.id) : 0,
|
||||
name: isSet(object.name) ? I18nString.fromJSON(object.name) : undefined,
|
||||
crew: isSet(object.crew) ? globalThis.Number(object.crew) : 0,
|
||||
game_mode_exclusive: isSet(object.gameModeExclusive)
|
||||
? globalThis.Boolean(object.gameModeExclusive)
|
||||
: isSet(object.game_mode_exclusive)
|
||||
? globalThis.Boolean(object.game_mode_exclusive)
|
||||
: false,
|
||||
include: globalThis.Array.isArray(object?.include)
|
||||
? object.include.map((e: any) => ConsumableTankFilter.fromJSON(e))
|
||||
: [],
|
||||
@@ -307,11 +314,11 @@ export const Provision: MessageFns<Provision> = {
|
||||
if (message.name !== undefined) {
|
||||
obj.name = I18nString.toJSON(message.name);
|
||||
}
|
||||
if (message.crew !== undefined && message.crew !== undefined) {
|
||||
if (message.crew !== undefined && message.crew !== 0) {
|
||||
obj.crew = message.crew;
|
||||
}
|
||||
if (message.game_mode_exclusive !== false) {
|
||||
obj.game_mode_exclusive = message.game_mode_exclusive;
|
||||
obj.gameModeExclusive = message.game_mode_exclusive;
|
||||
}
|
||||
if (message.include?.length) {
|
||||
obj.include = message.include.map((e) => ConsumableTankFilter.toJSON(e));
|
||||
@@ -330,8 +337,8 @@ export const Provision: MessageFns<Provision> = {
|
||||
message.id = object.id ?? 0;
|
||||
message.name = (object.name !== undefined && object.name !== null)
|
||||
? I18nString.fromPartial(object.name)
|
||||
: createBaseI18nString();
|
||||
message.crew = object.crew ?? undefined;
|
||||
: undefined;
|
||||
message.crew = object.crew ?? 0;
|
||||
message.game_mode_exclusive = object.game_mode_exclusive ?? false;
|
||||
message.include = object.include?.map((e) => ConsumableTankFilter.fromPartial(e)) || [];
|
||||
message.exclude = object.exclude?.map((e) => ConsumableTankFilter.fromPartial(e)) || [];
|
||||
@@ -360,14 +367,6 @@ function isSet(value: any): boolean {
|
||||
return value !== null && value !== undefined;
|
||||
}
|
||||
|
||||
function assertSet<T>(field: string, value: T | undefined): T {
|
||||
if (!isSet(value)) {
|
||||
throw new TypeError(`Required field ${field} is not set`);
|
||||
}
|
||||
|
||||
return value as T;
|
||||
}
|
||||
|
||||
export interface MessageFns<T> {
|
||||
encode(message: T, writer?: BinaryWriter): BinaryWriter;
|
||||
decode(input: BinaryReader | Uint8Array, length?: number): T;
|
||||
|
||||
@@ -14,7 +14,7 @@ message RatingLeaderboardV1 {
|
||||
}
|
||||
|
||||
message RatingLeaderboardEntryV1 {
|
||||
required uint32 id = 1;
|
||||
required uint32 id = 1;
|
||||
required uint32 score = 2;
|
||||
}
|
||||
|
||||
@@ -23,11 +23,11 @@ message RatingLeaderboardV2 {
|
||||
}
|
||||
|
||||
message RatingLeaderboardEntryV2 {
|
||||
required uint32 id = 1;
|
||||
required uint32 score = 2;
|
||||
required uint32 battles = 3;
|
||||
required uint32 wins = 4;
|
||||
required uint32 id = 1;
|
||||
required uint32 score = 2;
|
||||
required uint32 battles = 3;
|
||||
required uint32 wins = 4;
|
||||
required uint32 survived = 5;
|
||||
required uint32 damage = 6;
|
||||
required uint32 kills = 7;
|
||||
required uint32 damage = 6;
|
||||
required uint32 kills = 7;
|
||||
}
|
||||
@@ -1,8 +1,8 @@
|
||||
// Code generated by protoc-gen-ts_proto. DO NOT EDIT.
|
||||
// versions:
|
||||
// protoc-gen-ts_proto v2.2.2
|
||||
// protoc-gen-ts_proto v2.11.2
|
||||
// protoc v5.28.2
|
||||
// source: packages/core/src/protos/rating_leaderboard.proto
|
||||
// source: rating_leaderboard.proto
|
||||
|
||||
/* eslint-disable */
|
||||
import { BinaryReader, BinaryWriter } from "@bufbuild/protobuf/wire";
|
||||
@@ -36,7 +36,7 @@ export interface RatingLeaderboardEntryV2 {
|
||||
kills: number;
|
||||
}
|
||||
|
||||
export function createBaseRatingLeaderboard(): RatingLeaderboard {
|
||||
function createBaseRatingLeaderboard(): RatingLeaderboard {
|
||||
return { version: undefined };
|
||||
}
|
||||
|
||||
@@ -55,7 +55,7 @@ export const RatingLeaderboard: MessageFns<RatingLeaderboard> = {
|
||||
|
||||
decode(input: BinaryReader | Uint8Array, length?: number): RatingLeaderboard {
|
||||
const reader = input instanceof BinaryReader ? input : new BinaryReader(input);
|
||||
let end = length === undefined ? reader.len : reader.pos + length;
|
||||
const end = length === undefined ? reader.len : reader.pos + length;
|
||||
const message = createBaseRatingLeaderboard();
|
||||
while (reader.pos < end) {
|
||||
const tag = reader.uint32();
|
||||
@@ -99,8 +99,7 @@ export const RatingLeaderboard: MessageFns<RatingLeaderboard> = {
|
||||
const obj: any = {};
|
||||
if (message.version?.$case === "v1") {
|
||||
obj.v1 = RatingLeaderboardV1.toJSON(message.version.value);
|
||||
}
|
||||
if (message.version?.$case === "v2") {
|
||||
} else if (message.version?.$case === "v2") {
|
||||
obj.v2 = RatingLeaderboardV2.toJSON(message.version.value);
|
||||
}
|
||||
return obj;
|
||||
@@ -111,17 +110,25 @@ export const RatingLeaderboard: MessageFns<RatingLeaderboard> = {
|
||||
},
|
||||
fromPartial<I extends Exact<DeepPartial<RatingLeaderboard>, I>>(object: I): RatingLeaderboard {
|
||||
const message = createBaseRatingLeaderboard();
|
||||
if (object.version?.$case === "v1" && object.version?.value !== undefined && object.version?.value !== null) {
|
||||
message.version = { $case: "v1", value: RatingLeaderboardV1.fromPartial(object.version.value) };
|
||||
}
|
||||
if (object.version?.$case === "v2" && object.version?.value !== undefined && object.version?.value !== null) {
|
||||
message.version = { $case: "v2", value: RatingLeaderboardV2.fromPartial(object.version.value) };
|
||||
switch (object.version?.$case) {
|
||||
case "v1": {
|
||||
if (object.version?.value !== undefined && object.version?.value !== null) {
|
||||
message.version = { $case: "v1", value: RatingLeaderboardV1.fromPartial(object.version.value) };
|
||||
}
|
||||
break;
|
||||
}
|
||||
case "v2": {
|
||||
if (object.version?.value !== undefined && object.version?.value !== null) {
|
||||
message.version = { $case: "v2", value: RatingLeaderboardV2.fromPartial(object.version.value) };
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
return message;
|
||||
},
|
||||
};
|
||||
|
||||
export function createBaseRatingLeaderboardV1(): RatingLeaderboardV1 {
|
||||
function createBaseRatingLeaderboardV1(): RatingLeaderboardV1 {
|
||||
return { entries: [] };
|
||||
}
|
||||
|
||||
@@ -135,7 +142,7 @@ export const RatingLeaderboardV1: MessageFns<RatingLeaderboardV1> = {
|
||||
|
||||
decode(input: BinaryReader | Uint8Array, length?: number): RatingLeaderboardV1 {
|
||||
const reader = input instanceof BinaryReader ? input : new BinaryReader(input);
|
||||
let end = length === undefined ? reader.len : reader.pos + length;
|
||||
const end = length === undefined ? reader.len : reader.pos + length;
|
||||
const message = createBaseRatingLeaderboardV1();
|
||||
while (reader.pos < end) {
|
||||
const tag = reader.uint32();
|
||||
@@ -183,7 +190,7 @@ export const RatingLeaderboardV1: MessageFns<RatingLeaderboardV1> = {
|
||||
},
|
||||
};
|
||||
|
||||
export function createBaseRatingLeaderboardEntryV1(): RatingLeaderboardEntryV1 {
|
||||
function createBaseRatingLeaderboardEntryV1(): RatingLeaderboardEntryV1 {
|
||||
return { id: 0, score: 0 };
|
||||
}
|
||||
|
||||
@@ -200,7 +207,7 @@ export const RatingLeaderboardEntryV1: MessageFns<RatingLeaderboardEntryV1> = {
|
||||
|
||||
decode(input: BinaryReader | Uint8Array, length?: number): RatingLeaderboardEntryV1 {
|
||||
const reader = input instanceof BinaryReader ? input : new BinaryReader(input);
|
||||
let end = length === undefined ? reader.len : reader.pos + length;
|
||||
const end = length === undefined ? reader.len : reader.pos + length;
|
||||
const message = createBaseRatingLeaderboardEntryV1();
|
||||
while (reader.pos < end) {
|
||||
const tag = reader.uint32();
|
||||
@@ -232,8 +239,8 @@ export const RatingLeaderboardEntryV1: MessageFns<RatingLeaderboardEntryV1> = {
|
||||
|
||||
fromJSON(object: any): RatingLeaderboardEntryV1 {
|
||||
return {
|
||||
id: globalThis.Number(assertSet("RatingLeaderboardEntryV1.id", object.id)),
|
||||
score: globalThis.Number(assertSet("RatingLeaderboardEntryV1.score", object.score)),
|
||||
id: isSet(object.id) ? globalThis.Number(object.id) : 0,
|
||||
score: isSet(object.score) ? globalThis.Number(object.score) : 0,
|
||||
};
|
||||
},
|
||||
|
||||
@@ -259,7 +266,7 @@ export const RatingLeaderboardEntryV1: MessageFns<RatingLeaderboardEntryV1> = {
|
||||
},
|
||||
};
|
||||
|
||||
export function createBaseRatingLeaderboardV2(): RatingLeaderboardV2 {
|
||||
function createBaseRatingLeaderboardV2(): RatingLeaderboardV2 {
|
||||
return { entries: [] };
|
||||
}
|
||||
|
||||
@@ -273,7 +280,7 @@ export const RatingLeaderboardV2: MessageFns<RatingLeaderboardV2> = {
|
||||
|
||||
decode(input: BinaryReader | Uint8Array, length?: number): RatingLeaderboardV2 {
|
||||
const reader = input instanceof BinaryReader ? input : new BinaryReader(input);
|
||||
let end = length === undefined ? reader.len : reader.pos + length;
|
||||
const end = length === undefined ? reader.len : reader.pos + length;
|
||||
const message = createBaseRatingLeaderboardV2();
|
||||
while (reader.pos < end) {
|
||||
const tag = reader.uint32();
|
||||
@@ -321,7 +328,7 @@ export const RatingLeaderboardV2: MessageFns<RatingLeaderboardV2> = {
|
||||
},
|
||||
};
|
||||
|
||||
export function createBaseRatingLeaderboardEntryV2(): RatingLeaderboardEntryV2 {
|
||||
function createBaseRatingLeaderboardEntryV2(): RatingLeaderboardEntryV2 {
|
||||
return { id: 0, score: 0, battles: 0, wins: 0, survived: 0, damage: 0, kills: 0 };
|
||||
}
|
||||
|
||||
@@ -353,7 +360,7 @@ export const RatingLeaderboardEntryV2: MessageFns<RatingLeaderboardEntryV2> = {
|
||||
|
||||
decode(input: BinaryReader | Uint8Array, length?: number): RatingLeaderboardEntryV2 {
|
||||
const reader = input instanceof BinaryReader ? input : new BinaryReader(input);
|
||||
let end = length === undefined ? reader.len : reader.pos + length;
|
||||
const end = length === undefined ? reader.len : reader.pos + length;
|
||||
const message = createBaseRatingLeaderboardEntryV2();
|
||||
while (reader.pos < end) {
|
||||
const tag = reader.uint32();
|
||||
@@ -425,13 +432,13 @@ export const RatingLeaderboardEntryV2: MessageFns<RatingLeaderboardEntryV2> = {
|
||||
|
||||
fromJSON(object: any): RatingLeaderboardEntryV2 {
|
||||
return {
|
||||
id: globalThis.Number(assertSet("RatingLeaderboardEntryV2.id", object.id)),
|
||||
score: globalThis.Number(assertSet("RatingLeaderboardEntryV2.score", object.score)),
|
||||
battles: globalThis.Number(assertSet("RatingLeaderboardEntryV2.battles", object.battles)),
|
||||
wins: globalThis.Number(assertSet("RatingLeaderboardEntryV2.wins", object.wins)),
|
||||
survived: globalThis.Number(assertSet("RatingLeaderboardEntryV2.survived", object.survived)),
|
||||
damage: globalThis.Number(assertSet("RatingLeaderboardEntryV2.damage", object.damage)),
|
||||
kills: globalThis.Number(assertSet("RatingLeaderboardEntryV2.kills", object.kills)),
|
||||
id: isSet(object.id) ? globalThis.Number(object.id) : 0,
|
||||
score: isSet(object.score) ? globalThis.Number(object.score) : 0,
|
||||
battles: isSet(object.battles) ? globalThis.Number(object.battles) : 0,
|
||||
wins: isSet(object.wins) ? globalThis.Number(object.wins) : 0,
|
||||
survived: isSet(object.survived) ? globalThis.Number(object.survived) : 0,
|
||||
damage: isSet(object.damage) ? globalThis.Number(object.damage) : 0,
|
||||
kills: isSet(object.kills) ? globalThis.Number(object.kills) : 0,
|
||||
};
|
||||
},
|
||||
|
||||
@@ -494,14 +501,6 @@ function isSet(value: any): boolean {
|
||||
return value !== null && value !== undefined;
|
||||
}
|
||||
|
||||
function assertSet<T>(field: string, value: T | undefined): T {
|
||||
if (!isSet(value)) {
|
||||
throw new TypeError(`Required field ${field} is not set`);
|
||||
}
|
||||
|
||||
return value as T;
|
||||
}
|
||||
|
||||
export interface MessageFns<T> {
|
||||
encode(message: T, writer?: BinaryWriter): BinaryWriter;
|
||||
decode(input: BinaryReader | Uint8Array, length?: number): T;
|
||||
|
||||
@@ -8,10 +8,10 @@ message Reviews {
|
||||
|
||||
message Review {
|
||||
required float last_updated = 1;
|
||||
repeated Video videos = 2;
|
||||
repeated Video videos = 2;
|
||||
}
|
||||
|
||||
message Video {
|
||||
required string id = 1;
|
||||
required string id = 1;
|
||||
required string author = 2;
|
||||
}
|
||||
@@ -1,8 +1,8 @@
|
||||
// Code generated by protoc-gen-ts_proto. DO NOT EDIT.
|
||||
// versions:
|
||||
// protoc-gen-ts_proto v2.2.2
|
||||
// protoc-gen-ts_proto v2.11.2
|
||||
// protoc v5.28.2
|
||||
// source: packages/core/src/protos/reviews.proto
|
||||
// source: reviews.proto
|
||||
|
||||
/* eslint-disable */
|
||||
import { BinaryReader, BinaryWriter } from "@bufbuild/protobuf/wire";
|
||||
@@ -28,13 +28,13 @@ export interface Video {
|
||||
author: string;
|
||||
}
|
||||
|
||||
export function createBaseReviews(): Reviews {
|
||||
function createBaseReviews(): Reviews {
|
||||
return { reviews: {} };
|
||||
}
|
||||
|
||||
export const Reviews: MessageFns<Reviews> = {
|
||||
encode(message: Reviews, writer: BinaryWriter = new BinaryWriter()): BinaryWriter {
|
||||
Object.entries(message.reviews).forEach(([key, value]) => {
|
||||
globalThis.Object.entries(message.reviews).forEach(([key, value]: [string, Review]) => {
|
||||
Reviews_ReviewsEntry.encode({ key: key as any, value }, writer.uint32(10).fork()).join();
|
||||
});
|
||||
return writer;
|
||||
@@ -42,7 +42,7 @@ export const Reviews: MessageFns<Reviews> = {
|
||||
|
||||
decode(input: BinaryReader | Uint8Array, length?: number): Reviews {
|
||||
const reader = input instanceof BinaryReader ? input : new BinaryReader(input);
|
||||
let end = length === undefined ? reader.len : reader.pos + length;
|
||||
const end = length === undefined ? reader.len : reader.pos + length;
|
||||
const message = createBaseReviews();
|
||||
while (reader.pos < end) {
|
||||
const tag = reader.uint32();
|
||||
@@ -70,10 +70,13 @@ export const Reviews: MessageFns<Reviews> = {
|
||||
fromJSON(object: any): Reviews {
|
||||
return {
|
||||
reviews: isObject(object.reviews)
|
||||
? Object.entries(object.reviews).reduce<{ [key: number]: Review }>((acc, [key, value]) => {
|
||||
acc[globalThis.Number(key)] = Review.fromJSON(value);
|
||||
return acc;
|
||||
}, {})
|
||||
? (globalThis.Object.entries(object.reviews) as [string, any][]).reduce(
|
||||
(acc: { [key: number]: Review }, [key, value]: [string, any]) => {
|
||||
acc[globalThis.Number(key)] = Review.fromJSON(value);
|
||||
return acc;
|
||||
},
|
||||
{},
|
||||
)
|
||||
: {},
|
||||
};
|
||||
},
|
||||
@@ -81,7 +84,7 @@ export const Reviews: MessageFns<Reviews> = {
|
||||
toJSON(message: Reviews): unknown {
|
||||
const obj: any = {};
|
||||
if (message.reviews) {
|
||||
const entries = Object.entries(message.reviews);
|
||||
const entries = globalThis.Object.entries(message.reviews) as [string, Review][];
|
||||
if (entries.length > 0) {
|
||||
obj.reviews = {};
|
||||
entries.forEach(([k, v]) => {
|
||||
@@ -97,23 +100,26 @@ export const Reviews: MessageFns<Reviews> = {
|
||||
},
|
||||
fromPartial<I extends Exact<DeepPartial<Reviews>, I>>(object: I): Reviews {
|
||||
const message = createBaseReviews();
|
||||
message.reviews = Object.entries(object.reviews ?? {}).reduce<{ [key: number]: Review }>((acc, [key, value]) => {
|
||||
if (value !== undefined) {
|
||||
acc[globalThis.Number(key)] = Review.fromPartial(value);
|
||||
}
|
||||
return acc;
|
||||
}, {});
|
||||
message.reviews = (globalThis.Object.entries(object.reviews ?? {}) as [string, Review][]).reduce(
|
||||
(acc: { [key: number]: Review }, [key, value]: [string, Review]) => {
|
||||
if (value !== undefined) {
|
||||
acc[globalThis.Number(key)] = Review.fromPartial(value);
|
||||
}
|
||||
return acc;
|
||||
},
|
||||
{},
|
||||
);
|
||||
return message;
|
||||
},
|
||||
};
|
||||
|
||||
export function createBaseReviews_ReviewsEntry(): Reviews_ReviewsEntry {
|
||||
return { key: 0, value: createBaseReview() };
|
||||
function createBaseReviews_ReviewsEntry(): Reviews_ReviewsEntry {
|
||||
return { key: 0, value: undefined };
|
||||
}
|
||||
|
||||
export const Reviews_ReviewsEntry: MessageFns<Reviews_ReviewsEntry> = {
|
||||
encode(message: Reviews_ReviewsEntry, writer: BinaryWriter = new BinaryWriter()): BinaryWriter {
|
||||
if (message.key !== undefined) {
|
||||
if (message.key !== 0) {
|
||||
writer.uint32(8).uint32(message.key);
|
||||
}
|
||||
if (message.value !== undefined) {
|
||||
@@ -124,7 +130,7 @@ export const Reviews_ReviewsEntry: MessageFns<Reviews_ReviewsEntry> = {
|
||||
|
||||
decode(input: BinaryReader | Uint8Array, length?: number): Reviews_ReviewsEntry {
|
||||
const reader = input instanceof BinaryReader ? input : new BinaryReader(input);
|
||||
let end = length === undefined ? reader.len : reader.pos + length;
|
||||
const end = length === undefined ? reader.len : reader.pos + length;
|
||||
const message = createBaseReviews_ReviewsEntry();
|
||||
while (reader.pos < end) {
|
||||
const tag = reader.uint32();
|
||||
@@ -156,14 +162,14 @@ export const Reviews_ReviewsEntry: MessageFns<Reviews_ReviewsEntry> = {
|
||||
|
||||
fromJSON(object: any): Reviews_ReviewsEntry {
|
||||
return {
|
||||
key: globalThis.Number(assertSet("Reviews_ReviewsEntry.key", object.key)),
|
||||
value: Review.fromJSON(assertSet("Reviews_ReviewsEntry.value", object.value)),
|
||||
key: isSet(object.key) ? globalThis.Number(object.key) : 0,
|
||||
value: isSet(object.value) ? Review.fromJSON(object.value) : undefined,
|
||||
};
|
||||
},
|
||||
|
||||
toJSON(message: Reviews_ReviewsEntry): unknown {
|
||||
const obj: any = {};
|
||||
if (message.key !== undefined) {
|
||||
if (message.key !== 0) {
|
||||
obj.key = Math.round(message.key);
|
||||
}
|
||||
if (message.value !== undefined) {
|
||||
@@ -180,12 +186,12 @@ export const Reviews_ReviewsEntry: MessageFns<Reviews_ReviewsEntry> = {
|
||||
message.key = object.key ?? 0;
|
||||
message.value = (object.value !== undefined && object.value !== null)
|
||||
? Review.fromPartial(object.value)
|
||||
: createBaseReview();
|
||||
: undefined;
|
||||
return message;
|
||||
},
|
||||
};
|
||||
|
||||
export function createBaseReview(): Review {
|
||||
function createBaseReview(): Review {
|
||||
return { last_updated: 0, videos: [] };
|
||||
}
|
||||
|
||||
@@ -202,7 +208,7 @@ export const Review: MessageFns<Review> = {
|
||||
|
||||
decode(input: BinaryReader | Uint8Array, length?: number): Review {
|
||||
const reader = input instanceof BinaryReader ? input : new BinaryReader(input);
|
||||
let end = length === undefined ? reader.len : reader.pos + length;
|
||||
const end = length === undefined ? reader.len : reader.pos + length;
|
||||
const message = createBaseReview();
|
||||
while (reader.pos < end) {
|
||||
const tag = reader.uint32();
|
||||
@@ -234,7 +240,11 @@ export const Review: MessageFns<Review> = {
|
||||
|
||||
fromJSON(object: any): Review {
|
||||
return {
|
||||
last_updated: globalThis.Number(assertSet("Review.last_updated", object.last_updated)),
|
||||
last_updated: isSet(object.lastUpdated)
|
||||
? globalThis.Number(object.lastUpdated)
|
||||
: isSet(object.last_updated)
|
||||
? globalThis.Number(object.last_updated)
|
||||
: 0,
|
||||
videos: globalThis.Array.isArray(object?.videos) ? object.videos.map((e: any) => Video.fromJSON(e)) : [],
|
||||
};
|
||||
},
|
||||
@@ -242,7 +252,7 @@ export const Review: MessageFns<Review> = {
|
||||
toJSON(message: Review): unknown {
|
||||
const obj: any = {};
|
||||
if (message.last_updated !== 0) {
|
||||
obj.last_updated = message.last_updated;
|
||||
obj.lastUpdated = message.last_updated;
|
||||
}
|
||||
if (message.videos?.length) {
|
||||
obj.videos = message.videos.map((e) => Video.toJSON(e));
|
||||
@@ -261,7 +271,7 @@ export const Review: MessageFns<Review> = {
|
||||
},
|
||||
};
|
||||
|
||||
export function createBaseVideo(): Video {
|
||||
function createBaseVideo(): Video {
|
||||
return { id: "", author: "" };
|
||||
}
|
||||
|
||||
@@ -278,7 +288,7 @@ export const Video: MessageFns<Video> = {
|
||||
|
||||
decode(input: BinaryReader | Uint8Array, length?: number): Video {
|
||||
const reader = input instanceof BinaryReader ? input : new BinaryReader(input);
|
||||
let end = length === undefined ? reader.len : reader.pos + length;
|
||||
const end = length === undefined ? reader.len : reader.pos + length;
|
||||
const message = createBaseVideo();
|
||||
while (reader.pos < end) {
|
||||
const tag = reader.uint32();
|
||||
@@ -310,8 +320,8 @@ export const Video: MessageFns<Video> = {
|
||||
|
||||
fromJSON(object: any): Video {
|
||||
return {
|
||||
id: globalThis.String(assertSet("Video.id", object.id)),
|
||||
author: globalThis.String(assertSet("Video.author", object.author)),
|
||||
id: isSet(object.id) ? globalThis.String(object.id) : "",
|
||||
author: isSet(object.author) ? globalThis.String(object.author) : "",
|
||||
};
|
||||
},
|
||||
|
||||
@@ -358,14 +368,6 @@ function isSet(value: any): boolean {
|
||||
return value !== null && value !== undefined;
|
||||
}
|
||||
|
||||
function assertSet<T>(field: string, value: T | undefined): T {
|
||||
if (!isSet(value)) {
|
||||
throw new TypeError(`Required field ${field} is not set`);
|
||||
}
|
||||
|
||||
return value as T;
|
||||
}
|
||||
|
||||
export interface MessageFns<T> {
|
||||
encode(message: T, writer?: BinaryWriter): BinaryWriter;
|
||||
decode(input: BinaryReader | Uint8Array, length?: number): T;
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
// Code generated by protoc-gen-ts_proto. DO NOT EDIT.
|
||||
// versions:
|
||||
// protoc-gen-ts_proto v2.2.2
|
||||
// protoc-gen-ts_proto v2.11.2
|
||||
// protoc v5.28.2
|
||||
// source: packages/core/src/protos/skill_definitions.proto
|
||||
// source: skill_definitions.proto
|
||||
|
||||
/* eslint-disable */
|
||||
import { BinaryReader, BinaryWriter } from "@bufbuild/protobuf/wire";
|
||||
@@ -23,13 +23,13 @@ export interface Skill {
|
||||
skills: string[];
|
||||
}
|
||||
|
||||
export function createBaseSkillDefinitions(): SkillDefinitions {
|
||||
function createBaseSkillDefinitions(): SkillDefinitions {
|
||||
return { classes: {} };
|
||||
}
|
||||
|
||||
export const SkillDefinitions: MessageFns<SkillDefinitions> = {
|
||||
encode(message: SkillDefinitions, writer: BinaryWriter = new BinaryWriter()): BinaryWriter {
|
||||
Object.entries(message.classes).forEach(([key, value]) => {
|
||||
globalThis.Object.entries(message.classes).forEach(([key, value]: [string, Skill]) => {
|
||||
SkillDefinitions_ClassesEntry.encode({ key: key as any, value }, writer.uint32(10).fork()).join();
|
||||
});
|
||||
return writer;
|
||||
@@ -37,7 +37,7 @@ export const SkillDefinitions: MessageFns<SkillDefinitions> = {
|
||||
|
||||
decode(input: BinaryReader | Uint8Array, length?: number): SkillDefinitions {
|
||||
const reader = input instanceof BinaryReader ? input : new BinaryReader(input);
|
||||
let end = length === undefined ? reader.len : reader.pos + length;
|
||||
const end = length === undefined ? reader.len : reader.pos + length;
|
||||
const message = createBaseSkillDefinitions();
|
||||
while (reader.pos < end) {
|
||||
const tag = reader.uint32();
|
||||
@@ -65,10 +65,13 @@ export const SkillDefinitions: MessageFns<SkillDefinitions> = {
|
||||
fromJSON(object: any): SkillDefinitions {
|
||||
return {
|
||||
classes: isObject(object.classes)
|
||||
? Object.entries(object.classes).reduce<{ [key: number]: Skill }>((acc, [key, value]) => {
|
||||
acc[globalThis.Number(key)] = Skill.fromJSON(value);
|
||||
return acc;
|
||||
}, {})
|
||||
? (globalThis.Object.entries(object.classes) as [string, any][]).reduce(
|
||||
(acc: { [key: number]: Skill }, [key, value]: [string, any]) => {
|
||||
acc[globalThis.Number(key)] = Skill.fromJSON(value);
|
||||
return acc;
|
||||
},
|
||||
{},
|
||||
)
|
||||
: {},
|
||||
};
|
||||
},
|
||||
@@ -76,7 +79,7 @@ export const SkillDefinitions: MessageFns<SkillDefinitions> = {
|
||||
toJSON(message: SkillDefinitions): unknown {
|
||||
const obj: any = {};
|
||||
if (message.classes) {
|
||||
const entries = Object.entries(message.classes);
|
||||
const entries = globalThis.Object.entries(message.classes) as [string, Skill][];
|
||||
if (entries.length > 0) {
|
||||
obj.classes = {};
|
||||
entries.forEach(([k, v]) => {
|
||||
@@ -92,23 +95,26 @@ export const SkillDefinitions: MessageFns<SkillDefinitions> = {
|
||||
},
|
||||
fromPartial<I extends Exact<DeepPartial<SkillDefinitions>, I>>(object: I): SkillDefinitions {
|
||||
const message = createBaseSkillDefinitions();
|
||||
message.classes = Object.entries(object.classes ?? {}).reduce<{ [key: number]: Skill }>((acc, [key, value]) => {
|
||||
if (value !== undefined) {
|
||||
acc[globalThis.Number(key)] = Skill.fromPartial(value);
|
||||
}
|
||||
return acc;
|
||||
}, {});
|
||||
message.classes = (globalThis.Object.entries(object.classes ?? {}) as [string, Skill][]).reduce(
|
||||
(acc: { [key: number]: Skill }, [key, value]: [string, Skill]) => {
|
||||
if (value !== undefined) {
|
||||
acc[globalThis.Number(key)] = Skill.fromPartial(value);
|
||||
}
|
||||
return acc;
|
||||
},
|
||||
{},
|
||||
);
|
||||
return message;
|
||||
},
|
||||
};
|
||||
|
||||
export function createBaseSkillDefinitions_ClassesEntry(): SkillDefinitions_ClassesEntry {
|
||||
return { key: 0, value: createBaseSkill() };
|
||||
function createBaseSkillDefinitions_ClassesEntry(): SkillDefinitions_ClassesEntry {
|
||||
return { key: 0, value: undefined };
|
||||
}
|
||||
|
||||
export const SkillDefinitions_ClassesEntry: MessageFns<SkillDefinitions_ClassesEntry> = {
|
||||
encode(message: SkillDefinitions_ClassesEntry, writer: BinaryWriter = new BinaryWriter()): BinaryWriter {
|
||||
if (message.key !== undefined) {
|
||||
if (message.key !== 0) {
|
||||
writer.uint32(8).uint32(message.key);
|
||||
}
|
||||
if (message.value !== undefined) {
|
||||
@@ -119,7 +125,7 @@ export const SkillDefinitions_ClassesEntry: MessageFns<SkillDefinitions_ClassesE
|
||||
|
||||
decode(input: BinaryReader | Uint8Array, length?: number): SkillDefinitions_ClassesEntry {
|
||||
const reader = input instanceof BinaryReader ? input : new BinaryReader(input);
|
||||
let end = length === undefined ? reader.len : reader.pos + length;
|
||||
const end = length === undefined ? reader.len : reader.pos + length;
|
||||
const message = createBaseSkillDefinitions_ClassesEntry();
|
||||
while (reader.pos < end) {
|
||||
const tag = reader.uint32();
|
||||
@@ -151,14 +157,14 @@ export const SkillDefinitions_ClassesEntry: MessageFns<SkillDefinitions_ClassesE
|
||||
|
||||
fromJSON(object: any): SkillDefinitions_ClassesEntry {
|
||||
return {
|
||||
key: globalThis.Number(assertSet("SkillDefinitions_ClassesEntry.key", object.key)),
|
||||
value: Skill.fromJSON(assertSet("SkillDefinitions_ClassesEntry.value", object.value)),
|
||||
key: isSet(object.key) ? globalThis.Number(object.key) : 0,
|
||||
value: isSet(object.value) ? Skill.fromJSON(object.value) : undefined,
|
||||
};
|
||||
},
|
||||
|
||||
toJSON(message: SkillDefinitions_ClassesEntry): unknown {
|
||||
const obj: any = {};
|
||||
if (message.key !== undefined) {
|
||||
if (message.key !== 0) {
|
||||
obj.key = Math.round(message.key);
|
||||
}
|
||||
if (message.value !== undefined) {
|
||||
@@ -175,14 +181,12 @@ export const SkillDefinitions_ClassesEntry: MessageFns<SkillDefinitions_ClassesE
|
||||
): SkillDefinitions_ClassesEntry {
|
||||
const message = createBaseSkillDefinitions_ClassesEntry();
|
||||
message.key = object.key ?? 0;
|
||||
message.value = (object.value !== undefined && object.value !== null)
|
||||
? Skill.fromPartial(object.value)
|
||||
: createBaseSkill();
|
||||
message.value = (object.value !== undefined && object.value !== null) ? Skill.fromPartial(object.value) : undefined;
|
||||
return message;
|
||||
},
|
||||
};
|
||||
|
||||
export function createBaseSkill(): Skill {
|
||||
function createBaseSkill(): Skill {
|
||||
return { skills: [] };
|
||||
}
|
||||
|
||||
@@ -196,7 +200,7 @@ export const Skill: MessageFns<Skill> = {
|
||||
|
||||
decode(input: BinaryReader | Uint8Array, length?: number): Skill {
|
||||
const reader = input instanceof BinaryReader ? input : new BinaryReader(input);
|
||||
let end = length === undefined ? reader.len : reader.pos + length;
|
||||
const end = length === undefined ? reader.len : reader.pos + length;
|
||||
const message = createBaseSkill();
|
||||
while (reader.pos < end) {
|
||||
const tag = reader.uint32();
|
||||
@@ -263,14 +267,6 @@ function isSet(value: any): boolean {
|
||||
return value !== null && value !== undefined;
|
||||
}
|
||||
|
||||
function assertSet<T>(field: string, value: T | undefined): T {
|
||||
if (!isSet(value)) {
|
||||
throw new TypeError(`Required field ${field} is not set`);
|
||||
}
|
||||
|
||||
return value as T;
|
||||
}
|
||||
|
||||
export interface MessageFns<T> {
|
||||
encode(message: T, writer?: BinaryWriter): BinaryWriter;
|
||||
decode(input: BinaryReader | Uint8Array, length?: number): T;
|
||||
|
||||
@@ -2,48 +2,58 @@ syntax = "proto2";
|
||||
|
||||
package blitzkit;
|
||||
|
||||
import "packages/core/src/protos/i18n.proto";
|
||||
import "i18n.proto";
|
||||
|
||||
message TankDefinitions {
|
||||
map<uint32, TankDefinition> tanks = 1;
|
||||
}
|
||||
|
||||
message TankDefinition {
|
||||
required uint32 id = 1;
|
||||
required string slug = 2;
|
||||
map<uint32, uint32> roles = 3;
|
||||
required bool fixed_camouflage = 5;
|
||||
repeated int32 camouflages = 6;
|
||||
repeated int32 ancestors = 7;
|
||||
repeated int32 successors = 8;
|
||||
repeated Crew crew = 9;
|
||||
required uint32 health = 10;
|
||||
required string nation = 11;
|
||||
required I18nString name = 12;
|
||||
required TankType type = 13;
|
||||
required uint32 max_consumables = 14;
|
||||
required uint32 max_provisions = 15;
|
||||
required uint32 tier = 16;
|
||||
required TankClass class = 17;
|
||||
required bool testing = 18;
|
||||
required bool deprecated = 19;
|
||||
repeated TurretDefinition turrets = 20;
|
||||
repeated EngineDefinition engines = 21;
|
||||
repeated TrackDefinition tracks = 22;
|
||||
required TankPrice price = 23;
|
||||
optional ResearchCost research_cost = 24;
|
||||
required float speed_forwards = 25;
|
||||
required float speed_backwards = 26;
|
||||
required float camouflage_still = 27;
|
||||
required float camouflage_moving = 28;
|
||||
required float camouflage_onFire = 29;
|
||||
required string equipment_preset = 30;
|
||||
required uint32 weight = 31;
|
||||
required uint32 id = 1;
|
||||
required string slug = 2;
|
||||
map<uint32, uint32> roles = 3;
|
||||
required bool fixed_camouflage = 5;
|
||||
repeated int32 camouflages = 6;
|
||||
repeated int32 ancestors = 7;
|
||||
repeated int32 successors = 8;
|
||||
repeated Crew crew = 9;
|
||||
required uint32 health = 10;
|
||||
required string nation = 11;
|
||||
required I18nString name = 12;
|
||||
required TankType type = 13;
|
||||
required uint32 max_consumables = 14;
|
||||
required uint32 max_provisions = 15;
|
||||
required uint32 tier = 16;
|
||||
required TankClass class = 17;
|
||||
required bool testing = 18;
|
||||
required bool deprecated = 19;
|
||||
repeated TurretDefinition turrets = 20;
|
||||
repeated EngineDefinition engines = 21;
|
||||
repeated TrackDefinition tracks = 22;
|
||||
required TankPrice price = 23;
|
||||
optional ResearchCost research_cost = 24;
|
||||
required float speed_forwards = 25;
|
||||
required float speed_backwards = 26;
|
||||
required float camouflage_still = 27;
|
||||
required float camouflage_moving = 28;
|
||||
required float camouflage_on_fire = 29;
|
||||
required string equipment_preset = 30;
|
||||
required uint32 weight = 31;
|
||||
required string dev_name = 32;
|
||||
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 {
|
||||
oneof research_cost_type {
|
||||
uint32 xp = 1;
|
||||
uint32 xp = 1;
|
||||
ResearchCostSeasonalTokens seasonal_tokens = 2;
|
||||
}
|
||||
}
|
||||
@@ -55,77 +65,77 @@ message ResearchCostSeasonalTokens {
|
||||
|
||||
enum TankPriceType {
|
||||
TANK_PRICE_TYPE_CREDITS = 0;
|
||||
TANK_PRICE_TYPE_GOLD = 1;
|
||||
TANK_PRICE_TYPE_GOLD = 1;
|
||||
}
|
||||
|
||||
message TankPrice {
|
||||
required TankPriceType type = 1;
|
||||
required uint32 value = 2;
|
||||
required TankPriceType type = 1;
|
||||
required uint32 value = 2;
|
||||
}
|
||||
|
||||
message TrackDefinition {
|
||||
required uint32 id = 1;
|
||||
required uint32 tier = 2;
|
||||
required I18nString name = 3;
|
||||
required uint32 weight = 4;
|
||||
required float traverse_speed = 5;
|
||||
optional ResearchCost research_cost = 6;
|
||||
required float dispersion_move = 7;
|
||||
required float dispersion_traverse = 8;
|
||||
required float resistance_hard = 9;
|
||||
required float resistance_medium = 10;
|
||||
required float resistance_soft = 11;
|
||||
repeated Unlock unlocks = 12;
|
||||
required uint32 id = 1;
|
||||
required uint32 tier = 2;
|
||||
required I18nString name = 3;
|
||||
required uint32 weight = 4;
|
||||
required float traverse_speed = 5;
|
||||
optional ResearchCost research_cost = 6;
|
||||
required float dispersion_move = 7;
|
||||
required float dispersion_traverse = 8;
|
||||
required float resistance_hard = 9;
|
||||
required float resistance_medium = 10;
|
||||
required float resistance_soft = 11;
|
||||
repeated Unlock unlocks = 12;
|
||||
}
|
||||
|
||||
message EngineDefinition {
|
||||
required uint32 id = 1;
|
||||
required I18nString name = 2;
|
||||
required uint32 id = 1;
|
||||
required I18nString name = 2;
|
||||
optional ResearchCost research_cost = 3;
|
||||
required uint32 tier = 4;
|
||||
required float fire_chance = 5;
|
||||
required uint32 power = 6;
|
||||
required uint32 weight = 7;
|
||||
repeated Unlock unlocks = 8;
|
||||
required uint32 tier = 4;
|
||||
required float fire_chance = 5;
|
||||
required uint32 power = 6;
|
||||
required uint32 weight = 7;
|
||||
repeated Unlock unlocks = 8;
|
||||
}
|
||||
|
||||
message TurretDefinition {
|
||||
required uint32 id = 1;
|
||||
required uint32 health = 2;
|
||||
required uint32 view_range = 3;
|
||||
required float traverse_speed = 4;
|
||||
optional ResearchCost research_cost = 5;
|
||||
required I18nString name = 6;
|
||||
required uint32 tier = 7;
|
||||
required uint32 weight = 8;
|
||||
repeated GunDefinition guns = 9;
|
||||
repeated Unlock unlocks = 10;
|
||||
required uint32 id = 1;
|
||||
required uint32 health = 2;
|
||||
required uint32 view_range = 3;
|
||||
required float traverse_speed = 4;
|
||||
optional ResearchCost research_cost = 5;
|
||||
required I18nString name = 6;
|
||||
required uint32 tier = 7;
|
||||
required uint32 weight = 8;
|
||||
repeated GunDefinition guns = 9;
|
||||
repeated Unlock unlocks = 10;
|
||||
}
|
||||
|
||||
message GunDefinition {
|
||||
oneof gun_type {
|
||||
GunDefinitionRegular regular = 1;
|
||||
GunDefinitionAutoLoader auto_loader = 2;
|
||||
GunDefinitionRegular regular = 1;
|
||||
GunDefinitionAutoLoader auto_loader = 2;
|
||||
GunDefinitionAutoReloader auto_reloader = 3;
|
||||
}
|
||||
|
||||
required uint32 id = 4;
|
||||
required float rotation_speed = 5;
|
||||
optional ResearchCost research_cost = 6;
|
||||
required uint32 weight = 7;
|
||||
required I18nString name = 8;
|
||||
required uint32 tier = 9;
|
||||
repeated ShellDefinition shells = 10;
|
||||
required float camouflage_loss = 11;
|
||||
required float aim_time = 12;
|
||||
required float dispersion_base = 13;
|
||||
required float dispersion_traverse = 14;
|
||||
required float dispersion_shot = 15;
|
||||
required float dispersion_damaged = 16;
|
||||
repeated Unlock unlocks = 17;
|
||||
required uint32 shell_capacity = 18;
|
||||
optional AssaultRanges assault_ranges = 19;
|
||||
optional Burst burst = 20;
|
||||
required uint32 id = 4;
|
||||
required float rotation_speed = 5;
|
||||
optional ResearchCost research_cost = 6;
|
||||
required uint32 weight = 7;
|
||||
required I18nString name = 8;
|
||||
required uint32 tier = 9;
|
||||
repeated ShellDefinition shells = 10;
|
||||
required float camouflage_loss = 11;
|
||||
required float aim_time = 12;
|
||||
required float dispersion_base = 13;
|
||||
required float dispersion_traverse = 14;
|
||||
required float dispersion_shot = 15;
|
||||
required float dispersion_damaged = 16;
|
||||
repeated Unlock unlocks = 17;
|
||||
required uint32 shell_capacity = 18;
|
||||
optional AssaultRanges assault_ranges = 19;
|
||||
optional Burst burst = 20;
|
||||
}
|
||||
|
||||
message GunDefinitionRegular {
|
||||
@@ -134,101 +144,101 @@ message GunDefinitionRegular {
|
||||
|
||||
message GunDefinitionAutoLoader {
|
||||
required float clip_reload = 1;
|
||||
required float intra_clip = 2;
|
||||
required float intra_clip = 2;
|
||||
required float shell_count = 3;
|
||||
}
|
||||
|
||||
message Burst {
|
||||
required uint32 count = 1;
|
||||
required float interval = 2;
|
||||
required uint32 count = 1;
|
||||
required float interval = 2;
|
||||
}
|
||||
|
||||
message GunDefinitionAutoReloader {
|
||||
repeated float shell_reloads = 1;
|
||||
required float intra_clip = 2;
|
||||
required float shell_count = 3;
|
||||
required float intra_clip = 2;
|
||||
required float shell_count = 3;
|
||||
}
|
||||
|
||||
message AssaultRanges {
|
||||
repeated AssaultRange ranges = 1;
|
||||
repeated ShellType types = 2;
|
||||
repeated ShellType types = 2;
|
||||
}
|
||||
|
||||
message AssaultRange {
|
||||
required float distance = 1;
|
||||
required float factor = 2;
|
||||
required float factor = 2;
|
||||
}
|
||||
|
||||
message ShellDefinition {
|
||||
required uint32 id = 1;
|
||||
required I18nString name = 2;
|
||||
required uint32 velocity = 3;
|
||||
required uint32 armor_damage = 4;
|
||||
required uint32 module_damage = 5;
|
||||
required float caliber = 6;
|
||||
required string icon = 7;
|
||||
required ShellPenetration penetration = 8;
|
||||
required ShellType type = 9;
|
||||
optional float normalization = 10;
|
||||
optional float ricochet = 11;
|
||||
optional float explosion_radius = 12;
|
||||
required uint32 range = 13;
|
||||
required uint32 id = 1;
|
||||
required I18nString name = 2;
|
||||
required uint32 velocity = 3;
|
||||
required uint32 armor_damage = 4;
|
||||
required uint32 module_damage = 5;
|
||||
required float caliber = 6;
|
||||
required string icon = 7;
|
||||
required ShellPenetration penetration = 8;
|
||||
required ShellType type = 9;
|
||||
optional float normalization = 10;
|
||||
optional float ricochet = 11;
|
||||
optional float explosion_radius = 12;
|
||||
required uint32 range = 13;
|
||||
}
|
||||
|
||||
enum ShellType {
|
||||
SHELL_TYPE_AP = 0;
|
||||
SHELL_TYPE_AP = 0;
|
||||
SHELL_TYPE_APCR = 1;
|
||||
SHELL_TYPE_HEAT = 2;
|
||||
SHELL_TYPE_HE = 3;
|
||||
SHELL_TYPE_HE = 3;
|
||||
}
|
||||
|
||||
message ShellPenetration {
|
||||
required float near = 1;
|
||||
required float far = 2;
|
||||
required float far = 2;
|
||||
}
|
||||
|
||||
message Unlock {
|
||||
required int32 id = 1;
|
||||
required int32 id = 1;
|
||||
required ModuleType type = 2;
|
||||
required UnlockCost cost = 3;
|
||||
}
|
||||
|
||||
message UnlockCost {
|
||||
required string type = 1;
|
||||
required int32 value = 2;
|
||||
required string type = 1;
|
||||
required int32 value = 2;
|
||||
}
|
||||
|
||||
enum ModuleType {
|
||||
MODULE_TYPE_VEHICLE = 0;
|
||||
MODULE_TYPE_ENGINE = 1;
|
||||
MODULE_TYPE_TRACKS = 2;
|
||||
MODULE_TYPE_TURRET = 3;
|
||||
MODULE_TYPE_GUN = 4;
|
||||
MODULE_TYPE_ENGINE = 1;
|
||||
MODULE_TYPE_TRACKS = 2;
|
||||
MODULE_TYPE_TURRET = 3;
|
||||
MODULE_TYPE_GUN = 4;
|
||||
}
|
||||
|
||||
enum TankClass {
|
||||
TANK_CLASS_LIGHT = 0;
|
||||
TANK_CLASS_MEDIUM = 1;
|
||||
TANK_CLASS_HEAVY = 2;
|
||||
TANK_CLASS_LIGHT = 0;
|
||||
TANK_CLASS_MEDIUM = 1;
|
||||
TANK_CLASS_HEAVY = 2;
|
||||
TANK_CLASS_TANK_DESTROYER = 3;
|
||||
}
|
||||
|
||||
enum TankType {
|
||||
TANK_TYPE_RESEARCHABLE = 0;
|
||||
TANK_TYPE_PREMIUM = 1;
|
||||
TANK_TYPE_COLLECTOR = 2;
|
||||
TANK_TYPE_PREMIUM = 1;
|
||||
TANK_TYPE_COLLECTOR = 2;
|
||||
}
|
||||
|
||||
message Crew {
|
||||
required CrewType type = 1;
|
||||
required uint32 count = 2;
|
||||
required CrewType type = 1;
|
||||
required uint32 count = 2;
|
||||
repeated CrewType substitute = 3;
|
||||
}
|
||||
|
||||
enum CrewType {
|
||||
CREW_TYPE_COMMANDER = 0;
|
||||
CREW_TYPE_RADIOMAN = 1;
|
||||
CREW_TYPE_GUNNER = 2;
|
||||
CREW_TYPE_DRIVER = 3;
|
||||
CREW_TYPE_LOADER = 4;
|
||||
CREW_TYPE_RADIOMAN = 1;
|
||||
CREW_TYPE_GUNNER = 2;
|
||||
CREW_TYPE_DRIVER = 3;
|
||||
CREW_TYPE_LOADER = 4;
|
||||
}
|
||||
File diff suppressed because it is too large.
Load diff
@@ -0,0 +1,3 @@
|
||||
export function bufferToBigInt(buffer: ArrayBuffer) {
|
||||
return new DataView(buffer).getBigUint64(0, true);
|
||||
}
|
||||
@@ -1,4 +1,5 @@
|
||||
export * from './buffer';
|
||||
export * from './bufferToBigInt';
|
||||
export * from './dds';
|
||||
export * from './dids';
|
||||
export * from './pvr';
|
||||
@@ -7,3 +8,4 @@ export * from './sc2';
|
||||
export * from './scg';
|
||||
export * from './scpg';
|
||||
export * from './windows';
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { clamp, isEqual, times } from 'lodash-es';
|
||||
import { ReadStream } from './buffer';
|
||||
import { clamp, isEqual, times } from "lodash-es";
|
||||
import { ReadStream } from "./buffer";
|
||||
|
||||
export enum PvrFlags {
|
||||
NoFlag = 0,
|
||||
@@ -96,7 +96,7 @@ export class PvrReadStream extends ReadStream {
|
||||
const header = this.header();
|
||||
this.metadata();
|
||||
|
||||
if (typeof header.pixelFormat === 'number') {
|
||||
if (typeof header.pixelFormat === "number") {
|
||||
switch (header.pixelFormat) {
|
||||
default:
|
||||
throw new TypeError(
|
||||
@@ -142,12 +142,12 @@ export class PvrReadStream extends ReadStream {
|
||||
|
||||
times(pixelCount, (index) => {
|
||||
const buffer = this.consumeUint8Array(2);
|
||||
const bufferIndex = index * 4;
|
||||
const bufferIndex = index * 3;
|
||||
const r = ((buffer[1] & 0b11111000) >>> 3) / 31;
|
||||
const g =
|
||||
((buffer[1] & 0b111) << 3) |
|
||||
(((buffer[0] & 0b11100000) >>> 5) / 31);
|
||||
const b = buffer[0] & 0b11111;
|
||||
(((buffer[1] & 0b111) << 3) | ((buffer[0] & 0b11100000) >>> 5)) /
|
||||
63;
|
||||
const b = (buffer[0] & 0b11111) / 31;
|
||||
|
||||
data[bufferIndex] = Math.round(clamp(r * 255, 0, 255));
|
||||
data[bufferIndex + 1] = Math.round(clamp(g * 255, 0, 255));
|
||||
@@ -186,7 +186,7 @@ export class PvrReadStream extends ReadStream {
|
||||
metadataSize: this.uint32(),
|
||||
};
|
||||
|
||||
if (header.version !== 'PVR\x03') throw new TypeError('Endian mismatch');
|
||||
if (header.version !== "PVR\x03") throw new TypeError("Endian mismatch");
|
||||
|
||||
return header;
|
||||
}
|
||||
@@ -205,19 +205,19 @@ export class PvrReadStream extends ReadStream {
|
||||
resolveBitRatePixelFormat(
|
||||
pixelFormat: Exclude<ReturnType<typeof this.pixelFormat>, number>,
|
||||
) {
|
||||
if (pixelFormat.order === 'rgba') {
|
||||
if (pixelFormat.order === "rgba") {
|
||||
if (isEqual(pixelFormat.bitRates, [4, 4, 4, 4])) {
|
||||
return ResolvedBitRatePixelFormat.R4G4B4A4;
|
||||
} else
|
||||
throw new TypeError(
|
||||
`Unhandled rgba bit rate ${pixelFormat.bitRates.join(', ')}`,
|
||||
`Unhandled rgba bit rate ${pixelFormat.bitRates.join(", ")}`,
|
||||
);
|
||||
} else if (pixelFormat.order === 'rgb\0') {
|
||||
} else if (pixelFormat.order === "rgb\0") {
|
||||
if (isEqual(pixelFormat.bitRates, [5, 6, 5, 0])) {
|
||||
return ResolvedBitRatePixelFormat.R5G6B5A0;
|
||||
} else
|
||||
throw new TypeError(
|
||||
`Unhandled rgb bit rate ${pixelFormat.bitRates.join(', ')}`,
|
||||
`Unhandled rgb bit rate ${pixelFormat.bitRates.join(", ")}`,
|
||||
);
|
||||
} else {
|
||||
throw new TypeError(`Unhandled pixel order ${pixelFormat.order}`);
|
||||
|
||||
@@ -15,6 +15,9 @@ type DataNode = {
|
||||
qualityGroup?: string;
|
||||
fxName?: string;
|
||||
textures?: Textures;
|
||||
customCullMode?: number;
|
||||
enabledPresets?: EnabledPresets;
|
||||
properties?: Properties;
|
||||
} & (
|
||||
| ({
|
||||
configCount: number;
|
||||
@@ -24,7 +27,7 @@ type DataNode = {
|
||||
}
|
||||
);
|
||||
|
||||
interface ConfigArchive {
|
||||
export interface ConfigArchive {
|
||||
configName: string;
|
||||
fxName: string;
|
||||
properties: Properties;
|
||||
|
||||
@@ -1083,6 +1083,7 @@
|
||||
"tier": "Tier",
|
||||
"type": "Type",
|
||||
"dev_id": "DEV: ID",
|
||||
"dev_name": "DEV: NAME",
|
||||
"purchase": "Purchase price",
|
||||
"restoration": "Restoration price",
|
||||
"sale": "Sale price",
|
||||
@@ -1108,6 +1109,11 @@
|
||||
"configuration": {
|
||||
"title": "Configuration",
|
||||
|
||||
"equalizer": {
|
||||
"title": "Equalizer",
|
||||
"equalize": "Equalize",
|
||||
"beta": "Beta"
|
||||
},
|
||||
"modules": {
|
||||
"title": "Modules",
|
||||
"stock": "Stock",
|
||||
@@ -1285,7 +1291,8 @@
|
||||
},
|
||||
"skills": {
|
||||
"clear": "Clear",
|
||||
"maximize": "Maximize"
|
||||
"maximize": "Maximize",
|
||||
"equalize": "Equalize"
|
||||
},
|
||||
"modules": {
|
||||
"stock": "Stock",
|
||||
|
||||
+15
-469
@@ -37,10 +37,11 @@
|
||||
"d_1": "Ayer"
|
||||
},
|
||||
"branches": {
|
||||
"local": "DEV",
|
||||
"dev": "Beta",
|
||||
"opentest": "Prueba Abierta",
|
||||
"preview": "Avance"
|
||||
"beta": "Beta",
|
||||
"development": "Development",
|
||||
"opentest": "Prueba abierta",
|
||||
"preview": "Preview",
|
||||
"production": "Production"
|
||||
},
|
||||
"locales": {
|
||||
"en": "Ingles",
|
||||
@@ -184,460 +185,6 @@
|
||||
"cumulative_battle_life_time": "Tiempo total de batalla"
|
||||
}
|
||||
},
|
||||
"bot": {
|
||||
"common": {
|
||||
"errors": {
|
||||
"clan_not_found": "# Could not find clan\nCouldn't find \"{search}\". Try selecting a clan from the search result.",
|
||||
"player_not_found": "# Could not find user\nI couldn't find user \"{search}\". Try picking an user from the search result, typing in a valid username, or using the `/link` command.",
|
||||
"player_not_linked": "# Usa `/vincular` para empezar\n¡No sé quién eres, pero puedes decírmelo hoy!",
|
||||
"tank_name_not_found": "# Tank not found\nCould not find tank by the name \"{search}\".",
|
||||
"tank_id_not_found": "# Tank not found\nCould not find tank by the ID \"{search}\". Try typing the name of the tank instead of a number.",
|
||||
"no_tank_stats": "# No hay estadísticas de tanque disponibles\nEste jugador no tiene estadísticas disponibles. Este podría no ser el jugador que estás buscando.",
|
||||
"get_help": "Servidor de ayuda de Discord",
|
||||
"uncaught_error": "# ¡Blitzkrieg sufrió un error!\nLo sentimos mucho. Siéntete libre de [unirte al servidor oficial de Discord](https://discord.gg/nDt7AjGJQH) para obtener ayuda.",
|
||||
"preview": "# Este comando es una vista previa\n\nSolo puedes acceder a este comando en [el servidor oficial de Discord](https://discord.gg/nDt7AjGJQH). Generalmente este comando estará disponible pronto.",
|
||||
"query_too_small": "# Tu búsqueda es demasiado corta\nDebe ser por lo menos de 3 caracteres de largo.",
|
||||
"query_too_long": "# Tu búsqueda es demasiado larga\nDebe ser como mucho de 100 caracteres de largo."
|
||||
},
|
||||
"wn8": {
|
||||
"name": "WN8",
|
||||
"types": {
|
||||
"very_bad": "Muy Malo",
|
||||
"bad": "Malo",
|
||||
"below_average": "Debajo del Promedio",
|
||||
"average": "Promedio",
|
||||
"above_average": "Superior al Promedio",
|
||||
"good": "Bueno",
|
||||
"very_good": "Muy Bueno",
|
||||
"great": "Excelente",
|
||||
"unicum": "Unicum",
|
||||
"super_unicum": "Super Unicum"
|
||||
}
|
||||
},
|
||||
"subcommands": {
|
||||
"today": {
|
||||
"name": "Hoy",
|
||||
"description": "Hoy"
|
||||
},
|
||||
"30": {
|
||||
"name": "30",
|
||||
"description": "30 días"
|
||||
},
|
||||
"60": {
|
||||
"name": "60",
|
||||
"description": "60 días"
|
||||
},
|
||||
"90": {
|
||||
"name": "90",
|
||||
"description": "90 días"
|
||||
},
|
||||
"career": {
|
||||
"name": "carrera",
|
||||
"description": "Carrera"
|
||||
},
|
||||
"custom": {
|
||||
"name": "personalizado",
|
||||
"description": "Rango personalizado",
|
||||
"options": {
|
||||
"start": {
|
||||
"name": "comenzar",
|
||||
"description": "Comenzar en cantidad de días pasados desde hoy"
|
||||
},
|
||||
"end": {
|
||||
"name": "fin",
|
||||
"description": "Terminar en cantidad de días pasados desde hoy"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"options": {
|
||||
"clan": {
|
||||
"name": "clan",
|
||||
"description": "El nombre o etiqueta del clan"
|
||||
},
|
||||
"tank": {
|
||||
"name": "tanque",
|
||||
"description": "El tanque al cual conseguirle estadísticas"
|
||||
},
|
||||
"username": {
|
||||
"name": "nombre de usuario",
|
||||
"description": "El nombre de usuario de Blitz"
|
||||
},
|
||||
"filters": {
|
||||
"nation": {
|
||||
"name": "nación",
|
||||
"description": "Nación"
|
||||
},
|
||||
"class": {
|
||||
"name": "clase",
|
||||
"description": "Clase"
|
||||
},
|
||||
"type": {
|
||||
"name": "tipo",
|
||||
"description": "Tipo"
|
||||
}
|
||||
},
|
||||
"region": {
|
||||
"name": "región",
|
||||
"description": "Región"
|
||||
},
|
||||
"tier": {
|
||||
"name": "tier",
|
||||
"description": "Nivel",
|
||||
"choices": {
|
||||
"tier": "Tier {tier_1} - {tier_2}"
|
||||
}
|
||||
}
|
||||
},
|
||||
"periods": {
|
||||
"career": "Carrera",
|
||||
"today": "Hoy",
|
||||
"days": "{days} days",
|
||||
"custom": "{day_1} - {day_2} days"
|
||||
},
|
||||
"filters": {
|
||||
"none": "Sin filtros",
|
||||
"tier": "Tier {tier}"
|
||||
},
|
||||
"no_data": {
|
||||
"battles_in_period": "No hay batallas jugadas en este período",
|
||||
"battles_in_season": "No hay batallas jugadas en esta temporada",
|
||||
"players_in_period": "No hay jugadores en este período",
|
||||
"tanks_found": "No se encontraron tanques"
|
||||
},
|
||||
"buttons": {
|
||||
"refresh": "Actualizar"
|
||||
},
|
||||
"hero_stats": {
|
||||
"battles": "Batallas",
|
||||
"winrate": "Tasa de victorias",
|
||||
"damage": "Daño",
|
||||
"damage_ratio": "Relación de daño",
|
||||
"tier": "Nivel",
|
||||
"survival": "Supervivencia",
|
||||
"accuracy": "Precisión",
|
||||
"kills": "Bajas"
|
||||
}
|
||||
},
|
||||
"commands": {
|
||||
"replay": {
|
||||
"name": "repetición",
|
||||
"description": "Mostrar resultados de la repetición"
|
||||
},
|
||||
"research": {
|
||||
"name": "desarollar",
|
||||
"description": "Enumera los gastos por investigar una línea",
|
||||
"options": {
|
||||
"target_tank": {
|
||||
"name": "tanque objetivo",
|
||||
"description": "El último tanque a investigar en la línea"
|
||||
},
|
||||
"starting_tank": {
|
||||
"name": "tanque de inicio",
|
||||
"description": "El tanque inicial en la línea (se deduce automáticamente si no se proporciona)"
|
||||
}
|
||||
},
|
||||
"body": {
|
||||
"subtitle": "Investigar",
|
||||
"total": "Total",
|
||||
"research": "Research: {cost}",
|
||||
"upgrades": "Upgrades: {cost}",
|
||||
"purchase": "Purchase: {cost}",
|
||||
"equipment": "Equipment: {cost}",
|
||||
"estimation": "# ¡Esto es una estimación!\n\nEsta lista podría incluir tanques ya investigados debido a la información errónea que proporciona Wargaming. Si puedes, prueba proporcionando un `tanque-inicial` de la línea al usar el comando."
|
||||
},
|
||||
"errors": {
|
||||
"non_tech_tree": "# {tank} is not on the tech tree\n\nYou cannot research a premium/collector tank.",
|
||||
"tier_1": "# {tank} is a tier I\n\nTier I tanks are always unlocked for free for all players.",
|
||||
"already_researched": "# {tank} is already researched\n\nTry providing a `starting-tank` when using the command to view the totals for a line you have already researched.",
|
||||
"start_end_equal": "# {tank} was provided twice\n\nMake sure `starting-tank` and `target-tank` are different.",
|
||||
"tanks_not_on_line": "# {tank_1} and {tank_2} are not on the same line\n\nMake sure `starting-tank` and `target-tank` are on the same tech-tree line.",
|
||||
"unordered": "# {tank_1} higher tiered to {tank_2}\n\nMake sure to provide {tank_2} as the `starting-tank` instead as it is the lower tiered tank."
|
||||
}
|
||||
},
|
||||
"about": {
|
||||
"name": "acerca",
|
||||
"description": "Toda la información que necesitas sobre el bot",
|
||||
"subcommands": {
|
||||
"commands": {
|
||||
"name": "comandos",
|
||||
"description": "Lista de todos los comandos y sus descripciones",
|
||||
"body": "# Comandos\n\nBlitzKit ofrece los siguientes comandos:\n\n"
|
||||
},
|
||||
"embeds": {
|
||||
"name": "embeds",
|
||||
"description": "Cómo funcionan los embeds"
|
||||
},
|
||||
"introduction": {
|
||||
"name": "introducción",
|
||||
"description": "Sobre el bot"
|
||||
},
|
||||
"invite": {
|
||||
"name": "invitar",
|
||||
"description": "Cómo invitar al bot"
|
||||
},
|
||||
"timezones": {
|
||||
"name": "zonas horarias",
|
||||
"description": "Cómo Blitzkrieg infiere y utiliza tu zona horaria"
|
||||
},
|
||||
"credits": {
|
||||
"name": "créditos",
|
||||
"description": "Personas que han ayudado a BlitzKit"
|
||||
}
|
||||
}
|
||||
},
|
||||
"breakdown": {
|
||||
"name": "resumen",
|
||||
"description": "Resumen de un período por tanques jugados",
|
||||
"body": {
|
||||
"total": "Total",
|
||||
"battles": "Batallas",
|
||||
"wn8": "WN8",
|
||||
"winrate": "Tasa de victorias",
|
||||
"damage": "Daño",
|
||||
"unknown_tank": "Unknown tank {id}"
|
||||
}
|
||||
},
|
||||
"debug": {
|
||||
"name": "depurar",
|
||||
"description": "Muestra más información sobre el bot",
|
||||
"body": {
|
||||
"title": "# Depuración\n\n",
|
||||
"version": "Versión",
|
||||
"shard": {
|
||||
"label": "Fragmentar",
|
||||
"default": "predeterminado"
|
||||
},
|
||||
"uptime": "Tiempo en línea"
|
||||
}
|
||||
},
|
||||
"evolution": {
|
||||
"name": "evolución",
|
||||
"description": "Evolución de estadísticas",
|
||||
"groups": {
|
||||
"player": {
|
||||
"name": "jugador",
|
||||
"description": "Estadísticas del jugador"
|
||||
},
|
||||
"tank": {
|
||||
"name": "tanque",
|
||||
"description": "Estadísticas del tanque"
|
||||
}
|
||||
}
|
||||
},
|
||||
"inactive": {
|
||||
"name": "inactivo",
|
||||
"description": "Enumera a todos los jugadores inactivos en un clan por encima de un umbral",
|
||||
"options": {
|
||||
"threshold": {
|
||||
"name": "umbral",
|
||||
"description": "The number of days inactive (default: {days} days)"
|
||||
}
|
||||
},
|
||||
"body": {
|
||||
"subtitle": "Inactive for {days}+ days",
|
||||
"listing": "{days} days"
|
||||
}
|
||||
},
|
||||
"full_stats": {
|
||||
"name": "estadísticas completas",
|
||||
"description": "Estadísticas completas del juego",
|
||||
"body": {
|
||||
"cards": {
|
||||
"games": {
|
||||
"title": "Partidas",
|
||||
"winrate": "Tasa de victorias",
|
||||
"battles": "Batallas",
|
||||
"wins_losses": "Victorias / derrotas"
|
||||
},
|
||||
"efficiency": {
|
||||
"title": "Eficiencia",
|
||||
"wn8": "WN8",
|
||||
"survival": "Supervivencia",
|
||||
"accuracy": "Precisión"
|
||||
},
|
||||
"lethality": {
|
||||
"title": "Letalidad",
|
||||
"average_damage": "Daño promedio",
|
||||
"damage_per_tier": "Daño por nivel",
|
||||
"damage_ratio": "Relación de daño",
|
||||
"average_kills": "Promedio de bajas"
|
||||
},
|
||||
"miscellaneous": {
|
||||
"title": "Misceláneo",
|
||||
"average_tier": "Nivel promedio",
|
||||
"average_spots": "Promedio de detecciones",
|
||||
"average_xp": "Promedio de XP",
|
||||
"kills_to_death_ratio": "Relación bajas-muertes"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"link": {
|
||||
"name": "vincular",
|
||||
"description": "Vincula tu cuenta de Blitz y Discord",
|
||||
"body": {
|
||||
"accounts_linked": "Cuentas vinculadas",
|
||||
"no_role_permissions": {
|
||||
"title": "{name} failed to verify",
|
||||
"description": "No tengo permiso para administrar roles."
|
||||
}
|
||||
},
|
||||
"embed": {
|
||||
"title": "¿Cuenta incorrecta?",
|
||||
"description": "Usa el comando de nuevo y selecciona un usuario de los resultados de búsqueda."
|
||||
}
|
||||
},
|
||||
"search_clans": {
|
||||
"name": "buscar clanes",
|
||||
"description": "Buscar clanes",
|
||||
"options": {
|
||||
"limit": {
|
||||
"name": "límite",
|
||||
"description": "The max number of clan results (default: {limit})"
|
||||
}
|
||||
},
|
||||
"body": {
|
||||
"title": "Clan search for {search} in region {region}",
|
||||
"no_results": "No se encontraron clanes"
|
||||
}
|
||||
},
|
||||
"search_players": {
|
||||
"name": "buscar jugadores",
|
||||
"description": "Buscar jugadores",
|
||||
"options": {
|
||||
"limit": {
|
||||
"name": "límite",
|
||||
"description": "The max number of player results (default: {limit})"
|
||||
}
|
||||
},
|
||||
"body": {
|
||||
"title": "Player search for {search} in region {region}",
|
||||
"no_results": "No se encontraron jugadores"
|
||||
}
|
||||
},
|
||||
"rating_leaderboard": {
|
||||
"name": "tabla de clasificación",
|
||||
"description": "Estadísticas de batallas de clasificatoria",
|
||||
"subcommands": {
|
||||
"neighbors": {
|
||||
"name": "vecinos",
|
||||
"description": "Jugadores vecinos en la tabla de posiciones"
|
||||
},
|
||||
"league": {
|
||||
"name": "liga",
|
||||
"description": "Mejores jugadores de una liga"
|
||||
}
|
||||
},
|
||||
"options": {
|
||||
"limit": {
|
||||
"name": "limite",
|
||||
"description": "How many neighbors to display (default: {count})"
|
||||
},
|
||||
"season": {
|
||||
"name": "temporada",
|
||||
"description": "Número de temporada (predeterminado: actual)",
|
||||
"choices": {
|
||||
"current": "{season} (current)"
|
||||
}
|
||||
},
|
||||
"league": {
|
||||
"name": "liga",
|
||||
"description": "La liga a mostrar"
|
||||
}
|
||||
},
|
||||
"body": {
|
||||
"top_players": "Top {count} players",
|
||||
"no_participation": "# {player} didn't play rating in season {season}\n\nThis player did not participate in this season or did not get past calibration.",
|
||||
"no_ongoing_season": "# No hay temporada en curso\n\nActualmente no hay ninguna temporada de clasificatoria.",
|
||||
"deleted_player": "Deleted {id}",
|
||||
"neighbors": "Vecinos de clasificatoria",
|
||||
"more": "+ {count} more"
|
||||
}
|
||||
},
|
||||
"today": {
|
||||
"name": "hoy",
|
||||
"description": "Tanques jugados hoy y estadísticas"
|
||||
},
|
||||
"stats": {
|
||||
"name": "estadísticas",
|
||||
"description": "Estadísticas rápidas para un período"
|
||||
},
|
||||
"owned_tanks": {
|
||||
"name": "tanques en propiedad",
|
||||
"description": "Muestra todos los tanques propios en un nivel",
|
||||
"body": {
|
||||
"title": "# {name}'s owned tier {tier} tanks\n\n"
|
||||
}
|
||||
},
|
||||
"permissions": {
|
||||
"name": "permisos",
|
||||
"description": "Comprueba si el bot tiene los permisos requeridos para funcionar",
|
||||
"body": {
|
||||
"title": "# Permissions\n\n{body}",
|
||||
"view_channels": "Ver canales: necesario para encontrar el mensaje en el cual el botón \"actualizar\" fue usado",
|
||||
"read_message_history": "Leer historial de mensajes: necesario para encontrar el mensaje a actualizar",
|
||||
"attach_files": "Adjuntar archivos: necesario para añadir imágenes a los comandos basados en estas",
|
||||
"external_emojis": "Emoticonos externos: necesario para añadir emoticonos de banderas nacionales y clases de tanque"
|
||||
}
|
||||
},
|
||||
"ping": {
|
||||
"name": "ping",
|
||||
"description": "Comprueba si el bot está vivo.",
|
||||
"body": {
|
||||
"pong": "Pong 🏓",
|
||||
"pong_with_time": "Pong 🏓 - {time}ms"
|
||||
},
|
||||
"subcommands": {
|
||||
"blitzkit": {
|
||||
"name": "blitzkit",
|
||||
"description": "Hacerle un ping a BlitzKit"
|
||||
},
|
||||
"wotb": {
|
||||
"name": "wotb",
|
||||
"description": "Hacerle un ping a World of Tanks Blitz"
|
||||
}
|
||||
}
|
||||
},
|
||||
"player_info": {
|
||||
"name": "info del jugador",
|
||||
"description": "Información básica sobre un jugador",
|
||||
"body": {
|
||||
"title": "{name}'s information",
|
||||
"nickname": "Apodo",
|
||||
"battles": "Batallas",
|
||||
"winrate": "Tasa de victorias",
|
||||
"account_id": "ID de cuenta",
|
||||
"created": "Creado",
|
||||
"last_battle": "Última batalla"
|
||||
}
|
||||
},
|
||||
"rating": {
|
||||
"name": "clasificatoria",
|
||||
"description": "Estadísticas de clasificatoria del jugador",
|
||||
"subcommands": {
|
||||
"today": {
|
||||
"name": "hoy",
|
||||
"description": "Estadísticas de clasificatoria de hoy"
|
||||
},
|
||||
"season": {
|
||||
"name": "temporada",
|
||||
"description": "Estadísticas de clasificatoria de esta temporada"
|
||||
}
|
||||
},
|
||||
"body": {
|
||||
"subtitle": {
|
||||
"today": "Estadísticas de clasificatoria de hoy",
|
||||
"season": "Estadísticas de clasificatoria de esta temporada"
|
||||
}
|
||||
},
|
||||
"errors": {
|
||||
"no_participation": "# {name} hasn't played rating\n\nThis player hasn't participated in the rating gamemode this season.",
|
||||
"unrecorded_stats": "# Estadísticas no disponibles actualmente\n\nWargaming podría estar sufriendo una caída del servidor. Si hay alguna temporada en curso, las estadísticas deberían estar disponibles en 24 horas."
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"website": {
|
||||
"redirect": {
|
||||
"title": "301: moved permanently",
|
||||
@@ -734,14 +281,6 @@
|
||||
}
|
||||
},
|
||||
"home": {
|
||||
"pwa": {
|
||||
"title": "Install the BlitzKit App",
|
||||
"new": "NEW",
|
||||
"checking": "Checking compatibility...",
|
||||
"instructions": "Instructions for Apple devices.",
|
||||
"install": "Install",
|
||||
"dismiss": "Dismiss"
|
||||
},
|
||||
"discord": {
|
||||
"join_short": "Join cool people!",
|
||||
"join_long": "Join super duper cool people!",
|
||||
@@ -953,6 +492,7 @@
|
||||
"tier": "Nivel",
|
||||
"type": "Tipo",
|
||||
"dev_id": "DEV: ID",
|
||||
"dev_name": "DEV: NAME",
|
||||
"purchase": "Precio de compra",
|
||||
"restoration": "Precio de restauración",
|
||||
"sale": "Precio de venta",
|
||||
@@ -973,6 +513,11 @@
|
||||
},
|
||||
"configuration": {
|
||||
"title": "",
|
||||
"equalizer": {
|
||||
"title": "Equalizer",
|
||||
"equalize": "Equalize",
|
||||
"beta": "Beta"
|
||||
},
|
||||
"modules": {
|
||||
"title": "Módulos",
|
||||
"stock": "Base",
|
||||
@@ -1005,8 +550,8 @@
|
||||
"title": "Características",
|
||||
"compare": {
|
||||
"label": "Comparar con",
|
||||
"class": "Tier {tier} {class}",
|
||||
"tier": "All of tier {tier}",
|
||||
"class": "{tier} {class}",
|
||||
"tier": "All tier {tier}",
|
||||
"all": "Todos los tanques"
|
||||
},
|
||||
"values": {
|
||||
@@ -1142,7 +687,8 @@
|
||||
},
|
||||
"skills": {
|
||||
"clear": "Limpiar",
|
||||
"maximize": "Maximizar"
|
||||
"maximize": "Maximizar",
|
||||
"equalize": "Equalize"
|
||||
},
|
||||
"modules": {
|
||||
"stock": "Base",
|
||||
|
||||
+15
-469
@@ -37,10 +37,11 @@
|
||||
"d_1": "Hier"
|
||||
},
|
||||
"branches": {
|
||||
"local": "dev",
|
||||
"dev": "beta",
|
||||
"opentest": "test ouvert",
|
||||
"preview": "aperçu"
|
||||
"beta": "Beta",
|
||||
"development": "Development",
|
||||
"opentest": "OpenTest",
|
||||
"preview": "Preview",
|
||||
"production": "Production"
|
||||
},
|
||||
"locales": {
|
||||
"en": "Anglais",
|
||||
@@ -184,460 +185,6 @@
|
||||
"cumulative_battle_life_time": "Total de temps de bataille"
|
||||
}
|
||||
},
|
||||
"bot": {
|
||||
"common": {
|
||||
"errors": {
|
||||
"clan_not_found": "# Impossible de trouver le clan\nImpossible de trouver «{search} ». Essayez de sélectionner un clan dans le résultat de la recherche.",
|
||||
"player_not_found": "# Impossible de trouver l'utilisateur\nJe n'ai pas pu trouver l'utilisateur \"{search}\". Essayez de choisir un utilisateur dans le résultat de la recherche, en tapant un nom d'utilisateur valide, ou en utilisant la commande `/link`.",
|
||||
"player_not_linked": "# Utilisez `/link` pour commencer\nJe ne sais pas qui vous êtes, mais vous pouvez me le dire aujourd'hui !",
|
||||
"tank_name_not_found": "# Char introuvable\nImpossible de trouver le char sous le nom \"{search}\".",
|
||||
"tank_id_not_found": "# Char introuvable\nImpossible de trouver le char avec l'ID \"{search}\". Essayez de taper le nom du char au lieu d'un nombre.",
|
||||
"no_tank_stats": "# Aucune statistique de tank disponible\nCe joueur n'a pas de statistiques disponibles. Ce n'est peut-être pas le joueur que vous cherchez.",
|
||||
"get_help": "Aidez le serveur Discord",
|
||||
"uncaught_error": "# Blitzkit a rencontré une erreur !\nNous sommes désolés de cela. N'hésitez pas à [rejoindre le serveur officiel Discord](https://discord.gg/nDt7AjGJQH) pour obtenir de l'aide.",
|
||||
"preview": "# Cette commande est en aperçu\n\nVous ne pouvez accéder à cette commande que dans [le serveur officiel Discord](https://discord.gg/nDt7AjGJQH). La commande sera généralement disponible sous peu.",
|
||||
"query_too_small": "# Votre recherche est trop courte\nVotre recherche doit comporter au moins 3 caractères.",
|
||||
"query_too_long": "# Votre recherche est trop longue\nVotre recherche doit comporter au maximum 100 caractères."
|
||||
},
|
||||
"wn8": {
|
||||
"name": "WN8",
|
||||
"types": {
|
||||
"very_bad": "Très nul",
|
||||
"bad": "Nul",
|
||||
"below_average": "En-dessous de la moyenne",
|
||||
"average": "Moyenne",
|
||||
"above_average": "Au-dessus de la moyenne",
|
||||
"good": "Bien",
|
||||
"very_good": "Très bien",
|
||||
"great": "Super",
|
||||
"unicum": "Unique",
|
||||
"super_unicum": "Super unique"
|
||||
}
|
||||
},
|
||||
"subcommands": {
|
||||
"today": {
|
||||
"name": "aujourd'hui",
|
||||
"description": "Aujourd'hui"
|
||||
},
|
||||
"30": {
|
||||
"name": "30",
|
||||
"description": "30 jours"
|
||||
},
|
||||
"60": {
|
||||
"name": "60",
|
||||
"description": "60 jours"
|
||||
},
|
||||
"90": {
|
||||
"name": "90",
|
||||
"description": "90 jours"
|
||||
},
|
||||
"career": {
|
||||
"name": "carrière",
|
||||
"description": "Carrière"
|
||||
},
|
||||
"custom": {
|
||||
"name": "personnaliser",
|
||||
"description": "Période spécifique",
|
||||
"options": {
|
||||
"start": {
|
||||
"name": "début",
|
||||
"description": "Commencer il y a un nombre de jours à partir d'aujourd'hui"
|
||||
},
|
||||
"end": {
|
||||
"name": "fin",
|
||||
"description": "Fin en nombre de jours à partir d'aujourd'hui"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"options": {
|
||||
"clan": {
|
||||
"name": "clan",
|
||||
"description": "Le nom ou le tag du clan"
|
||||
},
|
||||
"tank": {
|
||||
"name": "char",
|
||||
"description": "Le char pour obtenir des statistiques pour"
|
||||
},
|
||||
"username": {
|
||||
"name": "nom d'utilisateur",
|
||||
"description": "Le nom d'utilisateur Blitz du joueur"
|
||||
},
|
||||
"filters": {
|
||||
"nation": {
|
||||
"name": "pays",
|
||||
"description": "Pays"
|
||||
},
|
||||
"class": {
|
||||
"name": "classe",
|
||||
"description": "Classe"
|
||||
},
|
||||
"type": {
|
||||
"name": "type",
|
||||
"description": "Type"
|
||||
}
|
||||
},
|
||||
"region": {
|
||||
"name": "région",
|
||||
"description": "Région"
|
||||
},
|
||||
"tier": {
|
||||
"name": "rang",
|
||||
"description": "Rang",
|
||||
"choices": {
|
||||
"tier": "Rang {tier_}1 - {tier_}2"
|
||||
}
|
||||
}
|
||||
},
|
||||
"periods": {
|
||||
"career": "Carrière",
|
||||
"today": "Aujourd'hui",
|
||||
"days": "{days} jours",
|
||||
"custom": "{day_1} - {day_2} jours"
|
||||
},
|
||||
"filters": {
|
||||
"none": "Aucun filtre",
|
||||
"tier": "Rang {tier}"
|
||||
},
|
||||
"no_data": {
|
||||
"battles_in_period": "",
|
||||
"battles_in_season": "Aucune bataille jouée dans cette saison",
|
||||
"players_in_period": "Aucun joueur pendant cette période",
|
||||
"tanks_found": "Aucun char de trouver"
|
||||
},
|
||||
"buttons": {
|
||||
"refresh": "Actualiser"
|
||||
},
|
||||
"hero_stats": {
|
||||
"battles": "Batailles",
|
||||
"winrate": "Taux de victoires",
|
||||
"damage": "Dégâts",
|
||||
"damage_ratio": "Rapport de dégâts",
|
||||
"tier": "Rang",
|
||||
"survival": "Survie",
|
||||
"accuracy": "Précision",
|
||||
"kills": "Tués"
|
||||
}
|
||||
},
|
||||
"commands": {
|
||||
"replay": {
|
||||
"name": "rejouer",
|
||||
"description": "Afficher les résultats de la relecture"
|
||||
},
|
||||
"research": {
|
||||
"name": "recherche",
|
||||
"description": "Liste des dépenses liées à la recherche d'une ligne",
|
||||
"options": {
|
||||
"target_tank": {
|
||||
"name": "char cible",
|
||||
"description": "Le dernier char à rechercher dans la ligne"
|
||||
},
|
||||
"starting_tank": {
|
||||
"name": "Char de départ",
|
||||
"description": ""
|
||||
}
|
||||
},
|
||||
"body": {
|
||||
"subtitle": "Recherche",
|
||||
"total": "Total",
|
||||
"research": "Recherche : {cost}",
|
||||
"upgrades": "Améliorations : {cost}",
|
||||
"purchase": "Achat : {cost}",
|
||||
"equipment": "Équipement : {cost}",
|
||||
"estimation": "# Ceci est une estimation !\n\nCette liste peut inclure des chars déjà recherchés en raison de l'information inexacte fournie par Wargaming. Essayez de fournir un `char de départ` depuis la ligne lorsque vous utilisez la commande si vous le pouvez."
|
||||
},
|
||||
"errors": {
|
||||
"non_tech_tree": "# {tank} n'est pas dans l'arbre technologique\n\nVous ne pouvez pas rechercher un char premium/de collection.",
|
||||
"tier_1": "# {tank} est un char de rang I\n\nLe char de rang 1 sont déverrouillé gratuitement pour tous les joueurs.",
|
||||
"already_researched": "# {tank} est déjà recherché\n\nEssayez de fournir un `char de départ` en utilisant la commande pour voir la progression d'une lignée.",
|
||||
"start_end_equal": "# {tank} a été fourni deux fois\n\nAssurez-vous que `starting-tank` et `target-tank` sont différents.",
|
||||
"tanks_not_on_line": "{tank_}1 et {tank_}2 ne sont pas sur la même ligne \n\nAssurez-vous que `starting-tank` et `target-tank` sont sur la même ligne d'arbre technologique.",
|
||||
"unordered": "# {tank_1} niveau supérieur à {tank_2}\n\nAssurez-vous de fournir {tank_2} comme le `starting-tank` à la place car c'est le char de niveau inférieur."
|
||||
}
|
||||
},
|
||||
"about": {
|
||||
"name": "à propos",
|
||||
"description": "Toutes les informations dont vous avez besoin sur le bot",
|
||||
"subcommands": {
|
||||
"commands": {
|
||||
"name": "commandes",
|
||||
"description": "Liste de toutes les commandes et leurs descriptions",
|
||||
"body": "# Commandes\n\nBlitzKit offre les commandes suivantes :\n\n"
|
||||
},
|
||||
"embeds": {
|
||||
"name": "intègre",
|
||||
"description": "Comment fonctionnent les intégrations"
|
||||
},
|
||||
"introduction": {
|
||||
"name": "introduction",
|
||||
"description": "À propos du bot"
|
||||
},
|
||||
"invite": {
|
||||
"name": "inviter",
|
||||
"description": "Comment inviter le bot"
|
||||
},
|
||||
"timezones": {
|
||||
"name": "fuseau horaire",
|
||||
"description": "Comment BlitzKit déduit et utilise votre fuseau horaire"
|
||||
},
|
||||
"credits": {
|
||||
"name": "crédits",
|
||||
"description": "Personnes qui ont aidé BlitzKit"
|
||||
}
|
||||
}
|
||||
},
|
||||
"breakdown": {
|
||||
"name": "décomposition",
|
||||
"description": "Répartition d'une période par chars joués",
|
||||
"body": {
|
||||
"total": "Total",
|
||||
"battles": "Batailles",
|
||||
"wn8": "WN8",
|
||||
"winrate": "Taux de victoires",
|
||||
"damage": "Dégâts",
|
||||
"unknown_tank": "Char {id} inconnu"
|
||||
}
|
||||
},
|
||||
"debug": {
|
||||
"name": "déboguer",
|
||||
"description": "Déboguer les informations sur le bot",
|
||||
"body": {
|
||||
"title": "# Debog\n\n",
|
||||
"version": "Version",
|
||||
"shard": {
|
||||
"label": "Fragment",
|
||||
"default": "par défaut"
|
||||
},
|
||||
"uptime": "Temps de fonctionnement"
|
||||
}
|
||||
},
|
||||
"evolution": {
|
||||
"name": "évolution",
|
||||
"description": "Évolution des statistiques",
|
||||
"groups": {
|
||||
"player": {
|
||||
"name": "joueur",
|
||||
"description": "Statistiques du joueur"
|
||||
},
|
||||
"tank": {
|
||||
"name": "char",
|
||||
"description": "Statistiques du char"
|
||||
}
|
||||
}
|
||||
},
|
||||
"inactive": {
|
||||
"name": "inactif",
|
||||
"description": "Liste tous les joueurs inactifs dans un clan au-dessus d'un seuil",
|
||||
"options": {
|
||||
"threshold": {
|
||||
"name": "seuil",
|
||||
"description": "Le nombre de jours inactifs (par défaut: {days} jours)"
|
||||
}
|
||||
},
|
||||
"body": {
|
||||
"subtitle": "Inactif depuis plus de {days} jours",
|
||||
"listing": "{days} jours"
|
||||
}
|
||||
},
|
||||
"full_stats": {
|
||||
"name": "statistiques complètes",
|
||||
"description": "Statistiques complètes en jeu",
|
||||
"body": {
|
||||
"cards": {
|
||||
"games": {
|
||||
"title": "Parties",
|
||||
"winrate": "Taux de victoires",
|
||||
"battles": "Batailles",
|
||||
"wins_losses": "Victoires/Défaites"
|
||||
},
|
||||
"efficiency": {
|
||||
"title": "Efficacité",
|
||||
"wn8": "WN8",
|
||||
"survival": "Survie",
|
||||
"accuracy": "Précision"
|
||||
},
|
||||
"lethality": {
|
||||
"title": "Létalité",
|
||||
"average_damage": "Dégâts moyens",
|
||||
"damage_per_tier": "Dégâts par tier",
|
||||
"damage_ratio": "Rapport de dégâts",
|
||||
"average_kills": "Destruction moyenne"
|
||||
},
|
||||
"miscellaneous": {
|
||||
"title": "Divers",
|
||||
"average_tier": "Tier moyen",
|
||||
"average_spots": "Repérage moyen",
|
||||
"average_xp": "Exp. Moyenne par bataille",
|
||||
"kills_to_death_ratio": "Rapport tués/morts"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"link": {
|
||||
"name": "lien",
|
||||
"description": "Lier votre compte Blitz et Discord",
|
||||
"body": {
|
||||
"accounts_linked": "Comptes liés",
|
||||
"no_role_permissions": {
|
||||
"title": "La vérification de {name} a échouée",
|
||||
"description": "Je n'ai pas l'autorisation de gérer les rôles."
|
||||
}
|
||||
},
|
||||
"embed": {
|
||||
"title": "Compte invalide ?",
|
||||
"description": "Utilisez à nouveau la commande et sélectionnez un nom d'utilisateur à partir des résultats de recherche."
|
||||
}
|
||||
},
|
||||
"search_clans": {
|
||||
"name": "clans de recherche",
|
||||
"description": "Rechercher des clans",
|
||||
"options": {
|
||||
"limit": {
|
||||
"name": "limite",
|
||||
"description": "Nombre maximum de résultats du clan (par défaut: {limit})"
|
||||
}
|
||||
},
|
||||
"body": {
|
||||
"title": "Recherche de clan {search} dans la région {region}",
|
||||
"no_results": "Pas de clan trouvé"
|
||||
}
|
||||
},
|
||||
"search_players": {
|
||||
"name": "recherche de joueur",
|
||||
"description": "Recherche des joueurs",
|
||||
"options": {
|
||||
"limit": {
|
||||
"name": "limite",
|
||||
"description": "Le nombre maximum de résultats de joueur (par défaut: {limit})"
|
||||
}
|
||||
},
|
||||
"body": {
|
||||
"title": "Recherche de {search} dans la région {region}",
|
||||
"no_results": "Pas de joueur de trouvé"
|
||||
}
|
||||
},
|
||||
"rating_leaderboard": {
|
||||
"name": "Classement de côté",
|
||||
"description": "Statistiques des batailles de cotés",
|
||||
"subcommands": {
|
||||
"neighbors": {
|
||||
"name": "voisins",
|
||||
"description": "Joueurs voisins dans le classement"
|
||||
},
|
||||
"league": {
|
||||
"name": "ligue",
|
||||
"description": "Meilleurs joueurs d'une ligue"
|
||||
}
|
||||
},
|
||||
"options": {
|
||||
"limit": {
|
||||
"name": "limite",
|
||||
"description": "Combien de voisins afficher (par défaut : {count})"
|
||||
},
|
||||
"season": {
|
||||
"name": "saison",
|
||||
"description": "Numéro de saison (défaut : courant)",
|
||||
"choices": {
|
||||
"current": "{season} (actuel)"
|
||||
}
|
||||
},
|
||||
"league": {
|
||||
"name": "ligue",
|
||||
"description": "La ligue à afficher"
|
||||
}
|
||||
},
|
||||
"body": {
|
||||
"top_players": "Top {count} joueurs",
|
||||
"no_participation": "# {player} n'a pas joué de cotées dans la saison {season}\n\nCe joueur n'a pas participé à cette saison ou n'a pas dépassé l'étalonnage.",
|
||||
"no_ongoing_season": "Pas de saison en cours\n\nIl n'y a pas de saison de notation en cours actuellement.",
|
||||
"deleted_player": "{id} supprimé",
|
||||
"neighbors": "évaluer les voisins",
|
||||
"more": "+ {count} plus"
|
||||
}
|
||||
},
|
||||
"today": {
|
||||
"name": "aujourd'hui",
|
||||
"description": "Les chars et les statistiques joués aujourd'hui"
|
||||
},
|
||||
"stats": {
|
||||
"name": "statistiques",
|
||||
"description": "Statistiques rapides pour une période"
|
||||
},
|
||||
"owned_tanks": {
|
||||
"name": "chars possédés",
|
||||
"description": "Affiche tous les chars d'un niveau",
|
||||
"body": {
|
||||
"title": "# Les chars du palier {tier} possédés par {name}"
|
||||
}
|
||||
},
|
||||
"permissions": {
|
||||
"name": "permissions",
|
||||
"description": "Vérifie si le bot a les permissions nécessaires pour fonctionner",
|
||||
"body": {
|
||||
"title": "# Permissions\n\n{body}",
|
||||
"view_channels": "Afficher les canaux : nécessaire pour trouver le message sur lequel le bouton d'actualisation a été utilisé",
|
||||
"read_message_history": "Lire l'historique des messages : nécessaire pour trouver le message à rafraîchir",
|
||||
"attach_files": "Joindre des fichiers : nécessaire pour ajouter des images à des commandes basées sur l'image",
|
||||
"external_emojis": "Émoticônes externes: nécessaire pour ajouter des drapeaux nationaux et des émojis de classe de char"
|
||||
}
|
||||
},
|
||||
"ping": {
|
||||
"name": "ping",
|
||||
"description": "Vérifiez si le bot est en vie.",
|
||||
"body": {
|
||||
"pong": "Pong 🏓",
|
||||
"pong_with_time": "Pong 🏓 - {time}ms"
|
||||
},
|
||||
"subcommands": {
|
||||
"blitzkit": {
|
||||
"name": "blitzkit",
|
||||
"description": "Ping blitzkit"
|
||||
},
|
||||
"wotb": {
|
||||
"name": "wotb",
|
||||
"description": "Ping World of Tanks Blitz"
|
||||
}
|
||||
}
|
||||
},
|
||||
"player_info": {
|
||||
"name": "info-joueur",
|
||||
"description": "Informations de base sur un joueur",
|
||||
"body": {
|
||||
"title": "Informations de {name}",
|
||||
"nickname": "Pseudo",
|
||||
"battles": "Batailles",
|
||||
"winrate": "Taux de victoires",
|
||||
"account_id": "Account ID",
|
||||
"created": "Créé",
|
||||
"last_battle": "Dernière bataille"
|
||||
}
|
||||
},
|
||||
"rating": {
|
||||
"name": "côtée",
|
||||
"description": "Statistiques des batailles cotées du joueur",
|
||||
"subcommands": {
|
||||
"today": {
|
||||
"name": "aujourd'hui",
|
||||
"description": "Statistiques des batailles cotées d'aujourd'hui"
|
||||
},
|
||||
"season": {
|
||||
"name": "saison",
|
||||
"description": "Statistiques des batailles cotées de cette saison"
|
||||
}
|
||||
},
|
||||
"body": {
|
||||
"subtitle": {
|
||||
"today": "Statistiques de batailles cotées d'aujourd'hui",
|
||||
"season": "Statistiques de batailles cotées cette saison"
|
||||
}
|
||||
},
|
||||
"errors": {
|
||||
"no_participation": "# {name} n’a pas joué en cotée\n\nCe joueur n’a pas participé au mode cotée cette saison.",
|
||||
"unrecorded_stats": "# Statistiques actuellement indisponibles\n\nWargaming rencontre peut-être une interruption de service.\nSi une saison est en cours, les statistiques devraient être disponibles sous 24 heures."
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"website": {
|
||||
"redirect": {
|
||||
"title": "301 : déplacé définitivement",
|
||||
@@ -734,14 +281,6 @@
|
||||
}
|
||||
},
|
||||
"home": {
|
||||
"pwa": {
|
||||
"title": "Install the BlitzKit App",
|
||||
"new": "NEW",
|
||||
"checking": "Checking compatibility...",
|
||||
"instructions": "Instructions for Apple devices.",
|
||||
"install": "Install",
|
||||
"dismiss": "Dismiss"
|
||||
},
|
||||
"discord": {
|
||||
"join_short": "Join cool people!",
|
||||
"join_long": "Join super duper cool people!",
|
||||
@@ -953,6 +492,7 @@
|
||||
"tier": "Rang",
|
||||
"type": "Type",
|
||||
"dev_id": "DEV: ID",
|
||||
"dev_name": "DEV: NAME",
|
||||
"purchase": "Purchase price",
|
||||
"restoration": "Restoration price",
|
||||
"sale": "Sale price",
|
||||
@@ -973,6 +513,11 @@
|
||||
},
|
||||
"configuration": {
|
||||
"title": "Configuration",
|
||||
"equalizer": {
|
||||
"title": "Equalizer",
|
||||
"equalize": "Equalize",
|
||||
"beta": "Beta"
|
||||
},
|
||||
"modules": {
|
||||
"title": "Modules",
|
||||
"stock": "Stock",
|
||||
@@ -1005,8 +550,8 @@
|
||||
"title": "Characteristics",
|
||||
"compare": {
|
||||
"label": "Compare against",
|
||||
"class": "Tier {tier} {class}",
|
||||
"tier": "All of tier {tier}",
|
||||
"class": "{tier} {class}",
|
||||
"tier": "All tier {tier}",
|
||||
"all": "All tanks"
|
||||
},
|
||||
"values": {
|
||||
@@ -1142,7 +687,8 @@
|
||||
},
|
||||
"skills": {
|
||||
"clear": "Clear",
|
||||
"maximize": "Maximize"
|
||||
"maximize": "Maximize",
|
||||
"equalize": "Equalize"
|
||||
},
|
||||
"modules": {
|
||||
"stock": "Stock",
|
||||
|
||||
+15
-469
@@ -37,10 +37,11 @@
|
||||
"d_1": "昨日"
|
||||
},
|
||||
"branches": {
|
||||
"local": "開発",
|
||||
"dev": "ベータ版",
|
||||
"opentest": "オープンテスト",
|
||||
"preview": "プレビュー"
|
||||
"beta": "Beta",
|
||||
"development": "Development",
|
||||
"opentest": "OpenTest",
|
||||
"preview": "Preview",
|
||||
"production": "Production"
|
||||
},
|
||||
"locales": {
|
||||
"en": "英語",
|
||||
@@ -184,460 +185,6 @@
|
||||
"cumulative_battle_life_time": "総戦闘時間"
|
||||
}
|
||||
},
|
||||
"bot": {
|
||||
"common": {
|
||||
"errors": {
|
||||
"clan_not_found": "",
|
||||
"player_not_found": "# ユーザーが見つかりませんでした\nユーザー「{search}」が見つかりませんでした。検索結果からユーザーを選択するか、有効なユーザー名を入力するか、/link コマンドを使用してください。",
|
||||
"player_not_linked": "# `/link`を使用して始めましょう\nはじめまして!あなたが誰か、私に教えてください。",
|
||||
"tank_name_not_found": "# Tank not found\nCould not find tank by the name \"{search}\".",
|
||||
"tank_id_not_found": "# 車両が見つかりません\nID「{search}」の戦車が見つかりませんでした。数字ではなく戦車の名前を入力してみてください。",
|
||||
"no_tank_stats": "# 利用可能な車輌統計がありません\nこのプレイヤーには利用可能な統計がありません。あなたが探しているプレイヤーではない可能性があります。",
|
||||
"get_help": "Discordサーバーに参加する",
|
||||
"uncaught_error": "# BlitzKitがエラーに遭遇しました!\n申し訳ありません。お気軽に[公式Discordサーバー](https://discord.gg/nDt7AjGJQH)にお問い合わせください。",
|
||||
"preview": "このコマンドは現在[公式Discardサーバー](https://discord.gg/nDt7AjGJQH)でのみ利用可能です。間もなく全体で利用可能になります。",
|
||||
"query_too_small": "# 単語が短すぎます\n検索には少なくとも3文字が含まれている必要があります。",
|
||||
"query_too_long": "# 単語が長すぎます\n検索は最大で100文字までです。"
|
||||
},
|
||||
"wn8": {
|
||||
"name": "WN8",
|
||||
"types": {
|
||||
"very_bad": "Very bad",
|
||||
"bad": "Bad",
|
||||
"below_average": "Below average",
|
||||
"average": "Average",
|
||||
"above_average": "Above average",
|
||||
"good": "Good",
|
||||
"very_good": "Very good",
|
||||
"great": "Great",
|
||||
"unicum": "Unicum",
|
||||
"super_unicum": "Super unicum"
|
||||
}
|
||||
},
|
||||
"subcommands": {
|
||||
"today": {
|
||||
"name": "today",
|
||||
"description": "Today"
|
||||
},
|
||||
"30": {
|
||||
"name": "30",
|
||||
"description": "30日"
|
||||
},
|
||||
"60": {
|
||||
"name": "60",
|
||||
"description": "60日"
|
||||
},
|
||||
"90": {
|
||||
"name": "90",
|
||||
"description": "90日"
|
||||
},
|
||||
"career": {
|
||||
"name": "総合戦績",
|
||||
"description": "Career"
|
||||
},
|
||||
"custom": {
|
||||
"name": "カスタム",
|
||||
"description": "Custom range",
|
||||
"options": {
|
||||
"start": {
|
||||
"name": "開始",
|
||||
"description": "Start in number of days ago from today"
|
||||
},
|
||||
"end": {
|
||||
"name": "end",
|
||||
"description": "End in number of days ago from today"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"options": {
|
||||
"clan": {
|
||||
"name": "クラン",
|
||||
"description": "クラン名もしくはタグ"
|
||||
},
|
||||
"tank": {
|
||||
"name": "車輌",
|
||||
"description": "統計を得る車輌"
|
||||
},
|
||||
"username": {
|
||||
"name": "ユーザー名",
|
||||
"description": "プレイヤーのBlitzユーザー名"
|
||||
},
|
||||
"filters": {
|
||||
"nation": {
|
||||
"name": "国家",
|
||||
"description": "国家"
|
||||
},
|
||||
"class": {
|
||||
"name": "",
|
||||
"description": "Class"
|
||||
},
|
||||
"type": {
|
||||
"name": "type",
|
||||
"description": "Type"
|
||||
}
|
||||
},
|
||||
"region": {
|
||||
"name": "地域",
|
||||
"description": "地域"
|
||||
},
|
||||
"tier": {
|
||||
"name": "tier",
|
||||
"description": "Tier",
|
||||
"choices": {
|
||||
"tier": "Tier {tier_1} - {tier_2}"
|
||||
}
|
||||
}
|
||||
},
|
||||
"periods": {
|
||||
"career": "Career",
|
||||
"today": "Today",
|
||||
"days": "{days} days",
|
||||
"custom": "{day_1} - {day_2} days"
|
||||
},
|
||||
"filters": {
|
||||
"none": "フィルターなし",
|
||||
"tier": "Tier {tier}"
|
||||
},
|
||||
"no_data": {
|
||||
"battles_in_period": "No battles played in this period",
|
||||
"battles_in_season": "No battles played in this season",
|
||||
"players_in_period": "No players in this period",
|
||||
"tanks_found": "No tanks found"
|
||||
},
|
||||
"buttons": {
|
||||
"refresh": "Refresh"
|
||||
},
|
||||
"hero_stats": {
|
||||
"battles": "戦闘数",
|
||||
"winrate": "勝率",
|
||||
"damage": "ダメージ",
|
||||
"damage_ratio": "ダメージ率",
|
||||
"tier": "Tier",
|
||||
"survival": "生存",
|
||||
"accuracy": "命中率",
|
||||
"kills": "撃破"
|
||||
}
|
||||
},
|
||||
"commands": {
|
||||
"replay": {
|
||||
"name": "replay",
|
||||
"description": "Display replay results"
|
||||
},
|
||||
"research": {
|
||||
"name": "研究",
|
||||
"description": "Lists the expenses in researching a line",
|
||||
"options": {
|
||||
"target_tank": {
|
||||
"name": "target-tank",
|
||||
"description": "The final tank to research in the line"
|
||||
},
|
||||
"starting_tank": {
|
||||
"name": "starting-tank",
|
||||
"description": "The starting tank in the line (inferred automatically if not provided)"
|
||||
}
|
||||
},
|
||||
"body": {
|
||||
"subtitle": "Research",
|
||||
"total": "トータル",
|
||||
"research": "Research: {cost}",
|
||||
"upgrades": "Upgrades: {cost}",
|
||||
"purchase": "Purchase: {cost}",
|
||||
"equipment": "Equipment: {cost}",
|
||||
"estimation": "# This is an estimation!\n\nThis list may include already researched tanks because of the inaccurate information Wargaming provides. Try providing a `starting-tank` from the line when using the command if you can."
|
||||
},
|
||||
"errors": {
|
||||
"non_tech_tree": "# {tank} is not on the tech tree\n\nYou cannot research a premium/collector tank.",
|
||||
"tier_1": "# {tank} is a tier I\n\nTier I tanks are always unlocked for free for all players.",
|
||||
"already_researched": "# {tank} is already researched\n\nTry providing a `starting-tank` when using the command to view the totals for a line you have already researched.",
|
||||
"start_end_equal": "# {tank} was provided twice\n\nMake sure `starting-tank` and `target-tank` are different.",
|
||||
"tanks_not_on_line": "# {tank_1} and {tank_2} are not on the same line\n\nMake sure `starting-tank` and `target-tank` are on the same tech-tree line.",
|
||||
"unordered": "# {tank_1} higher tiered to {tank_2}\n\nMake sure to provide {tank_2} as the `starting-tank` instead as it is the lower tiered tank."
|
||||
}
|
||||
},
|
||||
"about": {
|
||||
"name": "about",
|
||||
"description": "botについての情報の全て",
|
||||
"subcommands": {
|
||||
"commands": {
|
||||
"name": "コマンド",
|
||||
"description": "全コマンドのリストと説明",
|
||||
"body": "# コマンド\nBlitzKitは以下のコマンドを提供します:"
|
||||
},
|
||||
"embeds": {
|
||||
"name": "埋め込み",
|
||||
"description": "埋め込みがどう機能するか"
|
||||
},
|
||||
"introduction": {
|
||||
"name": "introduction",
|
||||
"description": "botについて"
|
||||
},
|
||||
"invite": {
|
||||
"name": "招待",
|
||||
"description": "botを招待する方法"
|
||||
},
|
||||
"timezones": {
|
||||
"name": "タイムゾーン",
|
||||
"description": "How BlitzKit infers and uses your timezone"
|
||||
},
|
||||
"credits": {
|
||||
"name": "クレジット",
|
||||
"description": "BlitzKitを支援した人々"
|
||||
}
|
||||
}
|
||||
},
|
||||
"breakdown": {
|
||||
"name": "breakdown",
|
||||
"description": "A period's breakdown by tanks played",
|
||||
"body": {
|
||||
"total": "トータル",
|
||||
"battles": "戦闘数",
|
||||
"wn8": "WN8",
|
||||
"winrate": "勝率",
|
||||
"damage": "ダメージ",
|
||||
"unknown_tank": "不明な車両{id}"
|
||||
}
|
||||
},
|
||||
"debug": {
|
||||
"name": "debug",
|
||||
"description": "Debug information about the bot",
|
||||
"body": {
|
||||
"title": "# Debug\n\n",
|
||||
"version": "Version",
|
||||
"shard": {
|
||||
"label": "Shard",
|
||||
"default": "default"
|
||||
},
|
||||
"uptime": "Uptime"
|
||||
}
|
||||
},
|
||||
"evolution": {
|
||||
"name": "evolution",
|
||||
"description": "Evolution of statistics",
|
||||
"groups": {
|
||||
"player": {
|
||||
"name": "player",
|
||||
"description": "Player statistics"
|
||||
},
|
||||
"tank": {
|
||||
"name": "車輌",
|
||||
"description": "Tank statistics"
|
||||
}
|
||||
}
|
||||
},
|
||||
"inactive": {
|
||||
"name": "inactive",
|
||||
"description": "Lists all inactive players in a clan above a threshold",
|
||||
"options": {
|
||||
"threshold": {
|
||||
"name": "threshold",
|
||||
"description": "The number of days inactive (default: {days} days)"
|
||||
}
|
||||
},
|
||||
"body": {
|
||||
"subtitle": "Inactive for {days}+ days",
|
||||
"listing": "{days} days"
|
||||
}
|
||||
},
|
||||
"full_stats": {
|
||||
"name": "full-stats",
|
||||
"description": "Full in-game statistics",
|
||||
"body": {
|
||||
"cards": {
|
||||
"games": {
|
||||
"title": "Games",
|
||||
"winrate": "勝率",
|
||||
"battles": "戦闘数",
|
||||
"wins_losses": "Wins / losses"
|
||||
},
|
||||
"efficiency": {
|
||||
"title": "Efficiency",
|
||||
"wn8": "WN8",
|
||||
"survival": "生存",
|
||||
"accuracy": "精度"
|
||||
},
|
||||
"lethality": {
|
||||
"title": "Lethality",
|
||||
"average_damage": "Average damage",
|
||||
"damage_per_tier": "Damage per tier",
|
||||
"damage_ratio": "ダメージ比",
|
||||
"average_kills": "Average kills"
|
||||
},
|
||||
"miscellaneous": {
|
||||
"title": "Miscellaneous",
|
||||
"average_tier": "Average tier",
|
||||
"average_spots": "Average spots",
|
||||
"average_xp": "Average XP",
|
||||
"kills_to_death_ratio": "撃破/被撃破比"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"link": {
|
||||
"name": "link",
|
||||
"description": "Links your Blitz and Discord account",
|
||||
"body": {
|
||||
"accounts_linked": "Accounts linked",
|
||||
"no_role_permissions": {
|
||||
"title": "{name} failed to verify",
|
||||
"description": "I don't have the permission to manage roles."
|
||||
}
|
||||
},
|
||||
"embed": {
|
||||
"title": "Incorrect account?",
|
||||
"description": "Use the command again and select a username from the search results."
|
||||
}
|
||||
},
|
||||
"search_clans": {
|
||||
"name": "search-clans",
|
||||
"description": "Search clans",
|
||||
"options": {
|
||||
"limit": {
|
||||
"name": "limit",
|
||||
"description": "The max number of clan results (default: {limit})"
|
||||
}
|
||||
},
|
||||
"body": {
|
||||
"title": "Clan search for {search} in region {region}",
|
||||
"no_results": "No clans found"
|
||||
}
|
||||
},
|
||||
"search_players": {
|
||||
"name": "search-players",
|
||||
"description": "Search players",
|
||||
"options": {
|
||||
"limit": {
|
||||
"name": "limit",
|
||||
"description": "The max number of player results (default: {limit})"
|
||||
}
|
||||
},
|
||||
"body": {
|
||||
"title": "Player search for {search} in region {region}",
|
||||
"no_results": "No players found"
|
||||
}
|
||||
},
|
||||
"rating_leaderboard": {
|
||||
"name": "rating-leaderboard",
|
||||
"description": "Rating battles statistics",
|
||||
"subcommands": {
|
||||
"neighbors": {
|
||||
"name": "neighbors",
|
||||
"description": "Neighboring players on the leaderboard"
|
||||
},
|
||||
"league": {
|
||||
"name": "league",
|
||||
"description": "Top players of a league"
|
||||
}
|
||||
},
|
||||
"options": {
|
||||
"limit": {
|
||||
"name": "limit",
|
||||
"description": "How many neighbors to display (default: {count})"
|
||||
},
|
||||
"season": {
|
||||
"name": "season",
|
||||
"description": "Season number (default: current)",
|
||||
"choices": {
|
||||
"current": "{season} (current)"
|
||||
}
|
||||
},
|
||||
"league": {
|
||||
"name": "league",
|
||||
"description": "The league to display"
|
||||
}
|
||||
},
|
||||
"body": {
|
||||
"top_players": "Top {count} players",
|
||||
"no_participation": "# {player} didn't play rating in season {season}\n\nThis player did not participate in this season or did not get past calibration.",
|
||||
"no_ongoing_season": "# No ongoing season\n\nThere isn't a currently running rating season.",
|
||||
"deleted_player": "Deleted {id}",
|
||||
"neighbors": "Rating neighbors",
|
||||
"more": "+ {count} more"
|
||||
}
|
||||
},
|
||||
"today": {
|
||||
"name": "今日",
|
||||
"description": "Today's played tanks and statistics"
|
||||
},
|
||||
"stats": {
|
||||
"name": "",
|
||||
"description": "Quick statistics for a period"
|
||||
},
|
||||
"owned_tanks": {
|
||||
"name": "owned-tanks",
|
||||
"description": "Shows all own tanks in a tier",
|
||||
"body": {
|
||||
"title": "# {name}'s owned tier {tier} tanks\n\n"
|
||||
}
|
||||
},
|
||||
"permissions": {
|
||||
"name": "permissions",
|
||||
"description": "Checks wether the bot has the required permissions to function",
|
||||
"body": {
|
||||
"title": "# Permissions\n\n{body}",
|
||||
"view_channels": "View channels: needed to find the message the refresh button was used on",
|
||||
"read_message_history": "Read message history: needed to find the message to refresh",
|
||||
"attach_files": "Attach files: needed to add images to image-based commands",
|
||||
"external_emojis": "External emojis: needed to add national flags and tank class emojis"
|
||||
}
|
||||
},
|
||||
"ping": {
|
||||
"name": "ping",
|
||||
"description": "Check wether the bot is alive.",
|
||||
"body": {
|
||||
"pong": "Pong 🏓",
|
||||
"pong_with_time": "Pong 🏓 - {time}ms"
|
||||
},
|
||||
"subcommands": {
|
||||
"blitzkit": {
|
||||
"name": "blitzkit",
|
||||
"description": "Ping BlitzKit"
|
||||
},
|
||||
"wotb": {
|
||||
"name": "wotb",
|
||||
"description": "Ping World of Tanks Blitz"
|
||||
}
|
||||
}
|
||||
},
|
||||
"player_info": {
|
||||
"name": "player-info",
|
||||
"description": "Basic information about a player",
|
||||
"body": {
|
||||
"title": "{name}'s information",
|
||||
"nickname": "Nickname",
|
||||
"battles": "戦闘数",
|
||||
"winrate": "勝率",
|
||||
"account_id": "Account ID",
|
||||
"created": "Created",
|
||||
"last_battle": "Last battle"
|
||||
}
|
||||
},
|
||||
"rating": {
|
||||
"name": "rating",
|
||||
"description": "Rating player's statistics",
|
||||
"subcommands": {
|
||||
"today": {
|
||||
"name": "今日",
|
||||
"description": "Today's rating statistics"
|
||||
},
|
||||
"season": {
|
||||
"name": "season",
|
||||
"description": "This season's rating statistics"
|
||||
}
|
||||
},
|
||||
"body": {
|
||||
"subtitle": {
|
||||
"today": "Today's rating statistics",
|
||||
"season": "This season's rating statistics"
|
||||
}
|
||||
},
|
||||
"errors": {
|
||||
"no_participation": "# {name} hasn't played rating\n\nThis player hasn't participated in the rating gamemode this season.",
|
||||
"unrecorded_stats": "# Statistics currently unavailable\n\nWargaming may be currently be facing server downtime. If there is an on-going season, statistics should be available withing 24 hours."
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"website": {
|
||||
"redirect": {
|
||||
"title": "301: moved permanently",
|
||||
@@ -734,14 +281,6 @@
|
||||
}
|
||||
},
|
||||
"home": {
|
||||
"pwa": {
|
||||
"title": "Install the BlitzKit App",
|
||||
"new": "NEW",
|
||||
"checking": "Checking compatibility...",
|
||||
"instructions": "Instructions for Apple devices.",
|
||||
"install": "Install",
|
||||
"dismiss": "Dismiss"
|
||||
},
|
||||
"discord": {
|
||||
"join_short": "Join cool people!",
|
||||
"join_long": "Join super duper cool people!",
|
||||
@@ -953,6 +492,7 @@
|
||||
"tier": "Tier",
|
||||
"type": "タイプ",
|
||||
"dev_id": "DEV: ID",
|
||||
"dev_name": "DEV: NAME",
|
||||
"purchase": "購入価格",
|
||||
"restoration": "再購入価格",
|
||||
"sale": "売却価格",
|
||||
@@ -973,6 +513,11 @@
|
||||
},
|
||||
"configuration": {
|
||||
"title": "構成",
|
||||
"equalizer": {
|
||||
"title": "Equalizer",
|
||||
"equalize": "Equalize",
|
||||
"beta": "Beta"
|
||||
},
|
||||
"modules": {
|
||||
"title": "モジュール",
|
||||
"stock": "初期装備",
|
||||
@@ -1005,8 +550,8 @@
|
||||
"title": "性能値",
|
||||
"compare": {
|
||||
"label": "比較対象",
|
||||
"class": "Tier {tier} {class}",
|
||||
"tier": "All of tier {tier}",
|
||||
"class": "{tier} {class}",
|
||||
"tier": "All tier {tier}",
|
||||
"all": "全車輌"
|
||||
},
|
||||
"values": {
|
||||
@@ -1142,7 +687,8 @@
|
||||
},
|
||||
"skills": {
|
||||
"clear": "クリア",
|
||||
"maximize": "最大"
|
||||
"maximize": "最大",
|
||||
"equalize": "Equalize"
|
||||
},
|
||||
"modules": {
|
||||
"stock": "初期装備",
|
||||
|
||||
+47
-501
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"test": {
|
||||
"default": "",
|
||||
"default": "test",
|
||||
"long": "This is a long test string. You MUST NEVER see this in the UI. My favorite fruit is {fruit} because it has the color of {color}. I like it so much that I will say its name 3 times! {fruit}! {fruit}! {fruit}! Once again, it's {color}, not {not_color}.",
|
||||
"fox": "Szybki brązowy lis przeskoczył nad leniwym psem."
|
||||
},
|
||||
@@ -17,9 +17,9 @@
|
||||
"plus": "+{value}"
|
||||
},
|
||||
"gun_types": {
|
||||
"auto_loader": "Auto loader",
|
||||
"auto_loader": "Samo ładowacz",
|
||||
"auto_reloader": "Automatyczne przeładowanie",
|
||||
"regular": ""
|
||||
"regular": "Regular"
|
||||
},
|
||||
"shells": {
|
||||
"ap": "AP",
|
||||
@@ -28,19 +28,20 @@
|
||||
"he": "OB"
|
||||
},
|
||||
"player_count_period": {
|
||||
"total": "Total",
|
||||
"d_120": "Past 120 days",
|
||||
"d_90": "Past 90 days",
|
||||
"d_60": "Past 60 days",
|
||||
"d_30": "Past month",
|
||||
"total": "Łącznie",
|
||||
"d_120": "Powyżej 120 dni",
|
||||
"d_90": "Powyżej 90 dni",
|
||||
"d_60": "Powyżej 60 dni",
|
||||
"d_30": "W ciągu miesiąca",
|
||||
"d_7": "W minionym tygodniu",
|
||||
"d_1": "Yesterday"
|
||||
"d_1": "Wczoraj"
|
||||
},
|
||||
"branches": {
|
||||
"local": "dev",
|
||||
"dev": "beta",
|
||||
"opentest": "opentest",
|
||||
"preview": "podgląd"
|
||||
"beta": "Beta",
|
||||
"development": "Development",
|
||||
"opentest": "OpenTest",
|
||||
"preview": "Preview",
|
||||
"production": "Production"
|
||||
},
|
||||
"locales": {
|
||||
"en": "Angielski",
|
||||
@@ -80,45 +81,45 @@
|
||||
},
|
||||
"nations": {
|
||||
"ussr": "ZSRR",
|
||||
"germany": "Germany",
|
||||
"usa": "U.S.A.",
|
||||
"germany": "Niemcy",
|
||||
"usa": "Stany Zjednoczone.",
|
||||
"china": "Chiny",
|
||||
"uk": "Wielka Brytania",
|
||||
"france": "France",
|
||||
"japan": "Japan",
|
||||
"france": "Francja",
|
||||
"japan": "Japonia",
|
||||
"european": "Nacja Europejska",
|
||||
"other": "Nacja Hybrydowa"
|
||||
},
|
||||
"nations_adjectives": {
|
||||
"ussr": "ZSRR",
|
||||
"germany": "German",
|
||||
"germany": "Niemcy",
|
||||
"usa": "Amerykański",
|
||||
"china": "Chiński",
|
||||
"uk": "Wielkiej Brytanii",
|
||||
"france": "Francuski",
|
||||
"japan": "Japoński",
|
||||
"european": "European",
|
||||
"other": "Hybrid"
|
||||
"european": "Europa",
|
||||
"other": "Hybryda"
|
||||
},
|
||||
"tank_class_short": {
|
||||
"-1": "unrecognized",
|
||||
"0": "Light",
|
||||
"1": "Medium",
|
||||
"2": "Heavy",
|
||||
"0": "Lekki",
|
||||
"1": "Średni",
|
||||
"2": "Ciężki",
|
||||
"3": "TD"
|
||||
},
|
||||
"tank_class_short_plural_lowercase": {
|
||||
"0": "lights",
|
||||
"1": "mediums",
|
||||
"2": "heavies",
|
||||
"0": "lekkie",
|
||||
"1": "średnie",
|
||||
"2": "ciężkie",
|
||||
"3": "TDs"
|
||||
},
|
||||
"tank_class_medium": {
|
||||
"-1": "unrecognized",
|
||||
"0": "Lekki",
|
||||
"1": "Medium",
|
||||
"2": "Heavy",
|
||||
"3": "Tank destroyer"
|
||||
"1": "Średni",
|
||||
"2": "Ciężki",
|
||||
"3": "Niszczyciel czołgów"
|
||||
},
|
||||
"tree_type": {
|
||||
"-1": "unrecognized",
|
||||
@@ -184,460 +185,6 @@
|
||||
"cumulative_battle_life_time": "Całkowity czas bitwy"
|
||||
}
|
||||
},
|
||||
"bot": {
|
||||
"common": {
|
||||
"errors": {
|
||||
"clan_not_found": "# Could not find clan\nCouldn't find \"{search}\". Try selecting a clan from the search result.",
|
||||
"player_not_found": "# Could not find user\nI couldn't find user \"{search}\". Try picking an user from the search result, typing in a valid username, or using the `/link` command.",
|
||||
"player_not_linked": "# Użyj `/link` aby zacząć\nNie wiem, kim jesteś, ale możesz mi dziś powiedzieć!",
|
||||
"tank_name_not_found": "# Tank not found\nCould not find tank by the name \"{search}\".",
|
||||
"tank_id_not_found": "# Tank not found\nCould not find tank by the ID \"{search}\". Try typing the name of the tank instead of a number.",
|
||||
"no_tank_stats": "# Brak dostępnych statystyk czołgów\nTen gracz nie ma żadnych dostępnych statystyk. Może to nie być gracz, którego szukasz.",
|
||||
"get_help": "Pomóż serwerowi Discord",
|
||||
"uncaught_error": "# BlitzKit wpadł w błąd!\nPrzepraszamy za to. Możesz [dołączyć do oficjalnego serwera Discord](https://discord.gg/nDt7AjGJQH), aby uzyskać pomoc.",
|
||||
"preview": "# Ta komenda jest w podglądzie\n\nMożesz uzyskać dostęp do tej komendy tylko na [oficjalnym serwerze Discorda](https://discord.gg/nDt7AjGJQH). Polecenie będzie ogólnie dostępne wkrótce.",
|
||||
"query_too_small": "# Twoje wyszukiwanie jest zbyt krótkie\nTwoje wyszukiwanie musi mieć co najmniej 3 znaki.",
|
||||
"query_too_long": "# Twoje wyszukiwanie jest zbyt długie\nTwoje wyszukiwanie musi mieć maksymalnie 100 znaków."
|
||||
},
|
||||
"wn8": {
|
||||
"name": "WN8",
|
||||
"types": {
|
||||
"very_bad": "Bardzo złe",
|
||||
"bad": "Złe",
|
||||
"below_average": "Poniżej średniej",
|
||||
"average": "Średnia",
|
||||
"above_average": "Powyżej średniej",
|
||||
"good": "Dobrze",
|
||||
"very_good": "Bardzo dobrze",
|
||||
"great": "Świetne",
|
||||
"unicum": "Unikalny ",
|
||||
"super_unicum": "Bardzo unikalny"
|
||||
}
|
||||
},
|
||||
"subcommands": {
|
||||
"today": {
|
||||
"name": "dziś",
|
||||
"description": "Dziś"
|
||||
},
|
||||
"30": {
|
||||
"name": "30",
|
||||
"description": "30 dni"
|
||||
},
|
||||
"60": {
|
||||
"name": "60",
|
||||
"description": "60 dni"
|
||||
},
|
||||
"90": {
|
||||
"name": "90",
|
||||
"description": "90 dni"
|
||||
},
|
||||
"career": {
|
||||
"name": "kariera",
|
||||
"description": "Kariera"
|
||||
},
|
||||
"custom": {
|
||||
"name": "Niestandardowy",
|
||||
"description": "Zakres niestandardowy",
|
||||
"options": {
|
||||
"start": {
|
||||
"name": "start",
|
||||
"description": "Rozpocznij od dnia dzisiejszego"
|
||||
},
|
||||
"end": {
|
||||
"name": "zakończ",
|
||||
"description": "Zakończ od dnia dzisiejszego"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"options": {
|
||||
"clan": {
|
||||
"name": "klan",
|
||||
"description": "Wpisz nazwę klanu lub tag"
|
||||
},
|
||||
"tank": {
|
||||
"name": "czołg",
|
||||
"description": "Czołg do pobrania statystyk"
|
||||
},
|
||||
"username": {
|
||||
"name": "nazwa użytkownika",
|
||||
"description": "Nazwa użytkownika Blitz gracza"
|
||||
},
|
||||
"filters": {
|
||||
"nation": {
|
||||
"name": "naród",
|
||||
"description": "Naród"
|
||||
},
|
||||
"class": {
|
||||
"name": "klasa",
|
||||
"description": "Klasa"
|
||||
},
|
||||
"type": {
|
||||
"name": "rodzaj",
|
||||
"description": "Rodzaj"
|
||||
}
|
||||
},
|
||||
"region": {
|
||||
"name": "region",
|
||||
"description": "Region"
|
||||
},
|
||||
"tier": {
|
||||
"name": "poziom",
|
||||
"description": "Poziom",
|
||||
"choices": {
|
||||
"tier": "Tier {tier_1} - {tier_2}"
|
||||
}
|
||||
}
|
||||
},
|
||||
"periods": {
|
||||
"career": "Kariera",
|
||||
"today": "Dzisiaj",
|
||||
"days": "{days} days",
|
||||
"custom": "{day_1} - {day_2} days"
|
||||
},
|
||||
"filters": {
|
||||
"none": "Brak filtrów",
|
||||
"tier": "Tier {tier}"
|
||||
},
|
||||
"no_data": {
|
||||
"battles_in_period": "Brak bitew w tym okresie",
|
||||
"battles_in_season": "Brak bitew w tym sezonie",
|
||||
"players_in_period": "Brak graczy w tym okresie",
|
||||
"tanks_found": "Nie znaleziono czołgu"
|
||||
},
|
||||
"buttons": {
|
||||
"refresh": "Odśwież"
|
||||
},
|
||||
"hero_stats": {
|
||||
"battles": "Bitwy",
|
||||
"winrate": "Zwycięstwa",
|
||||
"damage": "Obrażenia",
|
||||
"damage_ratio": "Współczynnik obrażeń",
|
||||
"tier": "Poziom",
|
||||
"survival": "Przeżycie",
|
||||
"accuracy": "Celność",
|
||||
"kills": "Zabójstwa"
|
||||
}
|
||||
},
|
||||
"commands": {
|
||||
"replay": {
|
||||
"name": "powtórz",
|
||||
"description": "Wyświetl wyniki powtórki"
|
||||
},
|
||||
"research": {
|
||||
"name": "badanie",
|
||||
"description": "Wyświetla wydatki na badanie linii",
|
||||
"options": {
|
||||
"target_tank": {
|
||||
"name": "docelowy czołg",
|
||||
"description": "Ostatni czołg do badań w linii"
|
||||
},
|
||||
"starting_tank": {
|
||||
"name": "czołg rozpoczynający",
|
||||
"description": "Czołg początkowy w linii (automatycznie, jeżeli nie jest dostarczony)"
|
||||
}
|
||||
},
|
||||
"body": {
|
||||
"subtitle": "Rozpocznij badania",
|
||||
"total": "Całkowity",
|
||||
"research": "Research: {cost}",
|
||||
"upgrades": "Upgrades: {cost}",
|
||||
"purchase": "Purchase: {cost}",
|
||||
"equipment": "Equipment: {cost}",
|
||||
"estimation": "# To jest szacunek!\n\nTa lista może zawierać już zbadane czołgi z powodu niedokładnych informacji dostarczanych przez Wargaming. Spróbuj podać `starting-tank` z wiersza podczas używania polecenia, jeśli możesz."
|
||||
},
|
||||
"errors": {
|
||||
"non_tech_tree": "# {tank} is not on the tech tree\n\nYou cannot research a premium/collector tank.",
|
||||
"tier_1": "# {tank} is a tier I\n\nTier I tanks are always unlocked for free for all players.",
|
||||
"already_researched": "# {tank} is already researched\n\nTry providing a `starting-tank` when using the command to view the totals for a line you have already researched.",
|
||||
"start_end_equal": "# {tank} was provided twice\n\nMake sure `starting-tank` and `target-tank` are different.",
|
||||
"tanks_not_on_line": "# {tank_1} and {tank_2} are not on the same line\n\nMake sure `starting-tank` and `target-tank` are on the same tech-tree line.",
|
||||
"unordered": "# {tank_1} higher tiered to {tank_2}\n\nMake sure to provide {tank_2} as the `starting-tank` instead as it is the lower tiered tank."
|
||||
}
|
||||
},
|
||||
"about": {
|
||||
"name": "opis",
|
||||
"description": "Wszystkie informacje na temat bota",
|
||||
"subcommands": {
|
||||
"commands": {
|
||||
"name": "komendy",
|
||||
"description": "Lista wszystkich poleceń i ich opisów",
|
||||
"body": "# Polecenia\n\nBlitzKit oferuje następujące polecenia:\n\n"
|
||||
},
|
||||
"embeds": {
|
||||
"name": "osadzenie",
|
||||
"description": "Jak działają osadzone"
|
||||
},
|
||||
"introduction": {
|
||||
"name": "wprowadzenie",
|
||||
"description": "O bocie"
|
||||
},
|
||||
"invite": {
|
||||
"name": "zaproszenie",
|
||||
"description": "Jak zaprosić bota"
|
||||
},
|
||||
"timezones": {
|
||||
"name": "strefy czasowe",
|
||||
"description": "W jaki sposób BlitzKit wnioskuje i wykorzystuje Twoją strefę czasową"
|
||||
},
|
||||
"credits": {
|
||||
"name": "uznania",
|
||||
"description": "Ludzie, którzy pomogli BlitzKit"
|
||||
}
|
||||
}
|
||||
},
|
||||
"breakdown": {
|
||||
"name": "podział",
|
||||
"description": "Podział przez okres według rozgrywanych czołgów",
|
||||
"body": {
|
||||
"total": "Ogółem",
|
||||
"battles": "Bitwy",
|
||||
"wn8": "WN8",
|
||||
"winrate": "Śr. wygranych",
|
||||
"damage": "Uszkodzenia",
|
||||
"unknown_tank": "Unknown tank {id}"
|
||||
}
|
||||
},
|
||||
"debug": {
|
||||
"name": "debugowanie",
|
||||
"description": "Debugowanie informacji o botu",
|
||||
"body": {
|
||||
"title": "# Debug\n\n",
|
||||
"version": "Wersja",
|
||||
"shard": {
|
||||
"label": "Fragment",
|
||||
"default": "domyślne"
|
||||
},
|
||||
"uptime": "Czas działania"
|
||||
}
|
||||
},
|
||||
"evolution": {
|
||||
"name": "rozwój",
|
||||
"description": "Rozwój statystyk",
|
||||
"groups": {
|
||||
"player": {
|
||||
"name": "gracz",
|
||||
"description": "Statystyki gracza"
|
||||
},
|
||||
"tank": {
|
||||
"name": "czołg",
|
||||
"description": "Statystyki czołgu"
|
||||
}
|
||||
}
|
||||
},
|
||||
"inactive": {
|
||||
"name": "inactive",
|
||||
"description": "Lists all inactive players in a clan above a threshold",
|
||||
"options": {
|
||||
"threshold": {
|
||||
"name": "threshold",
|
||||
"description": "The number of days inactive (default: {days} days)"
|
||||
}
|
||||
},
|
||||
"body": {
|
||||
"subtitle": "Inactive for {days}+ days",
|
||||
"listing": "{days} days"
|
||||
}
|
||||
},
|
||||
"full_stats": {
|
||||
"name": "full-stats",
|
||||
"description": "Full in-game statistics",
|
||||
"body": {
|
||||
"cards": {
|
||||
"games": {
|
||||
"title": "Games",
|
||||
"winrate": "Śr. wygranych",
|
||||
"battles": "Bitwy",
|
||||
"wins_losses": "Zwycięstwa / porażki"
|
||||
},
|
||||
"efficiency": {
|
||||
"title": "Efficiency",
|
||||
"wn8": "WN8",
|
||||
"survival": "Przeżycie",
|
||||
"accuracy": "Skuteczność"
|
||||
},
|
||||
"lethality": {
|
||||
"title": "Lethality",
|
||||
"average_damage": "Średnie uszkodzenia",
|
||||
"damage_per_tier": "Damage per tier",
|
||||
"damage_ratio": "Współczynnik obrażeń",
|
||||
"average_kills": "Average kills"
|
||||
},
|
||||
"miscellaneous": {
|
||||
"title": "Miscellaneous",
|
||||
"average_tier": "Średni poziom",
|
||||
"average_spots": "Average spots",
|
||||
"average_xp": "Average XP",
|
||||
"kills_to_death_ratio": "Stosunek zabójstw do śmierci"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"link": {
|
||||
"name": "link",
|
||||
"description": "Links your Blitz and Discord account",
|
||||
"body": {
|
||||
"accounts_linked": "Accounts linked",
|
||||
"no_role_permissions": {
|
||||
"title": "{name} failed to verify",
|
||||
"description": "I don't have the permission to manage roles."
|
||||
}
|
||||
},
|
||||
"embed": {
|
||||
"title": "Incorrect account?",
|
||||
"description": "Use the command again and select a username from the search results."
|
||||
}
|
||||
},
|
||||
"search_clans": {
|
||||
"name": "search-clans",
|
||||
"description": "Search clans",
|
||||
"options": {
|
||||
"limit": {
|
||||
"name": "",
|
||||
"description": "The max number of clan results (default: {limit})"
|
||||
}
|
||||
},
|
||||
"body": {
|
||||
"title": "Clan search for {search} in region {region}",
|
||||
"no_results": "No clans found"
|
||||
}
|
||||
},
|
||||
"search_players": {
|
||||
"name": "search-players",
|
||||
"description": "Search players",
|
||||
"options": {
|
||||
"limit": {
|
||||
"name": "",
|
||||
"description": "The max number of player results (default: {limit})"
|
||||
}
|
||||
},
|
||||
"body": {
|
||||
"title": "Player search for {search} in region {region}",
|
||||
"no_results": "No players found"
|
||||
}
|
||||
},
|
||||
"rating_leaderboard": {
|
||||
"name": "rating-leaderboard",
|
||||
"description": "Rating battles statistics",
|
||||
"subcommands": {
|
||||
"neighbors": {
|
||||
"name": "neighbors",
|
||||
"description": "Neighboring players on the leaderboard"
|
||||
},
|
||||
"league": {
|
||||
"name": "league",
|
||||
"description": "Najlepsi gracze ligi"
|
||||
}
|
||||
},
|
||||
"options": {
|
||||
"limit": {
|
||||
"name": "",
|
||||
"description": "How many neighbors to display (default: {count})"
|
||||
},
|
||||
"season": {
|
||||
"name": "season",
|
||||
"description": "Season number (default: current)",
|
||||
"choices": {
|
||||
"current": "{season} (current)"
|
||||
}
|
||||
},
|
||||
"league": {
|
||||
"name": "league",
|
||||
"description": "The league to display"
|
||||
}
|
||||
},
|
||||
"body": {
|
||||
"top_players": "Top {count} players",
|
||||
"no_participation": "# {player} didn't play rating in season {season}\n\nThis player did not participate in this season or did not get past calibration.",
|
||||
"no_ongoing_season": "# No ongoing season\n\nThere isn't a currently running rating season.",
|
||||
"deleted_player": "Deleted {id}",
|
||||
"neighbors": "Rating neighbors",
|
||||
"more": "+ {count} more"
|
||||
}
|
||||
},
|
||||
"today": {
|
||||
"name": "dzisiaj",
|
||||
"description": "Dzisiejsze zagrane czołgami i statystyki"
|
||||
},
|
||||
"stats": {
|
||||
"name": "stats",
|
||||
"description": "Szybkie statystyki na okres"
|
||||
},
|
||||
"owned_tanks": {
|
||||
"name": "posiadane czołgi",
|
||||
"description": "Pokazuje wszystkie własne czołgi na poziomie",
|
||||
"body": {
|
||||
"title": "# {name}'s owned tier {tier} tanks\n\n"
|
||||
}
|
||||
},
|
||||
"permissions": {
|
||||
"name": "uprawnienia",
|
||||
"description": "Sprawdza, czy bot ma wymagane uprawnienia do funkcji",
|
||||
"body": {
|
||||
"title": "# Permissions\n\n{body}",
|
||||
"view_channels": "Wyświetl kanały: potrzebne do znalezienia wiadomości użyty przycisk odświeżania",
|
||||
"read_message_history": "Przeczytaj historię wiadomości: potrzebne do znalezienia wiadomości do odświeżenia",
|
||||
"attach_files": "Dołącz pliki: potrzebne do dodawania obrazów do komend opartych na obrazach",
|
||||
"external_emojis": "Zewnętrzne emotikony: potrzebne do dodania flagi krajowych i emotikonów klasy zbiorników"
|
||||
}
|
||||
},
|
||||
"ping": {
|
||||
"name": "ping",
|
||||
"description": "Sprawdź, czy bot żyje.",
|
||||
"body": {
|
||||
"pong": "Pong 🏓",
|
||||
"pong_with_time": "Pong 🏓 - {time}ms"
|
||||
},
|
||||
"subcommands": {
|
||||
"blitzkit": {
|
||||
"name": "blitzkit",
|
||||
"description": "Ping BlitzKit"
|
||||
},
|
||||
"wotb": {
|
||||
"name": "wotb",
|
||||
"description": "Ping World of Tanks Blitz"
|
||||
}
|
||||
}
|
||||
},
|
||||
"player_info": {
|
||||
"name": "informacje o graczu",
|
||||
"description": "Podstawowe informacje o graczu",
|
||||
"body": {
|
||||
"title": "{name}'s information",
|
||||
"nickname": "Nick",
|
||||
"battles": "Bitwy",
|
||||
"winrate": "Śr. wygranych",
|
||||
"account_id": "ID konta",
|
||||
"created": "Stworzony",
|
||||
"last_battle": "Ostatnia bitwa"
|
||||
}
|
||||
},
|
||||
"rating": {
|
||||
"name": "klasyfikacja",
|
||||
"description": "Statystyki klasyfikacji gracza",
|
||||
"subcommands": {
|
||||
"today": {
|
||||
"name": "dzisiaj",
|
||||
"description": "Dzisiejsze statystyki klasyfikacji"
|
||||
},
|
||||
"season": {
|
||||
"name": "sezon",
|
||||
"description": "Statystyki klasyfikacji w tym sezonie"
|
||||
}
|
||||
},
|
||||
"body": {
|
||||
"subtitle": {
|
||||
"today": "Dzisiejsze statystyki klasyfikacji",
|
||||
"season": "Statystyki klasyfikacji w tym sezonie"
|
||||
}
|
||||
},
|
||||
"errors": {
|
||||
"no_participation": "# {name} hasn't played rating\n\nThis player hasn't participated in the rating gamemode this season.",
|
||||
"unrecorded_stats": "# Statistics currently unavailable\n\nWargaming may be currently be facing server downtime. If there is an on-going season, statistics should be available withing 24 hours."
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"website": {
|
||||
"redirect": {
|
||||
"title": "301: moved permanently",
|
||||
@@ -734,14 +281,6 @@
|
||||
}
|
||||
},
|
||||
"home": {
|
||||
"pwa": {
|
||||
"title": "Install the BlitzKit App",
|
||||
"new": "NEW",
|
||||
"checking": "Checking compatibility...",
|
||||
"instructions": "Instructions for Apple devices.",
|
||||
"install": "Install",
|
||||
"dismiss": "Dismiss"
|
||||
},
|
||||
"discord": {
|
||||
"join_short": "Join cool people!",
|
||||
"join_long": "Join super duper cool people!",
|
||||
@@ -849,7 +388,7 @@
|
||||
"hull": "Hull",
|
||||
"turret": "Turret",
|
||||
"hard": "Hard",
|
||||
"medium": "Medium",
|
||||
"medium": "Średni",
|
||||
"soft": "Soft",
|
||||
"effective": "Effective"
|
||||
},
|
||||
@@ -953,6 +492,7 @@
|
||||
"tier": "Poziom",
|
||||
"type": "Rodzaj",
|
||||
"dev_id": "DEV: ID",
|
||||
"dev_name": "DEV: NAME",
|
||||
"purchase": "Purchase price",
|
||||
"restoration": "Restoration price",
|
||||
"sale": "Sale price",
|
||||
@@ -973,6 +513,11 @@
|
||||
},
|
||||
"configuration": {
|
||||
"title": "Configuration",
|
||||
"equalizer": {
|
||||
"title": "Equalizer",
|
||||
"equalize": "Equalize",
|
||||
"beta": "Beta"
|
||||
},
|
||||
"modules": {
|
||||
"title": "Modules",
|
||||
"stock": "Stock",
|
||||
@@ -1005,8 +550,8 @@
|
||||
"title": "Characteristics",
|
||||
"compare": {
|
||||
"label": "Compare against",
|
||||
"class": "Tier {tier} {class}",
|
||||
"tier": "All of tier {tier}",
|
||||
"class": "{tier} {class}",
|
||||
"tier": "All tier {tier}",
|
||||
"all": "All tanks"
|
||||
},
|
||||
"values": {
|
||||
@@ -1059,19 +604,19 @@
|
||||
"speedBackwards": "Backwards",
|
||||
"hardTerrainCoefficient": "Hard",
|
||||
"hardTerrainCoefficientRaw": "Hard",
|
||||
"mediumTerrainCoefficient": "Medium",
|
||||
"mediumTerrainCoefficientRaw": "Medium",
|
||||
"mediumTerrainCoefficient": "Średni",
|
||||
"mediumTerrainCoefficientRaw": "Średni",
|
||||
"softTerrainCoefficient": "Soft",
|
||||
"softTerrainCoefficientRaw": "Soft",
|
||||
"enginePower": "Engine power",
|
||||
"powerToWeightRatioHardTerrain": "Hard",
|
||||
"powerToWeightRatioMediumTerrain": "Medium",
|
||||
"powerToWeightRatioMediumTerrain": "Średni",
|
||||
"powerToWeightRatioSoftTerrain": "Soft",
|
||||
"weight": "Weight",
|
||||
"turretTraverseSpeed": "Turret traverse speed",
|
||||
"gunTraverseSpeed": "Gun traverse speed",
|
||||
"hullTraverseHardTerrain": "Hard",
|
||||
"hullTraverseMediumTerrain": "Medium",
|
||||
"hullTraverseMediumTerrain": "Średni",
|
||||
"hullTraverseSoftTerrain": "Soft",
|
||||
"health": "Health",
|
||||
"fireChance": "Fire chance",
|
||||
@@ -1142,7 +687,8 @@
|
||||
},
|
||||
"skills": {
|
||||
"clear": "Clear",
|
||||
"maximize": "Maximize"
|
||||
"maximize": "Maximize",
|
||||
"equalize": "Equalize"
|
||||
},
|
||||
"modules": {
|
||||
"stock": "Stock",
|
||||
@@ -1174,7 +720,7 @@
|
||||
"table": {
|
||||
"tanks": {
|
||||
"header": "Tank",
|
||||
"total": "Total"
|
||||
"total": "Łącznie"
|
||||
},
|
||||
"stats": {
|
||||
"winrate": "Śr. wygranych",
|
||||
@@ -1232,7 +778,7 @@
|
||||
},
|
||||
"table": {
|
||||
"tank": "Tank",
|
||||
"total": "Total",
|
||||
"total": "Łącznie",
|
||||
"remove": "Remove"
|
||||
}
|
||||
},
|
||||
|
||||
+15
-469
@@ -37,10 +37,11 @@
|
||||
"d_1": "Ontem"
|
||||
},
|
||||
"branches": {
|
||||
"local": "dev",
|
||||
"dev": "beta",
|
||||
"opentest": "testeaberto",
|
||||
"preview": "visualização"
|
||||
"beta": "Beta",
|
||||
"development": "Development",
|
||||
"opentest": "TesteAberto",
|
||||
"preview": "Preview",
|
||||
"production": "Production"
|
||||
},
|
||||
"locales": {
|
||||
"en": "Inglês",
|
||||
@@ -184,460 +185,6 @@
|
||||
"cumulative_battle_life_time": "Tempo de batalha total"
|
||||
}
|
||||
},
|
||||
"bot": {
|
||||
"common": {
|
||||
"errors": {
|
||||
"clan_not_found": "# Could not find clan\nCouldn't find \"{search}\". Try selecting a clan from the search result.",
|
||||
"player_not_found": "# Could not find user\nI couldn't find user \"{search}\". Try picking an user from the search result, typing in a valid username, or using the `/link` command.",
|
||||
"player_not_linked": "Digite \"/link\" para começar.\nEu posso não saber quem é você, mas pode-me dizer hoje sobre isso!",
|
||||
"tank_name_not_found": "# Tank not found\nCould not find tank by the name \"{search}\".",
|
||||
"tank_id_not_found": "# Tank not found\nCould not find tank by the ID \"{search}\". Try typing the name of the tank instead of a number.",
|
||||
"no_tank_stats": "# Nenhuma estatística de tanques disponível\nEsse jogador não tem as suas estatísticas disponíveis. Talvez esse pode não ser o jogador que procura.",
|
||||
"get_help": "Servidor de Ajuda no Discord",
|
||||
"uncaught_error": "# O BlitzKit apresentou um erro!\nSentimos muito por isso. Sinta-se a vontade para [entrar no servidor oficial no Discord]\n(https://discord.gg/nDt7AjGJQH) para conseguir ajuda.",
|
||||
"preview": "# Este comando está na pré-visualização\n\nVocê só pode acessar este comando no [servidor oficial do Discord](https://discord.gg/nDt7AjGJQH). O comando estará geralmente disponível em breve.",
|
||||
"query_too_small": "# Sua pesquisa é muito curta\nSua pesquisa deve ter pelo menos 3 caracteres.",
|
||||
"query_too_long": "# Sua pesquisa é muito longa\nSua pesquisa deve ter no máximo 100 caracteres."
|
||||
},
|
||||
"wn8": {
|
||||
"name": "WN8",
|
||||
"types": {
|
||||
"very_bad": "Muito ruim",
|
||||
"bad": "Ruim",
|
||||
"below_average": "Abaixo da média",
|
||||
"average": "Na média",
|
||||
"above_average": "Acima da média",
|
||||
"good": "Bom",
|
||||
"very_good": "Muito bom",
|
||||
"great": "Ótimo",
|
||||
"unicum": "Unicum",
|
||||
"super_unicum": "Super unicum"
|
||||
}
|
||||
},
|
||||
"subcommands": {
|
||||
"today": {
|
||||
"name": "hoje",
|
||||
"description": "Hoje"
|
||||
},
|
||||
"30": {
|
||||
"name": "30",
|
||||
"description": "30 dias"
|
||||
},
|
||||
"60": {
|
||||
"name": "60",
|
||||
"description": "60 dias"
|
||||
},
|
||||
"90": {
|
||||
"name": "90",
|
||||
"description": "90 dias"
|
||||
},
|
||||
"career": {
|
||||
"name": "carreira",
|
||||
"description": "Carreira"
|
||||
},
|
||||
"custom": {
|
||||
"name": "personalizado",
|
||||
"description": "Intervalo personalizado",
|
||||
"options": {
|
||||
"start": {
|
||||
"name": "iniciar",
|
||||
"description": "Iniciar em número de dias atrás a partir de hoje"
|
||||
},
|
||||
"end": {
|
||||
"name": "terminar",
|
||||
"description": "Termina em número de dias atrás a partir de hoje"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"options": {
|
||||
"clan": {
|
||||
"name": "clã",
|
||||
"description": "O nome ou tag do clã"
|
||||
},
|
||||
"tank": {
|
||||
"name": "tanque",
|
||||
"description": "O tanque para obter estatísticas para"
|
||||
},
|
||||
"username": {
|
||||
"name": "nome de usuário",
|
||||
"description": "O nome de usuário Blitz do jogador"
|
||||
},
|
||||
"filters": {
|
||||
"nation": {
|
||||
"name": "nação",
|
||||
"description": "Nação"
|
||||
},
|
||||
"class": {
|
||||
"name": "classe",
|
||||
"description": "Classe"
|
||||
},
|
||||
"type": {
|
||||
"name": "tipo",
|
||||
"description": "Tipo"
|
||||
}
|
||||
},
|
||||
"region": {
|
||||
"name": "região",
|
||||
"description": "Região"
|
||||
},
|
||||
"tier": {
|
||||
"name": "nível",
|
||||
"description": "Nível",
|
||||
"choices": {
|
||||
"tier": "Tier {tier_1} - {tier_2}"
|
||||
}
|
||||
}
|
||||
},
|
||||
"periods": {
|
||||
"career": "Carreira",
|
||||
"today": "Hoje",
|
||||
"days": "{days} days",
|
||||
"custom": "{day_1} - {day_2} days"
|
||||
},
|
||||
"filters": {
|
||||
"none": "Sem filtros",
|
||||
"tier": "Tier {tier}"
|
||||
},
|
||||
"no_data": {
|
||||
"battles_in_period": "Não há batalhas jogadas neste período",
|
||||
"battles_in_season": "Não há batalhas jogadas nesta temporada",
|
||||
"players_in_period": "Nenhum jogador neste período",
|
||||
"tanks_found": "Nenhum tanque encontrado"
|
||||
},
|
||||
"buttons": {
|
||||
"refresh": "Atualizar"
|
||||
},
|
||||
"hero_stats": {
|
||||
"battles": "Batalhas",
|
||||
"winrate": "Taxa de vitória",
|
||||
"damage": "Dano",
|
||||
"damage_ratio": "Razão entre dano dado e recebido",
|
||||
"tier": "Nível",
|
||||
"survival": "Sobrevivência",
|
||||
"accuracy": "Precisão",
|
||||
"kills": "Abates"
|
||||
}
|
||||
},
|
||||
"commands": {
|
||||
"replay": {
|
||||
"name": "replay",
|
||||
"description": "Exibir resultados de replays"
|
||||
},
|
||||
"research": {
|
||||
"name": "pesquisa",
|
||||
"description": "Liste as despesas na pesquisa de uma linha",
|
||||
"options": {
|
||||
"target_tank": {
|
||||
"name": "tanque-alvo",
|
||||
"description": "O último tanque para pesquisar na linha"
|
||||
},
|
||||
"starting_tank": {
|
||||
"name": "tanque-inicial",
|
||||
"description": "O tanque inicial na linha (inferido automaticamente se não fornecido)"
|
||||
}
|
||||
},
|
||||
"body": {
|
||||
"subtitle": "Pesquisa",
|
||||
"total": "Total",
|
||||
"research": "Research: {cost}",
|
||||
"upgrades": "Upgrades: {cost}",
|
||||
"purchase": "Purchase: {cost}",
|
||||
"equipment": "Equipment: {cost}",
|
||||
"estimation": "# Esta é uma estimativa!\n\nEsta lista pode incluir tanques já pesquisados devido à informação imprecisa que a Wargaming fornece. Tente fornecer um `tanque-inicial` da linha ao usar o comando, se puder."
|
||||
},
|
||||
"errors": {
|
||||
"non_tech_tree": "# {tank} is not on the tech tree\n\nYou cannot research a premium/collector tank.",
|
||||
"tier_1": "# {tank} is a tier I\n\nTier I tanks are always unlocked for free for all players.",
|
||||
"already_researched": "# {tank} is already researched\n\nTry providing a `starting-tank` when using the command to view the totals for a line you have already researched.",
|
||||
"start_end_equal": "# {tank} was provided twice\n\nMake sure `starting-tank` and `target-tank` are different.",
|
||||
"tanks_not_on_line": "# {tank_1} and {tank_2} are not on the same line\n\nMake sure `starting-tank` and `target-tank` are on the same tech-tree line.",
|
||||
"unordered": "# {tank_1} higher tiered to {tank_2}\n\nMake sure to provide {tank_2} as the `starting-tank` instead as it is the lower tiered tank."
|
||||
}
|
||||
},
|
||||
"about": {
|
||||
"name": "sobre",
|
||||
"description": "Todas as informações que você precisa sobre o bot",
|
||||
"subcommands": {
|
||||
"commands": {
|
||||
"name": "comandos",
|
||||
"description": "Lista de todos os comandos e suas descrições",
|
||||
"body": "# Comandos\n\nBlitzKit oferece os seguintes comandos:\n"
|
||||
},
|
||||
"embeds": {
|
||||
"name": "incorporar",
|
||||
"description": "Como incorporações funcionam"
|
||||
},
|
||||
"introduction": {
|
||||
"name": "Introdução",
|
||||
"description": "Sobre o bot"
|
||||
},
|
||||
"invite": {
|
||||
"name": "convite",
|
||||
"description": "Como convidar o bot"
|
||||
},
|
||||
"timezones": {
|
||||
"name": "fusos horários",
|
||||
"description": "Como o BlitzKit inferi e usa seu fuso horário"
|
||||
},
|
||||
"credits": {
|
||||
"name": "créditos",
|
||||
"description": "Pessoas que ajudaram BlitzKit"
|
||||
}
|
||||
}
|
||||
},
|
||||
"breakdown": {
|
||||
"name": "divisão",
|
||||
"description": "Análise de um período por tanques jogados",
|
||||
"body": {
|
||||
"total": "Total",
|
||||
"battles": "Batalhas",
|
||||
"wn8": "WN8",
|
||||
"winrate": "Taxa de vitória",
|
||||
"damage": "Dano",
|
||||
"unknown_tank": "Unknown tank {id}"
|
||||
}
|
||||
},
|
||||
"debug": {
|
||||
"name": "depuração",
|
||||
"description": "Depurar informações sobre o bot",
|
||||
"body": {
|
||||
"title": "# Depuração\n",
|
||||
"version": "Versão",
|
||||
"shard": {
|
||||
"label": "Fragmento",
|
||||
"default": "padrão"
|
||||
},
|
||||
"uptime": "Tempo de atividade"
|
||||
}
|
||||
},
|
||||
"evolution": {
|
||||
"name": "evolução",
|
||||
"description": "Evolução das estatísticas",
|
||||
"groups": {
|
||||
"player": {
|
||||
"name": "jogador",
|
||||
"description": "Estatísticas do Jogador"
|
||||
},
|
||||
"tank": {
|
||||
"name": "tanque",
|
||||
"description": "Estatísticas do tanque"
|
||||
}
|
||||
}
|
||||
},
|
||||
"inactive": {
|
||||
"name": "inativo",
|
||||
"description": "Liste todos os jogadores inativos em um clã acima de um limite",
|
||||
"options": {
|
||||
"threshold": {
|
||||
"name": "limite",
|
||||
"description": "The number of days inactive (default: {days} days)"
|
||||
}
|
||||
},
|
||||
"body": {
|
||||
"subtitle": "Inactive for {days}+ days",
|
||||
"listing": "{days} days"
|
||||
}
|
||||
},
|
||||
"full_stats": {
|
||||
"name": "estatísticas-completas",
|
||||
"description": "Estatísticas completas dentro do jogo",
|
||||
"body": {
|
||||
"cards": {
|
||||
"games": {
|
||||
"title": "Jogos",
|
||||
"winrate": "Taxa de vitória",
|
||||
"battles": "Batalhas",
|
||||
"wins_losses": "Vitórias / Derrotas"
|
||||
},
|
||||
"efficiency": {
|
||||
"title": "Eficiência",
|
||||
"wn8": "WN8",
|
||||
"survival": "Sobrevivência",
|
||||
"accuracy": "Precisão"
|
||||
},
|
||||
"lethality": {
|
||||
"title": "Letalidade",
|
||||
"average_damage": "Dano médio",
|
||||
"damage_per_tier": "Dano por nível",
|
||||
"damage_ratio": "Razão entre dano dado e recebido",
|
||||
"average_kills": "Média de abates"
|
||||
},
|
||||
"miscellaneous": {
|
||||
"title": "Diversos",
|
||||
"average_tier": "Nível médio",
|
||||
"average_spots": "Média de detecções",
|
||||
"average_xp": "EXP Médio",
|
||||
"kills_to_death_ratio": "Razão entre abates e mortes"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"link": {
|
||||
"name": "link",
|
||||
"description": "Conecte sua conta Blitz e Discord",
|
||||
"body": {
|
||||
"accounts_linked": "Contas vinculadas",
|
||||
"no_role_permissions": {
|
||||
"title": "{name} failed to verify",
|
||||
"description": "Eu não tenho permissão para gerenciar funções."
|
||||
}
|
||||
},
|
||||
"embed": {
|
||||
"title": "Conta incorreta?",
|
||||
"description": "Use o comando novamente e selecione um nome de usuário dos resultados da pesquisa."
|
||||
}
|
||||
},
|
||||
"search_clans": {
|
||||
"name": "procurar-clãs",
|
||||
"description": "Procurar clãs",
|
||||
"options": {
|
||||
"limit": {
|
||||
"name": "limite",
|
||||
"description": "The max number of clan results (default: {limit})"
|
||||
}
|
||||
},
|
||||
"body": {
|
||||
"title": "Clan search for {search} in region {region}",
|
||||
"no_results": "Nenhum clã encontrado"
|
||||
}
|
||||
},
|
||||
"search_players": {
|
||||
"name": "pesquisa-jogadores",
|
||||
"description": "Procurar jogadores",
|
||||
"options": {
|
||||
"limit": {
|
||||
"name": "limite",
|
||||
"description": "The max number of player results (default: {limit})"
|
||||
}
|
||||
},
|
||||
"body": {
|
||||
"title": "Player search for {search} in region {region}",
|
||||
"no_results": "Nenhum jogador encontrado"
|
||||
}
|
||||
},
|
||||
"rating_leaderboard": {
|
||||
"name": "classificação-tabela de classificação",
|
||||
"description": "Estatísticas de batalhas de classificação",
|
||||
"subcommands": {
|
||||
"neighbors": {
|
||||
"name": "vizinhos",
|
||||
"description": "Jogadores vizinhos na tabela de classificação"
|
||||
},
|
||||
"league": {
|
||||
"name": "Liga",
|
||||
"description": "Melhores jogadores de uma liga"
|
||||
}
|
||||
},
|
||||
"options": {
|
||||
"limit": {
|
||||
"name": "limite",
|
||||
"description": "How many neighbors to display (default: {count})"
|
||||
},
|
||||
"season": {
|
||||
"name": "temporada",
|
||||
"description": "Número da temporada (padrão: atual)",
|
||||
"choices": {
|
||||
"current": "{season} (current)"
|
||||
}
|
||||
},
|
||||
"league": {
|
||||
"name": "Liga",
|
||||
"description": "A liga para exibir"
|
||||
}
|
||||
},
|
||||
"body": {
|
||||
"top_players": "Top {count} players",
|
||||
"no_participation": "# {player} didn't play rating in season {season}\n\nThis player did not participate in this season or did not get past calibration.",
|
||||
"no_ongoing_season": "# Nenhuma temporada em andamento\n\nNão há uma temporada de classificação em execução no momento.",
|
||||
"deleted_player": "Deleted {id}",
|
||||
"neighbors": "Classificação de vizinhos",
|
||||
"more": "+ {count} more"
|
||||
}
|
||||
},
|
||||
"today": {
|
||||
"name": "hoje",
|
||||
"description": "Tanques jogados hoje e estatísticas"
|
||||
},
|
||||
"stats": {
|
||||
"name": "estatísticas",
|
||||
"description": "Estatísticas rápidas para um período"
|
||||
},
|
||||
"owned_tanks": {
|
||||
"name": "tanques-possuídos",
|
||||
"description": "Mostra todos os tanques possuídos em um nível",
|
||||
"body": {
|
||||
"title": "# {name}'s owned tier {tier} tanks\n\n"
|
||||
}
|
||||
},
|
||||
"permissions": {
|
||||
"name": "Permissões",
|
||||
"description": "Verifica se o bot tem as permissões necessárias para funcionar",
|
||||
"body": {
|
||||
"title": "# Permissions\n\n{body}",
|
||||
"view_channels": "Ver canais: necessário para encontrar a mensagem em que o botão atualizar foi usado",
|
||||
"read_message_history": "Histórico de mensagens lidas: necessário para encontrar a mensagem para atualizar",
|
||||
"attach_files": "Anexar arquivos: necessário para adicionar imagens a comandos baseados em imagens",
|
||||
"external_emojis": "Emojis externos: necessário para adicionar bandeiras nacionais e emojis de classe de tanque"
|
||||
}
|
||||
},
|
||||
"ping": {
|
||||
"name": "ping",
|
||||
"description": "Verifique se o bot está vivo.",
|
||||
"body": {
|
||||
"pong": "Pong 🏓",
|
||||
"pong_with_time": "Pong 🏓 - {time}ms"
|
||||
},
|
||||
"subcommands": {
|
||||
"blitzkit": {
|
||||
"name": "blitzkit",
|
||||
"description": "Ping BlitzKit"
|
||||
},
|
||||
"wotb": {
|
||||
"name": "wotb",
|
||||
"description": "Ping World of Tanks Blitz"
|
||||
}
|
||||
}
|
||||
},
|
||||
"player_info": {
|
||||
"name": "informação do jogador",
|
||||
"description": "Informações básicas sobre um jogador",
|
||||
"body": {
|
||||
"title": "{name}'s information",
|
||||
"nickname": "Apelido",
|
||||
"battles": "Batalhas",
|
||||
"winrate": "Taxa de vitória",
|
||||
"account_id": "ID da conta",
|
||||
"created": "Criado",
|
||||
"last_battle": "Última batalha"
|
||||
}
|
||||
},
|
||||
"rating": {
|
||||
"name": "classificação",
|
||||
"description": "Estatísticas de jogador de classificação",
|
||||
"subcommands": {
|
||||
"today": {
|
||||
"name": "hoje",
|
||||
"description": "Estatísticas de classificação hoje"
|
||||
},
|
||||
"season": {
|
||||
"name": "temporada",
|
||||
"description": "Estatísticas de classificação desta temporada"
|
||||
}
|
||||
},
|
||||
"body": {
|
||||
"subtitle": {
|
||||
"today": "Estatísticas de classificação hoje",
|
||||
"season": "Estatísticas de classificação desta temporada"
|
||||
}
|
||||
},
|
||||
"errors": {
|
||||
"no_participation": "# {name} hasn't played rating\n\nThis player hasn't participated in the rating gamemode this season.",
|
||||
"unrecorded_stats": "# Estatísticas atualmente indisponível\n\nWargaming pode estar no momento, enfrentando tempo de inatividade do servidor. Se houver uma temporada em curso, as estatísticas deverão ser disponibilizadas dentro de 24 horas."
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"website": {
|
||||
"redirect": {
|
||||
"title": "301: moved permanently",
|
||||
@@ -734,14 +281,6 @@
|
||||
}
|
||||
},
|
||||
"home": {
|
||||
"pwa": {
|
||||
"title": "Install the BlitzKit App",
|
||||
"new": "NEW",
|
||||
"checking": "Checking compatibility...",
|
||||
"instructions": "Instructions for Apple devices.",
|
||||
"install": "Install",
|
||||
"dismiss": "Dismiss"
|
||||
},
|
||||
"discord": {
|
||||
"join_short": "Join cool people!",
|
||||
"join_long": "Join super duper cool people!",
|
||||
@@ -953,6 +492,7 @@
|
||||
"tier": "Nível",
|
||||
"type": "Tipo",
|
||||
"dev_id": "DEV: ID",
|
||||
"dev_name": "DEV: NAME",
|
||||
"purchase": "Preço de compra",
|
||||
"restoration": "Preço de recuperação",
|
||||
"sale": "Preço de venda",
|
||||
@@ -973,6 +513,11 @@
|
||||
},
|
||||
"configuration": {
|
||||
"title": "Configuração",
|
||||
"equalizer": {
|
||||
"title": "Equalizer",
|
||||
"equalize": "Equalize",
|
||||
"beta": "Beta"
|
||||
},
|
||||
"modules": {
|
||||
"title": "Módulos",
|
||||
"stock": "Padrão",
|
||||
@@ -1005,8 +550,8 @@
|
||||
"title": "Características",
|
||||
"compare": {
|
||||
"label": "Comparar com",
|
||||
"class": "Tier {tier} {class}",
|
||||
"tier": "All of tier {tier}",
|
||||
"class": "{tier} {class}",
|
||||
"tier": "All tier {tier}",
|
||||
"all": "Todos os tanques"
|
||||
},
|
||||
"values": {
|
||||
@@ -1142,7 +687,8 @@
|
||||
},
|
||||
"skills": {
|
||||
"clear": "Limpar",
|
||||
"maximize": "Maximizar"
|
||||
"maximize": "Maximizar",
|
||||
"equalize": "Equalize"
|
||||
},
|
||||
"modules": {
|
||||
"stock": "Padrão",
|
||||
|
||||
+16
-470
@@ -37,10 +37,11 @@
|
||||
"d_1": "Вчера"
|
||||
},
|
||||
"branches": {
|
||||
"local": "dev",
|
||||
"dev": "бета",
|
||||
"opentest": "общий тест",
|
||||
"preview": "превью"
|
||||
"beta": "Бета",
|
||||
"development": "Development",
|
||||
"opentest": "Открытый тест",
|
||||
"preview": "Preview",
|
||||
"production": "Production"
|
||||
},
|
||||
"locales": {
|
||||
"en": "Английский",
|
||||
@@ -139,7 +140,7 @@
|
||||
}
|
||||
},
|
||||
"leagues": {
|
||||
"diamond": "Диамантовая",
|
||||
"diamond": "Алмазная",
|
||||
"platinum": "Платиновая",
|
||||
"gold": "Золотая",
|
||||
"silver": "Серебряная",
|
||||
@@ -184,460 +185,6 @@
|
||||
"cumulative_battle_life_time": "Общее время в боях"
|
||||
}
|
||||
},
|
||||
"bot": {
|
||||
"common": {
|
||||
"errors": {
|
||||
"clan_not_found": "# Не удалось найти клан\nНе найден «{search}». Попробуйте выбрать клан из результатов поиска.",
|
||||
"player_not_found": "# Не удалось найти пользователя\nНе удалось найти пользователя «{search}». Попробуйте выбрать пользователя из результатов поиска, введя правильное имя пользователя или используя команду «/link».",
|
||||
"player_not_linked": "# Используйте «/link», чтобы начать\nЯ не знаю, кто ты, но давай познакомимся сегодня!",
|
||||
"tank_name_not_found": "# Танк не найден\nНе удалось найти танк с названием «{search}».",
|
||||
"tank_id_not_found": "# Танк не найден\nНе удалось найти танк с ID «{search}». Попробуйте ввести название танка вместо числа.",
|
||||
"no_tank_stats": "# Статистика танка недоступна\nУ этого игрока нет доступной статистики. Возможно, это не тот игрок, которого вы ищете.",
|
||||
"get_help": "Получить помощь",
|
||||
"uncaught_error": "# BlitzKit столкнулся с ошибкой!\nНам очень жаль. Не стесняйтесь и [присоединяйтесь к официальному серверу Discord](https://discord.gg/nDt7AjGJQH), чтобы получить помощь.",
|
||||
"preview": "# Эта команда находится в тестируется\n\nВы можете получить доступ к этой команде только на [официальном сервере Discord] (https://discord.gg/nDt7AjGJQH). Команда скоро станет общедоступной.",
|
||||
"query_too_small": "# Ваш поисковой запрос слишком короткий\nДлина вашего запроса должна составлять не менее 3 символов.",
|
||||
"query_too_long": "# Ваш поисковой запрос слишком длинный\nДлина вашего запроса должна составлять не более 100 символов."
|
||||
},
|
||||
"wn8": {
|
||||
"name": "WN8",
|
||||
"types": {
|
||||
"very_bad": "Очень плохо",
|
||||
"bad": "Плохо",
|
||||
"below_average": "Ниже среднего",
|
||||
"average": "Средне",
|
||||
"above_average": "Выше среднего",
|
||||
"good": "Хорошо",
|
||||
"very_good": "Очень хорошо",
|
||||
"great": "Отлично",
|
||||
"unicum": "Уникально",
|
||||
"super_unicum": "Крайне уникально"
|
||||
}
|
||||
},
|
||||
"subcommands": {
|
||||
"today": {
|
||||
"name": "cегодня",
|
||||
"description": "Cегодня"
|
||||
},
|
||||
"30": {
|
||||
"name": "30",
|
||||
"description": "30 дней"
|
||||
},
|
||||
"60": {
|
||||
"name": "60",
|
||||
"description": "60 дней"
|
||||
},
|
||||
"90": {
|
||||
"name": "90",
|
||||
"description": "90 дней"
|
||||
},
|
||||
"career": {
|
||||
"name": "карьера",
|
||||
"description": "Карьера"
|
||||
},
|
||||
"custom": {
|
||||
"name": "пользовательский",
|
||||
"description": "Собственный диапазон",
|
||||
"options": {
|
||||
"start": {
|
||||
"name": "начать",
|
||||
"description": "Начать через N дней с сегодняшнего дня"
|
||||
},
|
||||
"end": {
|
||||
"name": "конец",
|
||||
"description": "Закончить через N дней с сегодняшнего дня"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"options": {
|
||||
"clan": {
|
||||
"name": "клан",
|
||||
"description": "Название или тег клана"
|
||||
},
|
||||
"tank": {
|
||||
"name": "танк",
|
||||
"description": "Танк для получения статистики для"
|
||||
},
|
||||
"username": {
|
||||
"name": "ник",
|
||||
"description": "Ник игрока в Blitz"
|
||||
},
|
||||
"filters": {
|
||||
"nation": {
|
||||
"name": "нация",
|
||||
"description": "Нация"
|
||||
},
|
||||
"class": {
|
||||
"name": "класс",
|
||||
"description": "Класс"
|
||||
},
|
||||
"type": {
|
||||
"name": "тип",
|
||||
"description": "Тип"
|
||||
}
|
||||
},
|
||||
"region": {
|
||||
"name": "регион",
|
||||
"description": "Регион"
|
||||
},
|
||||
"tier": {
|
||||
"name": "уровень",
|
||||
"description": "Уровень",
|
||||
"choices": {
|
||||
"tier": "Уровень {tier_1} - {tier_2}"
|
||||
}
|
||||
}
|
||||
},
|
||||
"periods": {
|
||||
"career": "Карьера",
|
||||
"today": "Cегодня",
|
||||
"days": "{days} дней",
|
||||
"custom": "{day_1} - {day_2} дней"
|
||||
},
|
||||
"filters": {
|
||||
"none": "Без фильтров",
|
||||
"tier": "{tier} уровень"
|
||||
},
|
||||
"no_data": {
|
||||
"battles_in_period": "За этот период боёв не было",
|
||||
"battles_in_season": "За этот сезон боёв не было",
|
||||
"players_in_period": "Нет игроков за этот период",
|
||||
"tanks_found": "Танки не найдены"
|
||||
},
|
||||
"buttons": {
|
||||
"refresh": "Обновить"
|
||||
},
|
||||
"hero_stats": {
|
||||
"battles": "Боёв",
|
||||
"winrate": "Коэффициент побед",
|
||||
"damage": "Урон",
|
||||
"damage_ratio": "Коэффициент урона",
|
||||
"tier": "Уровень",
|
||||
"survival": "Выживание",
|
||||
"accuracy": "Точность стрельбы",
|
||||
"kills": "Уничтожил"
|
||||
}
|
||||
},
|
||||
"commands": {
|
||||
"replay": {
|
||||
"name": "повтор",
|
||||
"description": "Показать результаты повтора"
|
||||
},
|
||||
"research": {
|
||||
"name": "исследование",
|
||||
"description": "Список ресурсов для исследования ветки",
|
||||
"options": {
|
||||
"target_tank": {
|
||||
"name": "желаемый танк",
|
||||
"description": "Желаемый танк ветки исследования"
|
||||
},
|
||||
"starting_tank": {
|
||||
"name": "стартовый-танк",
|
||||
"description": "Стартовый танк в ветке (назначен автоматически, если не установлен)"
|
||||
}
|
||||
},
|
||||
"body": {
|
||||
"subtitle": "Исследование",
|
||||
"total": "Всего",
|
||||
"research": "Исследование: {cost}",
|
||||
"upgrades": "Улучшения: {cost}",
|
||||
"purchase": "Покупка: {cost}",
|
||||
"equipment": "Снаряжение: {cost}",
|
||||
"estimation": "# Это приблизительная оценка!\n\nВ этот список могут входить уже исследованные танки из-за неточной информации, предоставляемой Wargaming. Попробуйте указать «стартовый-танк» в строке при использовании команды, если сможете."
|
||||
},
|
||||
"errors": {
|
||||
"non_tech_tree": "# {tank} отсутствует в дереве танков\n\nВы не можете исследовать премиумный / коллекционный танк.",
|
||||
"tier_1": "# {tank} — танк I уровня\n\nУровень I всегда открыт бесплатно для всех игроков.",
|
||||
"already_researched": "# {tank} уже исследован\n\nПопробуйте предоставить «starting-tank» при использовании команды для просмотра итогов уже исследованной ветки.",
|
||||
"start_end_equal": "# {tank} был предоставлен дважды\n\nУбедитесь, что «starting-tank» и «target-tank» различаются.",
|
||||
"tanks_not_on_line": "# {tank_1} и {tank_2} находятся не в одной ветке\n\nУбедитесь, что «starting-tank» и «target-tank» находятся на той же ветке дерева танков.",
|
||||
"unordered": "# У {tank_1} более высокий уровень чем у {tank_2}\n\nОбязательно укажите {tank_2} в качестве «starting-tank», так как это танк более низкого уровня."
|
||||
}
|
||||
},
|
||||
"about": {
|
||||
"name": "о-боте",
|
||||
"description": "Вся необходимая информация о боте",
|
||||
"subcommands": {
|
||||
"commands": {
|
||||
"name": "команды",
|
||||
"description": "Список всех команд и их описаний",
|
||||
"body": "# Команды\n\nBlitzKit предлагает следующие команды:\n\n"
|
||||
},
|
||||
"embeds": {
|
||||
"name": "встраиваемые-элементы",
|
||||
"description": "Как работают встраиваемые элементы"
|
||||
},
|
||||
"introduction": {
|
||||
"name": "введение",
|
||||
"description": "О боте"
|
||||
},
|
||||
"invite": {
|
||||
"name": "пригласить",
|
||||
"description": "Как пригласить бота"
|
||||
},
|
||||
"timezones": {
|
||||
"name": "часовой-пояс",
|
||||
"description": "Как BlitzKit определяет и использует ваш часовой пояс"
|
||||
},
|
||||
"credits": {
|
||||
"name": "авторы",
|
||||
"description": "Люди, которые помогли BlitzKit"
|
||||
}
|
||||
}
|
||||
},
|
||||
"breakdown": {
|
||||
"name": "распределение",
|
||||
"description": "Статистика игр за период с распределением по танкам",
|
||||
"body": {
|
||||
"total": "Всего",
|
||||
"battles": "Боёв",
|
||||
"wn8": "WN8",
|
||||
"winrate": "Коэффициент побед",
|
||||
"damage": "Урон",
|
||||
"unknown_tank": "Неизвестный танк {id}"
|
||||
}
|
||||
},
|
||||
"debug": {
|
||||
"name": "отладка",
|
||||
"description": "Сведения для отладки",
|
||||
"body": {
|
||||
"title": "# Отладка",
|
||||
"version": "Версия",
|
||||
"shard": {
|
||||
"label": "Фрагмент",
|
||||
"default": "по умолчанию"
|
||||
},
|
||||
"uptime": "Время работы"
|
||||
}
|
||||
},
|
||||
"evolution": {
|
||||
"name": "изменения",
|
||||
"description": "Изменения статистики",
|
||||
"groups": {
|
||||
"player": {
|
||||
"name": "игрок",
|
||||
"description": "Статистика игрока"
|
||||
},
|
||||
"tank": {
|
||||
"name": "танк",
|
||||
"description": "Статистика танков"
|
||||
}
|
||||
}
|
||||
},
|
||||
"inactive": {
|
||||
"name": "неактивно",
|
||||
"description": "Список всех неактивных игроков в клане выше порога",
|
||||
"options": {
|
||||
"threshold": {
|
||||
"name": "порог",
|
||||
"description": "Количество дней не активности (по умолчанию: {days} дней)"
|
||||
}
|
||||
},
|
||||
"body": {
|
||||
"subtitle": "Неактивен {days}+ дней",
|
||||
"listing": "{days} дней"
|
||||
}
|
||||
},
|
||||
"full_stats": {
|
||||
"name": "полная-статистика",
|
||||
"description": "Полная игровая статистика",
|
||||
"body": {
|
||||
"cards": {
|
||||
"games": {
|
||||
"title": "Игры",
|
||||
"winrate": "Коэффициент побед",
|
||||
"battles": "Боёв",
|
||||
"wins_losses": "Побед / поражений"
|
||||
},
|
||||
"efficiency": {
|
||||
"title": "Эффективность",
|
||||
"wn8": "WN8",
|
||||
"survival": "Выжил",
|
||||
"accuracy": "Точность стрельбы"
|
||||
},
|
||||
"lethality": {
|
||||
"title": "Смертность",
|
||||
"average_damage": "Средний урон",
|
||||
"damage_per_tier": "Урон по уровню",
|
||||
"damage_ratio": "Коэффициент урона",
|
||||
"average_kills": "Среднее число уничтоженных"
|
||||
},
|
||||
"miscellaneous": {
|
||||
"title": "Прочее",
|
||||
"average_tier": "Средний уровень",
|
||||
"average_spots": "Среднее число попаданий",
|
||||
"average_xp": "Средний опыт",
|
||||
"kills_to_death_ratio": "Коэффициент убийств и смертей"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"link": {
|
||||
"name": "ссылка",
|
||||
"description": "Привяжите учётную запись Blitz и Discord",
|
||||
"body": {
|
||||
"accounts_linked": "Аккаунты привязаны",
|
||||
"no_role_permissions": {
|
||||
"title": "{name} не удалось проверить",
|
||||
"description": "У меня нет разрешения на управление ролями."
|
||||
}
|
||||
},
|
||||
"embed": {
|
||||
"title": "Неверный аккаунт?",
|
||||
"description": "Используйте команду снова и выберите имя пользователя из результатов поиска."
|
||||
}
|
||||
},
|
||||
"search_clans": {
|
||||
"name": "поиск-кланов",
|
||||
"description": "Поиск кланов",
|
||||
"options": {
|
||||
"limit": {
|
||||
"name": "лимит",
|
||||
"description": "Максимальное количество результатов клана (по умолчанию: {limit})"
|
||||
}
|
||||
},
|
||||
"body": {
|
||||
"title": "Поиск клана {search} в регионе {region}",
|
||||
"no_results": "Кланов не найдено"
|
||||
}
|
||||
},
|
||||
"search_players": {
|
||||
"name": "поиск-игроков",
|
||||
"description": "Поиск игроков",
|
||||
"options": {
|
||||
"limit": {
|
||||
"name": "лимит",
|
||||
"description": "Максимальное число результатов игрока (по умолчанию: {limit})"
|
||||
}
|
||||
},
|
||||
"body": {
|
||||
"title": "Поиск игрока {search} в регионе {region}",
|
||||
"no_results": "Игроков не найдено"
|
||||
}
|
||||
},
|
||||
"rating_leaderboard": {
|
||||
"name": "таблица-лидеров",
|
||||
"description": "Статистика рейтингов боёв",
|
||||
"subcommands": {
|
||||
"neighbors": {
|
||||
"name": "ближайшие",
|
||||
"description": "Ближайшие игроки в таблице лидеров"
|
||||
},
|
||||
"league": {
|
||||
"name": "лига",
|
||||
"description": "Топ игроков лиги"
|
||||
}
|
||||
},
|
||||
"options": {
|
||||
"limit": {
|
||||
"name": "лимит",
|
||||
"description": "Количество отображаемых ближайших игроков (по умолчанию: {count})"
|
||||
},
|
||||
"season": {
|
||||
"name": "сезон",
|
||||
"description": "Номер сезона (по умолчанию: текущий)",
|
||||
"choices": {
|
||||
"current": "{season} (текущий)"
|
||||
}
|
||||
},
|
||||
"league": {
|
||||
"name": "лига",
|
||||
"description": "Отображаемая лига"
|
||||
}
|
||||
},
|
||||
"body": {
|
||||
"top_players": "Топ {count} игроков",
|
||||
"no_participation": "# {player} не играл в рейтинг в сезоне {season}\n\nЭтот игрок не участвовал в этом сезоне или не получил прошлую калибровку.",
|
||||
"no_ongoing_season": "# Нет текущего сезона\n\nВ данный момент нет рейтингового сезона.",
|
||||
"deleted_player": "Удаленный {id}",
|
||||
"neighbors": "Рейтинг ближайших игроков",
|
||||
"more": "+ ещё {count}"
|
||||
}
|
||||
},
|
||||
"today": {
|
||||
"name": "cегодня",
|
||||
"description": "Танки, на которых сыграли сегодня и статистика"
|
||||
},
|
||||
"stats": {
|
||||
"name": "статистика",
|
||||
"description": "Быстрая статистика за период"
|
||||
},
|
||||
"owned_tanks": {
|
||||
"name": "cобственные-танки",
|
||||
"description": "Показывает все принадлежащие танки на уровне",
|
||||
"body": {
|
||||
"title": "# {name} принадлежат танки {tier} уровня\n\n"
|
||||
}
|
||||
},
|
||||
"permissions": {
|
||||
"name": "разрешения",
|
||||
"description": "Проверяет, есть ли у бота необходимые разрешения для работы",
|
||||
"body": {
|
||||
"title": "# Разрешения\n\n{body}",
|
||||
"view_channels": "Просмотр каналов: необходимо найти сообщение, на котором была использована кнопка обновления",
|
||||
"read_message_history": "Просмотр истории сообщений: необходимо найти сообщение для обновления",
|
||||
"attach_files": "Прикрепить файлы: необходимо для добавления изображений в команды на основе изображения",
|
||||
"external_emojis": "Внешние эмоции: необходимы для добавления национальных флагов и эмодзи класса танков"
|
||||
}
|
||||
},
|
||||
"ping": {
|
||||
"name": "пинг",
|
||||
"description": "Проверьте, что бот жив.",
|
||||
"body": {
|
||||
"pong": "Понг 🏓",
|
||||
"pong_with_time": "Понг 🏓 — {time}мс"
|
||||
},
|
||||
"subcommands": {
|
||||
"blitzkit": {
|
||||
"name": "blitzkit",
|
||||
"description": "Пинг BlitzKit"
|
||||
},
|
||||
"wotb": {
|
||||
"name": "wotb",
|
||||
"description": "Пинг World of Tanks Blitz"
|
||||
}
|
||||
}
|
||||
},
|
||||
"player_info": {
|
||||
"name": "информация-об-игроке",
|
||||
"description": "Основная информация о игроке",
|
||||
"body": {
|
||||
"title": "Информация о {name}",
|
||||
"nickname": "Никнейм",
|
||||
"battles": "Боёв",
|
||||
"winrate": "Коэффициент побед",
|
||||
"account_id": "ID учётной записи",
|
||||
"created": "Создано",
|
||||
"last_battle": "Последний бой"
|
||||
}
|
||||
},
|
||||
"rating": {
|
||||
"name": "рейтинг",
|
||||
"description": "Статистика рейтинга игрока",
|
||||
"subcommands": {
|
||||
"today": {
|
||||
"name": "cегодня",
|
||||
"description": "Статистика рейтинга за сегодня"
|
||||
},
|
||||
"season": {
|
||||
"name": "сезон",
|
||||
"description": "Статистика рейтинга в этом сезоне"
|
||||
}
|
||||
},
|
||||
"body": {
|
||||
"subtitle": {
|
||||
"today": "Статистика рейтинга за сегодня",
|
||||
"season": "Статистика рейтинга в этом сезоне"
|
||||
}
|
||||
},
|
||||
"errors": {
|
||||
"no_participation": "# {name} не получил рейтинга\n\nЭтот игрок в этом сезоне не участвовал в рейтинговом режиме.",
|
||||
"unrecorded_stats": "# Статистика недоступна в настоящее время\n\nВ настоящее время Wargaming, возможно, сталкивается с простоями сервера. Если сезон продолжается, статистика должна быть доступна в течение 24 часов."
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"website": {
|
||||
"redirect": {
|
||||
"title": "301: перемещено навсегда",
|
||||
@@ -734,14 +281,6 @@
|
||||
}
|
||||
},
|
||||
"home": {
|
||||
"pwa": {
|
||||
"title": "Установите приложение BlitzKit",
|
||||
"new": "НОВИНКА",
|
||||
"checking": "Проверка совместимости...",
|
||||
"instructions": "Инструкция для устройств Apple.",
|
||||
"install": "Установка",
|
||||
"dismiss": "Отклонить"
|
||||
},
|
||||
"discord": {
|
||||
"join_short": "Присоединяйтесь к крутым ребятам!",
|
||||
"join_long": "Присоединяйся к супер-дупер крутым ребятам!",
|
||||
@@ -817,7 +356,7 @@
|
||||
"skip": "Пропустить",
|
||||
"guess": "Угадать",
|
||||
"next": "Следующий",
|
||||
"no_results": "Ничего не найденo"
|
||||
"no_results": "Ничего не найдено"
|
||||
},
|
||||
"stats": "{correct} / {total} правильно, серия: {streak}",
|
||||
"help": {
|
||||
@@ -953,6 +492,7 @@
|
||||
"tier": "Уровень",
|
||||
"type": "Тип",
|
||||
"dev_id": "DEV: ID",
|
||||
"dev_name": "DEV: NAME",
|
||||
"purchase": "Цена покупки",
|
||||
"restoration": "Цена восстановления",
|
||||
"sale": "Цена продажи",
|
||||
@@ -973,6 +513,11 @@
|
||||
},
|
||||
"configuration": {
|
||||
"title": "Конфигурация",
|
||||
"equalizer": {
|
||||
"title": "Уравнение",
|
||||
"equalize": "Уравнять",
|
||||
"beta": "Бета"
|
||||
},
|
||||
"modules": {
|
||||
"title": "Модули",
|
||||
"stock": "Сток",
|
||||
@@ -1005,7 +550,7 @@
|
||||
"title": "Характеристики",
|
||||
"compare": {
|
||||
"label": "Сравнивать с",
|
||||
"class": "{class} {tier} уровня",
|
||||
"class": "{tier} {class}",
|
||||
"tier": "Все {tier} уровня",
|
||||
"all": "Все танки"
|
||||
},
|
||||
@@ -1142,7 +687,8 @@
|
||||
},
|
||||
"skills": {
|
||||
"clear": "Очистить",
|
||||
"maximize": "Максимум"
|
||||
"maximize": "Максимум",
|
||||
"equalize": "Уравнять"
|
||||
},
|
||||
"modules": {
|
||||
"stock": "Сток",
|
||||
|
||||
+68
-522
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"test": {
|
||||
"default": "тест",
|
||||
"long": "{fruit}",
|
||||
"long": "{color}{fruit}",
|
||||
"fox": "Швидка бура лисиця перестрибує через лінивого собаку."
|
||||
},
|
||||
"common": {
|
||||
@@ -23,7 +23,7 @@
|
||||
},
|
||||
"shells": {
|
||||
"ap": "ББ",
|
||||
"ap_cr": "APCR",
|
||||
"ap_cr": "",
|
||||
"hc": "HEAT",
|
||||
"he": "ОФ"
|
||||
},
|
||||
@@ -37,10 +37,11 @@
|
||||
"d_1": "Вчора"
|
||||
},
|
||||
"branches": {
|
||||
"local": "розробник",
|
||||
"dev": "бета",
|
||||
"opentest": "відкритий тест",
|
||||
"preview": "попередній перегляд"
|
||||
"beta": "Beta",
|
||||
"development": "Development",
|
||||
"opentest": "Відкритий тест",
|
||||
"preview": "Preview",
|
||||
"production": "Production"
|
||||
},
|
||||
"locales": {
|
||||
"en": "Англійська",
|
||||
@@ -184,460 +185,6 @@
|
||||
"cumulative_battle_life_time": "Загальний час бою"
|
||||
}
|
||||
},
|
||||
"bot": {
|
||||
"common": {
|
||||
"errors": {
|
||||
"clan_not_found": "# Не вдалося знайти клан\nНе вдалося знайти \"{search}\". Спробуйте обрати клан з результату пошуку.",
|
||||
"player_not_found": "# Не вдалося знайти користувача\nНе вдалося знайти користувача \"{search}\". Спробуйте вибрати користувача із результатів пошуку, ввівши правильне ім'я користувача, або скористайтеся командою `/link`.",
|
||||
"player_not_linked": "# Використайте команду \"/link\" щоб почати\nЯ не знаю, хто ви, але ви можете сказати мені сьогодні!",
|
||||
"tank_name_not_found": "# Танк не знайдено\nНе вдалося знайти танк із назвою «{search}».",
|
||||
"tank_id_not_found": "# Танк не знайдено\nНе вдалося знайти танк з ID «{search}». Спробуйте ввести назву танка замість номера.",
|
||||
"no_tank_stats": "# Немає статистики для танка\nЦей гравець не має статистики.\nМожливо, це не той гравець, якого ви шукаєте.",
|
||||
"get_help": "Допомогти Discord серверу",
|
||||
"uncaught_error": "# Упс! BlitzKit зіткнувся з помилкою!\nНам дуже шкода. Можете попросити допомоги на [офіційному сервері Discord](https://discord.gg/nDt7AjGJQH).",
|
||||
"preview": "# Ця команда є в попередньому перегляді\n\nВи можете отримати доступ лише до цієї команди на [офіційному сервері Discord](https://discord.gg/nDt7AjGJQH). Команда в цілому буде доступна найближчим часом.",
|
||||
"query_too_small": "# Ваш пошук занадто короткий\nВаш пошук повинен бути щонайменше 3 символи.",
|
||||
"query_too_long": "# Ваш пошук занадто довгий\nВаш пошук повинен бути щонайбільше 100 символи."
|
||||
},
|
||||
"wn8": {
|
||||
"name": "WN8",
|
||||
"types": {
|
||||
"very_bad": "Дуже погано",
|
||||
"bad": "Погано",
|
||||
"below_average": "Нижче середнього",
|
||||
"average": "Середнє",
|
||||
"above_average": "Вище середнього",
|
||||
"good": "Добре",
|
||||
"very_good": "Дуже добре",
|
||||
"great": "Відмінно",
|
||||
"unicum": "Винятковий",
|
||||
"super_unicum": "Супер винятковий"
|
||||
}
|
||||
},
|
||||
"subcommands": {
|
||||
"today": {
|
||||
"name": "сьогодні",
|
||||
"description": "Сьогодні"
|
||||
},
|
||||
"30": {
|
||||
"name": "30",
|
||||
"description": "30 днів"
|
||||
},
|
||||
"60": {
|
||||
"name": "60",
|
||||
"description": "60 днів"
|
||||
},
|
||||
"90": {
|
||||
"name": "90",
|
||||
"description": "90 днів"
|
||||
},
|
||||
"career": {
|
||||
"name": "кар'єра",
|
||||
"description": "Кар'єра"
|
||||
},
|
||||
"custom": {
|
||||
"name": "користувацьке",
|
||||
"description": "Власний діапазон",
|
||||
"options": {
|
||||
"start": {
|
||||
"name": "почати",
|
||||
"description": "Початок за кількістю днів тому від сьогодні"
|
||||
},
|
||||
"end": {
|
||||
"name": "кінець",
|
||||
"description": "Кінець за кількістю днів тому від сьогодні"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"options": {
|
||||
"clan": {
|
||||
"name": "клан",
|
||||
"description": "Назва клану або тег"
|
||||
},
|
||||
"tank": {
|
||||
"name": "танк",
|
||||
"description": "Танк для якого треба отримати статистику"
|
||||
},
|
||||
"username": {
|
||||
"name": "ім'я користувача",
|
||||
"description": "Бліц ім'я гравця"
|
||||
},
|
||||
"filters": {
|
||||
"nation": {
|
||||
"name": "нація",
|
||||
"description": "Нація"
|
||||
},
|
||||
"class": {
|
||||
"name": "клас",
|
||||
"description": "Клас"
|
||||
},
|
||||
"type": {
|
||||
"name": "вид",
|
||||
"description": "Вид"
|
||||
}
|
||||
},
|
||||
"region": {
|
||||
"name": "регіон",
|
||||
"description": "Регіон"
|
||||
},
|
||||
"tier": {
|
||||
"name": "рівень",
|
||||
"description": "Рівень",
|
||||
"choices": {
|
||||
"tier": "Рівень {tier_1} - {tier_2}"
|
||||
}
|
||||
}
|
||||
},
|
||||
"periods": {
|
||||
"career": "Кар'єра",
|
||||
"today": "Сьогодні",
|
||||
"days": "{days} днів",
|
||||
"custom": "{day_1} - {day_2} днів"
|
||||
},
|
||||
"filters": {
|
||||
"none": "Немає фільтрів",
|
||||
"tier": "Рівень {tier}"
|
||||
},
|
||||
"no_data": {
|
||||
"battles_in_period": "За цей період боїв не було",
|
||||
"battles_in_season": "У цьому сезоні боїв не було",
|
||||
"players_in_period": "Немає гравців за цей період",
|
||||
"tanks_found": "Жодних танків не знайдено"
|
||||
},
|
||||
"buttons": {
|
||||
"refresh": "Оновити"
|
||||
},
|
||||
"hero_stats": {
|
||||
"battles": "Бої",
|
||||
"winrate": "Відсоток перемог",
|
||||
"damage": "Шкода",
|
||||
"damage_ratio": "Коефіцієнт шкоди",
|
||||
"tier": "Рівень",
|
||||
"survival": "Виживання",
|
||||
"accuracy": "Точність",
|
||||
"kills": "Знищено"
|
||||
}
|
||||
},
|
||||
"commands": {
|
||||
"replay": {
|
||||
"name": "реплей",
|
||||
"description": "Показати результати реплею"
|
||||
},
|
||||
"research": {
|
||||
"name": "дослідження",
|
||||
"description": "Показує витрати в дослідженні гілки",
|
||||
"options": {
|
||||
"target_tank": {
|
||||
"name": "цільовий танк",
|
||||
"description": "Останній танк для дослідження в гілці"
|
||||
},
|
||||
"starting_tank": {
|
||||
"name": "початковий танк",
|
||||
"description": "Початковий танк в гілці (виводиться автоматично, якщо не передбачено)"
|
||||
}
|
||||
},
|
||||
"body": {
|
||||
"subtitle": "Дослідження",
|
||||
"total": "Загалом",
|
||||
"research": "Дослідження: {cost}",
|
||||
"upgrades": "Прокачування: {cost}",
|
||||
"purchase": "Вартість: {cost}",
|
||||
"equipment": "Спорядження: {cost}",
|
||||
"estimation": "# Це оцінка!\n\nЦей список може включати вже досліджені танки через неточну інформацію для вантажу. Спробуйте використати \"початковий танк\" з рядка за допомогою команди."
|
||||
},
|
||||
"errors": {
|
||||
"non_tech_tree": "#{tank} відсутній в дереві дослідження\n\nВи не можете дослідити преміум/колеційний танк.",
|
||||
"tier_1": "#{tank} І рівня \n\nТанки І рівня завжди розблоковані для всіх гравців безкоштовно",
|
||||
"already_researched": "# {tank} вже було досліджено\n\nСпробуйте використати `початковий-танк` коли використовуєте команду для перегляду загальної гілки, яку ви вже дослідили",
|
||||
"start_end_equal": "#{tank} було введено двічі \n\nПереконайтесь що `початковий-танк` та `ціль-танк` різні",
|
||||
"tanks_not_on_line": "# {tank_1} та {tank_2} не в одній гілці\n\nПереконайтесь що `початковий-танк` та `ціль-танк` знаходяться в єдиній гілці дерева дослідження",
|
||||
"unordered": "# {tank_1} вище рівнем відносно {tank_2}\n\nОбов’язково вкажіть {tank_2} як `початковий-танк`, оскільки це танк нижчого рівня."
|
||||
}
|
||||
},
|
||||
"about": {
|
||||
"name": "про бота",
|
||||
"description": "Вся інформація про бота",
|
||||
"subcommands": {
|
||||
"commands": {
|
||||
"name": "команди",
|
||||
"description": "Список всіх команд та їх описів",
|
||||
"body": "# Команди\n\nBlitzKit пропонує наступні команди:\n\n"
|
||||
},
|
||||
"embeds": {
|
||||
"name": "вкладення",
|
||||
"description": "Як працюють вкладення"
|
||||
},
|
||||
"introduction": {
|
||||
"name": "ознайомлення",
|
||||
"description": "Про бота"
|
||||
},
|
||||
"invite": {
|
||||
"name": "запрошення",
|
||||
"description": "Як запросити бота"
|
||||
},
|
||||
"timezones": {
|
||||
"name": "часові пояси",
|
||||
"description": "Як BlitzKit отримує інформацію про час і використовує ваш часовий пояс"
|
||||
},
|
||||
"credits": {
|
||||
"name": "кредити",
|
||||
"description": "Люди, які допомогли BlitzKit"
|
||||
}
|
||||
}
|
||||
},
|
||||
"breakdown": {
|
||||
"name": "аналіз",
|
||||
"description": "Аналіз періоду за зіграними танками",
|
||||
"body": {
|
||||
"total": "Загалом",
|
||||
"battles": "Бої",
|
||||
"wn8": "WN8",
|
||||
"winrate": "Відсоток перемог",
|
||||
"damage": "Шкода",
|
||||
"unknown_tank": "Невідомий танк {id}"
|
||||
}
|
||||
},
|
||||
"debug": {
|
||||
"name": "налагодження",
|
||||
"description": "Інформація про налагодження бота",
|
||||
"body": {
|
||||
"title": "# Налагодження\n\n",
|
||||
"version": "Версія",
|
||||
"shard": {
|
||||
"label": "Уламок",
|
||||
"default": "за замовчуванням"
|
||||
},
|
||||
"uptime": "Час роботи"
|
||||
}
|
||||
},
|
||||
"evolution": {
|
||||
"name": "еволюція",
|
||||
"description": "Еволюція статистики",
|
||||
"groups": {
|
||||
"player": {
|
||||
"name": "гравець",
|
||||
"description": "Статистика гравця"
|
||||
},
|
||||
"tank": {
|
||||
"name": "танк",
|
||||
"description": "Статистика танків"
|
||||
}
|
||||
}
|
||||
},
|
||||
"inactive": {
|
||||
"name": "неактивний",
|
||||
"description": "Відображає всіх неактивних гравців у клані вище порогу",
|
||||
"options": {
|
||||
"threshold": {
|
||||
"name": "поріг",
|
||||
"description": "Кількість днів неактивності (за замовчуванням: {days} днів)"
|
||||
}
|
||||
},
|
||||
"body": {
|
||||
"subtitle": "Неактивний {days}+ днів",
|
||||
"listing": "{days} днів"
|
||||
}
|
||||
},
|
||||
"full_stats": {
|
||||
"name": "повна статистика",
|
||||
"description": "Повна ігрова статистика",
|
||||
"body": {
|
||||
"cards": {
|
||||
"games": {
|
||||
"title": "Ігри",
|
||||
"winrate": "Відсоток перемог",
|
||||
"battles": "Бої",
|
||||
"wins_losses": "Перемоги / поразки"
|
||||
},
|
||||
"efficiency": {
|
||||
"title": "Ефективність",
|
||||
"wn8": "WN8",
|
||||
"survival": "Виживання",
|
||||
"accuracy": "Точність"
|
||||
},
|
||||
"lethality": {
|
||||
"title": "Летальність",
|
||||
"average_damage": "Середня шкода",
|
||||
"damage_per_tier": "Шкода за рівень",
|
||||
"damage_ratio": "Коефіцієнт шкоди",
|
||||
"average_kills": "Середня кількість знищень"
|
||||
},
|
||||
"miscellaneous": {
|
||||
"title": "Різне",
|
||||
"average_tier": "Середній рівень",
|
||||
"average_spots": "Середній засвіт",
|
||||
"average_xp": "Середній досвід",
|
||||
"kills_to_death_ratio": "Співвідношення знищень до смертей"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"link": {
|
||||
"name": "посилання",
|
||||
"description": "Прив'язує ваш Blitz та Discord акаунт",
|
||||
"body": {
|
||||
"accounts_linked": "Прив'язані акаунти",
|
||||
"no_role_permissions": {
|
||||
"title": "{name} не вдалося перевірити",
|
||||
"description": "У мене немає дозволу керувати ролями."
|
||||
}
|
||||
},
|
||||
"embed": {
|
||||
"title": "Невірний обліковий запис?",
|
||||
"description": "Використайте команду ще раз і виберіть ім'я користувача з результатів пошуку."
|
||||
}
|
||||
},
|
||||
"search_clans": {
|
||||
"name": "пошук кланів",
|
||||
"description": "Пошук кланів",
|
||||
"options": {
|
||||
"limit": {
|
||||
"name": "ліміт",
|
||||
"description": "Максимальна кількість результатів клану (за замовчуванням: {limit})"
|
||||
}
|
||||
},
|
||||
"body": {
|
||||
"title": "Пошук клану для {search} в регіоні {region}",
|
||||
"no_results": "Жодного клану не знайдено"
|
||||
}
|
||||
},
|
||||
"search_players": {
|
||||
"name": "пошук гравців",
|
||||
"description": "Пошук гравців",
|
||||
"options": {
|
||||
"limit": {
|
||||
"name": "ліміт",
|
||||
"description": "Максимальна кількість результатів гравця (за замовчуванням: {limit})"
|
||||
}
|
||||
},
|
||||
"body": {
|
||||
"title": "Пошук гравця для {search} у регіоні {region}",
|
||||
"no_results": "Гравця не знайдено"
|
||||
}
|
||||
},
|
||||
"rating_leaderboard": {
|
||||
"name": "таблиця рейтингу",
|
||||
"description": "Статистика рейтингових боїв",
|
||||
"subcommands": {
|
||||
"neighbors": {
|
||||
"name": "сусіди",
|
||||
"description": "Сусідуючі гравці в лідерборді"
|
||||
},
|
||||
"league": {
|
||||
"name": "ліга",
|
||||
"description": "Найкращий гравець ліги"
|
||||
}
|
||||
},
|
||||
"options": {
|
||||
"limit": {
|
||||
"name": "ліміт",
|
||||
"description": "Скільки сусідів відобразити (за замовчуванням: {count})"
|
||||
},
|
||||
"season": {
|
||||
"name": "сезон",
|
||||
"description": "Базова інформація про гравця",
|
||||
"choices": {
|
||||
"current": "{season} (поточний)"
|
||||
}
|
||||
},
|
||||
"league": {
|
||||
"name": "ліга",
|
||||
"description": "Ліга для відображення"
|
||||
}
|
||||
},
|
||||
"body": {
|
||||
"top_players": "Топ {count} гравців",
|
||||
"no_participation": "# {player} не грав у рейтингу в сезоні {season}\n\nЦей гравець не брав участь у цьому сезоні або не проходив калібрування",
|
||||
"no_ongoing_season": "# Немає поточного сезону\n\nВ даний час немає сезону рейтингу.",
|
||||
"deleted_player": "",
|
||||
"neighbors": "Сусіди по рейтингу",
|
||||
"more": "+ {count} ще"
|
||||
}
|
||||
},
|
||||
"today": {
|
||||
"name": "сьогодні",
|
||||
"description": "Сьогодні зіграні танки та статистика"
|
||||
},
|
||||
"stats": {
|
||||
"name": "статистика",
|
||||
"description": "Коротка статистика за період"
|
||||
},
|
||||
"owned_tanks": {
|
||||
"name": "отримані танки",
|
||||
"description": "Показує всі ваші танки даного рівня",
|
||||
"body": {
|
||||
"title": "# {name} отриманих рівнів {tier} танків\n\n"
|
||||
}
|
||||
},
|
||||
"permissions": {
|
||||
"name": "дозволи",
|
||||
"description": "Перевіряє чи бот має необхідні дозволи для роботи",
|
||||
"body": {
|
||||
"title": "# Дозволи\n\n{body}",
|
||||
"view_channels": "Перегляньте канали: необхідне для знаходження повідомлення, на якому використовувалася кнопка оновлення",
|
||||
"read_message_history": "Прочитайте історію повідомлень: потрібно знайти повідомлення для оновлення",
|
||||
"attach_files": "Закріпіть файли: потрібно для додавання зображень до команд на основі зображень",
|
||||
"external_emojis": "Зовнішні емодзі: потрібні для додавання емодзі національних прапорів та класів техніки"
|
||||
}
|
||||
},
|
||||
"ping": {
|
||||
"name": "",
|
||||
"description": "Перевірити чи бот живий",
|
||||
"body": {
|
||||
"pong": "Понг🏓",
|
||||
"pong_with_time": "Понг🏓 - {time}мс"
|
||||
},
|
||||
"subcommands": {
|
||||
"blitzkit": {
|
||||
"name": "BlitzKit",
|
||||
"description": "Ping BlitzKit"
|
||||
},
|
||||
"wotb": {
|
||||
"name": "WoTB",
|
||||
"description": "Ping World of Tanks Blitz"
|
||||
}
|
||||
}
|
||||
},
|
||||
"player_info": {
|
||||
"name": "інформація про гравця",
|
||||
"description": "Базова інформація про гравця",
|
||||
"body": {
|
||||
"title": "інформація про {name}",
|
||||
"nickname": "Нік",
|
||||
"battles": "Бої",
|
||||
"winrate": "Відсоток перемог",
|
||||
"account_id": "ID акаунта",
|
||||
"created": "Створено",
|
||||
"last_battle": "Остання битва"
|
||||
}
|
||||
},
|
||||
"rating": {
|
||||
"name": "рейтинг",
|
||||
"description": "Статистика рейтингових боїв гравця ",
|
||||
"subcommands": {
|
||||
"today": {
|
||||
"name": "сьогодні",
|
||||
"description": "Сьогоднішня статистика рейтингових боїв"
|
||||
},
|
||||
"season": {
|
||||
"name": "сезон",
|
||||
"description": "Статистика рейтингових боїв поточного сезону"
|
||||
}
|
||||
},
|
||||
"body": {
|
||||
"subtitle": {
|
||||
"today": "Сьогоднішня статистика рейтингових боїв",
|
||||
"season": "Статистика рейтингових боїв даного сезону"
|
||||
}
|
||||
},
|
||||
"errors": {
|
||||
"no_participation": "# {name} не грав рейтингові бої\n\nЦей гравець не брав участь у рейтинговому режимі цього сезону.",
|
||||
"unrecorded_stats": "# Статистика на цей момент недоступна\n\nWargaming наразі зіткнулась з технічними несправностями. Якщо зараз проходить сезон, статистика буде доступною в найближчі 24 години."
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"website": {
|
||||
"redirect": {
|
||||
"title": "301: переміщено назавжди",
|
||||
@@ -660,7 +207,7 @@
|
||||
},
|
||||
"tank_search": {
|
||||
"select_dialog_title": "Знайти танк",
|
||||
"swap_dialog_title": "Swap tank",
|
||||
"swap_dialog_title": "Резервуар підміни",
|
||||
"clear_filters": "Очистити",
|
||||
"login": "Увійдіть, щоб скористатися",
|
||||
"search_bar_hint": "Шукайте техніку...",
|
||||
@@ -671,8 +218,8 @@
|
||||
"sorting_by": "Відсортувати за {name}",
|
||||
"clear": "Clear",
|
||||
"tier": "Рівень {tier}",
|
||||
"passive": "{name} (Passive)",
|
||||
"active": "{name} (Active)",
|
||||
"passive": "",
|
||||
"active": "{name}{name}",
|
||||
"no_tanks_found": {
|
||||
"body": "Нічого не знайдено.",
|
||||
"search_again": "Спробуйте шукати заново.",
|
||||
@@ -734,30 +281,22 @@
|
||||
}
|
||||
},
|
||||
"home": {
|
||||
"pwa": {
|
||||
"title": "Install the BlitzKit App",
|
||||
"new": "",
|
||||
"checking": "Checking compatibility...",
|
||||
"instructions": "Instructions for Apple devices.",
|
||||
"install": "Install",
|
||||
"dismiss": "Dismiss"
|
||||
},
|
||||
"discord": {
|
||||
"join_short": "Join cool people!",
|
||||
"join_long": "Join super duper cool people!",
|
||||
"join_short": "Приєднуйся до суспільства!",
|
||||
"join_long": "Приєднуйся до найкрутішого суспільства!",
|
||||
"action": "Discord"
|
||||
},
|
||||
"hero": {
|
||||
"credit": "By {name} ❤️"
|
||||
"credit": "Від {name} ❤️"
|
||||
},
|
||||
"hot_tanks": {
|
||||
"title": "Популярні танки",
|
||||
"subtitle": "Last {days} days"
|
||||
"subtitle": "Останні {days} днів"
|
||||
},
|
||||
"other_projects": {
|
||||
"title": "Інші класні проєкти"
|
||||
},
|
||||
"help_translate": "Please help translate {name} to {language}!",
|
||||
"help_translate": "Будь ласка, допоможіть перекласти {name} на {language}!",
|
||||
"seo_description": "Інструменти для всього, пов'язаного з WoT Blitz"
|
||||
},
|
||||
"docs": {
|
||||
@@ -771,7 +310,7 @@
|
||||
"reset": "Скинути",
|
||||
"shuffle": "Перемішати",
|
||||
"remove": "Видалити зіграні",
|
||||
"tracking": "BlitzKit is tracking your battles",
|
||||
"tracking": "BlitzKit відстежує ваші бої",
|
||||
"sort": {
|
||||
"button": "Сортувати за",
|
||||
"last_played": "Остання гра",
|
||||
@@ -797,15 +336,15 @@
|
||||
"description": "Tank playlist generator",
|
||||
"seo_description": "Don't know what to play in World of Tanks Blitz? Use BlitzKit Playlist to get suggestions!",
|
||||
"button": "Створити",
|
||||
"pool_size": "{count} possible tanks"
|
||||
"pool_size": "{count} можливі танки"
|
||||
},
|
||||
"mixer": {
|
||||
"name": "Mixer",
|
||||
"button": "Mix and match",
|
||||
"description": "Mix tank modules",
|
||||
"seo_description": "Mix and match hulls, turrets, and guns of tanks in World of Tanks Blitz",
|
||||
"screenshot": "Screenshot",
|
||||
"randomize": "Randomize"
|
||||
"screenshot": "Знімок екрану",
|
||||
"randomize": "Рандомізувати"
|
||||
},
|
||||
"guess": {
|
||||
"name": "Guess",
|
||||
@@ -814,16 +353,16 @@
|
||||
"seo_description": "Play a tank guessing game with a silhouette in World of Tanks Blitz",
|
||||
"search": {
|
||||
"placeholder": "Type to guess...",
|
||||
"skip": "Skip",
|
||||
"skip": "Пропустити",
|
||||
"guess": "Guess",
|
||||
"next": "Next",
|
||||
"next": "Наступний",
|
||||
"no_results": "Немає результатів"
|
||||
},
|
||||
"stats": "{correct} / {total} correct, {streak} streak",
|
||||
"help": {
|
||||
"title": "Partially reveal tank?",
|
||||
"description": "Reveals the tank without showing the name. This round will be considered incorrect and break your streak!",
|
||||
"cancel": "Cancel",
|
||||
"cancel": "",
|
||||
"reveal": "Reveal"
|
||||
},
|
||||
"clear": "Clear",
|
||||
@@ -831,7 +370,7 @@
|
||||
"tier": "Рівень {tier}"
|
||||
},
|
||||
"tankopedia": {
|
||||
"search": "Search a stat...",
|
||||
"search": "Шукаємо стати...",
|
||||
"name": "Танкопедія",
|
||||
"button": "Знайти танки",
|
||||
"description": "Танкова енциклопедія",
|
||||
@@ -869,7 +408,7 @@
|
||||
"yaw": "Yaw",
|
||||
"pitch": "Pitch",
|
||||
"min": "Min",
|
||||
"max": "Max"
|
||||
"max": "Макс"
|
||||
}
|
||||
},
|
||||
"sandbox": {
|
||||
@@ -901,8 +440,8 @@
|
||||
"normalization": "Нормалізація",
|
||||
"ricochet": "Рикошет",
|
||||
"explosion_radius": "Радіус розльоту уламків",
|
||||
"exit": "Exit",
|
||||
"reset": "Reset"
|
||||
"exit": "Вийти",
|
||||
"reset": "Скинути"
|
||||
},
|
||||
"advanced": "Advanced highlighting",
|
||||
"shot_card": {
|
||||
@@ -911,17 +450,17 @@
|
||||
"spaced": "Spaced",
|
||||
"external": "External",
|
||||
"gap": "Gap",
|
||||
"gun": "Gun",
|
||||
"track": "Tracks"
|
||||
"gun": "Пушка",
|
||||
"track": "Гусениці"
|
||||
},
|
||||
"status": {
|
||||
"penetration": "{damage}hp penetration",
|
||||
"blocked": "Blocked",
|
||||
"penetration": "{damage} од. шкоди з пробиттям",
|
||||
"blocked": "Заблоковано",
|
||||
"ricochet": "Рикошет",
|
||||
"splash": "{damage}hp splash"
|
||||
"splash": "{damage} Од"
|
||||
},
|
||||
"stats": {
|
||||
"thickness_and_angle": "{thickness}mm {angle}°",
|
||||
"thickness_and_angle": "{thickness}мм {angle}°",
|
||||
"nominal": "{thickness}mm nominal",
|
||||
"ricochet_loss": "{loss}% penetration"
|
||||
}
|
||||
@@ -934,7 +473,7 @@
|
||||
"external": "External",
|
||||
"edit": {
|
||||
"label": "Редагувати",
|
||||
"reset": "Reset"
|
||||
"reset": "Скинути"
|
||||
}
|
||||
}
|
||||
},
|
||||
@@ -947,12 +486,13 @@
|
||||
},
|
||||
"vanilla": "Vanilla",
|
||||
"opentest": "Відкритий тест",
|
||||
"full_name": "Full name",
|
||||
"full_name": "Повна назва",
|
||||
"nation": "Нація",
|
||||
"class": "Клас",
|
||||
"tier": "Рівень",
|
||||
"type": "Вид",
|
||||
"dev_id": "DEV: ID",
|
||||
"dev_name": "DEV: NAME",
|
||||
"purchase": "Purchase price",
|
||||
"restoration": "Restoration price",
|
||||
"sale": "Sale price",
|
||||
@@ -973,6 +513,11 @@
|
||||
},
|
||||
"configuration": {
|
||||
"title": "Configuration",
|
||||
"equalizer": {
|
||||
"title": "Equalizer",
|
||||
"equalize": "Equalize",
|
||||
"beta": "Beta"
|
||||
},
|
||||
"modules": {
|
||||
"title": "Модулі",
|
||||
"stock": "Stock",
|
||||
@@ -1005,8 +550,8 @@
|
||||
"title": "Characteristics",
|
||||
"compare": {
|
||||
"label": "Compare against",
|
||||
"class": "Tier {tier} {class}",
|
||||
"tier": "All of tier {tier}",
|
||||
"class": "{tier} {class}",
|
||||
"tier": "All tier {tier}",
|
||||
"all": "Усі танки"
|
||||
},
|
||||
"values": {
|
||||
@@ -1035,7 +580,7 @@
|
||||
"caliber": "Калібр",
|
||||
"penetration": "Бронепробиття",
|
||||
"damage": "Шкода",
|
||||
"damageWithoutAssault": "Damage without assault shells",
|
||||
"damageWithoutAssault": "Шкода без урахування золотих снарядів",
|
||||
"clipDamage": "Clipping potential",
|
||||
"moduleDamage": "Шкода по модулях",
|
||||
"explosionRadius": "Радіус розльоту уламків",
|
||||
@@ -1044,7 +589,7 @@
|
||||
"dispersion": "Нерухомо",
|
||||
"dispersionMoving": "У русі",
|
||||
"dispersionHullTraversing": "Hull traversing",
|
||||
"dispersionTurretTraversing": "Turret traversing",
|
||||
"dispersionTurretTraversing": "Обертання башти",
|
||||
"dispersionShooting": "Shooting",
|
||||
"dispersionGunDamaged": "Gun damaged",
|
||||
"gunDepression": "Depression",
|
||||
@@ -1073,7 +618,7 @@
|
||||
"hullTraverseHardTerrain": "Hard",
|
||||
"hullTraverseMediumTerrain": "Середній",
|
||||
"hullTraverseSoftTerrain": "Soft",
|
||||
"health": "Health",
|
||||
"health": "Здоров'я",
|
||||
"fireChance": "Fire chance",
|
||||
"viewRange": "View range",
|
||||
"camouflageStill": "Нерухомо",
|
||||
@@ -1142,7 +687,8 @@
|
||||
},
|
||||
"skills": {
|
||||
"clear": "Очистити",
|
||||
"maximize": "Збільшити все"
|
||||
"maximize": "Збільшити все",
|
||||
"equalize": "Equalize"
|
||||
},
|
||||
"modules": {
|
||||
"stock": "Stock",
|
||||
@@ -1160,7 +706,7 @@
|
||||
},
|
||||
"performance": {
|
||||
"name": "Performance",
|
||||
"button": "View tanks",
|
||||
"button": "Переглянути танки",
|
||||
"description": "Tank performance statistics",
|
||||
"seo_description": "Best tanks and their performances in World of Tanks Blitz",
|
||||
"estimation": {
|
||||
@@ -1197,10 +743,10 @@
|
||||
"name": "Gallery",
|
||||
"button": "Browse all",
|
||||
"description": "Blitz player avatars",
|
||||
"seo_description": "All World of Tanks Blitz player avatars",
|
||||
"seo_description": "Усі World of Tanks Blitz аватари гравців",
|
||||
"last_updated": "Last updated on {time}",
|
||||
"search": {
|
||||
"hint": "Search avatars...",
|
||||
"hint": "Шукаємо аватари...",
|
||||
"results": "{count} avatars"
|
||||
}
|
||||
},
|
||||
@@ -1237,18 +783,18 @@
|
||||
}
|
||||
},
|
||||
"tier_list": {
|
||||
"name": "Tier list",
|
||||
"button": "Rank tanks",
|
||||
"description": "Rank Blitz tanks",
|
||||
"name": "Список рівнів",
|
||||
"button": "Ранги танків",
|
||||
"description": "Ранги танків з блітзу",
|
||||
"seo_description": "Explore tier lists ranking tanks from best to worst, based on player ratings and statistical performance in World of Tanks Blitz",
|
||||
"buttons": {
|
||||
"reset": "Reset",
|
||||
"share": "Share"
|
||||
"reset": "Скинути",
|
||||
"share": "Поділитися"
|
||||
}
|
||||
},
|
||||
"embed": {
|
||||
"name": "Embed",
|
||||
"button": "Create now",
|
||||
"button": "Створити зараз",
|
||||
"description": "Embeds for streaming",
|
||||
"seo_description": "Create embeds for streaming World of Tanks Blitz with extreme customization",
|
||||
"coming_soon": "More embeds coming soon.",
|
||||
@@ -1259,22 +805,22 @@
|
||||
},
|
||||
"configuration": {
|
||||
"import": {
|
||||
"title": "Import",
|
||||
"title": "Імпортувати",
|
||||
"description": "Paste your current URL if you have one already to import your settings",
|
||||
"hint": "Paste URL...",
|
||||
"hint": "Вставити посилання...",
|
||||
"apply": "Apply",
|
||||
"idiot_title": "Invalid URL",
|
||||
"idiot_title": "Некоректне посилання",
|
||||
"idiot_description": "Try pasting the URL that BlitzKit previously generated, you silly goose!",
|
||||
"idiot_button": "Okay, my bad"
|
||||
},
|
||||
"export": {
|
||||
"title": "Export",
|
||||
"title": "Експортувати",
|
||||
"description": "Copy all properties for you streaming software",
|
||||
"generate": {
|
||||
"button": "Generate URL",
|
||||
"title": "Generate URL",
|
||||
"button": "Згенерувати посилання",
|
||||
"title": "Генерація посилання",
|
||||
"subtitle": "Search an account to track",
|
||||
"cancel": "Cancel",
|
||||
"cancel": "",
|
||||
"success": {
|
||||
"title": "Copy URL",
|
||||
"info": "Generated the URL for {name}. The embed will start tracking as soon as the URL is pasted. Reset at any time by right-clicking on PC or long-pressing on mobile and then selecting \"Reset\".",
|
||||
@@ -1289,7 +835,7 @@
|
||||
},
|
||||
"customize": {
|
||||
"title": "Customize",
|
||||
"reset": "Reset",
|
||||
"reset": "Скинути",
|
||||
"description": "Bells and whistles of your embed"
|
||||
}
|
||||
},
|
||||
@@ -1337,14 +883,14 @@
|
||||
"seo_description": "Live and archived full rating leaderboard for World of Tanks Blitz"
|
||||
},
|
||||
"discord": {
|
||||
"name": "Discord bot",
|
||||
"button": "Install now",
|
||||
"name": "Діскорд бот",
|
||||
"button": "Встановити зараз",
|
||||
"description": "Stats right in Discord",
|
||||
"seo_description": "Get stats right in Discord with BlitzKit's Discord bot"
|
||||
},
|
||||
"more": {
|
||||
"name": "More coming soon",
|
||||
"button": "Join Discord",
|
||||
"name": "Буде через певний час",
|
||||
"button": "Приєднатись до Діскорду",
|
||||
"description": "What we're making",
|
||||
"seo_description": "What we're making with BlitzKit"
|
||||
},
|
||||
|
||||
+65
-519
@@ -13,18 +13,18 @@
|
||||
"hp": "{value} 生命值",
|
||||
"x": "x{value}",
|
||||
"percentage": "{value}%",
|
||||
"deg_s": "{value}度°/秒",
|
||||
"deg_s": "{value}度每秒",
|
||||
"plus": "+{value}"
|
||||
},
|
||||
"gun_types": {
|
||||
"auto_loader": "弹夹型坦克",
|
||||
"auto_reloader": "自动装填型坦克",
|
||||
"auto_reloader": "弹鼓型坦克",
|
||||
"regular": "单发"
|
||||
},
|
||||
"shells": {
|
||||
"ap": "穿甲弹",
|
||||
"ap_cr": "硬式复合穿甲弹",
|
||||
"hc": "反战车高爆弹",
|
||||
"hc": "破甲弹",
|
||||
"he": "高爆弹"
|
||||
},
|
||||
"player_count_period": {
|
||||
@@ -37,10 +37,11 @@
|
||||
"d_1": "昨日"
|
||||
},
|
||||
"branches": {
|
||||
"local": "开发者",
|
||||
"dev": "测试版",
|
||||
"beta": "测试版",
|
||||
"development": "Development",
|
||||
"opentest": "开放测试",
|
||||
"preview": "预览"
|
||||
"preview": "Preview",
|
||||
"production": "Production"
|
||||
},
|
||||
"locales": {
|
||||
"en": "英语",
|
||||
@@ -60,23 +61,23 @@
|
||||
"3": "平均",
|
||||
"4": "高于平均",
|
||||
"5": "好",
|
||||
"6": "非常好",
|
||||
"6": "好",
|
||||
"7": "很好",
|
||||
"8": "极品",
|
||||
"9": "超级强势玩家"
|
||||
"8": "非常好",
|
||||
"9": "极品"
|
||||
},
|
||||
"bkni_percentile": {
|
||||
"0": "Super malum",
|
||||
"1": "Malum",
|
||||
"2": "非常差",
|
||||
"0": "垃圾",
|
||||
"1": "非常差",
|
||||
"2": "很差",
|
||||
"3": "差",
|
||||
"4": "低于平均",
|
||||
"5": "平均",
|
||||
"6": "高于平均",
|
||||
"6": "较好",
|
||||
"7": "好",
|
||||
"8": "非常好",
|
||||
"9": "極品",
|
||||
"10": "超级强势玩家"
|
||||
"8": "很好",
|
||||
"9": "非常好",
|
||||
"10": "极品"
|
||||
},
|
||||
"nations": {
|
||||
"ussr": "苏联",
|
||||
@@ -86,8 +87,8 @@
|
||||
"uk": "英国",
|
||||
"france": "法国",
|
||||
"japan": "日本",
|
||||
"european": "欧洲国家",
|
||||
"other": "混合型国家"
|
||||
"european": "欧盟 (E系)",
|
||||
"other": "X系"
|
||||
},
|
||||
"nations_adjectives": {
|
||||
"ussr": "苏联",
|
||||
@@ -97,34 +98,34 @@
|
||||
"uk": "英国",
|
||||
"france": "法国",
|
||||
"japan": "日本",
|
||||
"european": "欧洲国家",
|
||||
"other": "混合型国家"
|
||||
"european": "欧盟 (E系)",
|
||||
"other": "X系"
|
||||
},
|
||||
"tank_class_short": {
|
||||
"-1": "未识别",
|
||||
"-1": "未知",
|
||||
"0": "轻型坦克",
|
||||
"1": "中型坦克",
|
||||
"2": "重型战车",
|
||||
"3": "驱逐战车"
|
||||
"3": "坦克歼击车"
|
||||
},
|
||||
"tank_class_short_plural_lowercase": {
|
||||
"0": "轻型战车",
|
||||
"1": "中型战车",
|
||||
"2": "重型战车",
|
||||
"3": "驱逐战车"
|
||||
"0": "轻型坦克",
|
||||
"1": "中型坦克",
|
||||
"2": "重型坦克",
|
||||
"3": "坦克歼击车"
|
||||
},
|
||||
"tank_class_medium": {
|
||||
"-1": "未识别",
|
||||
"0": "轻型战车",
|
||||
"1": "中型战车",
|
||||
"2": "重型战车",
|
||||
"3": "驱逐战车"
|
||||
"-1": "未知",
|
||||
"0": "轻型坦克",
|
||||
"1": "中型坦克",
|
||||
"2": "重型坦克",
|
||||
"3": "坦克歼击车"
|
||||
},
|
||||
"tree_type": {
|
||||
"-1": "未识别",
|
||||
"-1": "未知",
|
||||
"0": "科技树",
|
||||
"1": "加值战车",
|
||||
"2": "收藏家战车"
|
||||
"1": "金币车",
|
||||
"2": "收藏车"
|
||||
},
|
||||
"regions": {
|
||||
"normal": {
|
||||
@@ -140,8 +141,8 @@
|
||||
},
|
||||
"leagues": {
|
||||
"diamond": "钻石",
|
||||
"platinum": "白金",
|
||||
"gold": "黃金",
|
||||
"platinum": "铂金",
|
||||
"gold": "黄金",
|
||||
"silver": "白银",
|
||||
"bronze": "青铜"
|
||||
},
|
||||
@@ -156,7 +157,7 @@
|
||||
"normalized_shots": "开火次数",
|
||||
"normalized_spotted": "侦查次数",
|
||||
"normalized_survived_battles": "存活率",
|
||||
"normalized_win_and_survived": "存活胜利率",
|
||||
"normalized_win_and_survived": "胜利并幸存的概率",
|
||||
"normalized_wins": "胜率",
|
||||
"normalized_xp": "经验值",
|
||||
"normalized_battle_life_time": "战斗时间",
|
||||
@@ -184,460 +185,6 @@
|
||||
"cumulative_battle_life_time": "总战斗时间"
|
||||
}
|
||||
},
|
||||
"bot": {
|
||||
"common": {
|
||||
"errors": {
|
||||
"clan_not_found": "# 找不到公会\n找不到\"{search}\"。请尝试从搜索结果中选择一个公会。",
|
||||
"player_not_found": "# 找不到玩家\n无法找到玩家 “{search}”。 尝试从搜索结果中选择玩家,或输入一个有效的玩家名称, 或使用“/link”命令。",
|
||||
"player_not_linked": "# 使用 `/link` 来开始\n我不知道你是谁,但你今天可以告诉我!",
|
||||
"tank_name_not_found": "# 找不到坦克\n找不到名为 “{search}” 的坦克。",
|
||||
"tank_id_not_found": "# 找不到坦克\n无法找到ID为 “{search}” 的坦克。 请尝试输入坦克的名称而不是数字。",
|
||||
"no_tank_stats": "# 没有这辆战车的数据\n这个玩家没有可用资料。 这可能不是你要找的玩家。",
|
||||
"get_help": "Discord的协助服务器",
|
||||
"uncaught_error": "# BlitzKit 发生错误!\n我们对此感到抱歉。 欢迎加入[官方Discord](https://discord.gg/nDt7AjGJQH),以方便帮助你解决问题。",
|
||||
"preview": "# 此命令处于预览\n\n您只能在[官方Discord服务器](https://discord.gg/nDt7AjGJQH)访问此命令。该命令将很快可用。",
|
||||
"query_too_small": "# 搜寻内容过短\n您的搜寻必需至少包含 3 个字元。",
|
||||
"query_too_long": "# 搜索内容过长\n您搜索的内容必须少于 100 个字符。"
|
||||
},
|
||||
"wn8": {
|
||||
"name": "WN8",
|
||||
"types": {
|
||||
"very_bad": "非常差",
|
||||
"bad": "差",
|
||||
"below_average": "低于平均",
|
||||
"average": "平均",
|
||||
"above_average": "高于平均",
|
||||
"good": "好",
|
||||
"very_good": "非常好",
|
||||
"great": "很好",
|
||||
"unicum": "極品",
|
||||
"super_unicum": "超强势玩家"
|
||||
}
|
||||
},
|
||||
"subcommands": {
|
||||
"today": {
|
||||
"name": "今日",
|
||||
"description": "今日:"
|
||||
},
|
||||
"30": {
|
||||
"name": "30",
|
||||
"description": "30 天"
|
||||
},
|
||||
"60": {
|
||||
"name": "60",
|
||||
"description": "60 天"
|
||||
},
|
||||
"90": {
|
||||
"name": "90",
|
||||
"description": "90 天"
|
||||
},
|
||||
"career": {
|
||||
"name": "生涯",
|
||||
"description": "玩家资料"
|
||||
},
|
||||
"custom": {
|
||||
"name": "自定义",
|
||||
"description": "自定义范围",
|
||||
"options": {
|
||||
"start": {
|
||||
"name": "开始",
|
||||
"description": "距今若干天前开始"
|
||||
},
|
||||
"end": {
|
||||
"name": "结束",
|
||||
"description": "距今若干天前开结束"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"options": {
|
||||
"clan": {
|
||||
"name": "公会",
|
||||
"description": "公会名称或标签"
|
||||
},
|
||||
"tank": {
|
||||
"name": "战车",
|
||||
"description": "要获取战绩的坦克"
|
||||
},
|
||||
"username": {
|
||||
"name": "用户名",
|
||||
"description": "玩家的闪击战游戏昵称"
|
||||
},
|
||||
"filters": {
|
||||
"nation": {
|
||||
"name": "国别",
|
||||
"description": "国别"
|
||||
},
|
||||
"class": {
|
||||
"name": "战车车型",
|
||||
"description": "战车车型"
|
||||
},
|
||||
"type": {
|
||||
"name": "战车类型",
|
||||
"description": "战车类型"
|
||||
}
|
||||
},
|
||||
"region": {
|
||||
"name": "所在地区",
|
||||
"description": "地区"
|
||||
},
|
||||
"tier": {
|
||||
"name": "阶级",
|
||||
"description": "阶级",
|
||||
"choices": {
|
||||
"tier": "{tier_1} - {tier_2} 阶"
|
||||
}
|
||||
}
|
||||
},
|
||||
"periods": {
|
||||
"career": "玩家资料",
|
||||
"today": "今日:",
|
||||
"days": "{days} 天",
|
||||
"custom": "{day_1} - {day_2} 天"
|
||||
},
|
||||
"filters": {
|
||||
"none": "无筛选器",
|
||||
"tier": "{tier} 阶"
|
||||
},
|
||||
"no_data": {
|
||||
"battles_in_period": "在这段时间里没有参与任何战斗",
|
||||
"battles_in_season": "在这个赛季中没有战斗记录",
|
||||
"players_in_period": "这段时间内没有玩家",
|
||||
"tanks_found": "找不到战车"
|
||||
},
|
||||
"buttons": {
|
||||
"refresh": "刷新"
|
||||
},
|
||||
"hero_stats": {
|
||||
"battles": "战斗场次",
|
||||
"winrate": "胜率",
|
||||
"damage": "伤害",
|
||||
"damage_ratio": "伤害比",
|
||||
"tier": "阶级",
|
||||
"survival": "生存",
|
||||
"accuracy": "命中率",
|
||||
"kills": "击杀数"
|
||||
}
|
||||
},
|
||||
"commands": {
|
||||
"replay": {
|
||||
"name": "回放",
|
||||
"description": "显示重播结果"
|
||||
},
|
||||
"research": {
|
||||
"name": "研发",
|
||||
"description": "列出研发线路的费用",
|
||||
"options": {
|
||||
"target_tank": {
|
||||
"name": "目标战车",
|
||||
"description": "需要研发的目标(战车)"
|
||||
},
|
||||
"starting_tank": {
|
||||
"name": "起始战车",
|
||||
"description": "研发线路中的起始战车(如果未提供则自动推定)"
|
||||
}
|
||||
},
|
||||
"body": {
|
||||
"subtitle": "研发",
|
||||
"total": "全部",
|
||||
"research": "研发:{cost}",
|
||||
"upgrades": "升级:{cost}",
|
||||
"purchase": "购买:{cost}",
|
||||
"equipment": "装备:{cost}",
|
||||
"estimation": "# 这是一个估计值!\n\n这个列表可能包含已经研发过的战车,因为 Wargaming 提供了不正确的资料。 如果可以,请尝试在同一研发线路中提供一个 “起始战车” 。"
|
||||
},
|
||||
"errors": {
|
||||
"non_tech_tree": "# \"{tank}\" 不在科技树里\n\n你不能研发一个 加值/收藏家 坦克。",
|
||||
"tier_1": "# {tank} 是一级坦克\n\n一级坦克一直是对所有玩家免费解锁的。",
|
||||
"already_researched": "# \"{tank}\" 已完成研发\n\n请尝试在同一研发线路上提供“起始坦克”, 以查看全部您已研发过的坦克。",
|
||||
"start_end_equal": "# \"{tank}\" 重复提供了\n\n请确认 \"初始坦克\" 和 \"目标坦克\" 是不同的。",
|
||||
"tanks_not_on_line": "# “{tank_1}” 和 “{tank_2}” 不在同一个研发线路上\n\n请确认“起始坦克” 和 “目标坦克” 在同一研发线路中。",
|
||||
"unordered": "# “{tank_1}” 阶级比 “{tank_2}” 高\n\n请以提供 {tank_2} 作为起始坦克,因为它的阶级更低。"
|
||||
}
|
||||
},
|
||||
"about": {
|
||||
"name": "关于",
|
||||
"description": "查看关于机器人的所有信息",
|
||||
"subcommands": {
|
||||
"commands": {
|
||||
"name": "指令",
|
||||
"description": "所有指令及其描述",
|
||||
"body": "# 指令\n\nBlitzKit 提供了以下指令:\n\n"
|
||||
},
|
||||
"embeds": {
|
||||
"name": "嵌入",
|
||||
"description": "嵌入如何运作"
|
||||
},
|
||||
"introduction": {
|
||||
"name": "介绍",
|
||||
"description": "关于此机器人"
|
||||
},
|
||||
"invite": {
|
||||
"name": "邀请",
|
||||
"description": "如何邀请机器人"
|
||||
},
|
||||
"timezones": {
|
||||
"name": "时区",
|
||||
"description": "BlitzKit 如何判断并使用你的时区"
|
||||
},
|
||||
"credits": {
|
||||
"name": "积分",
|
||||
"description": "谁帮助过 BlitzKit"
|
||||
}
|
||||
}
|
||||
},
|
||||
"breakdown": {
|
||||
"name": "详细分析",
|
||||
"description": "在特定时期中, 战车的详细分析",
|
||||
"body": {
|
||||
"total": "全部",
|
||||
"battles": "战斗场次",
|
||||
"wn8": "WN8",
|
||||
"winrate": "胜率",
|
||||
"damage": "伤害",
|
||||
"unknown_tank": "未知坦克 {id}"
|
||||
}
|
||||
},
|
||||
"debug": {
|
||||
"name": "侦错",
|
||||
"description": "机器人侦错信息",
|
||||
"body": {
|
||||
"title": "# 侦错\n\n",
|
||||
"version": "版本",
|
||||
"shard": {
|
||||
"label": "碎片",
|
||||
"default": "默认"
|
||||
},
|
||||
"uptime": "运行时间"
|
||||
}
|
||||
},
|
||||
"evolution": {
|
||||
"name": "演变",
|
||||
"description": "统计资料的演变",
|
||||
"groups": {
|
||||
"player": {
|
||||
"name": "玩家",
|
||||
"description": "玩家数据统计"
|
||||
},
|
||||
"tank": {
|
||||
"name": "战车",
|
||||
"description": "战车数据统计"
|
||||
}
|
||||
}
|
||||
},
|
||||
"inactive": {
|
||||
"name": "不活跃",
|
||||
"description": "列出公会中所有超过阈值的不活跃玩家",
|
||||
"options": {
|
||||
"threshold": {
|
||||
"name": "阈值",
|
||||
"description": "未上线天数( 默认:{days} 天)"
|
||||
}
|
||||
},
|
||||
"body": {
|
||||
"subtitle": "{days}+ 天未上线",
|
||||
"listing": "{days} 天"
|
||||
}
|
||||
},
|
||||
"full_stats": {
|
||||
"name": "完整统计资料",
|
||||
"description": "游戏内完整统计资料",
|
||||
"body": {
|
||||
"cards": {
|
||||
"games": {
|
||||
"title": "游戏",
|
||||
"winrate": "胜率",
|
||||
"battles": "战斗场次",
|
||||
"wins_losses": "胜利/失败"
|
||||
},
|
||||
"efficiency": {
|
||||
"title": "效率",
|
||||
"wn8": "WN8",
|
||||
"survival": "生存率",
|
||||
"accuracy": "命中率"
|
||||
},
|
||||
"lethality": {
|
||||
"title": "致命伤害",
|
||||
"average_damage": "平均伤害",
|
||||
"damage_per_tier": "各阶级伤害",
|
||||
"damage_ratio": "伤害比",
|
||||
"average_kills": "平均击毁"
|
||||
},
|
||||
"miscellaneous": {
|
||||
"title": "杂项",
|
||||
"average_tier": "平均阶级",
|
||||
"average_spots": "平均侦查",
|
||||
"average_xp": "平均经验",
|
||||
"kills_to_death_ratio": "击杀阵亡比"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"link": {
|
||||
"name": "链接",
|
||||
"description": "链接您的 Blitz 和 Discord 账户",
|
||||
"body": {
|
||||
"accounts_linked": "帐号已绑定",
|
||||
"no_role_permissions": {
|
||||
"title": "{name} 验证失败",
|
||||
"description": "我没有管理身份的权限。"
|
||||
}
|
||||
},
|
||||
"embed": {
|
||||
"title": "账户不正确?",
|
||||
"description": "再次使用此命令,从搜索结果中选择一个用户名。"
|
||||
}
|
||||
},
|
||||
"search_clans": {
|
||||
"name": "搜寻-公会资料",
|
||||
"description": "搜寻公会资料",
|
||||
"options": {
|
||||
"limit": {
|
||||
"name": "限制",
|
||||
"description": "公会结果的最大显示数量 (默认:{limit})"
|
||||
}
|
||||
},
|
||||
"body": {
|
||||
"title": "在地区 {region} 中搜索公会 {search}",
|
||||
"no_results": "没有找到该公会"
|
||||
}
|
||||
},
|
||||
"search_players": {
|
||||
"name": "搜索-玩家",
|
||||
"description": "搜索玩家",
|
||||
"options": {
|
||||
"limit": {
|
||||
"name": "限制",
|
||||
"description": "玩家结果的最大显示数量 (默认:{limit})"
|
||||
}
|
||||
},
|
||||
"body": {
|
||||
"title": "在地区 {region} 中搜索玩家 {search}",
|
||||
"no_results": "未找到玩家"
|
||||
}
|
||||
},
|
||||
"rating_leaderboard": {
|
||||
"name": "评价战斗-排行榜",
|
||||
"description": "评价战斗的统计数据",
|
||||
"subcommands": {
|
||||
"neighbors": {
|
||||
"name": "附近的",
|
||||
"description": "排行榜上附近的玩家"
|
||||
},
|
||||
"league": {
|
||||
"name": "段位",
|
||||
"description": "段位中的顶尖玩家"
|
||||
}
|
||||
},
|
||||
"options": {
|
||||
"limit": {
|
||||
"name": "限制",
|
||||
"description": "显示附近有多少玩家(默认:{count})"
|
||||
},
|
||||
"season": {
|
||||
"name": "赛季",
|
||||
"description": "赛季数 (默认:当前)",
|
||||
"choices": {
|
||||
"current": "{season} (当前)"
|
||||
}
|
||||
},
|
||||
"league": {
|
||||
"name": "段位",
|
||||
"description": "要显示的段位"
|
||||
}
|
||||
},
|
||||
"body": {
|
||||
"top_players": "前 {count} 玩家",
|
||||
"no_participation": "# {player} 没有在赛季 {season} 中进行过评价战斗\n\n该玩家没有参加该赛季或没有完成校准。",
|
||||
"no_ongoing_season": "# 没有进行中的赛季\n\n目前没有赛季。",
|
||||
"deleted_player": "已删除玩家 {id}",
|
||||
"neighbors": "对邻居进行评分",
|
||||
"more": "+ {count} 更多"
|
||||
}
|
||||
},
|
||||
"today": {
|
||||
"name": "今日",
|
||||
"description": "今天玩过的战车和统计资料"
|
||||
},
|
||||
"stats": {
|
||||
"name": "统计资料",
|
||||
"description": "一段时间内的快速统计"
|
||||
},
|
||||
"owned_tanks": {
|
||||
"name": "已拥有的战车",
|
||||
"description": "显示该阶级中所有您已拥有的战车",
|
||||
"body": {
|
||||
"title": "# {name} 所拥有的 {tier} 阶坦克\n\n"
|
||||
}
|
||||
},
|
||||
"permissions": {
|
||||
"name": "权限",
|
||||
"description": "检查机器人是否拥有运行所需的权限",
|
||||
"body": {
|
||||
"title": "# 权限\n\n{body}",
|
||||
"view_channels": "查看频道:需要找到重新整理按钮使用的讯息",
|
||||
"read_message_history": "读取消息历史: 需要找到消息以刷新",
|
||||
"attach_files": "附加文件:需要将图像添加到基于图像的命令",
|
||||
"external_emojis": "外部表情符号:需要添加国家旗帜和战车类别"
|
||||
}
|
||||
},
|
||||
"ping": {
|
||||
"name": "连接延迟",
|
||||
"description": "检查机器人是否处于活动状态。",
|
||||
"body": {
|
||||
"pong": "Pong 🏓",
|
||||
"pong_with_time": "Pong 🏓 - {time} 微秒"
|
||||
},
|
||||
"subcommands": {
|
||||
"blitzkit": {
|
||||
"name": "blitzkit",
|
||||
"description": "测试BlitzKit的ping值(延迟值)"
|
||||
},
|
||||
"wotb": {
|
||||
"name": "战车世界闪击战",
|
||||
"description": "测试战车世界闪击战的ping值(延迟值)"
|
||||
}
|
||||
}
|
||||
},
|
||||
"player_info": {
|
||||
"name": "玩家信息",
|
||||
"description": "玩家基本信息",
|
||||
"body": {
|
||||
"title": "{name} 的信息",
|
||||
"nickname": "昵称",
|
||||
"battles": "战斗场次",
|
||||
"winrate": "胜率",
|
||||
"account_id": "账号ID",
|
||||
"created": "创建时间",
|
||||
"last_battle": "最后一场战斗"
|
||||
}
|
||||
},
|
||||
"rating": {
|
||||
"name": "评价战斗",
|
||||
"description": "评价战斗的统计数据",
|
||||
"subcommands": {
|
||||
"today": {
|
||||
"name": "今日",
|
||||
"description": "今日评价战斗统计数据"
|
||||
},
|
||||
"season": {
|
||||
"name": "赛季",
|
||||
"description": "本季评价战斗统计数据"
|
||||
}
|
||||
},
|
||||
"body": {
|
||||
"subtitle": {
|
||||
"today": "今日评价战斗统计数据",
|
||||
"season": "本季评价战斗统计数据"
|
||||
}
|
||||
},
|
||||
"errors": {
|
||||
"no_participation": "# {name} 未曾游玩评价战斗\n\n该玩家未参与本赛季的评价战斗。",
|
||||
"unrecorded_stats": "# 统计数据目前无法使用\n\nWargaming 可能暂停了服务器。 如果有连续的赛季,统计数据可能在24小时内提供。"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"website": {
|
||||
"redirect": {
|
||||
"title": "301: 已永久移动",
|
||||
@@ -666,7 +213,7 @@
|
||||
"search_bar_hint": "搜寻战车……",
|
||||
"recent": "最近查看的",
|
||||
"select_all": "全选",
|
||||
"count_singular": "1辆战车",
|
||||
"count_singular": "1 辆坦克",
|
||||
"count_plural": "{count} 辆坦克",
|
||||
"sorting_by": "按 {name} 排序",
|
||||
"clear": "清除",
|
||||
@@ -674,7 +221,7 @@
|
||||
"passive": "{name} (被动)",
|
||||
"active": "{name} (主动)",
|
||||
"no_tanks_found": {
|
||||
"body": "找不到战车。",
|
||||
"body": "未找到坦克。",
|
||||
"search_again": "请尝试重新搜索。",
|
||||
"clear_filters": "请尝试清除筛选。"
|
||||
},
|
||||
@@ -688,11 +235,11 @@
|
||||
"survivability.volume": "体积",
|
||||
"survivability.length": "长度",
|
||||
"fire.dpm": "标准炮弹 每分钟伤害血量",
|
||||
"fire.dpmPremium": "加值炮弹 每分钟伤害血量",
|
||||
"fire.dpmPremium": "金币炮弹 每分钟伤害值",
|
||||
"fire.reload": "装填时间",
|
||||
"fire.caliber": "口径",
|
||||
"fire.standardPenetration": "标准炮弹穿透力",
|
||||
"fire.premiumPenetration": "加值炮弹穿透力",
|
||||
"fire.premiumPenetration": "金币炮弹穿透力",
|
||||
"fire.tertiaryPenetration": "第三种炮弹穿透力",
|
||||
"fire.damage": "炮弹伤害值",
|
||||
"fire.moduleDamage": "模组伤害值",
|
||||
@@ -734,17 +281,9 @@
|
||||
}
|
||||
},
|
||||
"home": {
|
||||
"pwa": {
|
||||
"title": "安装 BlitzKit 应用程序",
|
||||
"new": "新增",
|
||||
"checking": "正在检查兼容性……",
|
||||
"instructions": "Apple 设备的说明。",
|
||||
"install": "安装",
|
||||
"dismiss": "取消"
|
||||
},
|
||||
"discord": {
|
||||
"join_short": "加入超級酷的人群!",
|
||||
"join_long": "加入我們的Discord社群,和超酷的人一起聊天!",
|
||||
"join_short": "加入超级酷的人群!",
|
||||
"join_long": "加入我们的Discord社群,和超酷的人一起聊天!",
|
||||
"action": "Discord"
|
||||
},
|
||||
"hero": {
|
||||
@@ -758,7 +297,7 @@
|
||||
"title": "其他酷炫的项目"
|
||||
},
|
||||
"help_translate": "请帮忙将 {name} 翻译成 {language}!",
|
||||
"seo_description": "战车世界闪击战 全方位工具"
|
||||
"seo_description": "坦克世界闪击战 全方位工具"
|
||||
},
|
||||
"docs": {
|
||||
"patches": {
|
||||
@@ -793,7 +332,7 @@
|
||||
"proceed": "继续操作"
|
||||
},
|
||||
"generate": "创建游玩列表",
|
||||
"name": "遊玩列表",
|
||||
"name": "游玩列表",
|
||||
"description": "坦克游玩列表生成器",
|
||||
"seo_description": "想不到在坦克世界闪击战玩什么? 使用BlitzKit 游玩列表来获得建议!",
|
||||
"button": "生成",
|
||||
@@ -802,7 +341,7 @@
|
||||
"mixer": {
|
||||
"name": "组装",
|
||||
"button": "混合搭配",
|
||||
"description": "混合坦克模块",
|
||||
"description": "混搭不同坦克间的模块",
|
||||
"seo_description": "《坦克世界:闪击战》的车体, 炮塔, 主炮混合搭配",
|
||||
"screenshot": "屏幕截图",
|
||||
"randomize": "随机搭配"
|
||||
@@ -953,8 +492,9 @@
|
||||
"tier": "阶级",
|
||||
"type": "战车类型",
|
||||
"dev_id": "开发参数:ID",
|
||||
"dev_name": "DEV: NAME",
|
||||
"purchase": "购买价格",
|
||||
"restoration": "恢复战车价格",
|
||||
"restoration": "恢复坦克价格",
|
||||
"sale": "出售价格",
|
||||
"research": "研发所需经验"
|
||||
},
|
||||
@@ -973,6 +513,11 @@
|
||||
},
|
||||
"configuration": {
|
||||
"title": "配置设定",
|
||||
"equalizer": {
|
||||
"title": "Equalizer",
|
||||
"equalize": "Equalize",
|
||||
"beta": "测试版"
|
||||
},
|
||||
"modules": {
|
||||
"title": "坦克模块",
|
||||
"stock": "白板",
|
||||
@@ -1005,8 +550,8 @@
|
||||
"title": "属性",
|
||||
"compare": {
|
||||
"label": "比较",
|
||||
"class": "{tier}阶 {class}",
|
||||
"tier": "所有 {tier} 阶",
|
||||
"class": "{tier} 阶的 {class}",
|
||||
"tier": "所有{tier} 阶的",
|
||||
"all": "所有坦克"
|
||||
},
|
||||
"values": {
|
||||
@@ -1049,10 +594,10 @@
|
||||
"dispersionGunDamaged": "主炮损坏时",
|
||||
"gunDepression": "俯角",
|
||||
"gunElevation": "仰角",
|
||||
"gunFrontalDepression": "车辆前部俯角",
|
||||
"gunFrontalElevation": "车辆前部仰角",
|
||||
"gunRearDepression": "车辆後部俯角",
|
||||
"gunRearElevation": "车辆後部仰角",
|
||||
"gunFrontalDepression": "车体前部俯角",
|
||||
"gunFrontalElevation": "车体前部仰角",
|
||||
"gunRearDepression": "车体后部俯角",
|
||||
"gunRearElevation": "车体后部仰角",
|
||||
"azimuthLeft": "左射界",
|
||||
"azimuthRight": "右射界",
|
||||
"speedForwards": "最高前进速度",
|
||||
@@ -1089,8 +634,8 @@
|
||||
"shellCapacity": "携弹量",
|
||||
"gunType": "炮管类型",
|
||||
"penetrationAt250m": "两百五十米处的穿透力",
|
||||
"burstShells": "Burst shell count",
|
||||
"burstInterShell": "Burst inter-shell"
|
||||
"burstShells": "爆破计数",
|
||||
"burstInterShell": "爆破弹"
|
||||
}
|
||||
},
|
||||
"firepower": {
|
||||
@@ -1142,7 +687,8 @@
|
||||
},
|
||||
"skills": {
|
||||
"clear": "清除",
|
||||
"maximize": "最大化"
|
||||
"maximize": "最大化",
|
||||
"equalize": "平衡"
|
||||
},
|
||||
"modules": {
|
||||
"stock": "白板",
|
||||
@@ -1252,7 +798,7 @@
|
||||
"description": "用于串流的嵌入",
|
||||
"seo_description": "创建具有极高自订化的《坦克世界:闪击战》串流嵌入功能",
|
||||
"coming_soon": "更多嵌入功能即将推出。",
|
||||
"suggest": "建议与想法",
|
||||
"suggest": "建议与想法。",
|
||||
"preview": {
|
||||
"title": "示例预览",
|
||||
"upload": "上传测试背景"
|
||||
|
||||
@@ -24,7 +24,6 @@
|
||||
"fast-xml-parser": "^5.2.5",
|
||||
"googleapis": "^162.0.0",
|
||||
"lodash-es": "^4.17.21",
|
||||
"lz4js": "^0.2.0",
|
||||
"progress": "^2.0.3",
|
||||
"puppeteer": "^24.22.3",
|
||||
"sharp": "^0.34.4",
|
||||
|
||||
@@ -4,7 +4,7 @@ import { mkdir, writeFile } from "fs/promises";
|
||||
import { parse as parsePath } from "path";
|
||||
import ProgressBar from "progress";
|
||||
import { parse as parseYaml, stringify as stringifyYaml } from "yaml";
|
||||
import { vfs } from "./buildAssets/constants";
|
||||
import { PATCHES_ROOT, vfs } from "./buildAssets/constants";
|
||||
import { writeDVPL } from "./core/blitz/writeDVPL";
|
||||
|
||||
const versionTextFile = await vfs.text(`Data/version.txt`);
|
||||
@@ -20,27 +20,30 @@ let patchIndex = 1;
|
||||
while (true) {
|
||||
const response = await fetch(
|
||||
`${assertSecret(
|
||||
import.meta.env.WOTB_DLC_CDN
|
||||
)}/dlc/s${currentVersion}_${patchIndex}.yaml`
|
||||
import.meta.env.WOTB_DLC_CDN,
|
||||
)}/dlc/s${currentVersion}_${patchIndex}.yaml`,
|
||||
);
|
||||
|
||||
if (response.status === 200) {
|
||||
console.log(patchIndex, response.status)
|
||||
|
||||
if (!response.ok) break;
|
||||
|
||||
console.log(`Applying patch ${patchIndex}...`);
|
||||
|
||||
const data = parseYaml(await response.text());
|
||||
const dvpm = await fetch(
|
||||
`${assertSecret(import.meta.env.WOTB_DLC_CDN)}/dlc/${data.dx11}`
|
||||
`${assertSecret(import.meta.env.WOTB_DLC_CDN)}/dlc/${data.dx11}`,
|
||||
).then((response) => response.arrayBuffer());
|
||||
const dvpd = await fetch(
|
||||
`${assertSecret(import.meta.env.WOTB_DLC_CDN)}/dlc/${data.dx11.replace(
|
||||
".dvpm",
|
||||
".dvpd"
|
||||
)}`
|
||||
".dvpd",
|
||||
)}`,
|
||||
).then((response) => response.arrayBuffer());
|
||||
const files = await dvp(dvpm, dvpd);
|
||||
const bar = new ProgressBar(
|
||||
`Patching ${files.length} files :bar`,
|
||||
files.length
|
||||
files.length,
|
||||
);
|
||||
|
||||
for (const { path, data } of files) {
|
||||
@@ -49,43 +52,55 @@ while (true) {
|
||||
const { dir } = parsePath(path);
|
||||
|
||||
try {
|
||||
await mkdir(`Data/${dir}`, { recursive: true });
|
||||
await mkdir(`${PATCHES_ROOT}/Data/${dir}`, { recursive: true });
|
||||
} catch (error) {
|
||||
console.warn(`Failed to make directory "${dir}"`);
|
||||
}
|
||||
|
||||
const isDvpl = path.endsWith(".dvpl");
|
||||
const buffer = Buffer.from(data);
|
||||
|
||||
await writeFile(
|
||||
`Data/${path}${isDvpl ? "" : ".dvpl"}`,
|
||||
new Uint8Array(isDvpl ? buffer : writeDVPL(buffer))
|
||||
`${PATCHES_ROOT}/Data/${path}`,
|
||||
new Uint8Array(buffer),
|
||||
);
|
||||
|
||||
bar.tick();
|
||||
}
|
||||
|
||||
if ("dynamicContentLocalizationsDir" in data) {
|
||||
console.log("Found dynamic content localizations; patching...");
|
||||
console.log('patches done for patch')
|
||||
|
||||
if ("dynamicContentLocalizationsDir" in data) {
|
||||
console.log(
|
||||
`${assertSecret(import.meta.env.WOTB_DLC_CDN)}/dlc/${
|
||||
data.dynamicContentLocalizationsDir
|
||||
}/en.yaml`,
|
||||
);
|
||||
const localizationsResponse = await fetch(
|
||||
`${assertSecret(import.meta.env.WOTB_DLC_CDN)}/dlc/${
|
||||
data.dynamicContentLocalizationsDir
|
||||
}/en.yaml`
|
||||
}/en.yaml`,
|
||||
);
|
||||
console.log('fetched')
|
||||
const newStrings = parseYaml(await localizationsResponse.text());
|
||||
const oldStrings = await vfs.yaml<Record<string, string>>(
|
||||
`Data/Strings/en.yaml`
|
||||
);
|
||||
console.log('got new strings')
|
||||
const oldStrings =
|
||||
await vfs.yaml<Record<string, string>>(`Data/Strings/en.yaml`);
|
||||
console.log('got old strings')
|
||||
const patchedStrings = { ...oldStrings, ...newStrings };
|
||||
const patchedContent = stringifyYaml(patchedStrings);
|
||||
console.log('stringified')
|
||||
|
||||
await mkdir(`${PATCHES_ROOT}/Data/Strings`, { recursive: true });
|
||||
console.log('mkdir')
|
||||
await writeFile(
|
||||
`Data/Strings/en.yaml`,
|
||||
new Uint8Array(writeDVPL(Buffer.from(patchedContent)))
|
||||
`${PATCHES_ROOT}/Data/Strings/en.yaml`,
|
||||
new Uint8Array((Buffer.from(patchedContent))),
|
||||
);
|
||||
console.log('file')
|
||||
}
|
||||
|
||||
patchIndex++;
|
||||
} else break;
|
||||
}
|
||||
|
||||
vfs.dispose()
|
||||
process.exit(0);
|
||||
@@ -1,5 +1,6 @@
|
||||
import {
|
||||
AverageDefinitions,
|
||||
AverageDefinitionsAllStats,
|
||||
AverageDefinitionsEntry,
|
||||
type AverageDefinitionsManifest,
|
||||
type IndividualTankStats,
|
||||
@@ -30,9 +31,6 @@ type OptionalSecondLevel<T> = {
|
||||
};
|
||||
};
|
||||
|
||||
type AverageDefinitionsEntrySubPartial =
|
||||
OptionalSecondLevel<AverageDefinitionsEntry>;
|
||||
|
||||
const MINUTE = 60 * 1000;
|
||||
const HOUR = 60 * MINUTE;
|
||||
const DAY = 24 * HOUR;
|
||||
@@ -47,15 +45,15 @@ const preDiscoveredIds = await fetchPreDiscoveredIds();
|
||||
const playerIds: Record<Region, number[][]> = {
|
||||
asia: chunk(
|
||||
preDiscoveredIds.filter((id) => idToRegion(id) === "asia"),
|
||||
PLAYER_IDS_PER_CALL
|
||||
PLAYER_IDS_PER_CALL,
|
||||
),
|
||||
com: chunk(
|
||||
preDiscoveredIds.filter((id) => idToRegion(id) === "com"),
|
||||
PLAYER_IDS_PER_CALL
|
||||
PLAYER_IDS_PER_CALL,
|
||||
),
|
||||
eu: chunk(
|
||||
preDiscoveredIds.filter((id) => idToRegion(id) === "eu"),
|
||||
PLAYER_IDS_PER_CALL
|
||||
PLAYER_IDS_PER_CALL,
|
||||
),
|
||||
};
|
||||
let regionIndex = 0;
|
||||
@@ -71,7 +69,7 @@ times(THREADS, async () => {
|
||||
const regionIds = playerIds[region];
|
||||
const [ids] = regionIds.splice(
|
||||
Math.floor(Math.random() * regionIds.length),
|
||||
1
|
||||
1,
|
||||
);
|
||||
const accountInfo = await getAccountInfo(region, ids, undefined, {
|
||||
fields: "last_battle_time,statistics.all.battles",
|
||||
@@ -104,8 +102,8 @@ times(THREADS, async () => {
|
||||
filteredIds.map((id) =>
|
||||
getTankStats(region, id, {
|
||||
fields: "last_battle_time,battle_life_time,all,tank_id",
|
||||
})
|
||||
)
|
||||
}),
|
||||
),
|
||||
);
|
||||
|
||||
players.forEach((tanks) => {
|
||||
@@ -114,7 +112,7 @@ times(THREADS, async () => {
|
||||
|
||||
if (!tankIds.includes(tank.tank_id)) {
|
||||
console.log(
|
||||
`Found new tank: ${tank.tank_id} (${tankIds.length + 1})`
|
||||
`Found new tank: ${tank.tank_id} (${tankIds.length + 1})`,
|
||||
);
|
||||
tankIds.push(tank.tank_id);
|
||||
tanksSorted[tank.tank_id] = [];
|
||||
@@ -140,7 +138,7 @@ async function postWork() {
|
||||
console.log(
|
||||
`Generating statistics based on ${samples.d_120.toLocaleString()} players (${samples.total.toLocaleString()} checked in total) and ${
|
||||
tankIds.length
|
||||
} tanks...`
|
||||
} tanks...`,
|
||||
);
|
||||
|
||||
using uploader = new AssetUploader("averages");
|
||||
@@ -152,7 +150,12 @@ async function postWork() {
|
||||
// (tank) => Date.now() - tank.last_battle_time * 1000 <= MAX_ACTIVITY_TIME,
|
||||
// );
|
||||
const tanks = tanksSortedEntry;
|
||||
const entry: AverageDefinitionsEntrySubPartial = {
|
||||
const entry: {
|
||||
mu: Partial<Record<keyof AverageDefinitionsAllStats, number>>;
|
||||
sigma: Partial<Record<keyof AverageDefinitionsAllStats, number>>;
|
||||
r: Partial<Record<keyof AverageDefinitionsAllStats, number>>;
|
||||
samples: Samples;
|
||||
} = {
|
||||
mu: {},
|
||||
sigma: {},
|
||||
r: {},
|
||||
@@ -162,13 +165,13 @@ async function postWork() {
|
||||
tanks.forEach((tank) => {
|
||||
const timeSinceLastActivity = Date.now() - tank.last_battle_time * 1000;
|
||||
|
||||
entry.samples.total++;
|
||||
if (timeSinceLastActivity <= 120 * DAY) entry.samples.d_120++;
|
||||
if (timeSinceLastActivity <= 90 * DAY) entry.samples.d_90++;
|
||||
if (timeSinceLastActivity <= 60 * DAY) entry.samples.d_60++;
|
||||
if (timeSinceLastActivity <= 30 * DAY) entry.samples.d_30++;
|
||||
if (timeSinceLastActivity <= 7 * DAY) entry.samples.d_7++;
|
||||
if (timeSinceLastActivity <= 1 * DAY) entry.samples.d_1++;
|
||||
entry.samples!.total++;
|
||||
if (timeSinceLastActivity <= 120 * DAY) entry.samples!.d_120++;
|
||||
if (timeSinceLastActivity <= 90 * DAY) entry.samples!.d_90++;
|
||||
if (timeSinceLastActivity <= 60 * DAY) entry.samples!.d_60++;
|
||||
if (timeSinceLastActivity <= 30 * DAY) entry.samples!.d_30++;
|
||||
if (timeSinceLastActivity <= 7 * DAY) entry.samples!.d_7++;
|
||||
if (timeSinceLastActivity <= 1 * DAY) entry.samples!.d_1++;
|
||||
});
|
||||
|
||||
const dataWY = tanks.map((tank) => ({
|
||||
@@ -191,7 +194,7 @@ async function postWork() {
|
||||
function sum(slicer: (data: DataPoint) => number) {
|
||||
return data.reduce(
|
||||
(accumulator, data) => accumulator + slicer(data),
|
||||
0
|
||||
0,
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -6,13 +6,15 @@ export async function boosterIcons() {
|
||||
console.log("Building booster icons...");
|
||||
|
||||
const uploader = new AssetUploader("booster icons");
|
||||
const boosterFiles = vfs
|
||||
const boosterFiles = await vfs
|
||||
.dir("Data/Gfx/Shared/boosters")
|
||||
.filter(
|
||||
(file) => !file.includes("@2x.txt") && !file.startsWith("texture0")
|
||||
.then((files) =>
|
||||
files.filter(
|
||||
(file) => !file.includes("@2x.txt") && !file.startsWith("texture0"),
|
||||
),
|
||||
);
|
||||
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) {
|
||||
|
||||
@@ -6,7 +6,7 @@ export async function camouflageIcons() {
|
||||
|
||||
using uploader = new AssetUploader("camo icons");
|
||||
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" });
|
||||
|
||||
@@ -1,10 +1,15 @@
|
||||
import { assertSecret } from "@blitzkit/core";
|
||||
import { AbstractVFS } from "../core/vfs/abstract";
|
||||
import { LocalVFS } from "../core/vfs/local";
|
||||
import { SteamVFS } from "../core/vfs/steam";
|
||||
import { ZipVFS } from "../core/vfs/zip";
|
||||
import { MixedVFS } from "../core/vfs/mixed";
|
||||
|
||||
export const PATCHES_ROOT = "../../temp/patches";
|
||||
|
||||
const steamPattern = /steam:(\d+)\/(\d+)/;
|
||||
const zipPattern = /zip:(.+)/;
|
||||
const localePattern = /local:"?(.+)"?/;
|
||||
|
||||
const source = Bun.argv
|
||||
.find((arg) => arg.startsWith("--source="))
|
||||
@@ -21,13 +26,18 @@ if (!source) {
|
||||
assertSecret(import.meta.env.STEAM_USERNAME),
|
||||
assertSecret(import.meta.env.STEAM_PASSWORD),
|
||||
app,
|
||||
depot
|
||||
depot,
|
||||
).init();
|
||||
} else if (zipPattern.test(source)) {
|
||||
const [, url] = source.match(zipPattern)!;
|
||||
resolved = await new ZipVFS(url).init();
|
||||
} else if (localePattern.test(source)) {
|
||||
const [, path] = source.match(localePattern)!;
|
||||
resolved = await new LocalVFS(path).init();
|
||||
} else {
|
||||
throw new Error("No valid source specified");
|
||||
}
|
||||
|
||||
resolved = new MixedVFS([new LocalVFS(PATCHES_ROOT), resolved]);
|
||||
|
||||
export const vfs = resolved;
|
||||
@@ -1,5 +1,6 @@
|
||||
import sharp from "sharp";
|
||||
import { AssetUploader } from "../core/github/assetUploader";
|
||||
import { parsePackedSpriteRect } from "../core/blitz/parsePackedSpriteRect";
|
||||
import { vfs } from "./constants";
|
||||
import { ConsumablesCommon, ProvisionsCommon } from "./definitions";
|
||||
|
||||
@@ -13,31 +14,61 @@ interface Mappings {
|
||||
|
||||
const listItemsPattern = /<items path="(.+)\.xml"\/>/g;
|
||||
|
||||
async function extractPackedIcon(
|
||||
texture: sharp.Sharp,
|
||||
sizes: number[],
|
||||
context: string,
|
||||
) {
|
||||
const [left, top, width, height] = sizes;
|
||||
const bounds = [left, top, width, height];
|
||||
|
||||
if (!bounds.every(Number.isInteger)) {
|
||||
throw new Error(
|
||||
`Invalid RIFF sprite bounds for ${context}: ${bounds.join(" ")}`,
|
||||
);
|
||||
}
|
||||
|
||||
const metadata = await texture.metadata();
|
||||
|
||||
if (metadata.width === undefined || metadata.height === undefined) {
|
||||
throw new Error(`Failed to read image dimensions for ${context}`);
|
||||
}
|
||||
|
||||
if (
|
||||
left < 0 ||
|
||||
top < 0 ||
|
||||
width <= 0 ||
|
||||
height <= 0 ||
|
||||
left + width > metadata.width ||
|
||||
top + height > metadata.height
|
||||
) {
|
||||
throw new Error(
|
||||
`Out-of-bounds RIFF sprite for ${context}: ${bounds.join(" ")} in ${metadata.width}x${metadata.height}`,
|
||||
);
|
||||
}
|
||||
|
||||
return await texture.clone().extract({ left, top, width, height }).toBuffer();
|
||||
}
|
||||
|
||||
export async function consumableProvisionIcons() {
|
||||
console.log("Building consumable and provision icons...");
|
||||
|
||||
using uploader = new AssetUploader("consumable and provision icons");
|
||||
const styles = [
|
||||
"UI/Styles/Lobby/Inventory/InventoryNormalStyles.yaml",
|
||||
"UI/Styles/Lobby/Inventory/Event/InventoryBigStyles.yaml",
|
||||
"UI/Styles/Lobby/Inventory/Event/InventoryNormalStyles.yaml",
|
||||
"UI/Styles/Lobby/Inventory/InventoryNormalStyles.yaml",
|
||||
"UI/Screens3/Lobby/Inventory/Equipment/EquipmentItemImage.style.yaml",
|
||||
"UI/Screens/Battle/Styles/BattleEquipmentStyles.yaml",
|
||||
];
|
||||
const styleSheets = await Promise.all(
|
||||
styles.map(async (path) =>
|
||||
Object.values(
|
||||
(
|
||||
await vfs.yaml<Mappings>(`Data/${path}`)
|
||||
).StyleSheets
|
||||
)
|
||||
)
|
||||
Object.values((await vfs.yaml<Mappings>(`Data/${path}`)).StyleSheets),
|
||||
),
|
||||
).then((array) => array.flat());
|
||||
|
||||
for (const match of (
|
||||
await vfs.text(
|
||||
`Data/XML/item_defs/vehicles/common/consumables/list.xml`
|
||||
)
|
||||
await vfs.text(`Data/XML/item_defs/vehicles/common/consumables/list.xml`)
|
||||
).matchAll(listItemsPattern)) {
|
||||
const consumablesCommon = await vfs.xml<{
|
||||
root: ConsumablesCommon;
|
||||
@@ -46,13 +77,13 @@ export async function consumableProvisionIcons() {
|
||||
for (const consumable of Object.values(consumablesCommon.root)) {
|
||||
const styleSheet = styleSheets.find((styleSheet) =>
|
||||
styleSheet.selectors.some((selector) =>
|
||||
selector.includes(`${consumable.icon} `)
|
||||
)
|
||||
selector.includes(`${consumable.icon} `),
|
||||
),
|
||||
);
|
||||
|
||||
if (!styleSheet) {
|
||||
console.warn(
|
||||
`No style sheet found for consumable ${consumable.icon}; skipping...`
|
||||
`No style sheet found for consumable ${consumable.icon}; skipping...`,
|
||||
);
|
||||
continue;
|
||||
}
|
||||
@@ -62,11 +93,21 @@ export async function consumableProvisionIcons() {
|
||||
.replace(".psd", "")
|
||||
.replace(".txt", "");
|
||||
|
||||
if (vfs.resolve(`Data/${configPath}.packed.webp`)) {
|
||||
const image = sharp(
|
||||
await vfs.file(`Data/${configPath}.packed.webp`)
|
||||
);
|
||||
const content = await image.trim({ threshold: 100 }).toBuffer();
|
||||
if (await vfs.resolve(`Data/${configPath}.packed.webp`)) {
|
||||
const packedBuffer = await vfs.file(`Data/${configPath}.packed.webp`);
|
||||
const consumablesTexture = sharp(packedBuffer);
|
||||
const sizes = parsePackedSpriteRect(packedBuffer);
|
||||
let content: Buffer;
|
||||
|
||||
if (sizes) {
|
||||
content = await extractPackedIcon(
|
||||
consumablesTexture,
|
||||
sizes,
|
||||
`consumable ${consumable.icon}`,
|
||||
);
|
||||
} else {
|
||||
content = await consumablesTexture.trim({ threshold: 80 }).toBuffer();
|
||||
}
|
||||
|
||||
await uploader.add({
|
||||
path: `icons/consumables/${consumable.id}.webp`,
|
||||
@@ -78,8 +119,8 @@ export async function consumableProvisionIcons() {
|
||||
`${`Data/${configPath}`
|
||||
.split("/")
|
||||
.slice(0, -1)
|
||||
.join("/")}/texture0.packed.webp`
|
||||
)
|
||||
.join("/")}/texture0.packed.webp`,
|
||||
),
|
||||
);
|
||||
const sizes = (await vfs.text(`Data/${configPath}.txt`))
|
||||
.split("\n")[4]
|
||||
@@ -104,9 +145,7 @@ export async function consumableProvisionIcons() {
|
||||
}
|
||||
|
||||
for (const match of (
|
||||
await vfs.text(
|
||||
`Data/XML/item_defs/vehicles/common/provisions/list.xml`
|
||||
)
|
||||
await vfs.text(`Data/XML/item_defs/vehicles/common/provisions/list.xml`)
|
||||
).matchAll(listItemsPattern)) {
|
||||
const provisionsCommon = await vfs.xml<{
|
||||
root: ProvisionsCommon;
|
||||
@@ -115,13 +154,13 @@ export async function consumableProvisionIcons() {
|
||||
for (const provision of Object.values(provisionsCommon.root)) {
|
||||
const styleSheet = styleSheets.find((styleSheet) =>
|
||||
styleSheet.selectors.some((selector) =>
|
||||
selector.includes(`${provision.icon} `)
|
||||
)
|
||||
selector.includes(`${provision.icon} `),
|
||||
),
|
||||
);
|
||||
|
||||
if (!styleSheet) {
|
||||
console.warn(
|
||||
`No style sheet found for provision ${provision.icon}; skipping...`
|
||||
`No style sheet found for provision ${provision.icon}; skipping...`,
|
||||
);
|
||||
continue;
|
||||
}
|
||||
@@ -131,11 +170,21 @@ export async function consumableProvisionIcons() {
|
||||
.replace(".psd", "")
|
||||
.replace(".txt", "");
|
||||
|
||||
if (vfs.resolve(`Data/${configPath}.packed.webp`)) {
|
||||
const image = sharp(
|
||||
await vfs.file(`Data/${configPath}.packed.webp`)
|
||||
);
|
||||
const content = await image.trim({ threshold: 100 }).toBuffer();
|
||||
if (await vfs.resolve(`Data/${configPath}.packed.webp`)) {
|
||||
const packedBuffer = await vfs.file(`Data/${configPath}.packed.webp`);
|
||||
const provisionsTexture = sharp(packedBuffer);
|
||||
const sizes = parsePackedSpriteRect(packedBuffer);
|
||||
let content: Buffer;
|
||||
|
||||
if (sizes) {
|
||||
content = await extractPackedIcon(
|
||||
provisionsTexture,
|
||||
sizes,
|
||||
`provision ${provision.icon}`,
|
||||
);
|
||||
} else {
|
||||
content = await provisionsTexture.trim({ threshold: 80 }).toBuffer();
|
||||
}
|
||||
|
||||
await uploader.add({
|
||||
path: `icons/provisions/${provision.id}.webp`,
|
||||
@@ -147,8 +196,8 @@ export async function consumableProvisionIcons() {
|
||||
`${`Data/${configPath}`
|
||||
.split("/")
|
||||
.slice(0, -1)
|
||||
.join("/")}/texture0.packed.webp`
|
||||
)
|
||||
.join("/")}/texture0.packed.webp`,
|
||||
),
|
||||
);
|
||||
const sizes = (await vfs.text(`Data/${configPath}.txt`))
|
||||
.split("\n")[4]
|
||||
|
||||
@@ -20,7 +20,7 @@ export async function currencies() {
|
||||
|
||||
for (const [file, name] of ICONS) {
|
||||
const content = await sharp(
|
||||
await vfs.file(`Data/Gfx/Lobby/currency/${file}`)
|
||||
await vfs.file(`Data/Gfx/Lobby/currency/${file}`),
|
||||
)
|
||||
.trim()
|
||||
.toBuffer();
|
||||
@@ -36,14 +36,14 @@ export async function currencies() {
|
||||
.then((glossary) =>
|
||||
Object.values(glossary)
|
||||
.entries()
|
||||
.filter(([key]) => /^prx_season_\d+$/.test(`${key}`))
|
||||
.filter(([key]) => /^prx_season_\d+$/.test(`${key}`)),
|
||||
);
|
||||
|
||||
for (const [key, item] of glossary) {
|
||||
if (item.image_url === null) throw new Error(`No image_url for ${key}`);
|
||||
|
||||
const imageRaw = await fetch(item.image_url).then((response) =>
|
||||
response.arrayBuffer()
|
||||
response.arrayBuffer(),
|
||||
);
|
||||
const content = await sharp(imageRaw)
|
||||
.trim({
|
||||
|
||||
@@ -8,6 +8,7 @@ import {
|
||||
ConsumableTankCategoryFilterCategory,
|
||||
Crew,
|
||||
CrewType,
|
||||
Equalizer,
|
||||
EquipmentDefinitions,
|
||||
EquipmentSlot,
|
||||
GameDefinitions,
|
||||
@@ -32,6 +33,7 @@ import {
|
||||
} from "@blitzkit/core";
|
||||
import { SUPPORTED_LOCALE_BLITZ_MAP } from "@blitzkit/i18n";
|
||||
import locales from "@blitzkit/i18n/locales.json";
|
||||
import { readFile } from "fs/promises";
|
||||
import { deburr } from "lodash-es";
|
||||
import { parse as parsePath } from "path";
|
||||
import type { Vector3Tuple } from "three";
|
||||
@@ -81,16 +83,16 @@ const blitzTankFilterDefinitionCategoryToBlitzkit: Record<
|
||||
BlitzTankFilterDefinitionCategory,
|
||||
ConsumableTankCategoryFilterCategory
|
||||
> = {
|
||||
clip: ConsumableTankCategoryFilterCategory.CLIP,
|
||||
clip: ConsumableTankCategoryFilterCategory.CONSUMABLE_TANK_CATEGORY_FILTER_CATEGORY_CLIP,
|
||||
};
|
||||
function vector3TupleToBlitzkit(tuple: Vector3Tuple) {
|
||||
return { x: tuple[0], y: tuple[1], z: tuple[2] } satisfies Vector3;
|
||||
}
|
||||
const blitzTankClassToBlitzkit: Record<BlitzTankClass, TankClass> = {
|
||||
lightTank: TankClass.LIGHT,
|
||||
"AT-SPG": TankClass.TANK_DESTROYER,
|
||||
heavyTank: TankClass.HEAVY,
|
||||
mediumTank: TankClass.MEDIUM,
|
||||
lightTank: TankClass.TANK_CLASS_LIGHT,
|
||||
"AT-SPG": TankClass.TANK_CLASS_TANK_DESTROYER,
|
||||
heavyTank: TankClass.TANK_CLASS_HEAVY,
|
||||
mediumTank: TankClass.TANK_CLASS_MEDIUM,
|
||||
};
|
||||
export interface BlitzStrings {
|
||||
[key: string]: string;
|
||||
@@ -135,7 +137,7 @@ export interface ChassisDefinitionsList {
|
||||
}
|
||||
type VehicleDefinitionArmor = Record<
|
||||
string,
|
||||
number | { vehicleDamageFactor: 0; "#text": number }
|
||||
number | { vehicleDamageFactor: 0; "#text": number } | number[]
|
||||
>;
|
||||
interface UnlocksInner {
|
||||
cost: number | string;
|
||||
@@ -149,18 +151,18 @@ type BlitzModuleType = {
|
||||
type UnlocksListing = BlitzModuleType | undefined;
|
||||
type BlitzCrewType = "commander" | "radioman" | "gunner" | "driver" | "loader";
|
||||
const blitzCrewTypeToBlitzkit: Record<BlitzCrewType, CrewType> = {
|
||||
commander: CrewType.COMMANDER,
|
||||
driver: CrewType.DRIVER,
|
||||
gunner: CrewType.GUNNER,
|
||||
loader: CrewType.LOADER,
|
||||
radioman: CrewType.RADIOMAN,
|
||||
commander: CrewType.CREW_TYPE_COMMANDER,
|
||||
driver: CrewType.CREW_TYPE_DRIVER,
|
||||
gunner: CrewType.CREW_TYPE_GUNNER,
|
||||
loader: CrewType.CREW_TYPE_LOADER,
|
||||
radioman: CrewType.CREW_TYPE_RADIOMAN,
|
||||
};
|
||||
const blitzkitCrewTypeToBlitz: Record<CrewType, BlitzCrewType> = {
|
||||
[CrewType.COMMANDER]: "commander",
|
||||
[CrewType.DRIVER]: "driver",
|
||||
[CrewType.GUNNER]: "gunner",
|
||||
[CrewType.LOADER]: "loader",
|
||||
[CrewType.RADIOMAN]: "radioman",
|
||||
[CrewType.CREW_TYPE_COMMANDER]: "commander",
|
||||
[CrewType.CREW_TYPE_DRIVER]: "driver",
|
||||
[CrewType.CREW_TYPE_GUNNER]: "gunner",
|
||||
[CrewType.CREW_TYPE_LOADER]: "loader",
|
||||
[CrewType.CREW_TYPE_RADIOMAN]: "radioman",
|
||||
};
|
||||
interface VehicleDefinitions {
|
||||
invisibility: {
|
||||
@@ -298,7 +300,7 @@ interface VehicleDefinitions {
|
||||
type: "default";
|
||||
enabled: false;
|
||||
factorsModifiers: "";
|
||||
}
|
||||
},
|
||||
];
|
||||
};
|
||||
};
|
||||
@@ -517,20 +519,36 @@ type CombatRolesYaml = Record<
|
||||
>;
|
||||
|
||||
const blitzShellKindToBlitzkit: Record<ShellKind, ShellType> = {
|
||||
ARMOR_PIERCING: ShellType.AP,
|
||||
ARMOR_PIERCING_CR: ShellType.APCR,
|
||||
HIGH_EXPLOSIVE: ShellType.HE,
|
||||
HOLLOW_CHARGE: ShellType.HEAT,
|
||||
ARMOR_PIERCING: ShellType.SHELL_TYPE_AP,
|
||||
ARMOR_PIERCING_CR: ShellType.SHELL_TYPE_APCR,
|
||||
HIGH_EXPLOSIVE: ShellType.SHELL_TYPE_HE,
|
||||
HOLLOW_CHARGE: ShellType.SHELL_TYPE_HEAT,
|
||||
};
|
||||
export const botPattern = /^.+((tutorial_bot(\d+)?)|(TU))$/;
|
||||
const blitzModuleTypeToBlitzkit: Record<keyof BlitzModuleType, ModuleType> = {
|
||||
chassis: ModuleType.TRACKS,
|
||||
engine: ModuleType.ENGINE,
|
||||
gun: ModuleType.GUN,
|
||||
turret: ModuleType.TURRET,
|
||||
vehicle: ModuleType.VEHICLE,
|
||||
chassis: ModuleType.MODULE_TYPE_TRACKS,
|
||||
engine: ModuleType.MODULE_TYPE_ENGINE,
|
||||
gun: ModuleType.MODULE_TYPE_GUN,
|
||||
turret: ModuleType.MODULE_TYPE_TURRET,
|
||||
vehicle: ModuleType.MODULE_TYPE_VEHICLE,
|
||||
};
|
||||
|
||||
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() {
|
||||
console.log("Building definitions...");
|
||||
|
||||
@@ -555,18 +573,18 @@ export async function definitions() {
|
||||
const provisionDefinitions: ProvisionDefinitions = { provisions: {} };
|
||||
const skillDefinitions: SkillDefinitions = {
|
||||
classes: {
|
||||
[TankClass.LIGHT]: { skills: [] },
|
||||
[TankClass.MEDIUM]: { skills: [] },
|
||||
[TankClass.HEAVY]: { skills: [] },
|
||||
[TankClass.TANK_DESTROYER]: { skills: [] },
|
||||
[TankClass.TANK_CLASS_LIGHT]: { skills: [] },
|
||||
[TankClass.TANK_CLASS_MEDIUM]: { skills: [] },
|
||||
[TankClass.TANK_CLASS_HEAVY]: { skills: [] },
|
||||
[TankClass.TANK_CLASS_TANK_DESTROYER]: { skills: [] },
|
||||
},
|
||||
};
|
||||
const nations = vfs
|
||||
const nations = await vfs
|
||||
.dir("Data/XML/item_defs/vehicles")
|
||||
.filter((nation) => nation !== "common");
|
||||
.then((files) => files.filter((nation) => nation !== "common"));
|
||||
const tankStringIdMap: Record<string, number> = {};
|
||||
const optionalDevices = await vfs.xml<{ root: OptionalDevices }>(
|
||||
"Data/XML/item_defs/vehicles/common/optional_devices.xml"
|
||||
"Data/XML/item_defs/vehicles/common/optional_devices.xml",
|
||||
);
|
||||
const stringsI18n: Record<string, Record<string, string>> = {};
|
||||
|
||||
@@ -574,12 +592,12 @@ export async function definitions() {
|
||||
locales.supported.map(async ({ locale }) => {
|
||||
const blitzLocale = SUPPORTED_LOCALE_BLITZ_MAP[locale];
|
||||
const cache = await fetch(
|
||||
`https://stufficons.wgcdn.co/localizations/${blitzLocale}.yaml`
|
||||
`https://stufficons.wgcdn.co/localizations/${blitzLocale}.yaml`,
|
||||
)
|
||||
.then((response) => response.text())
|
||||
.then((string) => parseYaml(string) as BlitzStrings);
|
||||
const preInstalled = await vfs.yaml<BlitzStrings>(
|
||||
`Data/Strings/${blitzLocale}.yaml`
|
||||
`Data/Strings/${blitzLocale}.yaml`,
|
||||
);
|
||||
|
||||
stringsI18n[locale] = {
|
||||
@@ -588,7 +606,7 @@ export async function definitions() {
|
||||
};
|
||||
|
||||
console.log(`Loaded strings for ${locale}`);
|
||||
})
|
||||
}),
|
||||
);
|
||||
|
||||
function getString(name: string) {
|
||||
@@ -627,9 +645,9 @@ export async function definitions() {
|
||||
consumables,
|
||||
(
|
||||
await vfs.xml<{ root: ConsumablesCommon }>(
|
||||
`Data/XML/item_defs/vehicles/common/consumables/${match[1]}.xml`
|
||||
`Data/XML/item_defs/vehicles/common/consumables/${match[1]}.xml`,
|
||||
)
|
||||
).root
|
||||
).root,
|
||||
);
|
||||
}
|
||||
|
||||
@@ -642,39 +660,57 @@ export async function definitions() {
|
||||
provisions,
|
||||
(
|
||||
await vfs.xml<{ root: ConsumablesCommon }>(
|
||||
`Data/XML/item_defs/vehicles/common/provisions/${match[1]}.xml`
|
||||
`Data/XML/item_defs/vehicles/common/provisions/${match[1]}.xml`,
|
||||
)
|
||||
).root
|
||||
).root,
|
||||
);
|
||||
}
|
||||
|
||||
const avatar = await vfs.xml<{ root: Avatar }>(
|
||||
`Data/XML/item_defs/tankmen/avatar.xml`
|
||||
`Data/XML/item_defs/tankmen/avatar.xml`,
|
||||
);
|
||||
const maps = await vfs.yaml<Maps>(`Data/maps.yaml`);
|
||||
const tankXps = new Map<number, ResearchCost>();
|
||||
const camouflagesXml = await vfs.xml<{ root: CamouflagesXML }>(
|
||||
`Data/XML/item_defs/vehicles/common/camouflages.xml`
|
||||
`Data/XML/item_defs/vehicles/common/camouflages.xml`,
|
||||
);
|
||||
const camouflagesYaml = await vfs.yaml<CamouflagesYaml>(
|
||||
`Data/camouflages.yaml`
|
||||
`Data/camouflages.yaml`,
|
||||
);
|
||||
const camouflagesXmlEntries = Object.entries(camouflagesXml.root.camouflages);
|
||||
const squadBattleTypeStyles = await vfs.yaml<SquadBattleTypeStyles>(
|
||||
`Data/UI/Screens3/Lobby/Hangar/Squad/SquadBattleType.yaml`
|
||||
`Data/UI/Screens3/Lobby/Hangar/Squad/SquadBattleType.yaml`,
|
||||
);
|
||||
const gameTypeSelectorStyles = await vfs.yaml<SquadBattleTypeStyles>(
|
||||
`Data/UI/Screens/Lobby/Hangar/GameTypeSelector.yaml`
|
||||
`Data/UI/Screens/Lobby/Hangar/GameTypeSelector.yaml`,
|
||||
);
|
||||
const gameModeNativeNames: Record<string, number> = {};
|
||||
const combatRoles = await vfs.yaml<CombatRolesYaml>(
|
||||
`Data/XML/item_defs/vehicles/common/combat_roles.yaml`
|
||||
`Data/XML/item_defs/vehicles/common/combat_roles.yaml`,
|
||||
);
|
||||
const consumableNativeNames: Record<string, number> = {};
|
||||
const provisionNativeNames: Record<string, number> = {};
|
||||
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(
|
||||
/"(\d+)" -> "(battleType\/([a-zA-Z]+))"/g
|
||||
/"(\d+)" -> "(battleType\/([a-zA-Z]+))"/g,
|
||||
)) {
|
||||
const id = Number(match[1]);
|
||||
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(
|
||||
/eGameMode\.([a-zA-Z]+) -> "~res:\/Gfx\/UI\/Hangar\/GameTypes\/battle-type_([^"]+)"/g
|
||||
/eGameMode\.([a-zA-Z]+) -> "~res:\/Gfx\/UI\/Hangar\/GameTypes\/battle-type_([^"]+)"/g,
|
||||
)) {
|
||||
Object.entries(gameModeNativeNames).forEach(([key, value]) => {
|
||||
if (key.toLowerCase() === match[2].toLowerCase()) {
|
||||
@@ -720,7 +756,7 @@ export async function definitions() {
|
||||
|
||||
for (const nation of nations) {
|
||||
const tankList = await vfs.xml<{ root: VehicleDefinitionList }>(
|
||||
`Data/XML/item_defs/vehicles/${nation}/list.xml`
|
||||
`Data/XML/item_defs/vehicles/${nation}/list.xml`,
|
||||
);
|
||||
|
||||
for (const tankKey in tankList.root) {
|
||||
@@ -761,7 +797,7 @@ export async function definitions() {
|
||||
console.warn(
|
||||
`Multiple tanks share slug ${slug}: ${requesters
|
||||
.map(({ key }) => key)
|
||||
.join(", ")}`
|
||||
.join(", ")}`,
|
||||
);
|
||||
|
||||
if (requesters.length !== 2) {
|
||||
@@ -791,7 +827,7 @@ export async function definitions() {
|
||||
|
||||
if (canonical === undefined) {
|
||||
throw new Error(
|
||||
"Two tutorial bots share the same slug? The world is truly broken."
|
||||
"Two tutorial bots share the same slug? The world is truly broken.",
|
||||
);
|
||||
}
|
||||
|
||||
@@ -804,7 +840,7 @@ export async function definitions() {
|
||||
|
||||
for (const nation of nations) {
|
||||
const tankList = await vfs.xml<{ root: VehicleDefinitionList }>(
|
||||
`Data/XML/item_defs/vehicles/${nation}/list.xml`
|
||||
`Data/XML/item_defs/vehicles/${nation}/list.xml`,
|
||||
);
|
||||
const turretList = await vfs.xml<{
|
||||
root: TurretDefinitionsList;
|
||||
@@ -857,7 +893,7 @@ export async function definitions() {
|
||||
: Number(item.cost.split(":")[1]),
|
||||
},
|
||||
} satisfies Unlock;
|
||||
})
|
||||
}),
|
||||
)
|
||||
.flat();
|
||||
}
|
||||
@@ -872,10 +908,10 @@ export async function definitions() {
|
||||
const tank = tankList.root[tankKey];
|
||||
let tankPrice: TankPrice;
|
||||
const tankDefinition = await vfs.xml<{ root: VehicleDefinitions }>(
|
||||
`Data/XML/item_defs/vehicles/${nation}/${tankKey}.xml`
|
||||
`Data/XML/item_defs/vehicles/${nation}/${tankKey}.xml`,
|
||||
);
|
||||
const tankParameters = await vfs.yaml<TankParameters>(
|
||||
`Data/3d/Tanks/Parameters/${nation}/${tankKey}.yaml`
|
||||
`Data/3d/Tanks/Parameters/${nation}/${tankKey}.yaml`,
|
||||
);
|
||||
const turretOrigin = tankDefinition.root.hull.turretPositions.turret
|
||||
.split(" ")
|
||||
@@ -890,23 +926,23 @@ export async function definitions() {
|
||||
|
||||
if (slug === undefined) {
|
||||
throw new Error(
|
||||
`Could not find slug for ${nation}/${tankKey} (${tankId})`
|
||||
`Could not find slug for ${nation}/${tankKey} (${tankId})`,
|
||||
);
|
||||
}
|
||||
|
||||
if (tank.sellPrice) {
|
||||
tankPrice = {
|
||||
type: TankPriceType.GOLD,
|
||||
type: TankPriceType.TANK_PRICE_TYPE_GOLD,
|
||||
value: tank.sellPrice["#text"] * 2,
|
||||
};
|
||||
} else if (typeof tank.price === "number") {
|
||||
tankPrice = {
|
||||
type: TankPriceType.CREDITS,
|
||||
type: TankPriceType.TANK_PRICE_TYPE_CREDITS,
|
||||
value: tank.price,
|
||||
};
|
||||
} else {
|
||||
tankPrice = {
|
||||
type: TankPriceType.CREDITS,
|
||||
type: TankPriceType.TANK_PRICE_TYPE_CREDITS,
|
||||
value: tank.price["#text"] * 400,
|
||||
};
|
||||
}
|
||||
@@ -923,13 +959,7 @@ export async function definitions() {
|
||||
const armorId = parseInt(armorIdString);
|
||||
const armorRaw = tankDefinition.root.hull.armor[name];
|
||||
|
||||
if (typeof armorRaw === "number") {
|
||||
hullArmor.thickness[armorId] = armorRaw;
|
||||
} else {
|
||||
if (!hullArmor.spaced) hullArmor.spaced = [];
|
||||
hullArmor.thickness[armorId] = armorRaw["#text"];
|
||||
hullArmor.spaced.push(armorId);
|
||||
}
|
||||
assignArmor(armorRaw, armorId, hullArmor);
|
||||
});
|
||||
const crew: Crew[] = [];
|
||||
const fixedCamouflage = tankTags.includes("eventCamouflage_user");
|
||||
@@ -938,7 +968,7 @@ export async function definitions() {
|
||||
Object.entries(tankDefinition.root.crew).forEach(([crewKey, value]) => {
|
||||
let entry: Crew;
|
||||
const index = crew.findIndex(
|
||||
({ type }) => blitzkitCrewTypeToBlitz[type] === crewKey
|
||||
({ type }) => blitzkitCrewTypeToBlitz[type] === crewKey,
|
||||
);
|
||||
if (index === -1) {
|
||||
if (crewKey === "#text") return;
|
||||
@@ -988,10 +1018,23 @@ export async function definitions() {
|
||||
})
|
||||
.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] = {
|
||||
ancestors: [],
|
||||
successors: [],
|
||||
id: tankId,
|
||||
dev_name: tankKey,
|
||||
roles: {},
|
||||
camouflages: camouflages,
|
||||
fixed_camouflage: fixedCamouflage,
|
||||
@@ -1011,10 +1054,10 @@ export async function definitions() {
|
||||
slug,
|
||||
nation,
|
||||
type: tankTags.includes("collectible")
|
||||
? TankType.COLLECTOR
|
||||
? TankType.TANK_TYPE_COLLECTOR
|
||||
: (typeof tank.price === "number" ? false : "gold" in tank.price)
|
||||
? TankType.PREMIUM
|
||||
: TankType.RESEARCHABLE,
|
||||
? TankType.TANK_TYPE_PREMIUM
|
||||
: TankType.TANK_TYPE_RESEARCHABLE,
|
||||
tier: tank.level,
|
||||
class: blitzTankClassToBlitzkit[tankTags[0] as BlitzTankClass],
|
||||
testing: tankTags.includes("testTank"),
|
||||
@@ -1022,21 +1065,22 @@ export async function definitions() {
|
||||
price: tankPrice,
|
||||
camouflage_still: tankDefinition.root.invisibility.still,
|
||||
camouflage_moving: tankDefinition.root.invisibility.moving,
|
||||
camouflage_onFire: tankDefinition.root.invisibility.firePenalty,
|
||||
camouflage_on_fire: tankDefinition.root.invisibility.firePenalty,
|
||||
turrets: [],
|
||||
engines: [],
|
||||
tracks: [],
|
||||
equalizer,
|
||||
};
|
||||
|
||||
if (tank.combatRole) {
|
||||
Object.entries(tank.combatRole).forEach(([gameMode, role]) => {
|
||||
const id = Object.entries(gameModeNativeNames).find(
|
||||
([key]) => key.toLowerCase() === gameMode.toLowerCase()
|
||||
([key]) => key.toLowerCase() === gameMode.toLowerCase(),
|
||||
)?.[1];
|
||||
|
||||
if (id === undefined) {
|
||||
throw new Error(
|
||||
`Unknown game mode in tank ${tankKey}: ${gameMode}`
|
||||
`Unknown game mode in tank ${tankKey}: ${gameMode}`,
|
||||
);
|
||||
}
|
||||
|
||||
@@ -1118,7 +1162,7 @@ export async function definitions() {
|
||||
(turretKey, turretIndex) => {
|
||||
const turret = tankDefinition.root.turrets0[turretKey];
|
||||
const turretModel = Number(
|
||||
parsePath(turret.models.undamaged).name.split("_")[1]
|
||||
parsePath(turret.models.undamaged).name.split("_")[1],
|
||||
);
|
||||
const turretId = toUniqueId(nation, turretList.root.ids[turretKey]);
|
||||
const turretYaw = (
|
||||
@@ -1150,13 +1194,7 @@ export async function definitions() {
|
||||
const armorId = parseInt(armorIdString);
|
||||
const armorRaw = turret.armor[name];
|
||||
|
||||
if (typeof armorRaw === "number") {
|
||||
turretArmor.thickness[armorId] = armorRaw;
|
||||
} else {
|
||||
if (!turretArmor.spaced) turretArmor.spaced = [];
|
||||
turretArmor.thickness[armorId] = armorRaw["#text"];
|
||||
turretArmor.spaced.push(armorId);
|
||||
}
|
||||
assignArmor(armorRaw, armorId, turretArmor);
|
||||
});
|
||||
|
||||
turret.userString;
|
||||
@@ -1186,12 +1224,12 @@ export async function definitions() {
|
||||
min: vector3TupleToBlitzkit(
|
||||
tankParameters.collision[
|
||||
parsePath(turret.hitTester.collisionModel).name.toLowerCase()
|
||||
].bbox.min
|
||||
].bbox.min,
|
||||
),
|
||||
max: vector3TupleToBlitzkit(
|
||||
tankParameters.collision[
|
||||
parsePath(turret.hitTester.collisionModel).name.toLowerCase()
|
||||
].bbox.max
|
||||
].bbox.max,
|
||||
),
|
||||
},
|
||||
};
|
||||
@@ -1209,7 +1247,7 @@ export async function definitions() {
|
||||
.split(" ")
|
||||
.map(Number) as [number, number];
|
||||
const gunModel = Number(
|
||||
parsePath(gun.models.undamaged).name.split("_")[1]
|
||||
parsePath(gun.models.undamaged).name.split("_")[1],
|
||||
);
|
||||
const gunName = getString(gunListEntry.userString);
|
||||
const gunType =
|
||||
@@ -1287,13 +1325,8 @@ export async function definitions() {
|
||||
}
|
||||
const armorId = parseInt(armorIdString);
|
||||
const armorRaw = gun.armor[name];
|
||||
if (typeof armorRaw === "number") {
|
||||
gunArmor.thickness[armorId] = armorRaw;
|
||||
} else {
|
||||
if (!gunArmor.spaced) gunArmor.spaced = [];
|
||||
gunArmor.thickness[armorId] = armorRaw["#text"];
|
||||
gunArmor.spaced.push(armorId);
|
||||
}
|
||||
|
||||
assignArmor(armorRaw, armorId, gunArmor);
|
||||
});
|
||||
|
||||
tankDefinitions.tanks[tankId].turrets[turretIndex].guns.push({
|
||||
@@ -1332,24 +1365,24 @@ export async function definitions() {
|
||||
},
|
||||
}
|
||||
: gunType === "autoReloader"
|
||||
? {
|
||||
$case: "auto_reloader",
|
||||
value: {
|
||||
intra_clip: 60 / gun.clip!.rate,
|
||||
shell_count: gunClipCount,
|
||||
shell_reloads: gun
|
||||
.pumpGunReloadTimes!.split(" ")
|
||||
.map(Number),
|
||||
? {
|
||||
$case: "auto_reloader",
|
||||
value: {
|
||||
intra_clip: 60 / gun.clip!.rate,
|
||||
shell_count: gunClipCount,
|
||||
shell_reloads: gun
|
||||
.pumpGunReloadTimes!.split(" ")
|
||||
.map(Number),
|
||||
},
|
||||
}
|
||||
: {
|
||||
$case: "auto_loader",
|
||||
value: {
|
||||
intra_clip: 60 / gun.clip!.rate,
|
||||
clip_reload: gun.reloadTime,
|
||||
shell_count: gunClipCount,
|
||||
},
|
||||
},
|
||||
}
|
||||
: {
|
||||
$case: "auto_loader",
|
||||
value: {
|
||||
intra_clip: 60 / gun.clip!.rate,
|
||||
clip_reload: gun.reloadTime,
|
||||
shell_count: gunClipCount,
|
||||
},
|
||||
},
|
||||
} satisfies GunDefinition);
|
||||
|
||||
modelDefinitions.models[tankId].turrets[turretId].guns[gunId] = {
|
||||
@@ -1360,8 +1393,8 @@ export async function definitions() {
|
||||
gun.armor.gun === undefined
|
||||
? 0
|
||||
: typeof gun.armor.gun === "number"
|
||||
? gun.armor.gun
|
||||
: gun.armor.gun["#text"],
|
||||
? gun.armor.gun
|
||||
: gun.armor.gun["#text"],
|
||||
pitch: {
|
||||
min: gunPitch[0],
|
||||
max: gunPitch[1],
|
||||
@@ -1408,7 +1441,7 @@ export async function definitions() {
|
||||
type: blitzShellKindToBlitzkit[shell.kind],
|
||||
explosion_radius:
|
||||
shell.kind === "HIGH_EXPLOSIVE"
|
||||
? shell.explosionRadius ?? 0
|
||||
? (shell.explosionRadius ?? 0)
|
||||
: undefined,
|
||||
icon: shell.icon,
|
||||
penetration: {
|
||||
@@ -1419,7 +1452,7 @@ export async function definitions() {
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
},
|
||||
);
|
||||
|
||||
totalUnlocks.forEach((unlocks) => {
|
||||
@@ -1447,7 +1480,7 @@ export async function definitions() {
|
||||
case "gun": {
|
||||
gunXps.set(
|
||||
toUniqueId(nation, gunList.root.ids[vehicle["#text"]]),
|
||||
parseResearchCost(vehicle.cost)
|
||||
parseResearchCost(vehicle.cost),
|
||||
);
|
||||
break;
|
||||
}
|
||||
@@ -1455,7 +1488,7 @@ export async function definitions() {
|
||||
case "turret": {
|
||||
turretXps.set(
|
||||
toUniqueId(nation, turretList.root.ids[vehicle["#text"]]),
|
||||
parseResearchCost(vehicle.cost)
|
||||
parseResearchCost(vehicle.cost),
|
||||
);
|
||||
break;
|
||||
}
|
||||
@@ -1463,7 +1496,7 @@ export async function definitions() {
|
||||
case "engine": {
|
||||
engineXps.set(
|
||||
toUniqueId(nation, enginesList.root.ids[vehicle["#text"]]),
|
||||
parseResearchCost(vehicle.cost)
|
||||
parseResearchCost(vehicle.cost),
|
||||
);
|
||||
break;
|
||||
}
|
||||
@@ -1471,7 +1504,7 @@ export async function definitions() {
|
||||
case "chassis": {
|
||||
trackXps.set(
|
||||
toUniqueId(nation, chassisList.root.ids[vehicle["#text"]]),
|
||||
parseResearchCost(vehicle.cost)
|
||||
parseResearchCost(vehicle.cost),
|
||||
);
|
||||
break;
|
||||
}
|
||||
@@ -1518,7 +1551,7 @@ export async function definitions() {
|
||||
name: getString(optionalDeviceEntry.userString),
|
||||
description: getString(optionalDeviceEntry.description),
|
||||
};
|
||||
}
|
||||
},
|
||||
);
|
||||
|
||||
Object.entries(optionalDeviceSlots.root.presets).forEach(
|
||||
@@ -1537,7 +1570,7 @@ export async function definitions() {
|
||||
})
|
||||
.flat(),
|
||||
};
|
||||
}
|
||||
},
|
||||
);
|
||||
|
||||
Object.entries(consumables).forEach(([key, consumable]) => {
|
||||
@@ -1620,7 +1653,7 @@ export async function definitions() {
|
||||
(item) =>
|
||||
blitzTankFilterDefinitionCategoryToBlitzkit[
|
||||
item as BlitzTankFilterDefinitionCategory
|
||||
]
|
||||
],
|
||||
),
|
||||
},
|
||||
},
|
||||
@@ -1718,7 +1751,7 @@ export async function definitions() {
|
||||
(item) =>
|
||||
blitzTankFilterDefinitionCategoryToBlitzkit[
|
||||
item as BlitzTankFilterDefinitionCategory
|
||||
]
|
||||
],
|
||||
),
|
||||
},
|
||||
},
|
||||
@@ -1749,11 +1782,11 @@ export async function definitions() {
|
||||
value.default_abilities.forEach((ability) => {
|
||||
if (ability in consumableNativeNames) {
|
||||
gameDefinitions.roles[value.id].consumables.push(
|
||||
consumableNativeNames[ability]
|
||||
consumableNativeNames[ability],
|
||||
);
|
||||
} else if (ability in provisionNativeNames) {
|
||||
gameDefinitions.roles[value.id].provisions.push(
|
||||
provisionNativeNames[ability]
|
||||
provisionNativeNames[ability],
|
||||
);
|
||||
} else throw new Error(`Unknown ability ${ability}`);
|
||||
});
|
||||
|
||||
@@ -17,15 +17,15 @@ export async function equipmentIcons() {
|
||||
|
||||
using uploader = new AssetUploader("equipment icons");
|
||||
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>(
|
||||
`Data/UI/Screens3/Lobby/Inventory/OptionalDevices/OptionalDevicesItemImage.style.yaml`
|
||||
`Data/UI/Screens3/Lobby/Inventory/OptionalDevices/OptionalDevicesItemImage.style.yaml`,
|
||||
);
|
||||
const image = sharp(
|
||||
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) {
|
||||
@@ -35,8 +35,8 @@ export async function equipmentIcons() {
|
||||
|
||||
const mapping = mappings.StyleSheets.find((mapping) =>
|
||||
mapping.selectors.includes(
|
||||
`.optional_device_item.${optionalDevice.icon} #Img`
|
||||
)
|
||||
`.optional_device_item.${optionalDevice.icon} #Img`,
|
||||
),
|
||||
);
|
||||
|
||||
if (!mapping) {
|
||||
@@ -49,9 +49,7 @@ export async function equipmentIcons() {
|
||||
|
||||
if (configPath.startsWith("Gfx/Lobby")) {
|
||||
const configPathWebp = configPath.replace(".txt", "");
|
||||
const image = sharp(
|
||||
await vfs.file(`Data/${configPathWebp}.packed.webp`)
|
||||
);
|
||||
const image = sharp(await vfs.file(`Data/${configPathWebp}.packed.webp`));
|
||||
const content = await image.trim().toBuffer();
|
||||
|
||||
await uploader.add({
|
||||
|
||||
@@ -6,20 +6,32 @@ export async function flags() {
|
||||
console.log("Building flags...");
|
||||
|
||||
using uploader = new AssetUploader("flags");
|
||||
const circleFiles = vfs.dir(`Data/Gfx/Lobby/flags`).filter(
|
||||
(flag) =>
|
||||
flag.startsWith("flag_profile-stat_") &&
|
||||
!flag.endsWith("@2x.packed.webp")
|
||||
const circleFiles = await vfs
|
||||
.dir(`Data/Gfx/Lobby/flags`)
|
||||
.then((files) =>
|
||||
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.startsWith("flag_tutor-tank_") &&
|
||||
!flag.endsWith("@2x.packed.webp")
|
||||
)
|
||||
const fadedFiles = vfs.dir(`Data/Gfx/Lobby/flags`).filter(
|
||||
(flag) =>
|
||||
flag.startsWith("flag_filter_") && flag.endsWith("@2x.packed.webp")
|
||||
)
|
||||
!flag.endsWith("@2x.packed.webp"),
|
||||
),
|
||||
);
|
||||
const fadedFiles = await vfs
|
||||
.dir(`Data/Gfx/Lobby/flags`)
|
||||
.then((files) =>
|
||||
files.filter(
|
||||
(flag) =>
|
||||
flag.startsWith("flag_filter_") && flag.endsWith("@2x.packed.webp"),
|
||||
),
|
||||
);
|
||||
|
||||
for (const flag of circleFiles) {
|
||||
const image = sharp(await vfs.file(`Data/Gfx/Lobby/flags/${flag}`));
|
||||
@@ -43,9 +55,7 @@ export async function flags() {
|
||||
}
|
||||
|
||||
for (const flag of fadedFiles) {
|
||||
const content = await sharp(
|
||||
await vfs.file(`Data/Gfx/Lobby/flags/${flag}`)
|
||||
)
|
||||
const content = await sharp(await vfs.file(`Data/Gfx/Lobby/flags/${flag}`))
|
||||
.trim({
|
||||
threshold: 100,
|
||||
background: { r: 0, g: 0, b: 0, alpha: 0 },
|
||||
|
||||
@@ -8,35 +8,33 @@ export async function gameModeBanners() {
|
||||
|
||||
using uploader = new AssetUploader("game mode banners");
|
||||
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>(
|
||||
`Data/UI/Screens3/Lobby/Hangar/Squad/SquadBattleType.yaml`
|
||||
`Data/UI/Screens3/Lobby/Hangar/Squad/SquadBattleType.yaml`,
|
||||
);
|
||||
const bannerMatches: { name: string; path: string }[] = [];
|
||||
|
||||
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] });
|
||||
}
|
||||
|
||||
for (const match of squadBattleTypeStyles.Prototypes[0].components.UIDataLocalBindingsComponent.data[1][2].matchAll(
|
||||
/"(\d+)" -> "battleType\/([a-zA-Z]+)"/g
|
||||
/"(\d+)" -> "battleType\/([a-zA-Z]+)"/g,
|
||||
)) {
|
||||
const id = Number(match[1]);
|
||||
const name = match[2];
|
||||
let path = bannerMatches.find(
|
||||
(bannerMatch) => bannerMatch.name.toLowerCase() === name.toLowerCase()
|
||||
(bannerMatch) => bannerMatch.name.toLowerCase() === name.toLowerCase(),
|
||||
)?.path;
|
||||
|
||||
if (path === undefined) {
|
||||
path = `/Gfx/UI/Hangar/GameTypes/battle-type_${name.toLowerCase()}`;
|
||||
}
|
||||
|
||||
const content = await sharp(
|
||||
await vfs.file(`Data${path}.packed.webp`)
|
||||
)
|
||||
const content = await sharp(await vfs.file(`Data${path}.packed.webp`))
|
||||
.trim({ background: { r: 0, g: 0, b: 0, alpha: 0 } })
|
||||
.toBuffer();
|
||||
|
||||
|
||||
@@ -15,7 +15,7 @@ export async function glossary() {
|
||||
const glossary = await fetchGlossary(supported.blitz ?? supported.locale);
|
||||
|
||||
console.log(
|
||||
`Found ${Object.keys(glossary).length} things for ${supported.locale}`
|
||||
`Found ${Object.keys(glossary).length} things for ${supported.locale}`,
|
||||
);
|
||||
|
||||
for (const key in glossary) {
|
||||
@@ -30,7 +30,7 @@ export async function glossary() {
|
||||
}
|
||||
|
||||
if (key in avatars) {
|
||||
avatars[key].avatar.name.locales[supported.locale] =
|
||||
avatars[key].avatar.name!.locales[supported.locale] =
|
||||
glossaryEntry.title;
|
||||
} else {
|
||||
const extension = extname(glossaryEntry.image_url);
|
||||
@@ -45,7 +45,7 @@ export async function glossary() {
|
||||
};
|
||||
}
|
||||
}
|
||||
})
|
||||
}),
|
||||
);
|
||||
|
||||
const gallery: Gallery = { avatars: [] };
|
||||
@@ -53,12 +53,12 @@ export async function glossary() {
|
||||
|
||||
const bar = new ProgressBar(
|
||||
`Fetching avatars of ${totalCount} things :bar`,
|
||||
totalCount
|
||||
totalCount,
|
||||
);
|
||||
|
||||
await Promise.all(
|
||||
Object.entries(avatars).map(async ([key, { url, avatar }]) => {
|
||||
if (!(locales.default in avatars[key].avatar.name.locales)) {
|
||||
if (!(locales.default in avatars[key].avatar.name!.locales)) {
|
||||
console.warn(`Avatar ${key} has no ${locales.default} name`);
|
||||
bar.tick();
|
||||
|
||||
@@ -77,7 +77,7 @@ export async function glossary() {
|
||||
});
|
||||
|
||||
bar.tick();
|
||||
})
|
||||
}),
|
||||
);
|
||||
|
||||
await uploader.add({
|
||||
|
||||
@@ -8,11 +8,13 @@ export async function migration() {
|
||||
|
||||
using uploader = new AssetUploader("migration map");
|
||||
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) {
|
||||
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) {
|
||||
|
||||
@@ -6,15 +6,20 @@ export async function moduleIcons() {
|
||||
console.log("Building module icons...");
|
||||
|
||||
using uploader = new AssetUploader("module icons");
|
||||
const files = vfs.dir(`Data/Gfx/UI/ModulesTechTree`).filter(
|
||||
(file) => !file.endsWith("@2x.packed.webp") && file.startsWith("vehicle")
|
||||
)
|
||||
const files = await vfs
|
||||
.dir(`Data/Gfx/UI/ModulesTechTree`)
|
||||
.then((files) =>
|
||||
files.filter(
|
||||
(file) =>
|
||||
!file.endsWith("@2x.packed.webp") && file.startsWith("vehicle"),
|
||||
),
|
||||
);
|
||||
|
||||
for (const file of files) {
|
||||
const nameRaw = file.match(/vehicle(.+)\.packed\.webp/)![1];
|
||||
const name = nameRaw[0].toLowerCase() + nameRaw.slice(1);
|
||||
const content = await sharp(
|
||||
await vfs.file(`Data/Gfx/UI/ModulesTechTree/${file}`)
|
||||
await vfs.file(`Data/Gfx/UI/ModulesTechTree/${file}`),
|
||||
)
|
||||
.trim()
|
||||
.toBuffer();
|
||||
|
||||
@@ -17,7 +17,7 @@ export async function popularTanks() {
|
||||
const analytics = google.analyticsdata({ version: "v1beta", auth });
|
||||
const report = await analytics.properties.runReport({
|
||||
property: `properties/${assertSecret(
|
||||
import.meta.env.PUBLIC_GOOGLE_ANALYTICS_PROPERTY_ID
|
||||
import.meta.env.PUBLIC_GOOGLE_ANALYTICS_PROPERTY_ID,
|
||||
)}`,
|
||||
requestBody: {
|
||||
dateRanges: [{ startDate: "7daysAgo", endDate: "today" }],
|
||||
@@ -47,13 +47,13 @@ export async function popularTanks() {
|
||||
row.dimensionValues[0].value &&
|
||||
row.dimensionValues[0].value !== "/tanks/" &&
|
||||
row.metricValues &&
|
||||
row.metricValues[0].value
|
||||
row.metricValues[0].value,
|
||||
)
|
||||
.map((row) => ({
|
||||
id: Number(
|
||||
row.dimensionValues![0].value!.match(
|
||||
/\/tools\/tankopedia\/(\d+)\/?/
|
||||
)?.[1]
|
||||
/\/tools\/tankopedia\/(\d+)\/?/,
|
||||
)?.[1],
|
||||
),
|
||||
views: Number(row.metricValues![0].value!),
|
||||
}))
|
||||
|
||||
@@ -8,19 +8,17 @@ export async function shellIcons() {
|
||||
using uploader = new AssetUploader("shell icons");
|
||||
const image = sharp(
|
||||
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(
|
||||
`Data/Gfx/Shared/tank-supply/ammunition/big`
|
||||
).filter((file) => file.endsWith("_l.txt"))
|
||||
const files = await vfs
|
||||
.dir(`Data/Gfx/Shared/tank-supply/ammunition/big`)
|
||||
.then((files) => files.filter((file) => file.endsWith("_l.txt")));
|
||||
|
||||
for (const file of files) {
|
||||
const name = file.match(/(.+)_l\.txt/)![1];
|
||||
const sizes = (
|
||||
await vfs.text(
|
||||
`Data/Gfx/Shared/tank-supply/ammunition/big/${file}`
|
||||
)
|
||||
await vfs.text(`Data/Gfx/Shared/tank-supply/ammunition/big/${file}`)
|
||||
)
|
||||
.split("\n")[4]
|
||||
.split(" ")
|
||||
|
||||
@@ -26,7 +26,7 @@ export async function skillIcons() {
|
||||
console.log("Building skill icons...");
|
||||
|
||||
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");
|
||||
|
||||
|
||||
@@ -10,11 +10,13 @@ export async function tankArmors() {
|
||||
|
||||
using uploader = new AssetUploader("tank armors");
|
||||
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) {
|
||||
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) {
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import { NATION_IDS } from "@blitzkit/core";
|
||||
import sharp from "sharp";
|
||||
import type { Vector3Tuple } from "three";
|
||||
import { parsePackedSpriteRect } from "../core/blitz/parsePackedSpriteRect";
|
||||
import { AssetUploader } from "../core/github/assetUploader";
|
||||
import { vfs } from "./constants";
|
||||
import type { VehicleDefinitionList } from "./definitions";
|
||||
@@ -37,15 +38,56 @@ export interface TankParameters {
|
||||
};
|
||||
}
|
||||
|
||||
async function extractPackedTankIcon(packedBuffer: Buffer, context: string) {
|
||||
const texture = sharp(packedBuffer);
|
||||
const spriteRect = parsePackedSpriteRect(packedBuffer);
|
||||
|
||||
if (!spriteRect) {
|
||||
throw new Error(`Missing RIFF sprite bounds for ${context}`);
|
||||
}
|
||||
|
||||
const [left, top, width, height] = spriteRect;
|
||||
const bounds = [left, top, width, height];
|
||||
|
||||
if (!bounds.every(Number.isInteger)) {
|
||||
throw new Error(
|
||||
`Invalid RIFF sprite bounds for ${context}: ${bounds.join(" ")}`,
|
||||
);
|
||||
}
|
||||
|
||||
const metadata = await texture.metadata();
|
||||
|
||||
if (metadata.width === undefined || metadata.height === undefined) {
|
||||
throw new Error(`Failed to read image dimensions for ${context}`);
|
||||
}
|
||||
|
||||
if (
|
||||
left < 0 ||
|
||||
top < 0 ||
|
||||
width <= 0 ||
|
||||
height <= 0 ||
|
||||
left + width > metadata.width ||
|
||||
top + height > metadata.height
|
||||
) {
|
||||
throw new Error(
|
||||
`Out-of-bounds RIFF sprite for ${context}: ${bounds.join(" ")} in ${metadata.width}x${metadata.height}`,
|
||||
);
|
||||
}
|
||||
|
||||
return await texture.extract({ left, top, width, height }).toBuffer();
|
||||
}
|
||||
|
||||
export async function tankIcons() {
|
||||
console.log("Building 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) {
|
||||
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) {
|
||||
@@ -57,7 +99,7 @@ export async function tankIcons() {
|
||||
const id = (nationVehicleId << 8) + (NATION_IDS[nation] << 4) + 1;
|
||||
|
||||
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
|
||||
.replace(/~res:\//, "")
|
||||
@@ -65,12 +107,14 @@ export async function tankIcons() {
|
||||
const bigPath = `Data/${parameters.resourcesPath.bigIconPath
|
||||
.replace(/~res:\//, "")
|
||||
.replace(/\..+/, "")}.packed.webp`;
|
||||
const big = await sharp(await vfs.file(bigPath))
|
||||
.trim()
|
||||
.toBuffer();
|
||||
const small = await sharp(await vfs.file(smallPath))
|
||||
.trim()
|
||||
.toBuffer();
|
||||
const big = await extractPackedTankIcon(
|
||||
await vfs.file(bigPath),
|
||||
`tank ${tankKey} big`,
|
||||
);
|
||||
const small = await extractPackedTankIcon(
|
||||
await vfs.file(smallPath),
|
||||
`tank ${tankKey} small`,
|
||||
);
|
||||
|
||||
if (big) {
|
||||
await uploader.add({
|
||||
|
||||
Loaded 100 of 208 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user