Skip to content

伤害事件 API ​

EmakiAttributeDamageEvent 是可取消的 Bukkit 事件, 在属性伤害计算完成后, 实际应用到目标之前于主线程同步触发. 监听方可在回调内拦截, 修改或记录伤害

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

事件特性 ​

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

方法列表 ​

方法返回值说明
getAttacker()LivingEntity攻击者 (可为 null, 如环境伤害)
getTarget()LivingEntity目标实体
getProjectile()Projectile投射物; 近战为 null
getDamageTypeId()String伤害类型 ID (如 physical, spell)
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/false, yes/no, 1/0 (不区分大小写). 下列标志由伤害结算与 MythicMobs 机制读取, 括号内为等效别名:

标志默认值说明
allow_critical (critical)true是否允许暴击判定
allow_target_dodge (target_dodge, allow_dodge, dodge)false是否允许目标闪避
calculate_target_defense (target_defense, calculate_defense, defense)true是否计算目标防御
trigger_mythic_on_damaged (trigger_on_damaged, mythic_on_damaged)false是否触发 MythicMobs 的 on_damaged 事件

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

只读战斗事实 ​

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

变量说明
target_blocking目标本次是否构成有效举盾 (含正面判定), 1 或 0. 仅在 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() 判断