feat: New features (research, invest, gambling, new game+, trophies)

This commit is contained in:
gauvainboiche
2026-10-08 14:03:00 +02:00
parent 1caa4d92b9
commit fc0d5e3ba4
56 changed files with 4332 additions and 249 deletions
+58 -16
View File
@@ -1,5 +1,7 @@
// Upgrade effects. To add a new effect type: register it here, add its
// `effect.<type>` string to the core locale files, and use it in upgrades.json.
// 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.<type>` text to the core locale files, then use it
// in any data file.
export function newModifiers() {
return {
@@ -12,29 +14,69 @@ export function newModifiers() {
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: (m, e) => void (m.click *= e.value),
generator_mult: (m, e) => void (m.generators[e.target] = (m.generators[e.target] ?? 1) * e.value),
global_mult: (m, e) => void (m.global *= e.value),
demand_mult: (m, e) => void (m.demand *= e.value),
value_mult: (m, e) => void (m.value *= e.value),
material_efficiency: (m, e) => void (m.materialEfficiency *= e.value),
batch_discount: (m, e) => void (m.batchDiscount *= e.value),
batch_size_mult: (m, e) => void (m.batchSize *= e.value),
auto_buy_material: (m) => void (m.autoBuyMaterial = true),
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 every owned upgrade into a single set of multipliers. */
export function computeModifiers(ownedIds, upgradesById) {
/** Fold a list of `{ effect, times }` entries into one set of multipliers. */
export function foldEffects(entries) {
const m = newModifiers();
for (const id of ownedIds) {
const effect = upgradesById.get(id)?.effect;
if (effect) APPLY[effect.type]?.(m, effect);
for (const { effect, times = 1 } of entries) {
if (effect && times > 0) APPLY[effect.type]?.(m, effect, times);
}
return m;
}