First commit, done on M6 from the PLAN.MD
This commit is contained in:
@@ -0,0 +1,63 @@
|
||||
// Ways the term can end early. Checked once per day after the economy has moved.
|
||||
//
|
||||
// default debt above the limit: immediate
|
||||
// impeachment civil rights and opinion both very low for N days in a row: certain
|
||||
// coup army loyalty and stability both very low: a daily chance that grows each day in the zone
|
||||
// revolution unrest very high and opinion very low: same growing daily chance
|
||||
//
|
||||
// Entering a danger zone queues an urgent telegram (state.alerts) and pauses the game
|
||||
// until the player acknowledges it. state.risk counts the days spent in each zone.
|
||||
|
||||
import { nextFloat } from "./rng.js";
|
||||
|
||||
function alert(state, kind) {
|
||||
state.alerts.push({ kind, day: state.day });
|
||||
state.pending.alert = true;
|
||||
}
|
||||
|
||||
// Returns the game-over type or null. Mutates state.risk, state.alerts and the RNG.
|
||||
export function checkGameOver(state, bal) {
|
||||
const g = bal.gameOver;
|
||||
const ind = state.indicators;
|
||||
const risk = state.risk;
|
||||
const debtRatio = (state.economy.debt / state.economy.gdp) * 100;
|
||||
|
||||
// Zone bookkeeping: count consecutive days inside, fade (or reset) outside.
|
||||
const track = (name, inZone, fade) => {
|
||||
if (inZone) {
|
||||
risk[name] += 1;
|
||||
if (risk[name] === 1) alert(state, name);
|
||||
} else {
|
||||
risk[name] = fade === "reset" ? 0 : Math.max(0, risk[name] - fade);
|
||||
}
|
||||
};
|
||||
const chance = (name, perDay) => risk[name] > 0 && nextFloat(state) < Math.min(1, perDay * risk[name]);
|
||||
|
||||
if (debtRatio >= g.default.warnAbove) {
|
||||
if (!risk.defaultZone) {
|
||||
risk.defaultZone = true;
|
||||
alert(state, "default");
|
||||
}
|
||||
} else if (debtRatio < g.default.warnAbove - 10) {
|
||||
risk.defaultZone = false;
|
||||
}
|
||||
|
||||
const inImpeachment = ind.civilRights < g.impeachment.civilRightsBelow && ind.opinion < g.impeachment.opinionBelow;
|
||||
const inCoup = ind.armyLoyalty < g.coup.armyBelow && ind.stability < g.coup.stabilityBelow;
|
||||
const inRevolution = ind.unrest > g.revolution.unrestAbove && ind.opinion < g.revolution.opinionBelow;
|
||||
track("impeachment", inImpeachment, "reset");
|
||||
track("coup", inCoup, 1);
|
||||
track("revolution", inRevolution, 1);
|
||||
|
||||
if (debtRatio > g.default.debtAbove) return "default";
|
||||
if (risk.impeachment >= g.impeachment.days) return "impeachment";
|
||||
if (inCoup && chance("coup", g.coup.chancePerDay)) return "coup";
|
||||
if (inRevolution && chance("revolution", g.revolution.chancePerDay)) return "revolution";
|
||||
return null;
|
||||
}
|
||||
|
||||
// The player has read the telegram at the front of the queue.
|
||||
export function dismissAlert(state) {
|
||||
state.alerts.shift();
|
||||
state.pending.alert = state.alerts.length > 0;
|
||||
}
|
||||
Reference in New Issue
Block a user