pub enum Predicate {
HasType(String),
StatIs(String),
RelayIntLt(i64),
HasVolatile(String),
MoveTypeIsDefenderType,
TargetHasStatus(String),
Not(Box<Predicate>),
TargetHasAnyStatus,
LevelGE,
SelfHpBelow {
num: u32,
den: u32,
},
SourceHasStatus(String),
}Expand description
A closed predicate (doc 11 §1.1). Used by unless/when/cond guards.
Variants§
HasType(String)
The selector has the named type (chart membership).
StatIs(String)
The in-flight folded stat equals the named stat (the Sandstorm
WeatherModifyStat SpD case, doc 11 §1). Requires the driver to stash the
in-flight stat index in scratch via the binding; see crate::run_ops.
RelayIntLt(i64)
The current relay-as-int is strictly less than n (the Clear-Body
VetoIf(RelayIntLt(0)) pattern, doc 11 §1).
HasVolatile(String)
The target selector has the named volatile live (blueprint 15 §2 /
§3, the new predicate). The Gen-1 Substitute block on side-status:
VetoIf(HasVolatile("Substitute")) (status fails through a Substitute,
status_effects.rs). The volatile name is the game’s vocabulary; the binding
resolves it against the live ctx.effects arena
(RuleBindings::has_volatile). Pure
read; no entropy. Game-agnostic: the rules crate names no concrete volatile.
MoveTypeIsDefenderType
The in-flight move’s type equals one of the target selector’s types
(blueprint 15 §2 / §3). The Gen-1 burn/freeze/paralyze self-type-immunity
quirk #23: VetoIf(MoveTypeIsDefenderType) — a Fire-type can’t be burned by
a Fire move, etc. (status_effects.rs:85/110/135). The move type is
recovered from the compiled hook’s move_type_index (the record’s type:);
the binding answers membership
(RuleBindings::move_type_is_defender_type).
Pure read; no entropy.
TargetHasStatus(String)
The target selector currently has the named non-volatile status
(blueprint 15 §2, the Dream Eater sleep gate
VetoIf(!TargetHasStatus("sleep"))). The status name is the game’s
vocabulary, resolved by the binding’s status_index_of (compiled into the
status map) + RuleBindings::has_status.
Pure read; no entropy.
Not(Box<Predicate>)
Logical negation of a closed predicate — VetoIf(Not(TargetHasStatus( "sleep"))) fires when the target is NOT asleep (the Dream Eater gate:
drain only a sleeping target). Generic over any inner predicate; pure.
TargetHasAnyStatus
The target selector has ANY non-volatile status. Lets a compound
status move (VetoIf(TargetHasAnyStatus) then InflictStatus +
InflictVolatile) apply atomically or not at all — the Gen-1 Toxic
“already-statused ⇒ nothing happens” rule. The engine knows no concrete
status; the binding answers via
RuleBindings::has_any_status.
Pure read; no entropy.
LevelGE
The source selector’s level is ≥ the target selector’s level
(blueprint 15 §2/§3, the OHKO gate). The Gen-1 one-hit-KO connects only
when the user’s level is at least the foe’s (bug #19: a foe of strictly
higher level is immune). The level is the game’s per-battler quantity —
answered by RuleBindings::battler_level
(the rules crate stays game-agnostic: it reads level only through the binding,
never off BattlerState directly), which defaults to 0 so a game that
never authors LevelGE is unaffected.
Pure read; no entropy. Game-agnostic: the rules crate names no
game-specific level concept — only “a number the binding supplies per battler”.
SelfHpBelow
The source selector’s HP fraction is strictly below num/den (the
wuxia 「血越低攻越高」 self-HP-threshold gate, affinity.md §四 吕醉仙/苏夜).
True iff source_hp * den < source_max_hp * num (so < num/den); den
clamps to ≥1. Reads the SOURCE (the acting battler) directly off ctx
(hp/max_hp are engine fields, no binding needed), so a ModifyDamage
hook can scale outgoing damage only when the actor’s own HP is low. Pure
read; no entropy. Game-agnostic: a fraction of an engine HP field — no
game-specific/wuxia concept named here.
Fields
SourceHasStatus(String)
The source selector currently has the named non-volatile status —
exactly TargetHasStatus but on the SOURCE
(the acting battler) rather than the dispatch target. Lets a BeforeMove
VetoIf(SourceHasStatus("...")) skip the HOLDER’s OWN move (the wuxia
眩晕/控制 gate, affinity.md §四). The status name is the game’s vocabulary,
resolved by the same status_index_of map + the EXISTING
RuleBindings::has_status binding (no new
binding). Pure read; no entropy.