Pets
概览
Pets 添加了受 EcoPets 启发的可收集伙伴。每个宠物只需在网页面板中定义一次(Pet Definition),每位玩家各自拥有它的副本。宠物以代币物品的形式发放:右键点击代币即可将该宠物添加到玩家的伙伴菜单中。玩家可以在菜单中一次激活一只宠物,该宠物会悬浮在其头顶、在其身旁行走,或在其周围飞行。
当主人击杀怪物或你的剧情发放经验时,宠物会获得经验,并按照你编写的公式或表格升级。宠物可以对攻击其主人的怪物进行反击,并且可以拥有多种通过 TypeWriter 条件解锁的皮肤。
功能
- 三种显示模式 —
HEAD悬浮在玩家上方,GROUND在其身旁行走,FLY在设定的高度悬停。 - 伙伴菜单 — 一个 GUI,包含已拥有宠物的网格、激活、隐藏和显示、详情和皮肤。
- 代币物品 — 宠物以物品的形式在玩家之间转移,并保留其等级、经验、模式和皮肤。
- 经验与等级 — 公式(例如
{level} * 100)或显式表格,并带有最高等级。 - 击杀经验与剧情经验 — 每次击杀怪物获得的经验,外加可在任意序列中发放经验的动作。
- 反击 — 可选地对伤害主人的怪物进行反击,伤害随等级变化。
- 皮肤 — 每个宠物可有多个 NPC 皮肤,每个皮肤都有条件、优先级和菜单图标。
- 槽位权限 — 将菜单槽位锁定在权限之后,以出售额外的伙伴槽位。
- 占位符 — 当前激活宠物、某个槽位或任意宠物的名称、等级、经验、状态和归属。
- 模型支持 — 地面宠物和飞行宠物可使用任意实体定义,包括 ModelEngine 模型。
安装
- 安装负责绘制菜单的 GUI 扩展。
- 可选:如果宠物应使用动画模型,请安装 ModelEngine,以及将你的模型公开为实体定义的 TypeWriter 扩展。
- 将 Pets 的 JAR 放入
plugins/Typewriter/extensions/并重启服务器。 - 创建一个 Pet Storage 构件,以便保存已拥有的宠物,参见快速上手。
快速上手
创建第一只宠物并将其交给玩家:
- 在 TypeWriter 网页面板中,打开一个静态页面,添加一个 Pet Storage 构件。没有它,扩展会记录 "No pet_storage entry found",并且任何数据都不会持久化。
- 添加一个 Pet Definition。条目自己的
name是宠物的显示名称,其id是宠物标识符。 - 选择
defaultMode。对于HEAD,可以选择性地为悬浮的头颅粘贴一个 base64 的texture。对于GROUND或FLY,请将npc设为一个会生成在玩家身旁的实体定义条目。 - 在
xp下,设置maxLevel,以及使用{level}的formula(例如{level} * 100)或一个levels列表。设置killReward作为每次击杀的经验。 - 可选:勾选
combat.enabled以启用反击,并自定义token(物品、其名称和 lore,以及发光效果)。 - 添加一个 Pets Open Menu 动作,将其
storage设为你的 Pet Storage 构件,并通过 NPC、物品或命令触发它。 - 发布,然后以玩家身份运行
/pets give <pet> 1。右键点击代币,然后打开菜单并点击宠物以激活它。
若要通过剧情发放经验,请添加一个带有 amount 的 Pets Add XP 动作。经验会进入玩家当前激活的宠物。若要控制某个特定的宠物,请使用带有 pet 和 action 的 Pets State。
没有可以直接解锁宠物的动作。宠物以代币物品的形式到达玩家手中,来自 /pets give 或菜单中的“返回为物品”按钮。可在任务或商店中通过控制台命令动作运行该命令,使其成为可解锁的奖励。
工作原理
每位玩家对每个定义最多拥有一只宠物。同一时间只有一只宠物处于激活状态:激活另一只会使第一只失活。宠物会在后台保存到 Pet Storage 构件中,当玩家加入时会恢复当前激活的宠物。
显示模式。
HEAD在玩家头顶显示宠物,并应用headOffset。如果设置了npc,则使用该实体。否则,一个隐形的盔甲架会戴上带有texture的玩家头颅。GROUND会在玩家身后几格处生成npc(或所选皮肤的 NPC)并使其跟随。swimMode决定它是否在液体中游泳:AUTO遵循该实体的能力,ALWAYS和NEVER则强制设定。FLY与GROUND相同,但宠物会悬停在玩家上方flightHeight格处。
如果某只 GROUND 或 FLY 宠物没有 NPC(或其皮肤均不匹配),它不会显示,并会记录一条警告。每只激活的宠物上方都会显示一个带有等级的名称标签。模式在代币首次创建时取自 defaultMode,并保留在该宠物实例上。
经验与等级。 宠物从 1 级开始。levels 的每一项给出宠物达到某个等级所需的总经验,例如 2 级需要 100 经验,3 级需要 250 经验。显式条目优先于公式。公式在计算时会将 {level} 替换为要达到的等级,并支持 + - * /、括号和小数。没有下一级任何要求的宠物不会升级。
反击。 启用 combat.enabled 后,处于激活且可见状态的宠物会反击任何伤害主人的非玩家怪物,有短暂的延迟,并且对每个攻击者有 1.5 秒的冷却。伤害为不高于宠物等级的最高 levels 条目的 damage。没有该条目时,伤害为 1.5,超过 1 级的每一级再加 0.5。
皮肤。 每个 skins 条目指向一个 NPC 定义、一个 priority 和 criteria。如果玩家所选的皮肤的条件仍然匹配,宠物就使用它,否则使用条件匹配的最高优先级皮肤。定义中的 npc 字段是后备皮肤。皮肤条目需要一个 npc,否则会被忽略。
菜单
Pets Open Menu 动作会打开内置的伙伴菜单,标题为 “Compagnons”。每只已拥有的宠物都是一个玩家头颅图标,显示等级、经验进度和状态。左键点击会激活或停用宠物,右键点击会打开其详情界面。详情界面显示属性,并让玩家激活、选择皮肤(当宠物拥有多个皮肤时)、将宠物返回为物品,或返回。左下角的一个按钮可显示或隐藏当前激活的宠物。
菜单设置是该动作的 menu 对象的字段:
slots— 显示宠物的物品栏槽位编号。默认为三行共 21 个槽位。lockedSlots— 成对的slot和permission。玩家缺少其权限的槽位会显示一个锁定标记,并且无法在其中放置宠物。maxSlots— 使用的槽位数量上限(默认 21,最小 1):只有slots的前maxSlots个条目会被布局并可接收新宠物。它限制布局以及玩家可获得的宠物数量,而不限制玩家已经拥有的宠物。rows— 菜单高度,1 到 6。storage— 要使用的 Pet Storage 构件。
上次打开的菜单的槽位布局会随玩家数据一起保存,并决定令牌可以填入哪些槽位。玩家已拥有、但位于 maxSlots 之外(或菜单高度之外)槽位的宠物不会被隐藏:它会显示在菜单的空闲格子中(绝不会占用显示/隐藏按钮),点击时仍然作用于它自己的槽位。如果这类宠物多于空闲格子,多出的宠物仍归玩家所有,并显示在共享 Social 菜单的 Pets 页面中,该页面列出所有已拥有的宠物;每位玩家只会记录一次警告。
在你自己的菜单中使用。 该扩展为任意 GUI 菜单注册了 pets_button: 按钮前缀。将物品的 buttonPrefix 设为 pets_button:,并将其 buttonType 设为以下之一:
buttonType | 显示 |
|---|---|
PET_ENTRY | 玩家列表中该位置的宠物。左键点击切换其状态,右键点击为详情物品选中它。 |
PET_DETAIL_INFO | 所选宠物的等级、经验和模式。 |
PET_LEVEL_ENTRY | 所选宠物的某一个等级,包含其经验要求和状态。 |
PET_DETAIL_REMOVE | 将所选宠物返回为物品的按钮。 |
PET_LIST_NAV、PET_DETAIL_NAV | 宠物列表和等级列表的翻页箭头。 |
槽位还可以运行 pet_menu 命令:pet_menu activate <slot>、pet_menu deactivate <slot>、pet_menu toggle_visibility、pet_menu details <slot>、pet_menu skins <slot>、pet_menu select_skin <pet> <skin> 和 pet_menu remove <slot>。
如果安装了 UiCore,它可以读取玩家的伙伴来绘制 HUD 或菜单页面。
菜单文本、代币 lore 以及宠物上方的标签默认是法语(例如 “Niveau”、“Compagnons”)。请为每只宠物编辑代币的 name、lore 和 noSlotMessage。其他菜单文本在代码中是固定的。
命令
每个子命令都需要权限 typewriter.pets,以及所示的权限。大多数子命令在其参数之后接受一个可选的玩家选择器 [target],用于对其他人执行操作;没有它时则作用于发送者。
| 命令 | 权限 | 说明 |
|---|---|---|
/pets open [target] | typewriter.pets.open | 打开伙伴菜单。 |
/pets activate <pet> [target] | typewriter.pets.activate | 激活一只已拥有的宠物。 |
/pets deactivate [target] | typewriter.pets.deactivate | 让当前激活的宠物离开。 |
/pets show [target] | typewriter.pets.show | 重新显示当前激活的宠物。 |
/pets hide [target] | typewriter.pets.hide | 隐藏当前激活的宠物。 |
/pets remove <pet> [target] | typewriter.pets.remove | 从玩家的菜单中删除一只宠物。不会返还物品。 |
/pets give <pet> <amount> [target] | typewriter.pets.give | 给予 1 到 64 个代币物品。 |
<pet> 是 Pet Definition 条目的 id 或名称。在此版本中,单独的 /pets 命令没有任何作用:请使用 /pets open。
权限
没有任何权限注册了默认值,因此除非你通过权限插件授予,否则只有管理员拥有它们。
| 权限 | 授予 |
|---|---|
typewriter.pets | /pets 命令树。 |
typewriter.pets.open | /pets open。 |
typewriter.pets.activate | /pets activate。 |
typewriter.pets.deactivate | /pets deactivate。 |
typewriter.pets.show | /pets show。 |
typewriter.pets.hide | /pets hide。 |
typewriter.pets.remove | /pets remove。 |
typewriter.pets.give | /pets give。 |
来自 lockedSlots 的权限 | 解锁对应的菜单槽位。名称由你自己选择。 |
占位符
Pets 公开了一个 TypeWriter 占位符条目 Pets Placeholder。请创建一次。标签为 <typewriter_ENTRY:...>,其中 ENTRY 是该条目的小写名称或 id,例如当条目名为 pets_placeholder 时为 <typewriter_pets_placeholder:active:name>。
| 参数路径 | 返回 |
|---|---|
active | 当前激活宠物的名称,没有时为空。 |
active:name、active:id | 当前激活宠物的名称和 id。 |
active:level、active:xp、active:max_level | 等级、经验和最高等级。 |
active:next_xp | 下一级所需的经验,到顶时为 Max。 |
active:damage | 当前等级的反击伤害。 |
active:status | active 或 inactive。 |
active:visibility | hidden 或 visible。 |
active:mode | head、ground 或 fly。 |
slot:<index>:name、id、level、xp、next_xp、max_level、damage、visibility、mode | 该菜单槽位中宠物的相同字段。 |
slot:<index>:status | active、inactive 或 empty。 |
pet:<id>:name、description、max_level、xp_per_kill、default_mode、combat、texture | Pet Definition 的字段。 |
pet:<id>:owned | 对该玩家为 true 或 false。 |
pet:<id>:level、xp、next_xp、visibility、mode、damage | 玩家拥有的该宠物副本,未拥有时为空。 |
pet:<id>:status | active、inactive 或 unowned。 |
条目
6 个条目,由扩展源码生成。
动作3
- Pets Add XPGrant experience to a pet
- Pets Open MenuOpen the pet selection menu
- Pets StateChange the state of a pet
占位符1
- Pets PlaceholderExpose companion placeholders
构件1
- Pet StoragePersist companion data
清单1
- Pet DefinitionConfigure a companion pet
故障排查
重启后宠物丢失。 不存在 Pet Storage 构件,或者菜单动作没有 storage。日志会显示 "No pet_storage entry found. Companion data will not persist until one is created."
代币提示菜单已满。 该玩家菜单的每个槽位都已被占用或被锁定。请在 slots 中添加槽位,或授予被锁定槽位的权限。该消息是代币的 noSlotMessage。
“Ce familier est déjà présent dans ton menu.” 每位玩家对每只宠物只能拥有一份。他们不能为同一个定义使用第二个代币。
GROUND 或 FLY 宠物始终不出现。 日志会显示 "Unable to summon ground pet"。请在定义上设置 npc,或者至少为一个皮肤设置一个条件与玩家匹配的 npc。请检查该实体定义条目是否存在。
宠物不会升级。 宠物需要下一级的要求,可以是 levels 条目或 formula。无法求值的公式会被视为没有要求。请检查它是否只使用了数字、{level}、+ - * / 和括号。
/pets 没有输出任何内容。 请使用 /pets open。所有子命令都需要 typewriter.pets 加上各自的权限,而这些权限默认不会被授予。
某个皮肤显示为已锁定(“???”)。 它的 criteria 尚未匹配。请测试它所依赖的事实或任务。