feat(quests): Quests als Trigger mit Zaehler

Eine Quest IST ein Trigger mit count = N — kein zweiter Mechanismus.
Gezaehlt wird erst ab start_quest, erledigte bleiben mit done = true
stehen, und die Belohnung darf die naechste starten: das ist die Kette.

- fuenfzehnte Registry, Trigger per serde(flatten) eingebettet
- give_item als Aktion, damit eine Belohnung mehr als Erfahrung zahlt
- QuestLog auf q, Fortschritt im Speicherstand, unbekannte IDs verworfen
- eine Funktion entscheidet fuer alle Traeger, wann ein Trigger feuert

Befund: Die Ordnungszahlen im Aktionskatalog widersprechen sich — vier
Tickets zaehlten je vom eigenen Stand. Sie sind raus, CONTEXT.md fuehrt
die Liste.
This commit is contained in:
2026-08-13 07:43:46 +02:00
parent 090d9ae136
commit 37b5820c5b
12 changed files with 376 additions and 22 deletions

View File

@@ -272,3 +272,25 @@ Dazu `Game.events: Vec<Event>` als neues Feld im Baum.
nicht den einzelnen Raum.
- **13 Script-Engine wählen**: `emit_event` als Aktion und namespaced Events, sobald Stufe (c) steht.
- **14 Kampfformeln und Rundenablauf**: wo genau `attack_hit` und `damage_taken` im Zug feuern.
### Befunde aus M7
**„Eine Quest ist ein Trigger" hält — und zwar bis in den Code.** `Quest` trägt den `Trigger` per
`#[serde(flatten)]`, `on`/`when`/`condition`/`actions`/`chance` stehen also flach in derselben
TOML-Tabelle. Dieselbe Frage „feuert dieser Trigger auf dieses Ereignis?" beantwortet eine einzige
Funktion für Gegenstand, Modifikator, Gegner *und* Quest. Beim ersten Bauen stand die Prüfung zweimal
da; das war der Moment, in dem die Behauptung des Tickets fast nur eine Formulierung geblieben wäre.
**Der feste Träger ist der Grund, warum Quests neben der Trägerschleife stehen.** Das Ticket sagt
„für eine Quest ist der Träger der Held". Im Code heißt das: Der Questlauf gehört *neben* die Schleife
über die Beteiligten, nicht hinein — sonst würde jede Quest einmal pro Gegner gezählt.
**Die Kette braucht keinen Sonderfall.** Eine Belohnung, die `start_quest` ausführt, verlängert
`Game.quests` mitten im Zählen. Weil die Schleife über den Index läuft und ihre Länge vorher feststeht,
wird der neue Eintrag erst beim nächsten Ereignis gezählt — genau richtig, er war beim Auslöser noch
nicht da. Kein Zwischenpuffer nötig, nur die Reihenfolge richtig herum.
**Die Ordnungszahlen im Aktionskatalog widersprechen sich.** Ticket 08 nennt `start_quest` die
„siebte", Ticket 14 `flee` die „achte", M4 `open_shop` die „elfte" — jedes Ticket zählte von seinem
eigenen Stand aus, und keine der Zahlen stimmt mit den heute neun gebauten Varianten überein. Die
Ordnungszahlen sind aus dem Code raus; `CONTEXT.md` führt die Liste, und die ist zählbar.