Как использовать счётчики
Счётчики позволяют сохранять во время рассказа истории числа, а затем использовать их как условия отображения поинтов и кнопок.
Например, можно вести подсчёт каких-то событий в истории и в конце выводить разные вердикты в зависимости от их количества. Счётчики можно сравнивать друг с другом — чтобы определить, например, каких действий человек сделал больше: добрых или злых.
Принцип работы счётчиков похож на принцип работы артефактов.
Счётчики не могут быть глобальными
После прохождения истории все значения сбрасываются.
Выдача и обновление счётчика
Как и артефакт, счётчик выдаётся читателю в блоке reward. Это делается с помощью элемента counter:
<point>
<text>
<string>В этом поинте мы добавляем читателю счётчик и записываем в него число 5.</string>
</text>
<reward>
<counter id="points" operation="put" value="5"/>
</reward>
</point>
Элемент counter содержит три обязательных атрибута:
|
Атрибут |
Тип данных |
Смысл |
|
id |
Строка |
Идентификатор нужен для последующих изменений значений счётчика и для использования в условиях |
|
operation |
|
|
|
value |
Целое число |
Значение, которое нужно поместить в счётчик, прибавить к нему или отнять. |
Значение выданного читателю счётчика можно обновлять: прибавлять к нему числа и вычитать их из него, например:
<point>
<text>
<string>В этом поинте мы увеличиваем значение счётчика на 3, чтобы получилось 8.</string>
</text>
<reward>
<counter id="points" operation="increment" value="3"/>
</reward>
</point>
<point>
<text>
<string>А теперь вычитаем 2, чтобы получилось 6.</string>
</text>
<reward>
<counter id="points" operation="decrement" value="2"/>
</reward>
</point>
<point>
<text>
<string>А здесь читатель потерял все очки, сколько бы их ни было.</string>
</text>
<reward>
<counter id="points" operation="put" value="0"/>
</reward>
</point>
Что происходит, если применить increment и decrement к счётчику, которого ещё нет
Это не очень значительная тонкость
На неё можно поначалу не обращать внимания.
Будет создан счётчик со значением 0, а затем к нему прибавлено или от него отнято соответствующее число.
То есть increment на несуществующем счётчике даёт то же, что и put, а decrement — собственный value с обратным знаком. Такое поведение полезно для запихивания всей логики подсчёта очков в один поинт — как демо-истории.
Использование счётчиков в условиях показа
Смысл любого счётчика в том, что он используется в условиях показа поинтов и кнопок. Например, если набрано меньше пяти очков, выводится одно сообщение, а от пяти и выше — другое.
Принцип проверки похож на тот, что используется для артефактов, но механика более сложная: если артефакт может либо существовать, либо не существовать, то значение счётчика нужно сравнивать с каким-то другим числом.
Такое сравнение производят элементы, называемые компараторами. Каждый компанатор содержит в себе неравенство и отвечает «да», если оно верное и «нет», если оно неверное.
Устройство компараторов
Компараторы бывают двух видов: numerical-comparator сравнивает значение счётчика с числом, а counter-comparator — со значением другого счётчика.
<!-- Этот компаратор проверяет, набраны ли пять очков: -->
<numerical-comparator counter-id="points" comparison="greater-or-equal" value="5">
<!-- Этот компаратор проверяет, было ли белых шаров больше, чем чёрных: -->
<counter-comparator counter-id="white-balls" comparison="greater" value-from="black-balls">
|
Атрибут |
Тип данных |
Смысл |
|
counter-id |
Строка |
Идентификатор счётчика, значение которого мы собираемся сравнивать. |
|
comparison |
|
Какое условие должно быть выполнено:
|
|
value |
Целое число |
Число, с которым нужно сравнить значение счётчика. |
|
Атрибут |
Тип данных |
Смысл |
|
counter-id |
Строка |
Идентификатор счётчика (счётчик A), значение которого мы собираемся сравнивать. |
|
comparison |
|
Какое условие должно быть выполнено:
|
|
value-from |
Строка |
Идентификатор счётчика (счётчик Б), с которым мы сравниванием значение первого счётчика. |
Если сравнение невозможно, это считается за «нет»
Если компаратор не может выполнить своё сравнение (например, в нём указан несуществующий счётчик), он учитывается так же, как если бы сравнение было неверным.
Использование компараторов
Компараторы проверяются там же, где артефакты — в блоке prerequisites. Необходимые компараторы помещаются в блок needed-comparators, а запрещённые — в блок restricted-comparators.
Например:
<point>
<prerequisites>
<needed-comparators>
<numerical-comparator counter-id="points" comparison="greater-or-equal" value="1"/>
<numerical-comparator counter-id="points" comparison="less-or-equal" value="3"/>
</needed-comparators>
</prerequisites>
<text>
<string>Этот поинт будет показан, если читатель набрал от 1 до 3 очков.</string>
</text>
</point>
<point>
<prerequisites>
<restricted-comparators>
<numerical-comparator counter-id="points" comparison="greater-or-equal" value="4"/>
<numerical-comparator counter-id="points" comparison="less-or-equal" value="10"/>
</restricted-comparators>
</prerequisites>
<text>
<string>Этот поинт не будет показан, если читатель набрал от 4 до 10 очков.</string>
</text>
</point>
Взаимодействие условий друг с другом
В большом количестве условий легко запутаться
Если их получается очень много, лучше попытаться изменить устройство истории — например, сделать несколько поинтов вместо одного очень сложного.
Финальный вердикт prerequisites определяется в таком порядке:
- Вначале определяется, что даёт каждый из компараторов: «да» или «нет».
- Затем определяется, что даёт блок
needed-comparators: он даёт зелёный свет, если все компараторы внутри дают «да». - Затем определяется, что даёт блок
restricted-comparators: он даёт зелёный свет, если все компараторы внутри дают «нет». - Если в оба блока дают зелёный свет, поинт или кнопка отображается.
Например, у нас есть вот такие prerequisites:
<prerequisites>
<needed-comparators>
<numerical-comparator counter-id="points" comparison="greater-or-equal" value="1"/>
<numerical-comparator counter-id="points" comparison="less-or-equal" value="10"/>
</needed-comparators>
<restricted-comparators>
<numerical-comparator counter-id="points" comparison="greater-or-equal" value="4"/>
<numerical-comparator counter-id="points" comparison="less-or-equal" value="7"/>
</resctricted-comparators>
</prerequisites>
Пусть значение счётчика равно 2.
Вначале проверятся каждое из условий:
<prerequisites>
<needed-comparators>
<numerical-comparator counter-id="points" comparison="greater-or-equal" value="1"/> <!-- YES -->
<numerical-comparator counter-id="points" comparison="less-or-equal" value="10"/> <!-- YES -->
</needed-comparators>
<restricted-comparators>
<numerical-comparator counter-id="points" comparison="greater-or-equal" value="4"/> <!-- NO -->
<numerical-comparator counter-id="points" comparison="less-or-equal" value="7"/> <!-- YES -->
</resctricted-comparators>
</prerequisites>
Затем — что получается на «светофорах» needed-comparators и resctricted-comparators:
<prerequisites>
<needed-comparators> <!-- 🟢 -->
<numerical-comparator counter-id="points" comparison="greater-or-equal" value="1"/> <!-- YES -->
<numerical-comparator counter-id="points" comparison="less-or-equal" value="10"/> <!-- YES -->
</needed-comparators>
<restricted-comparators> <!-- 🟢 -->
<numerical-comparator counter-id="points" comparison="greater-or-equal" value="4"/> <!-- NO -->
<numerical-comparator counter-id="points" comparison="less-or-equal" value="7"/> <!-- YES -->
</resctricted-comparators>
</prerequisites>
Так как оба дают зелёный свет, поинт или кнопка отобразится:
<prerequisites> <!-- ✅ -->
<needed-comparators> <!-- 🟢 -->
<numerical-comparator counter-id="points" comparison="greater-or-equal" value="1"/> <!-- YES -->
<numerical-comparator counter-id="points" comparison="less-or-equal" value="10"/> <!-- YES -->
</needed-comparators>
<restricted-comparators> <!-- 🟢 -->
<numerical-comparator counter-id="points" comparison="greater-or-equal" value="4"/> <!-- NO -->
<numerical-comparator counter-id="points" comparison="less-or-equal" value="7"/> <!-- YES -->
</resctricted-comparators>
</prerequisites>
Теперь рассмотрим случай, если на счётчике 5.
Вначале проверятся каждое из условий:
<prerequisites>
<needed-comparators>
<numerical-comparator counter-id="points" comparison="greater-or-equal" value="1"/> <!-- YES -->
<numerical-comparator counter-id="points" comparison="less-or-equal" value="10"/> <!-- YES -->
</needed-comparators>
<restricted-comparators>
<numerical-comparator counter-id="points" comparison="greater-or-equal" value="4"/> <!-- YES -->
<numerical-comparator counter-id="points" comparison="less-or-equal" value="7"/> <!-- YES -->
</resctricted-comparators>
</prerequisites>
Затем — что получается на «светофорах» needed-comparators и resctricted-comparators:
<prerequisites>
<needed-comparators> <!-- 🟢 -->
<numerical-comparator counter-id="points" comparison="greater-or-equal" value="1"/> <!-- YES -->
<numerical-comparator counter-id="points" comparison="less-or-equal" value="10"/> <!-- YES -->
</needed-comparators>
<restricted-comparators> <!-- 🔴 -->
<numerical-comparator counter-id="points" comparison="greater-or-equal" value="4"/> <!-- YES -->
<numerical-comparator counter-id="points" comparison="less-or-equal" value="7"/> <!-- YES -->
</resctricted-comparators>
</prerequisites>
Так как на одном из «светофоров» красный, поинт или кнопка не проходит:
<prerequisites> <!-- ❌ -->
<needed-comparators> <!-- 🟢 -->
<numerical-comparator counter-id="points" comparison="greater-or-equal" value="1"/> <!-- YES -->
<numerical-comparator counter-id="points" comparison="less-or-equal" value="10"/> <!-- YES -->
</needed-comparators>
<restricted-comparators> <!-- 🔴 -->
<numerical-comparator counter-id="points" comparison="greater-or-equal" value="4"/> <!-- NO -->
<numerical-comparator counter-id="points" comparison="less-or-equal" value="7"/> <!-- YES -->
</resctricted-comparators>
</prerequisites>