显示规则
LyGemSoulRing 会从玩家配置的装备槽位中读取宝石 ID,再根据 plugins/LyGemSoulRing/soulring/ 目录中的魂环配置,创建绑定到玩家实体的 DragonCore 世界贴图。
插件不会发放魂环道具。只有装备物品中的宝石 ID 与魂环配置文件的顶层 ID 完全一致时,才能生成对应魂环。
生效条件
魂环显示需要满足以下条件:
- 服务器已安装并启用 DragonCore。插件只有检测到 DragonCore 已启用时,才会注册玩家加入、退出和按键监听器。
- 已安装实际使用的宝石插件,并且
gem-plugin与该宝石插件一致。 plugin-slot中的槽位格式正确,且对应的装备或背包插件可用。- 读取到的物品不为空,并且存在物品元数据。
- 物品中的宝石 ID 已在魂环配置文件中定义。
- 主配置和魂环 YAML 文件能够正常读取。
插件 plugin.yml 中声明的软依赖如下:
| 插件 | 用途 |
|---|---|
PlaceholderAPI | 处理显示和收回魂环时执行的指令变量 |
LyGemReload | 从装备物品中读取 LyGemReload 宝石 ID |
DragonCore 未在 plugin.yml 中声明为依赖,但魂环贴图、按键监听和玩家状态同步都直接使用 DragonCore API。未启用 DragonCore 时,这些功能不会注册。
代码还提供 YeeGem 宝石读取,以及多个装备插件的槽位读取方式。使用这些来源时,需要服务器安装对应插件并保证版本兼容。
魂环数据来源
插件重载时会递归扫描以下目录中的全部 .yml 文件:
text
plugins/LyGemSoulRing/soulring/子目录中的 .yml 文件也会被读取。每个文件的顶层键都会被当作一个宝石 ID,顶层键下的字段则作为对应魂环的世界贴图配置。
yaml
朱雀宝石:
path: '魂环/h2.png'
width: 3
height: 3
translateX: 0
translateY: 2.2
translateZ: 0
translateEntityFront: 0
translateEntityRight: 0
rotateX: 90
rotateY: 0
rotateZ: 0
through: false
distance: 64
alpha: 1
glow: true
followEntityDirection: false
animationList:
- 'ScaleAnimation'
- 'RotateAnimation'
- 'TranslateAnimation'只有装备中读取到的宝石 ID 与 朱雀宝石 完全一致时,才会使用这段配置。
载入魂环时,控制台会输出对应 ID。某个顶层 ID 读取失败时,插件会输出 载入失败 和异常信息,并继续处理其他配置。
如果不同文件定义了相同的顶层 ID,后读取的数据会覆盖内存中先读取的数据。文件实际读取顺序由运行环境返回的文件顺序决定,因此不应重复定义同一个魂环 ID。
玩家运行状态
玩家加入服务器时,插件会创建一份运行数据,其中包括:
- 当前是否已经展开魂环。
- 当前展开状态记录的魂环 ID 列表。
- 上一次尝试展开魂环的时间。
玩家的初始状态为隐藏。该状态只保存在运行内存中,退出服务器后会被移除,不会持久化保存。
如果 DragonCore 未启用,玩家加入监听器不会注册,玩家运行数据也不会创建。此时 /lgsr show 即使由玩家执行,也不会切换魂环状态。
展开与收回
玩家可以通过以下方式切换魂环状态:
| 触发方式 | 条件 | 行为 |
|---|---|---|
/lgsr show | 执行者是玩家,并且存在该玩家的运行数据 | 在展开与收回状态之间切换 |
| DragonCore 按键 | 松开的按键与 show-soulring-key 完全一致,并且存在玩家运行数据 | 在展开与收回状态之间切换 |
按键监听使用 DragonCore 的 KeyReleaseEvent,即松开按键时触发,不是按下按键时触发。
展开流程
玩家当前处于隐藏状态时,插件按以下顺序处理:
- 检查展开冷却。
- 将玩家状态设为展开,并记录本次展开时间。
- 从
plugin-slot配置的槽位中读取物品。 - 根据
gem-plugin提取所有宝石 ID。 - 保留存在对应魂环配置的宝石 ID。
- 如果没有匹配结果,将状态恢复为隐藏并发送无魂环提示。
- 如果存在匹配结果,记录魂环 ID,执行展开指令并发送世界贴图。
展开指令只会在至少找到一个有效魂环后执行。
收回流程
玩家当前处于展开状态时,插件会:
- 将玩家状态改为隐藏。
- 清空当前记录的魂环 ID。
- 从所有在线玩家客户端删除该玩家编号
0至19的魂环贴图。 - 删除当前版本带玩家 UUID 的贴图编号。
- 同时尝试删除旧版本不带玩家 UUID 的贴图编号。
- 执行
hide-soulring-command中的指令。
收回操作不检查冷却。
插件固定清理前 20 个贴图编号。如果把 max-soulring 设置为大于 20,序号 20 及以上的贴图不会被主动收回,因此不建议将最大显示数量设置到 20 以上。
装备变更行为
玩家展开魂环后,插件不会持续监听装备变化,也不会自动重新读取宝石。
这意味着:
- 更换装备不会自动替换已经展开的魂环。
- 取下装备不会自动收回已经展开的魂环。
- 修改物品中的宝石不会立即更新魂环。
- 需要先再次触发按键或执行
/lgsr show收回魂环,然后重新触发才能按新装备读取。
槽位读取顺序
plugin-slot 是一个字符串列表。插件会按照配置顺序逐个读取槽位:
yaml
plugin-slot:
- 'Origin#MainHand'
- 'Origin#Helmet'
- 'LyInventoryReload#饰品#项链'每个槽位最多返回一个装备物品,但一个物品可以提供多个宝石 ID。插件会把所有槽位中读取到的宝石 ID依次加入同一个列表。
以下情况会跳过当前槽位:
- 槽位配置为
null或空字符串。 - 对应槽位没有物品。
- 物品没有物品元数据。
- 对应装备插件没有返回可用物品。
当前代码同时兼容旧版单字符串写法:当 plugin-slot 无法读取到列表内容时,会再次尝试把它作为单个字符串读取。不过仍建议使用列表格式。
槽位字符串会使用 # 分割。必须按对应类型填写足够的参数,否则可能发生数组越界、数字转换失败或插件 API 调用异常。
支持的槽位格式
| 类型 | 格式 | 读取位置 |
|---|---|---|
| DragonCore | DragonCore#槽位名 | DragonCore 缓存槽位 |
| GermPlugin | GermPlugin#槽位标识 | GermPlugin 身份槽位 |
| LyInventory | LyInventory#背包文件#槽位 | LyInventory 背包中的指定槽位 |
| LyInventoryReload | LyInventoryReload#背包ID#类型 | LyInventoryReload 背包中的指定槽位 |
| YeeJewelry | YeeJewelry#背包ID#槽位ID | YeeJewelry 饰品背包槽位 |
| Minecraft | Minecraft#槽位ID | 原版玩家背包中的指定槽位 |
| Origin | Origin#MainHand | 玩家主手 |
| Origin | Origin#OffHand | 玩家副手 |
| Origin | Origin#Helmet | 玩家头盔槽位 |
| Origin | Origin#ChestPlate | 玩家胸甲槽位 |
| Origin | Origin#Legging | 玩家护腿槽位 |
| Origin | Origin#Boots | 玩家靴子槽位 |
Minecraft#槽位ID 会把槽位参数转换为整数,再调用原版背包槽位读取方法。默认配置注释约定使用 0 至 35。
槽位类型不区分大小写。Origin 的槽位名称同样使用不区分大小写的比较,但建议保持表格中的标准写法。
宝石 ID 读取
gem-plugin 决定如何从每件装备中提取宝石 ID:
yaml
gem-plugin: 'LyGemReload'| 配置值 | 读取行为 |
|---|---|
LyGemReload | 调用 LyGemReload API,读取物品中的全部宝石 ID |
YeeGem | 调用 YeeGem API 读取宝石数据,再从每个宝石数据中提取 gemId |
配置值使用不区分大小写的比较。
如果填写其他值,插件仍会读取槽位物品,但不会从物品中提取任何宝石 ID,最终会按“没有魂环”处理。
重复宝石
当前实现不会去重宝石 ID。
同一个宝石 ID 在以下情况下可能重复进入显示列表:
- 同一件装备包含多个相同 ID 的宝石。
- 不同槽位装备了相同 ID 的宝石。
- 不同物品读取出了相同 ID。
每次匹配都会作为一个独立魂环参与排序、缩放和数量限制。因此,相同的魂环配置可以被显示多次。
无匹配宝石
以下情况都会导致本次没有有效魂环:
- 所有配置槽位都为空。
- 读取到的物品没有宝石。
gem-plugin不受支持。- 宝石 ID 没有在
soulring目录中定义。 - 对应宝石插件没有返回有效 ID。
没有有效魂环时,插件会恢复隐藏状态、清空魂环列表,并向玩家发送:
text
你没有魂环!本次尝试仍然会更新上一次展开时间。因此,即使因为没有匹配宝石而展开失败,玩家紧接着再次尝试时也可能受到展开冷却限制。
显示数量
max-soulring 控制单个玩家发送的最大魂环数量:
yaml
max-soulring: 10实际显示数量取决于:
- 所有槽位中读取到的宝石总数。
- 宝石 ID 是否存在对应魂环配置。
- 重复宝石 ID 的数量。
max-soulring的限制。
魂环按照槽位顺序和宝石插件返回的 ID 顺序排列。序号从 0 开始,并在达到 max-soulring 时停止发送。
玩家运行数据会记录全部匹配成功的魂环 ID,不会先按 max-soulring 截断;发送贴图以及向新加入玩家同步时才应用数量限制。
贴图编号
每个魂环使用以下格式生成客户端贴图编号:
text
插件名_玩家UUID_魂环序号玩家 UUID 会区分不同玩家,魂环序号会区分同一玩家的不同魂环,避免广播贴图时互相覆盖。
收回或退出时,插件还会清理旧版格式:
text
插件名_魂环序号旧版编号不含玩家 UUID,只用于兼容清理旧版本可能残留的贴图。
多层魂环尺寸
soulring-scale 控制后续魂环相对于自身基础尺寸的递增量:
yaml
soulring-scale: 4计算方式如下:
text
实际宽度 = 配置宽度 + 魂环序号 × soulring-scale
实际高度 = 配置高度 + 魂环序号 × soulring-scale假设魂环配置中的 width 和 height 都是 3,soulring-scale 为 4:
| 魂环顺序 | 序号 | 实际宽度 | 实际高度 |
|---|---|---|---|
| 第一个 | 0 | 3 | 3 |
| 第二个 | 1 | 7 | 7 |
| 第三个 | 2 | 11 | 11 |
尺寸是在每个魂环自身配置的 width 和 height 基础上计算,不要求不同魂环使用相同基础尺寸。
显示延迟的实际行为
show-soulring-delay 会作为 Bukkit 定时任务的周期参数:
yaml
show-soulring-delay: 5单位为服务器 tick。
当前版本在创建定时任务之前,已经通过普通循环立即向所有在线玩家发送了一遍全部有效魂环。随后定时任务又会从第一个魂环开始,按照 show-soulring-delay 重复发送相同编号的贴图。
由于重复发送时使用相同贴图编号,后一次数据通常会覆盖前一次数据。按照当前代码,show-soulring-delay 不能实现“魂环从无到有逐圈出现”的效果,只会在首次全部显示后再次分批刷新相同贴图。
定时任务会在以下任一条件满足时停止:
- 已处理全部匹配魂环。
- 当前序号达到
max-soulring。 - 玩家对象为空。
- 玩家已经离线。
任务启动延迟固定为 0 tick,执行周期使用 show-soulring-delay。该配置应填写能够作为 Bukkit 调度周期使用的正整数。
冷却机制
show-soulring-cooldown 控制从隐藏状态尝试展开魂环的冷却时间,单位为毫秒:
yaml
show-soulring-cooldown: 10000冷却只在玩家当前处于隐藏状态、准备展开魂环时检查。收回魂环不受冷却限制。
当剩余冷却时间大于零时,插件不会:
- 重新读取装备槽位。
- 重新读取宝石 ID。
- 执行展开指令。
- 创建或发送魂环贴图。
提示由 show-soulring-cooldown-message 控制:
yaml
show-soulring-cooldown-message: '&c魂环绽放冷却中,还需{time}秒!'{time} 会替换为剩余秒数,并保留一位小数。
该消息通过 Bukkit 的 sendMessage 直接发送,代码没有把 & 颜色符号转换为 §。因此配置中的 &c 是否能显示为颜色取决于服务器其他处理;仅按当前插件代码,它不会主动转换颜色代码。
显示与收回指令
成功匹配到魂环后,插件会执行 show-soulring-command:
yaml
show-soulring-command:
- '[console]tell %player_name% 你释放了魂环'主动收回魂环时,插件会执行 hide-soulring-command:
yaml
hide-soulring-command:
- '[console]tell %player_name% 你收回了魂环'每个列表元素代表一条完整指令。执行前会调用 PlaceholderAPI 处理玩家变量。
| 标记 | 执行身份 | 处理方式 |
|---|---|---|
[console] | 控制台 | 删除标记后由控制台执行 |
[op] | 玩家临时 OP | 删除标记后以玩家身份执行,结束后恢复原 OP 状态 |
| 无标记 | 玩家 | 直接以玩家身份执行 |
标记检测使用字符串包含判断,并不是只检查指令开头。建议仍将标记放在指令最前方。
如果同一条指令同时包含 [op] 和 [console],代码会优先进入 [op] 分支,不会再按控制台指令处理。
展开指令在发送魂环贴图之前执行。收回指令在删除魂环贴图之后执行。
PlaceholderAPI 在代码中被直接调用。若配置了显示或收回指令,应安装并启用 PlaceholderAPI。
按键设置
show-soulring-key 设置切换魂环状态的 DragonCore 按键:
yaml
show-soulring-key: 'Z'插件每次重载时都会调用 DragonCore API 注册该键位,并在控制台输出注册成功或失败信息。
玩家松开按键后,插件会把事件中的键名与配置值进行区分大小写的完全比较:
text
事件键名.equals(配置键名)因此建议按 DragonCore 实际返回的标准大写键名填写,例如 Z。
配置为空或键名无法注册时,可以改用 /lgsr show 切换状态。
世界贴图创建
每个有效魂环都会创建一个新的 DragonCore WorldTexture,并绑定到展开魂环的玩家 UUID:
text
WorldTexture.entity = 玩家UUID随后插件根据魂环配置应用字段,再按照魂环序号修改 width 和 height。
贴图会发送给当前所有在线玩家,因此其他玩家也能看到展开者的魂环。贴图不是只发送给展开魂环的玩家本人。
世界贴图字段映射
除 animationList 外,魂环配置键会按照字段名反射查找 DragonCore WorldTexture 中的同名声明字段。
映射规则如下:
- 字段名称必须完全一致,包括大小写。
- 只查找
WorldTexture类自身声明的字段。 - 不存在的字段会被忽略。
- 无法转换为目标字段类型的值会被忽略。
- 字段赋值失败时会跳过该字段。
当前转换逻辑支持以下目标类型:
| 类型 | 转换方式 |
|---|---|
int / Integer | 转换为整数 |
long / Long | 转换为长整数 |
float / Float | 转换为浮点数 |
double / Double | 转换为双精度浮点数 |
boolean / Boolean | 转换为布尔值 |
UUID | 按 UUID 字符串解析 |
String | 使用文本值 |
示例配置中已确认使用的世界贴图属性如下:
| 配置键 | 值类型 | 作用 |
|---|---|---|
path | 字符串 | 魂环贴图路径 |
width | 数值 | 基础宽度 |
height | 数值 | 基础高度 |
translateX | 数值 | X 轴坐标偏移 |
translateY | 数值 | Y 轴坐标偏移 |
translateZ | 数值 | Z 轴坐标偏移 |
translateEntityFront | 数值 | 相对实体前后方向的偏移 |
translateEntityRight | 数值 | 相对实体左右方向的偏移 |
rotateX | 数值 | X 轴旋转角度 |
rotateY | 数值 | Y 轴旋转角度 |
rotateZ | 数值 | Z 轴旋转角度 |
through | 布尔值 | 是否穿透地形 |
distance | 数值 | 贴图显示距离 |
alpha | 数值 | 贴图透明度 |
glow | 布尔值 | 是否发光 |
followEntityDirection | 布尔值 | 是否跟随玩家视角方向旋转 |
animationList | 字符串列表 | 应用到贴图的动画列表 |
简化的魂环配置可以只填写需要覆盖的字段:
yaml
白虎宝石:
path: '魂环/h3.png'
width: 3
height: 3
translateY: 2.2
rotateX: 90
rotateY: 0
rotateZ: 0
animationList:
- 'ScaleAnimation'
- 'RotateAnimation'
- 'TranslateAnimation'没有填写的属性会保留 DragonCore WorldTexture 创建后的默认值。
动画选择
魂环通过 animationList 选择动画:
yaml
animationList:
- 'ScaleAnimation'
- 'RotateAnimation'
- 'TranslateAnimation'支持的名称如下:
| 名称 | 动画类型 | 固定方向 |
|---|---|---|
ScaleAnimation | 缩放动画 | 无方向参数 |
RotateAnimation | 旋转动画 | z |
TranslateAnimation | 位移动画 | z |
动画名称使用不区分大小写的比较。无法识别的动画名称会被忽略,不会加入世界贴图的动画列表。
多个魂环会复用重载时创建的同一组动画配置对象。动画参数统一从主配置读取,不能在单个魂环文件中分别设置不同参数。
旋转动画
yaml
RotateAnimation:
delay: 1000
angle: 360.0
duration: 3000
cycleCount: 1
fixed: true
resetTime: 1| 配置键 | 类型 | 代码默认值 | 作用 |
|---|---|---|---|
delay | 整数 | 0 | 动画延迟 |
angle | 数值 | 360 | 旋转角度 |
duration | 整数 | 6000 | 动画持续时间 |
cycleCount | 整数 | 1 | 循环次数 |
fixed | 布尔值 | true | 是否固定动画效果 |
resetTime | 整数 | 1 | 动画重置参数 |
旋转方向由插件固定为 z,没有对应的方向配置键。
位移动画
yaml
TranslateAnimation:
delay: 0
distance: 2
duration: 1000
cycleCount: 1
fixed: true| 配置键 | 类型 | 代码默认值 | 作用 |
|---|---|---|---|
delay | 整数 | 0 | 动画延迟 |
distance | 数值 | 1.1 | 位移距离 |
duration | 整数 | 3000 | 动画持续时间 |
cycleCount | 整数 | 1 | 循环次数 |
fixed | 布尔值 | true | 是否固定动画效果 |
位移方向由插件固定为 z。默认配置将该动画描述为上下动画,实际方向值由代码设置为 z。
缩放动画
yaml
ScaleAnimation:
delay: 0
cycleCount: 1
fixed: false
fromScale: 10.0
toScale: 1.0
duration: 1000| 配置键 | 类型 | 代码默认值 | 作用 |
|---|---|---|---|
delay | 整数 | 0 | 动画延迟 |
cycleCount | 整数 | 1 | 循环次数 |
fixed | 布尔值 | false | 是否固定动画效果 |
fromScale | 数值 | 3.0 | 初始缩放值 |
toScale | 数值 | 1.0 | 目标缩放值 |
duration | 整数 | 3000 | 动画持续时间 |
表格中的代码默认值只会在对应配置键缺失时使用。插件自带 config.yml 已为这些字段提供另一组默认配置文件值。
多人可见与加入同步
玩家展开魂环时,每个世界贴图都会发送给当时所有在线玩家。
新玩家加入服务器后,插件会遍历内存中的玩家运行数据,把其他玩家当前处于展开状态的魂环发送给新玩家。同步时会:
- 重新根据魂环 ID 查找当前内存中的魂环配置。
- 重新创建世界贴图。
- 保持原有魂环序号和尺寸递增效果。
- 应用当前
max-soulring数量限制。 - 只发送给刚加入的玩家。
如果记录中的某个魂环 ID 在当前内存配置中已经不存在,该魂环会被跳过。
退出清理
玩家退出服务器时,插件会:
- 从运行数据表中移除该玩家。
- 向仍在线的所有玩家发送贴图删除请求。
- 清理该玩家编号
0至19的当前版和旧版贴图编号。
玩家下次加入时会重新创建隐藏状态的数据,不会自动恢复退出前展开的魂环。
重载行为
执行 /lgsr reload 后,插件会:
- 确保默认
config.yml存在。 - 重新读取主配置。
- 确保默认的
soulring/示例魂环.yml存在,但不会覆盖已有文件。 - 重新创建三种动画数据。
- 清空内存中的魂环配置。
- 递归扫描并重新载入全部魂环 YAML。
- 重新注册
show-soulring-key配置的 DragonCore 按键。
重载不会清空玩家运行数据,也不会主动删除或重建已经发送到客户端的魂环贴图。
因此,玩家已经展开的贴图不会立刻应用新配置。需要玩家先收回,再重新展开。新加入玩家的同步贴图会根据重载后的魂环配置重新创建。
指令与权限行为
插件只注册一个根指令:
text
/lgsrplugin.yml 没有声明独立权限节点。权限由代码直接判断执行者是否为 OP 或玩家。
| 指令 | 执行条件 | 作用 |
|---|---|---|
/lgsr | 执行者是 OP | 显示插件帮助 |
/lgsr reload | 执行者是 OP | 重载主配置、动画、魂环文件和按键 |
/lgsr show | 执行者是玩家,且玩家运行数据已经建立 | 展开或收回自己的魂环 |
/lgsr show 不要求玩家是 OP。控制台不能使用该子指令,因为代码只处理玩家执行者。
没有满足条件时,指令不会发送无权限提示或用法提示。
Tab 补全只会向 OP 提供 reload。虽然 /lgsr show 可以由普通玩家执行,但当前补全器不会向普通玩家或 OP 提供 show 补全。
相关配置文件
| 文件 | 作用 |
|---|---|
plugins/LyGemSoulRing/config.yml | 宝石来源、装备槽位、按键、冷却、执行指令、显示数量、尺寸递增、显示周期和动画参数 |
plugins/LyGemSoulRing/soulring/*.yml | 宝石 ID 对应的魂环贴图字段和动画列表 |
修改这些文件后,使用以下指令重新载入:
text
/lgsr reload重载指令必须由 OP 执行。