Skip to content

击杀类属性(PLAYER_KILL_ENTITY)

概述

PLAYER_KILL_ENTITY 在玩家击杀任意实体时触发。

触发条件:

  • 必须是玩家击杀
  • 被击杀的可以是任何 LivingEntity(怪物、动物、其他玩家)

不触发场景:

  • 生物击杀生物
  • 玩家死亡(被击杀者是玩家时触发的是击杀者的属性)
  • 非直接击杀(如药水、火焰——取决于 Bukkit 的死亡事件判定)

需要重写的方法

Groovy
@Override
void onEnable()

/**
 * @param killer  击杀者(玩家)
 * @param entity  被击杀者
 * @param handler 处理器
 * @return 属性是否触发
 */
@Override
boolean onPlayerKillEntity(
    LivingEntity killer,
    LivingEntity entity,
    PlayerKillEntityHandler handler
)
JavaScript
function onEnable(attr)

function onPlayerKillEntity(attr, killer, entity, handler)

处理器能力

接口能力
AttributeTrackergetRandomValue, getAttrData, trigger
MetadataTrackersetMeta, getMeta, hasMeta

注意:这个处理器没有 DamageTracker(击杀时已经没有伤害需要计算了),也没有 Cancellable(不能取消击杀)。

示例:击杀恢复生命

Groovy
package scripts.attributes

import cn.org.bukkit.craneattribute.core.attribute.AttributeTypes
import cn.org.bukkit.craneattribute.core.attribute.handler.PlayerKillEntityHandler
import cn.org.bukkit.craneattribute.core.utils.BukkitUtils
import groovy.transform.CompileStatic
import scripts.libs.GroovyAttribute
import org.bukkit.entity.LivingEntity

@CompileStatic
class KillHeal extends GroovyAttribute {

    KillHeal() {
        super(AttributeTypes.PLAYER_KILL_ENTITY, "kill_heal", "击杀恢复", 1, 0.0D, -1.0D)
    }

    @Override
    boolean onPlayerKillEntity(LivingEntity killer, LivingEntity entity, PlayerKillEntityHandler handler) {
        // 获取击杀恢复面板值
        double heal = handler.getRandomValue(killer, "击杀恢复")

        if (heal > 0) {
            BukkitUtils.safeHeal(killer, heal)
            killer.sendMessage("§a击杀恢复!恢复了 ${String.format("%.2f", heal)} 点生命")
            return true
        }
        return false
    }
}

示例:击杀额外掉落

利用 MetadataTracker 记录击杀信息,或直接给予物品:

Groovy
@CompileStatic
class KillBonus extends GroovyAttribute {

    KillBonus() {
        super(AttributeTypes.PLAYER_KILL_ENTITY, "kill_bonus", "击杀额外掉落", 1, 0.0D, -1.0D)
    }

    @Override
    boolean onPlayerKillEntity(LivingEntity killer, LivingEntity entity, PlayerKillEntityHandler handler) {
        double bonusRate = handler.getRandomValue(killer, "击杀额外掉落")

        if (Utils.chance(bonusRate)) {
            // 在击杀位置额外掉落一个钻石(示例)
            SchedulerUtils.sync {
                entity.getWorld().dropItemNaturally(
                    entity.getLocation(),
                    new ItemStack(Material.DIAMOND, 1)
                )
            }
            killer.sendMessage("§e击杀额外掉落触发!额外获得钻石 x1")
            return true
        }
        return false
    }
}

示例:击杀计数器

结合 Counter(计数器)实现击杀计数:

Groovy
@CompileStatic
class KillCounter extends GroovyAttribute {

    KillCounter() {
        super(AttributeTypes.PLAYER_KILL_ENTITY, "kill_counter", "击杀计数", 1, 0.0D, -1.0D)
    }

    @Override
    boolean onPlayerKillEntity(LivingEntity killer, LivingEntity entity, PlayerKillEntityHandler handler) {
        // 获取击杀者的属性数据
        var data = handler.getAttrData(killer)
        // 获取计数器注册表
        var counterRegistry = data.getCounterRegistry()
        // 获取或创建「击杀数」计数器,并设置死亡时不重置
        Counter counter = counterRegistry.getOrPut("击杀数") {
            it.addRemoveTrigger("DEATH")
            it.setPersist(true) // 持久化到数据库
        }
        // 增加计数
        counter.updateNumber(1.0D, 0.0D)
        double count = counter.getNumber(0.0D)

        killer.sendMessage("§6当前击杀数:${count.toInteger()}")

        // 根据击杀数读取对应面板属性
        double bonus = handler.getRandomValue(killer, "击杀计数")
        if (bonus > 0) {
            damageBonus(killer, bonus)
        }
        return true
    }
}

JavaScript 示例

JavaScript
var type = "PLAYER_KILL_ENTITY"
var id = "kill_heal"
var name = "击杀恢复"
var priority = 1
var power = 0.0
var max = -1.0

function onPlayerKillEntity(attr, killer, entity, handler) {
    var heal = handler.getRandomValue(killer, "击杀恢复")
    if (heal > 0) {
        killer.sendMessage("击杀恢复!恢复了 " + heal.toFixed(2) + " 点生命")
        return true
    }
    return false
}

注意事项

  1. 只有玩家击杀才会触发——如果你想给怪物也做击杀奖励,需要自己编写扩展属性类型
  2. killer 参数在 PLAYER_KILL_ENTITY 中始终是 Player 类型,可以直接强转
  3. 击杀时实体已经死亡,操作被击杀者的 Location 等属性仍然可以,但不能修改其生命值等