Фреймворки на коде
Списки контента
Дайте персонажу получать контент в игре: объявите список, меняйте его действиями и покажите его на листе.
Что такое список
Список хранит контент, который персонаж получает в игре, например рюкзак с безделушками. Контент это другой Framework, а его пресеты это записи. Список живёт в журнале и не является полем конструктора. Менять его могут только действия.
| Параметр | Значение |
|---|---|
| label | Название списка. |
| of | Id Framework с контентом. |
| max | Сколько записей хранит список, от 1 до 128. |
| card | Frame, который рисует запись как карточку. Это должен быть Frame Framework с контентом. |
| summary | До 4 полей записи для показа в её строке. |
| effects, caps, distinctBy | Записи, которые меняют модификаторы, и их ограничения. См. «Пулы и модификаторы». |
Списки со строками, которые добавляют ячейки к каждой строке, существуют, но пока не описаны.
Объявите список
Добавьте список в Framework, который им владеет. Framework с контентом хранит записи как пресеты. Руководство «Вырастим Lantern» строит Framework Trinket шаг за шагом.
"lists": {
"pack": {
"label": "Pack",
"of": "trinket",
"max": 2,
"card": "trinket-card",
"summary": ["weight"]
}
}- Строка 45 Framework с контентом, чьи пресеты и есть записи.
- Строка 46 Список хранит не больше стольких записей.
- Строка 47 Frame, который рисует запись.
- Строка 48 Поля для показа в строке записи. Полю summary нужен замкнутый набор значений: варианты, минимум и максимум или да и нет.
Добавление и удаление
Список меняется только действиями. Возьмите запись как вход ContentRef и вызовите list.add с предложением.
export function pack_trinket(self: ElementRef, trinket: ContentRef): void {
list.add(self, "pack", trinket, offer.where({ weight: { lte: 3 } }));
}- Строка 1 Запись, которую выбирает игрок.
- Строка 2 list.add сначала проверяет предложение. Это предложение допускает записи с весом 3 или меньше.
Удалите запись с помощью list.remove.
export function unpack_trinket(self: ElementRef, trinket: ContentRef): void {
list.remove(self, "pack", trinket);
}- Строка 2 Удаляет выбранную запись. Если её нет в списке, действие отклоняется.
Когда игрок нажимает кнопку, Fabled просит выбрать одну из записей, которые допускает предложение. Используйте list.count, чтобы остановить добавление по своему правилу, как показано на странице «Написание правил».
Предложения
offer.where принимает условия для полей записи. Условия пишутся как литералы, поэтому предложение не может читать персонажа. Чтобы зависеть от персонажа, проверьте его через if перед list.add.
| Оператор | Значение | Пример |
|---|---|---|
| eq | Поле равно значению. | {"slot":{"eq":"Ring"}} |
| ne | Поле не равно значению. | {"slot":{"ne":"Ring"}} |
| gte | Число не меньше значения. | {"weight":{"gte":2}} |
| lte | Число не больше значения. | {"weight":{"lte":3}} |
| in | Поле равно одному из значений. До 64 значений. | {"slot":{"in":["Ring","Cloak"]}} |
| has | Поле это текст через запятую, в котором есть одно из значений. | {"tags":{"has":["fire"]}} |
Должны выполняться все условия предложения, а предложение называет не больше 6 полей. Поле, которого нет у записи, никогда не совпадает.
Покажите список на листе
Frame, который показывает список, использует версию 2.0. Объявите область в dataContract, затем нарисуйте её. Область может также дать каждой записи до 4 кнопок, и каждая запускает действие для этой записи.
{
"kind": "region",
"id": "pack_list",
"listBinding": "{{element.lists.pack}}",
"emptyText": "Your pack is empty.",
"itemActions": [{ "actionRef": "unpack_trinket", "label": "Unpack" }]
}- Строка 46 Показывается, пока список пуст.
- Строка 47 Кнопка на каждой записи. Действие должно принимать только запись.
Проверьте список
Проверьте каждый отказ, который могут дать предложение и размер. Шаги ниже добавляют запись, отклоняют тремя способами, удаляют и отклоняют удаление.
{
"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"] }
}- Строки 19-24 Принято: верёвка добавлена.
- Строки 25-31 Отказ: рюкзак уже содержит верёвку.
- Строки 32-38 Отказ: предложение не допускает наковальню.
- Строки 47-53 Отказ: в рюкзаке 2 записи, это его максимум.
- Строки 54-61 Удалено: верёвка уходит из рюкзака.
- Строки 62-68 Отказ: верёвки больше нет в рюкзаке.
- Строка 70 В конце в рюкзаке остаётся только свеча.
Сценарий может начинаться и со списка, в котором уже есть записи. Назовите их в lists по id пресета и проверьте через 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"] }
}- Строка 18 Список, с которым Element начинает.
- Строка 19 Список после сценария.
SAME_NAME и LIST_CAP приходят из ограничений списка, который применяет эффекты. Страница «Пулы и модификаторы» их проверяет.

