From 40fcfb61d86f2ac183542b6b68bcf57c7b38fac6 Mon Sep 17 00:00:00 2001 From: Wickedness Date: Thu, 18 Jun 2026 15:03:06 +0900 Subject: [PATCH] Add Wuchao depot supply pickup --- README.md | 2 +- data/scenarios/013_wuchao_raid.json | 8 ++++ docs/ROADMAP.md | 2 +- tools/smoke_event_item_pickups.gd | 71 +++++++++++++++++++++++++++++ 4 files changed, 81 insertions(+), 2 deletions(-) create mode 100644 tools/smoke_event_item_pickups.gd diff --git a/README.md b/README.md index e78ff55..c0da69f 100644 --- a/README.md +++ b/README.md @@ -39,7 +39,7 @@ Godot 4 tactical RPG prototype inspired by classic turn-based Romance of the Thr - Xiapi victory recruits Guo Jia, and White Horse starts the northern campaign with a decoy-line battle. - Yan Ford consumes the White Horse branch flags and adds Wen Chou's countercharge before Guandu. - Guandu consumes the Yan Ford branch flags and adds Yuan Shao's main assault. -- Wuchao consumes the Guandu branch flags and adds a depot-burning raid. +- Wuchao consumes the Guandu branch flags and adds a depot-burning raid with seized in-battle supplies. - Cangting consumes the Wuchao branch flags, breaks Yuan Shao's rear guard, and recruits Zhang He. - Ye consumes the Cangting branch flags and lets Zhang He deploy against the Yuan heirs. - Ye Siege consumes the Ye campaign branch flags and stages an inner-gate breach. diff --git a/data/scenarios/013_wuchao_raid.json b/data/scenarios/013_wuchao_raid.json index 1979c1d..f93ef9f 100644 --- a/data/scenarios/013_wuchao_raid.json +++ b/data/scenarios/013_wuchao_raid.json @@ -270,6 +270,14 @@ { "speaker": "Guo Jia", "text": "Now the raid becomes an escape through panic. Keep formation." } ] }, + { "type": "log", "text": "Usable Wuchao stores are seized before the granaries burn." }, + { + "type": "grant_items", + "items": [ + { "item_id": "bean", "count": 2 }, + "wine" + ] + }, { "type": "spawn_deployments", "deployments": [ diff --git a/docs/ROADMAP.md b/docs/ROADMAP.md index 5790806..de6d607 100644 --- a/docs/ROADMAP.md +++ b/docs/ROADMAP.md @@ -75,7 +75,7 @@ - Tenth-scenario content exists with White Horse relief, Guo Jia as a joined strategist, Yan Liang's vanguard, and 009 branch reactions. - Eleventh-scenario content exists with Yan Ford pursuit, Wen Chou's countercharge, and 010 branch reactions. - Twelfth-scenario content exists with Guandu's main assault, Yuan Shao's army, and 011 branch reactions. -- Thirteenth-scenario content exists with Wuchao depot raid, a burn-and-clear objective, and 012 branch reactions. +- Thirteenth-scenario content exists with Wuchao depot raid, a burn-and-clear objective, seized in-battle supplies, and 012 branch reactions. - Fourteenth-scenario content exists with Cangting pursuit, Zhang He recruitment, and 013 branch reactions. - Fifteenth-scenario content exists with Ye outer defense, Zhang He as a deployable officer, and 014 branch reactions. - Sixteenth-scenario content exists with Ye inner siege, Zhang He deployment, and 015 branch reactions. diff --git a/tools/smoke_event_item_pickups.gd b/tools/smoke_event_item_pickups.gd new file mode 100644 index 0000000..bccd772 --- /dev/null +++ b/tools/smoke_event_item_pickups.gd @@ -0,0 +1,71 @@ +extends SceneTree + +const BattleStateScript := preload("res://scripts/core/battle_state.gd") + + +func _init() -> void: + var failures: Array[String] = [] + _check_wuchao_depot_pickup(failures) + + if failures.is_empty(): + print("event item pickups smoke ok") + quit(0) + return + + for failure in failures: + push_error(failure) + quit(1) + + +func _check_wuchao_depot_pickup(failures: Array[String]) -> void: + var state = BattleStateScript.new() + if not state.load_battle("res://data/scenarios/013_wuchao_raid.json"): + failures.append("could not load Wuchao raid") + return + + var logs: Array[String] = [] + var feedback: Array[String] = [] + state.log_added.connect(func(message: String) -> void: + logs.append(message) + ) + state.combat_feedback_requested.connect(func(unit_id: String, text: String, kind: String) -> void: + feedback.append("%s|%s|%s" % [unit_id, text, kind]) + ) + + var cao_cao: Dictionary = state.get_unit("cao_cao_ch13") + if cao_cao.is_empty(): + failures.append("missing Cao Cao deployment in Wuchao raid") + return + + var before_inventory := state.get_inventory_snapshot() + cao_cao["pos"] = Vector2i(14, 4) + state._run_events("unit_reaches_tile", "player", 1, cao_cao) + + var after_inventory := state.get_inventory_snapshot() + if int(after_inventory.get("bean", 0)) != int(before_inventory.get("bean", 0)) + 2: + failures.append("Wuchao depot should grant Bean x2: before %s after %s" % [str(before_inventory), str(after_inventory)]) + if int(after_inventory.get("wine", 0)) != int(before_inventory.get("wine", 0)) + 1: + failures.append("Wuchao depot should grant Wine x1: before %s after %s" % [str(before_inventory), str(after_inventory)]) + if not logs.has("Usable Wuchao stores are seized before the granaries burn."): + failures.append("Wuchao depot pickup log missing") + if not logs.has("Received Bean x2."): + failures.append("Bean pickup receipt log missing") + if not logs.has("Received Wine."): + failures.append("Wine pickup receipt log missing") + if not feedback.has("cao_cao_ch13|+Bean|item"): + failures.append("Bean pickup feedback missing") + if not feedback.has("cao_cao_ch13|+Wine|item"): + failures.append("Wine pickup feedback missing") + if not state.fired_event_ids.has("wuchao_depot_burned"): + failures.append("Wuchao depot event should be marked fired") + + logs.clear() + feedback.clear() + state._run_events("unit_reaches_tile", "player", 1, cao_cao) + var repeat_inventory := state.get_inventory_snapshot() + if int(repeat_inventory.get("bean", 0)) != int(after_inventory.get("bean", 0)): + failures.append("Wuchao depot Bean pickup repeated despite once flag") + if int(repeat_inventory.get("wine", 0)) != int(after_inventory.get("wine", 0)): + failures.append("Wuchao depot Wine pickup repeated despite once flag") + if not logs.is_empty() or not feedback.is_empty(): + failures.append("Wuchao depot pickup should not repeat logs or feedback")