diff --git a/game/core/meta_progression.gd b/game/core/meta_progression.gd index b3c16df5..b8797b51 100644 --- a/game/core/meta_progression.gd +++ b/game/core/meta_progression.gd @@ -271,14 +271,8 @@ func hero_override() -> Dictionary: # 锻造路线加值内联(原 forge_weapon_atk_bonus/forge_armor_ac_bonus 单调用点收编——输出逐字: # 路线等级×每级增量,选中态异常/未解锁防御回退 0) var fs := meta_state.forge_state() - var atk_bonus := 0 - var wrow: Dictionary[Variant, Variant] = db.forge_route(String(fs["weapon"])) - if not wrow.is_empty() and String(wrow.get("kind", "")) == "weapon" and _forge_route_unlocked(String(fs["weapon"])): - atk_bonus = int(fs["levels"].get(String(fs["weapon"]), 0)) * int(wrow.get("per_level_gain", 0)) - var ac_bonus := 0 - var arow: Dictionary[Variant, Variant] = db.forge_route(String(fs["armor"])) - if not arow.is_empty() and String(arow.get("kind", "")) == "armor" and _forge_route_unlocked(String(fs["armor"])): - ac_bonus = int(fs["levels"].get(String(fs["armor"]), 0)) * int(arow.get("per_level_gain", 0)) + var atk_bonus := _forge_axis_bonus(fs, "weapon", "weapon") + var ac_bonus := _forge_axis_bonus(fs, "armor", "armor") # 树淬炼 flat 内联(原 tree_stat_flat 单调用点收编——四线 flat 汇总同轮扫描,三轴输出逐字等价) var tree_atk := 0 var tree_hp := 0 @@ -299,6 +293,15 @@ func hero_override() -> Dictionary: } +# 锻造轴加值原语(选中路线等级×每级增量;选中态异常(未解锁/表缺行)防御回退 0——注入面只认合法态) +func _forge_axis_bonus(fs: Dictionary, sel_key: String, kind: String) -> int: + var rid := String(fs[sel_key]) + var row: Dictionary[Variant, Variant] = db.forge_route(rid) + if row.is_empty() or String(row.get("kind", "")) != kind or not _forge_route_unlocked(rid): + return 0 + return int(fs["levels"].get(rid, 0)) * int(row.get("per_level_gain", 0)) + + # ---- 天赋树段(设计权威 整合定稿 §1.4 一树双币三脉一脊)---- # 全树已购总等级(row-gating 输入——「投入点数累计解锁新行」) @@ -312,31 +315,28 @@ func _tree_spent_total() -> int: # 节点可购校验(行门槛 + 显式前置 + 币 + cap;free 节点=钥匙不经购买,彩蛋=觉醒不经购买) func tree_can_buy(node_id: String) -> bool: var row: Dictionary[Variant, Variant] = db.tree_node(node_id) - if row.is_empty(): - return false # 彩蛋不经购买(觉醒唯一入口=_check_easter_egg 特化判定——V8 反例:手动购亮=红) - if String(row.get("kind", "")) == "easter": - return false - var lvl := meta_state.tree_state().nodes.get(node_id, 0) - if lvl >= int(row.get("cap", 1)): + if row.is_empty() or String(row.get("kind", "")) == "easter": return false + var nodes: Dictionary[Variant, Variant] = meta_state.tree_state()["nodes"] + var lvl := int(nodes.get(node_id, 0)) + var blocked := lvl >= int(row.get("cap", 1)) # 刷新升级节点:cap 主语=Y 账本(单一事实源——树上入口与装配段同 cap 同价,防双账漂移) if node_id == "ks_refresh" and db.meta_attune_refresh_row(meta_state.attune_state().refresh_level + 1).is_empty(): - return false + blocked = true # 行门槛(一线一节点:脊柱节点第 N 级需全树总投入 ≥4×(N−1)) - if String(row.get("vein", "")) == "spine" and String(row.get("kind", "")) == "stat": - if _tree_spent_total() < db.meta_tree.level_gate(lvl + 1): - return false + if String(row.get("vein", "")) == "spine" and String(row.get("kind", "")) == "stat" and _tree_spent_total() < db.meta_tree.level_gate(lvl + 1): + blocked = true for req in (row.get("requires", []) as Array): - if meta_state.tree_state().nodes.get(String(req), 0) < 1: - return false + if int(nodes.get(String(req), 0)) < 1: + blocked = true # 等级阈值前置(requires_level {node_id: n}:前置节点等级 ≥ n 才可购; # 现役表零配置=空转零行为影响) var req_lv: Dictionary[Variant, Variant] = row.get("requires_level", {}) as Dictionary for req_id in req_lv.keys(): - if meta_state.tree_state().nodes.get(String(req_id), 0) < int(req_lv[req_id]): - return false - return true + if int(nodes.get(String(req_id), 0)) < int(req_lv[req_id]): + blocked = true + return not blocked # 节点购买(营地树 UI 唯一写口):树全钥石单币。free=工作间钥匙零币点亮