merge: 判式换代批T0-T5全落(迭代14②号卡;冒烟750/0+run_all 15套+探针绿+doc三闸零新增)

This commit is contained in:
DKChan committed 2026-10-05 07:00:42 +08:00
commit 3e2c564b59
16 files changed
+416 -91

No files matched your search

+23 -4
View File
@@ -51,7 +51,7 @@ var _enemy_system: UnitContainer
var _status_effects: StatusContainer
var _reward_economy: RewardEconomy
var aux_inventory: AuxItems # 迭代 7 T3——LevelRunner 注入的关卡域库存引用;
# 每战新建本类,库存不归本类所有——注入面
# 每战新建本类,库存不归本类所有——注入面
var _damage: DamageController # 伤害控制器(伤害管线单据化批 2026-09-24——单据唯一兑付管线)
var encounter: Dictionary[String, Variant] = {}
@@ -687,6 +687,17 @@ func _grant_routed(snap: Dictionary, polarity: String, source_class: String, cel
return false
if polarity == "positive":
row["power"] = int(snap.get("power", int(row.power))) # 区间行快照 power(身份批 roll 值)覆盖表值——授予期零随机口径(E14)
# 标中兑付溢价(迭代14②判式换代批 T4——条款3 条件二旗溢价形态 a,2026-10-04 用户裁 P3):
# δ 读 settlement.flag_hit_premium(percent 域 125=×1.25 provisional);100=无溢价直通零扰动。
# 兑付公式一处=本块:只乘标中旗正向(flat power 乘后入单据/治疗/排队;percent 幅度经
# premium_pct 贯穿 _apply_percent_row 应用与呈现同乘)——标空/挖格/清图不乘,雷安同池冻结不动。
# 取整=四舍五入(与伤害管线 round_direction=floor 分域——registry clause3_inequality 随批登记;
# 1 点量纲行 ac_up/action 取整后不变=整数粒度地板)。
if source_class == "flag_hit" and int(db.settlement.flag_hit_premium) != 100:
var prem_pct: int = int(db.settlement.flag_hit_premium)
row = row.duplicate()
row["power"] = int(round(int(row.power) * prem_pct / 100.0))
row["premium_pct"] = prem_pct
# 惊巢反制(迭代 11 同调批 T5——底稿 §3:挖开雷格该次惩罚减半 + 反弹 N;duplicate 隔离——减半
# 不回写极性字典;仅 source_class=mine_hit 受理,标错旗/负向字典行走原通道)
if polarity == "negative" and source_class == "mine_hit" and _attune_has("nest_counter"):
@@ -717,10 +728,18 @@ func _apply_percent_row(row: Dictionary, source_class: String, cell: Vector2i, r
var eff := String(row.effect_id)
if eff == "gp_gain" or eff == "gp_loss":
return _apply_gp_row(row, source_class, cell, ri, highlight, label_suffix)
var ok: bool = _status_effects.apply_effect(eff, {"source_class": source_class, "origin_cell": cell, "round_index": ri})
var srow: Dictionary = db.status_effect_row(eff)
# 旗溢价贯穿(迭代14② T4——仅标中旗正向行携带 premium_pct;其余授予路径缺省 100 零扰动):
# 应用幅度与呈现行值同乘,容器经 magnitude_override 拿同一快照(抗表重载口径保持)。
var prem_pct: int = int(row.get("premium_pct", 100))
var eff_mag: int = int(srow.magnitude)
var src := {"source_class": source_class, "origin_cell": cell, "round_index": ri}
if prem_pct != 100:
eff_mag = int(round(eff_mag * prem_pct / 100.0))
src["magnitude_override"] = eff_mag
var ok: bool = _status_effects.apply_effect(eff, src)
if ok:
var srow: Dictionary = db.status_effect_row(eff)
_emit_row("effect", source_class, cell, ri, String(srow.display_name) + label_suffix, int(srow.magnitude), {"effect_id": eff, "pool_value": _pool_effective(eff)}, highlight)
_emit_row("effect", source_class, cell, ri, String(srow.display_name) + label_suffix, eff_mag, {"effect_id": eff, "pool_value": _pool_effective(eff)}, highlight)
return true
_emit_row("reward_ineffective", source_class, cell, ri, "奖励未生效(满层)%s" % label_suffix, 0, {"batch_key": eff}, highlight)
return false
+2
View File
@@ -42,6 +42,8 @@ func apply_effect(effect_id: String, source: Dictionary, duration_override: int
var max_stack: int = int(row.max_stack)
# 授予时快照(抗表重载——EC9)
var snap_m: int = int(row.magnitude)
if source.has("magnitude_override"):
snap_m = int(source["magnitude_override"]) # 旗溢价贯穿(迭代14② T4——标中旗 percent 形态同乘快照;缺省路径零扰动)
var snap_unit: String = String(row.unit)
var snap_display: String = String(row.display_name)
match policy:
+3
View File
@@ -8,6 +8,7 @@ extends Resource
@export var equivalence_ref_damage: int = 12 # [1,999] knob——当量参考敞口 D_ref
@export var p_perfect: int = 200 # {100,200} percent——完美排雷第二份兑付触发(载体域)
@export var flag_hit_premium: int = 100 # [100,999] percent knob——标中旗兑付溢价 ×(1+(n−100)/100):125=×1.25(条款3 条件二旗溢价形态 a,2026-10-05 判式换代批 provisional);100=无溢价直通零扰动。只乘标中旗正向兑付(flat power/percent 幅度/gp 缓冲三形态),标空/挖格/清图不乘;雷安同池冻结不动
@export var segment_order: PackedStringArray = [] # 结构冻结——恒等拍板段序校验违例致命
@export var source_label_map: Dictionary[String, Variant] = {} # 结构冻结——source_class→文案键
@export var effect_pool_map: Dictionary[String, Variant] = {} # 结构冻结——effect_id→pool(悬空加载致命)
@@ -48,6 +49,8 @@ func validate() -> Array:
errs.append({"category": "domain", "message": "equivalence_ref_damage 越域 [1,999]: %d" % equivalence_ref_damage})
if not P_PERFECT_DOMAIN.has(p_perfect):
errs.append({"category": "pperfect_oob", "message": "p_perfect 载体域 {100,200}: %d" % p_perfect})
if flag_hit_premium < 100 or flag_hit_premium > 999:
errs.append({"category": "domain", "message": "flag_hit_premium 越域 [100,999](100=无溢价): %d" % flag_hit_premium})
var seg := Array(segment_order)
if seg != FROZEN_SEGMENT_ORDER:
errs.append({"category": "segorder_violation", "message": "segment_order 违例——恒等拍板段序校验失败: %s" % str(seg)})
+1
View File
@@ -6,6 +6,7 @@
script = ExtResource("1")
equivalence_ref_damage = 4
p_perfect = 200
flag_hit_premium = 125
segment_order = PackedStringArray("grant", "buff_debuff", "combat", "decay", "verdict")
source_label_map = {
"safe_cell": "安全格",
+6
View File
@@ -119,6 +119,12 @@ func _initialize() -> void:
"mine_dmg": int(st.get("mine_dmg", 0)),
"taken": int(st["hero_dmg"]) + int(st.get("mine_dmg", 0)),
"refreshes": int(st["refreshes"]), "choices": int(st["choices"]),
# 旗经济五字段(迭代14②判式换代批 T1——η=flag_hit÷flag_placed、标空率=flag_miss÷flag_placed
# 派生归分析侧;gain/penalty=结算流水行值合计(原始行值口径,等价换算归判读侧——登记))
"flag_placed": int(st.get("flag_placed", 0)), "flag_hit": int(st.get("flag_hit", 0)),
"flag_miss": int(st.get("flag_miss", 0)),
"flag_hit_gain": int(st.get("flag_hit_gain", 0)),
"flag_miss_penalty": int(st.get("flag_miss_penalty", 0)),
"relics": st.get("relics", []),
"visited_count": (st["visited_ids"] as Array).size(),
"encounter_max_hp_seq": st["encounter_max_hp_seq"],
+25
View File
@@ -57,6 +57,9 @@ static func run_level(db, seed_val: int, level_index: int, atk_pct: int, hp_pct:
"boss_depth": -1, "hp_at_boss": -1, "rows": [], "timeout": false,
"log_path": "", "policy": policy, "refreshes": 0, "mine_hits": 0, "mine_dmg": 0,
"visited_ids": [], "choices": 0, "last_battle_enemies": [],
# 旗经济五字段(迭代14②判式换代批 T1——runsum 读数面;聚合自结算流水 source_class,
# 零新随机源零核心改动;η=flag_hit÷flag_placed 与标空率派生归分析侧)
"flag_placed": 0, "flag_hit": 0, "flag_miss": 0, "flag_hit_gain": 0, "flag_miss_penalty": 0,
"prng": _policy_rng(seed_val), "mine_slips": 0, "skip_digs": 0, "shop_buys": 0,
}
runner.step_row.connect(_on_step_row.bind(runner, st, collect_rows))
@@ -136,6 +139,8 @@ static func run_adventure(db, seed_val: int, atk_pct: int, hp_pct: int, collect_
"summary": {}, "wallet_events": [], "encounter_max_hp_seq": [], "reward_events": [],
"relic_mode": String(relic.get("mode", "off")), # 流派件分层开关(迭代 12 T7——off=316-f 通用竞争/on=成型画像优先捕捞 relic)
"shop_gp_seq": [], # 商店房到达余额序(逐关 1 次——GP 跨关延续验收取数面)
# 旗经济五字段(迭代14②判式换代批 T1——与 run_level 同口径,见彼处注释)
"flag_placed": 0, "flag_hit": 0, "flag_miss": 0, "flag_hit_gain": 0, "flag_miss_penalty": 0,
"prng": _policy_rng(seed_val), "mine_slips": 0, "skip_digs": 0, "shop_buys": 0,
"adv": true, # v3 档位行为开关(选路评分/失误注入/商店购买只挂冒险测量面——单关夹具保持旧语义零扰动)
@@ -435,6 +440,24 @@ static func _on_step_row(row: Dictionary, _runner, st: Dictionary, collect_rows:
_note_enemy(String(row.get("text", "")), st) # 施放行(毒爆挂毒等——伤害行可能缺席的死亡遭遇仍可归因)
if row.source_class == "mine_hit":
st.mine_hits += 1 # 踩雷证据行(负向兑付——完美档断言恒 0;盲挖惩罚链埋点)
# 旗经济聚合(迭代14②判式换代批 T1——自结算流水聚合,零新随机源):
# ⚠ 行侧判据考证实录:结算段对存续增益实例每轮复发行 effect 行且复用实例 source_class
#(battle_orchestrator 状态列举行)——source_class=flag_hit 的行 ≠ 标中事件。事件行唯一判据
# = 授予行专带 highlight="flag_hit"(实测 87 行 == 受理插旗 87 动作,1:1 精确);
# 雷区图谱追加分grant 无高光,以 display_name 后缀补捕(计入事件与合计——同旗第二份兑付)。
# 满层拒收行(reward_ineffective)零兑付不入。标空事件=归因行(type=flag_miss 每格恰一次);
# 标空惩罚合计只入一次性兑付行(flat 直伤 damage/heal + gp_loss escrow 行)——sapped 授予行
# 与其状态复发行行侧不可区分不入合计(登记注记,判读侧按事件数补算)。
if row.source_class == "flag_hit" and row.type != "reward_ineffective":
if String(row.get("highlight", "")) == "flag_hit" \
or String(row.get("display_name", "")).contains("雷区图谱"):
st.flag_hit += 1
st.flag_hit_gain += int(row.value)
if row.type == "flag_miss":
st.flag_miss += 1
elif row.source_class == "flag_miss" and (row.type == "damage" or row.type == "heal" \
or String(row.get("effect_id", "")) == "gp_loss"):
st.flag_miss_penalty += int(row.value)
if collect_rows:
st.rows.append(row)
@@ -525,6 +548,8 @@ static func _autoplay_battle(runner, settlement, st: Dictionary, logger) -> void
if ok:
if kind == "refresh":
st.refreshes = int(st.refreshes) + 1
elif kind == "flag":
st.flag_placed = int(st.get("flag_placed", 0)) + 1 # 插旗数(η 分母=全部插旗数——迭代14② Q5 裁决;失误注入转化旗不计数=转化后实为挖)
rejects = 0
else:
rejects += 1
+41 -1
View File
@@ -2420,6 +2420,46 @@ func _smoke_polarity_routing() -> void:
if eff != "" and not POSITIVE_EFFECTS.has(eff):
hit_ok = false
check(hit_ok, "标中旗 → 该雷格资源的正向兑付行(origin 指回雷格,效果 ∈ 正向字典)")
# 条款3 条件二旗溢价断言(迭代14② T4——标中兑付行数值 = 同型正向 ×(1+δ)):
# δ 读 settlement.flag_hit_premium(125 provisional);九型正向行值全固定(唯一区间行 clear_blast
# 系清图槽不入格池)⇒ 逐型期望全确定。整数量级四舍五入域注记:ac_up/action 1 点量纲取整后不变
# =整数粒度地板——等号压线判读在当量聚合面(audit 工具/registry clause3_inequality),非断言面。
var prem_pct: int = int(_db.settlement.flag_hit_premium)
check(prem_pct == 125, "旗溢价配置在位(flag_hit_premium=125 provisional——形态 a 兑付溢价)")
var prem_rows := 0
var prem_ok := true
for r in probe["rows"]:
if String(r.get("source_class", "")) != "flag_hit" or String(r.get("highlight", "")) != "flag_hit":
continue
prem_rows += 1
var rtype := String(r.get("type", ""))
var v := int(r.get("value", 0))
var eff := String(r.get("effect_id", ""))
if rtype == "effect":
if eff == "gp_gain":
prem_ok = prem_ok and v == int(round(3 * prem_pct / 100.0)) # 金币袋 3→4
elif eff == "ap_delta":
prem_ok = prem_ok and v == 1 # +1AP:1 点量纲(round(1.25)=1——整数粒度地板)
else:
var mag: int = int(_db.status_effect_row(eff).get("magnitude", -999))
prem_ok = prem_ok and v == int(round(mag * prem_pct / 100.0)) # 增伤50→63/削弱65→81/护甲1→1
elif rtype == "heal":
# 急救 2→3(clamp 封顶只降不升:满血走 reward_ineffective 不入本行——区间断言)
prem_ok = prem_ok and v >= 1 and v <= int(round(2 * prem_pct / 100.0))
elif rtype == "damage":
var at := String(r.get("attack_type", ""))
if at == "":
prem_ok = prem_ok and v == int(round(1 * prem_pct / 100.0)) # 爆裂粉尘 1→1(群伤行值=表值直付)
else:
# 穿刺/魔法 2→3(行值=落地伤=基准+克制点数——反推基准核对;damage_floor 兜底下成立)
prem_ok = prem_ok and (v - int(r.get("effectiveness", 0))) == int(round(2 * prem_pct / 100.0))
check(prem_rows >= 1 and prem_ok, "标中兑付溢价(×%d 行逐型=同型正向 ×%d/100——等号压线注记:δ=1.25 时条件二 E[标中]=1.25·E_dig 恰等成立)" % [prem_rows, prem_pct])
# 标空不乘溢价:负向直伤行(反噬6/陷阱8/魔法反噬8 固定表值)零溢价污染——溢价值挂标中正向单点
var miss_flat_ok := true
for r in _rows_at(probe["rows"], "flag_miss", probe["miss_cell"]):
if String(r.get("type", "")) == "damage":
miss_flat_ok = miss_flat_ok and int(r.get("value", 0)) in [6, 8]
check(miss_flat_ok, "标空惩罚零溢价(负向直伤行=固定表值原值——溢价只挂标中正向)")
# 标空旗:归因行 + 该安全格负向兑付行(flag_miss 来源)
var miss_rows := _rows_at(probe["rows"], "flag_miss", probe["miss_cell"])
var miss_neg_ok := false
@@ -3223,7 +3263,7 @@ func _smoke_level_graph() -> void:
# 逐种子全关卡通关扫描找命中,期望路径过期时 258 次模拟撞 180s 闸(台账 257 + 2026-10-02
# 出度≤2 重建两次实证)。存储种子常态一次跑完;图表/数值有意变更致本断言红=快速失败(一次
# 即红非扫描超时),重采=临时脚本跑同款 run_level 循环取首命中种子回填(离线一次性)。
const MAX_PATH_SEED := 42
const MAX_PATH_SEED := 43 # 2026-10-05 判式换代批重采(旗溢价 δ=1.25 落地致种子 42 战局位移=败于终点;同款循环首命中——断言注释既定程序,临时脚本用后即删)
var win_max: Dictionary = autoplay.run_level(_db, MAX_PATH_SEED, 2, 200, 100, false, null, "normal", "max", 0)
check(win_max.result == "victory" and win_max.visited_ids == [0, 2, 6, 7, 8, 9],
"L2·满配 max 路径(max 取最大编号候选)通关 = 0→2(奖励)→6→7→8(商店零购离开)→9(存储种子 %d——T17 出度≤2 拍板模板 0 重建)" % MAX_PATH_SEED)