意外受伤类属性(ACCIDENTAL_DAMAGED)
概述
ACCIDENTAL_DAMAGED 在实体受到非直接攻击伤害时触发。这包括:
- 摔落伤害
- 溺水伤害
- 火焰/岩浆伤害
- 窒息伤害
- 药水伤害(部分情况)
- 仙人掌、甜浆果丛等环境伤害
与 ATTACK_AND_DEFENSE 的区别:
ATTACK_AND_DEFENSE:实体 A 攻击实体 BACCIDENTAL_DAMAGED:没有具体的攻击者(或者攻击者不重要),伤害来自环境
需要重写的方法
Groovy
@Override
void onEnable()
/**
* @param it 抽象的「攻击者」——一个随机生成的 UUID(非真实实体)
* @param entity 受伤者
* @param handler 处理器
* @return 属性是否触发
*/
@Override
boolean onAccidentalDamage(
UUID it,
LivingEntity entity,
AccidentalDamageHandler handler
)JavaScript
function onEnable(attr)
function onAccidentalDamage(attr, it, entity, handler)关于 it 参数:it 是一个随机生成的 UUID,不代表任何真实存在的实体。它的作用是给伤害分配一个「来源标识」,让你可以在伤害分源机制中使用。对于大部分场景,你不需要直接使用它——操作伤害时用 handler.addDamage(entity, ...) 即可。
处理器能力
| 接口 | 能力 |
|---|---|
DamageTracker | addDamage, getDamage, setDamage, multiplyDamage |
AttributeTracker | getRandomValue, getAttrData, trigger |
MetadataTracker | setMeta, getMeta, hasMeta |
BlockTracker | 获取造成伤害的方块信息 |
Cancellable | setCancelled(true) |
注意: 有 DamageTracker!和 ATTACK_AND_DEFENSE 一样,可以操作伤害。但没有 MessageTracker,消息需要自己发。
示例:摔落减伤
Groovy
package scripts.attributes
import cn.org.bukkit.craneattribute.core.attribute.AttributeTypes
import cn.org.bukkit.craneattribute.core.attribute.handler.AccidentalDamageHandler
import groovy.transform.CompileStatic
import scripts.libs.GroovyAttribute
import org.bukkit.entity.LivingEntity
@CompileStatic
class FallReduction extends GroovyAttribute {
FallReduction() {
super(AttributeTypes.ACCIDENTAL_DAMAGED, "fall_reduction", "摔落减伤", 1, 0.0D, -1.0D)
Utils.registerDefaultAttribute("fall_resist", "摔落抗性", 0.0D, -1.0D)
}
@Override
boolean onAccidentalDamage(UUID it, LivingEntity entity, AccidentalDamageHandler handler) {
// 获取摔落抗性面板值
double reduction = handler.getRandomValue(entity, "摔落抗性")
if (reduction > 0) {
// 获取当前累计伤害
double currentDamage = handler.getDamage(entity)
// 计算减免后的伤害(不低于0)
double newDamage = Math.max(0, currentDamage - reduction)
// 设置减免后的伤害
handler.setDamage(entity, newDamage)
entity.sendMessage("§a摔落减伤!减免了 ${String.format("%.2f", reduction)} 点伤害,最终受到 ${String.format("%.2f", newDamage)} 点伤害")
return true
}
return false
}
}示例:火焰免疫
完全取消火焰伤害:
Groovy
@CompileStatic
class FireImmunity extends GroovyAttribute {
FireImmunity() {
super(AttributeTypes.ACCIDENTAL_DAMAGED, "fire_immunity", "火焰免疫", 1, 0.0D, -1.0D)
}
@Override
boolean onAccidentalDamage(UUID it, LivingEntity entity, AccidentalDamageHandler handler) {
// 判断伤害原因(需要在 attribute.yml 中配置 trigger damage cause)
// 或者通过 DamageCause 判断(需要 BlockTracker 接口提供的方法)
double immunity = handler.getRandomValue(entity, "火焰免疫")
if (immunity >= 100) {
// 完全免疫:取消本次伤害
handler.setCancelled(true)
entity.setFireTicks(0) // 灭火
entity.sendMessage("§6火焰免疫触发!")
return true
} else if (immunity > 0) {
// 部分减免
double damage = handler.getDamage(entity)
handler.setDamage(entity, damage * (1 - immunity / 100))
return true
}
return false
}
}注意: ACCIDENTAL_DAMAGED 有一个触发器配置 trigger damage cause(在 attribute.yml 中),可以用来限制只有特定伤害原因才触发。例如,你不想让「火焰免疫」属性在玩家摔落时也触发检测。
配置伤害原因白名单
在 attribute.yml 中:
YAML
trigger setting:
ACCIDENTAL_DAMAGED:
trigger damage cause:
- FALL
- FIRE
- LAVA如果配置了白名单,只有列表中的伤害原因才会触发 ACCIDENTAL_DAMAGED 类型的属性。
JavaScript 示例
JavaScript
var type = "ACCIDENTAL_DAMAGED"
var id = "fall_reduction"
var name = "摔落减伤"
var priority = 1
var power = 0.0
var max = -1.0
function init(attr) {
AttributeAPI.registerDefaultAttribute("fall_resist", "摔落抗性", 0.0, -1.0)
}
function onAccidentalDamage(attr, it, entity, handler) {
var reduction = handler.getRandomValue(entity, "摔落抗性")
if (reduction > 0) {
var currentDmg = handler.getDamage(entity)
var newDmg = Math.max(0, currentDmg - reduction)
handler.setDamage(entity, newDmg)
entity.sendMessage("摔落减伤触发!减免 " + reduction.toFixed(2) + " 点")
return true
}
return false
}注意事项
it是随机 UUID,不代表真实实体——不要尝试用Bukkit.getEntity(it)获取实体- 伤害减免设置后,最终伤害由所有
ACCIDENTAL_DAMAGED属性的处理结果叠加决定 - 使用
handler.setCancelled(true)可以完全取消伤害 - 如果要区分伤害类型(摔落/火焰/溺水等),需要在
attribute.yml中配置trigger damage cause - 不需要对
it(UUID)操作伤害——直接对entity操作即可
