T4穿刺流+普攻流八件(迭代12——整合定稿S2/S3):relics.tres填8行(贯穿射击rarest锚点·击杀弹射/连珠矢rare·开格节奏转段数/猎弱本能rare·折扣档前移/猎手刺剑common·pierce-vs-light+1——对重甲无增益正负双修+矿工的执拗common·轮内开格数转攻击踩雷清零/矿工重锤common·命中交换+25%对-2AC/专注rare·免掷骰恒75%方差买断/碎甲震击rare·命中重甲授予off_guard复用零新状态行);damage_controller掷骰面四改写(重锤threshold减/专注roll改写roll记0归因/猎弱_discount_shift_up折扣表向全额移档/clamp扩pierce_vs_light)+执拗动态rider(dig_streak×value上限cap)+碎甲apply_effect+贯穿射击击杀半额弹射(B模式入队/A模式递归——「溢出追踪」单分量模型不可行半额裁定披露待追认);orchestrator本轮扫雷事实推导(safe计数/踩雷清零——执拗连珠矢共用取数面)+连珠矢段数攻击后附加单(origin=英雄格——(-1,-1)越界脚本错误事故修复留痕);冒烟+2断言表换代16行→692/0三闸+run_all全绿
This commit is contained in:
1 parent
a85de50336
commit
db65b73bc7
4 files changed
+201
-14
No files matched your search
@@ -111,6 +111,8 @@ func _relic_flags_for(relic_ids: Array) -> void:
|
||||
flags["clamp_magic_magic"] = int(flags.get("clamp_magic_magic", 0)) + int(fx.get("value", 0))
|
||||
elif String(fx.get("polarity", "")) == "magic_vs_heavy":
|
||||
flags["clamp_magic_heavy"] = int(flags.get("clamp_magic_heavy", 0)) + int(fx.get("value", 0))
|
||||
elif String(fx.get("polarity", "")) == "pierce_vs_light":
|
||||
flags["clamp_pierce_light"] = int(flags.get("clamp_pierce_light", 0)) + int(fx.get("value", 0))
|
||||
"first_dig_spell":
|
||||
flags["first_dig_spell"] = true
|
||||
flags["spell_value"] = int(fx.get("value", 0))
|
||||
@@ -122,6 +124,23 @@ func _relic_flags_for(relic_ids: Array) -> void:
|
||||
flags["flag_all_hit_mult"] = int(fx.get("value", 0))
|
||||
"flag_strike":
|
||||
flags["flag_strike_value"] = int(fx.get("value", 0))
|
||||
"kill_overflow":
|
||||
flags["kill_overflow"] = true
|
||||
"dig_count_segments":
|
||||
flags["chain_value"] = int(fx.get("value", 0))
|
||||
flags["chain_cap"] = int(fx.get("cap", 2))
|
||||
"roll_discount":
|
||||
flags["discount_shift"] = int(fx.get("value", 0))
|
||||
"round_dig_bonus":
|
||||
flags["round_dig_value"] = int(fx.get("value", 0))
|
||||
flags["round_dig_cap"] = int(fx.get("cap", 5))
|
||||
"hit_trade":
|
||||
flags["hit_trade_atk"] = int(fx.get("trade_atk", 0))
|
||||
flags["hit_trade_hit"] = int(fx.get("trade_hit", 0))
|
||||
"armor_roll_rewrite":
|
||||
flags["armor_roll_rewrite"] = int(fx.get("value", 0))
|
||||
"heavy_debuff":
|
||||
flags["crack_value"] = int(fx.get("value", 0))
|
||||
var mt := int(tiers.get("magic", 0))
|
||||
if mt >= 1:
|
||||
flags["rider_flat"] = int(flags.get("rider_flat", 0)) + 1 # 档一质变(≥2 件):rider +1(provisional)
|
||||
@@ -747,6 +766,17 @@ func _roll_round_actions() -> void:
|
||||
# 停开(B 模式下若 flush 中主角倒下,由控制器死亡事件终止余单——两模式同一结果)。
|
||||
|
||||
func _combat_segment(ri: int) -> void:
|
||||
# 本轮扫雷事实推导(迭代 12 T4——执拗 streak/连珠矢段数共用取数面):本轮 safe 事件数=
|
||||
# streak;踩雷即清零(mine_hit 监听同口——执拗「踩雷清零」承载)。攻击在战斗段=授予段后
|
||||
# 同一次 _settle 内,facts 已定。
|
||||
var round_safe := 0
|
||||
var round_mine := false
|
||||
for evt in _facts_reveals:
|
||||
if evt.kind == "safe":
|
||||
round_safe += 1
|
||||
elif evt.kind == "mine":
|
||||
round_mine = true
|
||||
_damage.relic_flags["dig_streak"] = 0 if round_mine else round_safe
|
||||
# ⓪ 主角先手攻击(基础攻击恒存在——2026-09-11 用户裁决;先于敌方行动;授予段负向直伤致死 → 致电短路不先手)。
|
||||
# 单分量伤害构成(2026-09-19 充能退役批·用户拍板):主角攻击 = 唯一基础分量(atk,吃掷点含暴击;
|
||||
# 类型 = 主角 attack_type 表值——2026-09-18 营地扩展前置批:量与类型抽象分离;查甲效矩阵对应行取克制修正)。
|
||||
@@ -760,6 +790,16 @@ func _combat_segment(ri: int) -> void:
|
||||
var ht := _damage.open_ticket(DamageController.KIND_HERO_ATTACK, "hero_attack", "主角攻击", "combat", _hero_atk, \
|
||||
DamageController.TARGET_FRONT_ALIVE, ri, Vector2i(-1, -1), String(_enemy_system.hero_unit().get("attack_type", "normal")))
|
||||
_damage.submit(ht)
|
||||
# 连珠矢(迭代 12 T4 穿刺流——开格节奏变攻击段数):本轮每开 ~3 安全格 +1 段穿刺附加
|
||||
# (上限 cap;段值 provisional 固定值不乘 atk——台账披露)。扫描雷结算触发点=dig_count_segments。
|
||||
var chain_value := int(_damage.relic_flags.get("chain_value", 0))
|
||||
if chain_value > 0:
|
||||
var segments := mini(int(_damage.relic_flags.get("chain_cap", 2)), int(_damage.relic_flags.get("dig_streak", 0)) / 3)
|
||||
for s in segments:
|
||||
var ct := _damage.open_ticket(DamageController.KIND_BOARD_TYPED, "relic_chain_arrows",
|
||||
"连珠矢", "board", chain_value, DamageController.TARGET_FRONT_ALIVE, ri,
|
||||
minesweeper.hero_pos(), "pierce")
|
||||
_damage.submit(ct)
|
||||
# 敌方行动(敌人技能池批——本拍动作开轮已摇定,此处按技能行兑现;行序 = 生成序)。
|
||||
# 死亡即不动手:摇定后、兑现前死亡的敌不在存活序中——本拍技能作废,不 commit、不进冷却。
|
||||
for u in _enemy_system.query_alive("enemy"):
|
||||
|
||||
@@ -198,14 +198,34 @@ func _resolve_hero_attack(t: Dictionary) -> void:
|
||||
var atk_type: String = String(t.attack_type)
|
||||
var roll_read: Dictionary = _armor_roll()
|
||||
var threshold: int = defender_ac(target) + int(db.settlement.attack_bonus)
|
||||
# 矿工重锤·命中交换(迭代 12 T4 普攻流——正负双修原生形态:命中判定减成 trade_hit 点
|
||||
# 〔更易命中〕换攻击增伤 trade_atk%——高 AC 负期望/低 AC 正期望)
|
||||
var trade_hit := int(relic_flags.get("hit_trade_hit", 0))
|
||||
if trade_hit > 0:
|
||||
threshold = maxi(1, threshold - trade_hit)
|
||||
var crit: bool = bool(roll_read.crit)
|
||||
var discount: int = _roll_discount(int(roll_read.roll), threshold)
|
||||
# 专注(迭代 12 T4 普攻流——免掷骰恒定折扣:方差买断成期望——稳定器人格;roll 记 0 归因)
|
||||
var rewrite := int(relic_flags.get("armor_roll_rewrite", 0))
|
||||
if rewrite > 0:
|
||||
discount = rewrite
|
||||
crit = false
|
||||
roll_read["roll"] = 0
|
||||
# 猎弱本能(迭代 12 T4 穿刺流——对轻甲敌折扣档改善 value 档:对冲 pierce 列 L1 −1 开局罚;
|
||||
# 改善 = 折扣表向全额方向移档,nat 最大面/已全额不重复)
|
||||
var shift := int(relic_flags.get("discount_shift", 0))
|
||||
if shift > 0 and armor == "light" and discount < 100:
|
||||
discount = _discount_shift_up(discount, shift)
|
||||
var cdelta: int = _counter_delta(atk_type, armor) + _relic_clamp_bonus(atk_type, armor)
|
||||
# 淬毒刃纹(迭代 11 同调批 T5——底稿 §3:对被克制敌人的穿刺/魔法直伤 +N;条件 = 克制成立 ×
|
||||
# 攻击类型限定,主角攻击面专属——棋盘克制直伤走 _resolve_board_typed 不吃本加成)
|
||||
if attune_venom > 0 and (atk_type == "pierce" or atk_type == "magic") and cdelta > 0:
|
||||
cdelta += attune_venom
|
||||
var rolled: int = DamageMath.rolled_component(float(t.base_value), discount, crit, int(db.settlement.crit_multiplier), cdelta)
|
||||
var base_value := float(t.base_value)
|
||||
var trade_atk := int(relic_flags.get("hit_trade_atk", 0))
|
||||
if trade_atk > 0:
|
||||
base_value *= 1.0 + float(trade_atk) / 100.0 # 重锤增伤面(交换的正向侧)
|
||||
var rolled: int = DamageMath.rolled_component(base_value, discount, crit, int(db.settlement.crit_multiplier), cdelta)
|
||||
var payload: Dictionary = {"target": String(target.display_name)}
|
||||
payload[atk_type] = rolled # 分量键 = 实际攻击类型(归因字段,单分量模型)
|
||||
payload["roll"] = int(roll_read.roll)
|
||||
@@ -227,6 +247,11 @@ func _resolve_hero_attack(t: Dictionary) -> void:
|
||||
for eff in effects.query_active("enemy"):
|
||||
if String(eff.effect_id) == "weaken":
|
||||
hero_rider += nest_aura
|
||||
# 矿工的执拗(迭代 12 T4 普攻流——「排雷排得多好,打得就有多疼」):本轮安全开格 streak
|
||||
# 〔编排器授予段实时写入 relic_flags.dig_streak;踩雷清零〕×value,上限 cap。
|
||||
var rdig := int(relic_flags.get("round_dig_value", 0))
|
||||
if rdig > 0:
|
||||
hero_rider += mini(int(relic_flags.get("round_dig_cap", 5)), int(relic_flags.get("dig_streak", 0)) * rdig)
|
||||
if hero_rider > 0:
|
||||
if crit and bool(relic_flags.get("rider_crit", false)):
|
||||
hero_rider = int(round(float(hero_rider) * float(db.settlement.crit_multiplier)))
|
||||
@@ -234,10 +259,29 @@ func _resolve_hero_attack(t: Dictionary) -> void:
|
||||
payload["hero_rider"] = hero_rider
|
||||
units.apply_damage(target, landed)
|
||||
payload["killed"] = not target.alive # 击杀标记在扣血后取(原语义不变)
|
||||
# 碎甲震击(迭代 12 T4 普攻流——命中重甲附加「护甲裂解」):复用 off_guard(enemy percent
|
||||
# +25 受伤加深——零新状态行);apply_effect 域闭/重复授予由状态容器自行守卫。
|
||||
var crack := int(relic_flags.get("crack_value", 0))
|
||||
if crack > 0 and armor == "heavy":
|
||||
effects.apply_effect("off_guard", {"source_class": "relic_armor_crack"}, -1)
|
||||
payload["cracked"] = true
|
||||
var label := _attack_label(String(t.display), crit, discount)
|
||||
if hero_rider > 0:
|
||||
label += "+奥术%d(必中)" % hero_rider
|
||||
emit_row_cb.call("damage", String(t.source_class), t.origin_cell, int(t.round_index), label, landed, payload, String(t.highlight))
|
||||
# 贯穿射击(迭代 12 T4 穿刺流——击杀溢出弹射):击杀时对下一存活敌以穿刺类型弹射
|
||||
# 本体半额〔原设计「溢出伤害」追踪在单分量模型不可行——半额弹射 provisional 裁定披露待追认;
|
||||
# 无次敌=弹射落空〕。B 模式入队段尾 flush 兑现;A 模式递归 resolve(目标存活守卫内建)。
|
||||
if bool(payload.get("killed", false)) and int(relic_flags.get("kill_overflow", 0)) > 0:
|
||||
var next_target = units.default_target()
|
||||
if next_target != null:
|
||||
var of_t := open_ticket(DamageController.KIND_BOARD_TYPED, "relic_pierce_shot",
|
||||
"贯穿射击", "board", maxi(int(db.settlement.damage_floor), int(landed / 2)),
|
||||
DamageController.TARGET_FRONT_ALIVE, int(t.round_index), t.origin_cell, "pierce")
|
||||
if policy == POLICY_SEGMENT:
|
||||
_queue.append(of_t)
|
||||
else:
|
||||
_resolve(of_t)
|
||||
_outcomes[int(t.ticket_id)] = "redeemed"
|
||||
|
||||
|
||||
@@ -355,20 +399,32 @@ func _counter_delta(attack_type: String, armor: String) -> int:
|
||||
return int(row.get(armor, 0))
|
||||
|
||||
|
||||
# 克制点直调(迭代 12 T2 魔法流 clamp_modifier 件——克制矩阵查表值后的流派件调整;空旗=0 零扰动):
|
||||
# 魔网织者=magic vs magic(矩阵罚 −1 → 0/正——「对魔法护甲敌获得克制加成」);湛蓝誓约=magic vs
|
||||
# heavy(+1 → +2——「对重甲敌所有魔法伤害克制点 +1」)。hero_attack 与 board_typed 两消费面同享。
|
||||
# 克制点直调(迭代 12 T2 魔法流/T4 穿刺流 clamp_modifier 件——克制矩阵查表值后的流派件调整;
|
||||
# 空旗=0 零扰动):魔网织者=magic vs magic(矩阵罚 −1 → 0/正);湛蓝誓约=magic vs heavy(+1 → +2);
|
||||
# 猎手刺剑=pierce vs light(+1——对轻甲敌穿刺提升,对重甲无增益=正负双修)。hero_attack 与
|
||||
# board_typed 两消费面同享。
|
||||
func _relic_clamp_bonus(attack_type: String, armor: String) -> int:
|
||||
if attack_type != "magic":
|
||||
return 0
|
||||
var bonus := 0
|
||||
if armor == "magic":
|
||||
bonus += int(relic_flags.get("clamp_magic_magic", 0))
|
||||
elif armor == "heavy":
|
||||
bonus += int(relic_flags.get("clamp_magic_heavy", 0))
|
||||
if attack_type == "magic":
|
||||
if armor == "magic":
|
||||
bonus += int(relic_flags.get("clamp_magic_magic", 0))
|
||||
elif armor == "heavy":
|
||||
bonus += int(relic_flags.get("clamp_magic_heavy", 0))
|
||||
elif attack_type == "pierce":
|
||||
if armor == "light":
|
||||
bonus += int(relic_flags.get("clamp_pierce_light", 0))
|
||||
return bonus
|
||||
|
||||
|
||||
# 折扣档改善(迭代 12 T4 猎弱本能——折扣表向全额方向移 value 档;查不到当前档 = 不动防御口径)
|
||||
func _discount_shift_up(discount: int, shift: int) -> int:
|
||||
var tbl: Array = db.settlement.roll_tier_discounts
|
||||
var idx := tbl.find(discount)
|
||||
if idx < 0:
|
||||
return discount
|
||||
return int(tbl[mini(tbl.size() - 1, idx + shift)])
|
||||
|
||||
|
||||
# 淬毒刃纹 N(迭代 11 同调批 T5——战斗结算 begin_battle 注入;0 = 未装配零扰动)
|
||||
var attune_venom: int = 0
|
||||
|
||||
|
||||
@@ -78,6 +78,82 @@ rows = [{
|
||||
"effects": {
|
||||
"value": 2
|
||||
}
|
||||
}, {
|
||||
"relic_id": "pierce_shot",
|
||||
"display_name": "贯穿射击",
|
||||
"rarity": "rarest",
|
||||
"archetype": "pierce",
|
||||
"hook": "kill_overflow",
|
||||
"effects": {
|
||||
"value": 1
|
||||
}
|
||||
}, {
|
||||
"relic_id": "chain_arrows",
|
||||
"display_name": "连珠矢",
|
||||
"rarity": "rare",
|
||||
"archetype": "pierce",
|
||||
"hook": "dig_count_segments",
|
||||
"effects": {
|
||||
"value": 2,
|
||||
"cap": 2
|
||||
}
|
||||
}, {
|
||||
"relic_id": "weak_instinct",
|
||||
"display_name": "猎弱本能",
|
||||
"rarity": "rare",
|
||||
"archetype": "pierce",
|
||||
"hook": "roll_discount",
|
||||
"effects": {
|
||||
"value": 1
|
||||
}
|
||||
}, {
|
||||
"relic_id": "hunter_rapier",
|
||||
"display_name": "猎手刺剑",
|
||||
"rarity": "common",
|
||||
"archetype": "pierce",
|
||||
"hook": "clamp_modifier",
|
||||
"effects": {
|
||||
"value": 1,
|
||||
"polarity": "pierce_vs_light"
|
||||
}
|
||||
}, {
|
||||
"relic_id": "miner_stubborn",
|
||||
"display_name": "矿工的执拗",
|
||||
"rarity": "common",
|
||||
"archetype": "normal",
|
||||
"hook": "round_dig_bonus",
|
||||
"effects": {
|
||||
"value": 1,
|
||||
"cap": 5
|
||||
}
|
||||
}, {
|
||||
"relic_id": "miner_hammer",
|
||||
"display_name": "矿工重锤",
|
||||
"rarity": "common",
|
||||
"archetype": "normal",
|
||||
"hook": "hit_trade",
|
||||
"effects": {
|
||||
"trade_atk": 25,
|
||||
"trade_hit": 2
|
||||
}
|
||||
}, {
|
||||
"relic_id": "focus_mind",
|
||||
"display_name": "专注",
|
||||
"rarity": "rare",
|
||||
"archetype": "normal",
|
||||
"hook": "armor_roll_rewrite",
|
||||
"effects": {
|
||||
"value": 75
|
||||
}
|
||||
}, {
|
||||
"relic_id": "armor_crack",
|
||||
"display_name": "碎甲震击",
|
||||
"rarity": "rare",
|
||||
"archetype": "normal",
|
||||
"hook": "heavy_debuff",
|
||||
"effects": {
|
||||
"value": 25
|
||||
}
|
||||
}]
|
||||
|
||||
; 双层 BD 实施批(2026-10-04):机制件表——行 = 流派件定义
|
||||
|
||||
+19
-4
@@ -602,8 +602,8 @@ func _smoke_adventure() -> void:
|
||||
|
||||
func _smoke_relics() -> void:
|
||||
print("--- 机制件基建(relic_table · 档位激活引擎 · 机制件带接线)---")
|
||||
# ① 现行表牌库构成:T2 magic 四件+T3 flag 四件入池——98 数值令牌+8 relic 令牌(投放档 rare×6/rarest×2)
|
||||
check(_db.relics != null and (_db.relics.rows as Array).size() == 8, "relic_table 已加载(T2 magic 4+T3 flag 4 在池——T4-T6 逐流派续填)")
|
||||
# ① 现行表牌库构成:T2 magic 4+T3 flag 4+T4 pierce 4/normal 4 入池——98 数值令牌+16 relic 令牌
|
||||
check(_db.relics != null and (_db.relics.rows as Array).size() == 16, "relic_table 已加载(T2/T3/T4 四流派 16 件在池——T5/T6 续填)")
|
||||
var a_r0 = load("res://core/adventure_runner.gd").new(_db, _fresh_rng(71))
|
||||
check(a_r0.start_adventure(71, {"first_script": true}), "机制件带场景:冒险启动(seed 71)")
|
||||
var relic_tokens := 0
|
||||
@@ -613,8 +613,8 @@ func _smoke_relics() -> void:
|
||||
relic_tokens += 1
|
||||
if String((t as Dictionary).get("tier", "")) == "rarest":
|
||||
rarest_tokens += 1
|
||||
check(relic_tokens == 8 and rarest_tokens == 2 and a_r0._bonus_deck.size() == 106,
|
||||
"机制件带入池:8 件(rare 档 6 + rarest 锚点 2)——牌库 98+8=106")
|
||||
check(relic_tokens == 16 and rarest_tokens == 3 and a_r0._bonus_deck.size() == 114,
|
||||
"机制件带入池:16 件(rare 档 13 + rarest 锚点 3)——牌库 98+16=114")
|
||||
check(_db.relics.validate().is_empty(), "relic_table.validate 零违例(有行流派扫雷端铁律——magic first_dig_spell 在案)")
|
||||
# ② 档位激活引擎(纯函数直测——构造表 4 件 magic + 1 件 flag + 1 件 rarest 锚点)
|
||||
var rt := RelicTable.new()
|
||||
@@ -691,6 +691,21 @@ func _smoke_relics() -> void:
|
||||
check(int(rf8.get("flag_resource_extra", -1)) == 1 and int(rf8.get("nest_aura_value", -1)) == 1
|
||||
and int(rf8.get("flag_all_hit_mult", -1)) == 2 and int(rf8.get("flag_strike_value", -1)) == 2,
|
||||
"标旗流求值:雷区图谱额外资源 1 · 猎巢人光环 +1/巢 · 完美布防 ×2 · 战旗军规旗伤 2(复用 board_typed 零新配方)")
|
||||
# ⑥ T4 穿刺/普攻流求值面(全 16 件持有——四流派档位成型)
|
||||
orch._relic_flags_for(["arcane_ember", "mana_weaver", "azure_oath", "mana_resonance",
|
||||
"mine_atlas", "nest_hunter", "perfect_defense", "war_banner",
|
||||
"pierce_shot", "chain_arrows", "weak_instinct", "hunter_rapier",
|
||||
"miner_stubborn", "miner_hammer", "focus_mind", "armor_crack"])
|
||||
var rf16: Dictionary = orch._damage.relic_flags
|
||||
check(bool(rf16.get("kill_overflow", false)) and int(rf16.get("chain_value", -1)) == 2
|
||||
and int(rf16.get("discount_shift", -1)) == 1 and int(rf16.get("clamp_pierce_light", -1)) == 1,
|
||||
"穿刺流求值:贯穿射击弹射旗 · 连珠矢段值 2 上限 2 · 猎弱本能折扣改善 1 档 · 猎手刺剑 pierce-vs-light +1")
|
||||
check(int(rf16.get("round_dig_value", -1)) == 1 and int(rf16.get("hit_trade_atk", -1)) == 25
|
||||
and int(rf16.get("hit_trade_hit", -1)) == 2 and int(rf16.get("armor_roll_rewrite", -1)) == 75
|
||||
and int(rf16.get("crack_value", -1)) == 25,
|
||||
"普攻流求值:执拗 +1/格上限 5 · 重锤交换 +25%/−2AC · 专注恒 75% 免掷骰 · 碎甲震击 off_guard 授予旗")
|
||||
check(bool(rf16.get("rider_crit", false)) and bool(rf16.get("rider_crit", false)),
|
||||
"档位质变:magic/pierce/normal/flag 四流派档二(16 件混合——同标签 ≥4 判档二确定性)")
|
||||
var orch0 = load("res://core/battle_orchestrator.gd").new(_db, _fresh_rng(74))
|
||||
orch0._relic_flags_for([])
|
||||
check((orch0._damage.relic_flags as Dictionary).is_empty(),
|
||||
|
||||
Reference in new issue
Block a user