运行类属性(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)处理器能力
| 接口 | 能力 |
|---|---|
AttributeTracker | getRandomValue, getAttrData, trigger |
MetadataTracker | setMeta, 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 开销,但会让效果触发不那么及时。
注意事项
- 运行间隔是全局的,不能为每个属性单独设置
onRuntimeAfter是在后台线程调用的,操作 Bukkit API 需要用SchedulerUtils.sync {}- 避免在
onRuntimeAfter中做复杂计算——它每 N tick 就运行一次,如果逻辑太重会影响性能
