使用枚举类管理属性
为什么需要枚举?
当你的插件有几十个属性时,管理它们的 ID、名称、优先级、战斗力会变得很麻烦。属性 ID 散落在各个文件中,改一个名字可能要改好几个地方。
解决方法:用一个枚举类统一管理所有属性的配置,然后所有脚本都引用这个枚举。
插件的系统属性就是这么做的——scripts/libs/ 下有一个 AttributeName.groovy 枚举类。
AttributeName 枚举
Groovy
package scripts.libs
import groovy.transform.CompileStatic
@CompileStatic
enum AttributeName {
// ———— 枚举条目:id, name, priority, power, max ————
HIT_CHANCE("HIT_CHANCE", "命中几率", 1, 1.0D, -1),
PHYSICAL_ATTACK("PHYSICAL_ATTACK", "物理攻击", 1, 1.0D, -1),
PHYSICAL_ARMOR("PHYSICAL_ARMOR", "物理护甲", 1, 0.0D, -1),
HEALTH("HEALTH", "生命值", 1, 1.0D, -1),
SPEED("SPEED", "移速加成", 1, 0.0D, -1),
// ... 更多属性
// ———— 成员变量 ————
final String id
final String name
final int priority
final double power
final double max
// ———— 构造函数 ————
AttributeName(String id, String name, int priority, double power, double max) {
this.id = id
this.name = name
this.priority = priority
this.power = power
this.max = max
}
}在属性脚本中使用
有了枚举后,属性脚本可以这样写:
Groovy
class HitChance extends GroovyAttribute {
HitChance() {
// 使用枚举,一行搞定
super(AttributeTypes.ATTACK_AND_DEFENSE, AttributeName.HIT_CHANCE)
// 注册子属性也使用枚举
Utils.registerDefaultAttribute(AttributeName.DOGE_CHANCE)
}
@Override
boolean onAttackAndDefense(LivingEntity attacker, LivingEntity entity, AttackAndDefenseHandler handler) {
// 通过枚举获取属性名称
double v = handler.getRandomValue(attacker, AttributeName.HIT_CHANCE.name)
// ...
}
}好处:
- 属性名拼写错误会被编译器检查出来(编译时错误,而不是运行时才发现)
- 修改属性名只需改枚举中的一处
- IDE 可以自动补全
AttributeName.后面的内容 - 优先级排序一目了然
注意事项
- 枚举只是一种推荐的管理方式,不是必须的。你完全可以不用枚举,直接在构造函数里写字符串
- 枚举文件可以放在
scripts/libs/下的任意位置 - JavaScript 无法使用 Groovy 枚举——JS 脚本只能直接用字符串
- 在
config.yml的groovy load sort中,libs必须在attributes之前加载(默认配置已经这样做了)
不使用枚举的对比
Groovy
// 不使用枚举——属性名散落在各处,容易拼错
super(AttributeTypes.ATTACK_AND_DEFENSE, "物理攻击", "物理攻击", 1, 1.0D, -1.0D)
// ... 另一个文件
handler.getRandomValue(entity, "物理攻击") // 字符串拼写错误要到运行时才发现!
handler.getRandomValue(entity, "物理功击") // 拼错了!但编译器不报错
// 使用枚举——编译器帮你检查
super(AttributeTypes.ATTACK_AND_DEFENSE, AttributeName.PHYSICAL_ATTACK)
handler.getRandomValue(entity, AttributeName.PHYSICAL_ATTACK.name)
// 如果写错 AttributeName.xxx,编译时就会报错