Code-Frameworks
Listen mit Inhalten
Lass einen Charakter im Spiel Inhalte erhalten: deklariere eine Liste, ändere sie mit Aktionen und zeige sie auf dem Bogen.
Was eine Liste ist
Eine Liste hält Inhalte, die ein Charakter im Spiel erhält, zum Beispiel ein Pack Trinkets. Der Inhalt ist ein anderes Framework, und seine Presets sind die Einträge. Eine Liste lebt im Ledger und ist kein Konstruktorfeld. Nur Aktionen ändern sie.
| Option | Bedeutung |
|---|---|
| label | Der Name der Liste. |
| of | Die id des Inhalts-Frameworks. |
| max | Wie viele Einträge die Liste hält, von 1 bis 128. |
| card | Der Frame, der einen Eintrag als Karte zeichnet. Er muss ein Frame des Inhalts-Frameworks sein. |
| summary | Bis zu 4 Felder des Eintrags, die in seiner Zeile erscheinen. |
| effects, caps, distinctBy | Einträge, die Modifikatoren ändern, und Limits dafür. Siehe Pools und Modifikatoren. |
Zeilenlisten, die jeder Zeile Zellen hinzufügen, gibt es. Sie sind noch nicht beschrieben.
Eine Liste deklarieren
Füge die Liste dem Framework hinzu, dem sie gehört. Das Inhalts-Framework hält die Einträge als Presets. Die Anleitung Grow Lantern baut das Trinket-Framework Schritt für Schritt.
"lists": {
"pack": {
"label": "Pack",
"of": "trinket",
"max": 2,
"card": "trinket-card",
"summary": ["weight"]
}
}- Zeile 45 Das Inhalts-Framework, dessen Presets die Einträge sind.
- Zeile 46 Die Liste hält höchstens so viele Einträge.
- Zeile 47 Der Frame, der einen Eintrag zeichnet.
- Zeile 48 Felder, die in der Zeile eines Eintrags erscheinen. Ein summary-Feld braucht einen geschlossenen Wertebereich: Optionen, ein Minimum und Maximum oder wahr und falsch.
Hinzufügen und entfernen
Eine Liste ändert sich nur durch Aktionen. Nimm den Eintrag als ContentRef-Eingabe und rufe list.add mit einem Angebot auf.
export function pack_trinket(self: ElementRef, trinket: ContentRef): void {
list.add(self, "pack", trinket, offer.where({ weight: { lte: 3 } }));
}- Zeile 1 Der Eintrag, den der Spieler wählt.
- Zeile 2 list.add prüft zuerst das Angebot. Dieses Angebot erlaubt Einträge, die höchstens 3 wiegen.
Entferne einen Eintrag mit list.remove.
export function unpack_trinket(self: ElementRef, trinket: ContentRef): void {
list.remove(self, "pack", trinket);
}- Zeile 2 Entfernt den gewählten Eintrag. Die Aktion wird abgelehnt, wenn die Liste ihn nicht hält.
Wenn ein Spieler die Schaltfläche nutzt, bittet Fabled ihn, einen der Einträge zu wählen, die das Angebot erlaubt. Nutze list.count, um ein Hinzufügen durch eine eigene Regel zu stoppen, wie die Seite Regeln schreiben zeigt.
Angebote
offer.where nimmt Bedingungen für die Felder des Eintrags. Du schreibst die Bedingungen als Literale, also kann ein Angebot den Charakter nicht lesen. Wenn es vom Charakter abhängen soll, prüfe ihn mit if vor list.add.
| Operator | Bedeutung | Beispiel |
|---|---|---|
| eq | Das Feld ist gleich dem Wert. | {"slot":{"eq":"Ring"}} |
| ne | Das Feld ist ungleich dem Wert. | {"slot":{"ne":"Ring"}} |
| gte | Die Zahl ist mindestens so groß wie der Wert. | {"weight":{"gte":2}} |
| lte | Die Zahl ist höchstens so groß wie der Wert. | {"weight":{"lte":3}} |
| in | Das Feld ist gleich einem der Werte. Bis zu 64 Werte. | {"slot":{"in":["Ring","Cloak"]}} |
| has | Das Feld ist ein Text mit Kommas, der einen der Werte enthält. | {"tags":{"has":["fire"]}} |
Jede Bedingung eines Angebots muss zutreffen, und ein Angebot nennt höchstens 6 Felder. Ein Feld, das der Eintrag nicht hat, passt nie.
Auf dem Bogen anzeigen
Ein Frame, der eine Liste zeigt, nutzt Version 2.0. Deklariere einen Bereich im dataContract und zeichne ihn dann. Ein Bereich kann jedem Eintrag auch bis zu 4 Schaltflächen geben, die je eine Aktion für diesen Eintrag ausführen.
{
"kind": "region",
"id": "pack_list",
"listBinding": "{{element.lists.pack}}",
"emptyText": "Your pack is empty.",
"itemActions": [{ "actionRef": "unpack_trinket", "label": "Unpack" }]
}- Zeile 46 Erscheint, solange die Liste leer ist.
- Zeile 47 Eine Schaltfläche an jedem Eintrag. Die Aktion darf nur den Eintrag als Eingabe haben.
Testen
Teste jede Ablehnung, die das Angebot und die Größe geben können. Die Schritte unten fügen hinzu, lehnen auf drei Arten ab, entfernen und lehnen ein Entfernen ab.
{
"id": "pack-trinkets",
"framework": "keeper",
"parameters": {
"name": "Mira",
"max_hp": 10,
"calling": "Guard",
"lamp": "lamp"
},
"expectedValues": {
"name": "Mira",
"max_hp": 10,
"hp": 10,
"calling": "Guard",
"guard": 3
},
"expectedChildren": { "lamp": { "name": "Lantern", "oil": 5 } },
"actions": [
{
"action": "pack_trinket",
"parameters": {},
"choose": { "trinket": "rope" },
"expectedWrites": [{ "op": "list.add", "key": "pack", "value": "rope" }]
},
{
"action": "pack_trinket",
"parameters": {},
"choose": { "trinket": "rope" },
"expectedRefusal": "ALREADY_IN_LIST",
"expectedWrites": []
},
{
"action": "pack_trinket",
"parameters": {},
"choose": { "trinket": "anvil" },
"expectedRefusal": "NOT_OFFERED",
"expectedWrites": []
},
{
"action": "pack_trinket",
"parameters": {},
"choose": { "trinket": "candle" },
"expectedWrites": [
{ "op": "list.add", "key": "pack", "value": "candle" }
]
},
{
"action": "pack_trinket",
"parameters": {},
"choose": { "trinket": "bell" },
"expectedRefusal": "LIST_FULL",
"expectedWrites": []
},
{
"action": "unpack_trinket",
"parameters": {},
"choose": { "trinket": "rope" },
"expectedWrites": [
{ "op": "list.remove", "key": "pack", "value": "rope" }
]
},
{
"action": "unpack_trinket",
"parameters": {},
"choose": { "trinket": "rope" },
"expectedRefusal": "NOT_IN_LIST",
"expectedWrites": []
}
],
"expectedLists": { "pack": ["candle"] }
}- Zeilen 19-24 Angenommen: Das Seil wird hinzugefügt.
- Zeilen 25-31 Abgelehnt: Das Pack hält das Seil schon.
- Zeilen 32-38 Abgelehnt: Das Angebot erlaubt den Amboss nicht.
- Zeilen 47-53 Abgelehnt: Das Pack hält 2 Einträge, das ist sein Maximum.
- Zeilen 54-61 Entfernt: Das Seil verlässt das Pack.
- Zeilen 62-68 Abgelehnt: Das Seil ist nicht mehr im Pack.
- Zeile 70 Am Ende hält das Pack nur die Kerze.
Ein Szenario kann auch mit einer Liste starten, die schon Einträge hält. Nenne sie in lists, mit der Preset-id, und prüfe sie mit expectedLists.
{
"id": "seeded-pack",
"framework": "keeper",
"parameters": {
"name": "Mira",
"max_hp": 10,
"calling": "Guard",
"lamp": "lamp"
},
"expectedValues": {
"name": "Mira",
"max_hp": 10,
"hp": 10,
"calling": "Guard",
"guard": 3
},
"expectedChildren": { "lamp": { "name": "Lantern", "oil": 5 } },
"lists": { "pack": ["rope"] },
"expectedLists": { "pack": ["rope"] }
}- Zeile 18 Die Liste, mit der das Element startet.
- Zeile 19 Die Liste nach dem Szenario.
SAME_NAME und LIST_CAP kommen von den Limits einer Liste, die Effekte anwendet. Die Seite Pools und Modifikatoren beweist sie.

