Files
aetherbound-guild/runtime/tests/p9_10/full_runtime_touch_test.gd
T

205 lines
9.3 KiB
GDScript

extends SceneTree
const Controller = preload("res://p9_10/runtime_controller.gd")
const State = preload("res://p9_10/contract_state.gd")
const Fixture = preload("res://tests/p9_10/runtime_fixture.gd")
const VIEWPORT := Vector2i(844, 390)
var failures: Array[String] = []
var experience
var parsed_touches := 0
var parsed_drags := 0
var ordinary_feedback := {}
var boss_feedback := {}
func _initialize() -> void:
call_deferred("run_test")
func run_test() -> void:
await mount(Fixture.p99_market_four())
await neutral_drag()
for round_index in range(4, 13):
await prepare_market(round_index)
var route_id := "P910-R%d-Q0" % round_index
await tap("P910RouteTarget_%s" % route_id)
await tap("P910RouteTarget_%s" % route_id)
expect(experience.battle_active and not experience.boss_battle_active, "Round %d starts through its world gate" % round_index)
var guard := 0
while not experience.battle.state.terminal and guard < 2000:
experience.advance_battle_ticks(1)
guard += 1
expect(guard < 2000 and experience.battle.state.outcome == "victory", "Round %d wins automatically" % round_index)
await settle_frames()
merge_counts(ordinary_feedback, experience.presented_event_counts)
await tap("P97SettleButton")
expect(experience.market.state.phase == State.Phase.BOSS_MUSTER and experience.market.state.line_capacity == 10, "nine touched Rounds reach the capacity-ten Gale Loom Muster")
expect(experience.find_child("P910BossPlanTarget_break_spindle", true, false) != null, "Muster exposes the spindle plan as a world target")
await tap("P910BossPlanTarget_break_spindle")
await tap("P910BossPlanTarget_break_spindle")
expect(experience.boss_battle_active and experience.find_child("P910BossBattleActor", true, false) != null, "Boss plan starts the visible Gale Loom")
var boss_guard := 0
while not experience.boss_battle.state.terminal and boss_guard < 1900:
experience.advance_battle_ticks(1)
boss_guard += 1
expect(boss_guard < 1900 and experience.boss_battle.state.outcome == "victory", "Gale Loom terminates in victory")
await settle_frames()
merge_counts(boss_feedback, experience.presented_event_counts)
await tap("P910BossSettleButton")
expect(experience.market.state.phase == State.Phase.CONTRACT_RESULT and experience.find_child("P910CloseContractButton", true, false) != null, "Boss result exposes one persistent close")
await tap("P910CloseContractButton")
expect(experience.market.state.phase == State.Phase.RUN_CLOSED and experience.market.state.run_closed, "touch closes the second Contract")
expect(experience.market.state.contract_clear_ids[-1] == "CLEAR-RG01-C02" and experience.market.state.renown_receipts[0].renown_delta == 18, "close grants the exact second clear and Renown")
expect(experience.market.state.unlocked_region_ids == ["RG-01", "RG-02"] and experience.find_child("P910RegionSeal_RG-02", true, false) != null, "persistent result shows RG-02")
expect(int(ordinary_feedback.get("member_action", 0)) > 0 and int(ordinary_feedback.get("enemy_action", 0)) > 0 and int(ordinary_feedback.get("enemy_rule", 0)) > 0, "ordinary feedback binds actions, pressure and gusts")
expect(int(boss_feedback.get("member_action", 0)) > 0 and int(boss_feedback.get("boss_action", 0)) > 0 and int(boss_feedback.get("boss_rule", 0)) > 0 and int(boss_feedback.get("boss_plan", 0)) > 0, "Boss feedback binds attacks, damage, spindle, gust and plan movement")
await verify_boss_recovery_touch()
experience.queue_free()
for _index in 45:
await process_frame
if failures.is_empty():
print("ABG_P9_10_FULL_RUNTIME_TOUCH_OK touch=%d drag=%d fallback=0 direct=0 markets=4-12 hires=5 equipment=3 formation=automatic reorder=preview,confirm routes=9 battles=9 boss=BO-R1-02 plans=break_spindle,hold_line recovery=touch,cost16,same_muster feedback=attack,heal,projectile,push,gust,damage,spindle,opposed clear=CLEAR-RG01-C02 renown=18 rg02=true controls=48 cards=0" % [parsed_touches, parsed_drags])
quit(0)
else:
for failure in failures:
push_error(failure)
quit(1)
func prepare_market(round_index: int) -> void:
if not experience.market.state.available_recruit_offer_ids.is_empty() and experience.market.state.company.size() < experience.market.state.line_capacity:
var recruit_id: String = experience.market.state.available_recruit_offer_ids[0]
if round_index == 11:
recruit_id = "P910-M11-H2"
await tap("P910HireTarget_%s" % recruit_id)
await tap("P910HireTarget_%s" % recruit_id)
if not experience.market.state.available_equipment_offer_ids.is_empty():
var offer_id: String = experience.market.state.available_equipment_offer_ids[0]
var target: String = experience.market.state.deployed_recruit_ids[-1]
await tap("P910EquipmentTarget_%s" % offer_id)
await tap("P910EquipmentTarget_%s" % offer_id)
await tap("P910CompanyTarget_%s" % target)
await tap("P910CompanyTarget_%s" % target)
if round_index == 12:
await tap("P910FinalReorderButton")
await tap("P910FinalReorderButton")
func verify_boss_recovery_touch() -> void:
experience.queue_free()
for _index in 45:
await process_frame
await mount(boss_recovery_muster())
var muster_hash := String(experience.market.state.boss_muster.muster_hash)
var checkpoint_hp: Dictionary = experience.market.state.boss_muster.member_hp.duplicate(true)
var coin_before: int = experience.market.state.coin
await tap("P910BossPlanTarget_hold_line")
await tap("P910BossPlanTarget_hold_line")
expect(experience.boss_battle_active, "recovery fixture starts the visible Boss through parsed touch")
var guard := 0
while not experience.boss_battle.state.terminal and guard < 1900:
experience.advance_battle_ticks(1)
guard += 1
expect(guard < 1900 and experience.boss_battle.state.outcome == "defeat", "single-survivor Company reaches a natural visible Boss defeat")
await settle_frames()
await tap("P910BossSettleButton")
expect(experience.market.state.recovery_required and experience.market.state.recovery_kind == "boss_defeat", "Boss defeat returns to one explicit recovery state")
expect(experience.find_child("P910BossRecoveryButton", true, false) != null, "Boss recovery is a visible world action")
await tap("P910BossRecoveryButton")
expect(not experience.market.state.recovery_required and experience.market.state.coin == coin_before - 16, "parsed recovery touch charges exactly 16 Coin")
expect(experience.market.state.member_condition == checkpoint_hp, "recovery restores the exact pre-Boss living checkpoint")
expect(String(experience.market.state.boss_muster.muster_hash) == muster_hash and experience.market.state.selected_boss_plan.is_empty(), "recovery preserves the same Muster and reopens both plans")
expect(experience.find_child("P910BossPlanTarget_break_spindle", true, false) != null and experience.find_child("P910BossPlanTarget_hold_line", true, false) != null, "both plans return after recovery")
func boss_recovery_muster() -> Dictionary:
var snapshot: Dictionary = Fixture.p910_boss_muster("CH-RG01-CATALOG-01", false).duplicate(true)
for index in snapshot.deployed_recruit_ids.size():
var recruit_id: String = snapshot.deployed_recruit_ids[index]
if index > 0:
snapshot.member_condition[recruit_id] = 0
snapshot.boss_muster.member_hp[recruit_id] = 0
snapshot.coin = 32
snapshot.boss_muster.coin = 32
var authority: Dictionary = snapshot.boss_muster.duplicate(true)
authority.erase("muster_hash")
snapshot.boss_muster = authority.duplicate(true)
snapshot.boss_muster["muster_hash"] = JSON.stringify(authority).sha256_text()
return snapshot
func mount(snapshot: Dictionary) -> void:
root.content_scale_mode = Window.CONTENT_SCALE_MODE_CANVAS_ITEMS
root.content_scale_aspect = Window.CONTENT_SCALE_ASPECT_EXPAND
root.content_scale_size = VIEWPORT
root.size = VIEWPORT
experience = Controller.new()
experience.persistence_enabled = false
experience.battle_auto_advance = false
experience.size = Vector2(VIEWPORT)
experience.configure_entry(snapshot)
root.add_child(experience)
await settle_frames()
func tap(node_name: String) -> void:
var control := experience.find_child(node_name, true, false) as Control
expect(control != null, "%s exists before parsed touch" % node_name)
if control == null:
return
var point := root.get_final_transform() * control.get_global_rect().get_center()
var down := InputEventScreenTouch.new()
down.index = 0
down.position = point
down.pressed = true
Input.parse_input_event(down)
parsed_touches += 1
await process_frame
var up := InputEventScreenTouch.new()
up.index = 0
up.position = point
up.pressed = false
Input.parse_input_event(up)
await settle_frames()
func neutral_drag() -> void:
var down := InputEventScreenTouch.new()
down.index = 1
down.position = Vector2(288, 54)
down.pressed = true
Input.parse_input_event(down)
await process_frame
var drag := InputEventScreenDrag.new()
drag.index = 1
drag.position = Vector2(352, 54)
drag.relative = Vector2(64, 0)
Input.parse_input_event(drag)
parsed_drags += 1
await process_frame
var up := InputEventScreenTouch.new()
up.index = 1
up.position = drag.position
up.pressed = false
Input.parse_input_event(up)
await settle_frames()
func merge_counts(target: Dictionary, source: Dictionary) -> void:
for key in source:
target[key] = int(target.get(key, 0)) + int(source[key])
func settle_frames() -> void:
await process_frame
await process_frame
await process_frame
await process_frame
func expect(condition: bool, message: String) -> void:
if not condition:
failures.append("P9.10 full runtime touch: %s" % message)