From 7986bb2eb6b721297c7704ae3d6cbadd7ee8d40a Mon Sep 17 00:00:00 2001 From: Thomas Date: Sun, 23 Aug 2026 12:48:26 +0200 Subject: [PATCH] =?UTF-8?q?Heli:=20Treibstoff=20kann=20leer=20werden=20(1?= =?UTF-8?q?=E2=98=85-Takeover)=20+=20Live-Score=20fuer=20Tag-Farbe=20+=20A?= =?UTF-8?q?ktuell-Status/Phase?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - start.html: Sprit-Floor 0.05->0; Treibstoff-leer loest Chefpilotin-Takeover aus (stars:1) - game.html: GGS_LIVE_STATE liefert progressiven score (Routing/Start/Landung/Gesamt) -> farbige Tag-Balken - teacher.html: Phasen-Map + Status-Spalte fuer mission/briefing/unterwegs (kein leeres "...") Co-Authored-By: Claude Opus 4.8 --- App/sims/heli/game.html | 13 +++++++++++++ App/sims/heli/start.html | 17 ++++++++++++++++- App/teacher.html | 5 +++-- 3 files changed, 32 insertions(+), 3 deletions(-) diff --git a/App/sims/heli/game.html b/App/sims/heli/game.html index c180668..54086e3 100644 --- a/App/sims/heli/game.html +++ b/App/sims/heli/game.html @@ -480,6 +480,19 @@ window.GGS_LIVE_STATE = function () { totalStars: landingDone ? (game.totalStars || 0) : null, failed: !!game.missionFailed, missionStartedAt: game.missionStartedAt || null, + // Laufender 0–100-Score für die Ampelfarbe im Lehrer-Live (Tag-Balken). + // Progressiv: Routing-Genauigkeit, dann Ø mit Start-/Landungssternen; am Ende + // die Gesamtsterne. In der Auftragswahl (mission/briefing) kein Score. + score: (function(){ + if (!phase || phase === 'mission' || phase === 'briefing') return null; + if (landingDone && game.totalStars != null) return Math.round(Math.max(0,Math.min(5,game.totalStars))/5*100); + var parts = []; + if (routeLen > 1) parts.push(Math.max(0, Math.min(100, (game.planTotal?(game.planCorrect||0)/game.planTotal:0)*100 - (game.planAttempts||0)*4))); + if (startDone && game.startScore != null) parts.push(Math.max(0,Math.min(5,game.startScore))/5*100); + if (landingDone && game.landingScore != null) parts.push(Math.max(0,Math.min(5,game.landingScore))/5*100); + if (!parts.length) return null; + return Math.round(parts.reduce(function(a,b){return a+b;},0)/parts.length); + })(), }; }; diff --git a/App/sims/heli/start.html b/App/sims/heli/start.html index 8b71a4a..754c151 100644 --- a/App/sims/heli/start.html +++ b/App/sims/heli/start.html @@ -1723,7 +1723,22 @@ if (wantFlap) thrustMult += 0.8; if (h.vy < -40) thrustMult += Math.min(1.0, -h.vy / 160); else if (h.vy > 60) thrustMult = Math.max(0.4, thrustMult - 0.5); - h.fuel = Math.max(0.05, h.fuel - 0.005 * altFactor * thrustMult * dt); + h.fuel = Math.max(0, h.fuel - 0.005 * altFactor * thrustMult * dt); + // Treibstoff leer → Chefpilotin übernimmt (wie 3 Berührungen): schlechteste + // Start-Bewertung (1★). Nur einmal auslösen und nicht, wenn ohnehin schon + // ein Takeover läuft. + if (h.fuel <= 0 && state.mode !== 'autopilot' && !state._fuelEmpty) { + state._fuelEmpty = true; + state.mode = 'autopilot'; + stopAllAmbient(); + state.autopilotT = 0; + h.invul = 999; + state.takeoverReason = 'Treibstoff leer — die Chefpilotin bringt den Helikopter sicher zurück. Beim nächsten Start früher auf den Verbrauch achten und nicht zu hoch steigen (dünne Luft = ×8 Verbrauch).'; + state.takeoverShort = 'Treibstoff leer'; + state.radio.current = 'Pilot: Tank leer! Ich übernehme.'; + state.radio.shown = 0; state.radio.nextAt = 99; + try { playRadio('warn_fuel'); } catch(_){} + } // Visuelle Höhenwarnung: roter Pulse oben + Fuel-HUD blinkt // Greift sobald altRatio > 0.9 (= im obersten 10 % der Bildhöhe). var inDangerZone = altRatio > 0.9; diff --git a/App/teacher.html b/App/teacher.html index 7610032..1c4c648 100644 --- a/App/teacher.html +++ b/App/teacher.html @@ -856,7 +856,7 @@ var LIVE_PRIMARY_FIELDS = { ], 'heli': [ {k:'phase', label:'Phase', align:'center', fmt:function(v){ - var m = {plan:'🗺️ Routenplan', start:'🛫 Start', flight:'✈️ Flug', approach:'🎯 Anflug', landing:'🛬 Landung', results:'🏁 Ende'}; + var m = {mission:'📋 Auftragswahl', plan:'🗺️ Routenplan', briefing:'📋 Briefing', start:'🛫 Start', flight:'✈️ Flug', approach:'🎯 Anflug', landing:'🛬 Landung', results:'🏁 Ende'}; return m[v] || (v ? v : '—'); }}, {k:'missionId', label:'Auftrag', align:'left', fmt:function(v, row){ @@ -905,7 +905,8 @@ var LIVE_PRIMARY_FIELDS = { var s = row.state||{}; if (v === true) return '⚠ Chefpilot'; if (s.phase === 'results') return '✓ Erfolg'; - return ''; + if (s.phase === 'mission' || !s.phase) return 'wählt Auftrag'; + return '🟢 unterwegs'; }}, ], 'fluss': [