extends Node const SCREEN := preload("res://scripts/planets/surface_screen.gd") func _ready() -> void: if not InputMap.has_action("ship_mini_boost"): InputMap.add_action("ship_mini_boost") GameState.start_new_run() GameState.system_level = 7 var captain := GameState.captain for gear in captain.gear_items: gear.level = 12 var progress: Resource = captain.expedition var profile := {"id":"single-visit-ui","name":"Asteria","seed":8428159,"difficulty":0.4,"landing_damage":5,"oxygen":55,"temperature":55,"flora":10,"easy":false,"system_level":7} assert(progress.begin_visit(profile)) var layer := CanvasLayer.new() add_child(layer) var surface := Control.new() surface.set_script(SCREEN) surface.captain = captain surface.progress = progress layer.add_child(surface) surface.set_process(false) surface.set_physics_process(false) # Keep optional encounter popups away from the ordinary POI fixture. for event in surface.world.data.events: event.position = Vector2(10000,10000) var poi: Dictionary = surface.world.data.pois[0] assert(poi.kind == "warehouse") surface.lander.position = poi.position surface._previous_position = poi.position surface.camera.position = poi.position surface.camera.reset_smoothing() surface.world.refresh_pois(poi.position) assert(surface.world._poi_labels[poi.id].text.contains("[E]")) var key := InputEventKey.new() key.pressed = true key.keycode = KEY_E poi.bonus_available = false var hp: float = progress.lander_hp var permanent := captain.minerals.duplicate() surface._input(key) assert(surface._dialog.visible and not poi.complete and progress.cargo.is_empty()) assert(progress.lander_hp == hp,"Opening the forecast does not charge health") var preview_labels := "" for label in surface._choices.find_children("*","Label",true,false): preview_labels += label.text+"\n" assert(preview_labels.contains("PRZEWIDYWANA NAGRODA") and preview_labels.contains("Uszkodzenia lądownika")) assert(not preview_labels.to_lower().contains("zagro") and not preview_labels.contains("TLEN") and not preview_labels.contains("×")) assert(surface._threat.text.is_empty() and not surface._threat.visible) var plan := preload("res://scripts/planets/poi_rules.gd").preview(profile,captain,poi,progress.visit_seed) if DisplayServer.get_name() != "headless": for frame in 12: await get_tree().process_frame await RenderingServer.frame_post_draw assert(get_viewport().get_texture().get_image().save_png("res://artifacts/planet_poi_forecast.png") == OK) surface._dialog.hide() surface._input(key) assert(progress.lander_hp == hp and progress.cargo.is_empty(),"Reopening forecast is free") surface._choices.get_node("ExploreButton").pressed.emit() assert(poi.complete and progress.cargo == plan.materials) assert(progress.lander_hp < hp,"Confirmed exploration wears down the lander") assert(captain.minerals == permanent,"Loot waits in expedition cargo until safe return") var labels := "" for label in surface._choices.find_children("*","Label",true,false): labels += label.text+"\n" assert(labels.contains("ZDOBYTO") and not labels.contains("ETAP") and not labels.contains("Powodzenie")) var snapshot: Dictionary = progress.cargo.duplicate() if not DisplayServer.get_name() == "headless": for frame in 12: await get_tree().process_frame await RenderingServer.frame_post_draw assert(get_viewport().get_texture().get_image().save_png("res://artifacts/single_visit_planet_poi.png") == OK) surface._input(key) assert(not surface._dialog.visible and progress.cargo == snapshot) surface._input(key) assert(not surface._dialog.visible and progress.cargo == snapshot,"Repeated E cannot reclaim visited POIs") poi.bonus_available = true surface._input(key) assert(surface._dialog.visible and surface._choices.has_node("BonusExploreButton")) var before_bonus: Dictionary = progress.cargo.duplicate() var bonus_hp: float = progress.lander_hp if DisplayServer.get_name() != "headless": await get_tree().process_frame await RenderingServer.frame_post_draw get_viewport().get_texture().get_image().save_png("res://artifacts/planet_poi_bonus.png") surface._choices.get_node("BonusExploreButton").pressed.emit() assert(poi.bonus_complete and progress.cargo != before_bonus and progress.lander_hp < bonus_hp) snapshot = progress.cargo.duplicate() surface._dialog.hide() # Services keep their own interfaces and do not become auto-collected loot. for kind in ["time_engineer","hermit","crew","deep_deposit"]: var special := {"kind":kind,"complete":false} surface._poi = special surface._show_poi() assert(surface._dialog.visible and not special.complete) assert(progress.cargo == snapshot) surface._dialog.hide() var encounter := {"kind":"trader","seed":42,"complete":false} surface._show_event(encounter) assert(surface._dialog.visible and not encounter.complete) assert(surface._poi.is_empty(),"Previous result must not hijack event interaction") surface._input(key) assert(surface._dialog.visible) # A confirmed dangerous action must reach the existing destruction/return flow. progress.lander_hp = 1 surface._poi = {"id":999,"kind":"deposit","position":surface.lander.position,"complete":true,"bonus_available":true,"bonus_complete":false} surface._show_poi() var death_labels := "" for label in surface._choices.find_children("*","Label",true,false): death_labels += label.text assert(death_labels.contains("Lądownik może zostać zniszczony")) var ended := [false] var owned_credits: int = captain.credits var owned_minerals: Dictionary = captain.minerals.duplicate() surface.finished.connect(func(success: bool) -> void: assert(not success) progress.finish_visit(captain,success) ended[0] = true) surface._choices.get_node("BonusExploreButton").pressed.emit() assert(surface._ending and progress.lander_hp == 0 and not surface.lander.visible) await get_tree().create_timer(5.6).timeout assert(ended[0] and not progress.active and progress.cargo.is_empty()) assert(captain.credits == owned_credits and captain.minerals == owned_minerals) print("SINGLE_VISIT_SURFACE_TEST: PASS (E opens a read-only reward/damage forecast; confirmation grants loot and damages hull, no stages, close/repeat safety, pending cargo, engineers/cartographer/crew/deposit and question-mark events retained)") get_tree().quit()