test(m80-i35): exercise the crosswind line in a focused battle
This commit is contained in:
@@ -114,6 +114,7 @@ reach/目标选择、Guard/护盾、伤害公式(含暴击与标签化随机
|
||||
| `M80-I14` | RESOLVED(2026-09-15)| 链接落地:`link`/`relink` 字段、`link_id` 绑定、`link_broken` 条件随绑定单位倒下而成立、PF-B08 三行可跑;
|
||||
门 `ABG_M80_LINK_OK`。**至此 23 个优先条件全部 enabled(pending=0)** |
|
||||
| `M80-I34` | RESOLVED(2026-09-16)| **EQ-276 跨战先手**(本轮最有产品价值的一条,接合同推进):新效果类 `ready_carry`——
|
||||
| `M80-I35` | RESOLVED(2026-09-18,M92)| **EN-R1-09 Crosswind Scribe 签名**(on_advance:在敌方最前/最后之间画线;下一次跨线换位 → `hindered`;窗口 `CROSSWIND_WINDOW_TICKS=30` 未跨线 → 一次弱范围命中 `floor(base×coefficient×0.5)` 打全员。窗口时长文档未给,取既有 status 默认档 30 并记录在案):门 `ABG_M80_ENEMY_ACTIONS_OK ... implemented=12 enr1_09=%d` |
|
||||
战斗结束时,若该同伴**一次/每战触发**(引擎已有的三种"已用"标记:标签镜像、共享清洁、打断守卫)全都未用,则 `ready_with_priority=true`;
|
||||
`carry_from`/`apply_carry` 把它随 HP 一起带进下一战;桥 `_ally_row` 透传;仿真里以该标记进场者 **开局准备度=阈值 100**(第一拍即可行动)。
|
||||
装备门 implemented 276→277;`contract_run` 门标记扩为 `ready_carry=carries`(四环断言:未用→标记 / 携带 / 折叠 / 下一战先手)。
|
||||
|
||||
@@ -20,7 +20,7 @@ func _run() -> void:
|
||||
var battle := _run_region_one()
|
||||
var fired := _signature_events(battle)
|
||||
var implemented := _implemented_rows()
|
||||
var crosswind := _crosswind_events(battle)
|
||||
var crosswind := _crosswind_events(battle) + _crosswind_events(_run_crosswind_scenario())
|
||||
_expect(String(battle.outcome) in ["victory", "defeat", "timeout"], "a region-one battle resolves")
|
||||
_expect(not Array(battle.journal).is_empty(), "the enemies act in the battle")
|
||||
_expect(crosswind >= 1, "EN-R1-09 signature is observed in a real battle (%d)" % crosswind)
|
||||
@@ -73,6 +73,35 @@ func _verify_profiles() -> void:
|
||||
_expect(not Dictionary(row.get("action", {})).is_empty(), "%s declares an action" % enemy_id)
|
||||
|
||||
|
||||
func _run_crosswind_scenario() -> Dictionary:
|
||||
# Focused fixture: an ally pulls the rear scribe forward so its on_advance
|
||||
# line window opens inside a real battle.
|
||||
var simulation: ABGBattleSimulation = Simulation.new()
|
||||
var front := Authoring.enemy_row("EN-R1-01", "ordinary", 1)
|
||||
front["id"] = "enemy-EN-R1-01"
|
||||
front["position"] = 0
|
||||
front["profession_id"] = ""
|
||||
front["action"] = Dictionary(EnemyActions.profile("EN-R1-01").get("action", {}))
|
||||
front["profession_table"] = {}
|
||||
front["equipment_hooks"] = [EnemyActions.hook_row("EN-R1-01")]
|
||||
var scribe := Authoring.enemy_row("EN-R1-09", "ordinary", 1)
|
||||
scribe["id"] = "enemy-EN-R1-09"
|
||||
scribe["position"] = 1
|
||||
scribe["profession_id"] = ""
|
||||
scribe["action"] = Dictionary(EnemyActions.profile("EN-R1-09").get("action", {}))
|
||||
scribe["profession_table"] = {}
|
||||
scribe["equipment_hooks"] = [EnemyActions.hook_row("EN-R1-09")]
|
||||
var puller := {"id": "ally-puller", "position": 0, "level": 4, "profession_id": "",
|
||||
"trait_ids": [], "might": 10, "finesse": 10, "insight": 10, "vigor": 20, "resolve": 10,
|
||||
"profession_base_hp": 600, "profession_base_tempo": 30, "profession_base_initiative": 20,
|
||||
"weapon_power": 2, "focus_power": 2, "armor_guard": 6, "armor_ward": 6,
|
||||
"profession_table": {},
|
||||
"action": {"base": 1, "coefficient": 0.1, "power_source": "physical_power", "reach": 1,
|
||||
"kind": "damage", "target": "rearmost", "pull": 1}}
|
||||
simulation.setup("crosswind-scenario", [puller], [front, scribe])
|
||||
return simulation.run()
|
||||
|
||||
|
||||
func _run_region_one() -> Dictionary:
|
||||
var simulation: ABGBattleSimulation = Simulation.new()
|
||||
var enemies: Array = []
|
||||
|
||||
Reference in New Issue
Block a user