feat: functionality and icons

This commit is contained in:
TrèsAbhi committed 2024-03-15 12:28:29 -05:00
1 parent 035f751bf1
commit 787d3ae6ea
8 files changed
+253 -40

No files matched your search

+147 -5
View File
@@ -1,12 +1,15 @@
import { escapeMarkdown } from 'discord.js';
import CommandWrapper from '../components/CommandWrapper';
import TitleBar from '../components/TitleBar';
import { equipmentPriceMatrix } from '../constants/equipmentPrice';
import { getAccountInfo } from '../core/blitz/getAccountInfo';
import { getClanAccountInfo } from '../core/blitz/getClanAccountInfo';
import getTankStats from '../core/blitz/getTankStats';
import resolveTankId from '../core/blitz/resolveTankId';
import { asset } from '../core/blitzkrieg/asset';
import { buildTechTreeLine } from '../core/blitzkrieg/buildTechTreeLine';
import { emblemIdToURL } from '../core/blitzkrieg/emblemIdToURL';
import { iconPng } from '../core/blitzkrieg/iconPng';
import { resolveAncestry } from '../core/blitzkrieg/resolveAncestry';
import { tankDefinitions } from '../core/blitzkrieg/tankDefinitions';
import {
@@ -54,7 +57,7 @@ export const researchCommand = new Promise<CommandRegistry>((resolve) => {
);
if (firstOwnedTechTree === undefined) {
return `idk what to call this error lol`;
throw new Error('No first owned tech tree found.');
}
const line = (
@@ -82,6 +85,48 @@ export const researchCommand = new Promise<CommandRegistry>((resolve) => {
{await Promise.all(
line.map(async (id) => {
const tank = awaitedTankDefinitions[id];
const turretXps = new Map<number, number>();
const gunXps = new Map<number, number>();
const engineXps = new Map<number, number>();
const trackXps = new Map<number, number>();
tank.turrets.forEach((turret) => {
if (turret.xp !== undefined) {
turretXps.set(turret.id, turret.xp);
}
turret.guns.forEach((gun) => {
if (gun.xp !== undefined) {
gunXps.set(gun.id, gun.xp);
}
});
});
tank.engines.forEach((engine) => {
if (engine.xp !== undefined) {
engineXps.set(engine.id, engine.xp);
}
});
tank.tracks.forEach((track) => {
if (track.xp !== undefined) {
trackXps.set(track.id, track.xp);
}
});
let moduleXp = 0;
turretXps.forEach((value) => {
moduleXp += value;
});
gunXps.forEach((value) => {
moduleXp += value;
});
engineXps.forEach((value) => {
moduleXp += value;
});
trackXps.forEach((value) => {
moduleXp += value;
});
return (
<div
@@ -173,14 +218,111 @@ export const researchCommand = new Promise<CommandRegistry>((resolve) => {
flex: 1,
display: 'flex',
flexDirection: 'column',
justifyContent: 'center',
gap: 8,
padding: '16px 0',
}}
>
<span>Research: 144,000</span>
<span>Upgrades: 62,000</span>
<span>Purchase: 1,500,000</span>
<span>Equipment: 450,000</span>
<div
style={{
display: 'flex',
gap: 4,
alignItems: 'center',
}}
>
<img
src={await iconPng(asset('icons/currencies/xp.webp'))}
width={16}
height={16}
/>
<span
style={{
fontSize: 16,
color: theme.colors.textHighContrast,
}}
>
Research:{' '}
{tank.xp?.toLocaleString(interaction.locale)}
</span>
</div>
{moduleXp > 0 && (
<div
style={{
display: 'flex',
gap: 4,
alignItems: 'center',
}}
>
<img
src={await iconPng(
asset('icons/currencies/free-xp.webp'),
)}
width={16}
height={16}
/>
<span
style={{
fontSize: 16,
color: theme.colors.textHighContrast,
}}
>
Upgrades: {moduleXp.toLocaleString()}
</span>
</div>
)}
<div
style={{
display: 'flex',
gap: 4,
alignItems: 'center',
}}
>
<img
src={await iconPng(
asset('icons/currencies/silver.webp'),
)}
width={16}
height={16}
/>
<span
style={{
fontSize: 16,
color: theme.colors.textHighContrast,
}}
>
Purchase:{' '}
{tank.price.value.toLocaleString(interaction.locale)}
</span>
</div>
<div
style={{
display: 'flex',
gap: 4,
alignItems: 'center',
}}
>
<img
src={await iconPng(
asset('icons/currencies/silver.webp'),
)}
width={16}
height={16}
/>
<span
style={{
fontSize: 16,
color: theme.colors.textHighContrast,
}}
>
Equipment:{' '}
{equipmentPriceMatrix[tank.tier]
.reduce((a, b) => a + 3 * b, 0)
.toLocaleString(interaction.locale)}
</span>
</div>
</div>
</div>
);
+15
View File
@@ -0,0 +1,15 @@
import { Vector3Tuple } from 'three';
import { Tier } from '../core/blitzkrieg/tankDefinitions';
export const equipmentPriceMatrix: Record<Tier, Vector3Tuple> = {
1: [100, 200, 300],
2: [200, 300, 400],
3: [400, 500, 600],
4: [4000, 5000, 6000],
5: [40_000, 50_000, 60_000],
6: [100_000, 120_000, 140_000],
7: [150_000, 170_000, 190_000],
8: [200_000, 225_000, 250_000],
9: [250_000, 275_000, 300_000],
10: [300_000, 350_000, 400_000],
};
+14
View File
@@ -0,0 +1,14 @@
import sharp from 'sharp';
const cache: Record<string, string> = {};
export async function iconPng(url: string) {
if (cache[url]) return cache[url];
const imageResponse = await fetch(url);
const imageBufferWEBP = await imageResponse.arrayBuffer();
const imageBufferPNG = await sharp(imageBufferWEBP).png().toBuffer();
cache[url] = `data:image/png;base64,${imageBufferPNG.toString('base64')}`;
return cache[url];
}
+8 -8
View File
@@ -1,8 +1,8 @@
import { readFile } from 'fs/promises';
import { deburr } from 'lodash';
import { Vector2Tuple } from 'three';
import { TankClass, TreeType } from '../../../components/Tanks';
import { asset } from '../asset';
import { fetchCdonLz4 } from '../fetchCdonLz4';
import { superDecompress } from '../superDecompress';
import { TIERS } from './constants';
export type ShellType = 'ap' | 'ap_cr' | 'hc' | 'he';
@@ -142,14 +142,14 @@ export type ShellDefinition = {
explosionRadius?: number;
};
export const tankDefinitions = fetchCdonLz4<TankDefinitions>(
asset('definitions/tanks.cdon.lz4'),
);
// export const tankDefinitions = readFile('test.tanks.cdon.lz4').then((data) =>
// superDecompress<TankDefinitions>(data.buffer),
// export const tankDefinitions = fetchCdonLz4<TankDefinitions>(
// asset('definitions/tanks.cdon.lz4'),
// );
export const tankDefinitions = readFile('test.tanks.cdon.lz4').then((data) =>
superDecompress<TankDefinitions>(data.buffer),
);
const entries = new Promise<TankDefinition[]>(async (resolve) => {
resolve(Object.entries(await tankDefinitions).map(([, entry]) => entry));
});
+3 -6
View File
@@ -1,9 +1,6 @@
import sharp from 'sharp';
import { iconPng } from './iconPng';
import { tankIcon } from './tankIcon';
export async function tankIconPng(id: number) {
const imageResponse = await fetch(tankIcon(id));
const imageBufferWEBP = await imageResponse.arrayBuffer();
const imageBufferPNG = await sharp(imageBufferWEBP).png().toBuffer();
return `data:image/png;base64,${imageBufferPNG.toString('base64')}`;
export function tankIconPng(id: number) {
return iconPng(tankIcon(id));
}