150 lines
6.5 KiB
GDScript
150 lines
6.5 KiB
GDScript
extends SceneTree
|
|
|
|
const MainScene = preload("res://main.tscn")
|
|
const PROFESSIONS := ["Hearthguard", "Wayrunner", "Farstring", "Kindhand"]
|
|
const ITEMS := ["EQ-002", "EQ-061"]
|
|
|
|
var failures: Array[String] = []
|
|
|
|
|
|
func _initialize() -> void:
|
|
call_deferred("run_test")
|
|
|
|
|
|
func run_test() -> void:
|
|
var game := MainScene.instantiate()
|
|
game.auto_boot = false
|
|
root.add_child(game)
|
|
await settle(10)
|
|
game.locale = "zh_CN"
|
|
game.muted = true
|
|
var paths := 0
|
|
for left_index in range(PROFESSIONS.size()):
|
|
for right_index in range(left_index + 1, PROFESSIONS.size()):
|
|
var pair: Array[String] = [PROFESSIONS[left_index], PROFESSIONS[right_index]]
|
|
for item in ITEMS:
|
|
game.clear_experience()
|
|
game.selected_recruits.assign(pair)
|
|
expect(game.assign_automatic_formation(), "%s assigns automatic order" % pair_key(pair))
|
|
game.begin_first_battle()
|
|
resolve_battle(game, false)
|
|
expect(game.page == game.AppPage.VICTORY, "%s reaches first Victory" % pair_key(pair))
|
|
expect(first_diagnosis_is_truthful(game), "%s first diagnosis names both actual behaviors" % pair_key(pair))
|
|
expect(game.coin == 20 and game.first_reward_committed, "%s first reward commits once" % pair_key(pair))
|
|
game.open_adaptation()
|
|
expect(game.page == game.AppPage.ADAPTATION and game.adaptation_choice.is_empty(), "%s adaptation starts unselected" % pair_key(pair))
|
|
expect(game.adaptation_effect("EQ-002").contains("先行者") and game.adaptation_effect("EQ-061").contains("先行者"), "%s equipment language follows automatic lead" % pair_key(pair))
|
|
game.choose_adaptation("EQ-061" if item == "EQ-002" else "EQ-002")
|
|
game.choose_adaptation(item)
|
|
game.begin_second_battle()
|
|
expect(game.adaptation_committed and game.adaptation_choice == item, "%s/%s locks revised equipment" % [pair_key(pair), item])
|
|
game.choose_adaptation("EQ-061" if item == "EQ-002" else "EQ-002")
|
|
expect(game.adaptation_choice == item, "%s/%s rejects post-commit revision" % [pair_key(pair), item])
|
|
var elapsed := resolve_battle(game, true)
|
|
var expected_hp := expected_lead_hp(game.rear_choice, item)
|
|
expect(game.page == game.AppPage.SECOND_RESULT and game.enemy_hp == 0, "%s/%s reaches second Victory" % [pair_key(pair), item])
|
|
expect(game.front_hp == expected_hp, "%s/%s lead HP is %d" % [pair_key(pair), item, expected_hp])
|
|
expect(is_equal_approx(elapsed, 7.05 if item == "EQ-002" else 6.00), "%s/%s has declared battle time" % [pair_key(pair), item])
|
|
expect(game.coin == 20 and game.victory_events == 2, "%s/%s preserves one reward across two victories" % [pair_key(pair), item])
|
|
expect(second_action_is_truthful(game), "%s/%s preserves actual second-member action" % [pair_key(pair), item])
|
|
expect(result_is_truthful(game, item), "%s/%s result names equipment, lead and second action" % [pair_key(pair), item])
|
|
var exceptional := pair == ["Hearthguard", "Wayrunner"] or pair == ["Farstring", "Kindhand"]
|
|
expect(game.later_preview_supports_pair() != exceptional, "%s has honest later-preview boundary" % pair_key(pair))
|
|
game.clear_experience()
|
|
paths += 2
|
|
|
|
game.selected_recruits.assign(["Farstring", "Kindhand"])
|
|
game.assign_automatic_formation()
|
|
game.begin_first_battle()
|
|
resolve_battle(game, false)
|
|
game.open_adaptation()
|
|
game.choose_adaptation("EQ-002")
|
|
game.begin_second_battle()
|
|
resolve_battle(game, true)
|
|
game.go_home()
|
|
expect(game.page == game.AppPage.MAIN_MENU and game.selected_recruits.is_empty() and game.coin == 0, "Home clears an exceptional pair adaptation")
|
|
|
|
game.queue_free()
|
|
await settle(90)
|
|
if failures.is_empty():
|
|
print("ABG_P9_0R10_PAIR_ADAPTATION_OK pairs=6 items=2 paths=%d safe_hp=90,100 tempo_hp=70,82 times=7.05,6.00 counter=true ranged=true healing=true reward_once=true boundary=2 cleanup=true" % paths)
|
|
quit(0)
|
|
else:
|
|
for failure in failures:
|
|
push_error(failure)
|
|
quit(1)
|
|
|
|
|
|
func resolve_battle(game: Control, second: bool) -> float:
|
|
var elapsed := 0.0
|
|
for phase in range(6):
|
|
var duration: float = game.phase_duration(phase)
|
|
if second:
|
|
game.second_battle_elapsed += duration
|
|
elapsed += duration
|
|
game.advance_battle_phase()
|
|
return elapsed
|
|
|
|
|
|
func first_diagnosis_is_truthful(game: Control) -> bool:
|
|
var diagnosis: String = game.victory_explanation()
|
|
if not diagnosis.contains(game.candidate_name(game.front_choice)) or not diagnosis.contains(game.candidate_name(game.rear_choice)):
|
|
return false
|
|
if game.rear_choice == "Wayrunner":
|
|
return diagnosis.contains("侧翼反击")
|
|
if game.rear_choice == "Farstring":
|
|
return diagnosis.contains("远程伤害")
|
|
return diagnosis.contains("恢复先行者")
|
|
|
|
|
|
func second_action_is_truthful(game: Control) -> bool:
|
|
var feedback: Dictionary = feedback_for_phase(game.battle_feedback_history, 3)
|
|
if feedback.is_empty():
|
|
return false
|
|
var event_text: String = with_phase_text(game, 3)
|
|
if game.rear_choice == "Wayrunner":
|
|
return feedback["qualifier_zh"] == "侧翼反击" and feedback["target"] == "enemy" and event_text.contains("侧翼反击")
|
|
if game.rear_choice == "Farstring":
|
|
return feedback["qualifier_zh"] == "后排命中" and feedback["target"] == "enemy" and event_text.contains("远程伤害")
|
|
return feedback["qualifier_zh"] == "治疗" and feedback["target"] == "front" and event_text.contains("恢复")
|
|
|
|
|
|
func feedback_for_phase(history: Array[Dictionary], phase: int) -> Dictionary:
|
|
for feedback in history:
|
|
if feedback["phase"] == phase:
|
|
return feedback
|
|
return {}
|
|
|
|
|
|
func result_is_truthful(game: Control, item: String) -> bool:
|
|
var explanation: String = game.second_result_explanation()
|
|
var action_term := "侧翼反击" if game.rear_choice == "Wayrunner" else ("远程伤害" if game.rear_choice == "Farstring" else "恢复")
|
|
return explanation.contains(game.adaptation_name(item)) and explanation.contains(game.candidate_name(game.front_choice)) and explanation.contains(game.candidate_name(game.rear_choice)) and explanation.contains(action_term)
|
|
|
|
|
|
func with_phase_text(game: Control, phase: int) -> String:
|
|
var previous_phase: int = game.battle_phase
|
|
game.battle_phase = phase
|
|
var value: String = game.second_battle_event_text()
|
|
game.battle_phase = previous_phase
|
|
return value
|
|
|
|
|
|
func expected_lead_hp(second_member: String, item: String) -> int:
|
|
var base := 90 if item == "EQ-002" else 70
|
|
return mini(100, base + 12) if second_member == "Kindhand" else base
|
|
|
|
|
|
func pair_key(pair: Array[String]) -> String:
|
|
return "%s+%s" % [pair[0], pair[1]]
|
|
|
|
|
|
func settle(frames: int) -> void:
|
|
for frame in range(frames):
|
|
await process_frame
|
|
|
|
|
|
func expect(condition: bool, message: String) -> void:
|
|
if not condition:
|
|
failures.append("P9.0R10 pair adaptation: %s" % message)
|