Перейти к основному содержимому

Numerical Storage

Именованные числовые балансы игроков с уровнями, процентами, меню банка и плейсхолдерами.

Бесплатныеv0.15Экономика и крафт
ТребуетсяTypeWriter0.9GUI (GuiAndDialogs)PlaceholderAPIнеобязательноVaultнеобязательноProfilesнеобязательно

Обзор​

Numerical Storage позволяет создавать для каждого игрока именованные числовые хранилища: банковский счёт, запас маны, кошелёк с жетонами, резерв любого ресурса. Вы описываете хранилище один раз в определении (definition), а расширение сохраняет по одному балансу и одному уровню на игрока.

У хранилища могут быть уровни, у каждого из которых есть максимальная вместимость. Игроки вносят и снимают средства через меню-инвентарь, построенное на расширении GUI. Деньги могут поступать из вашего плагина экономики через Vault либо из любого выбранного вами плейсхолдера и консольной команды. Проценты можно начислять по расписанию, а хранилища можно сбрасывать, редактировать или открывать командами.

Балансы сохраняются в артефакте TypeWriter и записываются асинхронно, поэтому внесение средств никогда не блокирует серверный поток. Балансы, уровни и вместимость доступны как плейсхолдеры PlaceholderAPI для скорбордов, голограмм и меню.

Возможности​

  • Несколько хранилищ — создавайте сколько угодно определений, у каждого своё имя, префикс, уровни и меню.
  • Уровни и вместимость — у каждого уровня есть максимальный баланс; игроки повышают уровень, чтобы увеличить его.
  • Требования к уровням — открывайте уровень по сравнению плейсхолдеров или фактов и при желании списывайте стоимость.
  • Проценты — расписание cron, глобальная ставка, ставка для каждого уровня и ставка для каждого права, с ограничением на цикл.
  • Vault или команды — внесение и снятие проходят через Vault либо через плейсхолдер и консольные команды.
  • Переводы — атомарный перенос баланса между двумя хранилищами.
  • Кнопки меню — фиксированная сумма, процент, всё, произвольная сумма (диалог), подменю, повышение уровня и закрытие.
  • Надёжное сохранение — асинхронные сохранения, одна блокировка на артефакт и автоматическая миграция старых файлов.
  • Режим профилей — необязательные балансы для каждого профиля через MMOProfiles.
  • Плейсхолдеры и команды — читайте значения где угодно и редактируйте их из консоли.

Установка​

  1. Установите расширение GUI: Numerical Storage нужен он для меню. Расширение GUI публикуется под названием GuiAndDialogs.
  2. Установите PlaceholderAPI, если хотите использовать плейсхолдеры %typewriter_ns_...%.
  3. По желанию: установите Vault (расширение собрано под VaultUnlocked) и плагин экономики, чтобы использовать режим транзакций VAULT.
  4. По желанию: установите MMOProfiles, чтобы использовать profileMode.
  5. Положите JAR-файл Numerical Storage в plugins/Typewriter/extensions/ и перезапустите сервер.

Окно произвольной суммы использует диалоги Paper, поэтому нужна версия Paper, которая их поддерживает (Minecraft 1.21.6 или новее).

Сделайте резервную копию перед обновлением

Начиная с версии 0.9 новые артефакты используют технический идентификатор и версию 2 схемы JSON. При первом чтении старого файла он копируется по новому пути, сохраняется в backups/numericalstorage/ и удаляется. Сохраните копию папки assets/ TypeWriter перед обновлением.

Быстрый старт​

Создадим банк, оплачиваемый вашей экономикой Vault:

  1. В веб-панели TypeWriter откройте страницу manifest и добавьте артефакт Player Numerical Storage. Оставьте artifactId пустым: TypeWriter сгенерирует его сам.
  2. Добавьте Numerical Storage Definition. Задайте displayName (например Bank), prefix и свяжите артефакт в artifact.
  3. В levels добавьте первый уровень с limit равным 1000, затем второй с 5000. Заполните depositMessage и levelUpMessage, если хотите собственный текст.
  4. В transaction задайте transactionMode равным VAULT.
  5. В menu.transactionButtons добавьте кнопку типа DEPOSIT с amountType FIXED, amount равным 100 и предметом для отображения. Добавьте вторую кнопку типа WITHDRAW.
  6. Добавьте действие Open Numerical Storage Menu. Свяжите definition.
  7. В его layoutPool добавьте макет simple с id main и задайте mainLayoutId равным main. В макет добавьте предмет с buttonPrefix, равным numericalstorage_button:, и buttonType, равным DEPOSIT_FIXED:100. Сделайте то же самое для WITHDRAW_FIXED:100, UPGRADE_LEVEL и NAV_CLOSE.
  8. Свяжите действие с диалогом NPC или событием-командой, опубликуйте и откройте банк в игре. Также можно выполнить /typewriter ns open <definition>.
Одна запись открытия меню на определение

После каждой транзакции меню открывается заново, чтобы показать новый баланс. Расширение ищет запись Open Numerical Storage Menu, связанную с тем же определением. Если её нет, меню просто закрывается.

Как это работает​

Меню​

Меню — это обычный макет GUI. Действие Open Menu открывает его с заголовком и числом рядов из определения (menu.title, menu.rows, от 1 до 6), а ваш layoutPool определяет, где находится каждый предмет. Расширение превращает предмет в рабочую кнопку, если у предмета buttonPrefix равен numericalstorage_button: и задан buttonType из этого списка:

buttonTypeЧто делает кнопка
DEPOSIT_FIXEDВносит фиксированную сумму. Добавьте сумму после двоеточия, например DEPOSIT_FIXED:100.
DEPOSIT_PERCENTВносит процент от баланса источника, например DEPOSIT_PERCENT:50.
DEPOSIT_CUSTOMЗакрывает меню и запрашивает сумму в диалоге.
DEPOSIT_ALLВносит весь баланс источника, вплоть до оставшейся вместимости. Нужен amountPlaceholder: в режиме VAULT кнопка пытается внести всю оставшуюся вместимость и завершается ошибкой, если баланс в экономике меньше.
DEPOSIT_SUBMENUОткрывает подменю кнопок внесения. Id подменю следует после двоеточия.
WITHDRAW_FIXED, WITHDRAW_PERCENT, WITHDRAW_CUSTOM, WITHDRAW_ALL, WITHDRAW_SUBMENUТо же, что выше, для снятия. Процент берётся от хранящегося баланса.
TRANSFER_FIXED, TRANSFER_PERCENT, TRANSFER_ALLПереносят баланс в другое определение. Кнопка берётся из записи transactionButtons типа TRANSFER с transferTarget.
SUB_MENUОткрывает подменю, id которого следует после двоеточия, например SUB_MENU:deposit_options.
UPGRADE_LEVELПовышает до следующего уровня или показывает предмет максимального уровня.
NAV_CLOSEЗакрывает меню.

Если у buttonType есть сумма (DEPOSIT_FIXED:100), расширение выбирает запись menu.transactionButtons с тем же типом, типом суммы и суммой и использует её template в качестве предмета. Без суммы используется первая подходящая запись. Если ничего не подходит, показывается обычный предмет-краситель с подписью по умолчанию.

Подменю определяются в menu.subMenus как соответствие id заголовку, числу рядов, кнопкам транзакций, размещённым в slots, кнопке «назад» и кнопке закрытия.

Для кнопки перевода нужен transferTarget другого определения (id его записи), а в целевом хранилище у игрока должно хватать места.

Команды​

Все команды являются подкомандами /typewriter (псевдоним /tw). <definition> — запись определения. Необязательный [target] выбирает другого игрока; без него команда применяется к отправителю.

КомандаПравоОписание
/typewriter ns open <definition> [target]typewriter.ns.openОткрывает меню хранилища через его запись Open Menu.
/typewriter ns add <definition> <amount> [target]typewriter.ns.addДобавляет к балансу. Вместимость не проверяется.
/typewriter ns remove <definition> <amount> [target]typewriter.ns.removeВычитает из баланса, не ниже 0.
/typewriter ns level <definition> <level> [target]typewriter.ns.levelЗадаёт уровень и сбрасывает баланс в 0.
/typewriter ns reset <definition> [target]typewriter.ns.resetСбрасывает уровень в 1 и баланс в 0.

Команды /typewriter numstorage tx ..., upgrade и back_main используются кнопками меню внутри. Для игрока без открытого меню они ничего не делают.

При включённом profileMode команды add, remove, level и reset меняют баланс и уровень профиля цели, как и меню.

Ответы команд​

Ответы add, remove, level, reset и open, а также ответы об ошибках ниже — это поля adminMessages в определении. Они написаны в MiniMessage. В каждом можно использовать <player>, <storage> (идентификатор определения) и <prefix>.

ПолеДополнительный плейсхолдерПо умолчанию
resetMessageнетNumerical storage reset for <player>.
levelSetMessage<level>Set numerical storage level to <level> for <player>.
addMessage<amount>Added <amount> to <player>.
removeMessage<amount>Removed <amount> from <player>.
noMenuMessageнетСообщение, которое показывается, когда у хранилища нет записи Open Menu.
invalidAmountMessage<amount> (введённое значение)Invalid amount '<amount>'. Use a positive number. Показывается командами add и remove, когда сумма не является положительным числом.
noArtifactMessageнетСообщение, которое показывают add, remove, level и reset, когда к определению не привязан артефакт.
noActiveProfileMessageнет<player> has no active profile. Показывается командами add, remove, level и reset, а также игроку, нажавшему действие меню, когда profileMode включён и у игрока нет активного профиля MMOProfiles. Ничего не записывается.

Значения по умолчанию начинаются с префикса Typewriter. Три текста не принадлежат ни одному определению, поэтому вместо этого они являются сниппетами в snippets.yml: numericalstorage.command.player_only (команды кнопок меню, выполняемые не игроком) и тексты плейсхолдеров numericalstorage.placeholder.interest_disabled (Disabled), numericalstorage.placeholder.interest_error (Error) и numericalstorage.placeholder.capacity_unlimited (знак бесконечности). Единицы времени в interest_cooldown — это сниппеты numericalstorage.duration.days, hours, minutes, seconds (каждый — шаблон с {value}, по умолчанию {value}j) и numericalstorage.duration.separator.

Права​

ПравоДаёт доступ к
typewriter.ns.open/typewriter ns open.
typewriter.ns.add/typewriter ns add.
typewriter.ns.remove/typewriter ns remove.
typewriter.ns.level/typewriter ns level.
typewriter.ns.reset/typewriter ns reset.
Права в interestRatesДают игроку определённую процентную ставку. Используется первое право из списка, которое есть у игрока.

Плейсхолдеры​

Замените <id> на id записи определения. Им нужен PlaceholderAPI, а значения читаются из кэша, поэтому их безопасно использовать в скорбордах. При включённом profileMode значения balance, level, capacity и interest относятся к профилю, за который играет игрок, как и в меню.

ПлейсхолдерВозвращает
%typewriter_ns_balance_<id>%Текущий баланс.
%typewriter_ns_level_<id>%Текущий уровень, начиная с 1.
%typewriter_ns_capacity_<id>%Вместимость текущего уровня или знак бесконечности, если уровни не определены.
%typewriter_ns_interest_<id>%Процентная ставка, действующая для игрока, в процентах.
%typewriter_ns_interest_cooldown_<id>%Время до следующего запланированного цикла начисления процентов или Disabled.
%typewriter_ns_name_<id>%displayName определения.
%typewriter_ns_prefix_<id>%prefix определения.

Записи​

Записей: 4, сгенерированы из исходного кода расширения.

Действия2
Артефакты1
Манифесты1

Устранение неполадок​

Меню открывается пустым или кнопки ничего не делают. Проверьте, что у каждого предмета buttonPrefix в точности равен numericalstorage_button: и задан корректный buttonType. Если префикс неверный, предмет остаётся обычным предметом без действия. Также проверьте, что mainLayoutId совпадает с id макета в layoutPool.

Меню закрывается после каждого внесения. Меню открывается заново через запись Open Numerical Storage Menu, связанную с тем же определением. Добавьте её, даже если вы открываете меню другой записью.

«Cannot add ... Would exceed limit». Хранилище заполнено до вместимости уровня игрока (levels[].limit). Повысьте уровень или увеличьте лимит. Если уровни не определены, лимита нет.

Внесение в режиме INTERNAL не удаётся. Баланс-источник игрока читается через amountPlaceholder и должен возвращать простое число. addCommand выполняется из консоли перед внесением и должна завершиться успешно. Используйте в команде {player} и {amount}.

«Economy system is not available.» transactionMode равен VAULT, но Vault или поставщик экономики отсутствует. Установите оба и перезапустите сервер.

Проценты не начисляются. Проценты применяются при входе игрока за циклы cron, прошедшие с его последней выплаты (не более 100 циклов). Должен быть включён interestEnabled и заполнен interestCron. Первый вход только фиксирует начальное время. Баланс, равный вместимости своего уровня, ничего не приносит.

Повышение уровня требует в качестве стоимости вместимость. Если у следующего уровня нет criteria, стоимость повышения равна limit текущего уровня и списывается с хранящегося баланса. Добавьте criteria следующему уровню, чтобы задать другое требование.

Плейсхолдеры показывают баланс другого профиля. При включённом profileMode плейсхолдеры и кнопка улучшения читают баланс и уровень профиля, выбранного игроком. Без MMOProfiles они читают собственный баланс игрока. С MMOProfiles и без активного профиля (экран выбора, после /mmoprofiles quit) они показывают 0, так как UUID игрока — это идентификатор его профиля Main, и его баланс нельзя ни показывать, ни пополнять. Запись отклоняется с noActiveProfileMessage, а проценты профиля начисляются при его выборе.

Плейсхолдер пуст сразу после перезапуска. Хранилище загружается в фоне при входе: первое чтение может прийти до конца загрузки; следующее покажет сохранённое значение.

Плейсхолдер пустой. Id в плейсхолдере должен быть id записи определения, а не его именем. Для проверки выполните /papi parse me %typewriter_ns_balance_<id>%.

Связанные расширения​

  • GUI — движок меню, используемый для макетов и кнопок.
  • MMOProfiles — необязательный плагин, используется в profileMode.