跳到主要内容

Numerical Storage

每位玩家的命名数值余额,支持等级、利息、银行菜单和占位符。

免费v0.15经济与制作
依赖TypeWriter0.9GUI (GuiAndDialogs)PlaceholderAPI可选Vault可选Profiles可选

概述​

Numerical Storage 让你为每位玩家创建具名的数值存储:银行账户、法力池、代币钱包,或任意资源的储备。你只需在一个 definition 中描述一次存储,扩展就会为每位玩家保存一个余额和一个等级。

存储可以拥有等级,每个等级都有最大容量。玩家通过一个使用 GUI 扩展构建的物品栏菜单向其中存入和取出。资金可以通过 Vault 来自你的经济插件,也可以来自你选择的任意占位符和控制台命令。利息可以按计划增加,存储还可以通过命令重置、编辑或打开。

余额保存在 TypeWriter artifact 中并异步写入,因此存款永远不会阻塞服务器主线程。余额、等级和容量会以 PlaceholderAPI 占位符的形式提供,可用于计分板、全息图和菜单。

功能​

  • 多个存储 — 你需要多少个 definition 就能创建多少个,每个都有自己的名称、前缀、等级和菜单。
  • 等级与容量 — 每个等级都有最大余额;玩家通过升级来提高它。
  • 等级要求 — 通过占位符或 fact 的比较来解锁某个等级,还可以选择扣除费用。
  • 利息 — 支持 cron 计划、全局利率、按等级的利率以及按权限的利率,并带有每个周期的上限。
  • Vault 或命令 — 存款和取款可通过 Vault 进行,也可通过占位符加控制台命令进行。
  • 转账 — 在两个存储之间以原子方式转移余额。
  • 菜单按钮 — 固定金额、百分比、全部、自定义金额(对话框)、子菜单、升级和关闭。
  • 安全的持久化 — 异步保存、每个 artifact 一把锁,以及对旧文件的自动迁移。
  • 档案模式 — 通过 MMOProfiles 实现的可选按档案余额。
  • 占位符和命令 — 可在任何地方读取数值,并通过控制台进行编辑。

安装​

  1. 安装 GUI 扩展:Numerical Storage 的菜单需要它。GUI 扩展以 GuiAndDialogs 的名称发布。
  2. 如果你想使用 %typewriter_ns_...% 占位符,请安装 PlaceholderAPI。
  3. 可选:安装 Vault(扩展基于 VaultUnlocked 构建)和一个经济插件,以使用 VAULT 交易模式。
  4. 可选:安装 MMOProfiles 以使用 profileMode。
  5. 将 Numerical Storage 的 JAR 放入 plugins/Typewriter/extensions/,然后重启服务器。

自定义金额窗口使用 Paper 对话框,因此需要使用支持它们的 Paper 版本(Minecraft 1.21.6 或更高)。

更新前请先备份

自 0.9 版本起,新的 artifact 使用技术标识符和 JSON schema 版本 2。旧文件在第一次被读取时,会被复制到新路径,保存到 backups/numericalstorage/ 下,并被删除。更新前请保留一份 TypeWriter assets/ 文件夹的副本。

快速上手​

创建一个使用你的 Vault 经济支付的银行:

  1. 在 TypeWriter 网页面板中,打开一个 manifest 页面,添加一个 Player Numerical Storage artifact。让 artifactId 保持为空:TypeWriter 会自动生成。
  2. 添加一个 Numerical Storage Definition。设置 displayName(例如 Bank)、prefix,并在 artifact 中链接该 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 中,添加一个 id 为 main 的 simple 布局,并将 mainLayoutId 设为 main。在布局中添加一个物品,将 buttonPrefix 设为 numericalstorage_button:,buttonType 设为 DEPOSIT_FIXED:100。对 WITHDRAW_FIXED:100、UPGRADE_LEVEL 和 NAV_CLOSE 也这样操作。
  8. 将该动作链接到某个 NPC 对话或命令事件,发布,然后在游戏中打开银行。你也可以运行 /typewriter ns open <definition>。
每个 definition 对应一个 open-menu 条目

每次交易之后,菜单都会重新打开以显示新的余额。扩展会查找链接到同一 definition 的 Open Numerical Storage Menu 条目。如果没有,菜单会直接关闭。

工作原理​

菜单​

菜单是一个普通的 GUI 布局。Open Menu 动作会使用 definition 中的标题和行数(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将余额转移到另一个 definition。该按钮来自 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 中的交易按钮、返回按钮和关闭按钮的映射。

转账按钮需要另一个 definition 的 transferTarget(其条目 id),并且玩家在目标存储中必须还有空间。

命令​

所有命令都是 /typewriter(别名 /tw)的子命令。<definition> 是一个 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>(定义的 id)和 <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无定义没有关联 artifact 时,add、remove、level 和 reset 显示的消息。
noActiveProfileMessage无<player> has no active profile. 当 profileMode 开启且玩家没有活动的 MMOProfiles 档案时,由 add、remove、level 和 reset 显示,也会显示给点击菜单操作的玩家。不会写入任何内容。

默认值以 Typewriter 前缀开头。有三条文本不属于任何定义,因此改为 snippets.yml 中的 snippet:numericalstorage.command.player_only(由非玩家执行的菜单按钮命令),以及占位符文本 numericalstorage.placeholder.interest_disabled(Disabled)、numericalstorage.placeholder.interest_error(Error)和 numericalstorage.placeholder.capacity_unlimited(无穷符号)。interest_cooldown 的时间单位是 snippet 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> 替换为 definition 的条目 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>%definition 的 displayName。
%typewriter_ns_prefix_<id>%definition 的 prefix。

条目​

4 个条目,由扩展源码生成。

动作2
构件1
清单1

故障排查​

菜单打开后是空的,或按钮没有反应。 请检查每个物品的 buttonPrefix 是否严格设为 numericalstorage_button:,并且 buttonType 有效。如果前缀有误,该物品只会是一个没有任何动作的普通物品。同时检查 mainLayoutId 是否与 layoutPool 中某个布局的 id 匹配。

每次存款之后菜单都会关闭。 菜单是通过链接到同一 definition 的 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 档案的 id,不能显示或增加它的余额。写入会被 noActiveProfileMessage 拒绝,档案的利息在选择该档案时结算。

重启后占位符立刻显示为空。 存储在加入时于后台加载:第一次读取可能早于加载完成;下一次读取会显示已保存的值。

占位符为空。 占位符中的 id 必须是 definition 的条目 id,而不是它的名称。运行 /papi parse me %typewriter_ns_balance_<id>% 进行测试。

相关扩展​

  • GUI — 用于布局和按钮的菜单引擎。
  • MMOProfiles — 可选,供 profileMode 使用。