Atlas: Logistik-Gerüst + Heli-Fix + Waypoints-Regen + Level-Picker

- Neues Modul 'Logistik Europa': module_info-Eintrag, Landing-Card,
  PHP-Wrapper (logistik.php, modul-logistik.php), Engine-Skelett mit
  Enums + Helpern (travelCost, latePenalty, Bonus, Dijkstra,
  Polyline-Interpolation), Test-Harness, Kompetenzen-Draft,
  5 Seed-Dateien (locations, vehicle-types, cargo-types, railnet,
  contract-templates), 3 Level-Einträge in game_levels, Phase 0 durch
  die Logistik-Instanz geliefert und Atlas-Review bestanden
- Heli-Fix: heli-game.php mit BASE_PATH (production-sicher) +
  Asset-Pfad-Injection, geo_waypoints-Tabelle per Seed-Script
  auffindbar gemacht
- Waypoints-Regen-Tool: regen-waypoints-sql.php synchronisiert
  waypoints.sql aus DB (70 Einträge)
- Design-System: .ggs-level-grid / .ggs-level-card als Standard
  gepromotet (Klimas Muster, iPad-hover-safe)
- Inbox-Nachrichten: Kickoff-Briefings für Heli und Logistik,
  Asset-Map für Heli, DALL-E-Pipeline-Anleitung, Koordinations-
  nachrichten an Fluss, Klima, Glossar, Lehrplan

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-04-19 20:43:48 +02:00
parent 3931a701e1
commit 3885c83294
54 changed files with 5717 additions and 71 deletions
+161
View File
@@ -0,0 +1,161 @@
<!DOCTYPE html>
<html lang="de">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Logistik Europa — Simulation</title>
<link rel="stylesheet" href="https://unpkg.com/leaflet@1.9.4/dist/leaflet.css">
<link rel="stylesheet" href="../../assets/fonts/inter.css">
<link rel="stylesheet" href="../../assets/css/design-system.css">
<style>
/* ===== Modul-spezifische Styles (minimal) =====
Regel: Alles, was auch andere Module brauchen könnten, gehört ins
Design-System (mit Atlas absprechen). Hier nur Logistik-Spezifisches. */
html, body { height: 100%; margin: 0; padding: 0; font-family: 'Inter', system-ui, sans-serif; background: var(--ggs-bg); color: var(--ggs-text); }
/* Layout-Raster: Header + Hauptbereich (3 Spalten) + Status-Leiste + Didaktik */
.lg-layout { display: grid; grid-template-rows: auto 1fr auto auto; height: 100vh; }
.lg-main { display: grid; grid-template-columns: 240px 1fr 240px; gap: 8px; padding: 8px; min-height: 0; }
.lg-panel { background: var(--ggs-white); border-radius: var(--ggs-radius-md); padding: 12px; overflow-y: auto; box-shadow: var(--ggs-shadow-sm); }
.lg-map { background: var(--ggs-white); border-radius: var(--ggs-radius-md); overflow: hidden; box-shadow: var(--ggs-shadow-sm); position: relative; }
#map { width: 100%; height: 100%; }
.lg-status { display: flex; gap: 12px; align-items: center; padding: 8px 16px; background: var(--ggs-white); border-top: 1px solid var(--ggs-border); font-size: 0.85rem; }
.lg-didaktik { max-height: 120px; overflow-y: auto; padding: 8px 16px; background: var(--ggs-bg); border-top: 1px solid var(--ggs-border); font-size: 0.82rem; }
/* iPad Landscape (1180×820) */
@media (min-width: 900px) and (max-width: 1199px) {
.lg-main { grid-template-columns: 215px 1fr 215px; }
}
/* Phone / schmale Tablets */
@media (max-width: 899px) {
.lg-main { grid-template-columns: 1fr; grid-template-rows: auto auto 300px; }
}
/* Platzhalter-Skelett — wird von Logistik-Instanz in Phase 1+ befüllt */
.lg-placeholder { padding: 40px 20px; text-align: center; color: var(--ggs-text-muted); }
.lg-placeholder h2 { font-size: 1.2rem; margin-bottom: 10px; color: var(--ggs-text); }
.lg-placeholder code { display: inline-block; padding: 2px 6px; background: var(--ggs-bg); border-radius: 4px; font-size: 0.8rem; }
</style>
</head>
<body>
<!-- Injection-Point für logistik.php-Wrapper (BASE_PATH, Seeds, Levels, Sim-Name) -->
<script>
/*__LOGISTIK_INJECTION__*/
// Fallback für direkten HTML-Aufruf (Dev-Modus ohne PHP-Wrapper)
if (!window.LOGISTIK_BASE) {
window.LOGISTIK_BASE = '';
window.LOGISTIK_SIM_NAME = 'Logistik Europa (Dev)';
window.LOGISTIK_SEEDS = { locations: [], vehicleTypes: [], cargoTypes: [], railnet: { nodes: [], edges: [] }, contractTemplates: [] };
window.LOGISTIK_LEVELS = [];
}
</script>
<div class="lg-layout">
<!-- ============= Header ============= -->
<header class="ggs-header">
<div class="ggs-header-left">
<img src="../../assets/img/bildLogo.png" alt="" class="ggs-logo-img">
<img src="../../assets/img/textlogo_geograsim.svg" alt="GeoGraSim" class="ggs-logo-text">
<span class="ggs-sim-badge" id="simName">Logistik Europa</span>
</div>
<div class="ggs-header-right">
<div class="ggs-speed-ctrl" id="speedCtrl">
<button class="ggs-btn-icon" data-speed="1">1×</button>
<button class="ggs-btn-icon" data-speed="2">2×</button>
<button class="ggs-btn-icon" data-speed="4">4×</button>
<button class="ggs-btn-icon" data-speed="8">8×</button>
</div>
<button class="ggs-btn-icon" title="Speichern" id="btnSave">💾</button>
<button class="ggs-btn-icon" title="Laden" id="btnLoad">📂</button>
<a class="ggs-btn-icon" title="Cockpit" href="../../sim">🏠</a>
</div>
</header>
<!-- ============= Hauptbereich ============= -->
<main class="lg-main">
<!-- Links: Aufträge -->
<aside class="lg-panel" id="contractsPanel">
<div class="lg-placeholder">
<h2>Aufträge</h2>
<p>Panel wird von Logistik-Instanz in Phase 2 befüllt.</p>
<p><code>#contractsPanel</code></p>
</div>
</aside>
<!-- Mitte: Karte -->
<section class="lg-map">
<div id="map"></div>
</section>
<!-- Rechts: Fahrzeuge -->
<aside class="lg-panel" id="vehiclesPanel">
<div class="lg-placeholder">
<h2>Fahrzeuge</h2>
<p>Panel wird von Logistik-Instanz in Phase 2/3 befüllt.</p>
<p><code>#vehiclesPanel</code></p>
</div>
</aside>
</main>
<!-- ============= Status-Leiste ============= -->
<div class="lg-status">
<span>Zeit: <b id="statusTime"></b></span>
<span>Konto: <b id="statusBalance"></b></span>
<span>Score: <b id="statusScore"></b></span>
<span style="flex: 1"></span>
<span id="statusState" class="ggs-badge">INIT</span>
</div>
<!-- ============= Didaktikfenster (einklappbar) ============= -->
<div class="lg-didaktik" id="didaktik">
<em>Willkommen in der Simulation „Logistik Europa". Diese Seite ist ein leeres Gerüst — die Logistik-Instanz baut hier die Kern-Simulation in mehreren Phasen.</em>
</div>
</div>
<!-- ============= Scripts ============= -->
<script src="https://unpkg.com/leaflet@1.9.4/dist/leaflet.js"></script>
<script src="engine.js"></script>
<script>
// === Gerüst-Initialisierung — Logistik-Instanz erweitert in Phase 1+ ===
document.getElementById('simName').textContent = window.LOGISTIK_SIM_NAME || 'Logistik Europa';
// Leaflet-Karte mit Carto Positron (heller, didaktisch ruhiger)
const map = L.map('map', {
center: [50.5, 10.5], // Zentral-Europa
zoom: 4,
minZoom: 4,
maxZoom: 10,
zoomControl: true,
});
L.tileLayer('https://{s}.basemaps.cartocdn.com/light_all/{z}/{x}/{y}{r}.png', {
attribution: '© OpenStreetMap contributors, © CARTO',
subdomains: 'abcd',
maxZoom: 19,
}).addTo(map);
// Skelett: Engine-Game erzeugen (Level 1 per Default)
const game = LogistikEngine.createGame(1);
document.getElementById('statusState').textContent = game.state;
document.getElementById('statusBalance').textContent = game.balance.toLocaleString('de-DE') + ' €';
document.getElementById('statusScore').textContent = game.score;
document.getElementById('statusTime').textContent = new Date(game.simulationTime).toLocaleString('de-DE');
// === TODO Logistik-Instanz — Phase 1+ ===
// - Seed-Daten auf Karte darstellen (Marker pro Location)
// - Contracts-Panel befüllen
// - Vehicle-Panel befüllen
// - Tick-Loop starten
// - Speed-Buttons verdrahten
// - Save/Load an API binden (App/php/api/logistik-*.php)
console.info('[Logistik-Gerüst] Engine bereit, ' + (window.LOGISTIK_SEEDS.locations.length || 0) + ' Locations geladen.');
</script>
</body>
</html>