176 lines
6.3 KiB
GDScript
176 lines
6.3 KiB
GDScript
extends SceneTree
|
|
|
|
const BattleSceneScript := preload("res://scripts/scenes/battle_scene.gd")
|
|
|
|
|
|
func _init() -> void:
|
|
var failures: Array[String] = []
|
|
var scene = BattleSceneScript.new()
|
|
if not scene.state.load_battle("res://data/scenarios/001_yellow_turbans.json"):
|
|
push_error("Could not load smoke scenario.")
|
|
quit(1)
|
|
return
|
|
if not scene.campaign_state.load_campaign("res://data/campaign/campaign.json"):
|
|
push_error("Could not load smoke campaign.")
|
|
quit(1)
|
|
return
|
|
scene.campaign_state.start_new("001_yellow_turbans")
|
|
scene.campaign_state.gold = 320
|
|
|
|
scene.battle_result_summary = {
|
|
"saved": true,
|
|
"rewards_applied": true,
|
|
"already_completed": false,
|
|
"pending_choice": false,
|
|
"gold": 100,
|
|
"items": ["bean", "bean"],
|
|
"joined_officers": ["xiahou_yuan", "cao_ren"],
|
|
"left_officers": [],
|
|
"progression_events": [
|
|
{"type": "level_up", "name": "조조", "to_level": 2}
|
|
],
|
|
"next_scenario_id": "002_sishui_gate",
|
|
"next_scenario_title": "사수관 선봉전",
|
|
"choice_applied": true,
|
|
"choice_label": ""
|
|
}
|
|
var result_text: String = scene._format_battle_result_summary()
|
|
_check_contains(failures, "reward section", result_text, "전리품")
|
|
_check_contains(failures, "gold reward", result_text, "군자금 +100냥")
|
|
_check_contains(failures, "item reward", result_text, "콩 2점")
|
|
_check_contains(failures, "roster section", result_text, "합류: 하후연, 조인")
|
|
_check_contains(failures, "growth section", result_text, "조조 품계 2")
|
|
_check_contains(failures, "campaign section", result_text, "다음 행군: 사수관 선봉전")
|
|
_check_contains(failures, "next camp section", result_text, "다음 군막")
|
|
_check_contains(failures, "next camp location", result_text, "사수관, 초평 원년")
|
|
_check_contains(failures, "next camp talk", result_text, "군막 회의 · 3건")
|
|
_check_contains(failures, "next camp shop", result_text, "군상 물품 · 6종")
|
|
_check_contains(failures, "next camp deploy", result_text, "출진 명부 · 2/4")
|
|
_check_contains(failures, "next camp formation", result_text, "진형 배치 6칸")
|
|
scene._create_hud()
|
|
scene._rebuild_result_reward_strip()
|
|
if scene.result_reward_strip == null or not scene.result_reward_strip.visible:
|
|
failures.append("victory result should show a compact reward icon strip")
|
|
elif scene.result_reward_strip.get_child_count() < 4:
|
|
failures.append("reward icon strip should include gold, item, and two opening officer chips")
|
|
var reward_tooltips := _collect_tooltips(scene.result_reward_strip)
|
|
_check_contains(failures, "reward strip gold tooltip", reward_tooltips, "군자금 +100냥")
|
|
_check_contains(failures, "reward strip item tooltip", reward_tooltips, "물자: 콩 2점")
|
|
_check_contains(failures, "reward strip Xiahou Yuan tooltip", reward_tooltips, "합류: 하후연")
|
|
_check_contains(failures, "reward strip Cao Ren tooltip", reward_tooltips, "합류: 조인")
|
|
_check_contains(failures, "reward strip archer class tooltip", reward_tooltips, "병과: 궁병")
|
|
_check_contains(failures, "reward strip infantry class tooltip", reward_tooltips, "병과: 보병")
|
|
if _count_named_nodes(scene.result_reward_strip, "ResultRewardClassBadge") < 2:
|
|
failures.append("joined officer reward chips should show compact class crests")
|
|
if not _has_texture_rect(scene.result_reward_strip):
|
|
failures.append("reward icon strip should reuse item or officer artwork")
|
|
|
|
scene.battle_result_summary = {
|
|
"saved": false,
|
|
"rewards_applied": false,
|
|
"already_completed": false,
|
|
"pending_choice": false,
|
|
"gold": 0,
|
|
"items": [],
|
|
"joined_officers": [],
|
|
"left_officers": [],
|
|
"progression_events": [],
|
|
"next_scenario_title": "사수관 선봉전",
|
|
"choice_applied": true,
|
|
"choice_label": ""
|
|
}
|
|
var failed_save_text: String = scene._format_battle_result_summary()
|
|
_check_contains(failures, "failed rewards", failed_save_text, "아직 기록되지 않음")
|
|
_check_contains(failures, "failed save", failed_save_text, "전기 봉인 실패")
|
|
|
|
scene.battle_result_summary = {
|
|
"saved": true,
|
|
"pending_choice": true,
|
|
"next_scenario_id": "002_sishui_gate",
|
|
"next_scenario_title": "청주 평정전"
|
|
}
|
|
var pending_choice_text := scene._format_battle_result_summary()
|
|
_check_contains(
|
|
failures,
|
|
"pending choice prompt",
|
|
pending_choice_text,
|
|
"응답을 고르십시오"
|
|
)
|
|
_check_not_contains(
|
|
failures,
|
|
"pending choice should wait for response before next camp preview",
|
|
pending_choice_text,
|
|
"다음 군막"
|
|
)
|
|
|
|
scene.battle_result_summary = {
|
|
"saved": true,
|
|
"already_completed": true,
|
|
"next_scenario_title": "Current Battle"
|
|
}
|
|
_check_contains(
|
|
failures,
|
|
"replay rewards",
|
|
scene._format_battle_result_summary(),
|
|
"이미 수령"
|
|
)
|
|
|
|
var choice_text: String = scene._format_post_battle_choice_reward_text({
|
|
"gold": 50,
|
|
"items": ["war_axe"],
|
|
"join_officers": ["dian_wei"]
|
|
})
|
|
_check_contains(failures, "choice gold", choice_text, "+50냥")
|
|
_check_contains(failures, "choice item", choice_text, "전부")
|
|
_check_contains(failures, "choice join", choice_text, "합류 전위")
|
|
|
|
if failures.is_empty():
|
|
scene.free()
|
|
print("result summary smoke ok")
|
|
quit(0)
|
|
return
|
|
|
|
scene.free()
|
|
for failure in failures:
|
|
push_error(failure)
|
|
quit(1)
|
|
|
|
|
|
func _check_contains(failures: Array[String], label: String, text: String, expected: String) -> void:
|
|
if text.contains(expected):
|
|
return
|
|
failures.append("%s expected `%s` in `%s`" % [label, expected, text])
|
|
|
|
|
|
func _check_not_contains(failures: Array[String], label: String, text: String, unexpected: String) -> void:
|
|
if not text.contains(unexpected):
|
|
return
|
|
failures.append("%s did not expect `%s` in `%s`" % [label, unexpected, text])
|
|
|
|
|
|
func _collect_tooltips(root: Node) -> String:
|
|
var parts := []
|
|
if root is Control:
|
|
var tooltip := (root as Control).tooltip_text
|
|
if not tooltip.is_empty():
|
|
parts.append(tooltip)
|
|
for child in root.get_children():
|
|
parts.append(_collect_tooltips(child))
|
|
return "\n".join(parts)
|
|
|
|
|
|
func _has_texture_rect(root: Node) -> bool:
|
|
if root is TextureRect and (root as TextureRect).texture != null:
|
|
return true
|
|
for child in root.get_children():
|
|
if _has_texture_rect(child):
|
|
return true
|
|
return false
|
|
|
|
|
|
func _count_named_nodes(root: Node, node_name: String) -> int:
|
|
var count := 1 if root.name == node_name else 0
|
|
for child in root.get_children():
|
|
count += _count_named_nodes(child, node_name)
|
|
return count
|