iter41-卡1:核心数据面结构收敛批:85键全清——三族拆域+config_db归位容器+存档拆件+meta瘦身+adventure拆段+spawn束化;行为零变化,8新件在阈

This commit is contained in:
DKChan committed 2026-10-29 01:33:50 +08:00
1 parent bda377eb16
commit a613a3cb90
157 files changed
+7453 -4288

No files matched your search

+25 -25
View File
@@ -294,7 +294,7 @@ func _hero_attack_ctx(t: Dictionary) -> Dictionary:
func _ctx_rewrites(t: Dictionary, target: Dictionary, armor: String, matchup: String) -> Dictionary:
var ac_hits: Array[Variant] = (t.context.get("fx_attack_hits", []) as Array)
var roll_read: Dictionary[Variant, Variant] = _armor_roll()
var threshold: int = defender_ac(target) + int(db.settlement.damage_roll.attack_bonus)
var threshold: int = defender_ac(target) + int(db.combat.settlement.damage_roll.attack_bonus)
# armor_roll 发射点(敌护甲掷骰判定;免掷恒折扣订阅面)
var ar_hits := _fx_hits("armor_roll", {"target_ac": threshold, "roll": int(roll_read.roll)})
var trade_hit := 0
@@ -383,7 +383,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.damage_roll.crit_multiplier), int(ctx["cdelta"]))
var rolled: int = DamageMath.rolled_component(base_value, int(ctx["discount"]), bool(ctx["crit"]), int(db.combat.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)
@@ -392,7 +392,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_roll.damage_floor), pooled)
var landed: int = maxi(int(db.combat.settlement.damage_roll.damage_floor), pooled)
# 加法族:英雄侧 rider(enemy_skill rider 对称位补齐口径)——后置必中附加,独立于掷点与乘区
# (奥术余烬「普攻命中后恒定结算」语义);猎巢人巢控光环(per nest_count)/矿工的执拗开格加成
# (per dig_streak、cap 封顶)同通道合计;档一质变 rider+1 / 档二(crit 时)rider 乘暴击倍率。
@@ -406,7 +406,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 bool(inject["rider_tier_crit"]):
hero_rider = int(round(float(hero_rider) * float(db.settlement.damage_roll.crit_multiplier)))
hero_rider = int(round(float(hero_rider) * float(db.combat.settlement.damage_roll.crit_multiplier)))
landed += hero_rider
payload["hero_rider"] = hero_rider
units.apply_damage(target, landed)
@@ -432,7 +432,7 @@ func _kill_overflow(t: Dictionary, target: Dictionary, landed: int) -> void:
# source_class 用中性名(fx_overflow 泛用通道,不挂件名)
var of_t := open_ticket(DamageController.KIND_BOARD_TYPED, "fx_overflow", "贯穿弹射",
{"channel": "board",
"base_value": maxi(int(db.settlement.damage_roll.damage_floor), int(landed * int(h.get("value", 50)) / 100)),
"base_value": maxi(int(db.combat.settlement.damage_roll.damage_floor), int(landed * int(h.get("value", 50)) / 100)),
"target_rule": DamageController.TARGET_FRONT_ALIVE, "ri": int(t.round_index),
"origin_cell": t.origin_cell, "attack_type": "pierce"})
if policy == POLICY_SEGMENT:
@@ -492,13 +492,13 @@ func _resolve_enemy_skill(t: Dictionary) -> void:
func _enemy_roll(t: Dictionary) -> Dictionary:
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.damage_roll.attack_bonus)
var threshold: int = defender_ac(hero) + int(db.combat.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.damage_roll.crit_multiplier), cdelta)
var rolled: int = DamageMath.rolled_component(float(t.base_value), discount, crit, int(db.combat.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_roll.damage_floor), pooled) + int(t.rider) # rider 后置于伤害下限——独立必中加项,不进乘区
var total: int = maxi(int(db.combat.settlement.damage_roll.damage_floor), pooled) + int(t.rider) # rider 后置于伤害下限——独立必中加项,不进乘区
return {"roll": int(roll_read.roll), "threshold": threshold, "crit": crit, "discount": discount, "total": total}
@@ -520,7 +520,7 @@ func _enemy_shield_apply(hits: Array, total: int) -> Dictionary:
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_roll.damage_floor), total - shield)
total = maxi(int(db.combat.settlement.damage_roll.damage_floor), total - shield)
return {"total": total, "shield": shield}
@@ -541,7 +541,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_roll.damage_floor))
var dealt: int = DamageMath.counter_component(int(t.base_value), cdelta, int(db.combat.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,
@@ -556,7 +556,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_roll.damage_floor), int(t.base_value)) # 伤害下限全来源
var blast_dmg: int = maxi(int(db.combat.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),
@@ -567,7 +567,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_roll.damage_floor), int(t.base_value)) # 伤害下限全来源
var dealt: int = maxi(int(db.combat.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():
@@ -580,16 +580,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.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)}
var stream: RandomNumberGenerator = rng.open_stream(String(db.combat.settlement.damage_roll.armor_roll_stream))
var roll: int = stream.randi_range(1, int(db.combat.settlement.damage_roll.roll_faces))
return {"roll": roll, "crit": roll == int(db.combat.settlement.damage_roll.crit_roll)}
# 掷点折扣读数:nat 最大面恒全额(暴击分支前置),其余查档(缺口 = 阈值 − 掷点)
func _roll_discount(roll: int, threshold: int) -> int:
if roll == int(db.settlement.damage_roll.crit_roll):
if roll == int(db.combat.settlement.damage_roll.crit_roll):
return 100
return DamageMath.roll_discount_percent(roll, threshold, db.settlement.damage_roll.roll_tier_bounds, db.settlement.damage_roll.roll_tier_discounts)
return DamageMath.roll_discount_percent(roll, threshold, db.combat.settlement.damage_roll.roll_tier_bounds, db.combat.settlement.damage_roll.roll_tier_discounts)
# 防守方护甲等级读数(数值轴——与 armor_type 克制属性轴严格分离):敌人 = spawn 期行值快照;
@@ -599,15 +599,15 @@ func defender_ac(unit: Dictionary) -> int:
if bool(unit.get("is_hero", false)):
var total: int = _hero_ac_override
if total < 0:
total = int(db.hero.armor_class)
total = int(db.combat.hero.armor_class)
for eff in effects.query_active("hero"):
var row: Dictionary[Variant, Variant] = db.status_effect_row(eff.effect_id)
var row: Dictionary[Variant, Variant] = db.combat.status_effects.row_by_id(eff.effect_id)
if not row.is_empty() and String(row.unit) == "ac":
total += int(eff.effective_value)
return total
var total_e: int = int(unit.get("armor_class", 0))
for eff_e in effects.query_active("enemy"):
var erow_ac: Dictionary[Variant, Variant] = db.status_effect_row(eff_e.effect_id)
var erow_ac: Dictionary[Variant, Variant] = db.combat.status_effects.row_by_id(eff_e.effect_id)
if not erow_ac.is_empty() and String(erow_ac.unit) == "ac":
total_e += int(eff_e.effective_value)
return total_e
@@ -618,14 +618,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.damage_roll.armor_effectiveness
var tbl: Dictionary[Variant, Variant] = db.combat.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.damage_roll.roll_tier_discounts
var tbl: Array[Variant] = db.combat.settlement.damage_roll.roll_tier_discounts
var idx := tbl.find(discount)
if idx < 0:
return discount
@@ -636,12 +636,12 @@ func _discount_shift_up(discount: int, shift: int) -> int:
func clamped_pool(pool: String) -> int:
var total := 0
for eff in effects.query_active("hero") + effects.query_active("enemy"):
var row: Dictionary[Variant, Variant] = db.status_effect_row(eff.effect_id)
var row: Dictionary[Variant, Variant] = db.combat.status_effects.row_by_id(eff.effect_id)
if row.is_empty():
continue
if String(db.settlement.core.effect_pool_map.get(eff.effect_id, "")) == pool and String(row.unit) == "percent":
if String(db.combat.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.core.pool_clamp_lo), int(db.settlement.core.pool_clamp_hi))
return clampi(total, int(db.combat.settlement.core.pool_clamp_lo), int(db.combat.settlement.core.pool_clamp_hi))
# 攻击行显示名(掷点档位随行文本可读;重档折扣 = "被压制")