Skip to content

自定义映射读取组件

概述

映射读取组件的作用是:将一行 Lore 文本映射为一组属性

与数值/条件读取组件不同,映射读取器不关心这一行「值是多少」或「条件是否满足」,而是关心「根据这一行文本,应该给这件装备哪些属性」。

使用场景

  • 材质映射:「这是一个红宝石」→ 赋予属性「力量 +1」
  • 套装识别:「§6远古套装部件」→ 赋予套装属性
  • 词条映射:某些特殊文字 → 赋予对应属性组合

插件自带的 LineReadMapping 就是映射读取组件——在 read.yml 中配置文本到属性的映射关系。自定义映射读取器可以实现更动态的映射逻辑。

基础结构

Groovy
package scripts.reads

import cn.org.bukkit.craneattribute.api.attribute.data.AttributeData
import cn.org.bukkit.craneattribute.api.attribute.source.AttributeSource
import cn.org.bukkit.craneattribute.api.read.ReadableLine
import cn.org.bukkit.craneattribute.core.read.data.AttributeReadResult
import groovy.transform.CompileStatic
import scripts.libs.GroovyMappingReader

@CompileStatic
class YourMappingReader extends GroovyMappingReader {

    YourMappingReader() {
        super("your_mapping", 10)  // name, priority
    }

    @Override
    AttributeReadResult read(ReadableLine readableLine, AttributeData data, AttributeSource attributeSource) {
        // 映射逻辑
    }
}

完整示例:词条映射

假设你有一个「符文之语」系统,物品 Lore 上的特定词条会赋予特定属性:

Groovy
package scripts.reads

import cn.org.bukkit.craneattribute.api.attribute.data.AttributeData
import cn.org.bukkit.craneattribute.api.attribute.source.AttributeSource
import cn.org.bukkit.craneattribute.api.read.ReadableLine
import cn.org.bukkit.craneattribute.core.read.data.AttributeReadResult
import groovy.transform.CompileStatic
import scripts.libs.GroovyMappingReader

@CompileStatic
class RuneWordMappingReader extends GroovyMappingReader {

    // 词条 → 属性映射表
    private static final Map<String, List<String>> RUNE_MAPPING = [
        "§c烈焰符文":     ["火焰攻击 50", "火焰抗性 20"],
        "§b寒冰符文":     ["冰霜攻击 50", "冰霜抗性 20"],
        "§e雷霆符文":     ["雷电攻击 50", "雷电抗性 20"],
        "§a生命符文":     ["生命值 200", "生命恢复 10"],
        "§5暗影符文":     ["暗影攻击 80", "吸血率 5(%)"],
        "§f神圣符文":     ["神圣攻击 60", "治疗加成 30(%)"]
    ]

    RuneWordMappingReader() {
        super("rune_word_mapping", 10)
    }

    @Override
    AttributeReadResult read(ReadableLine readableLine, AttributeData data, AttributeSource attributeSource) {
        // 获取原始行文本(保留颜色代码)
        String line = readableLine.getRawLine()

        // 在映射表中查找
        for (Map.Entry<String, List<String>> entry : RUNE_MAPPING.entrySet()) {
            if (line.contains(entry.getKey())) {
                // 找到匹配,返回映射的属性列表
                return new AttributeReadResult(entry.getValue())
            }
        }

        // 没有匹配,返回 null(交给其他读取器)
        return null
    }
}

AttributeReadResult

AttributeReadResult 的使用非常简单——传入一个字符串列表,每个字符串与 Lore 行的格式相同:

Groovy
// 单个属性
new AttributeReadResult(["物理攻击 100"])

// 多个属性
new AttributeReadResult(["物理攻击 100", "生命值 500", "暴击率 10(%)"])

// 百分比属性
new AttributeReadResult(["移速加成 50(%)"])

插件会自动把 AttributeReadResult 中的属性合并到该属性源中。

另一个示例:物品材质映射

根据物品的材料类型自动给予属性:

Groovy
@CompileStatic
class MaterialMappingReader extends GroovyMappingReader {

    // 材质 → 属性
    private static final Map<Material, List<String>> MATERIAL_MAPPING = [
        (Material.DIAMOND_SWORD):  ["物理攻击 100", "暴击率 10(%)"],
        (Material.DIAMOND_CHESTPLATE): ["生命值 200", "物理护甲 50"],
        (Material.GOLDEN_APPLE):   ["生命恢复 5", "治疗效果 20(%)"],
        (Material.BOW):            ["远程攻击 80", "暴击率 15(%)"]
    ]

    MaterialMappingReader() {
        super("material_mapping", 10)
    }

    @Override
    AttributeReadResult read(ReadableLine readableLine, AttributeData data, AttributeSource attributeSource) {
        // 此方法对每一行 Lore 都会被调用
        // 如果是基于物品的映射,更好的做法是根据 attributeSource 获取物品
        if (attributeSource instanceof ItemStackBased) {
            ItemStack item = attributeSource.getItemStack()
            if (item != null) {
                List<String> mappedAttributes = MATERIAL_MAPPING.get(item.getType())
                if (mappedAttributes != null) {
                    return new AttributeReadResult(mappedAttributes)
                }
            }
        }
        return null
    }
}

与系统 LineReadMapping 的比较

系统 LineReadMapping自定义 GroovyMappingReader
配置方式read.yml YAML 配置Groovy 脚本
灵活性静态映射动态逻辑、数据库查询等
修改成本改 YAML,无需重载脚本改脚本,需要 /ca reload
适合场景简单固定的映射复杂条件、动态生成的映射

注意事项

  1. 映射读取器也可以使用过滤符(read.yml 中配置的 filter char
  2. readableLine.getRawLine() 返回原始行(含颜色代码),getClearLine() 返回去除颜色代码后的纯文本
  3. 映射结果中的属性格式与普通 Lore 行完全相同——数值读取器会进一步处理它们
  4. 返回 null 让其他读取器有机会处理——不要返回空的 AttributeReadResult

下一步

映射读取是读取组件中最灵活的类型。更多底层细节请参考 开发文档