Skip to content

条件系统 (Condition System)

条件系统用来做条件判断——给它一个表达式,它告诉你是 true 还是 false。支持比较运算符、逻辑组合和自动类型推断。最常见的用法是配合动作系统的 @if 前缀,不过其他模块也可以单独调用。

基本语法

条件表达式的基本形式:

<左值> <运算符> <右值>
yaml
# 示例
"@if=%player_level%>=10 givemoney amount=500"
"@if=%player_world%==world sendmessage message=你在主世界"

支持的运算符

运算符说明示例
==等于%player_world%==world
!=不等于%player_world%!=world_nether
<小于%player_level%<10
<=小于等于%player_health%<=5
>大于%player_level%>20
>=大于等于%balance%>=1000

逻辑组合符

多个条件可以用逻辑组合符连接起来:

组合符说明示例
&&逻辑与(全部满足)%player_level%>=10&&%player_world%==world
||逻辑或(任一满足)%player_world%==world||%player_world%==world_the_end
yaml
actions:
  # 等级 >= 10 且在主世界
  - "@if=%player_level%>=10&&%player_world%==world givemoney amount=500"

  # 在主世界或末地
  - "@if=%player_world%==world||%player_world%==world_the_end sendmessage message=<green>安全区域"

注意

&&|| 不能混用在同一个 @if 表达式中。这是为了避免运算符优先级带来的歧义。如果需要更复杂的逻辑组合,用下面的结构化条件配置。

结构化条件配置

当内联的 @if 表达式不够用时(比如需要混合 AND 和 OR,或者条件特别多),可以在 YAML 里用结构化的方式来写。

all_of — 全部满足

所有子条件都为 true 时整体才为 true,相当于逻辑与:

yaml
conditions:
  type: all_of
  conditions:
    - "%player_level% >= 10"
    - "%player_world% == world"
    - "%balance% >= 500"

any_of — 任一满足

任意一个子条件为 true 就行,相当于逻辑或:

yaml
conditions:
  type: any_of
  conditions:
    - "%player_world% == world"
    - "%player_world% == world_the_end"
    - "%player_world% == world_nether"

at_least — 至少满足 N 个

至少有 count 个子条件为 true 时整体为 true。这在 all_ofany_of 之间提供了一个中间地带——比如"四个条件里满足任意两个就行":

yaml
conditions:
  type: at_least
  count: 2
  conditions:
    - "%player_level% >= 10"
    - "%balance% >= 1000"
    - "%player_health% >= 15"
    - "%player_food_level% >= 18"

exactly — 恰好满足 N 个

恰好有 count 个子条件为 true 时整体为 true。适合"互斥选择"的场景——比如玩家只能在三个世界中的一个:

yaml
conditions:
  type: exactly
  count: 1
  conditions:
    - "%player_world% == world"
    - "%player_world% == world_nether"
    - "%player_world% == world_the_end"

嵌套组合

结构化条件可以嵌套,用来构建任意复杂的逻辑。比如下面这个例子表示"等级 >= 10,且(在主世界或末地),且(余额 >= 500 或者是 OP)":

yaml
conditions:
  type: all_of
  conditions:
    - "%player_level% >= 10"
    - type: any_of
      conditions:
        - "%player_world% == world"
        - "%player_world% == world_the_end"
    - type: at_least
      count: 1
      conditions:
        - "%balance% >= 500"
        - "%player_is_op% == true"

类型推断

条件系统会自动判断比较值的类型,你不需要手动声明:

推断规则说明示例
两侧均为数值按数值比较%player_level%>=10 → 数值比较
任一侧为非数值按字符串比较%player_world%==world → 字符串比较
布尔值true / false 按字符串比较%player_is_op%==true → 字符串比较
yaml
# 数值比较 — 支持所有运算符
"@if=%player_level%>=10 ..."        # 10, 11, 12... 均满足
"@if=%balance%<100 ..."             # 99.9, 50, 0 均满足

# 字符串比较 — 只支持 == 和 !=
"@if=%player_world%==world ..."     # 精确匹配 "world"
"@if=%player_name%!=Steve ..."      # 不等于 "Steve"

注意

对字符串用 <, <=, >, >= 时,系统会按字典序比较。这通常不是你想要的效果,所以字符串比较建议只用 ==!=

在 @if 前缀中使用

@if 是条件系统最常见的入口:

yaml
actions:
  # 简单条件
  - "@if=%player_level%>=10 givemoney amount=500"

  # 组合条件
  - "@if=%player_level%>=20&&%player_world%==world givemoney amount=2000"

  # 和其他控制前缀一起用
  - "@if=%player_level%>=30 @chance=0.5 @delay=20 givemoney amount=5000"

编程接口

除了在 YAML 配置里用,条件系统也可以在代码里直接调用:

java
ConditionService conditionService = EmakiServiceRegistry.get(ConditionService.class);

// 求值简单条件
Map<String, String> placeholders = Map.of(
    "player_level", "15",
    "player_world", "world"
);

boolean result = conditionService.evaluate("%player_level% >= 10", placeholders);
// true

// 求值结构化条件
ConditionConfig config = ConditionConfig.allOf(
    SimpleCondition.of("%player_level%", ">=", "10"),
    SimpleCondition.of("%player_world%", "==", "world")
);

boolean result2 = conditionService.evaluate(config, placeholders);
// true

提示

条件求值本身很轻量,不涉及 I/O 或复杂计算,在高频路径中用也没问题。占位符会在求值前被替换成实际值,所以条件表达式里可以用任何已注册的占位符。

Released under the GPL-3.0 License