sendou.ink/app/modules/in-game-lists/weapon-ids.ts
Kalle 8dc92140fc
Some checks failed
E2E Tests / e2e (push) Has been cancelled
Tests and checks on push / run-checks-and-tests (push) Has been cancelled
Updates translation progress / update-translation-progress-issue (push) Has been cancelled
Optimize builds loaders (#3076)
2026-05-17 16:21:13 +03:00

321 lines
7.7 KiB
TypeScript

import { assertUnreachable } from "~/utils/types";
import type { MainWeaponId, SpecialWeaponId, SubWeaponId } from "./types";
export const weaponCategories = [
{
name: "SHOOTERS",
weaponIds: [
0, 1, 10, 11, 20, 21, 22, 30, 31, 32, 40, 41, 42, 45, 46, 47, 50, 51, 60,
61, 70, 71, 72, 80, 81, 82, 90, 91, 92, 100, 101, 300, 301, 302, 310, 311,
312, 400, 401,
],
},
{
name: "BLASTERS",
weaponIds: [
200, 201, 205, 210, 211, 212, 220, 221, 230, 231, 240, 241, 250, 251, 252,
260, 261,
],
},
{
name: "ROLLERS",
weaponIds: [
1000, 1001, 1002, 1010, 1011, 1015, 1020, 1021, 1022, 1030, 1031, 1040,
1041, 1042,
],
},
{
name: "BRUSHES",
weaponIds: [1100, 1101, 1110, 1111, 1112, 1115, 1120, 1121, 1122],
},
{
name: "CHARGERS",
weaponIds: [
2000, 2001, 2010, 2011, 2012, 2015, 2020, 2021, 2022, 2030, 2031, 2040,
2041, 2050, 2051, 2060, 2061, 2070, 2071,
],
},
{
name: "SLOSHERS",
weaponIds: [
3000, 3001, 3005, 3010, 3011, 3012, 3020, 3021, 3030, 3031, 3040, 3041,
3050, 3051, 3052,
],
},
{
name: "SPLATLINGS",
weaponIds: [
4000, 4001, 4002, 4010, 4011, 4015, 4020, 4021, 4022, 4030, 4031, 4040,
4041, 4050, 4051,
],
},
{
name: "DUALIES",
weaponIds: [
5000, 5001, 5002, 5010, 5015, 5011, 5012, 5020, 5021, 5030, 5031, 5032,
5040, 5041, 5050, 5051,
],
},
{
name: "BRELLAS",
weaponIds: [
6000, 6001, 6005, 6010, 6011, 6012, 6020, 6021, 6022, 6030, 6031,
],
},
{
name: "STRINGERS",
weaponIds: [7010, 7011, 7012, 7015, 7020, 7021, 7022, 7030, 7031],
},
{
name: "SPLATANAS",
weaponIds: [8000, 8001, 8002, 8005, 8010, 8011, 8012, 8020, 8021],
},
] as const;
export const mainWeaponIds = weaponCategories
.flatMap((category) => category.weaponIds)
.sort((a, b) => a - b);
const weaponIdToAltId = new Map<MainWeaponId, MainWeaponId | MainWeaponId[]>([
[40, [45, 47]],
[41, 46],
[200, 205],
[1010, 1015],
[1110, 1115],
[2010, 2015],
[3000, 3005],
[4010, 4015],
[5010, 5015],
[6000, 6005],
[7010, 7015],
[8000, 8005],
]);
const altWeaponIdToId = new Map<MainWeaponId, MainWeaponId>([
[45, 40],
[47, 40],
[46, 41],
[205, 200],
[1015, 1010],
[1115, 1110],
[2015, 2010],
[3005, 3000],
[4015, 4010],
[5015, 5010],
[6005, 6000],
[7015, 7010],
[8005, 8000],
]);
/**
* Folds an alt-skin weapon id to its base id, leaving non-alt ids untouched.
*
* Unlike {@link weaponIdToBaseWeaponId}, alt kits are preserved (e.g. Tentatek
* Splattershot stays 41) — only cosmetic alt skins collapse to their base.
*
* Mirrors the `BuildWeapon.canonicalWeaponSplId` column so TypeScript callers
* and SQL queries agree on what a weapon's canonical id is.
*
* @example
* // Splattershot — base weapon, returned unchanged
* canonicalWeaponSplId(40); // -> 40
*
* // Tentatek Splattershot — alt kit, returned unchanged
* canonicalWeaponSplId(41); // -> 41
*
* // Hero Shot Replica — alt skin, folded to Splattershot
* canonicalWeaponSplId(45); // -> 40
*/
export function canonicalWeaponSplId(weaponSplId: MainWeaponId): MainWeaponId {
return altWeaponIdToId.get(weaponSplId) ?? weaponSplId;
}
/**
* Converts a given weapon ID to an array containing the weapon ID and its alternate IDs. For example if you enter the ID 40 (Splattershot) it will return [40, 45, 47] (Splattershot, Hero Shot Replica, Order Shot Replica)
*/
export function weaponIdToArrayWithAlts(weaponId: MainWeaponId) {
const altId = weaponIdToAltId.get(weaponId);
if (altId !== undefined) {
return [weaponId, ...(Array.isArray(altId) ? altId : [altId])];
}
const regularId = altWeaponIdToId.get(weaponId);
if (regularId !== undefined) {
const altId = weaponIdToAltId.get(regularId);
if (altId !== undefined) {
return [regularId, ...(Array.isArray(altId) ? altId : [altId])];
}
}
return [weaponId];
}
/**
* Determines the type of weapon based on its ID
*
* @returns "ALT_SKIN" if the weapon is an alternate skin, "BASE" if it's a base weapon, or "ALT_KIT" if it's an alternate kit
*
* @example
* // Splattershot is a base weapon
* weaponIdToType(40); // -> "BASE"
*
* // Tentatek Splattershot is an alternate kit
* weaponIdToType(41); // -> "ALT_KIT"
*
* // Hero Shot Replica is an alternate skin
* weaponIdToType(45); // -> "ALT_SKIN"
*/
export const weaponIdToType = (weaponId: MainWeaponId) => {
if (altWeaponIdToId.has(weaponId)) return "ALT_SKIN";
if (weaponId === weaponIdToBaseWeaponId(weaponId)) return "BASE";
return "ALT_KIT";
};
export const SPLAT_BOMB_ID = 0;
export const SUCTION_BOMB_ID = 1;
export const BURST_BOMB_ID = 2;
export const SPRINKLER_ID = 3;
export const SPLASH_WALL_ID = 4;
export const FIZZY_BOMB_ID = 5;
export const CURLING_BOMB_ID = 6;
export const AUTO_BOMB_ID = 7;
export const SQUID_BEAKON_ID = 8;
export const POINT_SENSOR_ID = 9;
export const INK_MINE_ID = 10;
export const TOXIC_MIST_ID = 11;
export const ANGLE_SHOOTER_ID = 12;
export const TORPEDO_ID = 13;
export const subWeaponIds = [
SPLAT_BOMB_ID,
SUCTION_BOMB_ID,
BURST_BOMB_ID,
SPRINKLER_ID,
SPLASH_WALL_ID,
FIZZY_BOMB_ID,
CURLING_BOMB_ID,
AUTO_BOMB_ID,
SQUID_BEAKON_ID,
POINT_SENSOR_ID,
INK_MINE_ID,
TOXIC_MIST_ID,
ANGLE_SHOOTER_ID,
TORPEDO_ID,
] as const;
export const nonBombSubWeaponIds = [
SPRINKLER_ID,
SPLASH_WALL_ID,
SQUID_BEAKON_ID,
POINT_SENSOR_ID,
TOXIC_MIST_ID,
] as SubWeaponId[];
export const TRIZOOKA_ID = 1;
export const BIG_BUBBLER_ID = 2;
export const ZIPCASTER_ID = 3;
const TENTA_MISSILES_ID = 4;
export const INK_STORM_ID = 5;
export const BOOYAH_BOMB_ID = 6;
export const WAVE_BREAKER_ID = 7;
export const INK_VAC_ID = 8;
export const KILLER_WAIL_ID = 9;
const INKJET_ID = 10;
const ULTRA_STAMP_ID = 11;
export const CRAB_TANK_ID = 12;
const REEF_SLIDER_ID = 13;
const TRIPLE_INKSTRIKE_ID = 14;
const TACTICOOLER_ID = 15;
export const SUPER_CHUMP_ID = 16;
const KRAKEN_ROYALE_ID = 17;
export const TRIPLE_SPLASHDOWN_ID = 18;
export const SPLATTERCOLOR_SCREEN_ID = 19;
export const specialWeaponIds = [
TRIZOOKA_ID,
BIG_BUBBLER_ID,
ZIPCASTER_ID,
TENTA_MISSILES_ID,
INK_STORM_ID,
BOOYAH_BOMB_ID,
WAVE_BREAKER_ID,
INK_VAC_ID,
KILLER_WAIL_ID,
INKJET_ID,
ULTRA_STAMP_ID,
CRAB_TANK_ID,
REEF_SLIDER_ID,
TRIPLE_INKSTRIKE_ID,
TACTICOOLER_ID,
SUPER_CHUMP_ID,
KRAKEN_ROYALE_ID,
TRIPLE_SPLASHDOWN_ID,
SPLATTERCOLOR_SCREEN_ID,
] as const;
export const nonDamagingSpecialWeaponIds = [BIG_BUBBLER_ID, TACTICOOLER_ID];
export const exampleMainWeaponIdWithSpecialWeaponId = (
specialWeaponId: SpecialWeaponId,
): MainWeaponId => {
switch (specialWeaponId) {
case TRIZOOKA_ID:
return 40;
case BIG_BUBBLER_ID:
return 10;
case ZIPCASTER_ID:
return 8000;
case TENTA_MISSILES_ID:
return 1030;
case INK_STORM_ID:
return 3040;
case BOOYAH_BOMB_ID:
return 3020;
case WAVE_BREAKER_ID:
return 220;
case INK_VAC_ID:
return 2010;
case KILLER_WAIL_ID:
return 50;
case INKJET_ID:
return 3010;
case ULTRA_STAMP_ID:
return 4000;
case CRAB_TANK_ID:
return 20;
case REEF_SLIDER_ID:
return 5040;
case TRIPLE_INKSTRIKE_ID:
return 41;
case TACTICOOLER_ID:
return 60;
case SUPER_CHUMP_ID:
return 61;
case KRAKEN_ROYALE_ID:
return 4011;
case TRIPLE_SPLASHDOWN_ID:
return 211;
case SPLATTERCOLOR_SCREEN_ID:
return 401;
default: {
assertUnreachable(specialWeaponId);
}
}
};
/**
* Calculates the base weapon ID from a main weapon ID.
*
* @example
* // Returns 40 (because Splattershot is the base weapon for its kit)
* weaponIdToBaseWeaponId(40); // -> 40
*
* // (41 is Tentatek Splattershot, which is an alt kit of Splattershot)
* weaponIdToBaseWeaponId(41); // -> 40
*
* // (45 is Hero Shot Replica, which is an alt skin of Splattershot)
* weaponIdToBaseWeaponId(45); // -> 40
*/
export const weaponIdToBaseWeaponId = (id: MainWeaponId) =>
(id - (id % 10)) as MainWeaponId;