T17反馈批收官: ①结算演播硬锁v3.1——锁期点击缓存+演播完边沿自动重放(玩家操作零丢失——实机卡死感根因=锁期点击被吞无反馈)②恢复被平反的两修复——血量口径(置满/回血封顶含pct)+选路呈现(干线偏移+非候选降透明)——probe卡死真因=probe未适配迭代10 BonusPickOverlay(假阳性扣压平反)③减动效按钮——文案不刷新bug修+语义命名「结算演出动画:完整/快速」+操作提示内联④出度≤2全套(用户拍板)——level_table第七检fanout_violation+L2L3十张模板重建(tools/t17_fanout2_rebuild.py五骨架出度≤2/层宽≤4/类型序列保持/自校验四检)+层宽上限5废止(数学不相容)改4+钉固断言5处随新图+文档两处(生成v0.6/地图v1.3)⑤probe适配BonusPick三态(替换/result继续/待选确认)+预算耗尽放弃收口+排播豁免;闸=冒烟628/0+run_all 15套+三探针+doc三闸零新增;连带义务=MC读数基线随图变漂移全旧锚作废只测不判,重锚归下一测量批

This commit is contained in:
DKChan committed 2026-10-02 08:11:06 +08:00
1 parent 16df50f93b
commit be772cfb2f
10 files changed
+220 -28

No files matched your search

+19 -10
View File
@@ -97,6 +97,17 @@ var _row_queue: Array = [] # 待排播行(step_row 载荷原样入队
var _row_pace_wait := 0.0 # 距下一行排播的剩余秒(_process 消耗)
var _pace_prev_segment := "" # 上一排播行的段型(段间/段内延迟判据)
var _was_pumping := false # 排播活跃边沿(T17——末行消费帧触发结算视觉回挖掘态刷新)
var _locked_click := {} # 锁期点击缓存(T17 v3.1——最后一次;演播完边沿重放,玩家操作零丢失)
# 锁期点击重放(v3.1):延迟一帧重入唯一动作通道——此刻队列空锁已解,按普通动作受理
#(局面在演播期无变化:逻辑先行、演播只是回放——点击语义保真)。
func _replay_locked_click() -> void:
if _locked_click.is_empty() or not _row_queue.is_empty():
return
var click: Dictionary = _locked_click
_locked_click = {}
_on_board_action(click["cell"], click["kind"])
const PACE_SEGMENT_GAP := 0.3 # 段间阶梯延迟(代拍板:白名单 0.2–0.4s 内取值,追认清单呈报)
const PACE_ROW_GAP := 0.22 # 段内间隔(三轮 #3 上调 0.06→0.22——逐条演出可感知,配合数字浮现/状态脉冲)
@@ -811,6 +822,10 @@ func _process(delta: float) -> void:
# 无核心信号驱动——此处主动刷回挖掘态(去饱和解除/明细带收起/mode=dig)。
_was_pumping = false
_refresh_presentations.call_deferred()
# 锁期点击重放(v3.1——玩家操作零丢失):最后一次锁期点击延迟一帧重入
# _on_board_action(此刻队列已空=锁已解,正常受理)。
if not _locked_click.is_empty():
_replay_locked_click.call_deferred()
return
_was_pumping = true
_row_pace_wait -= delta
@@ -928,9 +943,6 @@ func _on_node_continue() -> void:
func _on_choices_presented(candidates: Array) -> void:
# 零自动推进的停点呈现:整幅节点图 + 图上点击选路(候选按钮退役 2026-09-28——战斗胜利/兑付确认统一到达此处)
if OS.get_environment("T17_LOCK_DEBUG") != "":
print("[choices_dbg] handler entered cands=%d runner_null=%s node=%s" % [
candidates.size(), str(runner == null), str(runner.node_index) if runner != null else "-"])
if runner == null:
return
log_view.append_bb(Narrator.route_line(candidates, runner))
@@ -940,8 +952,6 @@ func _on_choices_presented(candidates: Array) -> void:
# 的当前节点非 battle 型——三态天然分流)。Boss 胜/失败走 level_finished 另路不经此处。
if _adventure_mode and runner.current_battle() == null \
and String(runner.current_node().get("type", "")) == "battle" and not candidates.is_empty():
if OS.get_environment("T17_LOCK_DEBUG") != "":
print("[choices_dbg] -> battle stop overlay (node %s)" % str(runner.node_index))
_settlement_stop_pending = true
_pending_candidates = candidates.duplicate()
_end_overlay.open_victory(Narrator.battle_end_text("victory", false), "下一节点",
@@ -950,9 +960,6 @@ func _on_choices_presented(candidates: Array) -> void:
_open_modal(_end_overlay)
_refresh_presentations()
return
if OS.get_environment("T17_LOCK_DEBUG") != "":
print("[choices_dbg] -> level_screen (node %s type %s cands %d)" % [
str(runner.node_index), String(runner.current_node().get("type", "")), candidates.size()])
_enter_level_screen()
level_screen.open_choices(candidates, runner)
_refresh_presentations()
@@ -1207,9 +1214,11 @@ func _on_board_action(cell: Vector2i, kind: String) -> void:
# 结算演播期棋盘冻结(T17 用户明确令 v3——不可点/不可移/不可挖):
# 锁面=排播队列活跃(纯队列判据;_row_pace_wait 有末行尾迹窗口不可作演播中标志)。
# 队列排空即解锁、无状态残留;HUD 按钮不在锁面(停手/明细回看各自通路,开启前
# _flush_row_queue 自行排空)。v1 撞收尾链的教训对策:ui_click_probe 的排播期 stall
# 豁免随批(合法停顿态),Waiting 收尾等待期**不豁免**——probe 报卡即为真回归信号。
# _flush_row_queue 自行排空)。
# **点击不丢弃**(v3.1——用户实机「卡死」根因):锁期点击缓存最后一次,演播完边沿
# (_process 泵 _was_pumping 分支)自动重放——玩家操作零丢失、体感=「演播一停动作就生效」。
if not _row_queue.is_empty():
_locked_click = {"cell": cell, "kind": kind}
return
# 魔法道具选中态劫持(迭代 7 T4——两步交互第二步):点格=使用目标拾取,不落挖格;
# 只劫持挖掘点击(move/flag 语义不冲突——选中期玩家仍可移动/插旗)
+8 -2
View File
@@ -394,6 +394,9 @@ func _draw_graph(canvas: Control) -> void:
var visited: Array = _runner.visited_ids()
var cand_ids: Array = _runner.next_candidate_ids()
# 连线(通道)先行画(方块覆盖其上);悬停预承诺 = 所属通道再增亮(加粗)
# T17 修复:选路停点(候选非空)非候选通道降透明——金岔路从结构网分离(干线共线重叠缺陷的
# 视觉主因:不同源通道共用同一垂直干线,金边与石色边焊接成「整列可走」假象)
var dim_passages: bool = not cand_ids.is_empty()
for node in nodes:
var from: Vector2 = pos[node]
for tid in _out_ids(node, nodes):
@@ -403,7 +406,7 @@ func _draw_graph(canvas: Control) -> void:
var to: Vector2 = pos[target]
var lit: bool = _id_of(node) == current_id and cand_ids.has(tid)
var hovered: bool = lit and _hover_id == tid
var col := COL_PASSAGE_LIT if lit else COL_PASSAGE
var col := COL_PASSAGE_LIT if lit else (Color(COL_PASSAGE, 0.35) if dim_passages else COL_PASSAGE)
var width := 4.0 if hovered else (3.0 if lit else 2.0) # 样张 v1 冻结:2/3/4(原 1.5 取整)
_draw_passage(canvas, from, to, col, width)
# 房间方块
@@ -511,6 +514,9 @@ func _draw_passage(canvas: Control, from: Vector2, to: Vector2, col: Color, widt
var b := to - Vector2(NODE_HALF.x, 0)
if b.x < a.x:
return
var mid_x := (a.x + b.x) / 2.0
# T17 修复:垂直干线 x 按源节点 y 偏移——不同源的边不再共线重叠(旧 mid_x=中点使相邻层
# 全部通道焊成一条干系,「金岔路+整列可走」误读的直接几何根源)。同源双边仍共线(同出发
# 点语义正确),跨源分离度 = 源行距 × 0.2(L2 行距 ~58px → 偏移 ~12px 可辨)。
var mid_x := (a.x + b.x) / 2.0 + (a.y - b.y) * 0.2
var pts := PackedVector2Array([a, Vector2(mid_x, a.y), Vector2(mid_x, b.y), b])
canvas.draw_polyline(pts, col, width)
+13 -2
View File
@@ -73,7 +73,8 @@ func _build() -> void:
box.add_child(_fs_btn)
# 减动效(battle.md §Transitions 承诺转正——时长减半,结算逐行兑现=信息载体不整体跳过)
_motion_btn = UiKit.button("减动效:关(动画时长减半——运动敏感/演示用)")
# 文案由 _sync_motion_text 按状态装配(构造串仅占位——_sync 启动即覆盖)
_motion_btn = UiKit.button("结算演出动画")
_motion_btn.toggle_mode = true
_motion_btn.toggled.connect(_on_motion_toggled)
box.add_child(_motion_btn)
@@ -91,7 +92,16 @@ func _sync() -> void:
_fs_btn.set_pressed_no_signal(_store.fullscreen)
_fs_btn.text = "全屏:%s" % ("开" if _store.fullscreen else "关")
_motion_btn.set_pressed_no_signal(_store.reduced_motion)
_motion_btn.text = "减动效:%s(动画时长减半——运动敏感/演示用)" % ("开" if _store.reduced_motion else "关")
_sync_motion_text()
# T17 修复:文案随状态即时刷新(旧 bug=切换后文案恒「开」,玩家无法得知当前态)+语义命名
# (「减动效」玩家读不懂——实称「结算演出动画」速度档)+操作提示内联(所见即所得)。
func _sync_motion_text() -> void:
if _store.reduced_motion:
_motion_btn.text = "结算演出动画:快速(时长减半——运动敏感/演示用)· 点击改回完整"
else:
_motion_btn.text = "结算演出动画:完整 · 点击改为快速(时长减半——运动敏感/演示用)"
func _on_volume_changed(v: float) -> void:
@@ -111,6 +121,7 @@ func _on_motion_toggled(on: bool) -> void:
_store.reduced_motion = on
_store.apply()
_store.save_settings()
_sync_motion_text() # T17 修复:切换即时刷新文案(旧版漏刷新=状态文字恒「开」)
func _emit_closed() -> void: