From 96d31705b3ef4c6d505fc86a82c98406499295e4 Mon Sep 17 00:00:00 2001 From: DKChan <524912269@qq.com> Date: Tue, 20 Oct 2026 23:02:13 +0800 Subject: [PATCH] =?UTF-8?q?feat(=E5=8D=A1=E2=91=A1=20T3):=207=20=E6=96=BD?= =?UTF-8?q?=E5=8A=A0=E7=82=B9=20ctx=20=E5=8C=96=20+=20dig=5Fcombo=20?= =?UTF-8?q?=E6=AD=BB=E8=B7=AF=E5=88=A0=E9=99=A4=20+=20run=5Fledger=20?= =?UTF-8?q?=E6=90=AC=E8=BF=90=E9=93=BE=E6=96=B9=E6=B3=95=E5=88=A0=E9=99=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - action_economy/damage_controller/reward_economy: dispatch 加 _ctx、写口改 EffectEngine.counter_add/counter(_ctx,...) - battle_orchestrator: _fx_emit→dispatch(counters_ctx)、counter_spend 静态化、删 counters_seed 回灌与 counters_export 战末导出、_feat_yield_adjust 删 dig_combo 死读数与 combo_cap 第五参(零行为差) - grant_segment: counter 读/value_counter/per ctx 化、_apply_counter_hit 写口静态化、combo_cap 收集删除 - run_ledger: 删 counters_seed_snapshot/counters_merge_export + 头注/字段注改 ctx 直写口径 数据行 domain/reset_at 删除与 feats.tres id 改名见 T6;核心层调用面已对齐新 API。 --- game/core/action_economy.gd | 12 ++++++------ game/core/battle_orchestrator.gd | 22 ++++++++-------------- game/core/damage_controller.gd | 8 ++++---- game/core/reward_economy.gd | 2 +- game/core/run_ledger.gd | 18 +++--------------- game/core/settlement/grant_segment.gd | 13 +++++-------- 6 files changed, 27 insertions(+), 48 deletions(-) diff --git a/game/core/action_economy.gd b/game/core/action_economy.gd index a559ad9f..9fef4244 100644 --- a/game/core/action_economy.gd +++ b/game/core/action_economy.gd @@ -102,15 +102,15 @@ func request_dig(chain_size: int, clears_map: bool) -> bool: # mod_eq 闸在行 when〕同面施加) var dig_refund := 0 if _fx != null: - for h in _fx.dispatch("dig_paid", {"ap_cost": cost, "ap_surplus": _ap - cost}): + for h in _fx.dispatch(_ctx, "dig_paid", {"ap_cost": cost, "ap_surplus": _ap - cost}): if String(h.get("kind", "")) == "counter_spend": var extra := int(h.get("value", 1)) if _ap >= cost + extra: cost += extra - _fx.counter_add(String(h.get("counter_id", "")), 1) + EffectEngine.counter_add(_ctx, String(h.get("counter_id", "")), 1) elif String(h.get("kind", "")) == "counter_add": var set_v = h.get("set", null) - _fx.counter_add(String(h.get("counter_id", "")), int(h.get("value", 0)) if set_v == null else int(set_v), set_v != null) + EffectEngine.counter_add(_ctx, String(h.get("counter_id", "")), int(h.get("value", 0)) if set_v == null else int(set_v), set_v != null) elif String(h.get("kind", "")) == "grant_ap": dig_refund += int(h.get("value", 0)) if _ap < cost: @@ -163,12 +163,12 @@ func request_stop() -> bool: # dig_stop 发射+施加(停手挂点〔弃图兑换〕:剩余 AP 随载荷外发,counter_add # value_event="ap_left" 取值面〔值=停手时刻真实余量〕;发射先于记账清零) if _fx != null: - for h in _fx.dispatch("dig_stop", {"ap_left": _ap}): + for h in _fx.dispatch(_ctx, "dig_stop", {"ap_left": _ap}): if String(h.get("kind", "")) == "counter_add": var val := int(h.get("value", 0)) if String(h.get("value_event", "")) == "ap_left": val = _ap - _fx.counter_add(String(h.get("counter_id", "")), val, h.has("set")) + EffectEngine.counter_add(_ctx, String(h.get("counter_id", "")), val, h.has("set")) _last_stop_ap = _ap _ap = 0 _finish_round("stopped", "same_board") @@ -190,7 +190,7 @@ func finish_round_stop(transfer: bool, transfer_pct: int = 100) -> void: var prev_layers := _charge_layers _charge_layers = mini(3, _charge_layers + _last_stop_ap) if _fx != null and _charge_layers >= 3 and prev_layers < 3: - _fx.dispatch("charge_full", {"layers": _charge_layers}) + _fx.dispatch(_ctx, "charge_full", {"layers": _charge_layers}) else: _rap += _last_stop_ap * maxi(1, transfer_pct) / 100 _last_stop_ap = 0 diff --git a/game/core/battle_orchestrator.gd b/game/core/battle_orchestrator.gd index c6814bbd..38c9b0f0 100644 --- a/game/core/battle_orchestrator.gd +++ b/game/core/battle_orchestrator.gd @@ -91,7 +91,7 @@ var counters_ctx: EffectContext = null # 四桶引用束(_ func _fx_emit(event: String, payload: Dictionary) -> Array: if _fx == null: return [] - return _fx.dispatch(event, payload, _fx_fact) + return _fx.dispatch(counters_ctx, event, payload, _fx_fact) # round_start 发射+施加(内容数据驱动扩展批 T3——grant_ap mode:queue=当轮入队,行动经济轮切换 @@ -395,9 +395,8 @@ func begin_battle(enc: Dictionary) -> bool: var tree_rules: Array[Variant] = enc.get("tree_rules", []) as Array # 效果引擎订阅重建(每战从持有集/装备集重建,中途获得下一战生效; # 树规则合成订阅同面装载。装载序=feats 表序→treasure 表序→树规则,写死保种子复放。 - # adventure 域计数器从共享引用回灌〔跨战持久〕) + # 计数器四桶经 counters_ctx 引用宿主容器,无回灌时点(旧 counters_seed 删除)) _fx.rebuild(feat_ids, attunement, tree_rules) - _fx.counters_seed(_ledger.counters_seed_snapshot()) # 秘宝常时参数注入(装配集 kind 分发:远程镐挖距放宽/信标网络封印可达豁免; # 缺省 0/false=零装配零扰动。注入在首板 install 之后〔板在早段〕——板生成不读两参数, # 参数只影响挖掘/插棋动作判据,时序安全) @@ -641,20 +640,16 @@ func _settle() -> void: # ---- 授予段 helpers(极性路由)---- # 开格产出乘区(贪婪矿灯/矿脉直觉/赌徒的血签事件收集器注入): -# positive=power ×(1+静态 mult% + 矿脉直觉连击加成 min(cap,combo)×10%);negative=power ×(1+cost%)。 -# 全零收集器=原快照原样返回(零扰动)。combo 读数=效果引擎 dig_combo 计数器(safe+1/mine 清零, -# 跨轮累计)。 -func _feat_yield_adjust(snap: Dictionary, positive: bool, pos_m: int, neg_m: int, combo_cap: int) -> Dictionary: - var combo_val := _fx.counter("dig_combo") if _fx != null else 0 - if positive and pos_m <= 0 and combo_cap <= 0: +# positive=power ×(1+静态 mult%);negative=power ×(1+cost%)。 +# 全零收集器=原快照原样返回(零扰动)。旧 dig_combo 连击加成死读数(全仓无声明行、combo_val 恒 0)已删——零行为差。 +func _feat_yield_adjust(snap: Dictionary, positive: bool, pos_m: int, neg_m: int) -> Dictionary: + if positive and pos_m <= 0: return snap if not positive and neg_m <= 0: return snap var out: Dictionary[Variant, Variant] = snap.duplicate() var power := int(out.get("power", int(_reward_economy.polarity_row(String(out.get("cell_type", "")), "positive" if positive else "negative").power))) var pct := pos_m if positive else neg_m - if positive and combo_cap > 0: - pct += mini(combo_cap, combo_val) * 10 out["power"] = maxi(1, int(round(float(power) * (1.0 + float(pct) / 100.0)))) return out @@ -721,7 +716,7 @@ func use_treasure(handle: int, target: Vector2i) -> Dictionary: var tu_hits := _fx_emit("treasure_used", {"item_id": String(v.item_id), "target": target}) for h in tu_hits: if String(h.get("kind", "")) == "counter_spend": - if not _fx.counter_spend(String(h.get("counter_id", "")), int(h.get("value", 1))): + if not EffectEngine.counter_spend(counters_ctx, String(h.get("counter_id", "")), int(h.get("value", 1))): var vrow: Dictionary[Variant, Variant] = db.treasure_item_row(String(v.item_id)) var cn_info: int = int(vrow.get("charge_n", 0)) # 读受理行自身 return {"ok": false, "reason": "%s:安全格积点未达(%d/%d)" % [String(vrow.get("display_name", "")), _attune_safe_seen % cn_info if cn_info > 0 else 0, cn_info]} @@ -1129,8 +1124,7 @@ func _battle_over(result: String) -> void: for axis in _fx_bonus_delta.keys(): _ledger.bonus_add_axis(axis, int(_fx_bonus_delta[axis])) _fx_bonus_delta = {"atk": 0, "max_hp": 0, "armor_class": 0, "ap": 0} - if _fx != null: - _ledger.counters_merge_export(_fx.counters_export()) + # 搬运链删除:adventure 桶经 ctx 引用直写 RunLedger,无战末导出时点(旧 counters_export/merge_export) # 映射随战斗结束退役(地图战斗资源 义务④——下一场战斗 = 新板新 scope 批,roll_board 相位守卫的前提) var hero_hp_left := int(_enemy_system.hero_unit().get("hp", 0)) # despawn 前捕获(信号载荷供呈现层"HP 带入下一层") var gp_dropped := _roll_gp_drop() # 战斗掉落(escrow 随此值上抛即弃) diff --git a/game/core/damage_controller.gd b/game/core/damage_controller.gd index 9e4fc7a7..18c0303d 100644 --- a/game/core/damage_controller.gd +++ b/game/core/damage_controller.gd @@ -77,7 +77,7 @@ func set_fx(fx: EffectEngine, ctx: EffectContext) -> void: func _fx_hits(event: String, payload: Dictionary) -> Array: if _fx == null: return [] - return _fx.dispatch(event, payload, _fx_fact) + return _fx.dispatch(_ctx, event, payload, _fx_fact) # 事件发射薄面(免施加观测位——enemy_hp_threshold 等现无订阅者的事件保留零扰动面) @@ -344,13 +344,13 @@ func _hero_attack_base_value(t: Dictionary, ctx: Dictionary) -> float: if String(h.get("kind", "")) == "attack_bonus": var contrib := int(h.get("value", 0)) * _per_value(String(h.get("per", "")), ac_payload) if h.has("value_counter") and String(h.get("value_counter", "")) != "": - contrib = _fx.counter(String(h.get("value_counter", ""))) + contrib = EffectEngine.counter(_ctx, String(h.get("value_counter", ""))) base_value += float(contrib) # 计数器施加(attack_commit 命中行内 counter_add〔用后清零行〕,命中序=声明序) for h in ac_hits: if String(h.get("kind", "")) == "counter_add": var set_v = h.get("set", null) - _fx.counter_add(String(h.get("counter_id", "")), int(h.get("value", 0)) if set_v == null else int(set_v), set_v != null) + EffectEngine.counter_add(_ctx, String(h.get("counter_id", "")), int(h.get("value", 0)) if set_v == null else int(set_v), set_v != null) # 任意真族:厚积薄发满层 spike 倍乘(≥3 层——强制必中已在折扣拍承载) if ctx["spike_ready"]: for h in ac_hits: @@ -463,7 +463,7 @@ func _resolve_enemy_skill(t: Dictionary) -> void: fx_ac_request.call(h) # 石肤 AC 累积归编排器单点(set_hero_ac_override 消费面) "counter_add": var set_v = h.get("set", null) - _fx.counter_add(String(h.get("counter_id", "")), int(h.get("value", 0)) if set_v == null else int(set_v), set_v != null) + EffectEngine.counter_add(_ctx, String(h.get("counter_id", "")), int(h.get("value", 0)) if set_v == null else int(set_v), set_v != null) if shield > 0: total = maxi(int(db.settlement.damage_floor), total - shield) units.apply_damage(hero, total) diff --git a/game/core/reward_economy.gd b/game/core/reward_economy.gd index 71f685cf..a74842af 100644 --- a/game/core/reward_economy.gd +++ b/game/core/reward_economy.gd @@ -64,7 +64,7 @@ func roll_board(eligible: Array) -> bool: # bias_rewards 订阅命中合计=偏运权重加算(行 value_from magnitude 定影);零命中=原行集零扰动) var luck_bias := 0 if _fx != null: - for h in _fx.dispatch("reward_roll", {"polarity": "positive", "cell_count": list.size()}): + for h in _fx.dispatch(_ctx, "reward_roll", {"polarity": "positive", "cell_count": list.size()}): if String(h.get("kind", "")) == "bias_rewards": luck_bias += int(h.get("value", 0)) var cell_rows: Array[Variant] = _biased_cell_rows(luck_bias) # cell 池正向行 weight>0(偏运硬币装配时稀有正向 kinds 权重 +N——池结构零触碰) diff --git a/game/core/run_ledger.gd b/game/core/run_ledger.gd index cad9650e..22899de4 100644 --- a/game/core/run_ledger.gd +++ b/game/core/run_ledger.gd @@ -4,12 +4,12 @@ extends RefCounted # 可写」收口 = 单类持四账)。 # 所有权:AdventureRunner 持有(开局构造、冒险全程唯一宿主);LevelRunner 经 set_run_ledger # 下传并装配 encounter;战斗侧(BattleOrchestrator)经 encounter["ledger"] 拿本类引用, -# 只走下方 read/append 原语——战末 export/开局 seed 时点语义不变(确定性设计原样保留, -# 只把「函数签名上不可见的共享可变引用」换成签名可见的显式类)。 +# 只走下方 read/append 原语;adventure 桶经 EffectContext 引用被效果引擎就地直写(无战末 export/ +# 开局 seed 搬运时点——跨战持久=同一字典引用,随本类生灭)。 var attune_charges: Dictionary[Variant, Variant] = {} # 同调主动件充能账(use_treasure 扣减;断点随局回档) var vision_counter: Dictionary[Variant, Variant] = {} # 真视类使用计数(冒险开始置 {"used":0}; # 缺省空 = 调试/单场战斗不计——enc 缺键守卫语义) -var adventure_counters: Dictionary[Variant, Variant] = {} # adventure 域效果计数器(rebuild 回灌/战末导出回写目标) +var adventure_counters: Dictionary[Variant, Variant] = {} # adventure 桶(adv_ 前缀计数器;经 EffectContext 引用被引擎就地直写、跨战持久随本类生灭) var bonus: Dictionary[Variant, Variant] = {} # 统一冒险加算区(冒险开始置四轴零账——商店购买/三选一属性件/战末 bonus_delta 汇入) @@ -33,18 +33,6 @@ func vision_count_add(n: int) -> void: vision_counter["used"] = int(vision_counter.get("used", 0)) + n -func counters_seed_snapshot() -> Dictionary: - return adventure_counters # 回灌读面(时点 = begin_battle rebuild 后——语义不变) - - -func counters_merge_export(exported: Dictionary) -> void: - # 战末回写(原编排器逐字语义:仅非空账参与、逐键覆写) - if adventure_counters.is_empty(): - return - for cid in exported.keys(): - adventure_counters[cid] = int(exported[cid]) - - func bonus_add_axis(axis: String, delta: int) -> void: # 原编排器战末汇入逐字语义(has 闸——账外轴丢弃) if bonus.has(axis): diff --git a/game/core/settlement/grant_segment.gd b/game/core/settlement/grant_segment.gd index 59a0bc30..39356838 100644 --- a/game/core/settlement/grant_segment.gd +++ b/game/core/settlement/grant_segment.gd @@ -51,15 +51,12 @@ func run(ri: int) -> void: "new_resource_type": is_new_type}) var pos_m := 0 var neg_m := 0 - var combo_cap := -1 for h in dr_hits: if String(h.get("kind", "")) != "yield_mult": continue pos_m += int(h.get("mult", 0)) neg_m += int(h.get("cost_mult", 0)) - if int(h.get("cap", 0)) > 0: - combo_cap = int(h.cap) # 矿脉直觉连击上限 - oc._grant_routed(oc._feat_yield_adjust(snap, true, pos_m, neg_m, combo_cap), "positive", "safe_cell", evt.cell, ri, "") + oc._grant_routed(oc._feat_yield_adjust(snap, true, pos_m, neg_m), "positive", "safe_cell", evt.cell, ri, "") # 计数器执行(连击计数——加法族,乘区收集后执行=本格兑付用旧值,与迁移前逐位一致) for h in dr_hits: if String(h.get("kind", "")) == "counter_add": @@ -100,7 +97,7 @@ func run(ri: int) -> void: halve_pct += int(h.get("value", 0)) "damage_reduce": if h.has("value_counter") and String(h.get("value_counter", "")) != "": - mine_reduce += oc._fx.counter(String(h.get("value_counter", ""))) # 安全帽——层值减免 + mine_reduce += EffectEngine.counter(oc.counters_ctx, String(h.get("value_counter", ""))) # 安全帽——层值减免 else: mine_reduce += int(h.get("value", 0)) # 背水——定值减免 "heal": @@ -122,7 +119,7 @@ func run(ri: int) -> void: _apply_counter_hit(h) if not oc._hits_of(mh_hits, "reveal_tiles").is_empty(): oc._fx_enqueue_reveal() # 见血开窍——每颗雷一次揭示(授予段末统一兑付) - oc._grant_routed(oc._feat_yield_adjust(snap, false, 0, 0, -1), "negative", "mine_hit", evt.cell, ri, "", "", halve_pct) + oc._grant_routed(oc._feat_yield_adjust(snap, false, 0, 0), "negative", "mine_hit", evt.cell, ri, "", "", halve_pct) for h in mh_hits: if String(h.get("kind", "")) == "open_ticket" and String(h.get("channel", "")) == "reflect": var nct := oc._damage.open_ticket(DamageController.KIND_BOARD_BLAST, "attune_nest_counter", "惊巢反制·反弹", "board", @@ -202,7 +199,7 @@ func run(ri: int) -> void: var re_fx := oc._fx_emit("round_end", {"round": ri}) for h in re_fx: if String(h.get("kind", "")) == "open_ticket" and String(h.get("channel", "")) == "blast": - var mg_layers := oc._fx.counter(String(h.get("per", ""))) + var mg_layers := EffectEngine.counter(oc.counters_ctx, String(h.get("per", ""))) var mg_total := int(h.get("value", 0)) * mg_layers if mg_total > 0: # source_class 用中性名;per-counter 反打通道保留泛用面 @@ -322,7 +319,7 @@ func _judge_seal(evt: Dictionary, ri: int) -> void: # counter_add 三行组单点(原五位分支本体逐字收拢——kind 分派随段归位 P1-1) func _apply_counter_hit(h: Dictionary) -> void: var set_v = h.get("set", null) - oc._fx.counter_add(String(h.get("counter_id", "")), int(h.get("value", 0)) if set_v == null else int(set_v), set_v != null) + EffectEngine.counter_add(oc.counters_ctx, String(h.get("counter_id", "")), int(h.get("value", 0)) if set_v == null else int(set_v), set_v != null) # grant_material 兑付块单点(原三位分支本体逐字收拢——source_class 两态 safe_cell/seal_hit 由参承载)