orbit/js/galaxy/FxSystems.js

45 lines
1.8 KiB
JavaScript

/**
* Picking a system for the effects demo (?fx=<type>) — pure over the
* seeded roster, so dev/system-effects.test.mjs can exercise the
* ranking in bare Node.
*
* The demo wants to drop the player into a system of the requested
* archetype that is GOOD for judging the effect: plenty of structure to
* warp (worlds, a belt, a gate or two to jump out of). Candidates are
* therefore ranked richest-first — more objects, then more jump gates —
* with roster order as the stable tiebreak (seed-deterministic either
* way: the roster is seed-ordered and the score is a pure function of
* the record + its cached contents).
*/
/**
* @param {object} galaxy a seeded galaxy (Galaxy.js) — reads `.records`
* ({ id, type, ... }[]) and `.contentCache` (Map id -> contents,
* possibly empty — content is lazy).
* @param {string} type the requested archetype (systems.types key)
* @returns {object | null} the chosen record (has `.id`), or null when
* the roster holds no system of that type.
*/
export function pickFxSystem(galaxy, type) {
const records = Array.isArray(galaxy?.records) ? galaxy.records : [];
const cache = galaxy?.contentCache instanceof Map ? galaxy.contentCache : null;
let best = null;
let bestKey = null;
for (const rec of records) {
if (!rec || rec.type !== type) continue;
const content = cache?.get(rec.id) ?? null;
const objects =
(Array.isArray(content?.planets) ? content.planets.length : 0) +
(Array.isArray(content?.settlements) ? content.settlements.length : 0) +
(Array.isArray(content?.asteroids) ? content.asteroids.length : 0);
const gates = Array.isArray(content?.jumps) ? content.jumps.length : 0;
const key = objects * 1000 + gates;
if (!best || key > bestKey) {
best = rec;
bestKey = key;
}
}
return best;
}