跳到主要内容

Rewards

为离线玩家提供奖励队列,包含领取菜单、定时发放和领取事件。

私有v0.2.0经济与制作
依赖TypeWriter0.9.0-beta-177 (BTC build)GUIMySQLMiniPlaceholders可选

专为 BornToCraft 服务器网络打造。此扩展仅作参考文档,不对外分发。

概览​

Rewards 为每位玩家维护一个队列,存放已经获得但尚未领取的奖励。你不再当场给予物品或运行命令,而是把奖励推入队列。玩家稍后在线并且物品栏有空位时,可从菜单中领取。即使奖励发放时玩家离线或物品栏已满,也不会丢失任何东西。

奖励是你只需定义一次的模板(一个奖励定义:展示物品、lore、所需空槽位数、领取时运行的动作)。发放它会向队列添加一条小记录;领取它会移除该记录,并触发你链接到该定义的 TypeWriter 动作。由于领取效果是一组 TypeWriter 动作,奖励可以给予物品、金钱、任务步骤,或 TypeWriter 能触发的任何其他内容。

队列存储在单个构件中。当 MySQL 扩展提供 Redis 时,共用同一存储的服务器会在每次保存后被通知重新加载该构件,因此在一台服务器上发放的奖励可以在另一台服务器上领取。

功能​

  • 延迟领取 — 奖励在队列中等待,直到玩家领取。
  • 奖励定义 — 每种奖励类型一个可重复使用的模板,包含展示物品、名称、lore 和空槽位要求。
  • 领取动作 — 领取会触发任意 TypeWriter 动作列表,而不是控制台命令。
  • 独立的领取菜单 — 带有奖励槽位、信息槽位、翻页按钮、批量领取和返回按钮的分页物品栏。
  • 可嵌入的按钮 — 奖励槽位和批量领取按钮可通过按钮类型放置在任意 GUI 页面上。
  • Cron 发放 — btc_give_reward 可以在每个 cron 周期内为每位玩家最多发放一次奖励(每日、每周奖励)。
  • 领取事件 — 每次领取时,事件条目都会触发,并带有奖励 id、自定义数据和计数器。
  • 待领取数量事实与占位符 — 在条件、计分板和菜单中使用该队列。
  • 防刷屏 — 同一玩家两次领取之间有 500 毫秒的冷却。

安装​

  1. 安装 GUI 扩展(其在构建中的插件名称为 GuiAndDialogs)和 MySQL 扩展,两者都被声明为 Rewards 的依赖项。Redis 仅用于跨服务器刷新,在单台服务器上不需要。
  2. 将 Rewards 的 JAR 放入 plugins/Typewriter/extensions/ 并重启服务器。
  3. 可选:安装 MiniPlaceholders,以便在 MiniMessage 文本中使用 rewards 占位符。

快速上手​

发放一份玩家从菜单中领取的每日登录奖励。

  1. 在 TypeWriter 网页面板中,打开一个**静态(static)**页面,添加一个 Rewards Artifact。只添加一个:占位符和嵌入式按钮会使用它们找到的第一个。
  2. 添加一个 Rewards Config 条目(同样只添加一个),用于调整消息和奖励 lore 的布局。
  3. 添加一个 Reward Definition。将 rewardId 设为 daily_login,source 设为 daily_login,选择一个 displayItem,并在 onClaimActions 中链接给予奖励的动作。
  4. 创建一个 Give Reward 动作。链接 artifact 和 reward,启用 useCron,并将 cronExpression 设为 0 0 0 * * * 表示每天一次。通过加入事件或 NPC 触发它。
  5. 创建一个使用相同 artifact 的 Open Rewards Menu 动作,并通过命令或 NPC 触发它。
  6. 发布。触发发放的玩家会获得一个待领取的奖励;在菜单中点击它即可领取。
统计奖励数量

在条件中使用 Has Pending Rewards,使通知只在玩家有东西可领取时才显示。

工作原理​

队列只存储 rewardId、发放时间和自定义数据。菜单中显示的物品以及要运行的动作,始终是在显示或领取的那一刻从定义中读取的。其定义已被删除的队列奖励不会显示,也无法领取。

菜单​

Rewards 可以通过两种共用同一套领取逻辑的方式显示。

独立菜单。 Open Rewards Menu 会打开自己的物品栏,rows 为 1 到 6。待领取的奖励按顺序填入 rewardSlotsConfig(一个范围,或在 useRange 关闭时使用显式的槽位列表)。当奖励数量多于槽位时,菜单会通过可选的 previousPageButton 和 nextPageButton 分页。可选的 infoSlot、bulkClaimButton 和 backButton 接受槽位编号、物品、MiniMessage 名称和 lore。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 事件条目。批量领取从最后加入队列的奖励到第一个,并以奖励 id bulk_claim 触发一次事件。
  • 成功消息和批量消息来自 Rewards Config 条目。对于嵌入式按钮,会使用找到的第一个 Rewards Config 条目。

奖励物品的 lore 由定义的 additionalLore 构建,然后是一条分隔线以及来源和空槽位行,最后是一条收尾提示;标签来自 Rewards Config 条目。

占位符​

MiniPlaceholders 扩展 rewards,可在 MiniMessage 文本中作为标签使用。

占位符返回
<rewards_pending>玩家待领取的奖励数量。
<rewards_pending:rewardId>具有该 rewardId 的待领取奖励数量。
<rewards_source:source>其定义具有该 source 的待领取奖励数量(不区分大小写)。定义已被删除的奖励不会被计入。
<rewards_claimed_total>玩家累计已领取的奖励数量。

奖励 id 是标签的参数:请写 <rewards_pending:daily_login>,而不是 <rewards_pending_daily_login>。如果不存在 Rewards Artifact,所有占位符都不返回任何内容。

条目​

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

动作2
事件1
事实1
构件1
清单2

故障排查​

菜单没有打开,且日志提示未安装 GUI Extension。 btc_open_rewards_menu 在运行时需要 GUI 扩展。请安装它并重启。当其 artifact 字段为空时,该动作同样不会执行任何操作,并给出警告。

Give Reward 没有任何作用。 当动作没有 artifact、没有 reward,或所链接的定义的 rewardId 为空时,日志会显示警告。请填写这三个字段。

Cron 奖励只发放了一次。 开启 useCron 时,上次发放时间按玩家和动作条目存储。只有在那之后 cron 表达式下一次匹配时,才会进行下一次发放。请使用较短的表达式进行测试,或为每个计划使用不同的动作条目。

待领取的奖励不可见或无法领取。 菜单会跳过无法通过 rewardId 找到其定义的队列奖励。在已经发放奖励之后,请勿更改定义的 rewardId。

领取被拒绝,并显示物品栏已满的消息。 玩家的空槽位少于 requiredInventorySlots。请注意,该检查会统计玩家物品栏对象的每一个空槽位,包括盔甲和副手槽位。

Toast、音效、noRewardsMessage 和 onClaimFailActions 没有效果。 这些字段存在于 Rewards Config 和 Reward Definition 中,但此版本的代码从不读取它们。只有领取消息、物品栏已满消息、批量消息以及 lore 布局会被应用。

奖励没有出现在另一台服务器上。 跨服务器刷新依赖于 MySQL 扩展提供的 Redis,并且两台服务器必须读取相同的构件存储。没有 Redis 时,每台服务器只能看到自己的副本,直到重启。

相关扩展​

  • GUI — 渲染由页面驱动的按钮和独立菜单。
  • MySQL — 服务器之间的 Redis 缓存失效。