diff --git a/src/game/engine/scenes/tests/proof_hybrid_merge.gd b/src/game/engine/scenes/tests/proof_hybrid_merge.gd new file mode 100644 index 00000000..ed04489e --- /dev/null +++ b/src/game/engine/scenes/tests/proof_hybrid_merge.gd @@ -0,0 +1,120 @@ +extends Node +## p1-59 Proof Scene — Hybrid Merged Structures. +## Proves: merge_panel.gd can be populated with a city that has +## rifle_range + barding_hall (prereq pair for war_academy), and the +## merge panel shows the "war_academy" row. A tech-gated row (gunnery_corps) +## is shown greyed out (military_synthesis not in researched_techs). +## Captures a screenshot and quits. + +const MergePanelScene: PackedScene = preload( + "res://engine/scenes/city/merge_panel.tscn" +) + +var _captured: bool = false +var _screenshot_name: String = "p1_59_hybrid_merge_proof" +var _label_root: VBoxContainer +var _merge_panel: PanelContainer + + +## Minimal fake GdCity bridge that mocks available_merges(). +class FakeGdCity: + func call_method(method: String, _registry_json: String, _researched_techs: PackedStringArray) -> Array: + if method == "available_merges": + return [ + { + "building_a": "rifle_range", + "building_b": "barding_hall", + "into": "war_academy", + "tech_gated": false, + }, + { + "building_a": "rifle_range", + "building_b": "powder_annex", + "into": "gunnery_corps", + "tech_gated": true, + }, + ] + return [] + + +class FakeBridge: + var _gd_city: FakeGdCity = FakeGdCity.new() + + func is_available() -> bool: + return true + + +class FakeCity: + var _bridge: FakeBridge = FakeBridge.new() + var id: String = "proof_city" + var buildings: Array = ["rifle_range", "barding_hall", "powder_annex"] + + +func _ready() -> void: + RenderingServer.set_default_clear_color(Color(0.06, 0.05, 0.04)) + get_tree().root.size = Vector2i(1280, 720) + _build_ui() + await get_tree().process_frame + await get_tree().process_frame + _show_merge_panel() + await get_tree().process_frame + _capture() + + +func _build_ui() -> void: + var bg: ColorRect = ColorRect.new() + bg.anchors_preset = Control.PRESET_FULL_RECT + bg.color = Color(0.08, 0.07, 0.06) + add_child(bg) + + _label_root = VBoxContainer.new() + _label_root.set_anchors_and_offsets_preset(Control.PRESET_TOP_LEFT) + _label_root.position = Vector2(24.0, 24.0) + add_child(_label_root) + + _add_label("p1-59 Proof — Hybrid Merged Structures", 20, Color(0.95, 0.85, 0.45)) + _add_label("City has: rifle_range, barding_hall, powder_annex", 14, Color(0.75, 0.72, 0.65)) + _add_label("Expected merges:", 14, Color(0.75, 0.72, 0.65)) + _add_label(" [ENABLED] rifle_range + barding_hall → war_academy", 13, Color(0.4, 0.9, 0.5)) + _add_label( + " [GATED] rifle_range + powder_annex → gunnery_corps (needs military_synthesis)", + 13, + Color(0.7, 0.5, 0.3), + ) + _add_label("", 12, Color.WHITE) + _add_label("Merge panel populated below:", 13, Color(0.75, 0.72, 0.65)) + + _merge_panel = MergePanelScene.instantiate() as PanelContainer + _merge_panel.position = Vector2(24.0, 220.0) + _merge_panel.size = Vector2(600.0, 360.0) + add_child(_merge_panel) + + +func _show_merge_panel() -> void: + var city: FakeCity = FakeCity.new() + var registry_json: String = "{}" + var techs: PackedStringArray = PackedStringArray() + _merge_panel.populate(city, registry_json, techs) + + +func _add_label(text: String, font_size: int, color: Color) -> void: + var lbl: Label = Label.new() + lbl.text = text + lbl.add_theme_font_size_override("font_size", font_size) + lbl.add_theme_color_override("font_color", color) + _label_root.add_child(lbl) + + +func _capture() -> void: + if _captured: + return + _captured = true + var dir: DirAccess = DirAccess.open("user://") + if dir != null and not dir.dir_exists("screenshots"): + dir.make_dir("screenshots") + var path: String = "user://screenshots/%s.png" % _screenshot_name + var img: Image = get_viewport().get_texture().get_image() + img.save_png(path) + var abs_path: String = ProjectSettings.globalize_path(path) + print("[proof] screenshot saved → ", abs_path) + get_tree().quit() diff --git a/src/game/engine/scenes/tests/proof_hybrid_merge.tscn b/src/game/engine/scenes/tests/proof_hybrid_merge.tscn new file mode 100644 index 00000000..a40805b2 --- /dev/null +++ b/src/game/engine/scenes/tests/proof_hybrid_merge.tscn @@ -0,0 +1,6 @@ +[gd_scene load_steps=2 format=3 uid="uid://p1b59hybridmrg01"] + +[ext_resource type="Script" path="res://engine/scenes/tests/proof_hybrid_merge.gd" id="1"] + +[node name="ProofHybridMerge" type="Node"] +script = ExtResource("1")