// Effects: the single vocabulary used by upgrades, research, legacy perks, // achievements, chips and temporary buffs. To add a new effect type: register // it here, add its `effect.` text to the core locale files, then use it // in any data file. export function newModifiers() { return { click: 1, generators: {}, global: 1, demand: 1, value: 1, materialEfficiency: 1, batchDiscount: 1, batchSize: 1, autoBuyMaterial: false, dividend: 1, reliability: 0, offline: 0, contract: 1, rp: 1, generatorCost: 1, startFunds: 0, priceAdvisor: false, materialPrice: 1, legacyGain: 1, }; } // `times` lets a repeatable effect (a perk level, N achievements) stack. function mult(key) { return (m, e, times) => { m[key] *= e.value ** times; }; } function add(key) { return (m, e, times) => { m[key] += e.value * times; }; } function flag(key) { return (m) => { m[key] = true; }; } const APPLY = { click_mult: mult('click'), generator_mult: (m, e, times) => { m.generators[e.target] = (m.generators[e.target] ?? 1) * e.value ** times; }, global_mult: mult('global'), demand_mult: mult('demand'), value_mult: mult('value'), material_efficiency: mult('materialEfficiency'), batch_discount: mult('batchDiscount'), batch_size_mult: mult('batchSize'), auto_buy_material: flag('autoBuyMaterial'), dividend_mult: mult('dividend'), reliability_add: add('reliability'), offline_add: add('offline'), contract_mult: mult('contract'), rp_mult: mult('rp'), generator_cost_mult: mult('generatorCost'), start_funds: add('startFunds'), price_advisor: flag('priceAdvisor'), material_price_mult: mult('materialPrice'), legacy_gain_mult: mult('legacyGain'), }; export const EFFECT_TYPES = Object.keys(APPLY); /** Fold a list of `{ effect, times }` entries into one set of multipliers. */ export function foldEffects(entries) { const m = newModifiers(); for (const { effect, times = 1 } of entries) { if (effect && times > 0) APPLY[effect.type]?.(m, effect, times); } return m; }