Finale: Polizei-Kontrolle vor Tresor; Fuehrerschein erst per Drag&Drop vorzeigen, dann misstrauische Ansage, dann Theoriepruefung

This commit is contained in:
David Kertzscher 2026-07-15 15:10:07 +00:00
parent a36c83c8f4
commit 32fd9a0cbb

74
app.py
View file

@ -933,18 +933,61 @@ def _blaulicht_intro():
<span class="polizei-badge">🚔 POLIZEI · VERKEHRSKONTROLLE</span> <span class="polizei-badge">🚔 POLIZEI · VERKEHRSKONTROLLE</span>
<h1>Anhalten Fahrzeugkontrolle!</h1> <h1>Anhalten Fahrzeugkontrolle!</h1>
<p class="adv-desc">Kurz vor dem Kragle-Tresor stoppt dich eine Streife. <p class="adv-desc">Kurz vor dem Kragle-Tresor stoppt dich eine Streife.
Die Beamten mustern deinen Führerschein misstrauisch: Ein Beamter tritt ans Fenster: <em>Guten Tag. Fahrzeugkontrolle
Ihren Führerschein bitte!</em></p>
<div class="dropzone" data-accept="fuehrerschein" data-go="/app/raum/40?fs=gezeigt">
<span class="dz-ico">🪪</span>
Zieh deinen <strong>Führerschein</strong> aus dem Inventar (links) hierher,
um ihn den Beamten vorzuzeigen.
</div>
</div>"""
return adventure_seite(inhalt, akzent="#1e50ff")
def _fs_ansage():
"""Nach dem Vorzeigen des Führerscheins: misstrauische Ansage der Beamten."""
inhalt = """
<style>
.blitz-overlay {
position:fixed; inset:0; z-index:5; pointer-events:none;
animation:blaulicht 0.9s steps(1,end) infinite;
}
@keyframes blaulicht {
0% { background:rgba(10,40,255,0.00); box-shadow:none; }
10% { background:rgba(30,90,255,0.55); box-shadow:inset 0 0 240px 80px #1e50ff; }
20% { background:rgba(10,40,255,0.00); box-shadow:none; }
50% { background:rgba(10,40,255,0.00); box-shadow:none; }
60% { background:rgba(30,90,255,0.55); box-shadow:inset 0 0 240px 80px #1e50ff; }
70% { background:rgba(10,40,255,0.00); box-shadow:none; }
100% { background:rgba(10,40,255,0.00); box-shadow:none; }
}
.polizei-card { position:relative; z-index:6; text-align:center;
border:2px solid #1e50ff !important;
box-shadow:0 0 40px rgba(30,80,255,0.6) !important; }
.polizei-siren { font-size:60px; margin-bottom:6px;
animation:sirene 0.9s ease-in-out infinite; }
@keyframes sirene {
0%,100% { filter:drop-shadow(0 0 4px #1e50ff); transform:scale(1); }
50% { filter:drop-shadow(0 0 22px #1e50ff); transform:scale(1.12); }
}
.polizei-badge { display:inline-block; background:#0b2a8a; color:#dbe5ff;
border:1px solid #1e50ff; border-radius:8px;
padding:6px 14px; font-weight:800; letter-spacing:2px;
margin-bottom:14px; }
</style>
<div class="blitz-overlay"></div>
<div class="adv-card polizei-card">
<div class="polizei-siren">🚨</div>
<span class="polizei-badge">🚔 POLIZEI · FÜHRERSCHEIN-PRÜFUNG</span>
<h1>Der ist doch nie echt!</h1>
<p class="adv-desc">Die Beamten mustern deinen Führerschein misstrauisch:
<em>Diesen Lappen haben Sie doch nie im Leben ehrlich bestanden! <em>Diesen Lappen haben Sie doch nie im Leben ehrlich bestanden!
Wenn er echt ist, beweisen Sie es: Lösen Sie diese drei Aufgaben Wenn er echt ist, beweisen Sie es: Lösen Sie diese drei Aufgaben
aus der Theorieprüfung dann dürfen Sie weiter.</em></p> aus der Theorieprüfung dann dürfen Sie weiter.</em></p>
<p class="adv-desc">🚦 <strong>Achtung:</strong> Bei manchen Fragen ist <p class="adv-desc">🚦 <strong>Achtung:</strong> Bei manchen Fragen ist
<strong>mehr als eine Antwort</strong> richtig. Kreuze <strong>alle</strong> <strong>mehr als eine Antwort</strong> richtig. Kreuze <strong>alle</strong>
zutreffenden an ein falsches Kreuz und du fällst durch.</p> zutreffenden an ein falsches Kreuz und du fällst durch.</p>
<div class="dropzone" data-accept="fuehrerschein" data-go="/app/raum/40?fs=1"> <a href="/app/raum/40?fs=1" class="exit-link">Theorieprüfung starten </a>
<span class="dz-ico">🪪</span>
Zieh deinen <strong>Führerschein</strong> aus dem Inventar (links) hierher,
um ihn den Beamten vorzuzeigen.
</div>
</div>""" </div>"""
return adventure_seite(inhalt, akzent="#1e50ff") return adventure_seite(inhalt, akzent="#1e50ff")
@ -1038,13 +1081,15 @@ def _fs_frage_screen(idx, feedback=""):
def fuehrerschein_kontrolle(): def fuehrerschein_kontrolle():
"""Steuert die dreiteilige Polizei-Führerschein-Kontrolle vor dem Finale.""" """Steuert die dreiteilige Polizei-Führerschein-Kontrolle vor dem Finale."""
# Noch nicht gestartet → Blaulicht-Intro (oder Start per ?fs=1) # Ablauf: Blaulicht + Führerschein droppen → misstrauische Ansage → 3 Fragen
if FS_IDX_KEY not in session: if FS_IDX_KEY not in session:
if request.args.get("fs") == "1": if request.args.get("fs") == "1":
session[FS_IDX_KEY] = 0 session[FS_IDX_KEY] = 0
session.modified = True session.modified = True
return redirect("/app/raum/40") return redirect("/app/raum/40")
return _blaulicht_intro() if request.args.get("fs") == "gezeigt":
return _fs_ansage() # Führerschein vorgezeigt → Ansage
return _blaulicht_intro() # Kontrolle: Führerschein hierher ziehen
idx = session.get(FS_IDX_KEY, 0) idx = session.get(FS_IDX_KEY, 0)
feedback = "" feedback = ""
@ -1107,9 +1152,14 @@ def raum(id):
# ═══ Räume mit Fragen: thema (Prüf-Weg) · ziel (Finale) ═══ # ═══ Räume mit Fragen: thema (Prüf-Weg) · ziel (Finale) ═══
if typ in ("thema", "ziel"): if typ in ("thema", "ziel"):
# ── Finale (Raum 40): Tresor-Schloss → Polizei-Kontrolle → Frage ── # ── Finale (Raum 40): erst Polizei-Kontrolle, dann Tresor-Schloss ──
if typ == "ziel" and id == 40: if typ == "ziel" and id == 40:
# Zugangsschlüssel einsetzen (per Drag&Drop ausgelöst) # 1) Polizei-Führerschein-Kontrolle zuerst
if not session.get(FS_DONE_KEY):
_stage_start(40) # Polizei-Kontrolle Zeitmessung
db.close()
return fuehrerschein_kontrolle()
# 2) Danach: Zugangsschlüssel in den Kragle-Tresor (per Drag&Drop)
if request.args.get("unlock") == "1" and not session.get("vault_unlocked"): if request.args.get("unlock") == "1" and not session.get("vault_unlocked"):
used = next((k for k in ACCESS_KEYS if _inv_has(k)), None) used = next((k for k in ACCESS_KEYS if _inv_has(k)), None)
if used: if used:
@ -1121,10 +1171,6 @@ def raum(id):
if not session.get("vault_unlocked"): if not session.get("vault_unlocked"):
db.close() db.close()
return _tresor_schloss() return _tresor_schloss()
if not session.get(FS_DONE_KEY):
_stage_start(40) # Polizei-Kontrolle Zeitmessung
db.close()
return fuehrerschein_kontrolle()
# ── Prüf-Weg-Räume: Zeitmessung dieses Abschnitts startet ── # ── Prüf-Weg-Räume: Zeitmessung dieses Abschnitts startet ──
if typ == "thema": if typ == "thema":
_stage_start(id) _stage_start(id)