From f5edb65d25c1f88c97d4f9bf6f370fb7759fb6ad Mon Sep 17 00:00:00 2001 From: DKChan <524912269@qq.com> Date: Tue, 29 Sep 2026 06:21:32 +0800 Subject: [PATCH] =?UTF-8?q?fix(review-batch2):=20=E8=A7=86=E5=9B=BE?= =?UTF-8?q?=E4=BF=A1=E5=8F=B7=E5=8F=AF=E5=AE=A1=E8=AE=A1=E6=80=A7+?= =?UTF-8?q?=E5=B0=81=E8=A3=85=E6=94=B6=E5=8F=A3=E2=80=94=E2=80=94=E7=94=9F?= =?UTF-8?q?=E4=BA=A724=E5=A4=84lambda=E8=BD=AC=E5=91=BD=E5=90=8D=E6=96=B9?= =?UTF-8?q?=E6=B3=95=E5=90=ABbind=E4=B8=A4=E5=A4=84(P1-3)+recent=5Fsummari?= =?UTF-8?q?es/hero=5Feffects=E5=80=BC=E6=8B=B7=E8=B4=9D=E5=87=BA=E6=88=B7(?= =?UTF-8?q?P2-3)=EF=BC=9B=E7=94=9F=E4=BA=A7lambda=E5=AE=A1=E8=AE=A1?= =?UTF-8?q?=E5=BD=92=E9=9B=B6(83=E2=86=9259=E5=85=A8smoke)=EF=BC=8C?= =?UTF-8?q?=E5=86=92=E7=83=9F576/0=E5=90=8C=E5=9F=BA=E7=BA=BF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- game/core/battle_orchestrator.gd | 2 +- game/core/save_manager.gd | 2 +- game/presentation/playtest_logger.gd | 8 +++- game/presentation/views/ap_bar_view.gd | 12 ++++- game/presentation/views/battle_end_overlay.gd | 12 ++++- game/presentation/views/board_zone_view.gd | 44 ++++++++++++++++--- game/presentation/views/camp_overlay_view.gd | 12 ++++- game/presentation/views/legend_overlay.gd | 9 ++-- game/presentation/views/node_overlay.gd | 6 ++- .../views/settlement_review_overlay.gd | 9 ++-- game/presentation/views/shop_overlay_view.gd | 12 ++++- game/presentation/views/status_slot_row.gd | 6 ++- game/presentation/views/tune_panel.gd | 24 ++++++++-- 13 files changed, 127 insertions(+), 31 deletions(-) diff --git a/game/core/battle_orchestrator.gd b/game/core/battle_orchestrator.gd index 2bce5d59..f6d1de1a 100644 --- a/game/core/battle_orchestrator.gd +++ b/game/core/battle_orchestrator.gd @@ -786,7 +786,7 @@ func presentation_snapshot() -> Dictionary: "can_refresh": can_refresh(), "hero": hero, "enemies": enemies, - "hero_effects": _status_effects.query_active("hero"), + "hero_effects": _status_effects.query_active("hero").duplicate(true), # 值拷贝出户(code-review 2026-09-29 P2-3——快照消费方直改不渗入状态容器) } diff --git a/game/core/save_manager.gd b/game/core/save_manager.gd index 4d7bab6b..92f31493 100644 --- a/game/core/save_manager.gd +++ b/game/core/save_manager.gd @@ -183,7 +183,7 @@ func boss_first_kill_marked(level_index: int) -> bool: func recent_summaries() -> Array: - return _data["meta"]["recent_summaries"] + return _data["meta"]["recent_summaries"].duplicate(true) # 值拷贝出户(本类契约「禁碰内部结构」——消费方直改不得渗入存档内存态) # 域更新原语(正式冒险收束唯一入账口——组合根经本函数入账,禁直改内部结构): diff --git a/game/presentation/playtest_logger.gd b/game/presentation/playtest_logger.gd index 42a9b3aa..85d0ae94 100644 --- a/game/presentation/playtest_logger.gd +++ b/game/presentation/playtest_logger.gd @@ -53,10 +53,14 @@ func log_path() -> String: func attach_battle(settlement) -> void: settlement.step_row.connect(_on_step_row) settlement.settlement_snapshot.connect(_on_settlement_snapshot) - settlement.battle_finished.connect(func(p): _append({ + settlement.battle_finished.connect(_on_battle_finished_log) + + +func _on_battle_finished_log(p: Dictionary) -> void: + _append({ "kind": "battle_end", "result": String(p.get("result", "")), "hero_hp": int(p.get("hero_hp", 0)), - "gp_dropped": int(p.get("gp_dropped", 0))})) # 战斗掉落列(GP+商店房实施批 2026-09-21——验收取数面) + "gp_dropped": int(p.get("gp_dropped", 0))}) # 战斗掉落列(GP+商店房实施批 2026-09-21——验收取数面) # ---- GP 钱包行(GP+商店房实施批——到账/购买/清零事件;runner wallet_changed 投影经组合根转发)---- diff --git a/game/presentation/views/ap_bar_view.gd b/game/presentation/views/ap_bar_view.gd index 4c71dfd9..f6ff1a42 100644 --- a/game/presentation/views/ap_bar_view.gd +++ b/game/presentation/views/ap_bar_view.gd @@ -55,7 +55,7 @@ func _init() -> void: _btn_stop = UiKit.button("停手") _btn_stop.custom_minimum_size = Vector2(64, 0) _btn_stop.size_flags_vertical = Control.SIZE_SHRINK_CENTER - _btn_stop.pressed.connect(func(): stop_pressed.emit()) + _btn_stop.pressed.connect(_emit_stop_pressed) row.add_child(_btn_stop) var spacer := Control.new() @@ -91,7 +91,7 @@ func _init() -> void: _btn_legend = UiKit.button("图例") _btn_legend.custom_minimum_size = Vector2(56, 0) _btn_legend.size_flags_vertical = Control.SIZE_SHRINK_CENTER - _btn_legend.pressed.connect(func(): legend_toggled.emit()) + _btn_legend.pressed.connect(_emit_legend_toggled) row.add_child(_btn_legend) var refresh_box := VBoxContainer.new() @@ -237,3 +237,11 @@ func _make_dot() -> ColorRect: d.color = COL_DOT_OFF d.mouse_filter = Control.MOUSE_FILTER_IGNORE return d + + +func _emit_stop_pressed() -> void: + stop_pressed.emit() + + +func _emit_legend_toggled() -> void: + legend_toggled.emit() diff --git a/game/presentation/views/battle_end_overlay.gd b/game/presentation/views/battle_end_overlay.gd index 38935018..3f81fe26 100644 --- a/game/presentation/views/battle_end_overlay.gd +++ b/game/presentation/views/battle_end_overlay.gd @@ -43,10 +43,10 @@ func _init() -> void: _gp_line.visible = false box.add_child(_gp_line) _review_btn = UiKit.button("明细回看") - _review_btn.pressed.connect(func(): review_pressed.emit()) + _review_btn.pressed.connect(_emit_review_pressed) box.add_child(_review_btn) _btn = UiKit.button("继续") - _btn.pressed.connect(func(): continue_pressed.emit()) + _btn.pressed.connect(_emit_continue_pressed) box.add_child(_btn) # 金蜡封占位(胜利):圆形色块落于扫雷图区中央——位置由 set_board_rect 注入 _seal = Panel.new() @@ -192,3 +192,11 @@ func _clear_crest_bricks() -> void: # 演出探针出口(fx_probe——胜利纹章/失败掸灰/旗光收回三断言面) func fx_probe() -> Dictionary: return {"crest_shards": _fx_crest_shards, "dust_motes": _fx_dust_motes, "flag_dots": _fx_flag_dots} + + +func _emit_review_pressed() -> void: + review_pressed.emit() + + +func _emit_continue_pressed() -> void: + continue_pressed.emit() diff --git a/game/presentation/views/board_zone_view.gd b/game/presentation/views/board_zone_view.gd index d8f716a1..7184358a 100644 --- a/game/presentation/views/board_zone_view.gd +++ b/game/presentation/views/board_zone_view.gd @@ -11,6 +11,7 @@ var ap_bar: ApBarView var board_view: BoardView var toast: ToastStack var fx: BoardFxView +var _board_area: Control # resized 命名转发用(原 lambda 局部捕获——P1-3 转命名 2026-09-29) signal action_requested(cell: Vector2i, kind: String) signal stop_pressed @@ -31,7 +32,8 @@ func _init() -> void: board_area.size_flags_vertical = Control.SIZE_EXPAND_FILL board_area.clip_contents = true vb.add_child(board_area) - board_area.resized.connect(func(): board_view.set_cell_area(board_area.size)) + _board_area = board_area + board_area.resized.connect(_on_board_area_resized) board_view = BoardView.new() board_view.set_anchors_preset(Control.PRESET_FULL_RECT) board_area.add_child(board_view) @@ -40,11 +42,39 @@ func _init() -> void: toast = ToastStack.new() board_area.add_child(toast) # 信号转发(组合根只接线一处) - board_view.action_requested.connect(func(c: Vector2i, kind: String): action_requested.emit(c, kind)) - board_view.hover_forbidden.connect(func(c: Vector2i): hover_forbidden.emit(c)) - board_view.chord_attempted.connect(func(c: Vector2i): chord_attempted.emit(c)) - ap_bar.stop_pressed.connect(func(): stop_pressed.emit()) - ap_bar.refresh_confirmed.connect(func(): refresh_confirmed.emit()) - ap_bar.legend_toggled.connect(func(): legend_toggled.emit()) + board_view.action_requested.connect(_forward_action) + board_view.hover_forbidden.connect(_forward_hover) + board_view.chord_attempted.connect(_forward_chord) + ap_bar.stop_pressed.connect(_emit_stop_pressed) + ap_bar.refresh_confirmed.connect(_emit_refresh_confirmed) + ap_bar.legend_toggled.connect(_emit_legend_toggled) + + +func _on_board_area_resized() -> void: + board_view.set_cell_area(_board_area.size) + + +func _forward_action(c: Vector2i, kind: String) -> void: + action_requested.emit(c, kind) + + +func _forward_hover(c: Vector2i) -> void: + hover_forbidden.emit(c) + + +func _forward_chord(c: Vector2i) -> void: + chord_attempted.emit(c) + + +func _emit_stop_pressed() -> void: + stop_pressed.emit() + + +func _emit_refresh_confirmed() -> void: + refresh_confirmed.emit() + + +func _emit_legend_toggled() -> void: + legend_toggled.emit() diff --git a/game/presentation/views/camp_overlay_view.gd b/game/presentation/views/camp_overlay_view.gd index 0341fc43..0d1ecef2 100644 --- a/game/presentation/views/camp_overlay_view.gd +++ b/game/presentation/views/camp_overlay_view.gd @@ -84,7 +84,7 @@ func _init() -> void: scroll.add_child(_recent_list) var close_btn := UiKit.button("关闭营地(回开始界面)") - close_btn.pressed.connect(func(): closed.emit()) + close_btn.pressed.connect(_emit_closed) box.add_child(close_btn) visible = false @@ -168,7 +168,7 @@ func _build_forge_row(holder: VBoxContainer, row: Dictionary) -> Dictionary: price_l.custom_minimum_size = Vector2(150, 0) line.add_child(price_l) var btn := UiKit.button("锻造 +1 级") - btn.pressed.connect(func(): buy_requested.emit(attr)) + btn.pressed.connect(_emit_buy_requested.bind(attr)) line.add_child(btn) holder.add_child(card) return {"attr": attr, "level_l": level_l, "price_l": price_l, "btn": btn} @@ -211,3 +211,11 @@ func _rebuild_recent(data: Dictionary) -> void: lines.append("%s · 通关 %d 关 · 钥石 +%d · 种子 %d" % [verdict, int(s.get("levels_cleared", 0)), int(s.get("keystone_total", 0)), int(s.get("master_seed", 0))]) _recent_list.text = "\n".join(lines) + + +func _emit_closed() -> void: + closed.emit() + + +func _emit_buy_requested(attr: String) -> void: + buy_requested.emit(attr) diff --git a/game/presentation/views/legend_overlay.gd b/game/presentation/views/legend_overlay.gd index cb9592d2..686b58db 100644 --- a/game/presentation/views/legend_overlay.gd +++ b/game/presentation/views/legend_overlay.gd @@ -25,9 +25,7 @@ func _init() -> void: var dim := ColorRect.new() dim.color = Color(UiKit.DIM, 0.55) dim.set_anchors_preset(Control.PRESET_FULL_RECT) - dim.gui_input.connect(func(ev: InputEvent): - if ev is InputEventMouseButton and ev.pressed: - close()) + dim.gui_input.connect(_on_dim_gui_input) add_child(dim) var center := CenterContainer.new() center.set_anchors_preset(Control.PRESET_FULL_RECT) @@ -83,3 +81,8 @@ func close() -> void: return visible = false closed.emit() + + +func _on_dim_gui_input(ev: InputEvent) -> void: + if ev is InputEventMouseButton and ev.pressed: + close() diff --git a/game/presentation/views/node_overlay.gd b/game/presentation/views/node_overlay.gd index dcdd64ca..4adb7dba 100644 --- a/game/presentation/views/node_overlay.gd +++ b/game/presentation/views/node_overlay.gd @@ -27,7 +27,7 @@ func _init() -> void: _label.horizontal_alignment = HORIZONTAL_ALIGNMENT_CENTER box.add_child(_label) _btn = UiKit.button("继续") - _btn.pressed.connect(func(): continue_pressed.emit()) + _btn.pressed.connect(_emit_continue_pressed) box.add_child(_btn) visible = false @@ -49,3 +49,7 @@ func show_rest(healed: int, hp_after: int, max_hp: int) -> void: # 探针复用:以真实按钮路径触发继续 func press_continue() -> void: _btn.pressed.emit() + + +func _emit_continue_pressed() -> void: + continue_pressed.emit() diff --git a/game/presentation/views/settlement_review_overlay.gd b/game/presentation/views/settlement_review_overlay.gd index 13d888c4..10e4ea3b 100644 --- a/game/presentation/views/settlement_review_overlay.gd +++ b/game/presentation/views/settlement_review_overlay.gd @@ -14,9 +14,7 @@ func _init() -> void: var dim := ColorRect.new() dim.color = Color(UiKit.DIM, 0.62) dim.set_anchors_preset(Control.PRESET_FULL_RECT) - dim.gui_input.connect(func(ev: InputEvent): - if ev is InputEventMouseButton and ev.pressed: - close()) + dim.gui_input.connect(_on_dim_gui_input) add_child(dim) var center := CenterContainer.new() center.set_anchors_preset(Control.PRESET_FULL_RECT) @@ -55,3 +53,8 @@ func close() -> void: return visible = false closed.emit() + + +func _on_dim_gui_input(ev: InputEvent) -> void: + if ev is InputEventMouseButton and ev.pressed: + close() diff --git a/game/presentation/views/shop_overlay_view.gd b/game/presentation/views/shop_overlay_view.gd index 473a890a..47457560 100644 --- a/game/presentation/views/shop_overlay_view.gd +++ b/game/presentation/views/shop_overlay_view.gd @@ -41,7 +41,7 @@ func _init() -> void: _cards_box.add_theme_constant_override("separation", 8) box.add_child(_cards_box) var leave_btn := UiKit.button("离开商店") - leave_btn.pressed.connect(func(): leave_pressed.emit()) + leave_btn.pressed.connect(_emit_leave_pressed) box.add_child(leave_btn) visible = false @@ -90,7 +90,7 @@ func _build_card(p: Dictionary) -> Dictionary: bought_l.add_theme_color_override("font_color", UiKit.WARM_FAINT) row.add_child(bought_l) var btn := UiKit.button("购买") - btn.pressed.connect(func(): buy_requested.emit(String(p.product_id))) + btn.pressed.connect(_emit_buy_requested.bind(p)) row.add_child(btn) _cards_box.add_child(card) return {"product_id": String(p.product_id), "price": price_l, "bought": bought_l, "btn": btn} @@ -100,3 +100,11 @@ func _build_card(p: Dictionary) -> Dictionary: func _card_title(p: Dictionary) -> String: var attr := String(p.get("attr", "")) return "%s(%s %+d)" % [String(p.get("display_name", "")), String(ATTR_LABELS.get(attr, attr)), int(p.get("flat_value", 0))] + + +func _emit_leave_pressed() -> void: + leave_pressed.emit() + + +func _emit_buy_requested(p: Dictionary) -> void: + buy_requested.emit(String(p.product_id)) diff --git a/game/presentation/views/status_slot_row.gd b/game/presentation/views/status_slot_row.gd index 4edc9fe5..8557bb1a 100644 --- a/game/presentation/views/status_slot_row.gd +++ b/game/presentation/views/status_slot_row.gd @@ -113,7 +113,7 @@ func _make_slot() -> PanelContainer: slot.custom_minimum_size = Vector2(50, 46) slot.add_theme_stylebox_override("panel", UiKit.panel_flat(UiKit.PANEL_DATA, UiKit.PANEL_BORDER)) slot.mouse_entered.connect(_on_slot_hover.bind(slot)) - slot.mouse_exited.connect(func(): _tip.visible = false) + slot.mouse_exited.connect(_hide_tip) var col := VBoxContainer.new() col.alignment = BoxContainer.ALIGNMENT_CENTER if compact: @@ -196,3 +196,7 @@ func _icon_tex(effect_id: String) -> Texture2D: push_error("[状态槽] 未知图标键(映射表外键——立即断言): %s" % effect_id) assert(false, "未知图标键: " + effect_id) return null + + +func _hide_tip() -> void: + _tip.visible = false diff --git a/game/presentation/views/tune_panel.gd b/game/presentation/views/tune_panel.gd index 3590cb0f..902a9a20 100644 --- a/game/presentation/views/tune_panel.gd +++ b/game/presentation/views/tune_panel.gd @@ -165,7 +165,7 @@ func _build() -> void: motion_row.add_child(UiKit.label("减动效(动画时长减半——运动敏感/演示用)", 14, false)) var motion_btn := CheckButton.new() motion_btn.button_pressed = UiKit.motion_scale < 1.0 - motion_btn.toggled.connect(func(on: bool): UiKit.motion_scale = 0.5 if on else 1.0) + motion_btn.toggled.connect(_on_motion_toggled) motion_row.add_child(motion_btn) box.add_child(HSeparator.new()) @@ -181,7 +181,7 @@ func _build() -> void: sim_row.add_child(_sim_count) sim_row.add_child(UiKit.label("次(理性玩家策略,含面板当前加成)", 13, false)) _sim_btn = UiKit.button("运行模拟") - _sim_btn.pressed.connect(func(): simulate_requested.emit(int(_sim_count.value))) + _sim_btn.pressed.connect(_emit_simulate_requested) sim_row.add_child(_sim_btn) _sim_out = RichTextLabel.new() _sim_out.bbcode_enabled = true @@ -189,7 +189,7 @@ func _build() -> void: box.add_child(_sim_out) var close_btn := UiKit.button("关闭") - close_btn.pressed.connect(func(): closed.emit()) + close_btn.pressed.connect(_emit_closed) box.add_child(close_btn) @@ -206,7 +206,7 @@ func _slider_row(box: VBoxContainer, title: String) -> Dictionary: var v := UiKit.label("+0%", 15, true) v.custom_minimum_size = Vector2(70, 0) row.add_child(v) - s.value_changed.connect(func(_value: float): _sync_labels()) + s.value_changed.connect(_on_slider_value_changed) return {"slider": s, "value_label": v} @@ -219,3 +219,19 @@ func _sync_labels() -> void: func _scaled(base: int, pct: int) -> int: return maxi(1, int(round(float(base) * (100.0 + float(pct)) / 100.0))) + + +func _on_motion_toggled(on: bool) -> void: + UiKit.motion_scale = 0.5 if on else 1.0 + + +func _emit_simulate_requested() -> void: + simulate_requested.emit(int(_sim_count.value)) + + +func _emit_closed() -> void: + closed.emit() + + +func _on_slider_value_changed(_value: float) -> void: + _sync_labels()