diff --git a/game/core/battle_orchestrator.gd b/game/core/battle_orchestrator.gd index c47203a3..3136eaaa 100644 --- a/game/core/battle_orchestrator.gd +++ b/game/core/battle_orchestrator.gd @@ -680,7 +680,7 @@ func _roll_round_actions() -> void: # 容器内直读主角行) var facts := { "round_index": round_index, - "last_round_end": "none" if (action_economy.last_round_end as Dictionary).is_empty() else String((action_economy.last_round_end as Dictionary).get("path_tag", "none")), + "last_round_end": "none" if action_economy.last_round_end().is_empty() else String(action_economy.last_round_end().get("path_tag", "none")), "mines_hit_last": int(_mines_hits["last"]), "mines_hit_total": int(_mines_hits["total"]), } diff --git a/game/core/config_domain_combat.gd.uid b/game/core/config_domain_combat.gd.uid new file mode 100644 index 00000000..517c2070 --- /dev/null +++ b/game/core/config_domain_combat.gd.uid @@ -0,0 +1 @@ +uid://dpy0a6fcggbwe diff --git a/game/core/config_domain_crossrun.gd.uid b/game/core/config_domain_crossrun.gd.uid new file mode 100644 index 00000000..a44745fc --- /dev/null +++ b/game/core/config_domain_crossrun.gd.uid @@ -0,0 +1 @@ +uid://du0gxv0lnrxnp diff --git a/game/core/config_domain_run.gd.uid b/game/core/config_domain_run.gd.uid new file mode 100644 index 00000000..3e07d6eb --- /dev/null +++ b/game/core/config_domain_run.gd.uid @@ -0,0 +1 @@ +uid://jaxlqd8ml3co diff --git a/game/core/meta_progression.gd b/game/core/meta_progression.gd index 0d9687c1..e762d613 100644 --- a/game/core/meta_progression.gd +++ b/game/core/meta_progression.gd @@ -145,7 +145,7 @@ func forge_buy_level(route_id: String) -> bool: var row: Dictionary[Variant, Variant] = db.crossrun.forge.route(route_id) if row.is_empty() or not _forge_route_unlocked(route_id): return false - var lvl := meta_state.forge_state().levels.get(route_id, 0) + var lvl: int = meta_state.forge_state().levels.get(route_id, 0) if lvl >= int(row.get("cap", 0)): return false var price := ForgeTable.level_price(row, lvl) @@ -206,13 +206,13 @@ func forge_shop_status() -> Array: var out: Array[Dictionary] = [] for row in db.crossrun.forge.route_rows(): var rid := String(row.get("route_id", "")) - var lvl := meta_state.forge_state().levels.get(rid, 0) + var lvl: int = meta_state.forge_state().levels.get(rid, 0) var cap_v := int(row.get("cap", 0)) var unlocked := _forge_route_unlocked(rid) var prereq := String(row.get("prereq_route", "")) - var plvl := meta_state.forge_state().levels.get(prereq, 0) if prereq != "" else 0 + var plvl: int = meta_state.forge_state().levels.get(prereq, 0) if prereq != "" else 0 var pcap := int(db.crossrun.forge.route(prereq).get("cap", 0)) if prereq != "" else 0 - var selected := (String(row.get("kind", "")) == "weapon" and meta_state.forge_state().weapon == rid) \ + var selected: bool = (String(row.get("kind", "")) == "weapon" and meta_state.forge_state().weapon == rid) \ or (String(row.get("kind", "")) == "armor" and meta_state.forge_state().armor == rid) out.append({ "route_id": rid, @@ -362,7 +362,7 @@ func tree_buy(node_id: String) -> bool: func tree_toggle_fork(group: String, side: String) -> bool: if not db.crossrun.meta_tree.FORK_GROUPS.has(group) or not (side == "a" or side == "b"): return false - var cur := meta_state.tree_state().fork_sides.get(group, "") + var cur: String = meta_state.tree_state().fork_sides.get(group, "") if cur == "" or cur == side: return false # 未解锁走购买面;同态零操作 meta_state.set_fork_side(group, side) @@ -521,7 +521,7 @@ func attune_camp_status() -> Dictionary: "equipped": equipped.has(iid), "unlocked": meta_state.item_unlocked(iid), }) - var lvl := meta_state.attune_state().refresh_level + var lvl: int = meta_state.attune_state().refresh_level var next_row: Dictionary[Variant, Variant] = db.crossrun.meta.attune_refresh_row(lvl + 1) return { "slots": Attunement.slots(db, save), diff --git a/game/core/meta_state_store.gd.uid b/game/core/meta_state_store.gd.uid new file mode 100644 index 00000000..43f69277 --- /dev/null +++ b/game/core/meta_state_store.gd.uid @@ -0,0 +1 @@ +uid://bc5perm32w2yp diff --git a/game/core/slot_store.gd.uid b/game/core/slot_store.gd.uid new file mode 100644 index 00000000..04116c73 --- /dev/null +++ b/game/core/slot_store.gd.uid @@ -0,0 +1 @@ +uid://dylsba7whx5ql diff --git a/game/data/schemas/adventure_cap_segment.gd.uid b/game/data/schemas/adventure_cap_segment.gd.uid new file mode 100644 index 00000000..9437e666 --- /dev/null +++ b/game/data/schemas/adventure_cap_segment.gd.uid @@ -0,0 +1 @@ +uid://b88nnsq53mium diff --git a/game/data/schemas/adventure_quota_segment.gd.uid b/game/data/schemas/adventure_quota_segment.gd.uid new file mode 100644 index 00000000..1af7b113 --- /dev/null +++ b/game/data/schemas/adventure_quota_segment.gd.uid @@ -0,0 +1 @@ +uid://bi52mqsld3mpc diff --git a/game/data/schemas/adventure_value_segment.gd.uid b/game/data/schemas/adventure_value_segment.gd.uid new file mode 100644 index 00000000..b611d35f --- /dev/null +++ b/game/data/schemas/adventure_value_segment.gd.uid @@ -0,0 +1 @@ +uid://c0y3hcpqyv1li diff --git a/game/presentation/curio_interact_controller.gd b/game/presentation/curio_interact_controller.gd index c59ff1c1..df3f20fc 100644 --- a/game/presentation/curio_interact_controller.gd +++ b/game/presentation/curio_interact_controller.gd @@ -8,18 +8,16 @@ extends RefCounted const Narrator := preload("res://presentation/battle_narrator.gd") var db -# u13 引用束注入:16 个 _init 抄写成员删除——正文读点改址 ctx 束(u20 三束键名; -# _pending_curio/_curio_context 纯内部态保持宿主) +var ctx: CurioFlowContext # u13 引用束注入:构造注入 context 活引用(views/getters/flow 三束键名) +# _pending_curio/_curio_context 纯内部态保持宿主 var _pending_curio := {} # 三选一停点载荷暂存(战斗总结结算确认后开三选一面;续玩停点复用) var _curio_context := "level_clear" # 三选一面上下文(level_clear=关卡完成停点→推进下一关 / reward_node=奖励节点→回图选路) -func _init(ctx: CurioFlowContext) -> void: - # 构造参数收拢 context 对象(16 参长签名收一处命名面) +func _init(ctx_ref: CurioFlowContext) -> void: + ctx = ctx_ref db = ctx.db - ctx.flow.fatal_screen = ctx.fatal_screen - ctx.flow.gp_summary = ctx.gp_summary # 停点在途判据(组合根 _on_battle_end_continue 分派面——战斗总结确认后开三选一) @@ -41,7 +39,7 @@ func resume_if_pending() -> bool: #(continue_to_next_level 的「停点未兑付拒推进」守卫因此放行)。 func _skip_empty_stop() -> bool: ctx.views.toast.show_toast("可用战利品为空——本次三选一跳过", "info") - var adventure = _adventure_get.call() + var adventure = ctx.getters.adventure_get.call() if adventure != null: adventure.stop().skip_empty_curio() # core 停点消化(其守卫=仅空候选放行) if _curio_context == "reward_node": @@ -88,7 +86,7 @@ func on_presented(payload: Dictionary) -> void: # 奖励节点三选一(与关卡完成三选一共享同池同权重同上限;CurioPickOverlay 共用面)。 # 无替换子交互(同调装配不可变,见类头)。 func present_node_curio() -> void: - var adventure = _adventure_get.call() + var adventure = ctx.getters.adventure_get.call() _curio_context = "reward_node" var node_draw: Dictionary[Variant, Variant] = adventure.stop().node_curio_candidates() var node_cands: Array[Variant] = node_draw.get("candidates", []) as Array @@ -111,7 +109,7 @@ func show_pick() -> void: var payload: Dictionary[Variant, Variant] = _pending_curio ctx.flow.open_modal.call(ctx.views.curio_overlay) ctx.views.curio_overlay.open_pick(Narrator.curio_pick_header(payload), _curio_card_texts(payload.get("candidates", []) as Array)) - var adventure = _adventure_get.call() + var adventure = ctx.getters.adventure_get.call() if adventure != null: _feed_refresh_display(adventure) # 刷新面投喂单点 ctx.flow.refresh_presentations.call() @@ -119,7 +117,7 @@ func show_pick() -> void: # 刷新呈现投喂单点(免费余量 X/Y + GP 付费价 + 冒险钱包可付——读数与商店 set_refresh_display 同构) func _feed_refresh_display(adventure: AdventureRunner) -> void: - var runner = _runner_get.call() + var runner = ctx.getters.runner_get.call() var gp := int(runner.gp) if runner != null else 0 var cost: int = adventure.refresh_bank().gp_cost() ctx.views.curio_overlay.set_refresh_display(adventure.refresh_bank().free_left(), cost, gp >= cost) @@ -154,10 +152,10 @@ func _curio_card_texts(candidates: Array) -> Array: # 同 shop_refresh_cost_base/curve 旋钮、同冒险钱包 runner.gp;关卡完成停点经重发 curio_choice_presented 直落 # 选择面,节点停点在此读在途态重 present——零自动推进契约不破,停点仍在途) func on_refresh() -> void: - var adventure = _adventure_get.call() + var adventure = ctx.getters.adventure_get.call() if adventure == null or not adventure.stop().curio_stop_pending(): return - var runner = _runner_get.call() + var runner = ctx.getters.runner_get.call() var refreshed: bool = adventure.stop().refresh_curio() if not refreshed: # 免费位(X/Y)已穷——GP 付费档(先扣钱包后重抽,余额不足拒绝零副作用) @@ -176,7 +174,7 @@ func on_refresh() -> void: func on_pick_confirmed(item_id: String) -> void: - var adventure = _adventure_get.call() + var adventure = ctx.getters.adventure_get.call() if adventure == null: return # TP0 令牌池——卡片 id "kind|tier|feat_id" 拆键(缺 | = 旧载荷防御归普通档;relic 三段) @@ -206,7 +204,7 @@ func on_resolved(result: Dictionary) -> void: func on_continue() -> void: ctx.flow.close_modal.call(ctx.views.curio_overlay) ctx.views.curio_overlay.close_pick() - var adventure = _adventure_get.call() + var adventure = ctx.getters.adventure_get.call() if _curio_context == "feat_ticket": return # T5 店内专长凭证面——专长兑付完成后关面回店(无推进/无回图) if _curio_context == "reward_node": @@ -223,7 +221,7 @@ func on_continue() -> void: # 数据源=treasure 装配词表 12 件 func item_name_lookup() -> Dictionary: var lookup := {} - var meta = _meta_get.call() + var meta = ctx.getters.meta_get.call() if meta != null: for row in db.crossrun.treasure_items.attunement_rows(): lookup[String(row.get("item_id", ""))] = String(row.get("display_name", "")) diff --git a/game/presentation/main_ui_build.gd b/game/presentation/main_ui_build.gd index 89cb145c..52f206c5 100644 --- a/game/presentation/main_ui_build.gd +++ b/game/presentation/main_ui_build.gd @@ -144,7 +144,7 @@ static func _build_curio(root: Variant) -> void: {"open_modal": root._open_modal, "open_modal_after_playback": root._open_modal_after_playback, "close_modal": root._close_modal, "refresh_presentations": root._refresh_presentations, "fatal_screen": root._fatal_screen, - "gp_summary": func() -> String: return root._gp_summary_text({"gp_dropped": root.run_scope.last_gain_amount}}))) # 构造参数收拢 context(u20 三束) + "gp_summary": _gp_summary_cb(root)})) # 构造参数收拢 context(u20 三束) root.curio_overlay.pick_confirmed.connect(root._bonus.on_pick_confirmed) root.curio_overlay.continue_pressed.connect(root._bonus.on_continue) root.curio_overlay.refresh_requested.connect(root._bonus.on_refresh) @@ -251,3 +251,8 @@ static func fatal_screen(root: Variant, msg: String) -> void: var l := UiKit.label(msg,UiKit.FS_SUB, true, UiKit.RED_ALERT) l.set_anchors_preset(Control.PRESET_CENTER) root.add_child(l) + + +# GP 总结行回调(gp_summary 束键——单行 lambda 内嵌字典实参收尾歧义,提函数承载) +static func _gp_summary_cb(root: Variant) -> Callable: + return func() -> String: return root._gp_summary_text({"gp_dropped": root.run_scope.last_gain_amount}) diff --git a/game/presentation/views/battle_end_overlay.gd b/game/presentation/views/battle_end_overlay.gd index d30b0f1f..d5340755 100644 --- a/game/presentation/views/battle_end_overlay.gd +++ b/game/presentation/views/battle_end_overlay.gd @@ -271,12 +271,7 @@ func _spawn_seal_dot(i: int, base: Vector2) -> void: tw.tween_callback(dot.queue_free) -# ---- 演出密度(程序化 tween,确定性散布,零新帧资产) ---- - -var st._crest_bricks: Array[ColorRect] = [] # 纹章碎砖驻留面(close 时回收) -var st._fx_crest_shards := 0 -var st._fx_dust_motes := 0 -var st._fx_seal_dots := 0 +# ---- 演出密度(程序化 tween,确定性散布,零新帧资产;计数与碎砖驻留面在 _EndOverlayState) ---- # 碎砖拼纹章(胜利 §2.4——蜡封落定后十枚碎砖自四周向蜡封外环收拢拼成纹章环,驻留至 close) diff --git a/game/presentation/views/board_cell_unit.gd b/game/presentation/views/board_cell_unit.gd index 87a45e23..38ceac79 100644 --- a/game/presentation/views/board_cell_unit.gd +++ b/game/presentation/views/board_cell_unit.gd @@ -323,7 +323,7 @@ func _draw_bevel() -> void: ## 变异标记域:真视格=危险红内缩框/未开格伤害型变异=左下角危险红三角 func _draw_mutation_marks() -> void: - if treasure_mark == "mine_reveal": + if st.treasure_mark == "mine_reveal": var inset := st.edge * 0.14 draw_rect(Rect2(inset, inset, st.edge - inset * 2.0, st.edge - inset * 2.0), Color(UiKit.RED_MINE, 0.9), false, 2.0) diff --git a/game/presentation/views/board_zone_view.gd b/game/presentation/views/board_zone_view.gd index 8577227c..b6509338 100644 --- a/game/presentation/views/board_zone_view.gd +++ b/game/presentation/views/board_zone_view.gd @@ -24,7 +24,6 @@ func _init() -> void: vb.add_theme_constant_override("separation", 4) add_child(vb) _build_views(vb) - _build_status_corner() ## 视图三件域:AP 条+棋盘区(含动效与 toast 叠层) @@ -37,11 +36,11 @@ func _build_views(vb: VBoxContainer) -> void: vb.add_child(board_area) _board_area = board_area board_area.resized.connect(_on_board_area_resized) - _build_board_children(board_area) + _build_board_children(board_area, vb) -## 棋盘子件域:视图+动效+toast 三叠层挂接 -func _build_board_children(board_area: Control) -> void: +## 棋盘子件域:视图+动效+toast 三叠层挂接+状态角标+操作提示条(hint 回挂 vb——树序与拆分前一致) +func _build_board_children(board_area: Control, vb: VBoxContainer) -> void: board_view = BoardView.new() board_view.set_anchors_preset(Control.PRESET_FULL_RECT) board_area.add_child(board_view) diff --git a/game/presentation/views/curio_pick_overlay.gd b/game/presentation/views/curio_pick_overlay.gd index 3ca6c255..9d187fb7 100644 --- a/game/presentation/views/curio_pick_overlay.gd +++ b/game/presentation/views/curio_pick_overlay.gd @@ -62,28 +62,6 @@ func _build_top_row(top: HBoxContainer) -> void: ## 主体域:入账信息行+三竖卡列+底部确认/继续钮与免费选择注记 func _build_body(box: VBoxContainer) -> void: - _label = UiKit.label("",UiKit.FS_BODY, false, UiKit.WARM_SOFT) - _label.horizontal_alignment = HORIZONTAL_ALIGNMENT_CENTER - box.add_child(_label) - _choice_box = HBoxContainer.new() - _choice_box.add_theme_constant_override("separation", 26) # demo .cards gap 26(T7 对齐) - _choice_box.alignment = BoxContainer.ALIGNMENT_CENTER - _choice_box.size_flags_vertical = Control.SIZE_EXPAND_FILL - box.add_child(_choice_box) - var foot := HBoxContainer.new() - foot.alignment = BoxContainer.ALIGNMENT_CENTER - foot.add_theme_constant_override("separation", 16) - box.add_child(foot) - _confirm_btn = UiKit.primary_button("确认选择") - _confirm_btn.pressed.connect(_on_confirm_pressed) - _confirm_btn.visible = false - foot.add_child(_confirm_btn) - _continue_btn = UiKit.button("继续") - _continue_btn.pressed.connect(_emit_continue_pressed) - _continue_btn.visible = false - foot.add_child(_continue_btn) - _foot_hint = UiKit.label("免费选择 · 刷新不消耗 AP",UiKit.FS_HINT, false, UiKit.WARM_FAINT) - foot.add_child(_foot_hint) _label = UiKit.label("",UiKit.FS_BODY, false, UiKit.WARM_SOFT) _label.horizontal_alignment = HORIZONTAL_ALIGNMENT_CENTER box.add_child(_label) diff --git a/game/presentation/views/ui_kit.gd b/game/presentation/views/ui_kit.gd index ad5c6faa..adac263f 100644 --- a/game/presentation/views/ui_kit.gd +++ b/game/presentation/views/ui_kit.gd @@ -351,7 +351,7 @@ const BEAMS_PEAK := 0.05 ## 光带像素域(循环体提函数——12° 斜向光带双三角衰减:带内峰值×纵向衰减逐像素着色) -func _paint_beams(img: Image) -> void: +static func _paint_beams(img: Image) -> void: var ca := BEAMS_TILT_CA var sa := BEAMS_TILT_SA var beam_col := Color(1.0, 236.0 / 255.0, 200.0 / 255.0)