fix(review-batch2): 视图信号可审计性+封装收口——生产24处lambda转命名方法含bind两处(P1-3)+recent_summaries/hero_effects值拷贝出户(P2-3);生产lambda审计归零(83→59全smoke),冒烟576/0同基线
This commit is contained in:
1 parent
463baac08e
commit
f5edb65d25
13 files changed
+127
-31
No files matched your search
@@ -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——快照消费方直改不渗入状态容器)
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -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) # 值拷贝出户(本类契约「禁碰内部结构」——消费方直改不得渗入存档内存态)
|
||||
|
||||
|
||||
# 域更新原语(正式冒险收束唯一入账口——组合根经本函数入账,禁直改内部结构):
|
||||
|
||||
@@ -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 投影经组合根转发)----
|
||||
|
||||
@@ -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()
|
||||
@@ -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()
|
||||
@@ -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()
|
||||
|
||||
|
||||
@@ -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)
|
||||
@@ -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()
|
||||
@@ -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()
|
||||
@@ -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()
|
||||
@@ -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))
|
||||
@@ -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
|
||||
@@ -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()
|
||||
Reference in new issue
Block a user