伤害事件 API
EmakiAttributeDamageEvent 是一个 Bukkit 事件,在属性伤害计算完成后触发。外部插件可以监听此事件来拦截、修改或记录伤害。
事件类位于公开 API 模块 EmakiAttributeApi,全限定名 emaki.jiuwu.craft.attribute.api.EmakiAttributeDamageEvent;相关模型类 DamageContext、DamageContextVariables、DamageResult 位于 emaki.jiuwu.craft.attribute.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() | DamageCause | Bukkit 伤害原因。 |
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()判断。