diff --git a/design/gdd/ux/battle.md b/design/gdd/ux/battle.md index 8d5e0128..07b784e3 100644 --- a/design/gdd/ux/battle.md +++ b/design/gdd/ux/battle.md @@ -6,7 +6,7 @@ > **Platform Target**: PC (Steam)——Keyboard/Mouse 主(全部操作纯鼠标可完成)、Gamepad Partial 非 MVP、Touch None(同 technical-preferences) > **上游修订依赖**: 弃图刷新挖掘期受理已随布局决策 4 落稿上游(2026-09-12:行动经济 Active 受理 + 每轮上限 2 次、排雷玩法 Active·仅刷新路径装板、战斗结算 `refresh_board` 编排 + 恒 same_board、registry `rap_rules` 同步——见 OQ11) > **Template**: UX Spec -> **覆盖子屏**: 挖掘阶段主界面 · 轮末自动战斗结算(战斗结算明细屏) · 胜利/失败终局 · 结算明细回看 +> **覆盖子屏**: 挖掘阶段主界面 · 轮末自动战斗结算(战斗结算明细屏) · 胜利/失败终局 · ~~结算明细回看~~(2026-10-04 P-C7 裁:冒险中回看退役归「生涯」——06 登记) > **输入义务**: 排雷玩法×6 + 行动经济 + 战斗结算×3 + 敌人系统×4 + 增益状态×4 + 地图战斗资源×5(旧版 systems-index 门禁增补记录,缺项即 blocking——承接落点见 §13 义务对照表) --- @@ -143,7 +143,7 @@ | B | 主角站桩立绘 | 站桩(无框立绘+底座) | HP 条悬浮头顶、状态效果小图标一排挂血条正下方(形状+色相双通道、层数角标)——**HP 与状态效果的唯一展示面(2026-09-26 信息归属拍板,原 C 区状态槽职责〔悬停 tooltip 来源+语义+剩余结算次数〕并入本组件)**;攻击值等规划数据仍归 C 区数据框(2026-09-20 全站桩拍板,英雄卡退役) | 悬停状态小图标看 tooltip | HUDView 拆分改造 | | B | 敌人站桩立绘 ×1–3 | 站桩(无框立绘+底座) | 血条+顺位徽标悬浮头顶、状态小图标挂血条正下方(敌方 side-wide 增益各立绘同值呈现——蓄力/硬化/削弱/暴走/警觉;伏击层数通道随 2026-09-20 八型批退役——数据源 = 战斗结算流水经增益状态投影,敌人系统×4④;2026-09-16 敌人技能池批改型:行为环点拆除〔proposal §2.4〕,意图占位 = 本拍摇定结果的动画占位——普通攻击零表示 / 特殊技类型级提示,敌方增益〔蓄力/硬化〕入状态图标行);死亡灰化加碎裂退场直接演在立绘上(2026-09-20 全站桩拍板,敌人卡退役);底座下名字行 = 纯名字 + 护甲类型图标(形状+色相双通道),AC 数值不展示——2026-09-26 终裁(用户口径:HP 信息已足够,攻防数值不直接写上;护甲类型图标保留克制对策可读性——类型可读、数值隐藏) | 只读 | 新建 | | B | 轮次·阶段指示 | 标签 | "第 N 轮 · 挖掘中/结算中"(终局定格「战斗结束」;Boss 变体附 Boss 名) | 只读 | 新建 | -| B | 结算明细带 | 滚动列表 | 结算期逐行流水([战斗结算](../systems/战斗循环/战斗结算.md#明细流水每一行都能指回你刚才的哪一步棋) 9 类行协议);挖掘期收起为上轮摘要 1 行 | 点击展开明细回看 overlay | battle_log_view.gd 改造 | +| B | 结算明细带 | 滚动列表 | 结算期逐行流水([战斗结算](../systems/战斗循环/战斗结算.md#明细流水每一行都能指回你刚才的哪一步棋) 9 类行协议);挖掘期收起为上轮摘要 1 行 | 点击展开明细回看 overlay(2026-10-04 P-C7 退役——带保留单行摘要,回看归「生涯」) | battle_log_view.gd 改造 | | B | 结算明细回看 | 模态 overlay | 完整流水逐行(现行 9 类行协议;未生效类行聚合计数) | 关闭 | battle_log_view.gd 改造 | | C | 攻击数据框 | 直角细线数据框 | 攻击值 + 修正来源角标 + 护甲 AC(AC 二轮拍板 2026-09-26 补入——我方 AC 唯一展示面;原「HP/攻击/RAP 显示」——HP 与 RAP 随信息归属拍板迁出本组件) | 只读 | HUDView 拆分 | | C | 魔法道具槽(已实装:四槽两步交互,详见 [node-reward.md](node-reward.md)) | 图标槽 ×4 | 随身战斗用道具的唯一展示面;库存已随迭代 7 落地(C 区四槽+关卡域库存),清库反馈呈现待批 | 悬停 tooltip(道具语义) | 新建(随魔法道具批,已落地) | diff --git a/game/presentation/main.gd b/game/presentation/main.gd index 3fd6e52c..5c04377c 100644 --- a/game/presentation/main.gd +++ b/game/presentation/main.gd @@ -112,7 +112,6 @@ var _row_queue: Array: # 模态 overlay(z 序 = 登记序;pattern 6 层级纪律) var legend_overlay: LegendOverlay -var review_overlay: SettlementReviewOverlay var node_overlay: NodeOverlay var shop_overlay: ShopOverlay # 商店覆盖层(GP+商店房实施批——商店房节点兑付呈现) var camp_overlay: CampOverlay # 营地覆盖层(元进度实现批——主菜单营地入口兑付呈现) @@ -223,7 +222,6 @@ func _build_ui() -> void: _aux = AuxInteractController.new(db, meta, info_panel, board_zone.toast, board_view, func() -> Variant: return settlement, func() -> Variant: return runner) - log_view.review_requested.connect(_open_review_from_band) board_zone.action_requested.connect(_on_board_action) info_panel.aux_slot_clicked.connect(_aux.on_slot_clicked) # 迭代 7 T4——两步交互第一步 board_zone.stop_pressed.connect(_on_stop_pressed) @@ -245,7 +243,6 @@ func _build_ui() -> void: # < 商店 < 营地 < 设置 < 确认弹窗 < 调试浮窗) var overlays: Dictionary = UiAssembler.build_overlays(self, db) legend_overlay = overlays.legend_overlay - review_overlay = overlays.review_overlay node_overlay = overlays.node_overlay _end_overlay = overlays.end_overlay shop_overlay = overlays.shop_overlay @@ -256,11 +253,9 @@ func _build_ui() -> void: #(兑付覆盖层在本屏域内弹出:模态栈打开低层时自动隐藏高层本屏、关闭自动恢复——零机制改动复用) move_child(level_screen, node_overlay.get_index() + 1) legend_overlay.closed.connect(_on_modal_closed.bind(legend_overlay)) - review_overlay.closed.connect(_on_modal_closed.bind(review_overlay)) node_overlay.continue_pressed.connect(_on_node_continue) level_screen.route_chosen.connect(_on_route_chosen) level_screen.abandon_requested.connect(_on_abandon_requested) # 放弃入口(2026-09-21 用户拍板——台账 119) - _end_overlay.review_pressed.connect(_on_end_review) _end_overlay.continue_pressed.connect(_on_battle_end_continue) settings_overlay = SettingsOverlay.new(settings_store) # 迭代 8 卡④——最小设置面(音量/全屏/减动效) add_child(settings_overlay) @@ -333,7 +328,7 @@ func _build_ui() -> void: # 模态登记(缺陷⑤纪律——登记序 = 树序:含 move_child 调位后的关卡画面/三选一终位) _modals = ModalStack.new() - for m: Control in [legend_overlay, review_overlay, node_overlay, level_screen, bonus_overlay, _end_overlay, shop_overlay, camp_overlay, settings_overlay, confirm_dialog, debug_overlay]: + for m: Control in [legend_overlay, node_overlay, level_screen, bonus_overlay, _end_overlay, shop_overlay, camp_overlay, settings_overlay, confirm_dialog, debug_overlay]: _register_modal(m) _tune_sim = TuneSimController.new(db, debug_overlay, int(db.hero.max_hp)) @@ -552,7 +547,7 @@ func _on_adventure_finished(summary: Dictionary) -> void: text += "\n" + Narrator.keystone_settle_text(detail, _bonus.item_name_lookup()) if result == "completed": _end_overlay.open_victory(text, "返回冒险", board_view.get_global_rect(), - "本局 GP 入账 · 合计 %d" % _adventure_gp_final) # 迭代 6 T7 卡⑩——GP 行只上冒险终局面板(C5) + "本局 GP 入账 · 合计 %d" % _adventure_gp_final) # 卡⑩ GP 行;钥石明细已在 text(keystone_settle_text)——M9 三行账 else: _end_overlay.open_defeat(text, "返回", board_view.get_global_rect()) logger.log_level_end(summary) # 试玩时间线:冒险终局(摘要随载荷) @@ -591,19 +586,6 @@ func _on_battle_end_continue() -> void: _refresh_presentations() -func _on_end_review() -> void: - review_overlay.open(log_view.parsed_text()) - _open_modal(review_overlay) # 迭代 6 T7——走模态栈:终局层在册上方的可见遮挡被显式隐藏, - # 修复「回看层被终局层全屏 STOP 遮罩压死」(直开绕栈缺陷) - - -# ==================== 调试模式(连续两层——编排归 debug_session.gd; -# 单场遭遇用户入口已删(2026-09-13 用户裁决)——debug_session.start_single 原语仅探针使用; -# 入口 2026-10-04 迁调试浮窗(debug_levels_requested 接线)) -# T4/D3 收口注记:本节处理器(battle_created/battle_ready/override/seed)系组合根绑定面—— -# settlement 写与 _wire_battle=ADR-0001 组合根 essence,override/seed 取数面在组合根 UI 态 -#(debug_overlay/_seed_edit)——不迁移,信号连接留本根(契约 3)。==================== - func _start_debug_levels() -> void: debug_overlay.reset_sliders() _close_modal(debug_overlay) # 浮窗内入口发起——随开随收(对局期不可再开:门禁在 _show_debug_overlay) @@ -710,11 +692,15 @@ func _on_battle_finished(payload: Dictionary) -> void: return "level_end": _end_overlay.open_victory(Narrator.battle_end_text("victory", true), - "返回", board_view.get_global_rect(), _gp_summary_text(payload)) + "返回", board_view.get_global_rect(), _gp_summary_text(payload), + "钥石 · 累计 %d" % runner.keystone, _bonus_summary_text(), + int(payload.get("gp_dropped", 0)), int(runner.gp)) "standalone_end": if result == "victory": _end_overlay.open_victory(Narrator.battle_end_text("victory", false), - "回到遭遇选择", board_view.get_global_rect(), _gp_summary_text(payload)) + "回到遭遇选择", board_view.get_global_rect(), _gp_summary_text(payload), + "钥石 · 累计 %d" % runner.keystone, _bonus_summary_text(), + int(payload.get("gp_dropped", 0)), int(runner.gp)) else: _end_overlay.open_defeat(Narrator.battle_end_text("defeat", false), "返回", board_view.get_global_rect()) @@ -729,6 +715,21 @@ func _gp_summary_text(payload: Dictionary) -> String: return "战利品 GP +%d · 合计 %d" % [int(payload.get("gp_dropped", 0)), int(runner.gp)] +# M9 结算三行账·本关加成行装配(呈现只读投影——runner.bonus 统一加算区同源;零加成=行隐藏) +func _bonus_summary_text() -> String: + if runner == null: + return "" + var b: Dictionary = runner.bonus + var parts: Array[String] = [] + if int(b.get("atk", 0)) != 0: + parts.append("攻 %+d" % int(b.get("atk", 0))) + if int(b.get("max_hp", 0)) != 0: + parts.append("上限 %+d" % int(b.get("max_hp", 0))) + if int(b.get("armor_class", 0)) != 0: + parts.append("AC %+d" % int(b.get("armor_class", 0))) + return "本关加成 " + " · ".join(parts) + + # ==================== core↔view 接线(战斗信号统一走这里)==================== func _wire_battle(settlement_ref) -> void: @@ -1078,11 +1079,6 @@ func _phase_text() -> String: # ==================== B 区明细带 / 图例(模态入口)==================== -func _open_review_from_band() -> void: - review_overlay.open(log_view.parsed_text()) - _open_modal(review_overlay) # 迭代 6 T7 同款——净空态下栈上无可隐藏层,行为与旧直开逐位等价 - - func _on_legend_toggled() -> void: if legend_overlay.is_open(): _close_modal(legend_overlay) diff --git a/game/presentation/ui_assembler.gd b/game/presentation/ui_assembler.gd index 9eb67e83..b6a2cb04 100644 --- a/game/presentation/ui_assembler.gd +++ b/game/presentation/ui_assembler.gd @@ -61,16 +61,14 @@ static func build_battle_ui(root: Control, db) -> Dictionary: } -# 模态覆盖层组(z 序 = 登记序:图例 < 明细回看 < 节点 < 终局 < 商店)。 -# 返回 {legend_overlay, review_overlay, node_overlay, end_overlay, shop_overlay, camp_overlay};调用方按本序 addChild。 -# (调整板已随迭代 14.5 调试整合批退役——调试浮窗由组合根直构挂树序最末,见 main._build_ui) +# 模态覆盖层组(z 序 = 登记序:图例 < 节点 < 终局 < 商店)。 +# 返回 {legend_overlay, node_overlay, end_overlay, shop_overlay, camp_overlay};调用方按本序 addChild。 +# (调整板已随迭代 14.5 调试整合批退役——调试浮窗由组合根直构挂树序最末,见 main._build_ui; +# 明细回看 overlay 已随 M9/P-C7 退役 2026-10-04——冒险中回看归「生涯」06 登记) static func build_overlays(host: Control, db) -> Dictionary: var legend_overlay := LegendOverlay.new(int(db.action_economy.rap_refresh_cost)) # 打磨包 2026-09-29——RAP 行表值注入 host.add_child(legend_overlay) - var review_overlay := SettlementReviewOverlay.new() - host.add_child(review_overlay) - var node_overlay := NodeOverlay.new() host.add_child(node_overlay) @@ -87,7 +85,6 @@ static func build_overlays(host: Control, db) -> Dictionary: return { "legend_overlay": legend_overlay, - "review_overlay": review_overlay, "node_overlay": node_overlay, "end_overlay": end_overlay, "shop_overlay": shop_overlay, diff --git a/game/presentation/views/battle_end_overlay.gd b/game/presentation/views/battle_end_overlay.gd index d985efff..04178636 100644 --- a/game/presentation/views/battle_end_overlay.gd +++ b/game/presentation/views/battle_end_overlay.gd @@ -6,8 +6,7 @@ class_name BattleEndOverlay extends Control -signal review_pressed -signal continue_pressed +signal continue_pressed # M9:review_pressed 退役(P-C7——冒险中回看归「生涯」,06 登记) const COL_GOLD := UiKit.GOLD const COL_DUSK := UiKit.DUSK # 暮蓝(全作唯一暮蓝档) @@ -16,8 +15,11 @@ const COL_WARM := UiKit.WARM var _dim: ColorRect var _seal: Panel var _verdict: Label -var _gp_line: Label # 战利品行(OQ14 口径:胜利总结结算展示 GP 总量+增量——T5 接线 2026-09-28) -var _review_btn: Button +var _rows_box: VBoxContainer # M9 三行账(GP/钥石/本关加成——demo ⑧;失败侧整行隐藏=P-C4 维持 OQ14) +var _gp_row: Label +var _ks_row: Label +var _bonus_row_l: Label +var _cele: TextureRect # M9 庆祝立绘(idle 占位浮动——正式帧待资产批) var _btn: Button var _board_rect := Rect2() @@ -39,22 +41,54 @@ func _init() -> void: _seal.mouse_filter = Control.MOUSE_FILTER_IGNORE var sb := UiKit.panel_flat(COL_GOLD, UiKit.GOLD_DEEP, 200, 4) _seal.add_theme_stylebox_override("panel", sb) - _seal.custom_minimum_size = Vector2(34, 34) + _seal.custom_minimum_size = Vector2(52, 52) _seal.size_flags_vertical = Control.SIZE_SHRINK_CENTER header.add_child(_seal) + var seal_img := TextureRect.new() + var flag_tex := UiKit.load_tex("res://assets/art/board/flag_seal.png") + if flag_tex != null: + seal_img.texture = flag_tex + seal_img.custom_minimum_size = Vector2(32, 32) + seal_img.expand_mode = TextureRect.EXPAND_IGNORE_SIZE + seal_img.stretch_mode = TextureRect.STRETCH_KEEP_ASPECT_CENTERED + seal_img.texture_filter = CanvasItem.TEXTURE_FILTER_NEAREST + seal_img.size_flags_vertical = Control.SIZE_SHRINK_CENTER + seal_img.mouse_filter = Control.MOUSE_FILTER_IGNORE + _seal.add_child(seal_img) _verdict = UiKit.label("", 24, true, UiKit.INK_TITLE) _verdict.horizontal_alignment = HORIZONTAL_ALIGNMENT_CENTER _verdict.size_flags_vertical = Control.SIZE_SHRINK_CENTER header.add_child(_verdict) - _gp_line = UiKit.label("", 16, true, UiKit.INK_LABEL) - _gp_line.horizontal_alignment = HORIZONTAL_ALIGNMENT_CENTER - _gp_line.visible = false - box.add_child(_gp_line) + # M9 庆祝立绘(demo ⑧——idle 帧浮动占位;正式帧归资产批;减动效=静帧) + _cele = TextureRect.new() + var cele_tex := UiKit.load_tex(UiKit.TEX_HERO_IDLE) + if cele_tex != null: + _cele.texture = cele_tex + _cele.custom_minimum_size = Vector2(64, 64) + _cele.expand_mode = TextureRect.EXPAND_IGNORE_SIZE + _cele.stretch_mode = TextureRect.STRETCH_KEEP_ASPECT_CENTERED + _cele.texture_filter = CanvasItem.TEXTURE_FILTER_NEAREST + _cele.size_flags_vertical = Control.SIZE_SHRINK_CENTER + _cele.visible = false + header.add_child(_cele) + _rows_box = VBoxContainer.new() + _rows_box.add_theme_constant_override("separation", 6) + _rows_box.visible = false + box.add_child(_rows_box) + _gp_row = UiKit.label("", 17, true, UiKit.GOLD_DEEP) + _gp_row.horizontal_alignment = HORIZONTAL_ALIGNMENT_CENTER + _rows_box.add_child(_gp_row) + _ks_row = UiKit.label("", 15, true, UiKit.INK_LABEL) + _ks_row.horizontal_alignment = HORIZONTAL_ALIGNMENT_CENTER + _ks_row.visible = false + _rows_box.add_child(_ks_row) + _bonus_row_l = UiKit.label("", 14, false, UiKit.INK_LABEL) + _bonus_row_l.horizontal_alignment = HORIZONTAL_ALIGNMENT_CENTER + _bonus_row_l.visible = false + _rows_box.add_child(_bonus_row_l) box.add_child(HSeparator.new()) - _review_btn = UiKit.button("明细回看") - _review_btn.pressed.connect(_emit_review_pressed) - box.add_child(_review_btn) - _btn = UiKit.button("继续") + # M9:明细回看钮退役(P-C7——冒险中回看归「生涯」) + _btn = UiKit.primary_button("继续") _btn.pressed.connect(_emit_continue_pressed) box.add_child(_btn) visible = false @@ -63,27 +97,42 @@ func _init() -> void: # 终局画面数据锚 = 战斗结算 判定行(verdict)——判定行文案由组合根装配传入。 # gp_summary(OQ14 口径——胜利总结结算展示 GP 总量+增量):组合根装配「战利品 +增量 · 合计总量」 # 传入(入账次序 = LevelRunner 入账先于组合根 handler,runner.gp 即战后总量);空串 = 不显示(失败侧恒空)。 -func open_victory(verdict_line: String, continue_label: String, board_rect: Rect2, gp_summary: String = "") -> void: +func open_victory(verdict_line: String, continue_label: String, board_rect: Rect2, gp_summary: String = "", + ks_summary: String = "", bonus_summary: String = "", gp_gain := -1, gp_total := -1) -> void: _dim.color = Color(COL_WARM, 0.28) _verdict.text = verdict_line _seal.visible = true # 胜利徽记(面板头部静态) - _gp_line.text = gp_summary - _gp_line.visible = gp_summary != "" + _seal.modulate = Color.WHITE + _gp_row.text = gp_summary + _ks_row.text = ks_summary + _ks_row.visible = ks_summary != "" + _bonus_row_l.text = bonus_summary + _bonus_row_l.visible = bonus_summary != "" + _rows_box.visible = gp_summary != "" or ks_summary != "" or bonus_summary != "" _btn.text = continue_label _board_rect = board_rect + _cele.visible = true + _play_celebrate() visible = true - _play_crest_assemble() # 碎砖拼纹章(§2.4——样张 v2 冻结批 T3 终稿;绕面板屏心环收) + if UiKit.victory_fx_style == "dust": + _play_victory_dust() # 尘金粒子(P-C5 两套并存——开关=调试浮窗,会话级) + else: + _play_crest_assemble() # 碎砖拼纹章(§2.4——样张 v2 冻结批 T3 终稿;默认) _play_flag_recall(0) # 胜利不放旗收回 + if gp_gain >= 0: + _roll_gp(gp_gain, gp_total) func open_defeat(verdict_line: String, continue_label: String, board_rect: Rect2) -> void: # 明度不变的暮蓝色相氛围(全屏唯一暮蓝档——§2.5 最静一拍) _dim.color = Color(COL_DUSK, 0.45) _verdict.text = verdict_line - _gp_line.visible = false # GP 总量+增量归胜利总结结算(OQ14)——失败侧不呈现 _board_rect = board_rect visible = true - _seal.visible = false # 失败无徽记(暮蓝氛围) + _seal.visible = true + _seal.modulate = Color(0.4, 0.4, 0.4) # M9:失败徽记灰化(demo ⑧;旧全隐藏退役) + _cele.visible = false + _rows_box.visible = false # P-C4 维持 OQ14:失败侧不呈现账行 _play_dust_sadle() # 坐砖掸灰(§2.5——终稿) _play_flag_recall(8) @@ -91,6 +140,8 @@ func open_defeat(verdict_line: String, continue_label: String, board_rect: Rect2 func close() -> void: visible = false _seal.visible = false + _seal.modulate = Color.WHITE + _cele.visible = false _clear_crest_bricks() @@ -172,6 +223,45 @@ func _play_dust_sadle() -> void: mtw.tween_callback(mote.queue_free) +# M9 庆祝立绘浮动(idle 占位——UiKit.motion 守减动效;motion_scale<1 静帧) +func _play_celebrate() -> void: + if UiKit.motion_scale < 1.0: + return + var tw := _cele.create_tween() + tw.set_loops() + tw.tween_property(_cele, "position:y", _cele.position.y - 4.0, UiKit.motion(0.6)).set_trans(Tween.TRANS_SINE).set_ease(Tween.EASE_IN_OUT) + tw.tween_property(_cele, "position:y", _cele.position.y, UiKit.motion(0.6)).set_trans(Tween.TRANS_SINE).set_ease(Tween.EASE_IN_OUT) + + +# M9 尘金粒子(P-C5 备选演出——金屑自面板上带飘落闪灭;确定性散布守 S2) +func _play_victory_dust() -> void: + _fx_dust_motes += 10 + var c := _fx_center() + for i in 10: + var mote := ColorRect.new() + mote.color = Color8(246, 198, 103) + mote.size = Vector2(5, 5) + mote.mouse_filter = Control.MOUSE_FILTER_IGNORE + mote.position = c + Vector2((float(i % 5) - 2.0) * 44.0, -40.0 - 10.0 * float(i / 5)) + add_child(mote) + var tw := mote.create_tween() + tw.tween_interval(UiKit.motion(0.12 * i)) + tw.tween_property(mote, "position:y", mote.position.y + 90.0, UiKit.motion(1.1)) + tw.parallel().tween_property(mote, "modulate:a", 0.0, UiKit.motion(1.1)) + tw.tween_callback(mote.queue_free) + + +# M9 GP 行数字滚动(demo ⑧——0.8s 三次缓出;减动效直出终值) +func _roll_gp(gp_gain: int, gp_total: int) -> void: + if UiKit.motion_scale < 1.0: + _gp_row.text = "战利品 GP +%d · 合计 %d" % [gp_gain, gp_total] + return + var tw := create_tween() + tw.tween_method(func(v: float) -> void: + _gp_row.text = "战利品 GP +%d · 合计 %d" % [roundi(gp_gain * v), gp_total], + 0.0, 1.0, UiKit.motion(0.8)).set_trans(Tween.TRANS_CUBIC).set_ease(Tween.EASE_OUT) + + func _clear_crest_bricks() -> void: for b in _crest_bricks: if is_instance_valid(b): @@ -184,9 +274,5 @@ 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/battle_log_view.gd b/game/presentation/views/battle_log_view.gd index 37ed2808..e803b15e 100644 --- a/game/presentation/views/battle_log_view.gd +++ b/game/presentation/views/battle_log_view.gd @@ -14,7 +14,6 @@ class_name BattleLogView extends PanelContainer -signal review_requested const BAND_H_DIG := 24 const BAND_H_SETTLE := 84 @@ -45,7 +44,7 @@ func _init(db_ref) -> void: _summary.clip_text = true _summary.text_overrun_behavior = TextServer.OVERRUN_TRIM_ELLIPSIS head.add_child(_summary) - _hint = UiKit.label("结算明细 ▸ 点击展开回看", 14, false, UiKit.WARM) # 辅助提示(≥14 辅助档)随上暖白 + _hint = UiKit.label("上轮摘要(回看归「生涯」)", 14, false, UiKit.WARM) # 辅助提示(≥14 辅助档)随上暖白 _hint.size_flags_horizontal = Control.SIZE_SHRINK_END head.add_child(_hint) _log = RichTextLabel.new() @@ -56,7 +55,6 @@ func _init(db_ref) -> void: _log.scroll_active = true vb.add_child(_log) _log.visible = false - gui_input.connect(_on_gui_input) func set_mode(mode: String) -> void: @@ -114,9 +112,7 @@ func parsed_text() -> String: return _log.get_parsed_text() -func _on_gui_input(ev: InputEvent) -> void: - if ev is InputEventMouseButton and ev.pressed and ev.button_index == MOUSE_BUTTON_LEFT: - review_requested.emit() +# M9(P-C7 裁):带点击回看入口退役——冒险中不给数据回看(归「生涯」06 登记);带保留单行摘要显示 # ---- 聚合计数(未生效类行防逐行惩罚轰炸——pattern 3 聚合纪律) ---- diff --git a/game/presentation/views/debug_overlay.gd b/game/presentation/views/debug_overlay.gd index 8ea16818..a580a0e4 100644 --- a/game/presentation/views/debug_overlay.gd +++ b/game/presentation/views/debug_overlay.gd @@ -146,6 +146,18 @@ func _build() -> void: list.add_theme_constant_override("separation", 8) scroll.add_child(list) + # 区块⓪胜利演出风格(P-C5 两套并存——纹章拼合[默认]/尘金粒子;会话级不落盘) + var fx_row := HBoxContainer.new() + fx_row.add_theme_constant_override("separation", 10) + list.add_child(fx_row) + fx_row.add_child(UiKit.label("胜利演出", 14, false, UiKit.WARM)) + var fx_btn := UiKit.button("纹章拼合" if UiKit.victory_fx_style == "crest" else "尘金粒子") + fx_btn.tooltip_text = "两套演出并存——点击切换(会话级,不落盘)" + fx_btn.pressed.connect(func() -> void: + UiKit.victory_fx_style = "dust" if UiKit.victory_fx_style == "crest" else "crest" + fx_btn.text = "纹章拼合" if UiKit.victory_fx_style == "crest" else "尘金粒子") + fx_row.add_child(fx_btn) + # 区块①随机种子(原开始覆盖层种子行迁入——非法定值回退 42 的口径归组合根 _seed_value) var seed_row := HBoxContainer.new() list.add_child(seed_row) diff --git a/game/presentation/views/ui_kit.gd b/game/presentation/views/ui_kit.gd index a0e704c2..9ddf47ac 100644 --- a/game/presentation/views/ui_kit.gd +++ b/game/presentation/views/ui_kit.gd @@ -109,6 +109,7 @@ const DOT_OFF := PANEL_BORDER # ── 减动效(battle.md §Transitions 内建承诺:开启时时长减半;结算逐行兑现为信息载体降速不跳过)── # 唯一入口 = 设置面开关(迭代 8 卡④ 转正;切片期调整板开关已随其退役,调整板本体 14.5 收进调试浮窗) static var motion_scale := 1.0 # 1.0 常态 / 0.5 减动效 +static var victory_fx_style := "crest" # 胜利演出风格(P-C5 两套并存——"crest"碎砖拼纹章[默认冻结件]/"dust"尘金粒子;切换=调试浮窗,会话级) # 全部呈现层 tween 时长经本函数包装——新增动效一律 UiKit.motion(秒),禁再写裸时长字面量 static func motion(dur: float) -> float: diff --git a/game/smoke/ui_click_probe.gd b/game/smoke/ui_click_probe.gd index 5a4890b5..120c6618 100644 --- a/game/smoke/ui_click_probe.gd +++ b/game/smoke/ui_click_probe.gd @@ -249,7 +249,7 @@ func _ready() -> void: # 卡⑥ 战斗胜利总结结算框(真实信号路径——每场普通胜利到达):断言已拍板面后点「下一节点」 if not main._input_locked(): _problems.append("胜利结算框打开时输入未锁定") - var gp_line: String = main._end_overlay._gp_line.text + var gp_line: String = main._end_overlay._gp_row.text if not gp_line.contains("GP +%d" % main._last_gain_amount) or not gp_line.contains("合计 %d" % int(main.runner.gp)): _problems.append("胜利结算框 GP 增量/总量与钱包实态不符(%s|实态 +%d/%d)" % [gp_line, main._last_gain_amount, int(main.runner.gp)]) if main._end_overlay.verdict_text() == "": @@ -465,7 +465,7 @@ func _run_modal_probes_once() -> void: main.ap_bar._btn_legend.pressed.emit() if not main.legend_overlay.is_open(): _problems.append("图例打开失败") - if main.review_overlay.is_open() or main._end_overlay.is_open() or main._start_overlay.visible: + if main._end_overlay.is_open() or main._start_overlay.visible: _problems.append("图例打开时上方遮挡层未隐藏(缺陷⑤复发)") if not main._input_locked(): _problems.append("图例打开时棋盘输入未锁定") @@ -478,33 +478,7 @@ func _run_modal_probes_once() -> void: main.legend_overlay.close() if main.legend_overlay.is_open() or main._input_locked(): _problems.append("图例关闭后未恢复输入/可见性") - # ② 结算明细回看模态(pattern 6):B 区明细带点击入口 → overlay → 关闭恢复 - if not _tested_review: - _tested_review = true - main._open_review_from_band() - if not main.review_overlay.is_open(): - _problems.append("明细回看打开失败") - if not main._input_locked(): - _problems.append("明细回看打开时输入未锁定") - main.review_overlay.close() - if main.review_overlay.is_open() or main._input_locked(): - _problems.append("明细回看关闭后未恢复") - # ②b 终局面板明细回看入口(迭代 6 T7——z 序修复回归闸):终局层开启态点回看 → - # 模态栈隐藏终局层、回看可用;关回看终局层恢复(修复「回看被终局层 STOP 遮罩压死」) - if not _tested_end_review: - _tested_end_review = true - main._end_overlay.open_victory("探针终局", "继续", Rect2(Vector2.ZERO, Vector2(400, 300))) - main._end_overlay.review_pressed.emit() # 真实信号路径(按钮 → 组合根 _on_end_review) - if not main.review_overlay.is_open(): - _problems.append("终局入口回看未打开(_on_end_review 路径)") - if main._end_overlay.visible: - _problems.append("回看打开时终局层未被模态栈隐藏(z 序压死复发——迭代 6 T7)") - main.review_overlay.close() - if not main._end_overlay.visible: - _problems.append("回看关闭后终局层未恢复(模态栈遮挡恢复缺失)") - main._end_overlay.close() - if main._end_overlay.is_open(): - _problems.append("终局层未关闭干净") + # ②/②b 明细回看模态探针退役(M9/P-C7——冒险中回看归「生涯」,06 登记) # ③ tooltip(状态效果槽悬停——来源+语义+剩余):有槽可见时触发 if not _tested_tooltip: var row = main.stage.hero_standee.slot_row # 状态 tooltip 载体 2026-09-26 迁 B 区站桩 diff --git a/game/smoke/ui_probe.gd b/game/smoke/ui_probe.gd index e8451371..95b54e49 100644 --- a/game/smoke/ui_probe.gd +++ b/game/smoke/ui_probe.gd @@ -222,8 +222,8 @@ func _ready() -> void: main.meta = meta_saved if not main._end_overlay.is_open(): problems.append("冒险终局面板未开(合成摘要路径)") - elif not main._end_overlay._gp_line.visible or not main._end_overlay._gp_line.text.contains("57"): - problems.append("终局面板 GP 行缺失或取数不对(%s)" % main._end_overlay._gp_line.text) + elif not main._end_overlay._gp_row.visible or not main._end_overlay._gp_row.text.contains("57"): + problems.append("终局面板 GP 行缺失或取数不对(%s)" % main._end_overlay._gp_row.text) main._end_overlay.close() main._close_modal(main._end_overlay) if problems.is_empty():