fix(battle): 地图伤害账殿后批(案C 2026-10-06 用户裁——「主角先手攻击一次」歧义质询触发)——①结算顺序定死=①授予段兑非伤害账(资源/增益/治疗/行动点/GP/警觉,伤害形态单据暂存不兑)→③战斗段「主角先基础攻击→敌人按生成序逐个还手→地图伤害账殿后」→④衰减→⑤判定;②切片=battle_orchestrator 暂存闸 _defer_board_damage/_deferred_board+_submit 案C分流(sync同闸——清图批一致延后)+_outcome_of(暂存单按「将兑付」回报——完美第二份依据开单时点事实)+授予段四处直提改走闸+战斗段末补提交块(主角死于怪物→暂存单整体不兑逐单留「未生效(主角已倒下)」行 forfeit=hero_down);③文档=战斗结算 v0.26(五段表①③行/授予段节/兑付形态表/结账时机双模式/战斗段节/P0闭环/三分量遗留顺手清+三处普通分量改基础分量)+敌人系统(P0第4步战斗段限定+地图账+死亡来源改述)+地图战斗资源(流程图/负向恒即时节/五步清单)+01-核心循环(「怪物的先手」用词相撞改警觉)+README案C批节+registry两处案C注记+编排器头部注释;④测试=行相位分类器换代(damage恒战斗段/reward_ineffective按forfeit分流)+先手断言收紧(存在或授予段终局→必存在)+新增案C段内序断言(地图账不得先于先手或插入敌方还手中间)——冒烟783/0三闸过+run_all 17套全绿+probe_gate --click全绿+gdd_lint与基线一致;⑤旧行为MC锚全数作废(授予段伤害致死短路先手语义消失),重锚归数值批
This commit is contained in:
1 parent
da157e3f65
commit
58dfb56272
8 files changed
+111
-47
No files matched your search
@@ -548,3 +548,11 @@ Godot_v4.7.2-stable_win64_console.exe --headless --path . --script res://smoke/a
|
||||
**结账时机双模式(2026-09-24 用户三裁决之二三)**:目标 = 结账时刻照规则看现场解析(最前存活敌 / 主角 / 全体存活敌),开单不冻结对象;现行 = 段界结账(授予段尾 / 清图批同步点 / 战斗段尾统一兑现),开单即结保留为回切结构位(控制器 policy 常量一行切回=逐位还原迁移前行为)。同一输入两模式结果可不同(兑现时机语义差异),历史基线读数自本批以段界结账口径为准(重测归曲线调参批)。
|
||||
|
||||
**验证**:冒烟 557 项 0 失败双模式全绿三闸过;A/B 对拍探针四配置(L1/L2 × 双种子)两模式各自同种子逐位确定、四配置全部真实分岔(行数两两恒等、纯次序位移——分岔面 = 伤害行攒批位移与治疗满血判定时机,符合段界结账语义);三场景探针全 PASS。设计权威 = 战斗结算.md v0.24「伤害单据与伤害控制器」节。
|
||||
|
||||
## 2026-10-06 地图伤害账殿后批(案C,用户裁——「主角先手」歧义质询触发;设计权威 = 战斗结算.md v0.26)
|
||||
|
||||
**裁决**:每轮结算内三者顺序定死 = ①授予段兑非伤害账(资源/增益/治疗/行动点/GP/警觉)→ ③战斗段「主角先基础攻击 → 敌人按生成序逐个还手 → 地图伤害账殿后」→ ④衰减 → ⑤判定。授予段不再当场兑付任何伤害——全部伤害形态单据(爆裂/直伤/反噬/地形变异/战旗军规/熔火反噬/惊巢反制/魔能共鸣/清障炸药等)暂存,战斗段怪物还手后按授予段事件序补提交统一结账;主角死于敌方还手 → 暂存单整体不兑,逐单留「未生效(主角已倒下)」行(载荷 forfeit=hero_down)。
|
||||
|
||||
**切片落点**:`battle_orchestrator.gd` 暂存闸 `_defer_board_damage`/`_deferred_board` + `_submit` 案C 分流(sync 同闸——清图批一致延后)+ `_outcome_of`(暂存单按「将兑付」回报——完美第二份/高光份数依据开单时点事实)+ 授予段四处直提改走闸 + 战斗段末补提交块(死亡守卫+留痕);授予段界 flush 保留(对空队 no-op 防御位);`smoke_all.gd` 行相位分类器换代(damage 恒战斗段/reward_ineffective 按 forfeit 分流)+ 先手断言收紧(「存在或授予段终局」→「必存在」)+ 新增案C 段内序断言(地图账不得先于主角先手或插入敌方还手中间)。
|
||||
|
||||
**验证**:冒烟 783 项 0 失败三闸过 + run_all 17 套全绿 + probe_gate(ui_input/ui_struct/ui_contrast/--click 行为走查)全绿、残留 0。**旧行为 MC 锚全数作废**(死亡短路语义变化:授予段伤害不再能致死短路先手;读数重采归数值批)。
|
||||
@@ -14,7 +14,10 @@
|
||||
# 伤害管线单据化批(2026-09-24 用户三裁决,06 台账 148):伤害兑付全部收口 伤害控制器(DamageController
|
||||
# 单点管线)——本类六调用点(主角先手/敌方伤害技/棋盘克制直伤/群伤/反噬/地形变异)退化为开单点
|
||||
# (流程决定何时开单给谁开单;单据怎么算归控制器)。结账时机开关在控制器 policy:IMMEDIATE(A=开单
|
||||
# 即结,逐位等价迁移前行为——回切位)/ SEGMENT(B=攒批到段界 flush:授予段尾〔含清图批前〕+ 战斗段尾)。
|
||||
# 即结,逐位等价迁移前行为——回切位)/ SEGMENT(B=攒批到段界 flush:战斗段尾统一兑现)。
|
||||
# 地图伤害账殿后批(案C 2026-10-06 用户裁——「主角先手」歧义质询触发):授予段不再当场兑付任何伤害——
|
||||
# 全部伤害形态单据经 _submit 暂存闸入 _deferred_board(保授予段事件序),战斗段「主角先手→逐敌还手」后
|
||||
# 补提交统一结账;主角死于敌方还手 → 暂存单整体不兑,逐单留「未生效(主角已倒下)」行(forfeit=hero_down)。
|
||||
# 死亡事件 = 单位容器 unit_died(单位自行宣布)→ 控制器作废该敌未结单据〔死亡即不动手〕/ 主角死终止兑付。
|
||||
# 切片登记:① 事件总线载体 = 直连信号(实现期 ADR 项,provisional)② Waiting 相位刷新通道 2026-09-15 用户拍板整体
|
||||
# 拆除(仅 Active 挖掘期受理)③ 效果行协议 = 授予段逐 grant 行 + 增益/减益段续存实例组合行。
|
||||
@@ -63,6 +66,8 @@ var _facts_reveals: Array[Dictionary] = []
|
||||
var _facts_flags: Array[Dictionary] = []
|
||||
var _facts_path := ""
|
||||
var _settling := false
|
||||
var _defer_board_damage := false # 案C 暂存闸(2026-10-06 用户裁:地图奖励伤害兑付迁战斗段末——怪物还手后)
|
||||
var _deferred_board: Array[Dictionary] = [] # 授予段暂存伤害单据(保授予段事件序;战斗段怪物还手后按序补提交统一结账)
|
||||
var _refresh_used_this_round := 0 # 每轮刷新计数(Active 相位合计,兜底上限 = ActionEconomyTable.refresh_cap_per_round)
|
||||
var _board_seq := 0 # 板序号(本战斗第几张板——快照归因用)
|
||||
var _board_from_midround_refresh := false # 装板 provenance:轮内刷新换来的图 = true(清图奖励守卫——刷新图不发清图奖励)
|
||||
@@ -449,8 +454,9 @@ func _maybe_settle() -> void:
|
||||
|
||||
func _settle() -> void:
|
||||
_settling = true
|
||||
_defer_board_damage = true # 案C:授予段伤害单据只暂存不结账(2026-10-06 用户裁——兑付时点=战斗段末)
|
||||
var ri := round_index
|
||||
# ① 授予段:结算队列(开格/旗判定/清图)→ 极性路由逐批兑付。
|
||||
# ① 授予段:结算队列(开格/旗判定/清图)→ 极性路由逐批兑付(伤害形态单据暂存——见 _submit 案C 闸)。
|
||||
# 判定基线 = 轮末在场旗(发射面已过滤——被挖开的旗已随挖掘擦除零兑付,插旗不可逆批 2026-09-19;
|
||||
# 开格事实不可撤)。
|
||||
for evt in _facts_reveals:
|
||||
@@ -489,7 +495,7 @@ func _settle() -> void:
|
||||
var spell_t := _damage.open_ticket(DamageController.KIND_BOARD_TYPED, "feat_first_dig_spell",
|
||||
"奥术矢", "board", int(_damage.feat_flags.get("spell_value", 0)),
|
||||
DamageController.TARGET_FRONT_ALIVE, ri, evt.cell, "magic")
|
||||
_damage.submit(spell_t)
|
||||
_submit(spell_t, false)
|
||||
# 掘进蓄能计数(迭代 11 同调批 T6——battle 域安全开格计数,每 charge_n 格积 1 点)
|
||||
if _attune_has("dig_charge"):
|
||||
_attune_safe_seen += 1
|
||||
@@ -501,9 +507,10 @@ func _settle() -> void:
|
||||
# 标中不发(旗已随挖掘擦除、不入轮末判定基线)。
|
||||
_grant_routed(_feat_yield_adjust(snap, false), "negative", "mine_hit", evt.cell, ri, "")
|
||||
_feat_combo = 0 # 矿脉直觉连击清零(踩雷断连——「推理密度直接奖励」的对侧)
|
||||
# 地形变异 兑付段(授予段尾——触发枚举 on_open:挖开即伤、chain 通道同口径,轮末结算逐行兑现;
|
||||
# 信息型 hide_number 不进结算——呈现层读取,见 board_view 数字遮蔽;雷格恒无变异——布置段排除,
|
||||
# 双层叠罚不存在;插旗格直挖照吃变异伤害——地形后果同 mine_hit 口径,非奖励不作废)
|
||||
# 地形变异 兑付段(授予段尾——触发枚举 on_open:挖开即伤、chain 通道同口径;伤害单据案C 暂存到
|
||||
# 战斗段末兑付〔2026-10-06 用户裁〕;信息型 hide_number 不进结算——呈现层读取,见 board_view 数字遮蔽;
|
||||
# 雷格恒无变异——布置段排除,双层叠罚不存在;插旗格直挖照吃变异伤害——地形后果同 mine_hit 口径,
|
||||
# 非奖励不作废;吞噬流资源兑付〔荆棘编织/地脉补偿〕中伤害形态行同样经案C闸暂存,非伤害形态照常当场)
|
||||
for evt in _facts_reveals:
|
||||
var vids: Array = evt.get("variant_ids", [])
|
||||
for vid in vids:
|
||||
@@ -513,7 +520,7 @@ func _settle() -> void:
|
||||
# 地形变异伤害单据(伤害管线单据化批 2026-09-24)——无类型必中,下限保底在控制器管线内
|
||||
var vt := _damage.open_ticket(DamageController.KIND_BOARD_FLAT_HERO, "地形变异", String(vrow.get("display_name", vid)), "board", \
|
||||
int(vrow.get("effect_value", 0)), DamageController.TARGET_HERO, ri, evt.cell, "", 0, "", {"variant_id": String(vid)})
|
||||
_damage.submit(vt)
|
||||
_submit(vt, false)
|
||||
# 吞噬流四面(迭代 12 T6——地形从纯税到第三资源带;伤害仍发生=乙稿判据 3 承载):
|
||||
# ①荆棘编织者=挖开伤害型地形格额外掉落一次格面资源(主动吃地形换资源)
|
||||
if int(_damage.feat_flags.get("terrain_dig_double", 0)) > 0:
|
||||
@@ -533,7 +540,7 @@ func _settle() -> void:
|
||||
# 战旗军规开单段(迭代 12 T3 标旗流——flag_judged 批后统一开单:轮末每面标中旗对最前存活敌
|
||||
# 结算 board_typed 必中伤害〔复用零新配方;「旗所在巢穴敌」简化为 default_target 最前存活敌——
|
||||
# 台账披露待追认〕;完美布防=本轮旗批全中(hit>0 且 miss==0)时旗伤 ×mult——全对推理奖励)。
|
||||
# 扫雷结算触发点=flag_strike/flag_all_hit/nest_aura 挂点承载红线①。
|
||||
# 扫雷结算触发点=flag_strike/flag_all_hit/nest_aura 挂点承载红线①;伤害单据案C 暂存战斗段末兑付。
|
||||
if int(_damage.feat_flags.get("flag_strike_value", 0)) > 0:
|
||||
var hits := 0
|
||||
var misses := 0
|
||||
@@ -553,23 +560,23 @@ func _settle() -> void:
|
||||
var st_t := _damage.open_ticket(DamageController.KIND_BOARD_TYPED, "feat_flag_strike",
|
||||
"战旗军规", "board", strike_value, DamageController.TARGET_FRONT_ALIVE, ri,
|
||||
fevt.cell, "normal")
|
||||
_damage.submit(st_t)
|
||||
# 熔火之躯轮末反打(迭代 12 T6 吞噬流——受地形伤积层,轮末每层对全体敌 ~1 必中反伤;
|
||||
# 触发键=「受地形伤」通用不按地形种类特化——定稿红线承载;反打后清零)
|
||||
_submit(st_t, false)
|
||||
# 熔火之躯轮末反打(迭代 12 T6 吞噬流——受地形伤积层,对全体敌 ~1 必中反伤;
|
||||
# 触发键=「受地形伤」通用不按地形种类特化——定稿红线承载;反打后清零;单据案C 暂存战斗段末)
|
||||
var magma := int(_damage.feat_flags.get("variant_counter_value", 0))
|
||||
if magma > 0 and _feat_magma_layers > 0:
|
||||
var mg_t := _damage.open_ticket(DamageController.KIND_BOARD_BLAST, "feat_magma_body",
|
||||
"熔火反噬 ×%d" % _feat_magma_layers, "board", magma * _feat_magma_layers,
|
||||
DamageController.TARGET_ALL_ALIVE, ri, minesweeper.hero_pos(), "", 0, "", {})
|
||||
_damage.submit(mg_t)
|
||||
_submit(mg_t, false)
|
||||
_feat_magma_layers = 0
|
||||
if _facts_path == "cleared":
|
||||
_grant_clear_reward(ri)
|
||||
_damage.flush() # 授予段界结账(B 模式——段内开单攒批到此统一兑现;A 模式 no-op;清图批前另有同步结账点)
|
||||
_damage.flush() # 授予段界结账(案C 后本段伤害单据全数暂存,此处对空队 no-op——保留作防御性段界)
|
||||
# ② 增益/减益段(续存实例组合行;本结算新授予的已在授予段逐 grant 出行——增益状态 义务⑦)
|
||||
_emit_composition_effects("hero", ri)
|
||||
_emit_composition_effects("enemy", ri)
|
||||
# ③ 战斗段(调用序:掷点判定 → apply_damage → commit_action;hero hp=0 短路)
|
||||
# ③ 战斗段(调用序:主角先手 → 逐敌还手 → 地图伤害账殿后〔案C 2026-10-06 用户裁〕;hero hp=0 短路)
|
||||
_combat_segment(ri)
|
||||
# ④ 衰减段(恰一次恒执行含末轮——先兑付后衰减)
|
||||
var k: int = _status_effects.decay_round()
|
||||
@@ -775,7 +782,7 @@ func _apply_flat_row(row: Dictionary, source_class: String, cell: Vector2i, ri:
|
||||
if ctype == "blast":
|
||||
var t := _damage.open_ticket(DamageController.KIND_BOARD_BLAST, source_class, display, "board", power, \
|
||||
DamageController.TARGET_ALL_ALIVE, ri, cell, "", 0, highlight, {"batch_key": String(row.reward_id)})
|
||||
return _damage.outcome(_submit(t, sync))
|
||||
return _outcome_of(_submit(t, sync))
|
||||
if ctype == "pierce" or ctype == "magic":
|
||||
# 伤害道具批(2026-09-18)语义不变:正向 = 单目标克制直伤(必中全额不掷点——棋盘来源伤害既有口径);
|
||||
# 负向 = 主角直伤(复用反噬通道)。
|
||||
@@ -784,7 +791,7 @@ func _apply_flat_row(row: Dictionary, source_class: String, cell: Vector2i, ri:
|
||||
var atk_type: String = String(row.get("attack_type", ctype))
|
||||
var t2 := _damage.open_ticket(DamageController.KIND_BOARD_TYPED, source_class, display, "board", power, \
|
||||
DamageController.TARGET_FRONT_ALIVE, ri, cell, atk_type, 0, highlight, {"batch_key": String(row.reward_id)})
|
||||
return _damage.outcome(_submit(t2, sync))
|
||||
return _outcome_of(_submit(t2, sync))
|
||||
if ctype == "heal":
|
||||
if String(row.get("polarity", "positive")) == "negative":
|
||||
return _submit_flat_hero(source_class, display, power, cell, ri, highlight, sync)
|
||||
@@ -805,14 +812,23 @@ func _apply_flat_row(row: Dictionary, source_class: String, cell: Vector2i, ri:
|
||||
# 开单分流:sync(清图批)走控制器同步开单——先按序结清段内排队单据、再当场兑现本单;
|
||||
# 常规开单按结账时机政策(A 即结 / B 入队)。
|
||||
func _submit(t: Dictionary, sync: bool) -> int:
|
||||
if _defer_board_damage:
|
||||
_deferred_board.append(t) # 案C:授予段伤害单据暂存——战斗段怪物还手后按事件序补提交(sync 同闸,清图批一致延后)
|
||||
return -1
|
||||
return _damage.flush_submit(t) if sync else _damage.submit(t)
|
||||
|
||||
|
||||
# 案C 结账读数:暂存单(_submit 返回 -1)以「将兑付」回报——授予段兑付决策(清图完美第二份等)只能
|
||||
# 依据开单时点事实(该时点敌人存活有保证);战斗段末实际结账若目标已灭,控制器自记未生效行。
|
||||
func _outcome_of(ticket_id: int) -> String:
|
||||
return "redeemed" if ticket_id < 0 else _damage.outcome(ticket_id)
|
||||
|
||||
|
||||
# 主角直伤单据(反噬/治疗包负向——无类型必中,下限保底在控制器管线内)
|
||||
func _submit_flat_hero(source_class: String, display: String, power: int, cell: Vector2i, ri: int, highlight: String, sync := false) -> String:
|
||||
var t := _damage.open_ticket(DamageController.KIND_BOARD_FLAT_HERO, source_class, display, "board", power, \
|
||||
DamageController.TARGET_HERO, ri, cell, "", 0, highlight, {})
|
||||
return _damage.outcome(_submit(t, sync))
|
||||
return _outcome_of(_submit(t, sync))
|
||||
|
||||
|
||||
# 旗判定批:标中 = 该雷格资源的正向兑付(每雷实例一次;高光 = 强制检查点);
|
||||
@@ -942,6 +958,7 @@ func _roll_round_actions() -> void:
|
||||
# 停开(B 模式下若 flush 中主角倒下,由控制器死亡事件终止余单——两模式同一结果)。
|
||||
|
||||
func _combat_segment(ri: int) -> void:
|
||||
_defer_board_damage = false # 案C 闸复位——战斗段起开单即入队(主角/敌方/补提交的地图单按开单序统一结账)
|
||||
# 本轮扫雷事实推导(迭代 12 T4——执拗 streak/连珠矢段数共用取数面):本轮 safe 事件数=
|
||||
# streak;踩雷即清零(mine_hit 监听同口——执拗「踩雷清零」承载)。攻击在战斗段=授予段后
|
||||
# 同一次 _settle 内,facts 已定。
|
||||
@@ -956,7 +973,8 @@ func _combat_segment(ri: int) -> void:
|
||||
# 蓄力层注入(迭代 12 T5——整备军备「每层下轮首段 +1」/厚积薄发满层 spike/铁壁整备减伤——
|
||||
# 三件同读 action_economy.charge_layers;battle 域每轮刷新)
|
||||
_damage.feat_flags["charge_layers"] = action_economy.charge_layers
|
||||
# ⓪ 主角先手攻击(基础攻击恒存在——2026-09-11 用户裁决;先于敌方行动;授予段负向直伤致死 → 致电短路不先手)。
|
||||
# ⓪ 主角先手攻击(基础攻击恒存在——2026-09-11 用户裁决;先于敌方行动。案C 后授予段不再产出伤害,
|
||||
# 主角进入战斗段时恒存活——先手必兑,除非场上无敌)。
|
||||
# 单分量伤害构成(2026-09-19 充能退役批·用户拍板):主角攻击 = 唯一基础分量(atk,吃掷点含暴击;
|
||||
# 类型 = 主角 attack_type 表值——2026-09-18 营地扩展前置批:量与类型抽象分离;查甲效矩阵对应行取克制修正)。
|
||||
# 原"基础 + 穿刺/魔法充能三分量"模型随充能系统整体退役——克制策略归冒险前配置(营地换型 / 未来冒险前参数面),
|
||||
@@ -1010,7 +1028,18 @@ func _combat_segment(ri: int) -> void:
|
||||
et["source_unit"] = u
|
||||
et["context"] = {"skill_id": skill_id, "baseline": baseline}
|
||||
_damage.submit(et)
|
||||
_damage.flush() # 战斗段界结账(B 模式——段内开单攒批到此统一兑现;A 模式 no-op)
|
||||
# 地图伤害兑付(案C 2026-10-06 用户裁——战斗段末:怪物还手后按授予段事件序补提交统一结账;
|
||||
# 主角死于怪物 → 地图账不兑,逐单留「未生效」行不作废静默——没生效也要留痕口径;
|
||||
# 补提交后若地图直伤反杀主角,控制器 _halted 作废余单——战斗已败,胜负归判定段)
|
||||
if int(_enemy_system.hero_unit().get("hp", 0)) <= 0:
|
||||
for t in _deferred_board:
|
||||
_emit_row("reward_ineffective", String(t.get("source_class", "")), t.get("origin_cell", Vector2i(-1, -1)), ri,
|
||||
"%s 未生效(主角已倒下)" % String(t.get("display", "")), 0, {"forfeit": "hero_down"}, "")
|
||||
else:
|
||||
for t in _deferred_board:
|
||||
_damage.submit(t)
|
||||
_deferred_board.clear()
|
||||
_damage.flush() # 战斗段界结账(B 模式——主角单+敌方单+地图单按开单序统一兑现;A 模式地图单补提交时即结)
|
||||
|
||||
|
||||
# ---- 算术读数(伤害管线单据化批 2026-09-24 迁移注记)----
|
||||
|
||||
+32
-6
@@ -1665,9 +1665,9 @@ func _smoke_full_battle(L: int, D: int, label: String) -> void:
|
||||
if not (row.has(atk_t) and row.has("roll") and row.has("ac") and row.has("tier")):
|
||||
hero_breakdown_ok = false
|
||||
check(has_verdict, "%s 步骤流含判定行" % label)
|
||||
# 伤害道具批(2026-09-18):单弱敌遭遇可被挖掘期兑付(穿刺弹/魔法矢/爆裂粉尘)在授予段单独击杀——
|
||||
# 敌全灭后战斗段整段跳过、零先手行为合法结局;先手规则本身由强敌场景(L1/L2 深节点)继续守护。
|
||||
check(hero_attacks >= 1 or run1.terminated, "%s 主角先手攻击行存在或授予段终局(2026-09-11 拍板① + 伤害道具批)×%d" % [label, hero_attacks])
|
||||
# 案C(2026-10-06 用户裁):授予段不再产出伤害——进入战斗段时主角恒存活且场上有敌,
|
||||
# 先手必兑;旧「挖掘期兑付可在授予段单独击杀、零先手合法」结局随地图账迁战斗段末整体消失。
|
||||
check(hero_attacks >= 1, "%s 主角先手攻击行必存在(2026-09-11 拍板① + 案C 地图账殿后)×%d" % [label, hero_attacks])
|
||||
check(hero_breakdown_ok, "%s 主角攻击行携带类型键与掷点读数(单分量——充能退役批)" % label)
|
||||
|
||||
|
||||
@@ -2784,6 +2784,32 @@ func _smoke_settlement_segments() -> void:
|
||||
if decays != 1 or verdicts != 1:
|
||||
decay_verdict_ok = false # 衰减/判定每结算恰一次
|
||||
check(order_ok, "每轮行相位单调(授予→增益/减益→战斗→衰减→判定)")
|
||||
# 案C 段内序(2026-10-06 用户裁):段内伤害序 = 主角先手 →〔连珠矢随先手段〕→ 敌方逐个 → 地图账殿后。
|
||||
# 地图账 = 全部棋盘来源伤害行 + 主角倒下不兑留痕行;违序(先于先手或插进敌方还手中间)即失败。
|
||||
var mapdmg_ok := true
|
||||
for ri_key in by_round.keys():
|
||||
var rows_r: Array = by_round[ri_key]
|
||||
var first_hero := -1
|
||||
var last_enemy := -1
|
||||
for i in rows_r.size():
|
||||
var rw: Dictionary = rows_r[i]
|
||||
if String(rw.get("type", "")) != "damage":
|
||||
continue
|
||||
if String(rw.get("source_class", "")) == "hero_attack" and first_hero < 0:
|
||||
first_hero = i
|
||||
elif String(rw.get("source_class", "")) == "enemy_action":
|
||||
last_enemy = i
|
||||
for i in rows_r.size():
|
||||
var rw: Dictionary = rows_r[i]
|
||||
var sc := String(rw.get("source_class", ""))
|
||||
var is_board_acct: bool = (String(rw.get("type", "")) == "damage" \
|
||||
and not ["hero_attack", "enemy_action", "feat_chain_arrows"].has(sc)) \
|
||||
or String(rw.get("forfeit", "")) == "hero_down"
|
||||
if not is_board_acct:
|
||||
continue
|
||||
if (first_hero >= 0 and i < first_hero) or (last_enemy >= 0 and i < last_enemy):
|
||||
mapdmg_ok = false
|
||||
check(mapdmg_ok, "案C 段内序:地图伤害账殿后(主角先手→敌方逐个→地图账;连珠矢随先手段)")
|
||||
check(decay_verdict_ok, "衰减/判定段每结算恰一段(先兑付后衰减——含末轮)")
|
||||
|
||||
|
||||
@@ -2797,9 +2823,9 @@ func _row_phase(row: Dictionary, ri: int) -> int:
|
||||
"cast":
|
||||
return 2
|
||||
"damage":
|
||||
if String(row.get("source_class", "")) in ["hero_attack", "enemy_action"]:
|
||||
return 2
|
||||
return 0 # 授予段 flat 兑付(爆裂/直伤)
|
||||
return 2 # 案C(2026-10-06 用户裁):全部伤害兑付=战斗段(主角先手/敌方还手/地图账殿后统一结账)
|
||||
"reward_ineffective":
|
||||
return 2 if String(row.get("forfeit", "")) == "hero_down" else 0 # 战斗段末地图账不兑留痕 vs 授予段未生效
|
||||
match String(row.get("source_class", "")):
|
||||
"safe_cell", "mine_hit", "flag_hit", "flag_miss", "clear_reward":
|
||||
if int(row.get("round_index", ri)) < ri:
|
||||
|
||||
Reference in new issue
Block a user