Rewards
Обзор
Rewards ведёт для каждого игрока очередь наград, которые заработаны, но ещё не получены. Вместо того чтобы сразу выдать предмет или выполнить команду, вы помещаете награду в очередь. Игрок забирает её позже из меню, когда находится в сети и у него есть место в инвентаре. Ничего не теряется, если игрока нет в сети или его инвентарь полон в момент выдачи награды.
Награда — это шаблон, который вы определяете один раз (определение награды: отображаемый предмет, описание, необходимое число свободных слотов, действия, выполняемые при получении). Выдача добавляет в очередь небольшую запись; получение удаляет запись и запускает действия TypeWriter, которые вы связали с определением. Поскольку эффект получения — это список действий TypeWriter, награда может выдавать предметы, деньги, шаг квеста или всё, что может запустить TypeWriter.
Очередь хранится в одном артефакте. Когда расширение MySQL предоставляет Redis, серверам с общим хранилищем после каждого сохранения сообщают о необходимости перезагрузить артефакт, поэтому награду, выданную на одном сервере, можно получить на другом.
Возможности
- Отложенное получение — награды ждут в очереди, пока игрок их не получит.
- Определения наград — один многоразовый шаблон на каждый тип награды, с отображаемым предметом, названием, описанием и требованием свободных слотов.
- Действия при получении — получение запускает любой список действий TypeWriter вместо консольной команды.
- Отдельное меню получения — инвентарь с пагинацией, слотами наград, информационным слотом, кнопками страниц, массовым получением и кнопкой «назад».
- Встраиваемые кнопки — слоты наград и кнопку массового получения можно разместить на любой странице GUI через типы кнопок.
- Выдача по cron —
btc_give_rewardможет выдавать награду не чаще одного раза за период cron для каждого игрока (ежедневные, еженедельные награды). - Событие получения — запись-событие срабатывает при каждом получении с идентификатором награды, пользовательскими данными и счётчиками.
- Факт и плейсхолдеры ожидающих наград — используйте очередь в критериях, на скорбордах и в меню.
- Защита от спама — перезарядка 500 мс между получениями одного и того же игрока.
Установка
- Установите расширение GUI (его название плагина в сборке —
GuiAndDialogs) и расширение MySQL, оба объявлены зависимостями Rewards. Redis используется только для обновления между серверами и на одном сервере не нужен. - Поместите JAR-файл Rewards в
plugins/Typewriter/extensions/и перезапустите сервер. - По желанию установите MiniPlaceholders, чтобы использовать плейсхолдеры
rewardsв тексте MiniMessage.
Начало работы
Выдайте ежедневную награду за вход, которую игроки забирают из меню.
- В веб-панели TypeWriter откройте страницу static и добавьте Rewards Artifact. Добавляйте только один: плейсхолдеры и встроенные кнопки используют первый найденный.
- Добавьте запись Rewards Config (тоже только одну), чтобы настроить сообщения и раскладку описания награды.
- Добавьте Reward Definition. Задайте
rewardIdравнымdaily_login,sourceравнымdaily_login, выберитеdisplayItemи свяжите действия, выдающие награду, вonClaimActions. - Создайте действие Give Reward. Свяжите
artifactиreward, включитеuseCronи задайтеcronExpressionравным0 0 0 * * *для одного раза в день. Запускайте его от события входа или NPC. - Создайте действие Open Rewards Menu с тем же
artifactи запускайте его командой или от NPC. - Опубликуйте. Игрок, запустивший выдачу, получает одну ожидающую награду; клик по ней в меню забирает её.
Используйте Has Pending Rewards в критерии, чтобы показывать уведомление только пока у игрока есть что забрать.
Как это работает
Очередь хранит только rewardId, время выдачи и пользовательские данные. Предмет, показываемый в меню, и действия, которые нужно выполнить, всегда читаются из определения в момент отображения или получения. Награда в очереди, определение которой было удалено, не показывается и не может быть получена.
Меню
Награды можно показывать двумя способами с общей логикой получения.
Отдельное меню. Open Rewards Menu открывает собственный инвентарь с rows от 1 до 6. Ожидающие награды заполняют rewardSlotsConfig по порядку (диапазон или явный список слотов, когда useRange выключен). Когда наград больше, чем слотов, меню разбивается на страницы с необязательными previousPageButton и nextPageButton. Необязательные infoSlot, bulkClaimButton и backButton принимают номера слотов, предмет, название и описание в MiniMessage. backButton.command выполняется от имени игрока (без начального слэша); оставьте его пустым, чтобы просто закрыть меню. Пустые слоты заполняются backgroundItem, если он задан. Номера слотов идут от 0 (левый верхний) до 8 в первом ряду, затем с 9 до 17 и так далее.
Кнопки на любой странице GUI. В меню GUI задайте buttonType предмета равным одному из маркеров Rewards. Настроенный вами предмет сохраняет свою позицию и стиль; для слотов наград он заменяется собственным отображаемым предметом награды.
| Тип кнопки | Поведение |
|---|---|
rewards_button:REWARD_SLOT#<n> | Показывает n-ю ожидающую награду зрителя (счёт с 0); левый клик получает её. После последней награды слот пуст. |
rewards_button:BULK_CLAIM | Левый клик получает все ожидающие награды, для которых у игрока есть место. |
Правила получения в обоих режимах:
- Награде нужно
requiredInventorySlotsпустых слотов в инвентаре игрока (0 означает отсутствие проверки). Если места недостаточно, получение отклоняется и отправляетсяinventoryFullMessage. - Получение запускает
onClaimActionsопределения, затем запускает каждую запись-событие Reward Claimed. Массовое получение идёт от последней награды в очереди к первой и запускает событие один раз с идентификатором наградыbulk_claim. - Сообщения об успехе и о массовом получении берутся из записи Rewards Config. Для встроенных кнопок используется первая найденная запись Rewards Config.
Описание предмета награды строится из additionalLore определения, затем разделителя и строк источника и свободных слотов, затем завершающей подсказки; подписи берутся из записи Rewards Config.
Плейсхолдеры
Расширение MiniPlaceholders rewards, используется в тексте MiniMessage как теги.
| Плейсхолдер | Возвращает |
|---|---|
<rewards_pending> | Число ожидающих наград игрока. |
<rewards_pending:rewardId> | Число ожидающих наград с этим rewardId. |
<rewards_source:source> | Число ожидающих наград, определение которых имеет этот source (без учёта регистра). Награды с удалённым определением не учитываются. |
<rewards_claimed_total> | Общее число наград, полученных игроком. |
Идентификатор награды — это аргумент тега: пишите <rewards_pending:daily_login>, а не <rewards_pending_daily_login>. Все плейсхолдеры ничего не возвращают, если Rewards Artifact не существует.
Записи
Записей: 7, сгенерированы из исходного кода расширения.
Действия2
- BTC Give RewardAdds a reward to a player's pending queue (with optional cron scheduling)
- BTC Open Rewards MenuOpens the rewards queue menu for a player
События1
- BTC Reward Claimed EventTriggered when a player successfully claims a reward
Факты1
- BTC Has Pending RewardsReturns the count of pending rewards for a player
Артефакты1
- BTC Rewards ArtifactStores pending rewards and claim history for all players
Манифесты2
- BTC Reward DefinitionDefines a reward type that can be given and claimed by players
- BTC Rewards ConfigGlobal configuration for the rewards system (sounds, toasts, messages)
Устранение неполадок
Меню не открывается, а в логе написано, что расширение GUI не установлено. btc_open_rewards_menu нужно расширение GUI во время работы. Установите его и перезапустите. Действие также ничего не делает, с предупреждением, когда его поле artifact пусто.
Give Reward ничего не делает. В логе появляется предупреждение, когда у действия нет artifact, нет reward или когда у связанного определения пустой rewardId. Заполните эти три поля.
Награда по cron выдаётся только один раз. При включённом useCron время последней выдачи хранится для каждого игрока и каждой записи-действия. Следующая выдача происходит только после следующего совпадения выражения cron после этого момента. Проверяйте с коротким выражением или используйте отдельную запись-действие для каждого расписания.
Ожидающая награда невидима или не может быть получена. Меню пропускает награды из очереди, определение которых не удаётся найти по rewardId. Не меняйте rewardId определения после того, как награды были выданы.
Получение отклонено сообщением о заполненном инвентаре. У игрока меньше пустых слотов, чем requiredInventorySlots. Учтите, что проверка считает каждый пустой слот объекта инвентаря игрока, включая слоты брони и второй руки.
Тосты, звуки, noRewardsMessage и onClaimFailActions не действуют. Эти поля есть в Rewards Config и Reward Definition, но код этой версии их никогда не читает. Применяются только сообщения о получении, заполненном инвентаре и массовом получении и раскладка описания.
Награды не появляются на другом сервере. Обновление между серверами опирается на Redis из расширения MySQL и на то, что оба сервера читают одно и то же хранилище артефактов. Без Redis каждый сервер видит только свою копию до перезапуска.