Skip to content

伤害事件 API

EmakiAttributeDamageEvent 是一个 Bukkit 事件,在属性伤害计算完成后触发。外部插件可以监听此事件来拦截、修改或记录伤害。

事件类位于公开 API 模块 EmakiAttributeApi,全限定名 emaki.jiuwu.craft.attribute.api.EmakiAttributeDamageEvent;相关模型类 DamageContextDamageContextVariablesDamageResult 位于 emaki.jiuwu.craft.attribute.model

事件特性

  • 可取消(Cancellable):取消后不造成伤害。
  • 可修改最终伤害(setFinalDamage);设为小于等于 0 同样会抑制本次伤害。
  • 在伤害实际应用到目标之前触发。

方法列表

方法返回值说明
getAttacker()LivingEntity攻击者(可为 null,如环境伤害)。
getTarget()LivingEntity目标实体。
getProjectile()Projectile投射物;近战为 null。
getDamageTypeId()String伤害类型 ID(如 physicalspell)。
getBaseDamage()double基础伤害值(计算前)。
isCritical()boolean是否暴击。
getRoll()double暴击判定骰值。
getFinalDamage()double最终伤害值(经过所有阶段计算后)。
setFinalDamage(double)void修改最终伤害值。
getCause()DamageCauseBukkit 伤害原因。
getDamageContext()DamageContext完整伤害上下文。
getDamageResult()DamageResult完整计算结果(含各阶段 stageValues)。
getVariables()DamageContextVariables上下文控制变量。
getContext()Map<String, Object>上下文数据 Map。
isCancelled()boolean是否已取消。
setCancelled(boolean)void取消或恢复事件。

DamageResult 字段

DamageResult 是不可变 record,可通过 getDamageResult() 读取:

方法返回值说明
damageTypeId()String解析后的伤害类型 ID。
finalDamage()double管线计算出的最终伤害;构造时已截断为非负。
critical()boolean是否判定为暴击。
roll()double结算时使用的随机骰值。
stageValues()Map<String, Double>每个 stage id 对应的计算结果。
damageContext()DamageContext计算所依据的上下文。
variables()DamageContextVariables上下文携带的控制变量。
context()Map<String, Object>控制变量的普通 Map 形式。

DamageContextVariables 控制标志

DamageContextVariables 的 key 会被规范化,取布尔值时接受 true/falseyes/no1/0(不区分大小写)。下列标志由伤害结算与 MythicMobs 机制读取,括号内为等效别名:

标志默认值说明
allow_criticalcriticaltrue是否允许暴击判定。
allow_target_dodgetarget_dodgeallow_dodgedodgefalse是否允许目标闪避。
calculate_target_defensetarget_defensecalculate_defensedefensetrue是否计算目标防御。
trigger_mythic_on_damagedtrigger_on_damagedmythic_on_damagedfalse是否触发 MythicMobs 的 on_damaged 事件。

常用读取方法:get(key)string(key, fallback)doubleValue(key, fallback)getBoolean(fallback, keys...)contains(key)asMap()

只读战斗事实

下列变量由 Attribute 写入,供伤害阶段表达式与监听方读取,不作为控制开关:

变量说明
target_blocking目标本次是否构成有效举盾(含正面判定),10。仅在 shield.mode: attribute 下可能为 1,否则恒为 0。详见伤害系统的「盾牌格挡」。

监听示例

java
@EventHandler
public void onAttributeDamage(EmakiAttributeDamageEvent event) {
    // 减少 10% 最终伤害
    double finalDamage = event.getFinalDamage();
    event.setFinalDamage(finalDamage * 0.9);

    // 取消暴击伤害
    if (event.isCritical()) {
        event.setCancelled(true);
    }

    // 读取各阶段结果
    Map<String, Double> stages = event.getDamageResult().stageValues();
    double defenseReduction = stages.getOrDefault("target_defense", 0.0);
}

注意事项

  • 事件在伤害结算过程中于主线程触发。
  • setFinalDamage 设置的值会直接应用到目标,不再经过后续阶段计算。
  • 取消事件、或把最终伤害设为小于等于 0,都会让 EmakiAttribute 放弃本次伤害。
  • 投射物伤害(弓箭、三叉戟)也会触发此事件,可通过 getProjectile() 判断。