Skip to content

自定义属性

完全使用脚本属性,你必须会使用 JavaScript 或 Groovy 才能编写属性

现在你可能看得两眼一黑,不要紧,可以到 属性编写教程 中查看脚本教程

嗯...插件自带一套基础属性脚本,可以在 attributes 文件夹下找到

脚本编写

一个示例

JavaScript
// 属性类型(字符串)
var type = "ATTACK_AND_DEFENSE";
// 属性 ID(全小写,单词间以下划线分隔)
var id = "test_script_attribute";
// 属性名称(用于显示)
var name = "测试脚本属性";
// 属性优先级(数值越小优先级越高)
var priority = 1;
// 属性战斗力(影响战斗相关计算的基准值)
var power = 1.0;

/**
 * 初始化函数,在属性首次加载时调用。
 * 可用于注册 DEFAULT 类型属性或其他初始化逻辑。
 * 若无需初始化,可省略此函数。
 *
 * @param attr - 当前属性对象本身
 */
function init(attr) {
    // 使用 AttributeAPI 快速注册
    AttributeAPI.registerDefaultAttribute("test_default", "测试默认属性", 0.0, -1.0);
    AttributeAPI.registerDefaultAttribute("test_default1", "测试另一个默认属性", 0.0, -1.0);
}

/**
 * 启用函数,在属性被激活(加载)时调用。
 * 通常用于注册事件监听器、调度任务等运行时逻辑。
 * 若无额外逻辑,可省略此函数。
 *
 * @param attr - 当前属性对象本身
 */
function onEnable(attr) {
}

/**
 * 禁用函数,在属性被卸载或禁用时调用。
 * 应在此处清理 onEnable 中注册的资源(如取消监听、停止任务等)。
 *
 * @param attr - 当前属性对象本身
 */
function onDisable(attr) {
}

/**
 * ATTACK_AND_DEFENSE 类型属性的专属回调函数。
 * 在发生攻击与防御交互时触发,可用于自定义伤害逻辑或附加效果。
 *
 * @param attr         - 当前属性对象本身
 * @param attacker     - 攻击者实体
 * @param entity       - 被攻击者实体
 * @param handler      - 属性处理器,提供随机值、伤害加成等工具方法
 * @returns {boolean}  - 返回 true 表示成功触发属性效果,false 表示不触发
 */
function onAttackAndDefense(attr, attacker, entity, handler) {

    // 向攻击者发送一条包含随机值的消息
    attacker.sendMessage(handler.getRandomValue(attacker, "测试脚本属性"));
    // 为本次攻击额外添加基于随机值的伤害
    handler.addDamage(attacker, handler.getRandomValue(attacker, "测试脚本属性"));
    
    // 返回 true 表示该属性已生效
    return true;
}
Groovy
package attributes

// 必须显式导入所需类,才能调用相关 API
import cn.org.bukkit.craneattribute.api.AttributeAPI
import cn.org.bukkit.craneattribute.core.attribute.AttributeTypes
import cn.org.bukkit.craneattribute.core.attribute.Attribute
import cn.org.bukkit.craneattribute.core.attribute.handler.AttackAndDefenseHandler
import org.bukkit.entity.LivingEntity
import groovy.transform.CompileStatic

/**
 * 测试用的自定义属性类。
 * 继承自 {@link Attribute},用于实现 ATTACK_AND_DEFENSE 类型的战斗行为。
 */
@CompileStatic
class TestAttribute extends Attribute {

    /**
     * 无参构造函数(必须提供,否则插件无法加载该属性)。
     * 在构造时完成属性基本信息的初始化,可用于注册 DEFAULT 类型属性或其他初始化逻辑。
     */
    public TestAttribute() {
        // 调用父类构造器:类型、ID、名称、优先级、战斗力
        super(AttributeTypes.ATTACK_AND_DEFENSE, "test_script_attribute", "测试脚本属性", 1, 1.0D)

        // 注册该属性所需的默认子属性(可在配置或随机计算中使用)
        AttributeAPI.registerDefaultAttribute("test_default", "测试默认属性", 0.0D)
        AttributeAPI.registerDefaultAttribute("test_default1", "测试另一个默认属性", 0.0D)
    }

    /**
     * 属性启用回调方法。
     * 当该属性被成功加载并激活时调用,可用于注册监听器、启动任务等。
     * 注意:与 JavaScript 脚本不同,此处无需传入 attr 参数,
     * 因为当前实例(this)即代表属性对象本身。
     */
    @Override
    public void onEnable() {
    }

    /**
     * 属性禁用回调方法。
     * 当该属性被卸载或禁用时调用,应在此清理 onEnable 中注册的资源。
     */
    @Override
    public void onDisable() {
    }

    /**
     * ATTACK_AND_DEFENSE 类型属性的核心逻辑方法。
     * 在攻击-防御交互发生时自动调用,用于实现自定义战斗效果。
     *
     * @param attacker 攻击者实体(非 null)
     * @param entity   被攻击者实体(非 null)
     * @param handler  属性处理器,提供伤害调整、随机值获取等工具方法
     * @return true 表示成功触发属性效果;false 表示不生效
     */
    @Override
    public boolean onAttackAndDefense(LivingEntity attacker, LivingEntity entity, AttackAndDefenseHandler handler) {
        // 向攻击者发送一条包含随机值的消息(用于调试或反馈)
        attacker.sendMessage(handler.getRandomValue(attacker, "测试脚本属性"))

        // 为本次攻击额外增加基于随机值的伤害
        handler.addDamage(attacker, handler.getRandomValue(attacker, "测试脚本属性"))

        // 返回 true 表示该属性已生效
        return true
    }
}