Skip to content

相关:动作与技能桥.md · API概览.md · 脚本API.md · ../05-参考/术语表.md

🔀 条件系统与表达式引擎(ConditionSystem / ExpressionEngine)

本页讲两套互补的求值工具:

  1. ConditionSystem —— 布尔判断框架(条件链、DSL 程序、操作符、组合条件)。
  2. ExpressionEngine —— 基于 exp4j 的数值表达式引擎(算术、函数、随机数)。

动作要「做什么」,条件决定「做不做」;表达式则给动作算出具体数值。三者通常一起用,见 动作与技能桥.md


一、ConditionSystem

1.1 Condition 接口与 ConditionContext

kotlin
interface Condition {
    val id: String
    fun evaluate(context: ConditionContext): Boolean
}

求值上下文 ConditionContext

成员说明
variables变量袋
traceId(可空)追踪 id
debug是否调试追踪

读写方法:

kotlin
context.setVar("hp", 18.0)
val hp: Double?  = context.getVar("hp")
val name: String = context.getVarString("targetName")
context.traceBuilder()

1.2 实现并注册一个条件

kotlin
class HasEnoughHpCondition : Condition {
    override val id = "has_enough_hp"

    override fun evaluate(context: ConditionContext): Boolean {
        val hp = context.getVar<Double>("hp") ?: return false
        return hp >= 10.0
    }
}

// 注册 / 查找 / 取全部
ConditionRegistry.register(HasEnoughHpCondition())
val cond = ConditionRegistry.get("has_enough_hp")
val all  = ConditionRegistry.all()

1.3 ConditionPipeline —— 条件链

kotlin
val pipeline = ConditionPipeline()
pipeline.addCondition(HasEnoughHpCondition())
// 或加载一个 DSL 程序
pipeline.loadProgram(myConditionDslProgram)

val ctx = ConditionContext(variables = mutableMapOf("hp" to 18.0))
val ok: Boolean = pipeline.evaluate(ctx)

1.4 DSL:ConditionNode / ConditionDslProgram

把条件写成节点,按 logic 取与 / 或聚合。compile / validate / optimize / execute 四段式与动作 DSL 一致。

kotlin
val program = ConditionDslProgram(
    id = "can_cast",
    nodes = listOf(
        ConditionNode(id = "n1", type = "var_eq", params = mapOf("key" to "class", "value" to "mage")),
        ConditionNode(id = "n2", type = "exists", params = mapOf("key" to "mana")),
    ),
    logic = "AND"     // "AND" | "OR",默认 "AND"
)

program.compile()
program.validate()
program.optimize()
val result: Boolean = program.execute(ctx)

ConditionNode(id, type, params)type 取下表内置操作符之一,params 为该操作符的参数。

1.5 内置节点操作符

操作符含义
eq相等
neq不相等
exists变量存在
notnull非 null
contains包含
var_eq变量等于某值

1.6 CompositeCondition —— 组合条件

把多个条件用逻辑运算符组合成一个:

kotlin
val composite = CompositeCondition(
    conditions = listOf(condA, condB, condC),
    operator = LogicOperator.AND      // AND / OR / NOT
)
val ok = composite.evaluate(ctx)

LogicOperator 取值:AND / OR / NOT


二、ExpressionEngine —— 表达式引擎

ExpressionEngine 基于 exp4j,把字符串表达式连同变量表算成一个 Double

2.1 evaluate

kotlin
val vars: Map<String, Double> = mapOf("level" to 12.0, "base" to 5.0)
val damage: Double = ExpressionEngine.evaluate("base + level * 1.5", vars)
// → 5 + 12 * 1.5 = 23.0

签名:evaluate(expression: String, variables: Map<String, Double>): Double

2.2 随机函数

引擎内置 4 个随机函数,可直接写进表达式:

函数含义
randomDouble(min, max)[min, max) 区间均匀随机小数
randomInt(min, max)区间随机整数
randomGaussian(mean, stdDev)正态分布随机数(均值 mean、标准差 stdDev)
randomExponential(lambda)指数分布随机数(速率 lambda)
kotlin
// 基础伤害 10 ± 浮动,再叠一点高斯抖动
val dmg = ExpressionEngine.evaluate(
    "10 + randomDouble(0, 3) + randomGaussian(0, 0.5)",
    emptyMap()
)
val crit = ExpressionEngine.evaluate("randomInt(1, 100)", emptyMap())   // 1~100 掷骰

2.3 exp4j 语法与内置函数

支持的运算与函数(exp4j 内置):

  • 算术+ - * / %(取余)、^pow(幂)
  • 比较与逻辑:比较运算、逻辑运算
  • 数学函数sin cos tan log log10 ln sqrt abs ceil floor exp
kotlin
ExpressionEngine.evaluate("sqrt(level) * 2 + abs(offset)", mapOf("level" to 16.0, "offset" to -3.0))
// → 4 * 2 + 3 = 11.0
ExpressionEngine.evaluate("ceil(hp / 2)", mapOf("hp" to 7.0))   // → 4.0
ExpressionEngine.evaluate("2 ^ 10", emptyMap())                  // → 1024.0

三、条件 + 表达式 + 动作 一起用

典型流程:先用表达式算数值塞进变量袋,再用条件判断要不要执行,最后跑动作。

kotlin
val ctx = ActionContext(player = player, variables = mutableMapOf())

// 1. 表达式算伤害
val dmg = ExpressionEngine.evaluate("base + level * 1.5", mapOf("base" to 5.0, "level" to 12.0))
ctx.setVar("damage", dmg)
ctx.setVar("hp", player.health)

// 2. 条件判断
val condCtx = ConditionContext(variables = ctx.variables)
if (HasEnoughHpCondition().evaluate(condCtx)) {
    // 3. 执行动作
    ActionRegistry.get("heal")?.execute(ctx)
}

📖 继续阅读