Skip to content

运行类属性(RUNTIME_AFTER)

概述

RUNTIME_AFTER 每隔若干 tick 自动运行一次。与 UPDATE_AFTER(事件驱动)不同,RUNTIME_AFTER时间驱动的。

触发间隔:attribute.yml 中的 trigger setting.RUNTIME_AFTER.runtime tick 配置决定,默认为 20 tick(1 秒)。

典型用途:

  • 自动回血(生命恢复.groovy
  • 周期性 buff 刷新
  • 定时检查玩家状态

需要重写的方法

Groovy
@Override
void onEnable()

/**
 * @param entity  触发者
 * @param handler 处理器
 * @return 属性是否触发
 */
@Override
boolean onRuntimeAfter(LivingEntity entity, RuntimeAfterHandler handler)
JavaScript
function onEnable(attr)

function onRuntimeAfter(attr, entity, handler)

处理器能力

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

处理器能力与 UPDATE_AFTER 相同——没有伤害管理,主要用于读取属性值和同步状态。

示例:生命恢复

Groovy
package scripts.attributes.runtime_after

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

@CompileStatic
class HealthRegen extends GroovyAttribute {

    HealthRegen() {
        super(AttributeTypes.RUNTIME_AFTER, "health_regen", "生命恢复", 1, 0.0D, -1.0D)
    }

    @Override
    boolean onRuntimeAfter(LivingEntity entity, RuntimeAfterHandler handler) {
        // 只对玩家生效
        if (entity.type != EntityType.PLAYER) return false

        // 获取生命恢复面板值
        double heal = handler.getRandomValue(entity, "生命恢复")

        if (heal > 0) {
            // 安全治疗(触发正确的 Bukkit 事件)
            SchedulerUtils.sync {
                BukkitUtils.safeHeal(entity, heal)
            }
        }
        return true
    }
}

示例:定时清除负面效果

每 5 秒自动清除所有药水效果:

Groovy
@CompileStatic
class AutoCleanse extends GroovyAttribute {

    AutoCleanse() {
        super(AttributeTypes.RUNTIME_AFTER, "auto_cleanse", "自动净化", 1, 0.0D, -1.0D)
    }

    @Override
    boolean onRuntimeAfter(LivingEntity entity, RuntimeAfterHandler handler) {
        if (entity.type != EntityType.PLAYER) return false

        // 读取触发概率
        double chance = handler.getRandomValue(entity, "自动净化")

        if (Utils.chance(chance)) {
            SchedulerUtils.sync {
                // 遍历所有药水效果,移除负面效果
                for (PotionEffect effect : entity.getActivePotionEffects()) {
                    if (isNegativeEffect(effect.getType())) {
                        entity.removePotionEffect(effect.getType())
                    }
                }
            }
            entity.sendMessage("§a自动净化触发!负面效果已清除")
            return true
        }
        return false
    }
}

JavaScript 示例

JavaScript
var type = "RUNTIME_AFTER"
var id = "health_regen"
var name = "生命恢复"
var priority = 1
var power = 0.0
var max = -1.0

function onRuntimeAfter(attr, entity, handler) {
    if (entity.getType() != org.bukkit.entity.EntityType.PLAYER) return false

    var heal = handler.getRandomValue(entity, "生命恢复")
    if (heal > 0) {
        entity.sendMessage("生命恢复 +" + heal.toFixed(2))
    }
    return true
}

配置运行间隔

attribute.yml 中可以调整 RUNTIME_AFTER 的运行间隔:

YAML
trigger setting:
  RUNTIME_AFTER:
    runtime tick: 20  # 20 tick = 1 秒(默认)

调大这个值可以降低 CPU 开销,但会让效果触发不那么及时。

注意事项

  1. 运行间隔是全局的,不能为每个属性单独设置
  2. onRuntimeAfter 是在后台线程调用的,操作 Bukkit API 需要用 SchedulerUtils.sync {}
  3. 避免在 onRuntimeAfter 中做复杂计算——它每 N tick 就运行一次,如果逻辑太重会影响性能