Klima: Geflutet-Kurve stetig + Schutz wirksam (Rebalance) · Lehrer-Cockpit "Nicht aktiv" responsiv

- engine.js: floodedPct steigt jetzt stetig mit dem schutzbereinigten Meeresspiegel statt bei 15% zu plateauen. Guter Schutz haelt das Inland lange trocken (effRise = sea - prot*0.85), Strand-Verlust gedeckelt bei 12%. Downstream mitrebalanciert: Pop-Verlust-Multiplikator 5->3, Wachstums-Schwellen 15/35, Flut-Events 8-20/40, Ende bei >60. Node-validiert: guter Spieler gewinnt + Bevoelkerung waechst (statt Kollaps), Flut diskriminiert gut/mittel/schlecht.
- teacher.html: iv-prow/iv-cols Grid flexibel (Name minmax(0,1fr) + Ellipsis, Datenspalten auto) -> "Nicht aktiv"-Liste laeuft nicht mehr aus der Karte.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
2026-08-22 23:29:39 +02:00
parent 0c4fb84606
commit 2386756a20
2 changed files with 21 additions and 20 deletions
+18 -17
View File
@@ -218,17 +218,17 @@
game.seaLevelCm = game.seaFastCm + game.committedSeaCm;
// Geflutet-Anteil = sichtbare Wirkung auf der Karte:
// 1) Strand frisst der Meeresspiegel sofort, unabhängig vom Schutz —
// schon kleine cm-Erhöhungen sind im Bild als verschwundenes Sandband
// sichtbar. Wir kappen Strand bei 15 % der Inselfläche.
// 2) Inneres Land (Häuser) säuft ab, sobald der Meeresspiegel den
// Schutz deutlich überschreitet. Protection halbiert die effektive
// Rise (Deiche/Mauern verzögern, halten aber nicht ewig).
const beachLoss = Math.min(15, game.seaLevelCm * 1.5);
const effRise = Math.max(0, game.seaLevelCm - game.protection * 0.5);
const interior = Math.min(85, Math.max(0, effRise - 30) * 1.2);
game.floodedPct = Math.round(beachLoss + interior);
// Geflutet-Anteil = sichtbare Wirkung auf der Karte. STETIG (kein Plateau),
// damit der Wert erkennen lässt, wie gut jemand spielt:
// 1) Strand: geht auch bei gutem Schutz ein Stück verloren (unvermeidbar),
// gedeckelt bei 12 % der „Preis" jedes cm Meeresspiegel.
// 2) Inneres Land (Häuser): wächst stetig mit dem SCHUTZ-bereinigten
// Anstieg. Guter Schutz (Deiche/Mauern) drückt effRise stark → hält
// das Inland lange trocken; ohne Schutz säuft es rasch ab.
const effRise = Math.max(0, game.seaLevelCm - game.protection * 0.85);
const beachLoss = Math.min(12, game.seaLevelCm * 0.55);
const interior = Math.min(85, effRise * 1.5);
game.floodedPct = Math.round(Math.min(100, beachLoss + interior));
}
/* ============================================================
@@ -328,7 +328,7 @@
if (game.population >= popCap) return;
const tempFactor = game.currentTemp < 16.5 ? 1 : game.currentTemp < 17.5 ? 0.4 : 0;
const floodFactor = game.floodedPct < 5 ? 1 : game.floodedPct < 15 ? 0.5 : 0;
const floodFactor = game.floodedPct < 15 ? 1 : game.floodedPct < 35 ? 0.5 : 0;
const demand = getPowerDemand(game);
const powerFactor = demand === 0 ? 1 : (game.powerOutput >= demand ? 1 : 0.3);
const budgetFactor = game.budget > 0 ? 1 : 0.2;
@@ -519,9 +519,9 @@
pushEvent(game, '🌡️', '+1 °C: Hitzewellen werden häufiger.', 'bad', 'temperature');
if (game.tick === 80 && game.currentTemp > 17 && !eventFiredOnce(game, 'warning-temp3'))
pushEvent(game, '🔥', '+2 °C: Pariser Klimaziel überschritten!', 'bad', 'temperature');
if (game.floodedPct > 5 && game.floodedPct < 10 && !eventFiredOnce(game, 'flood-1'))
if (game.floodedPct > 8 && game.floodedPct < 20 && !eventFiredOnce(game, 'flood-1'))
pushEvent(game, '🌊', 'Erste Häuser an der Küste sind betroffen.', 'bad', 'sealevel');
if (game.floodedPct > 20 && !eventFiredOnce(game, 'flood-2'))
if (game.floodedPct > 40 && !eventFiredOnce(game, 'flood-2'))
pushEvent(game, '🌊', 'Massive Überflutung — viele verlieren ihr Zuhause!', 'bad', 'sealevel');
if (game.seaLevelCm > 20 && !eventFiredOnce(game, 'vegetation-dying'))
pushEvent(game, '🌿', 'Mangroven und Küstenwälder sterben — Salzwasser versalzt die Böden.', 'bad', 'vegetation');
@@ -640,9 +640,10 @@
game.blackoutStreak = 0;
}
// Überflutungs-Schäden
// Überflutungs-Schäden — Multiplikator gesenkt (5 → 3), weil die Flut-Kurve
// jetzt stetig ist und mittlere Läufe höhere %-Werte zeigen als früher.
if (game.floodedPct > 0) {
game.population -= Math.round(game.floodedPct * 5 * game.diff.popLossMul);
game.population -= Math.round(game.floodedPct * 3 * game.diff.popLossMul);
}
if (game.seaLevelCm > 25) {
const sev = Math.min(1, (game.seaLevelCm - 25) / 40);
@@ -696,7 +697,7 @@
endReason = 'pleite';
game.levelCompleted = true;
game.levelWon = false;
} else if (game.floodedPct > 50) {
} else if (game.floodedPct > 60) {
endReason = 'ueberflutet';
game.levelCompleted = true;
game.levelWon = false;