# NPCs Nicht-Spieler-Figuren — optionaler Bonusteil laut Aufgabenstellung. Hier mit Talk- und Give-Interaktion modelliert. ## Domain-Modell ```mermaid classDiagram class Npc { -String id -String name -String description -String greeting -Map~String, NpcReaction~ reactions +talk(GameContext) void +receive(Item, GameContext) boolean } class NpcReaction { -Item consumes -Item gives -String response +apply(Player) void } Npc "1" --> "*" NpcReaction : reactions ``` - `reactions` ist `HashMap` mit dem Trigger-Item-id als Key. O(1) Nachschlagen beim `gib X an Y`. ## Interaktionen ### `talk ` - Sucht NPC im aktuellen Raum. - Wirft `greeting`-Text aus. - Mutiert nichts. ### `gib an ` ```mermaid sequenceDiagram actor Spieler participant Cmd as GiveCommand participant P as Player participant N as Npc participant IO Spieler->>Cmd: give lamp old_man Cmd->>P: hasItem("lamp")? P-->>Cmd: yes Cmd->>N: receive(lamp) N->>N: reactions.get("lamp") alt Reaktion existiert N->>P: inventory.remove(lamp) N->>P: inventory.add(key) N-->>Cmd: response text Cmd->>IO: write(response) else keine Reaktion N-->>Cmd: false Cmd->>IO: write("The NPC does not react.") end ``` ## YAML-Beispiel ```yaml - id: old_man name: Old Man description: A stooped old man with a grey beard. greeting: | "Hello traveller. If you bring me the lamp, I will show you the way to the cellar." reactions: - onReceive: lamp response: | "Thank you! Here, take this key." gives: key consumes: lamp ``` Felder einer Reaktion: | Feld | Pflicht | Bedeutung | |---|---|---| | `onReceive` | ja | Item-id, das ausgelöst werden muss | | `response` | ja | Antworttext nach erfolgreicher Übergabe | | `gives` | nein | Item-id, das der NPC zurückgibt | | `consumes` | nein | Item-id, das aus Spielerinventar entfernt wird (oft = `onReceive`) | ## Speichern in Räumen Räume halten ihre NPCs analog zu Items: ```java private final LinkedHashMap npcs = new LinkedHashMap<>(); ``` - `LinkedHashMap` weil O(1)-Lookup beim `talk ` *und* stabile Reihenfolge in der Raumbeschreibung („Here is: Old Man, Innkeeper"). ## Erweiterungen (bewusst nicht im MVP) - Bedingte Dialoge („wenn Quest X erledigt, sag Y") - Kauf/Verkauf mit Gold - NPC bewegt sich zwischen Räumen - Mehrfache Reaktionsketten (NPC-Memory) Diese würden ein eigenes Quest-/Event-System rechtfertigen. Für 3 Bonuspunkte überdimensioniert. ## Validierungsregeln Wiederholung aus [yaml-schemas.md](yaml-schemas.md), hier explizit pro NPC: 1. `id` eindeutig in `npcs.yaml` 2. `greeting` nicht leer (sonst sinnloses NPC) 3. Jede `onReceive`-id existiert in `items.yaml` 4. Jede `gives`-id existiert in `items.yaml` 5. Jede `consumes`-id existiert in `items.yaml` 6. Innerhalb eines NPCs ist `onReceive` eindeutig (keine zwei Reaktionen auf dasselbe Item)