From 442156bfb7c24c136c72b7443693778e649aacf7 Mon Sep 17 00:00:00 2001 From: DKChan <524912269@qq.com> Date: Tue, 29 Sep 2026 04:21:26 +0800 Subject: [PATCH] =?UTF-8?q?feat(t6):=20flat=5Fdamage=20=E5=8F=98=E5=BC=82?= =?UTF-8?q?=E6=A0=BC=E8=A7=86=E8=A7=89=E6=A0=87=E8=AE=B0=E2=80=94=E2=80=94?= =?UTF-8?q?=E5=8D=B1=E9=99=A9=E7=BA=A2=E8=A7=92=E6=A0=87+resolver=20?= =?UTF-8?q?=E6=B3=A8=E5=85=A5=E9=9D=A2=20=E2=91=A0board=5Fcell=5Funit=20?= =?UTF-8?q?=E5=A2=9E=20mutation=5Fmark=20=E7=A8=8B=E5=BA=8F=E5=8C=96?= =?UTF-8?q?=E8=A7=92=E6=A0=87(flat=5Fdamage=3D=E5=B7=A6=E4=B8=8B=E8=A7=92?= =?UTF-8?q?=E5=8D=B1=E9=99=A9=E7=BA=A2=E4=B8=89=E8=A7=92=200.28=20?= =?UTF-8?q?=E6=A0=BC=E8=BE=B9,=E5=8D=B1=E9=99=A9=E7=BA=A2=3D=E3=80=8C?= =?UTF-8?q?=E5=BC=80=E6=AD=A4=E6=A0=BC=E6=9C=89=E4=BB=A3=E4=BB=B7=E3=80=8D?= =?UTF-8?q?=E8=AF=AD=E4=B9=89=E4=BD=8D=E4=B8=8E=E9=9B=B7=E6=97=8F=E5=90=8C?= =?UTF-8?q?=E6=BA=90;tex=5Fmutation=20=E7=BA=B9=E5=B8=A6=E6=A7=BD=E7=95=99?= =?UTF-8?q?=E7=BB=99=E5=8F=98=E5=BC=82=E7=BA=B9=E5=B8=A6=E5=85=AD=E5=9E=8B?= =?UTF-8?q?=E8=87=AA=E4=BA=A7=E6=89=B9=E2=80=94=E2=80=94=E4=BB=A3=E6=8B=8D?= =?UTF-8?q?=E6=9D=BF=E4=BA=8C=E9=80=89=E4=B8=80=E6=8B=A9=E8=A7=92=E6=A0=87?= =?UTF-8?q?=E5=BE=85=E8=BF=BD=E8=AE=A4)=20=E2=91=A1board=5Fview=20?= =?UTF-8?q?=E5=A2=9E=20set=5Fvariant=5Fmark=5Fresolver=20=E5=8F=AA?= =?UTF-8?q?=E8=AF=BB=E5=9B=9E=E8=B0=83(=E5=90=8C=20mask=5Fresolver=20?= =?UTF-8?q?=E6=B3=A8=E5=85=A5=E5=85=88=E4=BE=8B)+=5Fpaint=5Fcell=20?= =?UTF-8?q?=E6=9C=AA=E5=BC=80=E6=A0=BC=E8=B5=8B=E5=80=BC(=E5=B7=B2?= =?UTF-8?q?=E5=BC=80=3D=E5=A8=81=E8=83=81=E5=B7=B2=E5=85=91=E7=8E=B0?= =?UTF-8?q?=E6=A0=87=E8=AE=B0=E9=80=80=E4=BD=8D;=E5=9B=9E=E8=B0=83?= =?UTF-8?q?=E7=BC=BA=E4=BD=8D=3D=E6=97=A0=E6=A0=87=E8=AE=B0=E5=9B=9E?= =?UTF-8?q?=E9=80=80=E6=80=81)=20=E2=91=A2main=20=E5=A2=9E=20=5Fvariant=5F?= =?UTF-8?q?mark=5Flookup(flat=5Fdamage=20=E6=95=88=E5=BA=94=E8=A7=A3?= =?UTF-8?q?=E6=9E=90,=E5=8F=98=E5=BC=82=E6=95=B0=E6=8D=AE=E8=A1=8C?= =?UTF-8?q?=E5=8A=A8=E9=9B=B6=E7=89=B9=E5=88=A4)+=E6=8E=A5=E7=BA=BF=20?= =?UTF-8?q?=E2=91=A3ui=5Finput=5Fprobe=20=E6=89=A9=20case=E2=91=AD(?= =?UTF-8?q?=E8=A7=92=E6=A0=87=E8=90=BD=E4=BD=8D+resolver=20=E5=A4=8D?= =?UTF-8?q?=E4=BD=8D=E6=96=AD=E8=A8=80,=E5=8D=81=E4=B8=89=E2=86=92?= =?UTF-8?q?=E5=8D=81=E5=9B=9B=E6=96=AD=E8=A8=80)=20=E8=BD=BB=E9=97=B8=3D?= =?UTF-8?q?=E5=86=92=E7=83=9F=20576/0+=E4=B8=89=E6=8E=A2=E9=92=88=20PASS;?= =?UTF-8?q?=E4=BA=A4=E5=8F=89=E5=AF=B9=E6=8B=8D=3Dmaster=20HEAD=20MC=20?= =?UTF-8?q?=E4=B8=8E=20worktree=20T0=20=E9=94=9A=20400/400=20=E9=80=90?= =?UTF-8?q?=E4=BD=8D=E4=B8=80=E8=87=B4(=E9=87=8D=E9=94=9A=E9=AA=8C?= =?UTF-8?q?=E8=AF=81=E9=97=AD=E5=90=88,=E4=B8=BB=E5=8C=BA=E5=9C=A8?= =?UTF-8?q?=E9=A3=9E=E6=96=87=E4=BB=B6=E5=85=A8=E9=9D=9E=E8=A1=8C=E4=B8=BA?= =?UTF-8?q?=E9=9D=A2)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- game/presentation/main.gd | 16 ++++++++++++++++ game/presentation/views/board_cell_unit.gd | 14 ++++++++++++++ game/presentation/views/board_view.gd | 13 +++++++++++++ game/smoke/ui_input_probe.gd | 15 ++++++++++++++- 4 files changed, 57 insertions(+), 1 deletion(-) diff --git a/game/presentation/main.gd b/game/presentation/main.gd index 386f87a8..cfa6819b 100644 --- a/game/presentation/main.gd +++ b/game/presentation/main.gd @@ -122,6 +122,7 @@ func _build_ui() -> void: board_view.set_identity_resolver(_identity_lookup) # 数字遮蔽数据源:地形变异 hide_number 解析只读回调(信息型呈现——board_view 渲染面读取) board_view.set_variant_mask_resolver(_variant_mask_lookup) + board_view.set_variant_mark_resolver(_variant_mark_lookup) # 迭代 6 T6——flat_damage 未开格角标 logger = PlaytestLogger.new() logger.ap_per_round = int(db.action_economy.ap_per_round) @@ -433,6 +434,21 @@ func _variant_mask_lookup(c: Vector2i) -> bool: return false +# 地形变异 角标解析(迭代 6 T6——伤害型变异未开格视觉标记;读取方按格子变异数据行动,规则本体零特判。 +# 策略纹理非数值墙:标记=玩家绕行/承担的决策输入,难度本体仍住数值包络) +func _variant_mark_lookup(c: Vector2i) -> String: + if settlement == null: + return "" + var b = settlement.minesweeper.current_board() + if b == null: + return "" + for vid in b.variant_ids(c): + var vrow: Dictionary = settlement.db.variation.row_by_id(String(vid)) + if String(vrow.get("effect", "")) == "flat_damage": + return "flat_damage" + return "" + + func _show_board_fx_for_node(node_type: String = "") -> void: # Boss 遭遇变体:紫赤影子爬棋盘一次性占位演出(§2.6) if node_type == "boss": diff --git a/game/presentation/views/board_cell_unit.gd b/game/presentation/views/board_cell_unit.gd index fb5059e5..73b94543 100644 --- a/game/presentation/views/board_cell_unit.gd +++ b/game/presentation/views/board_cell_unit.gd @@ -80,6 +80,14 @@ var tex_glyph: Texture2D = null # ③ 数字 var tex_badge: Texture2D = null # ③' 徽章 var tex_flag: Texture2D = null # ④ 旗 +# 变异角标(迭代 6 T6——程序化,tex_mutation 纹带槽留给变异纹带六型自产批): +# "flat_damage" = 未开格伤害型变异,左下角危险红三角(开格有代价的策略纹理标记) +var mutation_mark := "": + set(v): + if mutation_mark != v: + mutation_mark = v + queue_redraw() + func _draw() -> void: var rect := Rect2(Vector2.ZERO, Vector2(edge, edge)) @@ -165,6 +173,12 @@ func _draw() -> void: # ② 变异纹带(占位批次无程序化纹带——槽位先行,终稿换入即用) if tex_mutation != null: draw_texture_rect(tex_mutation, rect, false) + # ②' 变异角标(迭代 6 T6):左下角危险红三角(危险红=「开此格有代价」语义位,与雷族同源; + # 尺寸随格边比例——灰色可辨辅助=红对砖面明度差,禁喧宾) + if mutation_mark == "flat_damage": + var mw := edge * 0.28 + var mpts := PackedVector2Array([Vector2(0, edge - mw), Vector2(0, edge), Vector2(mw, edge)]) + draw_colored_polygon(mpts, Color(UiKit.RED_MINE, 0.85)) # ③ 数字/徽章(数字 ≥ 格高 50% 墨族对格底 ≥4.5:1;徽章右下角金,遮蔽态 = "?") if glyph != "": # 数字色牌(原则二:数字一律垫素色直角牌——对比由牌墨承载,可读不依赖格底。 diff --git a/game/presentation/views/board_view.gd b/game/presentation/views/board_view.gd index f782f1e1..976b5b52 100644 --- a/game/presentation/views/board_view.gd +++ b/game/presentation/views/board_view.gd @@ -97,6 +97,7 @@ var _board: BoardData = null var _minesweeper = null # 排雷玩法 只读查询引用(refresh 更新;null = 无战斗) var _identity_cb := Callable() # 地图战斗资源 身份解析回调(组合根注入只读面)——Vector2i → Dictionary/null var _mask_cb := Callable() # 地形变异 数字遮蔽回调(组合根注入只读面)——Vector2i → bool(true = 该格数字不显示) +var _vmark_cb := Callable() # 地形变异 角标回调(迭代 6 T6 只读面)——Vector2i → String("flat_damage"=伤害型变异未开格;""=无) var _diggable := {} # 可挖域(8 向相邻未开格)——呼吸微光作用集 var _breath_t := 0.0 var _contact_unit: Node2D = null # 接触带承载单元(=英雄格 CellUnit;rebuild 随清场复位) @@ -187,6 +188,12 @@ func set_variant_mask_resolver(cb: Callable) -> void: _mask_cb = cb +# 组合根注入 地形变异 角标只读回调(迭代 6 T6——flat_damage 未开格视觉标记;变异是策略纹理非数值墙: +# 玩家可据此绕行/承担的决策输入。空 Callable = 全板无标记(缺位回退态) +func set_variant_mark_resolver(cb: Callable) -> void: + _vmark_cb = cb + + # SubViewport 主题/字体显式注入挂点(Phase B 两舞台复用——SubViewport 不自动继承主场景 Control 主题; # 本项目无自定义主题,缺省 = 引擎回退字体,与旧 Button 渲染同源) func set_world_font(f: Font) -> void: @@ -715,6 +722,12 @@ func _paint_cell(c: Vector2i, hero: Vector2i) -> void: # 地面投影:北邻墙格在本已开格北缘投渐隐暗带(ITB 同款高度线索——带宽按格边比例常量) if north_in and not _minesweeper.is_revealed(north_n): u.proj_band = u.edge * WALL_PROJECTION_FRAC + # ②' 变异角标(迭代 6 T6):未开格带伤害型变异 → 危险红角标(已开=威胁已兑现标记退位); + # 回调缺位 = 无标记(程序化角标,tex_mutation 纹带槽留给变异纹带自产批) + if not revealed and _vmark_cb.is_valid(): + u.mutation_mark = String(_vmark_cb.call(c)) + else: + u.mutation_mark = "" u.badge_glyph = _update_badge(c) u.queue_redraw() diff --git a/game/smoke/ui_input_probe.gd b/game/smoke/ui_input_probe.gd index 12299d0d..8b3b6400 100644 --- a/game/smoke/ui_input_probe.gd +++ b/game/smoke/ui_input_probe.gd @@ -293,8 +293,21 @@ func _ready() -> void: _problems.append("case⑪ 缺位态数字格字形被破坏(glyph=%s 应=%d)" % [u11.glyph, digit11]) bv._hero_tex_idle = tex_saved bv.refresh() + # ---- case⑭ 变异角标(迭代 6 T6——flat_damage 未开格视觉标记;resolver 注入面+落位+复位) ---- + var mark_t: Vector2i = _pick_forbidden(bv, ms) # 任一未开格(禁入=未开非相邻) + if mark_t.x >= 0: + bv.set_variant_mark_resolver(func(_c): return "flat_damage") + bv.refresh() + if String(bv._cells[mark_t].mutation_mark) != "flat_damage": + _problems.append("case⑭ 变异角标未落位(mutation_mark=%s)" % str(bv._cells[mark_t].mutation_mark)) + bv.set_variant_mark_resolver(Callable()) + bv.refresh() + if String(bv._cells[mark_t].mutation_mark) != "": + _problems.append("case⑭ 角标未随 resolver 复位(mutation_mark=%s)" % str(bv._cells[mark_t].mutation_mark)) + else: + _problems.append("case⑭ 无未开格可验(板面异常)") if _problems.is_empty(): - print("[ui_input_probe] PASS — 悬停金框/禁入信号/路径预览/flag_place/chord/dig/英雄落位/影子构成/朝向/缩格重排/缺位回退 十三断言全绿(真实 push_input 路径——⑫图上命中⑬画布拟合 2026-09-28 增)") + print("[ui_input_probe] PASS — 悬停金框/禁入信号/路径预览/flag_place/chord/dig/英雄落位/影子构成/朝向/缩格重排/缺位回退/变异角标 十四断言全绿(真实 push_input 路径——⑫图上命中⑬画布拟合 2026-09-28 增,⑭变异角标 2026-09-29 增)") get_tree().quit(0) else: for p in _problems: