
`in_fire`表示实体正身处火中(如站在火块上)所受的持续性环境火伤,`on_fire`则表示实体自身已着火(如被火焰箭点燃)产生的燃烧伤害;二者语义不同,直接影响死亡消息、伤害计算与事件触发逻辑。
在Minecraft 1.19(及后续版本)的官方反编译源码(如MCP或Yarn映射)中,net.minecraft.world.damagesource.DamageSource 类定义了多个静态常量来区分不同来源的伤害。其中 IN_FIRE 和 ON_FIRE 表面相似,但设计意图和使用场景截然不同:
public static final DamageSource IN_FIRE = (new DamageSource("inFire")).bypassArmor().setIsFire();
public static final DamageSource ON_FIRE = (new DamageSource("onFire")).bypassArmor().setIsFire();虽然二者均调用 .bypassArmor()(无视护甲减免)和 .setIsFire()(标记为火属性伤害),但核心差异在于伤害触发条件与状态语义:
IN_FIRE:代表环境性火伤,即实体处于可造成火伤的方块中(如火、熔岩、营火、烛火等)。它不依赖实体是否“着火”,而是由位置决定。例如玩家站在火堆中每秒受到 IN_FIRE 伤害,即使其未被点燃(isOnFire() 返回 false)。
ON_FIRE:代表状态性燃烧伤害,源自实体自身的 fireTicks > 0 状态(即 Entity#isOnFire() 为 true)。该伤害由实体每刻主动施加,与所处位置无关——哪怕玩家在水中燃烧(通过命令或Mod实现),其持续掉血仍使用 ON_FIRE。
这一区分直接支撑了游戏关键机制:
-
死亡消息精准化:
- "Player was burnt to a crisp" → 来自 IN_FIRE(死于环境火)
- "Player went up in flames" → 来自 ON_FIRE(死于自身燃烧)
源码中 DamageSource#getDeathMessage(LivingEntity) 方法依据 this == IN_FIRE 或 this == ON_FIRE 返回不同本地化字符串。
事件与模组兼容性:
Forge/Fabric 的 LivingHurtEvent 或 AttackEntityEvent 可通过 damageSource == DamageSource.IN_FIRE 精确拦截环境火伤,而不干扰玩家被烈焰人喷火(ON_FIRE)等逻辑。伤害叠加与免疫逻辑:
某些效果(如防火药水)仅对 ON_FIRE 状态生效(清除 fireTicks),但无法减免 IN_FIRE 的环境伤害;反之,站在防火方块(如灵魂沙+营火)可能规避 IN_FIRE,却无法阻止 ON_FIRE 的持续燃烧。
✅ 开发建议:
- 在自定义伤害逻辑中,优先使用 DamageSource.IN_FIRE 表示“接触火源”,用 DamageSource.ON_FIRE 表示“已点燃状态”;
- 切勿因二者均含 setIsFire() 而混用——语义错误将导致死亡消息错乱、事件监听失效或模组兼容问题;
- 可通过 entity.hurt(DamageSource.IN_FIRE, amount) 主动施加环境火伤,而 entity.setSecondsOnFire(10) 则会间接触发 ON_FIRE 伤害循环。
总之,IN_FIRE 与 ON_FIRE 是Minecraft伤害系统中“位置驱动”与“状态驱动”两种火伤范式的精确建模,体现了源码设计对游戏表现力与扩展性的深层考量。









