Lehrer-Live: laufende Klima-Balken farbig (Ampel) + "Heute bereits erledigt" zeigt alle heutigen Durchgaenge
- klima game-2d/3d: GGS_LIVE_STATE liefert laufenden Punktestand (score, gleiche Formel wie Endbewertung) - live.php summary: laufende Sessions jeder Sim bekommen Ampel-Score (nicht mehr nur Farmer) -> Tag-Ansicht faerbt laufende Balken statt grau - teacher.html _renderInactiveToday: zeigt jetzt ALLE heute abgeschlossenen Laeufe (auch von gerade aktiven Schueler:innen); nur das laufende Spiel bleibt oben. Titel -> "Heute bereits erledigt" Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -339,8 +339,14 @@ if ($method === 'GET') {
|
||||
$startMs = ((int)$lr['started_ts']) * 1000;
|
||||
$endMs = ((int)$lr['last_seen_ts']) * 1000;
|
||||
$durSec = max(0, intval(($endMs - $startMs) / 1000));
|
||||
// Live-Erfolgs-Score für die Ampelfarbe: Farmer = aktuelle Trefferquote.
|
||||
$liveScore = ($simId === 'farmer' && isset($state['hit_rate'])) ? max(0, min(100, (int)$state['hit_rate'])) : null;
|
||||
// Live-Erfolgs-Score für die Ampelfarbe: Farmer = aktuelle Trefferquote,
|
||||
// sonst der vom Sim gelieferte laufende Punktestand (0–100, z. B. Klima).
|
||||
$liveScore = null;
|
||||
if ($simId === 'farmer' && isset($state['hit_rate'])) {
|
||||
$liveScore = max(0, min(100, (int)$state['hit_rate']));
|
||||
} elseif (isset($state['score']) && is_numeric($state['score'])) {
|
||||
$liveScore = max(0, min(100, (int)round($state['score'])));
|
||||
}
|
||||
$byStudent[$sid]['sessions'][] = [
|
||||
'simId' => $simId,
|
||||
'simTitle' => $mi['title'] ?? $simId,
|
||||
|
||||
@@ -1330,8 +1330,22 @@ window.GGS_LIVE_STATE = function () {
|
||||
speed: state.speed || 0,
|
||||
measures: Array.isArray(state.actionLog) ? state.actionLog.filter(a=>a.action==='buy').length : 0,
|
||||
levelWon: !!state.levelWon,
|
||||
// Laufender Punktestand (0–100, gleiche Formel wie am Ende) → Ampelfarbe im
|
||||
// Lehrer-Live (Tag-Ansicht färbt laufende Balken danach ein).
|
||||
score: _liveKlimaScore(),
|
||||
};
|
||||
};
|
||||
// Live-Score aus dem aktuellen Stand — nur während des Spiels sinnvoll.
|
||||
function _liveKlimaScore() {
|
||||
if (!state || !state.diff) return null;
|
||||
if (state.phase !== 'playing' && state.phase !== 'citizen' && state.phase !== 'end') return null;
|
||||
var sp = state.diff.startPopulation || 6000;
|
||||
var tempScore = Math.max(0, Math.min(35, 35 - ((state.currentTemp||0) - 15.5) * 20));
|
||||
var floodScore = Math.max(0, 25 - (state.floodedPct||0) * 0.8);
|
||||
var budgetScore = Math.max(0, Math.min(20, (state.budget||0) / 10));
|
||||
var popScore = Math.max(0, Math.min(20, ((state.population||0) / sp) * 20));
|
||||
return Math.round(tempScore + floodScore + budgetScore + popScore);
|
||||
}
|
||||
Object.assign(state, {
|
||||
phase: 'level-select',
|
||||
speed: 1, lastTickMs: 0,
|
||||
|
||||
@@ -1570,8 +1570,22 @@ window.GGS_LIVE_STATE = function () {
|
||||
hasShield: !!state.hasMountainShield,
|
||||
hasBeach: !!state.hasSandBeach,
|
||||
placing: typeof placementId !== 'undefined' && placementId !== null ? placementId : null,
|
||||
// Laufender Punktestand (0–100, gleiche Formel wie am Ende) → Ampelfarbe im
|
||||
// Lehrer-Live (Tag-Ansicht färbt laufende Balken danach ein).
|
||||
score: _liveKlimaScore(),
|
||||
};
|
||||
};
|
||||
// Live-Score aus dem aktuellen Stand — nur während des Spiels sinnvoll.
|
||||
function _liveKlimaScore() {
|
||||
if (!state || !state.diff) return null;
|
||||
if (state.phase !== 'playing' && state.phase !== 'citizen' && state.phase !== 'end') return null;
|
||||
var sp = state.diff.startPopulation || 6000;
|
||||
var tempScore = Math.max(0, Math.min(35, 35 - ((state.currentTemp||0) - 15.5) * 20));
|
||||
var floodScore = Math.max(0, 25 - (state.floodedPct||0) * 0.8);
|
||||
var budgetScore = Math.max(0, Math.min(20, (state.budget||0) / 10));
|
||||
var popScore = Math.max(0, Math.min(20, ((state.population||0) / sp) * 20));
|
||||
return Math.round(tempScore + floodScore + budgetScore + popScore);
|
||||
}
|
||||
|
||||
/* ============================================================
|
||||
UI HELPERS
|
||||
|
||||
+8
-6
@@ -1378,18 +1378,20 @@ async function _renderInactiveToday(activeSet) {
|
||||
if (!data || data.error || !Array.isArray(data.students)) return '';
|
||||
var groups = [];
|
||||
data.students.forEach(function(s){
|
||||
if (activeSet && activeSet[s.studentId]) return; // gerade online → oben
|
||||
var sess = (s.sessions||[]).filter(function(x){ return x.startMs; });
|
||||
if (!sess.length) return; // heute nichts gespielt
|
||||
if (sess.some(function(x){ return x.isLive || x.success==='running'; })) return; // läuft noch → oben
|
||||
// Alle HEUTE abgeschlossenen Durchgänge (das gerade laufende Spiel steht
|
||||
// oben in der Live-Liste und wird hier ausgelassen). Auch für Schüler:innen,
|
||||
// die gerade online sind — ihre schon fertigen Läufe sollen sichtbar bleiben.
|
||||
var sess = (s.sessions||[]).filter(function(x){ return x.startMs && !x.isLive && x.success!=='running'; });
|
||||
if (!sess.length) return; // heute nichts abgeschlossen
|
||||
sess.sort(function(a,b){ return (a.startMs||0)-(b.startMs||0); }); // chronologisch
|
||||
var lastEnd = 0; sess.forEach(function(x){ if((x.endMs||0)>lastEnd) lastEnd = x.endMs||0; });
|
||||
groups.push({ s:s, sess:sess, lastEnd:lastEnd });
|
||||
});
|
||||
if (!groups.length) return '';
|
||||
groups.sort(function(a,b){ return b.lastEnd - a.lastEnd; }); // zuletzt aktive Person oben
|
||||
var html = '<div class="card" style="margin-top:.8rem"><div class="card-h">Heute bereits aktiv · '+groups.length+'</div>';
|
||||
html += '<p style="font-size:.7rem;color:#8a8a8a;margin-bottom:.5rem">Heute schon gearbeitet, gerade aber offline — alle Aktivitäten mit Uhrzeit und Leistung.</p>';
|
||||
var totalRuns = groups.reduce(function(n,g){ return n + g.sess.length; }, 0);
|
||||
var html = '<div class="card" style="margin-top:.8rem"><div class="card-h">Heute bereits erledigt · '+groups.length+' Schüler*innen · '+totalRuns+' Durchgänge</div>';
|
||||
html += '<p style="font-size:.7rem;color:#8a8a8a;margin-bottom:.5rem">Alle heute abgeschlossenen Durchgänge (Weltküche, Klima, Farmer …) mit Uhrzeit und Leistung. Gerade laufende Spiele stehen oben.</p>';
|
||||
html += '<div style="overflow-x:auto"><table style="width:100%;border-collapse:collapse;font-size:.74rem">';
|
||||
html += '<thead><tr style="background:#f7f6f3;border-bottom:2px solid rgba(0,0,0,.08)">'
|
||||
+ '<th style="text-align:left;padding:.4rem .5rem;white-space:nowrap">Schüler*in</th>'
|
||||
|
||||
Reference in New Issue
Block a user