aotds-docks/src/lib/store/ship/weaponry/rules.ts

314 lines
6.1 KiB
TypeScript

import type { Reqs } from "$lib/shipDux/reqs";
export const arcs = ["FS", "F", "FP", "AP", "A", "AS"] as const;
export const broadsideArcs = ["FP", "AP", "AS", "FS"];
export type Arc = (typeof arcs)[number];
export type WeaponType = "beam";
type Beam = {
type: "beam";
weaponClass: 1 | 2 | 3 | 4;
arcs: Arc[];
};
type Submunition = {
type: "submunition";
arc: Arc;
};
type PDS = {
type: "pds";
};
type Scattergun = { type: "scattergun" };
type Needle = { type: "needle"; arc: Arc };
type HeavyMissile = {
type: "heavyMissile";
arcs: Arc[];
extended: boolean;
multiStage: boolean;
};
type SalvoMissileRack = {
type: "salvoMissileRack";
arcs: Arc[];
extended: boolean;
};
type MissileMagazine = {
id: number;
maxAmmo: number;
extended: boolean;
};
type SalvoMissileLauncher = {
type: "salvoMissileLauncher";
arcs: Arc[];
missileMagazineId: number;
};
type Graser = {
type: "graser";
weaponClass: 1 | 2 | 3;
arcs: Arc[];
};
type Torpedo = {
type: "torpedo";
weaponClass: 1 | 2 | 3 | 4;
arcs: Arc[];
};
export type Weapon =
| Beam
| Submunition
| PDS
| Scattergun
| Needle
| Graser
| Torpedo
| HeavyMissile
| SalvoMissileLauncher;
export const weaponTypes = [
{
type: "beam",
name: "beam",
reqs: beamReqs,
initial: {
type: "beam",
weaponClass: 1,
arcs,
} as any as Beam,
},
{
type: "graser",
name: "graser",
reqs: graserReqs,
initial: {
type: "graser",
weaponClass: 1,
arcs: ["F"],
} as any as Graser,
options: [
{ weaponClass: 1, nbrArcs: [1, 3, 6, "broadside"] },
{
weaponClass: 2,
nbrArcs: [1, 2, 3, 4, 5, 6, "broadside"],
},
{
weaponClass: 3,
nbrArcs: [1, 2, 3, 4, 5, 6, "broadside"],
},
],
},
{
type: "torpedo",
name: "torpedo",
reqs: torpedoReqs,
initial: {
type: "torpedo",
weaponClass: 1,
arcs: ["F"],
} as any as Torpedo,
options: {
maxClass: 4,
nbrArcs: [1, 2, 3, "broadside"],
},
},
{
type: "submunition",
name: "submunition pack",
reqs: { mass: 1, cost: 3 },
initial: { type: "submunition", arc: "F" } as Submunition,
},
{
name: "point defence system",
type: "pds",
reqs: { mass: 1, cost: 3 },
initial: {
type: "pds",
},
},
{
name: "scattergun",
type: "scattergun",
reqs: { mass: 1, cost: 4 },
initial: { type: "scattergun" },
},
{
name: "needle beam",
type: "needle",
reqs: { mass: 2, cost: 6 },
initial: { arc: "F", type: "needle" },
},
{
name: "heavy missile",
type: "heavyMissile",
reqs: missileReqs,
initial: {
arcs: ["FP", "F", "FS"],
extended: false,
multiStage: false,
type: "heavyMissile",
},
},
{
name: "salvo missile rack",
type: "smr",
reqs: smrReqs,
initial: {
arcs: ["FP", "F", "FS"],
extended: false,
type: "smr",
},
},
{
name: "salvo missile launcher",
type: "sml",
reqs: { cost: 9, mass: 3 },
initial: {
arcs: ["FP", "F", "FS"],
type: "sml",
missileMagazineId: 1,
},
},
];
export function weaponReqs(weapon): Reqs {
const { reqs } = weaponTypes.find((wt) => wt.type === weapon.type) || {};
if (!reqs)
return {
cost: 0,
mass: 0,
};
if (typeof reqs === "function") return reqs(weapon);
return reqs;
}
export const isBroadside = (arcs: Arc[]) => {
if (arcs.length !== 4) return false;
// that'd be A or F
return !arcs.some((a) => a.length === 1);
};
function beamReqs({ weaponClass, arcs }: Beam) {
let mass;
if (weaponClass === 1) {
mass = 1;
}
if (weaponClass === 2) {
mass = 2 + (arcs.length > 3 ? 1 : 0);
}
if (weaponClass == 3) {
mass = 4;
if (isBroadside(arcs)) {
mass += 2;
} else {
mass += arcs.length - 1;
}
}
if (weaponClass == 4) {
mass = 8;
if (isBroadside(arcs)) {
mass += 4;
} else {
mass += 2 * (arcs.length - 1);
}
}
return {
mass,
cost: 3 * mass,
};
}
function graserReqs({ weaponClass, arcs }: Graser) {
let mass: number;
if (weaponClass === 1) {
if (arcs.length === 1) {
mass = 2;
} else if (arcs.length === 3) {
mass = 3;
} else {
mass = 4;
}
} else if (weaponClass === 2) {
mass = 9;
if (isBroadside(arcs)) {
mass += 6;
} else {
mass += 3 * (arcs.length - 1);
}
} else if (weaponClass === 3) {
mass = 24;
if (isBroadside(arcs)) {
mass += 12;
} else {
mass += 6 * (arcs.length - 1);
}
}
return {
mass,
cost: 4 * mass,
};
}
function missileReqs({ extended, multiStage }: HeavyMissile): Reqs {
let mass = 2;
let cost = 6;
if (extended) {
mass += 1;
cost += 3;
}
if (multiStage) {
mass += 2;
cost *= 2;
}
return { cost, mass };
}
function smrReqs({ extended }: SalvoMissileRack): Reqs {
let mass = 4;
if (extended) mass += 1;
return {
mass,
cost: 3 * mass,
};
}
function torpedoReqs({ weaponClass, arcs }: Torpedo): Reqs {
let mass: number = 4;
if (isBroadside(arcs)) {
mass += 2;
} else {
mass += arcs.length - 1;
}
mass = mass * Math.pow(2, weaponClass - 1);
return {
mass,
cost: 3 * mass,
};
}