Add Tong Pass camp and Ma Chao bridge

This commit is contained in:
2026-06-19 05:00:19 +09:00
parent 70563668a2
commit b08370cf45
4 changed files with 369 additions and 2 deletions

View File

@@ -32,6 +32,61 @@
"The early western mobilization reaches Tong Pass quickly, but Ma Chao's scouts are already riding to meet it." "The early western mobilization reaches Tong Pass quickly, but Ma Chao's scouts are already riding to meet it."
] ]
} }
],
"camp_conversations": [
{
"id": "tong_pass_vanguard_council",
"group": "topic",
"label": "Pass Vanguard Council",
"speaker": "Xiahou Yuan",
"summary": "Set the column before the western riders close.",
"lines": [
{ "speaker": "Xiahou Yuan", "side": "left", "text": "Tong Pass does not welcome an army. It narrows it, tests it, and asks which men still trust the road." },
{ "speaker": "Cao Cao", "side": "right", "text": "Then we answer before the pass finishes asking. A vanguard that hesitates gives Ma Chao the field." }
]
},
{
"id": "tong_pass_zhang_he_pass_road",
"group": "officer",
"officer_id": "zhang_he",
"label": "Zhang He - Pass Road",
"speaker": "Zhang He",
"summary": "Read the western cavalry's first approach.",
"lines": [
{ "speaker": "Zhang He", "side": "left", "text": "Their riders will want open ground, but the pass gives them corners. We should make each corner cost them rhythm." },
{ "speaker": "Guo Jia", "side": "right", "text": "Good. Break rhythm first; pride follows after." }
]
},
{
"id": "tong_pass_jiangling_supply_medicine",
"group": "topic",
"label": "Jiangling Supply Medicine",
"speaker": "Field Surgeon",
"summary": "Claim medicine from the steadied Jiangling rear.",
"campaign_flags": { "stabilized_jiangling_rearguard": true },
"effects": [
{ "type": "grant_item", "item_id": "panacea", "count": 1 }
],
"lines": [
{ "speaker": "Field Surgeon", "side": "left", "text": "The Jiangling rear sent medicine west with the supply tally. It arrived dusty, but unbroken." },
{ "speaker": "Cao Ren", "side": "right", "text": "A stable rear still reaches the front. Keep it where the first charge lands." }
]
},
{
"id": "tong_pass_vanguard_rations",
"group": "topic",
"label": "Vanguard Rations",
"speaker": "Quartermaster",
"summary": "Claim rations moved ahead by the early western mobilization.",
"campaign_flags": { "mobilized_tong_pass_vanguard": true },
"effects": [
{ "type": "grant_item", "item_id": "bean", "count": 1 }
],
"lines": [
{ "speaker": "Quartermaster", "side": "left", "text": "The early column outran half the baggage, but not this ration sack. It was sent for the first line." },
{ "speaker": "Xiahou Yuan", "side": "right", "text": "Then feed the men before Ma Chao feeds them dust." }
]
}
] ]
}, },
"shop": { "shop": {
@@ -55,7 +110,14 @@
"campaign_flags": { "mobilized_tong_pass_vanguard": true }, "campaign_flags": { "mobilized_tong_pass_vanguard": true },
"items": ["war_drum"] "items": ["war_drum"]
} }
],
"merchant": {
"name": "Tong Pass Sutler",
"lines": [
"Western roads make poor customers and excellent liars. I trust coin, dry beans, and horses that do not limp.",
"Buy before Ma Chao's scouts decide my cart is part of your army."
] ]
}
}, },
"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

@@ -126,6 +126,10 @@ const JIANGLING_REARGUARD_STABILITY_MEDICINE_CONVERSATION_ID := "jiangling_rearg
const JIANGLING_REARGUARD_FORCED_MARCH_BEANS_CONVERSATION_ID := "jiangling_rearguard_forced_march_beans" 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_ID := "033_tong_pass_vanguard"
const TONG_PASS_SCENARIO_PATH := "res://data/scenarios/033_tong_pass_vanguard.json" const TONG_PASS_SCENARIO_PATH := "res://data/scenarios/033_tong_pass_vanguard.json"
const TONG_PASS_JIANGLING_MEDICINE_CONVERSATION_ID := "tong_pass_jiangling_supply_medicine"
const TONG_PASS_VANGUARD_RATIONS_CONVERSATION_ID := "tong_pass_vanguard_rations"
const MA_CHAO_COUNTERSTROKE_SCENARIO_ID := "034_ma_chao_counterstroke"
const MA_CHAO_COUNTERSTROKE_SCENARIO_PATH := "res://data/scenarios/034_ma_chao_counterstroke.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"
@@ -167,6 +171,7 @@ func _init() -> void:
_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_jiangling_rearguard_post_battle_choice_bridges_to_tong_pass(failures)
_check_tong_pass_post_battle_choice_bridges_to_ma_chao_counterstroke(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)
@@ -191,6 +196,7 @@ func _init() -> void:
_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_jiangling_rearguard_branch_camp_conversations(failures)
_check_tong_pass_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):
@@ -1453,6 +1459,29 @@ func _check_jiangling_rearguard_post_battle_choice_bridges_to_tong_pass(failures
) )
func _check_tong_pass_post_battle_choice_bridges_to_ma_chao_counterstroke(failures: Array[String]) -> void:
_check_tong_pass_choice_branch_to_ma_chao_counterstroke(
failures,
"fortify_tong_pass",
"fortified_tong_pass",
"pressed_ma_chao_vanguard",
"imperial_seal",
"war_drum",
"Tong Pass fortifications",
"fortified_pass_absorbs_charge"
)
_check_tong_pass_choice_branch_to_ma_chao_counterstroke(
failures,
"press_ma_chao_vanguard",
"pressed_ma_chao_vanguard",
"fortified_tong_pass",
"war_drum",
"imperial_seal",
"Pressing Ma Chao's vanguard",
"pressed_vanguard_draws_countercharge"
)
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,
@@ -2920,6 +2949,86 @@ func _check_jiangling_rearguard_choice_branch_to_tong_pass(
scene.free() scene.free()
func _check_tong_pass_choice_branch_to_ma_chao_counterstroke(
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, "Tong Pass choice bridge %s" % choice_id, TONG_PASS_SCENARIO_ID, TONG_PASS_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(
TONG_PASS_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("Tong Pass choice bridge %s could not reload Tong Pass 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("Tong Pass choice bridge %s should save 033 victory" % choice_id)
scene.free()
return
if not scene.campaign_state.get_joined_officers_snapshot().has("zhang_he"):
failures.append("Tong Pass choice bridge %s should keep Zhang He before Ma Chao Counterstroke" % choice_id)
if bool(result.get("choice_applied", true)):
failures.append("Tong Pass choice bridge %s should wait for a selected post-battle choice" % choice_id)
if scene.campaign_state.pending_post_battle_choice_scenario_id != TONG_PASS_SCENARIO_ID:
failures.append("Tong Pass choice bridge %s should mark Tong Pass choice pending" % choice_id)
var choice := _find_choice_by_id(result.get("post_battle_choices", []), choice_id)
if choice.is_empty():
failures.append("Tong Pass choice bridge missing choice: %s" % choice_id)
scene.free()
return
if not scene.campaign_state.try_apply_post_battle_choice(choice, TONG_PASS_SCENARIO_ID):
failures.append("Tong Pass 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("Tong Pass choice bridge %s should set %s" % [choice_id, expected_flag])
if flags.get(cleared_flag, true) != false:
failures.append("Tong Pass choice bridge %s should clear %s" % [choice_id, cleared_flag])
if scene.campaign_state.current_scenario_id != MA_CHAO_COUNTERSTROKE_SCENARIO_ID:
failures.append("Tong Pass choice bridge %s should advance to Ma Chao Counterstroke, got %s" % [choice_id, scene.campaign_state.current_scenario_id])
if not scene.state.load_battle(
MA_CHAO_COUNTERSTROKE_SCENARIO_PATH,
scene.campaign_state.get_roster_overrides(),
scene.campaign_state.get_inventory_snapshot(),
flags,
scene.campaign_state.get_joined_officers_snapshot()
):
failures.append("Tong Pass choice bridge %s could not load Ma Chao Counterstroke" % choice_id)
scene.free()
return
if scene.state.get_unit("zhang_he_ch34").is_empty():
failures.append("Tong Pass choice bridge %s should deploy Zhang He in Ma Chao Counterstroke" % choice_id)
elif not scene.state.is_required_deployment("zhang_he_ch34"):
failures.append("Tong Pass choice bridge %s should require Zhang He in Ma Chao Counterstroke" % choice_id)
var briefing_lines: Array = scene.state.get_briefing().get("lines", [])
if not _lines_contain_fragment(briefing_lines, expected_briefing_fragment):
failures.append("Tong Pass choice bridge %s should expose Ma Chao Counterstroke 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("Tong Pass choice bridge %s should expose Ma Chao Counterstroke 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("Tong Pass choice bridge %s should expose shop item %s" % [choice_id, expected_shop_item_id])
if shop_items.has(hidden_shop_item_id):
failures.append("Tong Pass 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: func _lines_contain_fragment(lines: Array, fragment: String) -> bool:
for line in lines: for line in lines:
if str(line).contains(fragment): if str(line).contains(fragment):
@@ -5004,6 +5113,121 @@ func _check_jiangling_rearguard_branch_camp_conversations(failures: Array[String
rushed_scene.free() rushed_scene.free()
func _check_tong_pass_branch_camp_conversations(failures: Array[String]) -> void:
var base_scene = _new_prebattle_scene_for(failures, "Tong Pass base camp", TONG_PASS_SCENARIO_ID, TONG_PASS_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(
TONG_PASS_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("Tong Pass base camp should reload with Zhang He joined")
else:
if base_scene._camp_conversation_by_id("tong_pass_vanguard_council").is_empty():
failures.append("Tong Pass should expose the vanguard council conversation")
if base_scene._camp_conversation_by_id("tong_pass_zhang_he_pass_road").is_empty():
failures.append("Tong Pass should expose Zhang He's pass road conversation")
if not base_scene._camp_conversation_by_id(TONG_PASS_JIANGLING_MEDICINE_CONVERSATION_ID).is_empty():
failures.append("Tong Pass Jiangling medicine should be hidden without stabilized Jiangling flag")
if not base_scene._camp_conversation_by_id(TONG_PASS_VANGUARD_RATIONS_CONVERSATION_ID).is_empty():
failures.append("Tong Pass vanguard rations should be hidden without mobilized vanguard flag")
var merchant: Dictionary = base_scene.state.get_shop_merchant()
if str(merchant.get("name", "")) != "Tong Pass Sutler":
failures.append("Tong Pass shop merchant name should be present")
var merchant_lines: Array = merchant.get("lines", [])
if merchant_lines.size() < 2:
failures.append("Tong Pass shop merchant should expose flavor lines")
if base_scene._format_talk_status_text(base_scene._camp_conversation_entries()) != "Camp conversations | 2 topics":
failures.append("Tong Pass base talk status should summarize two non-supply topics")
base_scene.free()
var stabilized_scene = _new_prebattle_scene_for(
failures,
"Tong Pass stabilized Jiangling camp",
TONG_PASS_SCENARIO_ID,
TONG_PASS_SCENARIO_PATH,
{"stabilized_jiangling_rearguard": true}
)
if stabilized_scene != null:
if not stabilized_scene.campaign_state.joined_officers.has("zhang_he"):
stabilized_scene.campaign_state.joined_officers.append("zhang_he")
if not stabilized_scene.state.load_battle(
TONG_PASS_SCENARIO_PATH,
stabilized_scene.campaign_state.get_roster_overrides(),
stabilized_scene.campaign_state.get_inventory_snapshot(),
stabilized_scene.campaign_state.get_flags_snapshot(),
stabilized_scene.campaign_state.get_joined_officers_snapshot()
):
failures.append("Tong Pass stabilized Jiangling camp should reload with Zhang He joined")
else:
var jiangling_medicine: Dictionary = stabilized_scene._camp_conversation_by_id(TONG_PASS_JIANGLING_MEDICINE_CONVERSATION_ID)
if jiangling_medicine.is_empty():
failures.append("stabilized Jiangling flag should expose Tong Pass medicine")
if not stabilized_scene._camp_conversation_by_id(TONG_PASS_VANGUARD_RATIONS_CONVERSATION_ID).is_empty():
failures.append("stabilized Jiangling flag should not expose Tong Pass vanguard rations")
if not jiangling_medicine.is_empty():
if stabilized_scene._format_talk_status_text(stabilized_scene._camp_conversation_entries()) != "Camp conversations | 3 topics | 1 supplies ready":
failures.append("Tong Pass stabilized Jiangling talk status should show one ready supply")
if not stabilized_scene._format_camp_conversation_button_text(jiangling_medicine).contains("보급 Panacea"):
failures.append("Tong Pass Jiangling medicine button should show Panacea supply")
var before_panacea := int(stabilized_scene.campaign_state.get_inventory_snapshot().get("panacea", 0))
stabilized_scene._apply_camp_conversation_effects(jiangling_medicine)
if int(stabilized_scene.campaign_state.get_inventory_snapshot().get("panacea", 0)) != before_panacea + 1:
failures.append("Tong Pass Jiangling medicine should add Panacea to campaign inventory")
if int(stabilized_scene.state.get_inventory_snapshot().get("panacea", 0)) != before_panacea + 1:
failures.append("Tong Pass Jiangling medicine should refresh battle Panacea inventory")
if not stabilized_scene.campaign_state.has_claimed_camp_conversation_effects(TONG_PASS_SCENARIO_ID, TONG_PASS_JIANGLING_MEDICINE_CONVERSATION_ID):
failures.append("Tong Pass Jiangling medicine claim should be saved")
if stabilized_scene._format_talk_status_text(stabilized_scene._camp_conversation_entries()) != "Camp conversations | 3 topics | 1 claimed":
failures.append("Tong Pass stabilized Jiangling talk status should show claimed supply after claim")
stabilized_scene.free()
var mobilized_scene = _new_prebattle_scene_for(
failures,
"Tong Pass mobilized vanguard camp",
TONG_PASS_SCENARIO_ID,
TONG_PASS_SCENARIO_PATH,
{"mobilized_tong_pass_vanguard": true}
)
if mobilized_scene != null:
if not mobilized_scene.campaign_state.joined_officers.has("zhang_he"):
mobilized_scene.campaign_state.joined_officers.append("zhang_he")
if not mobilized_scene.state.load_battle(
TONG_PASS_SCENARIO_PATH,
mobilized_scene.campaign_state.get_roster_overrides(),
mobilized_scene.campaign_state.get_inventory_snapshot(),
mobilized_scene.campaign_state.get_flags_snapshot(),
mobilized_scene.campaign_state.get_joined_officers_snapshot()
):
failures.append("Tong Pass mobilized vanguard camp should reload with Zhang He joined")
else:
var vanguard_rations: Dictionary = mobilized_scene._camp_conversation_by_id(TONG_PASS_VANGUARD_RATIONS_CONVERSATION_ID)
if vanguard_rations.is_empty():
failures.append("mobilized Tong Pass vanguard flag should expose Tong Pass rations")
if not mobilized_scene._camp_conversation_by_id(TONG_PASS_JIANGLING_MEDICINE_CONVERSATION_ID).is_empty():
failures.append("mobilized Tong Pass vanguard flag should not expose Tong Pass medicine")
if not vanguard_rations.is_empty():
if mobilized_scene._format_talk_status_text(mobilized_scene._camp_conversation_entries()) != "Camp conversations | 3 topics | 1 supplies ready":
failures.append("Tong Pass mobilized vanguard talk status should show one ready supply")
if not mobilized_scene._format_camp_conversation_button_text(vanguard_rations).contains("보급 Bean"):
failures.append("Tong Pass vanguard rations button should show Bean supply")
var before_bean := int(mobilized_scene.campaign_state.get_inventory_snapshot().get("bean", 0))
mobilized_scene._apply_camp_conversation_effects(vanguard_rations)
if int(mobilized_scene.campaign_state.get_inventory_snapshot().get("bean", 0)) != before_bean + 1:
failures.append("Tong Pass vanguard rations should add Bean to campaign inventory")
if int(mobilized_scene.state.get_inventory_snapshot().get("bean", 0)) != before_bean + 1:
failures.append("Tong Pass vanguard rations should refresh battle Bean inventory")
if not mobilized_scene.campaign_state.has_claimed_camp_conversation_effects(TONG_PASS_SCENARIO_ID, TONG_PASS_VANGUARD_RATIONS_CONVERSATION_ID):
failures.append("Tong Pass vanguard rations claim should be saved")
if mobilized_scene._format_talk_status_text(mobilized_scene._camp_conversation_entries()) != "Camp conversations | 3 topics | 1 claimed":
failures.append("Tong Pass mobilized vanguard talk status should show claimed supply after claim")
mobilized_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

@@ -2226,6 +2226,17 @@ func _check_battle_visual_data(failures: Array[String]) -> void:
failures.append("could not load Tong Pass Vanguard data") failures.append("could not load Tong Pass Vanguard data")
else: else:
_check_shop_items_unique(failures, tong_pass_state, "033 base") _check_shop_items_unique(failures, tong_pass_state, "033 base")
var tong_pass_conversations: Array = tong_pass_state.get_briefing().get("camp_conversations", [])
if tong_pass_conversations.size() != 2:
failures.append("033 base briefing should expose exactly two camp conversations")
else:
_check_camp_conversation(failures, _find_camp_conversation(tong_pass_conversations, "tong_pass_vanguard_council"), "tong_pass_vanguard_council", "topic", "")
_check_camp_conversation(failures, _find_camp_conversation(tong_pass_conversations, "tong_pass_zhang_he_pass_road"), "tong_pass_zhang_he_pass_road", "officer", "zhang_he")
var tong_pass_merchant := tong_pass_state.get_shop_merchant()
if str(tong_pass_merchant.get("name", "")) != "Tong Pass Sutler":
failures.append("033 shop should expose Tong Pass merchant name")
if (tong_pass_merchant.get("lines", []) as Array).size() < 2:
failures.append("033 shop should expose merchant flavor lines")
if tong_pass_state.get_unit("zhang_he_ch33").is_empty() or not tong_pass_state.is_required_deployment("zhang_he_ch33"): 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") 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, "war_drum", false, "033 base")
@@ -2236,6 +2247,19 @@ func _check_battle_visual_data(failures: Array[String]) -> void:
failures.append("could not load Tong Pass stabilized Jiangling data") failures.append("could not load Tong Pass stabilized Jiangling data")
else: else:
_check_shop_items_unique(failures, tong_pass_stabilized_state, "033 stabilized Jiangling rearguard") _check_shop_items_unique(failures, tong_pass_stabilized_state, "033 stabilized Jiangling rearguard")
var jiangling_supply_medicine: Dictionary = _find_camp_conversation(
tong_pass_stabilized_state.get_briefing().get("camp_conversations", []),
"tong_pass_jiangling_supply_medicine"
)
if jiangling_supply_medicine.is_empty():
failures.append("033 stabilized Jiangling rearguard should expose Jiangling supply medicine")
else:
_check_camp_conversation_effect(failures, jiangling_supply_medicine, "panacea", 1)
if not _find_camp_conversation(
tong_pass_stabilized_state.get_briefing().get("camp_conversations", []),
"tong_pass_vanguard_rations"
).is_empty():
failures.append("033 stabilized Jiangling rearguard should not expose vanguard rations")
_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, "imperial_seal", true, "033 stabilized Jiangling rearguard")
_check_shop_item_visibility(failures, tong_pass_stabilized_state, "war_drum", false, "033 stabilized Jiangling rearguard") _check_shop_item_visibility(failures, tong_pass_stabilized_state, "war_drum", false, "033 stabilized Jiangling rearguard")
@@ -2244,6 +2268,19 @@ func _check_battle_visual_data(failures: Array[String]) -> void:
failures.append("could not load Tong Pass mobilized vanguard data") failures.append("could not load Tong Pass mobilized vanguard data")
else: else:
_check_shop_items_unique(failures, tong_pass_mobilized_state, "033 mobilized Tong Pass vanguard") _check_shop_items_unique(failures, tong_pass_mobilized_state, "033 mobilized Tong Pass vanguard")
var vanguard_rations: Dictionary = _find_camp_conversation(
tong_pass_mobilized_state.get_briefing().get("camp_conversations", []),
"tong_pass_vanguard_rations"
)
if vanguard_rations.is_empty():
failures.append("033 mobilized Tong Pass vanguard should expose vanguard rations")
else:
_check_camp_conversation_effect(failures, vanguard_rations, "bean", 1)
if not _find_camp_conversation(
tong_pass_mobilized_state.get_briefing().get("camp_conversations", []),
"tong_pass_jiangling_supply_medicine"
).is_empty():
failures.append("033 mobilized Tong Pass vanguard should not expose Jiangling supply medicine")
_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, "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") _check_shop_item_visibility(failures, tong_pass_mobilized_state, "imperial_seal", false, "033 mobilized Tong Pass vanguard")
@@ -2254,6 +2291,50 @@ func _check_battle_visual_data(failures: Array[String]) -> void:
_check_shop_items_unique(failures, tong_pass_old_flags_state, "033 old Jiangling setup flags") _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, "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") _check_shop_item_visibility(failures, tong_pass_old_flags_state, "imperial_seal", false, "033 old Jiangling setup flags")
if not _find_camp_conversation(
tong_pass_old_flags_state.get_briefing().get("camp_conversations", []),
"tong_pass_jiangling_supply_medicine"
).is_empty():
failures.append("033 old Jiangling setup flags should not expose Jiangling supply medicine")
if not _find_camp_conversation(
tong_pass_old_flags_state.get_briefing().get("camp_conversations", []),
"tong_pass_vanguard_rations"
).is_empty():
failures.append("033 old Jiangling setup flags should not expose vanguard rations")
var ma_chao_counterstroke_state = BattleStateScript.new()
if not ma_chao_counterstroke_state.load_battle("res://data/scenarios/034_ma_chao_counterstroke.json", {}, {}, {}, ["zhang_he"]):
failures.append("could not load Ma Chao Counterstroke data")
else:
_check_shop_items_unique(failures, ma_chao_counterstroke_state, "034 base")
if ma_chao_counterstroke_state.get_unit("zhang_he_ch34").is_empty() or not ma_chao_counterstroke_state.is_required_deployment("zhang_he_ch34"):
failures.append("034 should deploy Zhang He as a required officer")
_check_shop_item_visibility(failures, ma_chao_counterstroke_state, "war_drum", false, "034 base")
_check_shop_item_visibility(failures, ma_chao_counterstroke_state, "imperial_seal", false, "034 base")
var ma_chao_fortified_state = BattleStateScript.new()
if not ma_chao_fortified_state.load_battle("res://data/scenarios/034_ma_chao_counterstroke.json", {}, {}, {"fortified_tong_pass": true}, ["zhang_he"]):
failures.append("could not load Ma Chao Counterstroke fortified Tong Pass data")
else:
_check_shop_items_unique(failures, ma_chao_fortified_state, "034 fortified Tong Pass")
_check_shop_item_visibility(failures, ma_chao_fortified_state, "imperial_seal", true, "034 fortified Tong Pass")
_check_shop_item_visibility(failures, ma_chao_fortified_state, "war_drum", false, "034 fortified Tong Pass")
var ma_chao_pressed_state = BattleStateScript.new()
if not ma_chao_pressed_state.load_battle("res://data/scenarios/034_ma_chao_counterstroke.json", {}, {}, {"pressed_ma_chao_vanguard": true}, ["zhang_he"]):
failures.append("could not load Ma Chao Counterstroke pressed vanguard data")
else:
_check_shop_items_unique(failures, ma_chao_pressed_state, "034 pressed Ma Chao vanguard")
_check_shop_item_visibility(failures, ma_chao_pressed_state, "war_drum", true, "034 pressed Ma Chao vanguard")
_check_shop_item_visibility(failures, ma_chao_pressed_state, "imperial_seal", false, "034 pressed Ma Chao vanguard")
var ma_chao_old_flags_state = BattleStateScript.new()
if not ma_chao_old_flags_state.load_battle("res://data/scenarios/034_ma_chao_counterstroke.json", {}, {}, {"stabilized_jiangling_rearguard": true, "mobilized_tong_pass_vanguard": true}, ["zhang_he"]):
failures.append("could not load Ma Chao Counterstroke old Tong Pass setup flag data")
else:
_check_shop_items_unique(failures, ma_chao_old_flags_state, "034 old Tong Pass setup flags")
_check_shop_item_visibility(failures, ma_chao_old_flags_state, "war_drum", false, "034 old Tong Pass setup flags")
_check_shop_item_visibility(failures, ma_chao_old_flags_state, "imperial_seal", false, "034 old Tong Pass 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)