Something went wrong. Try again.
Web frontend and supporting services for lance.blue
Something went wrong. Try again.
4.4 kB · 97 lines
TypeScript
1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798/** * MegaMek's era table, and the era a year falls in. * * The daily card names the era its fight belongs to, and the only input it has * for that is the years already in daily.json. The newest design in a fight is * the earliest the fight could be set, so `years.to` is what picks the era — * a fight fielding a 3063 machine is not a Succession Wars fight, whatever the * oldest chassis in it is. * * The boundaries are MegaMek's own, copied from `data/universe/eras.xml` in * the pinned arena image, so they are the same ones the game uses. `end` is * the era's last year: MegaMek's `docs/Universe Modding/Eras.txt` says a bare * `yyyy` end date means the last day of that year, and every canon boundary * below matches the chronology on sarna.net's BattleTech eras page. * * `name` is what the card shows and the key into `ERA_ICONS`, and it is not * always MegaMek's own `<name>`: * * - MegaMek's "Civil War" is the FedCom Civil War — sarna's Federated * Commonwealth Civil War, 3062 to 3067 — and "Civil War" alone does not say * which one. * - MegaMek splits the Republic at 3100 into Early and Late Republic. Sarna's * chronology has one Republic Age, 3081 to 3130, so both rows carry that * name; MegaMek's own docs say era names need not be unique. * - Sarna writes the Succession War sub-eras in the singular, and spells the * last one Dark Age rather than Dark Ages. * - Sarna groups MegaMek's two pre-2005 eras under Pre-Star League, which is * already the site's spelling, and no BattleMech is old enough to fall in * either of them anyway. */
/** One era: what to call it, and the last year it covers. */export type Era = { /** The era's code in MegaMek's `eras.xml`, which is the row to check against. */ code: string; /** The name shown on the card, and a key of `ERA_ICONS`. */ name: string; /** The era's last year, or null for the open-ended one at the end. */ end: number | null;};
/** MegaMek's eras, oldest first, one row per row of `eras.xml`. */export const ERAS: readonly Era[] = [ { code: "PSF", name: "Pre-Star League", end: 1950 }, { code: "ESF", name: "Pre-Star League", end: 2004 }, { code: "AOW", name: "Age of War", end: 2570 }, { code: "SL", name: "Star League", end: 2780 }, { code: "ESW", name: "Early Succession War", end: 2900 }, { code: "LSWL", name: "Late Succession War - LosTech", end: 3019 }, { code: "LSWR", name: "Late Succession War - Renaissance", end: 3049 }, { code: "CI", name: "Clan Invasion", end: 3061 }, { code: "CW", name: "FedCom Civil War", end: 3067 }, { code: "JHD", name: "Jihad", end: 3080 }, { code: "EREP", name: "Republic Age", end: 3100 }, { code: "LREP", name: "Republic Age", end: 3130 }, { code: "DAGE", name: "Dark Age", end: 3150 }, { code: "ILC", name: "ilClan", end: null },];
/** * The era a year falls in. * * Null for a year that is not one: `mms index` writes a year of 0 when arena's * report gave it nothing to work with, and a card that showed Pre-Star League * for that would be inventing an answer rather than leaving the gap. */export function eraFor(year: number): Era | null { if (!Number.isInteger(year) || year <= 0) return null; return ERAS.find((era) => era.end === null || year <= era.end) ?? null;}
/** * The years an era covers, as the card writes them: `2781-3019`, or `3131+` * for the open-ended one. * * Measured across every consecutive row sharing the era's name, not just the * row a year matched. Two rows are called Pre-Star League and two are called * Republic Age, and quoting one row's dates under the shared name would give * the Republic Age as 3081-3100 - half of it - which is worse than saying * nothing. * * The first era has no start year to quote: nothing it could name is older * than it, so it is written open at the bottom. */export function eraSpan(era: Era): string { const first = ERAS.findIndex((row) => row.name === era.name); if (first < 0) return ""; let last = first; while (last + 1 < ERAS.length && ERAS[last + 1]!.name === era.name) last++;
const before = first > 0 ? ERAS[first - 1]!.end : null; const start = before === null ? null : before + 1; const end = ERAS[last]!.end;
if (start === null) return end === null ? "" : `to ${end}`; return end === null ? `${start}+` : `${start}–${end}`;}