feat(fx): 迭代20 T1 效果引擎词表扩签+发射点施加面(专长实装批 A段一)

词表:EVENTS 16→18(+dig_stop/battle_won)、FACTS 9→17(8 新事实含 hp_ratio 生命比例前置兑付)、
EFFECT_KINDS +7 新类型(heal/ac_bonus/damage_reduce/bonus_delta/blast_scaled/preview_area/
target_attack_bonus)、OPS +mod_eq;DO_KEYS +4 键(value_event/value_counter/domain/axis)。
rewrite_board 暂留至 T3 删行同批除名(purge_sapper 仍在表),消费分支已摘除。

施加面:battle_orchestrator(dig_reveal 三事实/mine_hit 五新施加/terrain 减伤前置/flag_hit 四新/
round_end GP+AP 队列/battle_won 发射/bonus_delta 战末汇入/ac_bonus 累积器/揭示队列_.flush_pending_reveals)
+damage_controller(attack value_counter rider/敌技 damage_reduce/hp_ratio fact/kill 揭示回调)
+action_economy(dig_paid 返还/dig_stop 发射/上轮耗尽旗标)+minesweeper fx_reveal 效果通道
(只揭真格信息红线)+rng fx_reveal 分签。

T6 承载:EffectEngine adventure 域计数器(domain 键/counters_export/counters_seed)+
AdventureRunner.adventure_counters 共享引用(attune_charges 先例)+断点随档。

测试:effect_words_t1_test 新套(V1:新词在册/出域四路被拒/seed-export 往返/mod_eq 预评估口径)
入 run_all 19 套全绿;冒烟 846/0 持平基线零破坏。
This commit is contained in:
DKChan committed 2026-10-11 22:42:51 +08:00
1 parent 5dbcae227e
commit a57489e970
10 files changed
+506 -69

No files matched your search

+63 -13
View File
@@ -16,10 +16,11 @@
class_name EffectEngine
extends RefCounted
## 事件词汇(16 个发射点——需求卡片 §3.1 定稿;4 个登记暂不做事件不入本表)
## 事件词汇(迭代 20 专长实装批 T1 扩签——16→18:+dig_stop 停手挂点〔弃图兑换〕
## +battle_won 战斗胜利〔战地包扎〕;原 16 发射点不动)
const EVENTS := ["dig_reveal", "dig_paid", "flag_hit", "mine_hit", "attack_commit", "clamp_check",
"armor_roll", "kill", "damage_taken", "enemy_hp_threshold", "round_start", "flag_settle",
"round_end", "reward_roll", "treasure_used", "charge_full"]
"round_end", "reward_roll", "treasure_used", "charge_full", "dig_stop", "battle_won"]
## 扫雷侧事件集(🔴 流派扫雷触发铁律新形态:每流派 ≥1 行订阅本集事件——schema 加载校验。
## 原 MINE_HOOKS 的同义迁移:挖掘/标旗/轮末结算面事件)
@@ -32,26 +33,48 @@ const EFFECT_KINDS := ["add_ticket_rider", "modify_ticket", "damage_mult", "open
"attack_bonus", "attack_segments", "yield_mult", "spawn_spell", "overflow", "grant_material",
"grant_ap", "grant_gp", "bias_wallet", "shield", "spike", "apply_status", "counter_add",
"counter_spend", "rewrite_board", "reveal_tiles", "remove_mines", "refresh_pick",
"bias_rewards", "preview"]
"bias_rewards", "preview",
# 迭代 20 专长实装批 T1 扩签六型(奇物.md 基础件表 27 件声明清单——落法映射 commit 留痕):
# heal=回复生命〔血蜜/战地包扎〕;ac_bonus=护甲加值累积器〔封印桩本轮/石肤本场 cap〕;
# damage_reduce=受伤减免〔背水/安全帽〕;bonus_delta=冒险加算区增量〔血税 双向——battle 末汇入
# runner.bonus〕;blast_scaled=雷罚标定群伤〔陷阱爆发——值=事件伤害×mult〕;
# preview_area=资源类型预告〔示警烟火——3×3 邻域资源类型,不揭安危位置〕;
# target_attack_bonus=单位标记加伤〔处刑台——敌血量阈值挂单位字典,主角攻击面通用消费〕
"heal", "ac_bonus", "damage_reduce", "bonus_delta", "blast_scaled", "preview_area",
"target_attack_bonus"]
# 注:rewrite_board 保留至本批 T3——老 27 行 purge_sapper(净化工兵)仍在表,删行同批除名
# (迭代 20 卡 V14 连带清理;编排器消费分支已先行摘除=命中零消费 no-op 过渡)
## fact 条件词汇(封闭枚举 9 项——需求卡片 §四定稿)
## fact 条件词汇(封闭枚举——迭代 20 T1 扩签 9→17:payload 同名键直读面〔fact 取值序 payload
## 优先——effect_engine._fact_value 既有机制〕。new_resource_type=首开资源类型〔地质学家〕;
## is_edge_cell=边缘格〔边陲矿工〕;is_blank_zero=空白连锁〔跳格采掘〕;dug_under_flag=被挖格
## 当时有旗〔破封一击〕;ap_exhausted_last=上轮 AP 耗尽〔一滴不剩〕;hp_ratio=生命比例〔背水
## 06 前置条兑付〕;amount=单次伤害量〔保险丝〕;ap_left=停手剩余 AP〔弃图兑换〕)
const FACTS := ["matchup", "is_first_dig_of_battle", "terrain_kind", "target_armor_class",
"flags_count", "charge_layers", "nest_count", "round_index", "counter"]
"flags_count", "charge_layers", "nest_count", "round_index", "counter",
"new_resource_type", "is_edge_cell", "is_blank_zero", "dug_under_flag",
"ap_exhausted_last", "hp_ratio", "amount", "ap_left"]
## when 算子词汇(封闭——fact 查询面落法随批登记:mod_zero=计数器取模判满〔掘进蓄能〕、
## advantageous=克制矩阵正面判定〔淬毒刃纹〕、gte_ref/lt_ref=与另一计数器比较〔深挖钻头配额〕、
## ends_with=后缀匹配〔对某甲族的泛条件〕。均系映射表现状条件装进 9 项 fact 的查询面落法,
## 代拍板白名单覆盖,commit 留痕)
## ends_with=后缀匹配〔对某甲族的泛条件〕、mod_eq=取模余数判定〔双管镐每第 2 次——value=模数
## ref=余数;dispatch 预评估口径〔when 于命中前读计数器现值〕下「每第 N 次」系用 ref=N-1 表达〕。
## 均系映射表现状条件装进 fact 的查询面落法,代拍板白名单覆盖,commit 留痕)
const OPS := ["eq", "neq", "gt", "gte", "lt", "lte", "ends_with", "has", "mod_zero",
"advantageous", "gte_ref", "lt_ref"]
"advantageous", "gte_ref", "lt_ref", "mod_eq"]
## when 条件键白名单(trigger 行 when 数组元素键)
const WHEN_KEYS := ["fact", "op", "value", "id", "ref", "value_from"]
## do 效果键白名单(trigger 行 do 字典键——零裸 flat 同族护栏:kind 外键全部参数引用面)
## do 效果键白名单(trigger 行 do 字典键——零裸 flat 同族护栏:kind 外键全部参数引用面。
## 迭代 20 T1 扩签四键:value_event=事件载荷取值键名〔爆破会计——counter_add 值=本轮挖格花费
## payload.ap_cost〕;value_counter=计数器取值键〔疼痛记忆/弃图兑换——attack rider 值=账面层值〕;
## domain=计数器寿命域〔battle=战斗域重建清零〔缺省〕/adventure=跨战持久随 battle 末导出〕;
## axis=bonus_delta 加算区轴向)
const DO_KEYS := ["kind", "value", "value_from", "delta", "delta_from", "mult", "mult_from",
"cap", "cap_from", "cost_mult", "per", "divisor", "dtype", "mode", "channel", "counter_id",
"reset_at", "set", "status_id", "label", "fallback", "target_kinds", "trade_atk", "trade_hit"]
"reset_at", "set", "status_id", "label", "fallback", "target_kinds", "trade_atk", "trade_hit",
"value_event", "value_counter", "domain", "axis"]
## 主动件分发通道(不经事件订阅——刷新/显影/移除是玩家主动动作;use_treasure 按 kind 分发)
const ACTIVE_KINDS := ["reveal_tiles", "preview", "grant_ap", "remove_mines", "refresh_pick"]
@@ -60,6 +83,8 @@ const ACTIVE_KINDS := ["reveal_tiles", "preview", "grant_ap", "remove_mines", "r
var _triggers: Array = [] # [{source, id, on, when, do}](装载序=声明序,重建时定死)
var _counters: Dictionary = {} # counter_id → int(battle 域账本;重建清零;重置点由订阅行声明)
var _reset_on_round_start: Array[String] = [] # round_start 重置点计数器名单(装载时收集)
var _adventure_counter_ids: Array[String] = [] # domain=adventure 计数器名单(T6——重建时收集、不清零;
# battle 末 export → 冒险账本、begin_battle seed 回灌)
var db: ConfigDb # 矩阵/表读取(advantageous 算子消费)——可空(纯计数器用法零依赖)
@@ -72,8 +97,8 @@ func _init(db_ref: ConfigDb = null) -> void:
## 声明收集重置点(round_start)。
func rebuild(feat_ids: Array, item_ids: Array, tree_rules: Array = []) -> void:
_triggers.clear()
_counters.clear()
_reset_on_round_start.clear()
_adventure_counter_ids.clear()
if db != null and db.feats != null:
for row in db.feats.rows:
var fid := String(row.get("feat_id", ""))
@@ -99,6 +124,8 @@ func rebuild(feat_ids: Array, item_ids: Array, tree_rules: Array = []) -> void:
"posture_bulwark":
_push_trigger("tree", rk, {"on": "damage_taken",
"do": {"kind": "shield", "value": 1}}, {})
# 计数器账本重建(T6——battle 域清零照旧;adventure 域由 counters_seed 回灌〔rebuild 后调用〕)
_counters = {}
func _push_trigger(source: String, id: String, tr: Dictionary, row: Dictionary) -> void:
@@ -127,6 +154,11 @@ func _push_trigger(source: String, id: String, tr: Dictionary, row: Dictionary)
var cid := String(do_d.counter_id)
if not _reset_on_round_start.has(cid):
_reset_on_round_start.append(cid)
# 寿命域收集(T6——domain=adventure 计数器跨战持久:重建不清零、battle 末导出回冒险账本)
if do_d.has("counter_id") and String(do_d.get("domain", "")) == "adventure":
var aid := String(do_d.counter_id)
if not _adventure_counter_ids.has(aid):
_adventure_counter_ids.append(aid)
## 订阅查询面(发射点缺省行为仲裁用——如 round_end 无 transfer 订阅时走 RAP 转存)
@@ -181,6 +213,21 @@ func counter_spend(counter_id: String, value: int) -> bool:
return true
## adventure 域计数器导出(T6——battle 末调用,快照回冒险账本;仅 domain=adventure 名单内键)
func counters_export() -> Dictionary:
var out := {}
for cid in _adventure_counter_ids:
out[cid] = int(_counters.get(cid, 0))
return out
## adventure 域计数器回灌(T6——rebuild 后由发射宿主调用:冒险账本值回填名单内键,缺省 0;
## 名单=本次 rebuild 装载行声明 domain=adventure 的 counter_id 集)
func counters_seed(seed: Dictionary) -> void:
for cid in _adventure_counter_ids:
_counters[cid] = maxi(0, int(seed.get(cid, 0)))
# ---- when 判定(条件谓词——零随机全确定) ----
func _when_ok(when: Array, payload: Dictionary, facts: Callable) -> bool:
@@ -229,6 +276,9 @@ func _cond_ok(c: Dictionary, payload: Dictionary, facts: Callable) -> bool:
"mod_zero":
var m := int(val)
return m > 0 and int(actual) % m == 0
"mod_eq":
var me_m := int(val)
return me_m > 0 and int(actual) % me_m == int(c.get("ref", 0))
"advantageous":
# 克制矩阵正面判定(matchup = "{attack_type}_vs_{armor}"——矩阵值 > 0 = 克制成立)
return _counter_delta_of(String(actual)) > 0
@@ -326,7 +376,7 @@ static func validate_trigger_row(rid: String, row: Dictionary, triggers: Array,
## rewrite_board、apply_status——发射点逐条执行。
static func combo_of(kind: String) -> String:
match kind:
"add_ticket_rider", "attack_bonus", "grant_material", "counter_add", "shield":
"add_ticket_rider", "attack_bonus", "grant_material", "counter_add", "shield", "heal", "ac_bonus", "damage_reduce", "bonus_delta":
return "additive"
"grant_ap":
return "additive" # mode:transfer 由发射点即时执行族承载(转移非加法)
@@ -338,6 +388,6 @@ static func combo_of(kind: String) -> String:
return "ordered_write"
"counter_spend":
return "ordered_spend"
"open_ticket", "rewrite_board", "apply_status":
"open_ticket", "apply_status", "blast_scaled":
return "immediate"
return "immediate" # 默认即时执行(每条命中各自执行一次)