iter46-卡1:换图系双基座七件批: 七件实装+全局damage_taken统一+BattleRefreshFlow拆件+词表扩签+数据37行——代码域闸全绿
This commit is contained in:
1 parent
b5b2c55557
commit
3fa99583fb
15 files changed
+1055
-76
No files matched your search
@@ -0,0 +1,43 @@
|
||||
class_name BattleRefreshFlow
|
||||
extends RefCounted
|
||||
## 换图刷新流程件(迭代 46 卡A T3/T4 自编排器拆出):刷新可用性门、折价扣费、换图执行与成功事实登记。
|
||||
## 拆分边界(需求卡片 C13):本件只负责可用性、扣费、换图与成功事实登记——七件效果的算法留在
|
||||
## 效果引擎、授予段与伤害控制器。调用路径=呈现层→编排器单行转发→本件→行动经济/装板壳/授予段。
|
||||
## 反自动刷新(C11):只经玩家入口发起,禁 RAP 满自动刷——编排器公开面单行转发,无自动调用点。
|
||||
## 成功序钉死(T4):折价扣 RAP→refresh_used+1→旧资源退役→旧板退役→装新板→授予段成功事实发射;
|
||||
## 装板失败返回 false 且零效果——成功事实只在新板就位后发射。
|
||||
|
||||
|
||||
## 折价成本读数(refresh_request 命中省力周转 apply_discount——只认 kind==apply_discount 且
|
||||
## mode==refresh,取声明序第一命中,floor(base×cost_mult/100);无命中=表基线逐位不变。
|
||||
## can_refresh 与 execute 同源取数〔V3——can 与执行同源判断〕;折扣只改变门槛与扣费,
|
||||
## 不改变拒绝判据〔C2——每轮上限与相位判据照旧〕)
|
||||
static func _effective_refresh_cost(oc: BattleOrchestrator) -> int:
|
||||
var base := int(oc.db.run.action_economy.rap_refresh_cost)
|
||||
for h in oc.fx_host().fx_emit("refresh_request", {"mode": "refresh", "base": base}):
|
||||
if String(h.get("kind", "")) == "apply_discount" and String(h.get("mode", "")) == "refresh":
|
||||
return int(floor(float(base) * float(int(h.get("cost_mult", 100))) / 100.0))
|
||||
return base
|
||||
|
||||
|
||||
## 可用性门(HUD 刷新按钮同源判据):战斗未终局、每轮上限未满、Active 相位、RAP 抵折后价。
|
||||
static func can_refresh(oc: BattleOrchestrator) -> bool:
|
||||
return oc.battle_result == "" \
|
||||
and oc._facts.refresh_used < int(oc.db.run.action_economy.refresh_cap_per_round) \
|
||||
and oc.action_economy.phase == oc.action_economy.PHASE_ACTIVE \
|
||||
and oc.action_economy.rap >= _effective_refresh_cost(oc)
|
||||
|
||||
|
||||
## 执行(玩家请求刷新唯一通道体):扣费受理后继续;扣费拒绝/门拒零效果零事实。
|
||||
static func execute(oc: BattleOrchestrator) -> bool:
|
||||
if not can_refresh(oc):
|
||||
return false
|
||||
if not oc.action_economy.request_refresh(_effective_refresh_cost(oc)):
|
||||
return false
|
||||
oc._facts.refresh_used += 1
|
||||
oc._reward_economy.retire_mapping() # 旧图批次退役(地图战斗资源 Ready→retired;E6 新批重置前提)
|
||||
oc.minesweeper.retire_board(true) # 旧板退役(轮内通道)
|
||||
if not oc._install_and_reset(true): # 当场换图——失败即编排违例 fail-fast(零成功事实)
|
||||
return false
|
||||
oc._rounds._grant_seg.apply_board_refreshed(oc.round_index) # 成功事实:新板就位后一次发射
|
||||
return true
|
||||
@@ -0,0 +1 @@
|
||||
uid://d2kjxlt5b2eqv
|
||||
@@ -6,7 +6,8 @@ extends RefCounted
|
||||
# 效果施加归 BattleFxHost(段持三引用直调,零转发壳)——
|
||||
# 本段只搬运时序,零算法改动(🔴 零行为变更契约:同种子完整局输出逐位一致)。
|
||||
# run 编排骨架+批私有族(_reveal_batch/_terrain_batch/_seal_batch/_round_end_apply,段内施加面
|
||||
# 再拆 _reveal_safe_apply/_reveal_mine_apply/_terrain_damage_reduce/_seal_hit_effects 等单面函数);
|
||||
# 再拆 _reveal_safe_apply/_reveal_mine_apply/_seal_hit_effects 等单面函数);地形 damage_taken
|
||||
# 消费随迭代 46 卡A T2 并入伤害控制器全局消费族(本段零本地减伤函数);
|
||||
# kind 分派单点化(P1-1 同批):counter_add 五位三行组 / grant_material 三位兑付块
|
||||
# 收 _apply_counter_hit / _apply_material_hit 两助手(分支本体逐字保留在助手内)。
|
||||
|
||||
@@ -32,6 +33,27 @@ func run(ri: int) -> void:
|
||||
_round_end_apply(ri)
|
||||
|
||||
|
||||
# 成功刷新事实发射+施加(迭代 46 卡A T4——BattleRefreshFlow 装新板后单点调用,每成功刷新恰一次;
|
||||
# 拒绝刷新零事实〔C2〕。命中消费三面:counter_add→既有单点落账〔蓄力周转/石层缓冲/坑道小憩 计数〕;
|
||||
# grant_gp→战斗内缓冲 escrow 入账+fx_grant_gp 行〔矿道红利——不绑清图奖励,C7〕;
|
||||
# open_ticket channel=blast→崩壁冲击群伤单延迟入队〔案C 同队列,战斗段末按存活目标结账〕)
|
||||
func apply_board_refreshed(ri: int) -> void:
|
||||
var br_hits := fx_host.fx_emit("board_refreshed", {"round": ri})
|
||||
for h in br_hits:
|
||||
if String(h.get("kind", "")) == "counter_add":
|
||||
_apply_counter_hit(h)
|
||||
for h in br_hits:
|
||||
if String(h.get("kind", "")) == "grant_gp":
|
||||
reward_grant.escrow += int(h.get("value", 0))
|
||||
oc._emit_row({"type": "effect", "source_class": "fx_grant_gp", "origin_cell": Vector2i(-1, -1)}, ri, "专长·GP 入账 +%d" % int(h.get("value", 0)), int(h.get("value", 0)), {"effect_id": "fx_grant_gp", "escrow": reward_grant.escrow})
|
||||
for h in br_hits:
|
||||
if String(h.get("kind", "")) == "open_ticket" and String(h.get("channel", "")) == "blast":
|
||||
var bb_t := oc._damage.open_ticket(DamageController.KIND_BOARD_BLAST, "fx_board_refresh", "崩壁冲击",
|
||||
{"channel": "board", "base_value": int(h.get("value", 0)), "target_rule": DamageController.TARGET_ALL_ALIVE,
|
||||
"ri": ri, "origin_cell": Vector2i(-1, -1)})
|
||||
reward_grant.defer_ticket(bb_t)
|
||||
|
||||
|
||||
# 开格/踩雷兑付批(轮 facts_reveals 资源事件序:safe 正向乘区兑付 / mine_hit 减半负向兑付)
|
||||
func _reveal_batch(ri: int) -> void:
|
||||
for evt in oc._facts.reveals:
|
||||
@@ -167,37 +189,22 @@ func _terrain_batch(ri: int) -> void:
|
||||
if String(vrow.get("effect", "")) != "flat_damage":
|
||||
continue # 触发词表按 effect 路由:flat_damage=on_open 兑现;hide_number/on_open 外组合 = 数据行新词表未接线(显式忽略面)
|
||||
# 地形变异伤害单据——无类型必中,下限保底在控制器管线内
|
||||
# damage_taken 发射在单据开立前:damage_reduce〔背水——hp_ratio when
|
||||
# 面〕先收集再按减后值开单;counter_add〔保险丝/石肤〕+ ac_bonus〔石肤〕照常施加;
|
||||
# grant_material〔荆棘/地脉〕移到单据提交后(兑付值序一致——收益不因减伤变化)
|
||||
# damage_taken 统一发射(迭代 46 卡A T2——地形路径并入全局消费族 _emit_hero_damage_taken:
|
||||
# 发射在单据开立前、减后值开单,组合消费含 shield〔全局受伤语义〕;
|
||||
# hero_damage_consumed 标记入单据 context——战斗段末 _resolve_board_flat_hero 跳过重复发射;
|
||||
# grant_material〔荆棘/地脉〕移到单据提交后(兑付值序一致——收益不因减伤变化))
|
||||
var dt_amount := int(vrow.get("effect_value", 0))
|
||||
var dt_hits := fx_host.fx_emit("damage_taken", {"kind": "terrain", "amount": dt_amount,
|
||||
"source": String(vid), "cell": evt.cell, "round": ri, "terrain_kind": String(vid),
|
||||
"hp_ratio": int(round(100.0 * float(int(oc._enemy_system.hero_unit().get("hp", 0))) / float(maxi(1, int(oc._enemy_system.hero_unit().get("max_hp", 1))))))})
|
||||
dt_amount = _terrain_damage_reduce(dt_hits, dt_amount)
|
||||
var dt_res := oc._damage._emit_hero_damage_taken(dt_amount, "terrain", String(vid), evt.cell, ri)
|
||||
dt_amount = int(dt_res["total"])
|
||||
var vt := oc._damage.open_ticket(DamageController.KIND_BOARD_FLAT_HERO, "地形变异", String(vrow.get("display_name", vid)),
|
||||
{"channel": "board", "base_value": dt_amount, "target_rule": DamageController.TARGET_HERO,
|
||||
"ri": ri, "origin_cell": evt.cell, "context": {"variant_id": String(vid)}})
|
||||
"ri": ri, "origin_cell": evt.cell, "context": {"variant_id": String(vid), "hero_damage_consumed": true}})
|
||||
reward_grant.submit(vt, false)
|
||||
for h in dt_hits:
|
||||
for h in (dt_res["hits"] as Array):
|
||||
if String(h.get("kind", "")) == "grant_material":
|
||||
_apply_material_hit(h, evt.cell, ri)
|
||||
|
||||
|
||||
# damage_taken 施加面(damage_reduce 减量收集〔背水——定值〕/ac_bonus〔石肤〕/counter_add〔保险丝/石肤〕;
|
||||
# 返回减后 amount 交开单消费)
|
||||
func _terrain_damage_reduce(dt_hits: Array, dt_amount: int) -> int:
|
||||
for h in dt_hits:
|
||||
match String(h.get("kind", "")):
|
||||
"damage_reduce":
|
||||
dt_amount = maxi(0, dt_amount - int(h.get("value", 0)))
|
||||
"ac_bonus":
|
||||
fx_host.apply_ac_bonus(h)
|
||||
"counter_add":
|
||||
_apply_counter_hit(h)
|
||||
return dt_amount
|
||||
|
||||
|
||||
# 封印判定批+战封印军规开单段(封印流:seal_judged 批后统一开单:轮末每面封印命中对最前存活敌
|
||||
# 结算 board_typed 必中伤害〔复用零新配方;「封印所在巢穴敌」简化为 default_target 最前存活敌——
|
||||
# 台账披露待追认〕;完美布防=本轮封印批全中(hit>0 且 miss==0)时封印伤 ×mult——全对推理奖励)。
|
||||
@@ -259,6 +266,7 @@ func _seal_strike_value(fs_fx: Array, fs_hits: int, fs_misses: int) -> Dictionar
|
||||
func _round_end_apply(ri: int) -> void:
|
||||
var re_fx := fx_host.fx_emit("round_end", {"round": ri})
|
||||
_round_end_blast_tickets(re_fx, ri)
|
||||
_round_end_heal_value_counter(re_fx, ri) # 迭代 46 卡A T5——坑道小憩恢复兑付(先于清零行消费层值,声明序=heal 行在 counter set 行前)
|
||||
for h in re_fx:
|
||||
if String(h.get("kind", "")) == "counter_add":
|
||||
_apply_counter_hit(h)
|
||||
@@ -278,6 +286,24 @@ func _round_end_apply(ri: int) -> void:
|
||||
oc._damage.flush() # 授予段界结账(案C 后本段伤害单据全数暂存,此处对空队 no-op——保留作防御性段界)
|
||||
|
||||
|
||||
# round_end heal value_counter 兑付(迭代 46 卡A T5——坑道小憩:层值=本轮成功刷新累计恢复点,
|
||||
# units.heal 封顶、满血发未生效行;层清零由同事件 counter_add set 行承载〔声明序在后〕——本面
|
||||
# 先于 counter_add 遍历消费层值即保序。行源=成功刷新事实族(无棋盘格——fx_board_refresh 豁免类))
|
||||
func _round_end_heal_value_counter(re_fx: Array, ri: int) -> void:
|
||||
for h in re_fx:
|
||||
if String(h.get("kind", "")) != "heal" or String(h.get("value_counter", "")) == "":
|
||||
continue
|
||||
var layers := EffectEngine.counter(fx_host.counters_ctx, String(h.get("value_counter", "")))
|
||||
if layers <= 0:
|
||||
continue
|
||||
var hu: Dictionary[Variant, Variant] = oc._enemy_system.hero_unit()
|
||||
if int(hu.get("hp", 0)) >= int(hu.get("max_hp", 1)):
|
||||
oc._emit_row({"type": "reward_ineffective", "source_class": "fx_board_refresh", "origin_cell": Vector2i(-1, -1)}, ri, "坑道小憩 未生效(满血)", 0, {"batch_key": String(h.get("value_counter", ""))})
|
||||
continue
|
||||
var healed: int = oc._enemy_system.heal(hu, layers)
|
||||
oc._emit_row({"type": "heal", "source_class": "fx_board_refresh", "origin_cell": Vector2i(-1, -1)}, ri, "坑道小憩 回复", healed, {"target": "hero"})
|
||||
|
||||
|
||||
# round_end blast 通道反打单(per-counter 积层读数×value=反打总量;source_class 用中性名,
|
||||
# per-counter 反打通道保留泛用面;案C 暂存战斗段末兑付)
|
||||
func _round_end_blast_tickets(re_fx: Array, ri: int) -> void:
|
||||
|
||||
Reference in new issue
Block a user