Add Jiangling rearguard camp and Tong Pass bridge

This commit is contained in:
2026-06-19 04:53:59 +09:00
parent 7abe2b36c1
commit 70563668a2
4 changed files with 388 additions and 2 deletions

View File

@@ -32,6 +32,61 @@
"The rush toward Xuchang carried news ahead of panic, but the Jiangling rear is thinner and more exposed." "The rush toward Xuchang carried news ahead of panic, but the Jiangling rear is thinner and more exposed."
] ]
} }
],
"camp_conversations": [
{
"id": "jiangling_rearguard_council",
"group": "topic",
"label": "Rearguard Council",
"speaker": "Cao Ren",
"summary": "Shape the rear line before the coalition pursuit closes.",
"lines": [
{ "speaker": "Cao Ren", "side": "left", "text": "The wagons can still hear the enemy behind them. If this line shakes, the retreat hears it too." },
{ "speaker": "Guo Jia", "side": "right", "text": "Then make the line sound larger than it is. A firm rear can lend courage to men who never see it." }
]
},
{
"id": "jiangling_zhang_he_rear_line",
"group": "officer",
"officer_id": "zhang_he",
"label": "Zhang He - Rear Line",
"speaker": "Zhang He",
"summary": "Judge where the pursuit will test the line.",
"lines": [
{ "speaker": "Zhang He", "side": "left", "text": "The enemy will not spend strength on our center first. They will pull at the wagons and make our officers look aside." },
{ "speaker": "Cao Cao", "side": "right", "text": "Then hold the side roads like gates. If they want panic, make them buy it with time." }
]
},
{
"id": "jiangling_rearguard_stability_medicine",
"group": "topic",
"label": "Stability Medicine",
"speaker": "Field Surgeon",
"summary": "Claim medicine carried forward by the secured Huarong rearguard.",
"campaign_flags": { "secured_huarong_rearguard": true },
"effects": [
{ "type": "grant_item", "item_id": "panacea", "count": 1 }
],
"lines": [
{ "speaker": "Field Surgeon", "side": "left", "text": "The Huarong rearguard kept the medicine chest with the column. One packet survived the mud." },
{ "speaker": "Cao Ren", "side": "right", "text": "Keep it near the rear gate. A line that can heal does not yield easily." }
]
},
{
"id": "jiangling_rearguard_forced_march_beans",
"group": "topic",
"label": "Forced March Beans",
"speaker": "Quartermaster",
"summary": "Claim rations left in the thin rear after the rush north.",
"campaign_flags": { "rushed_xuchang_return": true },
"effects": [
{ "type": "grant_item", "item_id": "bean", "count": 1 }
],
"lines": [
{ "speaker": "Quartermaster", "side": "left", "text": "The fast road stripped most wagons bare, but I held one sack back for the men closing the rear." },
{ "speaker": "Xiahou Dun", "side": "right", "text": "Then do not let it sit like treasure. Feed the line before the enemy tests it." }
]
}
] ]
}, },
"shop": { "shop": {
@@ -55,7 +110,14 @@
"campaign_flags": { "rushed_xuchang_return": true }, "campaign_flags": { "rushed_xuchang_return": true },
"items": ["war_drum"] "items": ["war_drum"]
} }
] ],
"merchant": {
"name": "Jiangling Rear Road Sutler",
"lines": [
"A rear road sells different goods: dry bandages, quiet beans, and anything that keeps men from looking back.",
"Buy quickly. If the pursuit reaches my cart, I become a soldier or a memory."
]
}
}, },
"roster": { "roster": {
"max_units": 7, "max_units": 7,

View File

@@ -59,7 +59,7 @@
}, },
"roster": { "roster": {
"max_units": 7, "max_units": 7,
"required_officers": ["cao_cao", "guo_jia"] "required_officers": ["cao_cao", "guo_jia", "zhang_he"]
}, },
"formation": { "formation": {
"cells": [[1, 3], [1, 4], [1, 5], [2, 2], [2, 3], [2, 4], [2, 5], [2, 6], [3, 2], [3, 3], [3, 4], [3, 5], [3, 6]] "cells": [[1, 3], [1, 4], [1, 5], [2, 2], [2, 3], [2, 4], [2, 5], [2, 6], [3, 2], [3, 3], [3, 4], [3, 5], [3, 6]]

View File

@@ -122,6 +122,10 @@ const HUARONG_HELD_MEDICINE_CONVERSATION_ID := "huarong_held_line_medicine"
const HUARONG_OPEN_RETREAT_BEANS_CONVERSATION_ID := "huarong_open_retreat_beans" const HUARONG_OPEN_RETREAT_BEANS_CONVERSATION_ID := "huarong_open_retreat_beans"
const JIANGLING_REARGUARD_SCENARIO_ID := "032_jiangling_rearguard" const JIANGLING_REARGUARD_SCENARIO_ID := "032_jiangling_rearguard"
const JIANGLING_REARGUARD_SCENARIO_PATH := "res://data/scenarios/032_jiangling_rearguard.json" const JIANGLING_REARGUARD_SCENARIO_PATH := "res://data/scenarios/032_jiangling_rearguard.json"
const JIANGLING_REARGUARD_STABILITY_MEDICINE_CONVERSATION_ID := "jiangling_rearguard_stability_medicine"
const JIANGLING_REARGUARD_FORCED_MARCH_BEANS_CONVERSATION_ID := "jiangling_rearguard_forced_march_beans"
const TONG_PASS_SCENARIO_ID := "033_tong_pass_vanguard"
const TONG_PASS_SCENARIO_PATH := "res://data/scenarios/033_tong_pass_vanguard.json"
const SAVE_PATH := "user://campaign_save.json" const SAVE_PATH := "user://campaign_save.json"
const MANUAL_SAVE_PATH := "user://campaign_manual_save.json" const MANUAL_SAVE_PATH := "user://campaign_manual_save.json"
@@ -162,6 +166,7 @@ func _init() -> void:
_check_red_cliffs_post_battle_choice_bridges_to_fire(failures) _check_red_cliffs_post_battle_choice_bridges_to_fire(failures)
_check_red_cliffs_fire_post_battle_choice_bridges_to_huarong(failures) _check_red_cliffs_fire_post_battle_choice_bridges_to_huarong(failures)
_check_huarong_post_battle_choice_bridges_to_jiangling_rearguard(failures) _check_huarong_post_battle_choice_bridges_to_jiangling_rearguard(failures)
_check_jiangling_rearguard_post_battle_choice_bridges_to_tong_pass(failures)
_check_manual_checkpoint_reverts_claim(failures) _check_manual_checkpoint_reverts_claim(failures)
_check_completed_replay_cannot_claim(failures) _check_completed_replay_cannot_claim(failures)
_check_conditional_camp_conversations(failures) _check_conditional_camp_conversations(failures)
@@ -185,6 +190,7 @@ func _init() -> void:
_check_red_cliffs_branch_camp_conversations(failures) _check_red_cliffs_branch_camp_conversations(failures)
_check_red_cliffs_fire_branch_camp_conversations(failures) _check_red_cliffs_fire_branch_camp_conversations(failures)
_check_huarong_branch_camp_conversations(failures) _check_huarong_branch_camp_conversations(failures)
_check_jiangling_rearguard_branch_camp_conversations(failures)
_check_talk_menu_closes_on_cancel_and_reload(failures) _check_talk_menu_closes_on_cancel_and_reload(failures)
if not _restore_user_file(SAVE_PATH, save_backup): if not _restore_user_file(SAVE_PATH, save_backup):
@@ -1424,6 +1430,29 @@ func _check_huarong_post_battle_choice_bridges_to_jiangling_rearguard(failures:
) )
func _check_jiangling_rearguard_post_battle_choice_bridges_to_tong_pass(failures: Array[String]) -> void:
_check_jiangling_rearguard_choice_branch_to_tong_pass(
failures,
"stabilize_jiangling_rearguard",
"stabilized_jiangling_rearguard",
"mobilized_tong_pass_vanguard",
"imperial_seal",
"war_drum",
"Jiangling's stabilized rearguard",
"jiangling_stability_supplies"
)
_check_jiangling_rearguard_choice_branch_to_tong_pass(
failures,
"mobilize_tong_pass_vanguard",
"mobilized_tong_pass_vanguard",
"stabilized_jiangling_rearguard",
"war_drum",
"imperial_seal",
"early western mobilization",
"early_western_mobilization_meets_scouts"
)
func _check_wuchao_choice_branch_to_cangting( func _check_wuchao_choice_branch_to_cangting(
failures: Array[String], failures: Array[String],
choice_id: String, choice_id: String,
@@ -2811,6 +2840,105 @@ func _check_huarong_choice_branch_to_jiangling_rearguard(
scene.free() scene.free()
func _check_jiangling_rearguard_choice_branch_to_tong_pass(
failures: Array[String],
choice_id: String,
expected_flag: String,
cleared_flag: String,
expected_shop_item_id: String,
hidden_shop_item_id: String,
expected_briefing_fragment: String,
expected_event_id: String
) -> void:
var scene = _new_prebattle_scene_for(failures, "Jiangling Rearguard choice bridge %s" % choice_id, JIANGLING_REARGUARD_SCENARIO_ID, JIANGLING_REARGUARD_SCENARIO_PATH)
if scene == null:
return
if not scene.campaign_state.joined_officers.has("zhang_he"):
scene.campaign_state.joined_officers.append("zhang_he")
if not scene.state.load_battle(
JIANGLING_REARGUARD_SCENARIO_PATH,
scene.campaign_state.get_roster_overrides(),
scene.campaign_state.get_inventory_snapshot(),
scene.campaign_state.get_flags_snapshot(),
scene.campaign_state.get_joined_officers_snapshot()
):
failures.append("Jiangling Rearguard choice bridge %s could not reload Jiangling Rearguard with Zhang He joined" % choice_id)
scene.free()
return
scene.state.battle_status = "victory"
var result: Dictionary = scene.campaign_state.apply_battle_result(scene.state)
if not bool(result.get("saved", false)):
failures.append("Jiangling Rearguard choice bridge %s should save 032 victory" % choice_id)
scene.free()
return
if not scene.campaign_state.get_joined_officers_snapshot().has("zhang_he"):
failures.append("Jiangling Rearguard choice bridge %s should keep Zhang He before Tong Pass" % choice_id)
if bool(result.get("choice_applied", true)):
failures.append("Jiangling Rearguard choice bridge %s should wait for a selected post-battle choice" % choice_id)
if scene.campaign_state.pending_post_battle_choice_scenario_id != JIANGLING_REARGUARD_SCENARIO_ID:
failures.append("Jiangling Rearguard choice bridge %s should mark Jiangling Rearguard choice pending" % choice_id)
var choice := _find_choice_by_id(result.get("post_battle_choices", []), choice_id)
if choice.is_empty():
failures.append("Jiangling Rearguard choice bridge missing choice: %s" % choice_id)
scene.free()
return
if not scene.campaign_state.try_apply_post_battle_choice(choice, JIANGLING_REARGUARD_SCENARIO_ID):
failures.append("Jiangling Rearguard choice bridge %s should save selected choice" % choice_id)
scene.free()
return
var flags: Dictionary = scene.campaign_state.get_flags_snapshot()
if flags.get(expected_flag, false) != true:
failures.append("Jiangling Rearguard choice bridge %s should set %s" % [choice_id, expected_flag])
if flags.get(cleared_flag, true) != false:
failures.append("Jiangling Rearguard choice bridge %s should clear %s" % [choice_id, cleared_flag])
if scene.campaign_state.current_scenario_id != TONG_PASS_SCENARIO_ID:
failures.append("Jiangling Rearguard choice bridge %s should advance to Tong Pass, got %s" % [choice_id, scene.campaign_state.current_scenario_id])
if not scene.state.load_battle(
TONG_PASS_SCENARIO_PATH,
scene.campaign_state.get_roster_overrides(),
scene.campaign_state.get_inventory_snapshot(),
flags,
scene.campaign_state.get_joined_officers_snapshot()
):
failures.append("Jiangling Rearguard choice bridge %s could not load Tong Pass" % choice_id)
scene.free()
return
if scene.state.get_unit("zhang_he_ch33").is_empty():
failures.append("Jiangling Rearguard choice bridge %s should deploy Zhang He in Tong Pass" % choice_id)
elif not scene.state.is_required_deployment("zhang_he_ch33"):
failures.append("Jiangling Rearguard choice bridge %s should require Zhang He in Tong Pass" % choice_id)
var briefing_lines: Array = scene.state.get_briefing().get("lines", [])
if not _lines_contain_fragment(briefing_lines, expected_briefing_fragment):
failures.append("Jiangling Rearguard choice bridge %s should expose Tong Pass briefing fragment `%s`" % [choice_id, expected_briefing_fragment])
if not _battle_event_requires_flag(scene.state.battle_events, expected_event_id, expected_flag):
failures.append("Jiangling Rearguard choice bridge %s should expose Tong Pass event %s gated by %s" % [choice_id, expected_event_id, expected_flag])
var shop_items: Array = scene.state.get_shop_item_ids()
if not shop_items.has(expected_shop_item_id):
failures.append("Jiangling Rearguard choice bridge %s should expose shop item %s" % [choice_id, expected_shop_item_id])
if shop_items.has(hidden_shop_item_id):
failures.append("Jiangling Rearguard choice bridge %s should hide shop item %s" % [choice_id, hidden_shop_item_id])
scene.free()
func _lines_contain_fragment(lines: Array, fragment: String) -> bool:
for line in lines:
if str(line).contains(fragment):
return true
return false
func _battle_event_requires_flag(events: Array, event_id: String, flag_name: String) -> bool:
for event in events:
if typeof(event) != TYPE_DICTIONARY:
continue
if str(event.get("id", "")) != event_id:
continue
var when: Dictionary = event.get("when", {})
var campaign_flags: Dictionary = when.get("campaign_flags", {})
return campaign_flags.get(flag_name, false) == true
return false
func _find_choice_by_id(choices, choice_id: String) -> Dictionary: func _find_choice_by_id(choices, choice_id: String) -> Dictionary:
if typeof(choices) != TYPE_ARRAY: if typeof(choices) != TYPE_ARRAY:
return {} return {}
@@ -4761,6 +4889,121 @@ func _check_huarong_branch_camp_conversations(failures: Array[String]) -> void:
opened_scene.free() opened_scene.free()
func _check_jiangling_rearguard_branch_camp_conversations(failures: Array[String]) -> void:
var base_scene = _new_prebattle_scene_for(failures, "Jiangling Rearguard base camp", JIANGLING_REARGUARD_SCENARIO_ID, JIANGLING_REARGUARD_SCENARIO_PATH)
if base_scene != null:
if not base_scene.campaign_state.joined_officers.has("zhang_he"):
base_scene.campaign_state.joined_officers.append("zhang_he")
if not base_scene.state.load_battle(
JIANGLING_REARGUARD_SCENARIO_PATH,
base_scene.campaign_state.get_roster_overrides(),
base_scene.campaign_state.get_inventory_snapshot(),
base_scene.campaign_state.get_flags_snapshot(),
base_scene.campaign_state.get_joined_officers_snapshot()
):
failures.append("Jiangling Rearguard base camp should reload with Zhang He joined")
else:
if base_scene._camp_conversation_by_id("jiangling_rearguard_council").is_empty():
failures.append("Jiangling Rearguard should expose the council conversation")
if base_scene._camp_conversation_by_id("jiangling_zhang_he_rear_line").is_empty():
failures.append("Jiangling Rearguard should expose Zhang He's rear line conversation")
if not base_scene._camp_conversation_by_id(JIANGLING_REARGUARD_STABILITY_MEDICINE_CONVERSATION_ID).is_empty():
failures.append("Jiangling Rearguard stability medicine should be hidden without secured Huarong flag")
if not base_scene._camp_conversation_by_id(JIANGLING_REARGUARD_FORCED_MARCH_BEANS_CONVERSATION_ID).is_empty():
failures.append("Jiangling Rearguard forced march beans should be hidden without rushed return flag")
var merchant: Dictionary = base_scene.state.get_shop_merchant()
if str(merchant.get("name", "")) != "Jiangling Rear Road Sutler":
failures.append("Jiangling Rearguard shop merchant name should be present")
var merchant_lines: Array = merchant.get("lines", [])
if merchant_lines.size() < 2:
failures.append("Jiangling Rearguard shop merchant should expose flavor lines")
if base_scene._format_talk_status_text(base_scene._camp_conversation_entries()) != "Camp conversations | 2 topics":
failures.append("Jiangling Rearguard base talk status should summarize two non-supply topics")
base_scene.free()
var secured_scene = _new_prebattle_scene_for(
failures,
"Jiangling Rearguard secured Huarong camp",
JIANGLING_REARGUARD_SCENARIO_ID,
JIANGLING_REARGUARD_SCENARIO_PATH,
{"secured_huarong_rearguard": true}
)
if secured_scene != null:
if not secured_scene.campaign_state.joined_officers.has("zhang_he"):
secured_scene.campaign_state.joined_officers.append("zhang_he")
if not secured_scene.state.load_battle(
JIANGLING_REARGUARD_SCENARIO_PATH,
secured_scene.campaign_state.get_roster_overrides(),
secured_scene.campaign_state.get_inventory_snapshot(),
secured_scene.campaign_state.get_flags_snapshot(),
secured_scene.campaign_state.get_joined_officers_snapshot()
):
failures.append("Jiangling Rearguard secured Huarong camp should reload with Zhang He joined")
else:
var stability_medicine: Dictionary = secured_scene._camp_conversation_by_id(JIANGLING_REARGUARD_STABILITY_MEDICINE_CONVERSATION_ID)
if stability_medicine.is_empty():
failures.append("secured Huarong rearguard flag should expose Jiangling stability medicine")
if not secured_scene._camp_conversation_by_id(JIANGLING_REARGUARD_FORCED_MARCH_BEANS_CONVERSATION_ID).is_empty():
failures.append("secured Huarong rearguard flag should not expose Jiangling forced march beans")
if not stability_medicine.is_empty():
if secured_scene._format_talk_status_text(secured_scene._camp_conversation_entries()) != "Camp conversations | 3 topics | 1 supplies ready":
failures.append("Jiangling secured Huarong talk status should show one ready supply")
if not secured_scene._format_camp_conversation_button_text(stability_medicine).contains("보급 Panacea"):
failures.append("Jiangling stability medicine button should show Panacea supply")
var before_panacea := int(secured_scene.campaign_state.get_inventory_snapshot().get("panacea", 0))
secured_scene._apply_camp_conversation_effects(stability_medicine)
if int(secured_scene.campaign_state.get_inventory_snapshot().get("panacea", 0)) != before_panacea + 1:
failures.append("Jiangling stability medicine should add Panacea to campaign inventory")
if int(secured_scene.state.get_inventory_snapshot().get("panacea", 0)) != before_panacea + 1:
failures.append("Jiangling stability medicine should refresh battle Panacea inventory")
if not secured_scene.campaign_state.has_claimed_camp_conversation_effects(JIANGLING_REARGUARD_SCENARIO_ID, JIANGLING_REARGUARD_STABILITY_MEDICINE_CONVERSATION_ID):
failures.append("Jiangling stability medicine claim should be saved")
if secured_scene._format_talk_status_text(secured_scene._camp_conversation_entries()) != "Camp conversations | 3 topics | 1 claimed":
failures.append("Jiangling secured Huarong talk status should show claimed supply after claim")
secured_scene.free()
var rushed_scene = _new_prebattle_scene_for(
failures,
"Jiangling Rearguard rushed return camp",
JIANGLING_REARGUARD_SCENARIO_ID,
JIANGLING_REARGUARD_SCENARIO_PATH,
{"rushed_xuchang_return": true}
)
if rushed_scene != null:
if not rushed_scene.campaign_state.joined_officers.has("zhang_he"):
rushed_scene.campaign_state.joined_officers.append("zhang_he")
if not rushed_scene.state.load_battle(
JIANGLING_REARGUARD_SCENARIO_PATH,
rushed_scene.campaign_state.get_roster_overrides(),
rushed_scene.campaign_state.get_inventory_snapshot(),
rushed_scene.campaign_state.get_flags_snapshot(),
rushed_scene.campaign_state.get_joined_officers_snapshot()
):
failures.append("Jiangling Rearguard rushed return camp should reload with Zhang He joined")
else:
var forced_beans: Dictionary = rushed_scene._camp_conversation_by_id(JIANGLING_REARGUARD_FORCED_MARCH_BEANS_CONVERSATION_ID)
if forced_beans.is_empty():
failures.append("rushed Xuchang return flag should expose Jiangling forced march beans")
if not rushed_scene._camp_conversation_by_id(JIANGLING_REARGUARD_STABILITY_MEDICINE_CONVERSATION_ID).is_empty():
failures.append("rushed Xuchang return flag should not expose Jiangling stability medicine")
if not forced_beans.is_empty():
if rushed_scene._format_talk_status_text(rushed_scene._camp_conversation_entries()) != "Camp conversations | 3 topics | 1 supplies ready":
failures.append("Jiangling rushed return talk status should show one ready supply")
if not rushed_scene._format_camp_conversation_button_text(forced_beans).contains("보급 Bean"):
failures.append("Jiangling forced march beans button should show Bean supply")
var before_bean := int(rushed_scene.campaign_state.get_inventory_snapshot().get("bean", 0))
rushed_scene._apply_camp_conversation_effects(forced_beans)
if int(rushed_scene.campaign_state.get_inventory_snapshot().get("bean", 0)) != before_bean + 1:
failures.append("Jiangling forced march beans should add Bean to campaign inventory")
if int(rushed_scene.state.get_inventory_snapshot().get("bean", 0)) != before_bean + 1:
failures.append("Jiangling forced march beans should refresh battle Bean inventory")
if not rushed_scene.campaign_state.has_claimed_camp_conversation_effects(JIANGLING_REARGUARD_SCENARIO_ID, JIANGLING_REARGUARD_FORCED_MARCH_BEANS_CONVERSATION_ID):
failures.append("Jiangling forced march beans claim should be saved")
if rushed_scene._format_talk_status_text(rushed_scene._camp_conversation_entries()) != "Camp conversations | 3 topics | 1 claimed":
failures.append("Jiangling rushed return talk status should show claimed supply after claim")
rushed_scene.free()
func _check_talk_menu_closes_on_cancel_and_reload(failures: Array[String]) -> void: func _check_talk_menu_closes_on_cancel_and_reload(failures: Array[String]) -> void:
var scene = _new_prebattle_scene(failures, "talk menu close guards") var scene = _new_prebattle_scene(failures, "talk menu close guards")
if scene == null: if scene == null:

View File

@@ -2145,6 +2145,17 @@ func _check_battle_visual_data(failures: Array[String]) -> void:
failures.append("could not load Jiangling Rearguard data") failures.append("could not load Jiangling Rearguard data")
else: else:
_check_shop_items_unique(failures, jiangling_rearguard_state, "032 base") _check_shop_items_unique(failures, jiangling_rearguard_state, "032 base")
var jiangling_rearguard_conversations: Array = jiangling_rearguard_state.get_briefing().get("camp_conversations", [])
if jiangling_rearguard_conversations.size() != 2:
failures.append("032 base briefing should expose exactly two camp conversations")
else:
_check_camp_conversation(failures, _find_camp_conversation(jiangling_rearguard_conversations, "jiangling_rearguard_council"), "jiangling_rearguard_council", "topic", "")
_check_camp_conversation(failures, _find_camp_conversation(jiangling_rearguard_conversations, "jiangling_zhang_he_rear_line"), "jiangling_zhang_he_rear_line", "officer", "zhang_he")
var jiangling_rearguard_merchant := jiangling_rearguard_state.get_shop_merchant()
if str(jiangling_rearguard_merchant.get("name", "")) != "Jiangling Rear Road Sutler":
failures.append("032 shop should expose Jiangling rear road merchant name")
if (jiangling_rearguard_merchant.get("lines", []) as Array).size() < 2:
failures.append("032 shop should expose merchant flavor lines")
if jiangling_rearguard_state.get_unit("zhang_he_ch32").is_empty() or not jiangling_rearguard_state.is_required_deployment("zhang_he_ch32"): if jiangling_rearguard_state.get_unit("zhang_he_ch32").is_empty() or not jiangling_rearguard_state.is_required_deployment("zhang_he_ch32"):
failures.append("032 should deploy Zhang He as a required officer") failures.append("032 should deploy Zhang He as a required officer")
_check_shop_item_visibility(failures, jiangling_rearguard_state, "war_drum", false, "032 base") _check_shop_item_visibility(failures, jiangling_rearguard_state, "war_drum", false, "032 base")
@@ -2155,6 +2166,19 @@ func _check_battle_visual_data(failures: Array[String]) -> void:
failures.append("could not load Jiangling Rearguard secured Huarong data") failures.append("could not load Jiangling Rearguard secured Huarong data")
else: else:
_check_shop_items_unique(failures, jiangling_rearguard_secured_state, "032 secured Huarong rearguard") _check_shop_items_unique(failures, jiangling_rearguard_secured_state, "032 secured Huarong rearguard")
var stability_medicine: Dictionary = _find_camp_conversation(
jiangling_rearguard_secured_state.get_briefing().get("camp_conversations", []),
"jiangling_rearguard_stability_medicine"
)
if stability_medicine.is_empty():
failures.append("032 secured Huarong rearguard should expose stability medicine")
else:
_check_camp_conversation_effect(failures, stability_medicine, "panacea", 1)
if not _find_camp_conversation(
jiangling_rearguard_secured_state.get_briefing().get("camp_conversations", []),
"jiangling_rearguard_forced_march_beans"
).is_empty():
failures.append("032 secured Huarong rearguard should not expose forced march beans")
_check_shop_item_visibility(failures, jiangling_rearguard_secured_state, "imperial_seal", true, "032 secured Huarong rearguard") _check_shop_item_visibility(failures, jiangling_rearguard_secured_state, "imperial_seal", true, "032 secured Huarong rearguard")
_check_shop_item_visibility(failures, jiangling_rearguard_secured_state, "war_drum", false, "032 secured Huarong rearguard") _check_shop_item_visibility(failures, jiangling_rearguard_secured_state, "war_drum", false, "032 secured Huarong rearguard")
@@ -2163,6 +2187,19 @@ func _check_battle_visual_data(failures: Array[String]) -> void:
failures.append("could not load Jiangling Rearguard rushed Xuchang data") failures.append("could not load Jiangling Rearguard rushed Xuchang data")
else: else:
_check_shop_items_unique(failures, jiangling_rearguard_rushed_state, "032 rushed Xuchang return") _check_shop_items_unique(failures, jiangling_rearguard_rushed_state, "032 rushed Xuchang return")
var forced_march_beans: Dictionary = _find_camp_conversation(
jiangling_rearguard_rushed_state.get_briefing().get("camp_conversations", []),
"jiangling_rearguard_forced_march_beans"
)
if forced_march_beans.is_empty():
failures.append("032 rushed Xuchang return should expose forced march beans")
else:
_check_camp_conversation_effect(failures, forced_march_beans, "bean", 1)
if not _find_camp_conversation(
jiangling_rearguard_rushed_state.get_briefing().get("camp_conversations", []),
"jiangling_rearguard_stability_medicine"
).is_empty():
failures.append("032 rushed Xuchang return should not expose stability medicine")
_check_shop_item_visibility(failures, jiangling_rearguard_rushed_state, "war_drum", true, "032 rushed Xuchang return") _check_shop_item_visibility(failures, jiangling_rearguard_rushed_state, "war_drum", true, "032 rushed Xuchang return")
_check_shop_item_visibility(failures, jiangling_rearguard_rushed_state, "imperial_seal", false, "032 rushed Xuchang return") _check_shop_item_visibility(failures, jiangling_rearguard_rushed_state, "imperial_seal", false, "032 rushed Xuchang return")
@@ -2173,6 +2210,50 @@ func _check_battle_visual_data(failures: Array[String]) -> void:
_check_shop_items_unique(failures, jiangling_rearguard_old_flags_state, "032 old Huarong setup flags") _check_shop_items_unique(failures, jiangling_rearguard_old_flags_state, "032 old Huarong setup flags")
_check_shop_item_visibility(failures, jiangling_rearguard_old_flags_state, "war_drum", false, "032 old Huarong setup flags") _check_shop_item_visibility(failures, jiangling_rearguard_old_flags_state, "war_drum", false, "032 old Huarong setup flags")
_check_shop_item_visibility(failures, jiangling_rearguard_old_flags_state, "imperial_seal", false, "032 old Huarong setup flags") _check_shop_item_visibility(failures, jiangling_rearguard_old_flags_state, "imperial_seal", false, "032 old Huarong setup flags")
if not _find_camp_conversation(
jiangling_rearguard_old_flags_state.get_briefing().get("camp_conversations", []),
"jiangling_rearguard_stability_medicine"
).is_empty():
failures.append("032 old Huarong setup flags should not expose stability medicine")
if not _find_camp_conversation(
jiangling_rearguard_old_flags_state.get_briefing().get("camp_conversations", []),
"jiangling_rearguard_forced_march_beans"
).is_empty():
failures.append("032 old Huarong setup flags should not expose forced march beans")
var tong_pass_state = BattleStateScript.new()
if not tong_pass_state.load_battle("res://data/scenarios/033_tong_pass_vanguard.json", {}, {}, {}, ["zhang_he"]):
failures.append("could not load Tong Pass Vanguard data")
else:
_check_shop_items_unique(failures, tong_pass_state, "033 base")
if tong_pass_state.get_unit("zhang_he_ch33").is_empty() or not tong_pass_state.is_required_deployment("zhang_he_ch33"):
failures.append("033 should deploy Zhang He as a required officer")
_check_shop_item_visibility(failures, tong_pass_state, "war_drum", false, "033 base")
_check_shop_item_visibility(failures, tong_pass_state, "imperial_seal", false, "033 base")
var tong_pass_stabilized_state = BattleStateScript.new()
if not tong_pass_stabilized_state.load_battle("res://data/scenarios/033_tong_pass_vanguard.json", {}, {}, {"stabilized_jiangling_rearguard": true}, ["zhang_he"]):
failures.append("could not load Tong Pass stabilized Jiangling data")
else:
_check_shop_items_unique(failures, tong_pass_stabilized_state, "033 stabilized Jiangling rearguard")
_check_shop_item_visibility(failures, tong_pass_stabilized_state, "imperial_seal", true, "033 stabilized Jiangling rearguard")
_check_shop_item_visibility(failures, tong_pass_stabilized_state, "war_drum", false, "033 stabilized Jiangling rearguard")
var tong_pass_mobilized_state = BattleStateScript.new()
if not tong_pass_mobilized_state.load_battle("res://data/scenarios/033_tong_pass_vanguard.json", {}, {}, {"mobilized_tong_pass_vanguard": true}, ["zhang_he"]):
failures.append("could not load Tong Pass mobilized vanguard data")
else:
_check_shop_items_unique(failures, tong_pass_mobilized_state, "033 mobilized Tong Pass vanguard")
_check_shop_item_visibility(failures, tong_pass_mobilized_state, "war_drum", true, "033 mobilized Tong Pass vanguard")
_check_shop_item_visibility(failures, tong_pass_mobilized_state, "imperial_seal", false, "033 mobilized Tong Pass vanguard")
var tong_pass_old_flags_state = BattleStateScript.new()
if not tong_pass_old_flags_state.load_battle("res://data/scenarios/033_tong_pass_vanguard.json", {}, {}, {"secured_huarong_rearguard": true, "rushed_xuchang_return": true}, ["zhang_he"]):
failures.append("could not load Tong Pass old Jiangling setup flag data")
else:
_check_shop_items_unique(failures, tong_pass_old_flags_state, "033 old Jiangling setup flags")
_check_shop_item_visibility(failures, tong_pass_old_flags_state, "war_drum", false, "033 old Jiangling setup flags")
_check_shop_item_visibility(failures, tong_pass_old_flags_state, "imperial_seal", false, "033 old Jiangling setup flags")
for item_id in ["bronze_sword", "training_spear", "short_bow", "hand_axe", "iron_armor", "panacea"]: for item_id in ["bronze_sword", "training_spear", "short_bow", "hand_axe", "iron_armor", "panacea"]:
var item := state.get_item_def(item_id) var item := state.get_item_def(item_id)