First commit, done on M6 from the PLAN.MD
This commit is contained in:
@@ -0,0 +1,84 @@
|
||||
// Effects and timed modifiers. Card choices end up here.
|
||||
//
|
||||
// Effect shapes:
|
||||
// { stat, delta } instant shift of an indicator or economy variable
|
||||
// { stat, delta, days } shift spread evenly over `days` (then the value mean-reverts)
|
||||
// { stat, delta, bias: true, days? } offset on the stat's *target* for `days` (permanent if omitted)
|
||||
// { sector, delta[, days][, bias] } same, on a sector's quality
|
||||
// { revenue: "income"|"corporate"|"vat", delta } change tax rate (rate points), permanent
|
||||
// { revenue: "other", delta } change other revenue (% of GDP), permanent
|
||||
// { oneOff: pct } one-time cost in % of GDP (negative = windfall)
|
||||
// { extraSpending: delta } permanent extra spending in % of GDP
|
||||
|
||||
import { IND_IDS, VAR_IDS, TAX_IDS, clamp } from "./state.js";
|
||||
|
||||
function groupOf(effect, state) {
|
||||
if (effect.sector !== undefined) return state.sectors[effect.sector] ? ["sector", effect.sector] : null;
|
||||
if (IND_IDS.includes(effect.stat)) return ["ind", effect.stat];
|
||||
if (VAR_IDS.includes(effect.stat)) return ["var", effect.stat];
|
||||
return null;
|
||||
}
|
||||
|
||||
function shift(state, bal, group, key, delta) {
|
||||
if (group === "ind") state.indicators[key] = clamp(state.indicators[key] + delta, 0, 100);
|
||||
else if (group === "sector") state.sectors[key].quality = clamp(state.sectors[key].quality + delta, 0, 100);
|
||||
else {
|
||||
const v = bal.vars[key];
|
||||
state.economy[key] = clamp(state.economy[key] + delta, v.min, v.max);
|
||||
}
|
||||
}
|
||||
|
||||
export function applyEffect(state, bal, effect) {
|
||||
if (effect.stat !== undefined || effect.sector !== undefined) {
|
||||
const found = groupOf(effect, state);
|
||||
if (!found) return false;
|
||||
const [group, key] = found;
|
||||
if (effect.bias) {
|
||||
state.modifiers.push({ type: "bias", group, key, value: effect.delta, remaining: effect.days ?? null });
|
||||
} else if (effect.days > 0) {
|
||||
state.modifiers.push({ type: "shift", group, key, perDay: effect.delta / effect.days, remaining: effect.days });
|
||||
} else {
|
||||
shift(state, bal, group, key, effect.delta);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
const e = state.economy;
|
||||
if (effect.revenue !== undefined) {
|
||||
if (TAX_IDS.includes(effect.revenue)) e.taxes[effect.revenue] = Math.max(0, e.taxes[effect.revenue] + effect.delta);
|
||||
else if (effect.revenue === "other") e.otherRevenue = Math.max(0, e.otherRevenue + effect.delta);
|
||||
else return false;
|
||||
return true;
|
||||
}
|
||||
if (effect.oneOff !== undefined) {
|
||||
e.debt = Math.max(0, e.debt + (effect.oneOff / 100) * e.gdp);
|
||||
return true;
|
||||
}
|
||||
if (effect.extraSpending !== undefined) {
|
||||
e.extraSpending += effect.extraSpending;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// Start of each day: apply the spread-out shifts.
|
||||
export function applyShifts(state, bal) {
|
||||
for (const m of state.modifiers) {
|
||||
if (m.type !== "shift") continue;
|
||||
shift(state, bal, m.group, m.key, m.perDay);
|
||||
m.remaining -= 1;
|
||||
}
|
||||
state.modifiers = state.modifiers.filter((m) => m.type !== "shift" || m.remaining > 0);
|
||||
}
|
||||
|
||||
// Sum of active target offsets for one stat.
|
||||
export function biasFor(state, group, key) {
|
||||
let sum = 0;
|
||||
for (const m of state.modifiers) if (m.type === "bias" && m.group === group && m.key === key) sum += m.value;
|
||||
return sum;
|
||||
}
|
||||
|
||||
// End of each day: age timed biases.
|
||||
export function ageBias(state) {
|
||||
for (const m of state.modifiers) if (m.type === "bias" && m.remaining !== null) m.remaining -= 1;
|
||||
state.modifiers = state.modifiers.filter((m) => m.type !== "bias" || m.remaining === null || m.remaining > 0);
|
||||
}
|
||||
Reference in New Issue
Block a user