Skip to content

计数器

CounterRegistry

每个实体属性数据中都存在一个计数器注册表 CounterRegistry,在 CounterRegistry 中又包含了若干个 Counter,通过 Counter 可以手动为实体存储一些数据

Counter

提示

以下均为伪代码,使用时注意导包
import cn.org.bukkit.craneattribute.api.attribute.data.AttributeData
import cn.org.bukkit.craneattribute.core.attribute.counter.Counter
import cn.org.bukkit.craneattribute.core.attribute.counter.CounterRegistry

获取一个 Counter 对象

Groovy
@Override
boolean onAttackAndDefense(LivingEntity attacker, LivingEntity entity, AttackAndDefenseHandler handler) {
    // 获取攻击者的 AttackerData
    AttributeData data = handler.getAttackerData()
    // 从 AttackerData 获取它的 CounterRegistry
    CounterRegistry counterRegistry = data.getCounterRegistry()

    // 获取一个 Counter 计数器对象
    // 若 counterRegistry 中不包含 "测试1" 的计数器,则会注册一个
    Counter counter = counterRegistry.getOrPut("测试1")

    // 获取一个 Counter 计数器对象
    // 若 counterRegistry 中不包含 "测试2" 的计数器,则会注册一个
    // **注册时**会为计数器添加一个**重置触发器**
    Counter counter2 = counterRegistry.getOrPut("测试2") {
        it.addRemoveTrigger("DEATH")
    }
    // 获取一个包含**多个重置触发器**的 Counter 计数器对象
    // 若 counterRegistry 中不包含 "测试3" 的计数器,则会注册一个
    // **注册时**会为计数器添加多个**重置触发器**
    // **注册时**会使计数器持久化
    Counter counter3 = counterRegistry.getOrPut("测试3") {
        it.addRemoveTrigger("DEATH")
        it.addRemoveTrigger("CHANGE_WORLD")
        it.setPersist(true)
    }
    return true
}

判断是否拥有某 Counter 对象

Groovy
@Override
boolean onAttackAndDefense(LivingEntity attacker, LivingEntity entity, AttackAndDefenseHandler handler) {
    // 获取攻击者的 AttackerData
    AttributeData data = handler.getAttackerData()
    // 从 AttackerData 获取它的 CounterRegistry
    CounterRegistry counterRegistry = data.getCounterRegistry()

    // 判断是否包含有效的计数器
    boolean exist = counterRegistry.contains("xx")

    return true
}

移除一个 Counter 对象

Groovy
@Override
boolean onAttackAndDefense(LivingEntity attacker, LivingEntity entity, AttackAndDefenseHandler handler) {
    // 获取攻击者的 AttackerData
    AttributeData data = handler.getAttackerData()
    // 从 AttackerData 获取它的 CounterRegistry
    CounterRegistry counterRegistry = data.getCounterRegistry()

    // 移除一个 Counter 计数器对象
    // 若 counterRegistry 中不包含 "xx" 的计数器,则什么都不会发生
    // 移除不用的计数器是为了节省一丢丢内存
    boolean exist = counterRegistry.removeCounter("xx")

    return true
}

记录数值

计数器可以记录数值

Groovy
@Override
boolean onAttackAndDefense(LivingEntity attacker, LivingEntity entity, AttackAndDefenseHandler handler) {
    AttributeData data = handler.getAttackerData()
    CounterRegistry counterRegistry = data.getCounterRegistry()
    Counter testCounter = counterRegistry.get("测试")

    // 更新数值,加 10.0
    // 若计数器中不存在有效数值,则使用这里传入的默认值 0.0D
    testCounter.updateNumber(10.0D, 0.0D)
    // 更新数值,减去 10.0
    // 若计数器中不存在有效数值,则使用这里传入的默认值 0.0D
    testCounter.updateNumber(-10.0D, 0.0D)
    // 设置数值 10.0
    testCounter.setNumber(10.0D)
    // 获取数值
    // 若计数器中不存在有效数值,则获取这里传入的默认值 0.0D
    double value = testCounter.getNumber(0.0D)
    // 移除数值
    // 移除不用的数值,也是为了节省一丢丢内存
    testCounter.removeNumber()


    //-------------------- 高阶用法 -------------------- 
    // 一个 Counter 中不止能记录一个数值,可以记录无数个不同 name 的数值
    // 上面没有指定 name 的方法,都是快捷方法,实际上会使用默认 name "GENERIC"
    // "GENERIC" 是可以自己随便自定义的,但为了便于理解,继续使用 "GENERIC" 介绍
    // 下面的代码效果等同于上面的代码效果


    // 更新 "GENERIC" 的数值,加 10.0
    // 若计数器的 "GENERIC" 中不存在有效数值,则使用这里传入的默认值 0.0D
    testCounter.updateNumber("GENERIC", 10.0D, 0.0D)
    // 更新 "GENERIC" 的数值,减去 10.0
    // 若计数器的 "GENERIC" 中不存在有效数值,则使用这里传入的默认值 0.0D
    testCounter.updateNumber("GENERIC", -10.0D, 0.0D)
    // 设置 "GENERIC" 的数值 10.0
    testCounter.setNumber("GENERIC", 10.0D)
    // 获取 "GENERIC" 的数值
    // 若计数器的 "GENERIC" 中不存在有效数值,则获取这里传入的默认值 0.0D
    testCounter.getNumber("GENERIC", 0.0D)
    // 移除 "GENERIC" 的数值
    // 移除不用的数值,也是为了节省一丢丢内存
    testCounter.removeNumber("GENERIC")

    return true
}

记录文本

计数器可以记录字符串

Groovy
@Override
boolean onAttackAndDefense(LivingEntity attacker, LivingEntity entity, AttackAndDefenseHandler handler) {
    AttributeData data = handler.getAttackerData()
    CounterRegistry counterRegistry = data.getCounterRegistry()
    Counter testCounter = counterRegistry.get("测试")

    // 设置字符串为 "123456789"
    testCounter.setText("123456789")
    // 获取字符串
    // 若计数器中不存在有效字符串,则获取这里传入的默认值 "123456789"
    String value = testCounter.getTextOrDefault("123456789")
    // 获取字符串
    // 若计数器中不存在有效字符串,则获取 null
    String value = testCounter.getTextOrNull()
    // 移除字符串
    // 移除不用的字符串,也是为了节省一丢丢内存
    testCounter.removeText()


    //-------------------- 高阶用法 -------------------- 
    // 一个 Counter 中不止能记录一个数值,可以记录无数个不同 name 的数值
    // 上面没有指定 name 的方法,都是快捷方法,实际上会使用默认 name "GENERIC"
    // "GENERIC" 是可以自己随便自定义的,但为了便于理解,继续使用 "GENERIC" 介绍
    // 下面的代码效果等同于上面的代码效果


    // 设置 "GENERIC" 的字符串为 "123456789"
    testCounter.setText("GENERIC", "123456789")
    // 获取 "GENERIC" 的字符串
    // 若计数器的 "GENERIC" 的不存在有效字符串,则获取这里传入的默认值 "123456789"
    String value = testCounter.getTextOrDefault("GENERIC", "123456789")
    // 获取 "GENERIC" 的字符串
    // 若计数器的 "GENERIC" 的不存在有效字符串,则获取 null
    String value = testCounter.getTextOrNull("GENERIC")
    // 移除 "GENERIC" 的字符串
    // 移除不用的字符串,也是为了节省一丢丢内存
    testCounter.removeText("GENERIC")

    return true
}

移除触发器

计数器除了到期移除和主动移除之外,还能添加和定义移除触发器,会在对应事件发生后自动移除该计数器,若不设置,则不会启用此功能

插件默认提供一些移除触发器

CHANGE_WORLD:改变世界时重置
DEATH:死亡时重置