ToroHealth Damage Indicators
[!INFO] Git Commit:
845aa04| Updated: 2026-10-01
modid:torohealthmod(来自 ToroHealthMod.java:19
public static final String MODID = "torohealthmod";,并由 @Mod(modid = ToroHealthMod.MODID)
在 ToroHealthMod.java:12-16 引用)
显示名: gradle.properties 的 modName = ToroHealth Damage Indicators;
@Mod(name = Tags.MODNAME)(ToroHealthMod.java:14,值由 gradle token 注入)
mcmod.info 描述: “Displays damage indicators and health bars for all entities.”
网址: http://torocraft.net/
现状:纯客户端的伤害数字飘字,零方块 / 物品 / 实体
9 个 Java 文件里:
| 项目 | 数量 |
|---|---|
| 方块 / 物品 / 实体 / TileEntity | 0 / 0 / 0 / 0 |
| 指令 | 0 |
| 配置项 | 5(全在 CATEGORY_GENERAL) |
| 实体渲染的粒子类型 | 1(DamageParticles,一个 EntityFX 子类,不是注册的 EntityFX 实体 ID) |
| 服务端逻辑 | 0 |
⚠️ 描述与实现不符:没有血条
mcmod.info 写的是 “Displays damage indicators and health bars for all entities”,
但源码里不存在任何血条(health bar)渲染代码。DamageParticles.renderParticle
用的是 mc.fontRenderer.drawStringWithShadow 画纯数字(DamageParticles.java:117),
没有任何横向条形绘制、没有 RenderGameOverlayEvent 订阅、没有 GuiIngameMenu 之类挂钩。
唯一的事件订阅是 LivingEvent.LivingUpdateEvent(ToroHealthEventHandler.java:14-15)。
引用该描述会让人以为它能在实体头顶显示血量条——它做不到。
纯客户端 mod
- preInit 时若
Side.SERVER,只打一条日志说明"装在服务端没有意义,可以安全移除" (ToroHealthMod.java:26-30) - 唯一的 mixin(注入
EntityLivingBase血量快照)只在客户端加载 (MixinLoadingPlugin.getMixins里FMLLaunchHandler.side().isClient()判断,MixinLoadingPlugin.java:45-51) dependencies.gradle只有一个runtimeOnlyNonPublishable的 Waila(运行时非发布依赖, 仅用于开发期),没有真正的必需前置——ToroHealth 可以单独装
实现机制
不靠 Forge 事件拿伤害量,而是客户端自己逐 tick 快照血量再算差值:
- early mixin 给
EntityLivingBase注入两个@Unique字段torohealth$prevHealth/torohealth$prevMaxHealth,初值-1,并实现EntityLivingBaseExt接口暴露读写 (mixins/early/MixinEntityLivingBase.java:12-36、mixins/interfaces/EntityLivingBaseExt.java) LivingUpdateEvent(LOW优先级,仅isRemote)比较 floor 后的当前血量与快照, 不同则更新快照并用prevHealth - health作为伤害量生成粒子 (ToroHealthEventHandler.java:26-38)
这个设计有个刻意的排除逻辑(ToroHealthEventHandler.java:32-35):当最大血量也变了时
不生成粒子。源码注释点名这是为了跳过"外部 mod 在实体生成瞬间改血量"的情况,
举例是 EnderZoo 的 health modifier。
游戏内内容 / 机制列表
- 伤害数字粒子 - 12 tick 生命期、先放大后缩小的 3D 飘字,伤害红 / 回血绿,64 格外与遮挡时不生成
- 配置项 - 5 个 general 分类项;
Show Damage Particles通过注册/注销事件处理器实现热开关
本 mod 没有的内容(源码核实)
src/main/java 下 registerBlock、registerItem、registerEntity、registerTileEntity、
addCommand、keyBinding、Enchantment、Potion 各 0 命中;
src/main/resources 只有 3 个文件(mcmod.info + 两个 mixin json),无贴图 / 模型 / 语言文件。
mixins.torohealthmod.json与mixins.torohealthmod.early.json的mixins/client/server三个数组全为空(无package字段的常规版里package也未声明)。实际加载的 mixin 列表由MixinLoadingPlugin以编程方式给出, 走 GTNH 的IEarlyMixinLoader通道,不依赖 json 里的数组。
已知源码问题
- 描述宣称 health bars 但无实现(见上)。
ConfigurationHandler构造函数不保存 path:ConfigurationHandler.java:25-30只在config == null时才new Configuration(path);若 preInit 被触发两次(不会发生)第二次是空操作。 更实际的问题是eventHandler字段非final且只在showDamageParticles == true分支赋值 (ConfigurationHandler.java:41-45),首次进入false分支时unregister(null)不会被调用—— 这点是对的,但依赖了!= null判断,属隐式契约。- 颜色映射漏
WHITE(ConfigurationHandler.java:70-81),靠default兜底,见 配置项。 damage < 0判定与Math.abs显示组合有歧义:若某 tick 净效果恰好为 0 伤害,prevHealth - health == 0,会被判成damageColor(红)并显示数字0(DamageParticles.java:36-37)。源码未过滤damage == 0。- 距离阈值魔法数:
64D * 64D与25D无命名、无注释(DamageParticles.java:62、71), 且一个是"写成平方形式"、一个是"直接写平方",风格不一致,容易被后人误读成 64 格与 25 格。 mixins.torohealthmod.json缺package字段且数组全空,属 GTNH 项目模板残留, 实际不被使用。