卡①T4c(拆件批wr5/wr9/V12): settlement 拆两子 Resource 段——新建 settlement_core_table.gd(7列:source_label_map/effect_pool_map/pool_clamp_lo/pool_clamp_hi/round_direction/p_perfect/seal_hit_premium)+damage_roll_table.gd(10列:equivalence_ref_damage/armor_effectiveness/roll_faces/attack_bonus/roll_tier_bounds/roll_tier_discounts/crit_roll/crit_multiplier/damage_floor/armor_roll_stream)+.uid边车;主表三列形(segment_order留主表+core+damage_roll,类变量18→3,const四枚随主表),validate拆五私有(_validate_scalars/_validate_roll_scalars(9分支超阈续拆)/_validate_frozen/_validate_tier_table/_validate_armor_matrix)错误载荷逐字同构+段缺失fail-fast;settlement.tres单文件嵌套重建(两sub_resource,18列值与尾注批注史逐字—脚本比对18/18无diff+tail_equal);消费方改址97处(.settlement.<列>→.settlement.core./damage_roll. 链式95处+cross_validator局部2处,逐规则计数断言全中;segment_order直读1处零改址);测试改址9文件含G15清单(sim/probe/config_db交叉校验)。验收:gdstyle基线外0 NEW+16套件924 PASS+零SCRIPT ERROR〔拆件批 V12〕
This commit is contained in:
1 parent
bc7a171e3d
commit
e2a2fbf3ee
23 files changed
+221
-160
No files matched your search
@@ -274,7 +274,7 @@ func _hero_attack_ctx(t: Dictionary) -> Dictionary:
|
||||
var ac_hits: Array[Variant] = (t.context.get("fx_attack_hits", []) as Array)
|
||||
var ac_payload: Dictionary[Variant, Variant] = (t.context.get("fx_attack_payload", {}) as Dictionary)
|
||||
var roll_read: Dictionary[Variant, Variant] = _armor_roll()
|
||||
var threshold: int = defender_ac(target) + int(db.settlement.attack_bonus)
|
||||
var threshold: int = defender_ac(target) + int(db.settlement.damage_roll.attack_bonus)
|
||||
# armor_roll 发射点(敌护甲掷骰判定;免掷恒折扣订阅面)
|
||||
var ar_hits := _fx_hits("armor_roll", {"target_ac": threshold, "roll": int(roll_read.roll)})
|
||||
# 按序改写族第一拍:矿工重锤命中交换(正负双修原生形态:命中判定减成 trade_hit 点〔更易命中〕
|
||||
@@ -367,7 +367,7 @@ func _hero_attack_redeem(t: Dictionary, ctx: Dictionary, base_value: float) -> D
|
||||
var ac_hits: Array[Variant] = ctx["ac_hits"]
|
||||
var roll_read: Dictionary[Variant, Variant] = ctx["roll_read"]
|
||||
var atk_type: String = ctx["atk_type"]
|
||||
var rolled: int = DamageMath.rolled_component(base_value, int(ctx["discount"]), bool(ctx["crit"]), int(db.settlement.crit_multiplier), int(ctx["cdelta"]))
|
||||
var rolled: int = DamageMath.rolled_component(base_value, int(ctx["discount"]), bool(ctx["crit"]), int(db.settlement.damage_roll.crit_multiplier), int(ctx["cdelta"]))
|
||||
var payload: Dictionary[Variant, Variant] = {"target": String(target.display_name), "target_id": String(target.get("enemy_id", ""))}
|
||||
payload[atk_type] = rolled # 分量键 = 实际攻击类型(归因字段,单分量模型)
|
||||
payload["roll"] = int(roll_read.roll)
|
||||
@@ -376,7 +376,7 @@ func _hero_attack_redeem(t: Dictionary, ctx: Dictionary, base_value: float) -> D
|
||||
if bool(ctx["crit"]):
|
||||
payload["crit"] = true
|
||||
var pooled: int = DamageMath.pool_damage(rolled, clamped_pool("hero_offense"), clamped_pool("enemy_defense"))
|
||||
var landed: int = maxi(int(db.settlement.damage_floor), pooled)
|
||||
var landed: int = maxi(int(db.settlement.damage_roll.damage_floor), pooled)
|
||||
# 加法族:英雄侧 rider(enemy_skill rider 对称位补齐口径)——后置必中附加,独立于掷点与乘区
|
||||
# (奥术余烬「普攻命中后恒定结算」语义);猎巢人巢控光环(per nest_count)/矿工的执拗开格加成
|
||||
# (per dig_streak、cap 封顶)同通道合计;档一质变 rider+1 / 档二(crit 时)rider 乘暴击倍率。
|
||||
@@ -390,7 +390,7 @@ func _hero_attack_redeem(t: Dictionary, ctx: Dictionary, base_value: float) -> D
|
||||
hero_rider += contrib
|
||||
if hero_rider > 0:
|
||||
if bool(ctx["crit"]) and rider_tier_crit:
|
||||
hero_rider = int(round(float(hero_rider) * float(db.settlement.crit_multiplier)))
|
||||
hero_rider = int(round(float(hero_rider) * float(db.settlement.damage_roll.crit_multiplier)))
|
||||
landed += hero_rider
|
||||
payload["hero_rider"] = hero_rider
|
||||
units.apply_damage(target, landed)
|
||||
@@ -408,7 +408,7 @@ func _hero_attack_redeem(t: Dictionary, ctx: Dictionary, base_value: float) -> D
|
||||
if next_target != null:
|
||||
# source_class 用中性名(fx_overflow 泛用通道,不挂件名)
|
||||
var of_t := open_ticket(DamageController.KIND_BOARD_TYPED, "fx_overflow",
|
||||
"贯穿弹射", "board", maxi(int(db.settlement.damage_floor), int(landed * int(h.get("value", 50)) / 100)),
|
||||
"贯穿弹射", "board", maxi(int(db.settlement.damage_roll.damage_floor), int(landed * int(h.get("value", 50)) / 100)),
|
||||
DamageController.TARGET_FRONT_ALIVE, int(t.round_index), t.origin_cell, "pierce")
|
||||
if policy == POLICY_SEGMENT:
|
||||
_queue.append(of_t)
|
||||
@@ -440,13 +440,13 @@ func _hero_attack_deliver(t: Dictionary, ctx: Dictionary, redemption: Dictionary
|
||||
func _resolve_enemy_skill(t: Dictionary) -> void:
|
||||
var hero: Dictionary[Variant, Variant] = units.hero_unit()
|
||||
var roll_read: Dictionary[Variant, Variant] = _armor_roll()
|
||||
var threshold: int = defender_ac(hero) + int(db.settlement.attack_bonus)
|
||||
var threshold: int = defender_ac(hero) + int(db.settlement.damage_roll.attack_bonus)
|
||||
var crit: bool = bool(roll_read.crit)
|
||||
var discount: int = _roll_discount(int(roll_read.roll), threshold)
|
||||
var cdelta: int = _counter_delta(String(t.attack_type), String(hero.get("armor_type", "light")))
|
||||
var rolled: int = DamageMath.rolled_component(float(t.base_value), discount, crit, int(db.settlement.crit_multiplier), cdelta)
|
||||
var rolled: int = DamageMath.rolled_component(float(t.base_value), discount, crit, int(db.settlement.damage_roll.crit_multiplier), cdelta)
|
||||
var pooled: int = DamageMath.pool_damage(rolled, clamped_pool("hero_defense"), clamped_pool("enemy_output"))
|
||||
var total: int = maxi(int(db.settlement.damage_floor), pooled) + int(t.rider) # rider 后置于伤害下限——独立必中加项,不进乘区
|
||||
var total: int = maxi(int(db.settlement.damage_roll.damage_floor), pooled) + int(t.rider) # rider 后置于伤害下限——独立必中加项,不进乘区
|
||||
# damage_taken 发射+施加(kind=enemy_skill;铁壁整备减伤订阅面:
|
||||
# shield 加法族合计 value×per(charge_layers),稳健拓荒树规则同面(rebuild 合成订阅);
|
||||
# 减后过下限保底。damage_reduce〔背水 hp_ratio when〕/counter_add〔保险丝/
|
||||
@@ -466,7 +466,7 @@ func _resolve_enemy_skill(t: Dictionary) -> void:
|
||||
var set_v = h.get("set", null)
|
||||
EffectEngine.counter_add(_ctx, String(h.get("counter_id", "")), int(h.get("value", 0)) if set_v == null else int(set_v), set_v != null)
|
||||
if shield > 0:
|
||||
total = maxi(int(db.settlement.damage_floor), total - shield)
|
||||
total = maxi(int(db.settlement.damage_roll.damage_floor), total - shield)
|
||||
units.apply_damage(hero, total)
|
||||
var payload: Dictionary[Variant, Variant] = {"target": "hero", "skill_id": String(t.context.get("skill_id", "")), "baseline": int(t.context.get("baseline", 0)),
|
||||
"roll": int(roll_read.roll), "ac": threshold, "tier": discount, "attack_type": String(t.attack_type)}
|
||||
@@ -499,7 +499,7 @@ func _resolve_board_typed(t: Dictionary) -> void:
|
||||
# 无模式 delta 才入棋盘窗(mode 路由:clamp_bonus=主角攻击面专享、discount_shift=折扣档面)
|
||||
if String(h.get("kind", "")) == "modify_ticket" and h.has("delta") and String(h.get("mode", "")) == "":
|
||||
cdelta += int(h.delta)
|
||||
var dealt: int = DamageMath.counter_component(int(t.base_value), cdelta, int(db.settlement.damage_floor))
|
||||
var dealt: int = DamageMath.counter_component(int(t.base_value), cdelta, int(db.settlement.damage_roll.damage_floor))
|
||||
units.apply_damage(target, dealt)
|
||||
emit_row_cb.call({"type": "damage", "source_class": String(t.source_class), "origin_cell": t.origin_cell, "highlight": String(t.highlight)}, int(t.round_index),
|
||||
"%s → %s" % [String(t.display), String(target.display_name)], dealt,
|
||||
@@ -514,7 +514,7 @@ func _resolve_board_blast(t: Dictionary) -> void:
|
||||
_ineffective_row(t, "无存活敌人")
|
||||
_outcomes[int(t.ticket_id)] = "zero"
|
||||
return
|
||||
var blast_dmg: int = maxi(int(db.settlement.damage_floor), int(t.base_value)) # 伤害下限全来源
|
||||
var blast_dmg: int = maxi(int(db.settlement.damage_roll.damage_floor), int(t.base_value)) # 伤害下限全来源
|
||||
for u in alive:
|
||||
units.apply_damage(u, blast_dmg) # 恒定表值(下限保底),逐个;受击即死——死亡即不动手
|
||||
emit_row_cb.call({"type": "damage", "source_class": String(t.source_class), "origin_cell": t.origin_cell, "highlight": String(t.highlight)}, int(t.round_index),
|
||||
@@ -525,7 +525,7 @@ func _resolve_board_blast(t: Dictionary) -> void:
|
||||
|
||||
# 棋盘主角直伤(反噬/治疗包负向/地形变异):无类型必中,下限保底;context 键并入行载荷
|
||||
func _resolve_board_flat_hero(t: Dictionary) -> void:
|
||||
var dealt: int = maxi(int(db.settlement.damage_floor), int(t.base_value)) # 伤害下限全来源
|
||||
var dealt: int = maxi(int(db.settlement.damage_roll.damage_floor), int(t.base_value)) # 伤害下限全来源
|
||||
units.apply_damage(units.hero_unit(), dealt)
|
||||
var extra: Dictionary[Variant, Variant] = {"target": "hero"}
|
||||
for k in t.context.keys():
|
||||
@@ -538,16 +538,16 @@ func _resolve_board_flat_hero(t: Dictionary) -> void:
|
||||
|
||||
# 护甲等级掷点(armor_roll 封闭流——逐次掷逐次取号、逐位可回放):返回 {roll, crit}
|
||||
func _armor_roll() -> Dictionary:
|
||||
var stream: RandomNumberGenerator = rng.open_stream(String(db.settlement.armor_roll_stream))
|
||||
var roll: int = stream.randi_range(1, int(db.settlement.roll_faces))
|
||||
return {"roll": roll, "crit": roll == int(db.settlement.crit_roll)}
|
||||
var stream: RandomNumberGenerator = rng.open_stream(String(db.settlement.damage_roll.armor_roll_stream))
|
||||
var roll: int = stream.randi_range(1, int(db.settlement.damage_roll.roll_faces))
|
||||
return {"roll": roll, "crit": roll == int(db.settlement.damage_roll.crit_roll)}
|
||||
|
||||
|
||||
# 掷点折扣读数:nat 最大面恒全额(暴击分支前置),其余查档(缺口 = 阈值 − 掷点)
|
||||
func _roll_discount(roll: int, threshold: int) -> int:
|
||||
if roll == int(db.settlement.crit_roll):
|
||||
if roll == int(db.settlement.damage_roll.crit_roll):
|
||||
return 100
|
||||
return DamageMath.roll_discount_percent(roll, threshold, db.settlement.roll_tier_bounds, db.settlement.roll_tier_discounts)
|
||||
return DamageMath.roll_discount_percent(roll, threshold, db.settlement.damage_roll.roll_tier_bounds, db.settlement.damage_roll.roll_tier_discounts)
|
||||
|
||||
|
||||
# 防守方护甲等级读数(数值轴——与 armor_type 克制属性轴严格分离):敌人 = spawn 期行值快照;
|
||||
@@ -576,14 +576,14 @@ func defender_ac(unit: Dictionary) -> int:
|
||||
func _counter_delta(attack_type: String, armor: String) -> int:
|
||||
if attack_type == "":
|
||||
return 0
|
||||
var tbl: Dictionary[Variant, Variant] = db.settlement.armor_effectiveness
|
||||
var tbl: Dictionary[Variant, Variant] = db.settlement.damage_roll.armor_effectiveness
|
||||
var row: Dictionary[Variant, Variant] = tbl.get(attack_type, {})
|
||||
return int(row.get(armor, 0))
|
||||
|
||||
|
||||
# 折扣档改善(猎弱本能——折扣表向全额方向移 value 档;查不到当前档 = 不动防御口径)
|
||||
func _discount_shift_up(discount: int, shift: int) -> int:
|
||||
var tbl: Array[Variant] = db.settlement.roll_tier_discounts
|
||||
var tbl: Array[Variant] = db.settlement.damage_roll.roll_tier_discounts
|
||||
var idx := tbl.find(discount)
|
||||
if idx < 0:
|
||||
return discount
|
||||
@@ -597,9 +597,9 @@ func clamped_pool(pool: String) -> int:
|
||||
var row: Dictionary[Variant, Variant] = db.status_effect_row(eff.effect_id)
|
||||
if row.is_empty():
|
||||
continue
|
||||
if String(db.settlement.effect_pool_map.get(eff.effect_id, "")) == pool and String(row.unit) == "percent":
|
||||
if String(db.settlement.core.effect_pool_map.get(eff.effect_id, "")) == pool and String(row.unit) == "percent":
|
||||
total += eff.effective_value # 池内加算(L×m 原样——越域不 clamp 由本处收口)
|
||||
return clampi(total, int(db.settlement.pool_clamp_lo), int(db.settlement.pool_clamp_hi))
|
||||
return clampi(total, int(db.settlement.core.pool_clamp_lo), int(db.settlement.core.pool_clamp_hi))
|
||||
|
||||
|
||||
# 攻击行显示名(掷点档位随行文本可读;重档折扣 = "被压制")
|
||||
|
||||
Reference in new issue
Block a user