feat: migrated tankopedia search

This commit is contained in:
TrèsAbhi committed 2024-09-06 22:05:06 -05:00
1 parent 73c7bdf0c0
commit e1c8194beb
59 files changed
+146 -131

No files matched your search

+8
View File
@@ -0,0 +1,8 @@
export const TREE_TYPES = ['researchable', 'premium', 'collector'] as const;
export const TANK_CLASSES = [
'lightTank',
'mediumTank',
'heavyTank',
'AT-SPG',
] as const;
+2
View File
@@ -1 +1,3 @@
export * from './constants';
export * from './idToRegion';
export * from './resolveNearPenetration';
@@ -0,0 +1,5 @@
import { Vector2Tuple } from 'three';
export function resolveNearPenetration(penetration: number | Vector2Tuple) {
return typeof penetration === 'number' ? penetration : penetration[0];
}
+8
View File
@@ -0,0 +1,8 @@
import { assertSecret } from '@blitzkit/core/src/blitzkit/assertSecret';
import { ASSETS_REPO } from '../../../../src/constants/assets';
export function asset(path: string) {
return `https://raw.githubusercontent.com/tresabhi/${ASSETS_REPO}/${assertSecret(
process.env.NEXT_PUBLIC_ASSET_BRANCH,
)}/${path}`;
}
@@ -0,0 +1,16 @@
import { asset } from '@blitzkit/core/src/blitzkit/asset';
import { fetchCdonLz4 } from '@blitzkit/core/src/blitzkit/fetchCdonLz4';
export type CamouflageDefinitions = Record<
number,
{
id: number;
name: string;
tankName?: string;
tankNameFull?: string;
}
>;
export const camouflageDefinitions = fetchCdonLz4<CamouflageDefinitions>(
asset('definitions/camouflages.cdon.lz4'),
);
@@ -0,0 +1,7 @@
import { superDecompress } from '@blitzkit/core/src/blitzkit/superDecompress';
export async function fetchCdonLz4<Type>(url: string) {
return await fetch(url, { cache: 'no-store' })
.then((response) => response.arrayBuffer())
.then((buffer) => superDecompress<Type>(buffer));
}
+14
View File
@@ -0,0 +1,14 @@
import { TankFilters } from '../../../website/src/stores/tankFilters';
import { TankDefinition } from './tankDefinitions';
export function filterTank(filters: TankFilters, tank: TankDefinition) {
return (
(filters.tiers.length === 0 || filters.tiers.includes(tank.tier)) &&
(filters.nations.length === 0 || filters.nations.includes(tank.nation)) &&
(filters.classes.length === 0 || filters.classes.includes(tank.class)) &&
(filters.types.length === 0 || filters.types.includes(tank.treeType)) &&
(filters.testing === 'include' ||
(filters.testing === 'only' && tank.testing) ||
(filters.testing === 'exclude' && !tank.testing))
);
}
@@ -1,5 +1,5 @@
import { asset } from '../../../../src/core/blitzkit/asset';
import { fetchCdonLz4 } from '../../../../src/core/blitzkit/fetchCdonLz4';
import { asset } from './asset';
import { fetchCdonLz4 } from './fetchCdonLz4';
interface GameMode {
name: string;
+8
View File
@@ -1,4 +1,12 @@
export * from './assertSecret';
export * from './asset';
export * from './camouflageDefinitions';
export * from './fetchCdonLz4';
export * from './filterTank';
export * from './gameDefinitions';
export * from './modelDefinitions';
export * from './superCompress';
export * from './superDecompress';
export * from './tankDefinitions';
export * from './tankIcon';
export * from './tankNames';
@@ -0,0 +1,64 @@
import { Vector3Tuple } from 'three';
import { asset } from './asset';
import { fetchCdonLz4 } from './fetchCdonLz4';
export type ModelDefinitions = Record<number, ModelDefinition>;
export interface ModelArmor {
thickness: Record<number, number>;
spaced?: number[];
// dynamic?: Record<`${boolean}`, number[]>;
}
export interface BoundingBox {
min: Vector3Tuple;
max: Vector3Tuple;
}
export interface ModelDefinition {
armor: ModelArmor;
turretOrigin: Vector3Tuple;
turretRotation?: InitialTurretRotation;
turrets: Record<number, TurretModelDefinition>;
tracks: Record<number, TrackDefinition>;
boundingBox: BoundingBox;
}
interface TrackDefinition {
thickness: number;
origin: Vector3Tuple;
}
export interface InitialTurretRotation {
yaw: number;
pitch: number;
roll: number;
}
interface TurretModelDefinition {
boundingBox: BoundingBox;
armor: ModelArmor;
model: number;
gunOrigin: Vector3Tuple;
guns: Record<number, GunModelDefinition>;
yaw?: YawLimits;
}
export interface YawLimits {
min: number;
max: number;
}
interface GunModelDefinition {
armor: ModelArmor;
thickness: number;
model: number;
pitch: PitchLimits;
mask?: number;
}
export interface PitchLimits {
min: number;
max: number;
front?: { min: number; max: number; range: number };
back?: { min: number; max: number; range: number };
transition?: number;
}
export const modelDefinitions = fetchCdonLz4<ModelDefinitions>(
asset('definitions/models.cdon.lz4'),
);
@@ -0,0 +1,72 @@
import { CrewMember, GunDefinition, ShellType, Tier } from '.';
export const SHELL_NAMES: Record<ShellType, string> = {
ap: 'AP',
ap_cr: 'APCR',
hc: 'HEAT',
he: 'HE',
};
export const CREW_MEMBER_NAMES: Record<CrewMember, string> = {
commander: 'Commander',
radioman: 'Radioman',
gunner: 'Gunner',
driver: 'Driver',
loader: 'Loader',
};
export const GUN_TYPE_NAMES: Record<GunDefinition['type'], string> = {
regular: 'Regular',
autoLoader: 'Auto loader',
autoReloader: 'Auto reloader',
};
/**
* @deprecated use svg
*/
export const TANK_ICONS: Record<TankClass, string> = {
'AT-SPG': 'https://i.imgur.com/BIHSEH0.png',
lightTank: 'https://i.imgur.com/CSNha5V.png',
mediumTank: 'https://i.imgur.com/wvf3ltm.png',
heavyTank: 'https://i.imgur.com/ECeqlZa.png',
};
/**
* @deprecated use svg
*/
export const TANK_ICONS_PREMIUM: Record<TankClass, string> = {
'AT-SPG': 'https://i.imgur.com/TCu3EdR.png',
lightTank: 'https://i.imgur.com/zdkpTRb.png',
mediumTank: 'https://i.imgur.com/3z7eHX6.png',
heavyTank: 'https://i.imgur.com/P3vbmyA.png',
};
/**
* @deprecated use svg
*/
export const TANK_ICONS_COLLECTOR: Record<TankClass, string> = {
'AT-SPG': 'https://i.imgur.com/WTjeirB.png',
lightTank: 'https://i.imgur.com/EwhtKkU.png',
mediumTank: 'https://i.imgur.com/u8YDMBh.png',
heavyTank: 'https://i.imgur.com/8xRf3nc.png',
};
export const TIERS = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] as const;
export const TIER_ROMAN_NUMERALS: Record<Tier, string> = {
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>',
};
@@ -0,0 +1,182 @@
import { Vector2Tuple } from 'three';
import { TankClass, TreeType } from '../../../components/Tanks';
import { asset } from '../asset';
import { fetchCdonLz4 } from '../fetchCdonLz4';
import { TIERS } from './constants';
export enum ShellType {
AP = 'ap',
APCR = 'ap_cr',
HEAT = 'hc',
HE = 'he',
}
export type CrewMember =
| 'commander'
| 'radioman'
| 'gunner'
| 'driver'
| 'loader';
export type TankDefinitions = Record<number, TankDefinition>;
export type ModuleType = 'vehicle' | 'engine' | 'chassis' | 'turret' | 'gun';
export interface Unlock {
type: ModuleType;
id: number;
cost: {
// string being the season coins
type: 'xp' | string;
value: number;
};
}
export interface Crew {
type: CrewMember;
count?: number;
substitute?: CrewMember[];
}
export type ModuleDefinition =
| TrackDefinition
| EngineDefinition
| TurretDefinition
| GunDefinition;
export interface TankDefinition {
id: number;
roles: Record<number, number>;
description?: string;
fixedCamouflage?: boolean;
camouflages?: number[];
ancestors?: number[];
successors?: number[];
crew: Crew[];
health: number;
nation: string;
name: string;
nameFull?: string;
treeType: TreeType;
consumables: number;
provisions: number;
tier: Tier;
class: TankClass;
testing: boolean;
deprecated: boolean;
turrets: TurretDefinition[];
engines: EngineDefinition[];
tracks: TrackDefinition[];
price: TankPrice;
xp?: number;
speed: {
forwards: number;
backwards: number;
};
camouflage: {
still: number;
moving: number;
onFire: number;
};
equipment: string;
weight: number;
}
export interface TrackDefinition {
id: number;
tier: Tier;
name: string;
weight: number;
traverseSpeed: number;
xp?: number;
dispersion: {
move: number;
traverse: number;
};
resistance: {
hard: number;
medium: number;
soft: number;
};
unlocks?: Unlock[];
}
export interface EngineDefinition {
id: number;
name: string;
xp?: number;
tier: Tier;
fireChance: number;
power: number;
weight: number;
unlocks?: Unlock[];
}
export type TankPrice =
| { type: 'credits'; value: number }
| { type: 'gold'; value: number };
export interface TurretDefinition {
health: number;
viewRange: number;
traverseSpeed: number;
xp?: number;
id: number;
name: string;
tier: Tier;
guns: GunDefinition[];
weight: number;
unlocks?: Unlock[];
}
export type GunDefinition =
| GunDefinitionRegular
| GunDefinitionAutoLoader
| GunDefinitionAutoReloader;
interface GunDefinitionBase {
rotationSpeed: number;
xp?: number;
weight: number;
id: number;
name: string;
tier: Tier;
shells: ShellDefinition[];
camouflageLoss: number;
aimTime: number;
dispersion: {
base: number;
traverse: number;
shot: number;
damaged: number;
};
unlocks?: Unlock[];
}
interface GunDefinitionRegular extends GunDefinitionBase {
type: 'regular';
reload: number;
}
interface GunDefinitionAutoLoader extends GunDefinitionBase {
type: 'autoLoader';
reload: number;
intraClip: number;
count: number;
}
interface GunDefinitionAutoReloader extends GunDefinitionBase {
type: 'autoReloader';
reload: number[];
intraClip: number;
count: number;
}
export type ShellDefinition = {
id: number;
name: string;
speed: number;
damage: { armor: number; module: number };
caliber: number;
icon: string;
penetration: number | Vector2Tuple;
type: ShellType;
normalization?: number;
ricochet?: number;
explosionRadius?: number;
};
export const tankDefinitions = fetchCdonLz4<TankDefinitions>(
asset('definitions/tanks.cdon.lz4'),
);
export const tankDefinitionsArray = tankDefinitions.then((tanks) =>
Object.values(tanks),
);
export type Tier = (typeof TIERS)[number];
export * from './constants';
+5
View File
@@ -0,0 +1,5 @@
import { asset } from '@blitzkit/core/src/blitzkit/asset';
export function tankIcon(id: number, size: 'big' | 'small' = 'big') {
return asset(`icons/tanks/${size}/${id}.webp`);
}
+25
View File
@@ -0,0 +1,25 @@
import { deburr } from 'lodash';
import { camouflageDefinitions, tankDefinitionsArray } from '.';
export const tankNames = Promise.all([
tankDefinitionsArray,
camouflageDefinitions,
]).then(([tanks, camouflages]) =>
Promise.all(
tanks.map(async (tank, index) => {
const { id } = (await tankDefinitionsArray)[index];
return {
id,
name: tank.name,
nameFull: tank.nameFull,
searchableName: tank.nameFull ?? tank.name,
searchableNameDeburr: deburr(tank.nameFull ?? tank.name),
camouflages: tank.camouflages
?.map((id) => camouflages[id].name)
.join(' '),
treeType: tank.treeType,
};
}),
),
);