Minecraft源码中IN_FIRE与ON_FIRE伤害源的本质区别解析

2026-01-29 00:00:00 作者:心靈之曲

在minecraft 1.19源码中,`damagesource.in_fire`与`damagesource.on_fire`虽同为火系伤害源且均绕过护甲、标记为火焰类型,但语义与触发场景截然不同:前者表示实体**处于火焰方块中**(如站在火堆里),后者表示实体**自身正在燃烧**(如被火把点燃后持续掉血)。

这两个常量定义于 net.minecraft.world.damagesource.DamageSource 类中:

public static final DamageSource IN_FIRE = (new DamageSource("inFire")).bypassArmor().setIsFire();
public static final DamageSource ON_FIRE = (new DamageSource("onFire")).bypassArmor().setIsFire();

表面上看,二者行为高度相似——都调用 .bypassArmor()(无视护甲减免)和 .setIsFire()(启用火焰相关逻辑,如对凋灵造成伤害、触发防火药水效果等)。但其设计核心在于语义分离与上下文精确性,这是Minecraft死亡消息系统、成就判定及模组兼容性的关键基础。

✅ 实际使用场景差异

  • IN_FIRE:用于实体直接接触火焰方块(Fire Block)或熔岩时的即时伤害。
    例如:玩家跳入火堆、僵尸卡在燃烧的草方块中、掉落进岩浆池边缘的火焰层。该伤害每秒触发一次,且仅当实体的碰撞箱完全或部分位于火焰方块内时生效

  • ON_FIRE:用于实体已被点燃(setOnFireFor(int ticks))后,每刻(20 ticks/秒)持续承受的燃烧伤害
    例如:被烈焰人火球击中、手持打火石点燃自己、受“着火”状态效果影响。此伤害独立于环境方块,即使玩家瞬移出火堆,只要燃烧倒计时未结束,ON_FIRE 仍会持续造成伤害。

? 验证依据:死亡消息与日志表现

Minecraft通过 DamageSource.getLocalizedDeathMessage(LivingEntity) 方法生成死亡提示,而 IN_FIRE 与 ON_FIRE 对应不同本地化键:

  • inFire → "death.attack.inFire" → "Player was burnt to a crisp"`
  • onFire → "death.attack.onFire" → "Player went up in flames"`

你可以在 en_us.json 资源文件中查到这两条独立翻译,证实它们面向不同事件语义。若合并为同一 DamageSource,则无法实现精准死亡反馈——比如“在火里烤焦”和“自燃成灰”在游戏叙事中具有明确区分。

⚠️ 注意事项与开发建议

  • 模组开发中切勿混用:若你的模组添加自定义火焰伤害逻辑,请根据实际触发条件选择对应 DamageSource。误用 ON_FIRE 替代 IN_FIRE 可能导致死亡消息错误,或与防火药水、抗火附魔等机制产生意外交互。
  • 服务端同步安全:二者均为 public static final 常量,在多线程环境下安全共享,无需额外同步。
  • 扩展性考量:MCP(Mod Coder Pack)或Yarn映射中,此类命名规范(inXxx vs onXxx)是Mojang惯用模式,类似还有 IN_WALL / WALL(挤压伤害)、FALLING_BLOCK / FALLING_ANVIL(下落物细分)等,体现其精细化伤害建模哲学。

简言之,IN_FIRE 是环境致害,ON_FIRE 是状态致害;名称差异不是冗余,而是Minecraft底层伤害系统语义严谨性的直接体现。理解这一点,是读懂原版逻辑、编写健壮模组的基础。

猜你喜欢

联络方式:

400 9058 355

邮箱:8955556@qq.com

Q Q:8955556

微信二维码
在线咨询 拨打电话

电话

400 9058 355

微信二维码

微信二维码