fertig-classic-games/src/games/mastervega/VegaTechEffects.js

66 lines
4.3 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

// Master of Vega — human-readable descriptions for `tech.effects` values.
// Headless, no Phaser: kept separate from VegaTurnReport.js so any other
// screen (a future tech-tree view, say) can reuse the same wording without
// pulling in turn-report-specific code.
//
// Every formatter is hand-matched to how the effect is actually consumed
// elsewhere in the engine (VegaCombat.js/VegaLogic.js/VegaShips.js) — not a
// generic key/value dump. `scanRange` (VegaLogic.js's fleetInScanRange) is
// what unlocks a rival fleet's read-only detail view — MasterOfVegaGame.js's
// onFleetClick and VegaSidePanel.js's buildFleet — once one of your own
// colonies or fleets sits within range of it; it does not reveal star
// systems themselves (that's explored[], unrelated).
const pct = (mult) => `${Math.round(Math.abs(mult - 1) * 100)}%`;
function describeWeapon(w) {
const perRound = w.shots > 1 ? `, ${w.shots} shots per round` : '';
const pierce = w.shieldPierce
? `, pierces ${w.shieldPierce} point${w.shieldPierce === 1 ? '' : 's'} of enemy shields` : '';
const cracker = w.planetCracker ? ' — powerful enough to crack a planet apart' : '';
return `New ${w.kind} weapon available: ${w.name}, ${w.min}-${w.max} damage per shot${perRound}${pierce}${cracker}.`;
}
function hostilityWorlds(rules, tier) {
const names = rules.planetTypeList
.filter((t) => t.colonizable && t.hostility === tier)
.map((t) => t.name);
return names.length ? `${names.join('/')}-class` : `hostility ${tier}`;
}
const FORMATTERS = {
armor: (rules, v) => `Hull armor upgraded to ${v.name} plating — hull hit points ×${v.hpMult} (+${pct(v.hpMult)}).`,
cloaked: (rules) => `Ships are fitted with a stealth field — enemy weapons are ${Math.round((rules.combat.cloakEvasion ?? 0) * 100)} percentage points less likely to hit.`,
colonizeHostility: (rules, v) => `Colonists can now settle ${hostilityWorlds(rules, v)} worlds.`,
counterEspionage: (rules, v) => `+${v} counter-espionage — makes it harder for enemy agents to steal your technology.`,
engine: (rules, v) => `Engines upgraded to ${v.name} Drive (speed ${v.speed}).`,
espionage: (rules, v) => `+${v} espionage — improves your odds of stealing enemy technology.`,
factoryCostMult: (rules, v) => `Factories cost ${pct(v)} less to build.`,
fuelRange: (rules, v) => `Fuel range extended to ${v} parsecs — fleets can be ordered further from friendly colonies and starbases.`,
groundAttack: (rules, v) => `+${v} ground attack — improves the odds of a successful invasion.`,
groundDefense: (rules, v) => `+${v} ground defense — colonies field more defenders when invaded.`,
initiative: (rules, v) => `+${v} initiative — fleets choose their engagement range before slower opponents each combat round.`,
maxPopBonus: (rules, v) => `+${v} maximum population per colony.`,
planetaryShield: (rules, v) => (
`+${v} planetary shield — cuts population lost to bombardment by about ${Math.round((1 - 1 / (1 + v * 0.15)) * 100)}%.`
),
redirectInFlight: () => 'Fleets already in transit can be redirected to a new destination.',
refitCostMult: (rules, v) => `Auto-refit costs reduced by ${pct(v)}.`,
repairPerRound: (rules, v) => `Ships self-repair ${Math.round(v * 100)}% of max hull every combat round.`,
researchMult: (rules, v) => `Research output increased by ${pct(v)} empire-wide.`,
scanRange: (rules, v) => `+${v} parsec scanner range — enemy fleets within range of one of your `
+ 'colonies or fleets can be inspected in full, ship by ship.',
shield: (rules, v) => `Deflector shields absorb ${v} point${v === 1 ? '' : 's'} of damage from every incoming hit, on ships and planetary defenses alike.`,
singularity: (rules) => `A breakthrough in exotic physics — every weapon on this ship warps enemy deflectors, trimming ${rules.combat.singularityShieldPierce ?? 0} point of shielding off every hit it lands.`,
targeting: (rules, v) => `Combat accuracy increased by ${Math.round(v * 6)}% (better targeting computers).`,
wasteMult: (rules, v) => `Industrial waste reduced by ${pct(v)}.`,
weapon: (rules, v) => describeWeapon(v),
};
/** Turns a tech's `effects` object into an array of full sentences, one per effect. */
export function describeTechEffects(rules, effects) {
return Object.entries(effects ?? {})
.map(([key, value]) => FORMATTERS[key]?.(rules, value))
.filter(Boolean);
}