为 Minecraft 实体注入独立于原版血量的虚拟血量系统,自动映射到 Bossbar。支持 auto_init(/summon 直接带 NBT)、高频 tick 伤害检测、自定义死亡回调、百分比血量判定、无敌控制、伤害倍率与余数精度补偿。
🤖 本项目由 Deepseek AI 协助开发与调试 — 代码审查、bug 修复、文档撰写均由 AI 辅助完成。当前为社区早期版本,亟待更多玩家测试,欢迎反馈:Issues
/summon minecraft:zombie ~ ~ ~ {
data:{dvh:{max_health:40d, health:40d, on_death:"say died"}},
NoAI:1b
}
第一 tick 自动初始化,无需任何命令调用。
/execute as @n run \
function doom.virtual.health:api/create {with:{max_health:21.5, health:20}}
/execute as @e[tag=virtual_health_entity] run \
function doom.bossbar:api/create {with:{name:'"Boss"',color:red,style:progress,visible:"true",targets:"@a"}}
# 扣 500 mHP(= 0.5 HP)
/execute as @e[tag=virtual_health_entity] run \
function doom.virtual.health:api/add_health {points:-500}
# 无敌
/execute as @e[tag=virtual_health_entity] run \
function doom.virtual.health:api/set_invulnerable {state:1b}
精度:0.001 HP(mHP)。余数补偿保证长期累计不丢失。
| 倍率 | 效果 |
|---|---|
| 200 | 20% 伤害(等效原 Resistance IV) |
| 500 | 50% 伤害 |
| 1000 | 100% 伤害(默认) |
| 2000 | 200% 伤害(易伤) |
| 函数 | 参数 | 说明 |
|---|---|---|
| api/create | {with:{max_health, health, on_death?}} | 注册虚拟血量(重复调用 return fail) |
| api/remove | {with:{kill:1b/0b}} | 移除虚拟血量,kill:1b 同时杀死实体(默认 1b) |
| api/add_health | {points:int} | 加减血量,正=治疗 / 负=伤害(HP 单位,支持小数) |
| api/add_health_pct | {pct:int} | 按最大血量百分比加减(±100 范围) |
| api/set_health | {health:int} | 强制设定血量(HP 单位,≤0 触发死亡) |
| api/set_health_pct | {pct:int} | 按最大血量百分比设定([0,100]) |
| api/set_max_health | {max_health:int} | 设定最大血量(HP 单位,下限 1 HP) |
| api/add_max_health | {points:int} | 增加最大血量(HP 单位) |
| api/add_max_health_pct | {pct:int} | 按最大血量百分比增加 |
| api/get_health | (store result) | 当前血量(HP,÷1000) |
| api/get_health_mhp | (store result) | 当前血量(mHP 原始值) |
| api/get_max_health | (store result) | 最大血量(HP) |
| api/get_max_health_mhp | (store result) | 最大血量(mHP) |
| api/get_percentage | (store result) | 当前血量百分比 [0,100] |
| api/get_total_damage | (store result) | 累计受伤 (mHP) |
| api/get_total_healing | (store result) | 累计治疗 (mHP) |
| api/get_player_damage | (store result) | 玩家造成的累计伤害 (mHP) |
| api/get_stats | {damage_out, healing_out, scale} | 统计写入两个计分板并除以 scale |
| api/set_invulnerable | {state:1b/0b} | 设置无敌状态 |
| api/set_damage_mult | {mult:int} | 伤害倍率(×1000,范围 [1,100000]) |
| api/apply_trigger | 无 | 按实体类型分配 vitality 触发器槽位 |
| api/debug | 无 | 打印调试信息 |
| debug | 无 | 详细调试(含 bossbar/on_death) |
| dvhentity | {target} | 向指定玩家打印实体状态 |
所有 API 以 @s 为 VH 实体执行,非 VH 实体 return fail。单位:points/health/max_health 均为 HP(内部 ×1000 转 mHP,支持小数如 points:-0.5)。
| 函数 | 参数 | 说明 |
|---|---|---|
| api/create | {with:{...}} | 创建血条(重复调用 return fail) |
| api/remove | 无 | 移除血条 |
| api/sync_dvh | 无 | 手动同步血量到 Bossbar(tick 自动调用) |
| 参数 | 类型 | 默认 | 说明 |
|---|---|---|---|
| id | string | 自动生成 | Bossbar 标识 |
| name | string (JSON) | "Boss" | 血条显示文本 |
| color | string | "white" | 颜色 |
| style | string | "progress" | 样式 |
| visible | string | "true" | 可见性 |
| targets | string | "@a" | 可见玩家选择器 |
| persist | bool | false | 实体死亡后是否保留血条 |
| 函数 | 判定条件(return 1 = 成立) |
|---|---|
| predicate/is_invulnerable | 实体处于无敌状态 |
| predicate/below_percentage | 血量百分比 < @s dvh.pp |
| predicate/above_percentage | 血量百分比 > @s dvh.pp |
| predicate/between_percentage | 血量在 @s dvh.pp ~ @s dvh.pp_max 之间 |
| predicate/below_hp | 血量 < #dvh.hp_threshold(HP 伪全局) |
| predicate/above_hp | 血量 > #dvh.hp_threshold |
| predicate/between_hp | 血量在 #dvh.hp_threshold_low ~ #dvh.hp_threshold_high |
# 血量低于 30% 时触发
scoreboard players set @e[tag=virtual_health_entity] dvh.pp 30
execute as @e[tag=virtual_health_entity] if function \
doom.virtual.health:api/predicate/below_percentage run say low HP!
触发时机:dvh.health 降至 0(trigger_death)时执行。
用法:on_death 是任意命令字符串,以 VH 实体位置执行:
/execute as @e[tag=virtual_health_entity] run \
function doom.virtual.health:api/create {with:{max_health:100, health:100, on_death:"say I died"}}
或 auto_init 时:
/summon minecraft:zombie ~ ~ ~ {
data:{dvh:{max_health:100d, health:100d, on_death:"function mypack:boss_death"}},
NoAI:1b
}
execute at @s run <on_death 命令>,@s 是 VH 实体@s[tag=virtual_health_entity](选择器在回调时已失效),直接用 @s# 广播死亡消息
on_death: "say A VH entity has died"
# 调用自定义处理函数
on_death: "function mypack:boss_killed"
# 播放音效(以实体位置)
on_death: "playsound minecraft:entity.wither.death master @a ~ ~ ~ 1 1"
# 生成掉落物
on_death: "summon minecraft:item ~ ~ ~ {Item:{id:\"minecraft:diamond\",Count:1b}}"
/summon 时实体携带 data:{dvh:{...}},第一 tick 自动完成 create + apply_trigger:
/summon minecraft:zombie ~ ~ ~ {
data:{dvh:{max_health:"2000", health:"2000"}},
NoAI:1b
}
max_health / health / on_deathdata:{dvh:{ 处提示vitality 附魔挂在实体装备上,由附魔 tick 驱动装备加成同步,替代纯命令轮询。
enchantment/vitality.json(槽位:saddle、mainhand)注意:修改 enchantment JSON 需要重启服务器(/reload 无效)。
# 读取 HP(÷1000)
execute store result score #hp obj run function api/get_health
# #hp = 2000
# 读取 mHP(原始精度)
execute store result score #hp_mhp obj run function api/get_health_mhp
# #hp_mhp = 2000000
# 读取百分比 [0,100]
execute store result score #pct obj run function api/get_percentage
# #pct = 63
# 统计(写两个计分板并 scale)
execute as @e[tag=virtual_health_entity] run \
function doom.virtual.health:api/get_stats {damage_out:"#dmg", healing_out:"#heal", scale:1000}
| 计分板 | 类型 | 说明 |
|---|---|---|
| dvh.health | 实体 | 当前虚拟血量 (mHP) |
| dvh.max_health | 实体 | 最大虚拟血量 (mHP) |
| dvh.total_damage | 实体 | 累计受伤 (mHP) |
| dvh.total_healing | 实体 | 累计治疗 (mHP) |
| dvh.player_damage | 实体 | 玩家造成的伤害 (mHP) |
| dvh.rem_damage | 实体 | 伤害余数(进位补偿) |
| dvh.rem_heal | 实体 | 治疗余数 |
| dvh.pp | 实体 | 百分比阈值(下界)[0,100] |
| dvh.pp_max | 实体 | 百分比阈值(上界)[0,100] |
| dvh.prev_hp | 实体 | 上一 tick 血量探针 (×2200) |
| dvh.damage_mult | 实体 | 伤害倍率(×1000,默认 1000) |
| dvh.saddle_bonus | 实体 | 装备加成缓存 |
| dvh.temp | #虚拟 | 内部临时计算 |
| dbb.temp | #虚拟 | bossbar 临时标识 |
| 标签 | 说明 |
|---|---|
| virtual_health_entity | VH 实体标识 |
| dvh.invulnerable | 无敌状态 |
| dbb.has_bossbar | 已绑定血条 |
datapacks/ 文件夹/reload 加载数据包[DVH] Virtual Health System Loaded. 即成功亟待更多玩家测试:以下为代码审查中识别出的边界情况,部分已在设计中规避,部分受原版机制限制。
| # | 场景 | 表现 | 规避 |
|---|---|---|---|
| E1 | auto_init 的 NBT 用 double(40d) | 旧版宏展开 40.0 报错 | 已修复为 data get 版(兼容 double/int/string) |
| E2 | get_percentage 血量 < 1 HP | 整数除法可能显示 0% | 低血量用 get_health_mhp 精确读取 |
| E3 | scale 参数为 0 | 除零报错 | scale:1(mHP)或 scale:1000(HP) |
| E4 | add_health 大量治疗 | 钳制到 max_health | 已内置 #max_safe 溢出保护 |
| E5 | damage_mult 过大 | 数值溢出 | 已内置上限 100000 |
| # | 场景 | 表现 |
|---|---|---|
| E6 | 单 tick 超大数据伤害(/damage 999999) | Health 探针单次最多检测 512 HP,超出截断 |
| E7 | 治疗 Health 探针上限 1024 | 单次最多补 512 HP |
| E8 | 实体在未加载区块 | tick 检测暂停,血量不变 |
| E9 | damage_mult 极小时 | 向下取整后单次伤害可能为 0 |
| E10 | kill 命令直接杀死(绕过 VH) | on_death 不触发 |
| E11 | 原版 Regeneration/饱和回复 | Health 上升被识别为 VH 治疗 |
| E12 | 玩家实体 | 支持,但死亡掉落为原版行为 |
| # | 场景 | 表现 |
|---|---|---|
| E13 | on_death 命令含复杂引号/宏 | 宏展开可能破坏引号嵌套 |
| E14 | 多实体同一 tick 死亡 | 全局 storage 同步执行,无并发问题 |
| E15 | remove 后立刻 create | 需等 1 tick(NBT 写入延迟) |
| E16 | bossbar name 传 JSON 数组 | 嵌套引号可能失败,建议单 JSON 对象 |
kill 参数默认 {kill:1b},移除时会杀死实体;不想杀用 {kill:0b}on_death 回调不要写 @s[tag=virtual_health_entity](选择器已失效),直接用 @sadd_health {points:负数} 对无敌实体无效;set_health 不受无敌影响api/create 重复调用 return failscale:1 = mHP,scale:1000 = HP