feat(presentation): 八型批呈现层漏网修复——战斗日志视图退役拆行分支拆除(真人试玩卡断 bug,台账 113)
①根因=八型批伏击退役(7876642)拆除伤害行 attach 字段后 battle_log_view 两处拆行分支漏网未同步(战斗结算 §行协议「同步呈现层的行格式化」义务违约):基线+伏击分支见 baseline 即读 row.attach——敌方行动伤害行(编排器 payload 带 baseline 无 attach)每场首笔敌方还手即 Invalid access,结算战斗段中途夭折=界面整体卡断;普通+穿刺+魔法三分量分支随充能退役批(2026-09-19)同样过期,主角换型 pierce/magic 攻击类型时同型崩溃(潜伏雷) ②修复=两退役拆行分支拆除,行上归因读数只剩掷点档位随行(2026-09-16 掷点批口径不变);playtest_logger payload 字段注记 attach→rider 同步 ③测试基建=smoke 新增战斗日志视图行格式化呈现层同步闸 11 断言——现行形态敌方/主角伤害行、退役文案不出现、未生效聚合 ×2、其余六行型逐型解析文本增长(格式化中途夭折=零增长转可见 FAIL);行协议 9 类自此有呈现层回归网 ④验证=冒烟 355→366 项 0 失败三闸全过;四场景探针全过(ui_probe/tune PASS、click 问题=0、layout 全量转储 exit 0);纯呈现层零行值零机制改动
This commit is contained in:
1 parent
b1d05540b3
commit
f3381a9813
3 files changed
+51
-9
No files matched your search
@@ -118,7 +118,7 @@ func log_level_end(payload: Dictionary) -> void:
|
||||
func _on_step_row(row: Dictionary) -> void:
|
||||
_ring(_recent_steps, {"t": row.type, "src": row.source_class, "v": int(row.value), "r": int(row.round_index)})
|
||||
# 结算明细行逐行落盘(2026-09-12 用户要求——五段结算完整回放数据面);
|
||||
# 公共七字段之外的全部行字段(payload:roll/ac/tier/crit/normal/pierce/magic/baseline/attach/target/
|
||||
# 公共七字段之外的全部行字段(payload:roll/ac/tier/crit/normal/pierce/magic/baseline/rider/target/
|
||||
# effect_id/pool_value 等)随行平铺落盘(2026-09-17 数值分析工具批——无 payload 的旧日志反事实只能
|
||||
# 比例近似,新日志可精确重算)。
|
||||
var line := {"kind": "step", "type": row.type, "source": row.source_class,
|
||||
|
||||
@@ -6,7 +6,10 @@
|
||||
# Date: 2026-09-12(基础 = 2026-09-11 13 类行协议格式化版;2026-09-15 格面资源批 15→10 类:
|
||||
# 删 item / consumed_ineffective / use_rejected / window_open / window_skip 五类——可选类道具与窗口下线,
|
||||
# 战斗结算 行协议清单同步;2026-09-16 护甲等级掷点批:伤害行补掷点读数/档位随行标注 + nat20 金框高亮;
|
||||
# 同日 敌人技能池批:施放行 = 蓄力行 charge 改型〔增益技 0 伤害施放、具名技能〕)
|
||||
# 同日 敌人技能池批:施放行 = 蓄力行 charge 改型〔增益技 0 伤害施放、具名技能〕;
|
||||
# 2026-09-20 八型批呈现层漏网修复(真人试玩卡断):伏击退役拆除伤害行 attach 字段后,
|
||||
# 基线+伏击与普通+穿刺+魔法三分量两拆行分支未同步拆除——敌方行(带 baseline 无 attach)
|
||||
# 格式化即 Invalid access,结算段中途夭折、界面卡死;两分支随批拆除,行上归因只剩掷点随行)
|
||||
# 高内聚边界:战斗结算 步骤流 → 玩家文案的全部格式化规则内聚于此;来源文案映射来自 SettlementTable。
|
||||
class_name BattleLogView
|
||||
extends PanelContainer
|
||||
@@ -171,12 +174,8 @@ func _format_row(row: Dictionary, agg_count := -1) -> String:
|
||||
var body := "%s 单次%+d(池 %+d)%s" % [name_, v, pool, suffix]
|
||||
return prefix + (_gold_frame(body) if hl != "" else "[color=%s]%s[/color]" % [col, body])
|
||||
"damage":
|
||||
var extra := ""
|
||||
if row.get("baseline", null) != null:
|
||||
extra = "(基线 %d + 伏击 %d)" % [int(row.baseline), int(row.attach)]
|
||||
elif row.get("pierce", null) != null:
|
||||
# 主角攻击三分量拆行(攻击类型×护甲克制批——P2 归因:这刀里哪段是穿刺/魔法挣的)
|
||||
extra = "(普通 %d + 穿刺 %d + 魔法 %d)" % [int(row.normal), int(row.pierce), int(row.magic)]
|
||||
# 伤害行无行上拆行文案——基线+伏击与三分量两旧归因拆行已随伏击退役批(2026-09-20)
|
||||
# 与充能退役批(2026-09-19)出协议,行上归因读数只剩掷点档位随行
|
||||
# 护甲等级掷点留档(2026-09-16 掷点批——掷点读数与档位随行可读;吃掷点分量恒带,棋盘来源行不带)
|
||||
var roll_txt := ""
|
||||
if row.get("roll", null) != null:
|
||||
@@ -187,7 +186,7 @@ func _format_row(row: Dictionary, agg_count := -1) -> String:
|
||||
roll_txt += " · ×%d%%" % int(row.tier)
|
||||
roll_txt += "〕"
|
||||
var kill := " ⚔击杀!" if row.get("killed", false) else ""
|
||||
var body := "%s -%d%s%s%s%s%s" % [name_, v, extra, roll_txt, tail, kill, suffix]
|
||||
var body := "%s -%d%s%s%s%s" % [name_, v, roll_txt, tail, kill, suffix]
|
||||
var body_col := "#e07050" if row.get("killed", false) else ("#9a8a72" if v == 0 else "#e0a050")
|
||||
if bool(row.get("crit", false)):
|
||||
return prefix + _gold_frame(body) # nat 最大面暴击 = 金框高亮行
|
||||
|
||||
@@ -81,6 +81,7 @@ func _run_core_smoke(db, rng) -> void:
|
||||
_smoke_difficulty_table()
|
||||
_smoke_damage_types()
|
||||
_smoke_playtest_logger()
|
||||
_smoke_battle_log_view()
|
||||
_smoke_encounter_roll()
|
||||
_smoke_attack_chain_fresh_pool()
|
||||
_smoke_clear_reward_chain()
|
||||
@@ -2345,3 +2346,45 @@ func _fresh_rng(seed_val: int):
|
||||
var rng = load("res://core/rng_service.gd").new()
|
||||
rng.set_master_seed(seed_val)
|
||||
return rng
|
||||
|
||||
|
||||
# ---- 战斗日志视图·行格式化呈现层同步闸(2026-09-20 真人试玩卡断 bug 回归:八型批伏击退役拆除
|
||||
# 伤害行 attach 字段后本视图拆行分支漏网未同步——敌方首笔攻击行带 baseline 无 attach,
|
||||
# _format_row Invalid access 使结算段中途夭折、界面卡死。行协议变更必须同步呈现层〔战斗结算 §行协议〕,
|
||||
# 本段把现行行形态逐型喂进真实视图:拆行残留与行字段错位在此转红)----
|
||||
func _smoke_battle_log_view() -> void:
|
||||
print("--- 战斗日志视图行格式化(行协议 9 类呈现层同步闸)---")
|
||||
var view = load("res://presentation/views/battle_log_view.gd").new(_db)
|
||||
# 敌方行动伤害行(现行形态:baseline 在场、attach 已出协议——修复前此行即 Invalid access)
|
||||
view.append_row({"type": "damage", "display_name": "地精 撕咬", "value": 2, "target": "主角",
|
||||
"baseline": 3, "roll": 15, "ac": 12, "tier": 100,
|
||||
"source_class": "enemy_action", "round_index": 2})
|
||||
var enemy_txt: String = view.parsed_text()
|
||||
check(enemy_txt.contains("撕咬") and enemy_txt.contains("〔掷 15 vs 护甲 12"), "敌方伤害行格式化(baseline 行不读退役 attach)")
|
||||
check(not enemy_txt.contains("伏击") and not enemy_txt.contains("基线"), "退役伏击/基线拆行文案不再出现")
|
||||
# 主角攻击行·单分量模型(充能退役后 payload 只带实际攻击类型一键——修复前 pierce/magic 型即崩)
|
||||
view.append_row({"type": "damage", "display_name": "主角攻击", "value": 4, "pierce": 4,
|
||||
"roll": 20, "ac": 13, "tier": 100, "crit": true, "killed": true,
|
||||
"source_class": "hero_attack", "round_index": 2})
|
||||
var hero_txt: String = view.parsed_text()
|
||||
check(hero_txt.contains("暴击×") and hero_txt.contains("⚔击杀") and hero_txt.contains("■"), "主角穿刺型暴击行金框(单分量 payload 不触发三分量拆行)")
|
||||
check(not hero_txt.contains(" + 穿刺 "), "退役三分量拆行文案不再出现")
|
||||
# 未生效行聚合(pattern 3 聚合纪律——同键两行呈现 ×2 不逐行刷屏)
|
||||
view.append_row({"type": "reward_ineffective", "display_name": "增益未生效(满层)", "batch_key": "attack_up", "source_class": "safe_cell", "round_index": 1})
|
||||
view.append_row({"type": "reward_ineffective", "display_name": "增益未生效(满层)", "batch_key": "attack_up", "source_class": "safe_cell", "round_index": 1})
|
||||
view.append_row({"type": "heal", "display_name": "急救包", "value": 3, "target": "主角", "source_class": "safe_cell", "round_index": 1})
|
||||
var agg_txt: String = view.parsed_text()
|
||||
check(agg_txt.contains("⚠") and agg_txt.contains("×2"), "未生效行聚合计数 ×2 呈现")
|
||||
# 其余行型逐型喂入:格式化中途夭折 = 解析文本零增长(脚本错误静默吞断言的盲区由此转为可见 FAIL)
|
||||
var rest := {
|
||||
"effect": {"type": "effect", "display_name": "攻击强化", "value": 1, "pool_value": 2, "effect_id": "attack_up", "source_class": "flag_hit", "round_index": 1},
|
||||
"flag_miss": {"type": "flag_miss", "display_name": "标旗未中", "source_class": "flag_miss", "round_index": 1},
|
||||
"cast": {"type": "cast", "display_name": "卓尔精灵 施放 毒雾", "source_class": "enemy_action", "round_index": 3},
|
||||
"decay": {"type": "decay", "value": 1, "round_index": 3},
|
||||
"verdict": {"type": "verdict", "display_name": "下一轮次", "value": 0, "round_index": 3},
|
||||
"highlight": {"type": "highlight", "display_name": "完美排雷!清图奖励 ×2", "value": 2, "source_class": "clear_reward", "round_index": 4},
|
||||
}
|
||||
for row_type in rest:
|
||||
var before: int = view.parsed_text().length()
|
||||
view.append_row(rest[row_type])
|
||||
check(view.parsed_text().length() > before, "行型 %s 格式化落地(解析文本增长)" % String(row_type))
|
||||
Reference in new issue
Block a user