Localize western Hanzhong arc

This commit is contained in:
2026-06-19 10:04:40 +09:00
parent 6838aebcea
commit e4c87bf86f
7 changed files with 578 additions and 257 deletions

View File

@@ -2514,6 +2514,77 @@ func _check_battle_visual_data(failures: Array[String]) -> void:
).is_empty():
failures.append("035 old Counterstroke setup flags should not expose doubt rations")
var western_hanzhong_expectations := [
{
"path": "res://data/scenarios/036_weishui_crossing.json",
"label": "036 Weishui crossing",
"merchant": "위수 도하 야상",
"conversations": [
["weishui_crossing_council", "topic", ""],
["weishui_guo_jia_alliance_rift", "officer", "guo_jia"]
],
"imperial_flag": {"secured_weishui_crossing": true},
"war_drum_flag": {"deepened_han_sui_rift": true}
},
{
"path": "res://data/scenarios/037_guanzhong_foothold.json",
"label": "037 Guanzhong foothold",
"merchant": "관중 교두보 야상",
"conversations": [
["guanzhong_foothold_council", "topic", ""],
["guanzhong_zhang_he_rearguard", "officer", "zhang_he"]
],
"imperial_flag": {"secured_guanzhong_foothold": true},
"war_drum_flag": {"split_western_alliance": true}
},
{
"path": "res://data/scenarios/038_ma_chao_retreat.json",
"label": "038 Ma Chao retreat",
"merchant": "서량 퇴로 야상",
"conversations": [
["ma_chao_retreat_council", "topic", ""],
["ma_chao_guo_jia_hanzhong_shadow", "officer", "guo_jia"]
],
"imperial_flag": {"secured_guanzhong_commandery": true},
"war_drum_flag": {"pressed_ma_chao_retreat": true}
},
{
"path": "res://data/scenarios/039_hanzhong_approach.json",
"label": "039 Hanzhong approach",
"merchant": "한중 산문 야상",
"conversations": [
["hanzhong_approach_council", "topic", ""],
["hanzhong_guo_jia_pass_faith", "officer", "guo_jia"]
],
"imperial_flag": {"pacified_guanzhong": true},
"war_drum_flag": {"prepared_hanzhong_front": true}
},
{
"path": "res://data/scenarios/040_hanzhong_gate.json",
"label": "040 Hanzhong gate",
"merchant": "한중 관문 야상",
"conversations": [
["hanzhong_gate_council", "topic", ""],
["hanzhong_xiahou_yuan_beacon", "officer", "xiahou_yuan"]
],
"imperial_flag": {"secured_hanzhong_approach": true},
"war_drum_flag": {"pressed_zhang_lu_gate": true}
},
{
"path": "res://data/scenarios/041_hanzhong_settlement.json",
"label": "041 Hanzhong settlement",
"merchant": "한중 창고 야상",
"conversations": [
["hanzhong_settlement_council", "topic", ""],
["hanzhong_zhang_he_holdouts", "officer", "zhang_he"]
],
"imperial_flag": {"accepted_zhang_lu_submission": true},
"war_drum_flag": {"pacified_hanzhong": true}
}
]
for expectation in western_hanzhong_expectations:
_check_western_hanzhong_campaign_entry(failures, expectation)
for item_id in ["bronze_sword", "training_spear", "short_bow", "hand_axe", "iron_armor", "war_drum", "imperial_seal", "panacea"]:
var item := state.get_item_def(item_id)
if item.is_empty():
@@ -3391,6 +3462,64 @@ func _find_camp_conversation(conversations: Array, conversation_id: String) -> D
return {}
func _check_western_hanzhong_campaign_entry(failures: Array[String], expectation: Dictionary) -> void:
var path := str(expectation.get("path", ""))
var label := str(expectation.get("label", path))
var state = BattleStateScript.new()
if not state.load_battle(path, {}, {}, {}, ["zhang_he"]):
failures.append("could not load %s data" % label)
return
_check_shop_items_unique(failures, state, "%s base" % label)
var conversations: Array = state.get_briefing().get("camp_conversations", [])
var expected_conversations: Array = expectation.get("conversations", [])
if conversations.size() != expected_conversations.size():
failures.append("%s briefing should expose exactly %d camp conversations" % [label, expected_conversations.size()])
for expected_variant in expected_conversations:
if typeof(expected_variant) != TYPE_ARRAY:
failures.append("%s conversation expectation should be an array" % label)
continue
var expected: Array = expected_variant
if expected.size() < 3:
failures.append("%s conversation expectation should include id, group, and officer id" % label)
continue
var expected_id := str(expected[0])
var expected_group := str(expected[1])
var expected_officer_id := str(expected[2])
_check_camp_conversation(
failures,
_find_camp_conversation(conversations, expected_id),
expected_id,
expected_group,
expected_officer_id
)
var merchant: Dictionary = state.get_shop_merchant()
if str(merchant.get("name", "")) != str(expectation.get("merchant", "")):
failures.append("%s shop merchant name should be present" % label)
var merchant_lines: Array = merchant.get("lines", [])
if merchant_lines.size() < 2:
failures.append("%s shop should expose merchant flavor lines" % label)
_check_shop_item_visibility(failures, state, "imperial_seal", false, "%s base" % label)
_check_shop_item_visibility(failures, state, "war_drum", false, "%s base" % label)
var imperial_state = BattleStateScript.new()
var imperial_flags: Dictionary = expectation.get("imperial_flag", {})
if not imperial_state.load_battle(path, {}, {}, imperial_flags, ["zhang_he"]):
failures.append("could not load %s imperial branch data" % label)
else:
_check_shop_items_unique(failures, imperial_state, "%s imperial branch" % label)
_check_shop_item_visibility(failures, imperial_state, "imperial_seal", true, "%s imperial branch" % label)
_check_shop_item_visibility(failures, imperial_state, "war_drum", false, "%s imperial branch" % label)
var drum_state = BattleStateScript.new()
var drum_flags: Dictionary = expectation.get("war_drum_flag", {})
if not drum_state.load_battle(path, {}, {}, drum_flags, ["zhang_he"]):
failures.append("could not load %s war drum branch data" % label)
else:
_check_shop_items_unique(failures, drum_state, "%s war drum branch" % label)
_check_shop_item_visibility(failures, drum_state, "war_drum", true, "%s war drum branch" % label)
_check_shop_item_visibility(failures, drum_state, "imperial_seal", false, "%s war drum branch" % label)
func _check_shop_item_visibility(failures: Array[String], state, item_id: String, expected_visible: bool, context: String) -> void:
var visible: bool = state.get_shop_item_ids().has(item_id)
if visible != expected_visible: