T7 死代码与残留清扫段: 16项零争议死代码直删(equivalence_supply/pool_layers/index_of/has_variant/rows_by_pool/SUB_REASONS/ui_kit死色板五常量/reset_requested/set_legend_enabled/is_level_mode/legend.toggle/set_idle×2/COL_PATH/COL_INK/rebuild死守卫/_normalize合并/FACADE并档——删前逐项全仓grep零调用核实,next_candidates有level_autoplay调用存活未删=审计误报纠正)+T17归因件撤除(choices_dbg三段+t17dump两段,T17_LOCK_DEBUG全仓归零)+延迟三件(has_unrevealed下沉/is_item_unlocked访问器/rap残链snapshot面)+文档十件(过期注释/错挂注释/4242文案/README现行化/critical-paths道具窗口退役改写);闸=冲烟636/0+run_all 15套+八探针全绿
This commit is contained in:
1 parent
5584feb6e5
commit
54ac8759c9
27 files changed
+43
-131
No files matched your search
+3
-1
@@ -33,6 +33,8 @@ Godot_v4.7.2-stable_win64_console.exe --headless --path . res://smoke/ui_probe.t
|
||||
Godot_v4.7.2-stable_win64_console.exe --headless --path . res://smoke/ui_tune_probe.tscn
|
||||
```
|
||||
|
||||
其余七场景探针(九探针全 roster 登记——ui_click_probe 行为链 / ui_input_probe 输入合成 / ui_layout_probe 布局 / shot_probe·fx_probe·fx_shot_probe·board_shot_probe 画面与特效采样,同上式运行)+ 板图校准工具 `smoke/calibrate_boards.gd`(board_calibration.csv 重跑入口,--script 运行):
|
||||
|
||||
全冒险期望扫描(零加成三关连探批量——通关率/止步分布/败退节点;调参期难度读数一律走全冒险口径):
|
||||
|
||||
```
|
||||
@@ -79,7 +81,7 @@ Godot_v4.7.2-stable_win64_console.exe --headless --path . --script res://smoke/s
|
||||
- `B1BattleOrchestrator`:begin_battle 门序列增 `b4.notify_battle_start()`(编排唯一性不变)。
|
||||
- 表/护栏:RewardTable `POOL_TAGS` + `active_inject`;RewardConfigTable + `active_p0/active_decay`、k_dmg 1→0(F5 休眠);ConfigDB 跨表护栏更新(clear_no_value 含即时类 / no_damage_row 扫描全池活行 / 新增 inject_pool 护栏:非可选类拒绝 + 空池致命)。
|
||||
|
||||
**实测(N=200 板/深度,工具 reward_expectation.gd)**:注入 1.00 件/板(j=0,多件板 0)· 占比 小刀 59–65% / 精工 25–29% / 治疗包 7–17%(名义 60/30/10)· 格池零可选类泄漏 ✓。**实际获取期望**(level_monte_carlo「可选类/战」列,N=15):基线 0.88 → +200% 攻击 0.68 件/战(低于分配保证 1.0 的机理 = 注入格均匀随机,落在残余格/速杀未挖区时该件不获取;战斗末无兜底补发——**是否加"战斗末 j==0 补发 1 件"待用户拍板**)。每关合计 ≈ 4.5–6.5 件(原 24.8)✓ 拍板目标达成。
|
||||
**实测(N=200 板/深度,工具 reward_expectation.gd)**:注入 1.00 件/板(j=0,多件板 0)· 占比 小刀 59–65% / 精工 25–29% / 治疗包 7–17%(名义 60/30/10)· 格池零可选类泄漏 ✓。**实际获取期望**(level_monte_carlo「可选类/战」列,N=15——工具已退役,数据归档):基线 0.88 → +200% 攻击 0.68 件/战(低于分配保证 1.0 的机理 = 注入格均匀随机,落在残余格/速杀未挖区时该件不获取;战斗末无兜底补发——**是否加"战斗末 j==0 补发 1 件"待用户拍板**)。每关合计 ≈ 4.5–6.5 件(原 24.8)✓ 拍板目标达成。
|
||||
|
||||
**⚠️ 供给侧副作用(本轮扫描发现,待拍板)**:可选类退出格子池后,其 25% 概率质量被动流向即时类——攻防 buff 每格频率从 44% 升至 59%,基线通关率 55%→80%(N=15)、整关承伤 127→80:**难度不降反升方向反了**。即时类是"每格必有货"锁定设计下无法清空的(除非引入空白格 = 违反锁定事实)。候选杠杆:① 接受更快的 buff 节奏,敌 HP 曲线上调对冲(C3 主杠杆)② 下调 attack_up/defense_up 在即时池内的相对权重(压 buff 频率)③ buff 幅度下调(触碰 B3 表值)。
|
||||
|
||||
|
||||
@@ -34,10 +34,6 @@ static func row_major_key(c: Vector2i) -> int:
|
||||
return c.y * 1000 + c.x
|
||||
|
||||
|
||||
func index_of(c: Vector2i) -> int:
|
||||
return c.y * width + c.x
|
||||
|
||||
|
||||
func is_mine(c: Vector2i) -> bool:
|
||||
return mines.has(c)
|
||||
|
||||
@@ -54,10 +50,6 @@ func variant_ids(c: Vector2i) -> Array:
|
||||
return variants.get(c, [])
|
||||
|
||||
|
||||
func has_variant(c: Vector2i, vid: String) -> bool:
|
||||
return variant_ids(c).has(vid)
|
||||
|
||||
|
||||
func neighbors8(c: Vector2i) -> Array:
|
||||
var out: Array[Vector2i] = []
|
||||
for dy in range(-1, 2):
|
||||
|
||||
@@ -81,6 +81,11 @@ func _workshop_progress(channel: String) -> int:
|
||||
return 0 # 未知渠道恒 0 = 永不解锁(fail-safe 非致命——渠道词表校验兜底,不静默误解锁)
|
||||
|
||||
|
||||
# 道具解锁读数访问器(组合根/呈现层解锁门控查询面——禁再穿透 meta.save 直读 save_manager)
|
||||
func is_item_unlocked(item_id: String) -> bool:
|
||||
return save.item_unlocked(item_id)
|
||||
|
||||
|
||||
# 工坊六行只读投影(呈现层数据源):{item_id, display_name, threshold, unlocked, progress}
|
||||
func workshop_status() -> Array:
|
||||
var out: Array[Dictionary] = []
|
||||
|
||||
@@ -13,8 +13,6 @@ signal cell_revealed(evt: Dictionary)
|
||||
signal flag_judged(evt: Dictionary)
|
||||
signal round_end_board(payload: Dictionary) # 双发射源之棋盘路径(排雷玩法 外发;stopped 由 行动经济 直发)
|
||||
|
||||
const SUB_REASONS := ["not_adjacent", "target_revealed", "target_concealed", "flag_present", "no_path", "out_of_catalog"] # flag_absent 随 flag_pull 退役(2026-09-19)
|
||||
|
||||
var db: ConfigDb
|
||||
var action_economy: ActionEconomy
|
||||
# 棋盘状态私有(E2 封装收口 2026-09-13):对外只暴露 current_board()/reveal_record() 等查询面,
|
||||
@@ -75,6 +73,15 @@ func clear_map_cleared() -> bool:
|
||||
return safe_remaining() == 0
|
||||
|
||||
|
||||
# 未开格存在查询(aux 道具 usable 预判消费——全板扫描只读面)
|
||||
func has_unrevealed() -> bool:
|
||||
for y in _board.height:
|
||||
for x in _board.width:
|
||||
if not _revealed.has(Vector2i(x, y)):
|
||||
return true
|
||||
return false
|
||||
|
||||
|
||||
# ---- install(编排边界相位 = 行动经济 Idle/Waiting;Active 拒绝——防轮内换板)----
|
||||
|
||||
# during_round = 轮内刷新编排路径(2026-09-12 方案 A,战斗结算 唯一调用方):Active 相位合法——
|
||||
@@ -107,11 +114,11 @@ func install_board(b: BoardData, during_round := false) -> Dictionary:
|
||||
return _outcome(true, "executed", "", "")
|
||||
|
||||
|
||||
# during_round = 轮内刷新编排路径(2026-09-12 方案 A):Active 相位合法——换图前退役旧板
|
||||
func flag_count() -> int:
|
||||
return _flags.size()
|
||||
|
||||
|
||||
# during_round = 轮内刷新编排路径(2026-09-12 方案 A):Active 相位合法——换图前退役旧板
|
||||
func retire_board(during_round := false) -> Dictionary:
|
||||
if _board == null:
|
||||
return _outcome(true, "executed", "", "") # 幂等受理
|
||||
|
||||
@@ -172,24 +172,6 @@ func polarity_row(cell_type: String, polarity: String) -> Dictionary:
|
||||
return {}
|
||||
|
||||
|
||||
# ---- F6 当量供给(行动经济 条款①对照实物输入——全活行投影 + tier_min_buff)----
|
||||
|
||||
func equivalence_supply() -> Dictionary:
|
||||
var live: Array[Dictionary] = []
|
||||
var tier_min_buff := 99
|
||||
for row in db.reward.rows:
|
||||
if int(row.weight) <= 0:
|
||||
continue
|
||||
live.append(row.duplicate()) # E6:表行值拷贝出口——消费方禁改配置源
|
||||
# tier_min_buff = 我侧增益(hero_offense/hero_defense 池的 percent 正向行——attack_up/defense_up)最低档
|
||||
if String(row.get("pool_tag", "")) == "cell" and String(row.get("polarity", "")) == "positive" \
|
||||
and String(row.get("effect_id", "")) != "":
|
||||
var eff_row: Dictionary = db.status_effect_row(String(row.effect_id))
|
||||
if not eff_row.is_empty() and String(eff_row.get("target_side", "")) == "hero":
|
||||
tier_min_buff = mini(tier_min_buff, int(row.tier))
|
||||
return {"live_rows": live, "tier_min_buff": tier_min_buff}
|
||||
|
||||
|
||||
# ---- F1 选行算子纯函数 ----
|
||||
|
||||
func weighted_pick(rows: Array, r: int) -> String:
|
||||
|
||||
@@ -39,7 +39,7 @@ const FORGE_ATTRS := ["max_hp", "atk", "armor_class"] # 属性锻造三档合
|
||||
var _path: String # 存档文件路径(默认 user://save.json;冒烟注入隔离路径)
|
||||
var _read_only := false # 高版本拒读置位——write_to_disk 一律拒绝(契约 4 禁写)
|
||||
var _data: Dictionary[String, Variant] = {} # 内存数据模型(_init 即内置默认;load 后为档案内容)
|
||||
var _migrations: Dictionary[int, Callable] = {} # from_version → Callable(data)->data(升一版;生产链现为空——骨架先行)
|
||||
var _migrations: Dictionary[int, Callable] = {} # from_version → Callable(data)->data(升一版;v1→v3 生产迁移链现行——_init 自注册)
|
||||
|
||||
|
||||
func _init(path: String = "user://save.json") -> void:
|
||||
@@ -155,7 +155,7 @@ func write_to_disk() -> bool:
|
||||
|
||||
|
||||
# 迁移注册口:from_version → from_version+1 的升级函数(读档时链式调用)。fn 契约:
|
||||
# Dictionary → Dictionary,须写回 version = from_version + 1。生产迁移当前为空(v1 首版),
|
||||
# Dictionary → Dictionary,须写回 version = from_version + 1。生产迁移链现行(v1→v3,_init 自注册),
|
||||
# 冒烟经本口验证链式升级。
|
||||
func register_migration(from_version: int, fn: Callable) -> void:
|
||||
_migrations[from_version] = fn
|
||||
@@ -265,10 +265,10 @@ func _corrupt_fallback(reason: String) -> bool:
|
||||
# 迁移后/低版本档字段补齐(改版不弃档:缺新域按默认补齐,既有值保留)
|
||||
func _normalize(data: Dictionary) -> Dictionary[String, Variant]:
|
||||
var merged := _default_data()
|
||||
var def_meta: Dictionary = merged["meta"] # 补齐源引用(先于 data 覆盖取出——data 自带 meta 时 merged["meta"] 被换走,此引用仍指默认值)
|
||||
for key in data:
|
||||
merged[key] = data[key]
|
||||
var meta: Dictionary = merged.get("meta", {})
|
||||
var def_meta: Dictionary = _default_data()["meta"]
|
||||
for key in def_meta:
|
||||
if not meta.has(key):
|
||||
meta[key] = def_meta[key]
|
||||
|
||||
@@ -106,14 +106,6 @@ func query_active(side: String) -> Array:
|
||||
return out
|
||||
|
||||
|
||||
# 池层数读值(战斗结算·战斗段伏击池 L 的消费面)
|
||||
func pool_layers(effect_id: String) -> int:
|
||||
for inst in _instances:
|
||||
if inst.effect_id == effect_id:
|
||||
return inst.layers
|
||||
return 0
|
||||
|
||||
|
||||
# 轮末衰减:先兑付后衰减;每实例恰 −1;归 0 移除;返回移除数 k(恰一次执行由 战斗结算 编排信任承载)
|
||||
func decay_round() -> int:
|
||||
if not _open:
|
||||
|
||||
@@ -44,7 +44,8 @@ func validate() -> Array:
|
||||
errs.append({"category": "enum", "message": "%s polarity 出域: %s" % [rid, pol]})
|
||||
var atk_type: String = String(row.get("attack_type", ""))
|
||||
if atk_type != "" and not ["normal", "pierce", "magic"].has(atk_type):
|
||||
errs.append({"category": "enum", "message": "%s attack_type 出域 {normal, pierce, magic}: %s" % [rid, atk_type]}) # aux 投放行专属校验(迭代 7 T1):极性恒正/加权入池/effect_id=item_id 非空(悬空在 config_db 跨表层
|
||||
errs.append({"category": "enum", "message": "%s attack_type 出域 {normal, pierce, magic}: %s" % [rid, atk_type]})
|
||||
# aux 投放行专属校验(迭代 7 T1):极性恒正/加权入池/effect_id=item_id 非空(悬空在 config_db 跨表层
|
||||
# 对 aux_items 词表校验——reward_dangling_aux)/无 power 无区间(数值语义不复用,道具效果读 AuxItemTable)
|
||||
if ctype == AUX_ITEM_TYPE:
|
||||
# 负向行 = 雷格极性字典占位(雷安同池摇号下雷格可摇中 aux 身份——负路由零兑付兜底,
|
||||
@@ -118,14 +119,6 @@ func validate() -> Array:
|
||||
return errs
|
||||
|
||||
|
||||
func rows_by_pool(pool_tag: String) -> Array:
|
||||
var out: Array[Dictionary] = []
|
||||
for row in rows:
|
||||
if row.get("pool_tag", "") == pool_tag:
|
||||
out.append(row)
|
||||
return out
|
||||
|
||||
|
||||
func row_by_id(rid: String) -> Dictionary:
|
||||
for row in rows:
|
||||
if row.get("reward_id", "") == rid:
|
||||
|
||||
@@ -41,7 +41,7 @@ func unlocked_set() -> Dictionary:
|
||||
return out
|
||||
for row in db.aux_active_rows():
|
||||
var iid := String(row.get("item_id", ""))
|
||||
if meta.save.item_unlocked(iid):
|
||||
if meta.is_item_unlocked(iid):
|
||||
out[iid] = true
|
||||
return out
|
||||
|
||||
@@ -108,11 +108,7 @@ func inventory_projection() -> Array:
|
||||
var cb := Callable()
|
||||
if ms != null:
|
||||
cb = func(_c: Vector2i) -> bool:
|
||||
for y in ms.current_board().height:
|
||||
for x in ms.current_board().width:
|
||||
if not ms.is_revealed(Vector2i(x, y)):
|
||||
return true
|
||||
return false
|
||||
return ms.has_unrevealed() # 只读查询面(排雷玩法 has_unrevealed——手搓全板双循环收口)
|
||||
var out: Array = []
|
||||
for rec in runner.aux_inventory.query_inventory(cb):
|
||||
var arow: Dictionary = db.aux_item_row(String(rec.get("item_id", "")))
|
||||
|
||||
@@ -33,10 +33,6 @@ func _init(db_ref, rng_ref, hero_override: Callable, seed_value: Callable) -> vo
|
||||
_seed_value = seed_value
|
||||
|
||||
|
||||
func is_level_mode() -> bool:
|
||||
return _level_mode
|
||||
|
||||
|
||||
# 单场遭遇原语(2026-09-13 用户裁决:单场用户入口已删——本方法仅 ui_probe 单场段使用;
|
||||
# 无延续、standalone 终局语义保留供探针战斗收尾)
|
||||
func start_single(level: int) -> bool:
|
||||
|
||||
@@ -870,9 +870,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))
|
||||
@@ -882,8 +879,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), "下一节点",
|
||||
@@ -892,9 +887,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()
|
||||
@@ -1109,7 +1101,7 @@ func _on_refresh_confirmed() -> void:
|
||||
board_zone.toast.show_toast("RAP−%d · 旧板旗作废——新图已就位,AP 保留继续挖" % int(db.action_economy.rap_refresh_cost), "gold")
|
||||
else:
|
||||
# 资源面/上限拒绝(EC13 合法拒绝可见;行动经济 无载荷——客户端按上下文推断)
|
||||
var rap: int = int(settlement.action_economy.rap) if settlement != null else 0
|
||||
var rap: int = int(settlement.presentation_snapshot().get("rap", 0)) if settlement != null else 0
|
||||
var cost: int = int(db.action_economy.rap_refresh_cost)
|
||||
var result := "rejected_rap" if rap < cost else "rejected_cap"
|
||||
logger.log_ux("ux_refresh_attempt", {"result": result, "round_refresh_index": _refresh_used_round + 1})
|
||||
|
||||
@@ -171,10 +171,6 @@ func _render_rap_dots(rap: int) -> void:
|
||||
d.color = COL_GOLD if i < shown else COL_DOT_OFF
|
||||
|
||||
|
||||
func set_legend_enabled(on: bool) -> void:
|
||||
_btn_legend.disabled = not on
|
||||
|
||||
|
||||
# 探针/装配复用:刷新按钮可用性(预判 = RAP 足额 + 上限未到)
|
||||
func is_refresh_ready() -> bool:
|
||||
return not _btn_refresh.disabled
|
||||
|
||||
@@ -20,7 +20,6 @@ const BAND_H_DIG := 24
|
||||
const BAND_H_SETTLE := 84
|
||||
const AGG_TYPES := ["reward_ineffective"]
|
||||
const COL_GOLD := UiKit.HEX_GOLD
|
||||
const COL_INK := UiKit.HEX_INK
|
||||
|
||||
var _db
|
||||
var _log: RichTextLabel
|
||||
|
||||
@@ -67,7 +67,6 @@ var bevel := 0.0: # 顶面倒角强度(0=关——立体原
|
||||
const FACADE_HIGHLIGHT_PX := 2.0 # 口沿高光线厚(像素)
|
||||
const FACADE_NEAR_FRAC := 0.16 # 立面近段高(格边比——研究件 10/64)
|
||||
const FACADE_FAR_FRAC := 0.25 # 立面远段高(格边比——研究件 16/64)
|
||||
const FACADE_HIGHLIGHT_COL := Color8(196, 172, 132) # 口沿高光(研究件取色暖米白)
|
||||
const FACADE_NEAR_COL := Color(0, 0, 0, 0.60) # 立面近段黑罩(墙顶 132→52 实测 α≈0.61)
|
||||
const FACADE_FAR_COL := Color(0, 0, 0, 0.82) # 立面远段黑罩(墙顶 132→24 实测 α≈0.82)
|
||||
const PROJECTION_NEAR_COL := Color(0, 0, 0, 0.28) # 投影贴墙段(地面 66→46 实测 α≈0.28)
|
||||
@@ -251,7 +250,7 @@ func _draw_south_facade() -> void:
|
||||
var y_far := edge - far_h
|
||||
var y_near := y_far - near_h
|
||||
var y_hl := y_near - FACADE_HIGHLIGHT_PX
|
||||
draw_rect(Rect2(0.0, y_hl, edge, FACADE_HIGHLIGHT_PX), FACADE_HIGHLIGHT_COL, true)
|
||||
draw_rect(Rect2(0.0, y_hl, edge, FACADE_HIGHLIGHT_PX), UiKit.STAND_STONE_RIM, true) # 口沿高光(UiKit.STAND_STONE_RIM 并档——同值单点,清扫批 2026-10-02)
|
||||
draw_rect(Rect2(0.0, y_near, edge, near_h), FACADE_NEAR_COL, true)
|
||||
draw_rect(Rect2(0.0, y_far, edge, far_h), FACADE_FAR_COL, true)
|
||||
|
||||
|
||||
@@ -35,7 +35,6 @@ const COL_DIGIT := UiKit.INK # 数字——墨族 #33261B(对
|
||||
const COL_HERO := UiKit.HERO_BLUE # 小人边框——小人蓝 #2E6E8E
|
||||
const COL_FLAG := UiKit.SEAL_BLACK # 封印黑 #000000(旗朱→封印紫→封印黑,2026-09-28 用户拍板)
|
||||
const COL_GOLD := UiKit.GOLD # 奖励金 #F0A828
|
||||
const COL_PATH := UiKit.HERO_BLUE # 路径预览点迹——小人蓝细线
|
||||
const COL_CONTACT := UiKit.CONTACT_GLOW # 接触带微光基色(蓝族浅一档·近白蓝——§3.2 v2.8;旧绿相退役 2026-09-26)
|
||||
const COL_HL_TARGET := UiKit.GOLD # 悬停目标格边框(金)
|
||||
const REWARD_BADGE := { # 已开格格面资源身份 icon(cell_type 九型键;极性视觉归批 2)
|
||||
@@ -269,8 +268,6 @@ func rebuild(board: BoardData, minesweeper) -> void:
|
||||
_hover = Vector2i(-9, -9)
|
||||
for c in _board.compute_r0():
|
||||
_r0[c] = true
|
||||
if _board == null:
|
||||
return
|
||||
# 瓦片套随板图型切换(T6 换色批——board_gen 词表 v1.1 dungeon/underdark/deep_underdark;
|
||||
# 同图型重复 rebuild 零重载,_tiles_board_type 守卫)
|
||||
var bt: String = _board.board_type if _board.board_type != "" else "dungeon"
|
||||
|
||||
@@ -99,12 +99,6 @@ func set_level_bonuses(lines: Array) -> void:
|
||||
_bonus_section.visible = not lines.is_empty()
|
||||
|
||||
|
||||
func set_idle() -> void:
|
||||
_atk_label.text = "攻击 —"
|
||||
_armor_label.text = "护甲 AC —"
|
||||
set_level_bonuses([])
|
||||
|
||||
|
||||
func attack_text() -> String:
|
||||
return _atk_label.text
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
# 状态槽空态说明成文载入〔增益状态 D1×①〕)。
|
||||
# Date: 2026-09-12
|
||||
# pattern 6 模态 overlay 层级纪律:打开时由组合根隐藏上方遮挡层 + 锁棋盘输入;
|
||||
# 本类自持开关(toggle),探针断言"打开后自身 visible"——遮挡物断言归场景探针。
|
||||
# 本类自持开关(open/close),探针断言"打开后自身 visible"——遮挡物断言归场景探针。
|
||||
class_name LegendOverlay
|
||||
extends Control
|
||||
|
||||
@@ -72,13 +72,6 @@ func is_open() -> bool:
|
||||
return visible
|
||||
|
||||
|
||||
func toggle() -> void:
|
||||
if visible:
|
||||
close()
|
||||
else:
|
||||
open()
|
||||
|
||||
|
||||
func open() -> void:
|
||||
visible = true
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
# VERTICAL SLICE - NOT FOR PRODUCTION
|
||||
# Date: 2026-09-21(GP+商店房实施批——商店房覆盖层呈现)
|
||||
# 商店覆盖层(模态):标题「商店」/ 金币余额 / 三商品卡全陈列(显示名·档位文案·现价·已购档数)/
|
||||
# 购买按钮(余额不足禁用置灰)/ 离开按钮。模态挂接方式仿既有覆盖层(route_overlay 现成参照——
|
||||
# 购买按钮(余额不足禁用置灰)/ 离开按钮。模态挂接方式仿既有覆盖层(legend_overlay 现成参照——
|
||||
# dim + CenterContainer + box,组合根 _register_modal 收口层级)。
|
||||
# 高内聚边界:纯视图 setter 面——商品快照与余额经组合根喂入(runner.shop_products() 只读投影,
|
||||
# 现价/已购档数由 runner 现算),购买/离开意图经信号外发——零核心写调用、零 runner 持有。
|
||||
|
||||
@@ -124,11 +124,6 @@ func _set_hp(hp: int) -> void:
|
||||
_hp_tween.tween_property(self, "hp_value", target, UiKit.motion(0.15))
|
||||
|
||||
|
||||
func set_idle() -> void:
|
||||
_set_hp(0)
|
||||
set_effects([])
|
||||
|
||||
|
||||
# 主角/敌方共用——状态效果唯一展示面(壳层伴随件转发;空态 = 图标行隐藏不占位)
|
||||
func set_effects(effects: Array) -> void:
|
||||
if slot_row == null:
|
||||
|
||||
@@ -1,15 +1,14 @@
|
||||
# VERTICAL SLICE - NOT FOR PRODUCTION
|
||||
# Date: 2026-09-11(2026-09-12 code-review 修复批重构)
|
||||
# 测试用角色数值调整板(模拟天赋树属性提升——仅测试,正式侧归元进度)。
|
||||
# 纯视图边界(规范 1.3):本类只承载滑杆 UI 与生效值预览;加成应用 / 重置落表 / 批量模拟编排
|
||||
# 全部经信号外发由组合根承接(apply_requested / reset_requested / simulate_requested / closed),
|
||||
# 纯视图边界(规范 1.3):本类只承载滑杆 UI 与生效值预览;加成应用 / 批量模拟编排
|
||||
# 全部经信号外发由组合根承接(apply_requested / simulate_requested / closed);
|
||||
# 模拟进度与报告经 setter 注入——视图零核心写、零 smoke 脚本依赖、不拼报告文案(装配归 presenter)。
|
||||
# 探针接缝(ADR-0004"合成输入走真实翻译出口"口径):press_apply_for_probe 等三键 = 按钮真实信号路径。
|
||||
class_name TunePanel
|
||||
extends Control
|
||||
|
||||
signal apply_requested(atk_pct: int, hp_pct: int) # 应用并关闭——加成落表归组合根单一应用路径
|
||||
signal reset_requested() # 重置为 0——视图自清滑杆,落表归组合根
|
||||
signal simulate_requested(count: int) # 批量模拟编排归组合根(表基线复位 + 单路径施加)
|
||||
signal closed
|
||||
|
||||
@@ -106,7 +105,6 @@ func _apply_btn_pressed() -> void:
|
||||
|
||||
func _reset_btn_pressed() -> void:
|
||||
reset_sliders()
|
||||
reset_requested.emit()
|
||||
|
||||
|
||||
func effective_atk() -> int:
|
||||
|
||||
@@ -21,10 +21,7 @@ const INK_TITLE := Color8(30, 26, 22) # 亮底标题墨
|
||||
const INK_ROUTE := Color8(24, 20, 16) # 节点图最深墨
|
||||
const INK_ON_GOLD := Color8(60, 44, 20) # 金底上的深墨
|
||||
|
||||
const PANEL_HERO := Color8(232, 220, 196) # 面板底·主角侧(英雄卡/角色信息框)
|
||||
const PANEL_ENEMY := Color8(226, 212, 190) # 面板底·敌方卡
|
||||
const PANEL_DATA := Color8(226, 210, 182) # 面板底·数据框(AP 条/状态槽)
|
||||
const PANEL_STAGE := Color8(216, 200, 172) # 面板底·战斗画面区
|
||||
const PANEL_BORDER := Color8(120, 106, 88) # 面板细线框;兼熄灭点阵(DOT_OFF 别名)
|
||||
|
||||
const GOLD := Color8(240, 168, 40) # 奖励金
|
||||
@@ -50,12 +47,10 @@ const DUSK := Color8(90, 108, 140) # 暮蓝(全作唯一暮蓝档
|
||||
const WARM := Color8(240, 226, 200) # 暖白(暗底正文)
|
||||
const WARM_SOFT := Color8(200, 188, 166) # 暖白次级(说明文)
|
||||
const WARM_FAINT := Color8(178, 166, 146) # 暖白弱化(帮助文)
|
||||
const WARM_ROUTE_SUB := Color8(210, 196, 170) # 节点图编号暖白
|
||||
|
||||
const STONE := Color8(120, 110, 98) # 灰石(通道/箭头/失效)
|
||||
const STONE_FAINT := Color8(140, 124, 100) # 灰石弱化(占位提示文)
|
||||
const DARK_UPCOMING := Color8(64, 58, 52) # 未达暗字(底/文同值)
|
||||
const DARK_TEXT_FAINT := Color8(160, 150, 138)# 未达节点文字
|
||||
|
||||
const BRICK := Color8(201, 175, 131) # 棋盘·未开掩尘地砖 #C9AF83
|
||||
const FLOOR := Color8(179, 154, 120) # 棋盘·已开裸土 #B39A78
|
||||
@@ -78,7 +73,7 @@ const STAGE_BG := Color8(62, 52, 42) # B 区舞台暗底(方向稿 re
|
||||
const BEAM_LIGHT := Color8(255, 236, 200) # B 区顶光柱暖光(用时乘 alpha 渐隐——battle_stage_view 光柱层)
|
||||
const STAND_STONE := Color8(150, 130, 100) # 站桩石板地台·板身(standee_body 方向稿取色)
|
||||
const STAND_STONE_EDGE := Color8(90, 76, 58) # 站桩石板地台·描边
|
||||
const STAND_STONE_RIM := Color8(196, 172, 132) # 站桩石板地台·顶缘受光线(与 board_cell_unit.FACADE_HIGHLIGHT_COL 异源同值——并档归清扫卡)
|
||||
const STAND_STONE_RIM := Color8(196, 172, 132) # 站桩石板地台·顶缘受光线(board_cell_unit 口沿高光已并档至此——清扫批 2026-10-02)
|
||||
const CAMP_HEADER_BAND := Color8(122, 82, 50) # 营地柜台头带深棕(4-camp.png 方向稿取色)
|
||||
const CAMP_ROW_PLATE := Color8(240, 230, 206) # 营地行板暖米(同上)
|
||||
const CAMP_BADGE_PANEL := Color8(40, 32, 24) # 营地钥石徽暗底(同上)
|
||||
|
||||
@@ -15,7 +15,6 @@
|
||||
# 驱动循环按 route 策略显式 pick_next_node;route = "min"/"max"(候选节点编号最小/最大——
|
||||
# 确定性路径轴,零随机流自开;默认 "min" 既有调用方签名兼容)。
|
||||
# 2026-09-21 冒险结构实现批:run_adventure 三关连探驱动(AdventureRunner——主种子恰一次、
|
||||
# 2026-09-21 冒险结构实现批:run_adventure 三关连探驱动(AdventureRunner——主种子恰一次、
|
||||
# 通关兑付停点确认、adventure_finished 置 result/summary;外层每关重取 runner 实例经 _drive_level
|
||||
# 复用单关驱动)。run_level 驱动段抽成 _drive_level——签名与返回结构零变化,行为逐位不变。
|
||||
# 2026-10-01 迭代 10 奖励重构批:大奖励立即确认改三选一停点驱动(候选取首件/替换放弃新件)。
|
||||
|
||||
@@ -750,7 +750,7 @@ func _smoke_level() -> void:
|
||||
var expect: int = mini(int(floor(float(eff_max) * 0.3)), eff_max - rest.hp_before_rest)
|
||||
check(rest.rest_healed == expect, "恢复点回复 = floor(生效max_hp×30%%) 与缺口的较小值(%d/%d,生效 max %d)" % [rest.rest_healed, expect, eff_max])
|
||||
else:
|
||||
check(false, "恢复点未到达(seed 4242 hp+100 在恢复点前败北?%s)" % rest.result)
|
||||
check(false, "恢复点未到达(seed 42 hp+100 在恢复点前败北?%s)" % rest.result)
|
||||
# ③ 裸装败北路径(atk1/hp10——Roguelike 基线应难以通关)
|
||||
var lose = autoplay.run_level(_db, 42, 1, -80, -80)
|
||||
check(lose.result == "defeat", "关卡·裸装(atk≈1/hp≈10)败北路径可达(实测:%s)" % lose.result)
|
||||
|
||||
@@ -542,12 +542,3 @@ func _dump_state() -> void:
|
||||
str(diag.battle_result), str(diag.settling)])
|
||||
print(" board_installed=%s facts_path='%s' refresh_used=%s flags=%s" % [
|
||||
str(diag.minesweeper_board_installed), str(diag.facts_path), str(diag.refresh_used_round), str(_flags_placed)])
|
||||
# T17 硬锁 v3 归因面:收尾链全态
|
||||
print(" [t17dump] q=%d end_overlay=%s stop_pending=%s ref_same=%s level_screen=%s node_overlay=%s node=%s" % [
|
||||
main._row_queue.size(), str(main._end_overlay.is_open()), str(main._settlement_stop_pending),
|
||||
str(main.settlement == main.runner.current_battle()), str(main.level_screen.visible),
|
||||
str(main.node_overlay.visible), str(main.runner.node_index)])
|
||||
print(" [t17dump2] type=%s bonus_overlay=%s inter_overlay=%s shop=%s cands=%s" % [
|
||||
String(main.runner.current_node().get("type", "")), str(main.bonus_overlay.visible),
|
||||
str(main._inter_overlay.visible), str(main.shop_overlay.visible),
|
||||
str(main.runner.next_candidate_ids())])
|
||||
@@ -4,7 +4,7 @@
|
||||
**Test Framework**: 双载体(ADR-0004)——`--headless --script` 逻辑冒烟 + headless 场景探针;gdUnit4 **deferred**(D2 OQ1 关闭形态,正式 CI 期再议)
|
||||
**CI**: `.github/workflows/tests.yml`(首次 push 到 GitHub 后自动生效;仓库 2026-09-12 尚未初始化 git)
|
||||
**Setup date**: 2026-09-12
|
||||
**参考实现**: `game/smoke/`(冒烟 96/96 + 三 UI 探针——正式工程的活样板)
|
||||
**参考实现**: `game/smoke/`(冒烟 628+ 断言 + 九场景探针——正式工程的活样板)
|
||||
|
||||
## Directory Layout
|
||||
|
||||
@@ -26,7 +26,7 @@ godot --headless --script tests/run_all.gd # 统一入口(CI 调用
|
||||
godot --headless --script tests/unit/example_test.gd
|
||||
|
||||
# 场景探针(双载体之二)——以探针场景为运行目标,走完整项目引导(autoload 在位)
|
||||
godot --headless --path . res://tests/probes/<probe>.tscn
|
||||
godot --headless --path . res://smoke/<probe>.tscn
|
||||
|
||||
# CI 旁必须配外部 wall-clock 超时(ADR-0004:引擎无死锁探测)
|
||||
timeout 120s godot --headless --script tests/run_all.gd
|
||||
|
||||
@@ -17,17 +17,16 @@
|
||||
5. 移动:已开格瞬移、**已引爆雷格可通行可读**(工程债呈现半边)
|
||||
6. 停手:RAP 1:1 转存、下轮 AP 硬重置同图继续
|
||||
7. 轮末结算:明细逐行呈现、来源标注可读(P2——"这一行是我哪步扫雷带来的"可答)
|
||||
8. 道具使用窗口:授予段后弹出、至多选一件、满血治疗包 usable_now 禁选态正确
|
||||
9. 清图:清图奖励兑付 + 完美排雷高光(零误标时双份)+ 换新图;未刷新的停手轮不换图
|
||||
10. 轮内刷新(方案 A):Active 当场换图、AP 保留、RAP 扣减、每轮 ≤2 次、跨图事实结算完整
|
||||
8. 清图:清图奖励兑付 + 完美排雷高光(零误标时双份)+ 换新图;未刷新的停手轮不换图
|
||||
9. 轮内刷新(方案 A):Active 当场换图、AP 保留、RAP 扣减、每轮 ≤2 次、跨图事实结算完整
|
||||
|
||||
## Battle & Level
|
||||
|
||||
11. 战斗段:主角先手攻击行(hero_attack 来源)、敌方行为环读怪(姿态↔下一拍)、死亡即不动手
|
||||
12. 胜负判定与 battle_over 清理全序;库存跨战斗延续、关卡末"剩余道具 ×N 清空"反馈
|
||||
13. 关卡推进:节点链兑付(奖励点/恢复点)、Boss 房(Dmax 行)、层间 HP 携带
|
||||
10. 战斗段:主角先手攻击行(hero_attack 来源)、敌方行为环读怪(姿态↔下一拍)、死亡即不动手
|
||||
11. 胜负判定与 battle_over 清理全序;aux 魔法道具关内跨战斗延续(三选一 BonusPickOverlay 入包、C 区槽位两步交互施用)、关卡末"剩余道具 ×N 清空"反馈(aux_cleared)
|
||||
12. 关卡推进:节点链兑付(奖励点/恢复点)、Boss 房(Dmax 行)、层间 HP 携带
|
||||
|
||||
## Data & Perf
|
||||
|
||||
14. 数值调整板:**打开可见**(覆盖层层级回归——缺陷⑤)、滑条即时生效、批量模拟可跑
|
||||
15. 无明显卡顿(60fps 目标);连续 5 分钟无内存异常增长;窗口/结算屏文案中文显示正常(CJK 字体核对)
|
||||
13. 数值调整板:**打开可见**(覆盖层层级回归——缺陷⑤)、滑条即时生效、批量模拟可跑
|
||||
14. 无明显卡顿(60fps 目标);连续 5 分钟无内存异常增长;窗口/结算屏文案中文显示正常(CJK 字体核对)
|
||||
@@ -3,4 +3,4 @@
|
||||
每系统一个子目录(`reward_economy/`、`board_generator/`…)。协议与命名见 `tests/README.md`。
|
||||
|
||||
**活样板**:`example_test.gd`(本目录)——第一个真实测试请以它为模板。
|
||||
**参考实现**:`game/smoke/smoke_all.gd`(96 条断言的组织方式)。
|
||||
**参考实现**:`game/smoke/smoke_all.gd`(628+ 条断言的组织方式)。
|
||||
Reference in new issue
Block a user