// Server-side economy helpers — mirrors public/src/economy.js // Uses raw DB rows instead of a client-side cells Map. // ── Label constants (mirrors public/src/planetEconomy.js) ───────────────────── const resources = { common: { rock: "Roches communes", wood: "Bois communs", mineral: "Minérais communs", stones: "Gemmes communes", liquid: "Eau salée", oil: "Fioul brut", gas: "Gaz communs", grain: "Céréales", livestock: "Bétail commun", fish: "Poissons commun", plant: "Plantes communes", goods: "Biens de consommation", animals: "Animaux domestiques", science: "Sites archéologiques", factory: "Usines standards", acid: "Acides pauvres", }, rare: { rock: "Roches rares", wood: "Bois renforcés", mineral: "Minérais rares", stones: "Gemmes rares", liquid: "Eau douce", oil: "Fioul raffiné", gas: "Gaz nobles", grain: "Fruits", livestock: "Bétail raffiné", fish: "Poissons raffinés", plant: "Plantes rares", goods: "Biens de luxe", animals: "Animaux exotiques", science: "Artéfacts anciens", factory: "Usines planétaires", acid: "Acides riches", }, }; const elements = { common: "Matières premières", petrol: "Hydrocarbures", food: "Nourriture", medic: "Médicaments", science: "Science", industry: "Industrie", money: "Finance", goods: "Biens", }; // ── Pre-built lookup maps ───────────────────────────────────────────────────── /** French resource label → { cat: "common"|"rare", key: string } */ const LABEL_TO_RESOURCE = new Map(); for (const [cat, entries] of Object.entries(resources)) { for (const [key, label] of Object.entries(entries)) { LABEL_TO_RESOURCE.set(label, { cat, key }); } } /** French element label → config key (e.g. "Matières premières" → "common") */ const ELEMENT_LABEL_TO_KEY = Object.fromEntries( Object.entries(elements).map(([key, label]) => [label, key]) ); // ── Income computation ──────────────────────────────────────────────────────── /** * Compute total income per second for a team from DB grid rows. * * @param {string} team - "blue" or "red" * @param {Array<{ has_planet: boolean, planet_json: object|null, discovered_by: string }>} rows * @param {{ common: object, rare: object }} resourceWorth * @returns {number} credits per second */ export function computeTeamIncome(team, rows, resourceWorth) { let total = 0; for (const row of rows) { if (row.discovered_by !== team) continue; if (!row.has_planet || !row.planet_json) continue; const { naturalResources } = row.planet_json; if (!naturalResources) continue; for (const [label, pct] of Object.entries(naturalResources)) { const info = LABEL_TO_RESOURCE.get(label); if (!info) continue; const worth = resourceWorth?.[info.cat]?.[info.key] ?? 0; if (worth === 0) continue; total += (pct / 100) * worth; } } return total; } // ── Element bonus computation ───────────────────────────────────────────────── /** * Compute cumulative element bonus (%) for a team from DB grid rows. * * @param {string} team - "blue" or "red" * @param {Array<{ has_planet: boolean, planet_json: object|null, discovered_by: string }>} rows * @param {object} elementWorth - { common: 1, petrol: 3, ... } * @returns {number} bonus in percent */ export function computeTeamElementBonus(team, rows, elementWorth) { let bonus = 0; for (const row of rows) { if (row.discovered_by !== team) continue; if (!row.has_planet || !row.planet_json) continue; const { production } = row.planet_json; if (!production) continue; for (const [elementLabel, pct] of Object.entries(production)) { const elementKey = ELEMENT_LABEL_TO_KEY[elementLabel] ?? elementLabel; const worth = elementWorth?.[elementKey] ?? 0; if (worth === 0) continue; bonus += (pct / 100) * worth; } } return bonus; } // ── Military power computation ──────────────────────────────────────────────── const POP_LABEL_TO_KEY = new Map([ ["Humains", "humans"], ["Presque'humains", "near"], ["Aliens", "aliens"], ]); /** * Compute total military power (in billions) for a team from DB grid rows. * * @param {string} team - "blue" or "red" * @param {Array<{ has_planet: boolean, planet_json: object|null, discovered_by: string }>} rows * @param {object} militaryPower - { humans: 10, near: 5, aliens: 1 } * @returns {number} military power in billions */ export function computeTeamMilitaryPower(team, rows, militaryPower) { let total = 0; for (const row of rows) { if (row.discovered_by !== team) continue; if (!row.has_planet || !row.planet_json) continue; const pop = row.planet_json.population; if (!pop) continue; const key = POP_LABEL_TO_KEY.get(pop.majority); if (!key) continue; const pct = militaryPower?.[key] ?? 0; if (pct === 0) continue; total += pop.billions * pct / 100; } return total; }