This commit is contained in:
33333-33333 2026-05-13 17:51:12 +09:00
commit 09da7eee8a

View file

@ -1747,6 +1747,9 @@ class Simulation {
founded: this.year,
legitimacy: this.rng.range(0.68, 0.94),
cohesion: this.rng.range(0.58, 0.9),
charisma: this.rng.range(0.5, 1.5),
leaderStarted: this.year,
leaderTenureYears: this.rng.range(24, 68),
crisis: 0,
lastCrisisYear: this.year
};
@ -1811,6 +1814,45 @@ class Simulation {
for (const polity of this.polities) this.samplePolityHistory(polity);
}
selectNewLeader(polity, forced = false) {
if (!polity) return;
const previousCharisma = clamp(polity.charisma ?? 1, 0.5, 1.5);
const center = this.getCityById(polity.centerCityId);
const centerStability = center ? clamp(center.loyalty ?? 0.5, 0, 1) : 0.5;
const institutionalBias = ((polity.legitimacy ?? 0.7) + (polity.cohesion ?? 0.6) + centerStability) / 3;
const randomLeader = this.rng.range(0.5, 1.5);
const continuity = forced ? 0.18 : 0.34;
const institutionalPull = 0.82 + institutionalBias * 0.36;
const nextCharisma = clamp(
previousCharisma * continuity + randomLeader * (1 - continuity) * institutionalPull,
0.5,
1.5
);
polity.charisma = nextCharisma;
polity.leaderStarted = this.year;
polity.leaderTenureYears = this.rng.range(22, 72);
const change = nextCharisma - previousCharisma;
polity.legitimacy = clamp((polity.legitimacy ?? 0.7) + change * 0.08 - (forced ? 0.035 : 0), 0, 1);
polity.cohesion = clamp((polity.cohesion ?? 0.6) + change * 0.045 - (forced ? 0.020 : 0), 0, 1);
if (forced) polity.crisis = clamp((polity.crisis || 0) + 0.04, 0, 1.5);
}
updatePolityLeaders() {
for (const polity of this.polities) {
polity.charisma = clamp(polity.charisma ?? 1, 0.5, 1.5);
polity.leaderStarted ??= polity.founded ?? this.year;
polity.leaderTenureYears ??= this.rng.range(24, 68);
const tenureYears = (this.year - polity.leaderStarted) / MONTHS_PER_YEAR;
const oldLeader = Math.max(0, tenureYears - polity.leaderTenureYears);
const crisisPressure = clamp((polity.crisis || 0) * 0.045, 0, 0.09);
const successionChance = clamp(oldLeader * 0.018 + crisisPressure, 0, 0.36);
if (successionChance > 0 && this.rng.next() < successionChance) {
this.selectNewLeader(polity, (polity.crisis || 0) > 0.85);
}
}
}
markPolityEnded(polity, reason = "dissolved") {
if (!polity) return;
const history = this.ensurePolityHistory(polity);
@ -1916,7 +1958,7 @@ class Simulation {
const instability = this.polityInstability ? this.polityInstability(polity) : 0;
const agePressure = this.polityAgePressure ? this.polityAgePressure(polity) : 0;
return Math.max(0,
const basePower = Math.max(0,
Math.sqrt(population) * 1.35 +
Math.sqrt(treasury) * 1.15 +
avgLoyalty * 16 +
@ -1924,6 +1966,7 @@ class Simulation {
instability * 12 -
agePressure * 6
);
return basePower * clamp(polity.charisma ?? 1, 0.5, 1.5);
}
polityInfluenceRange(polity, wartime = false) {
@ -2656,6 +2699,7 @@ class Simulation {
if (this.erodePolityLegitimacy) this.erodePolityLegitimacy();
if (this.triggerPolityCrises) this.triggerPolityCrises();
if (this.applyOldStateStress) this.applyOldStateStress();
if (this.updatePolityLeaders) this.updatePolityLeaders();
this.updateCityLoyalty();
this.absorbIndependentCities();
@ -3059,6 +3103,9 @@ class Simulation {
founded: p.founded,
legitimacy: p.legitimacy,
cohesion: p.cohesion,
charisma: p.charisma,
leaderStarted: p.leaderStarted,
leaderTenureYears: p.leaderTenureYears,
crisis: p.crisis,
lastCrisisYear: p.lastCrisisYear
})),
@ -3145,6 +3192,9 @@ class Simulation {
founded: p.founded || 0,
legitimacy: p.legitimacy ?? 0.7,
cohesion: p.cohesion ?? 0.6,
charisma: clamp(p.charisma ?? 1, 0.5, 1.5),
leaderStarted: p.leaderStarted ?? p.founded ?? sim.year,
leaderTenureYears: clamp(p.leaderTenureYears ?? 48, 12, 96),
crisis: p.crisis ?? 0,
lastCrisisYear: p.lastCrisisYear ?? sim.year
}));
@ -3439,6 +3489,8 @@ function renderTooltip() {
${cityEthnicity ? `<span><b>City majority</b><em>E${cityEthnicity}</em></span>` : ""}
${city ? `<span><b>State</b><em>${polity ? `#${polity.id}` : "Independent"}</em></span>` : ""}
${city ? `<span><b>Loyalty</b><em>${city.loyalty.toFixed(2)}</em></span>` : ""}
${polity ? `<span><b>Charisma</b><em>${clamp(polity.charisma ?? 1, 0.5, 1.5).toFixed(2)}</em></span>` : ""}
${polity ? `<span><b>Leader tenure</b><em>${Math.floor((sim.year - (polity.leaderStarted ?? polity.founded ?? sim.year)) / MONTHS_PER_YEAR)}y</em></span>` : ""}
${polity ? `<span><b>Treasury</b><em>${polity.treasury.toFixed(1)}</em></span>` : ""}
${polity ? `<span><b>Center</b><em>${polity.centerCityId === city.id ? "yes" : "no"}</em></span>` : ""}
${agent ? `<span><b>Ethnicity</b><em>E${agent.ethnicity}</em></span>` : ""}