extends SceneTree # Headless gameplay test: run with # godot --headless -s res://tests/test_pickup_feedback.gd # Forgejo #79: collecting used to be silent - a rock vanished and a number in # the corner of the screen changed. Which number, and by how much, was left # for the player to notice. A "+N" in the resource's own colour now rises # where the pickup happened. # # Covers: # A. collecting ore raises a marker at the pickup point, carrying the right # resource and amount # B. it is built from the resource catalog's own glyph, so a material added # later cannot end up with one mark in the HUD and another in the world # C. it clears itself up rather than accumulating one node per pickup # D. a pickup that is REFUSED - a full hold - raises nothing, so the marker # never claims something the player did not get var game_state: Node var main: Node var fleet: Node var stage: int = 0 var elapsed: float = 0.0 func _initialize() -> void: game_state = root.get_node("GameState") game_state.buildings.clear() game_state.extractors.clear() game_state.reset_progression() main = load("res://Main.tscn").instantiate() root.add_child(main) current_scene = main fleet = main.get_node("Fleet") const PICKUP_VFX = preload("res://ResourcePickupVFX.gd") func _markers() -> Array: var found: Array = [] for node in root.get_children(): if node.get_script() == PICKUP_VFX: found.append(node) return found func _drop_rock_on_fleet() -> Node2D: var rock: Node2D = load("res://Rock.tscn").instantiate() rock.build_shape(7) rock.position = fleet.ships[0].global_position main.add_child(rock) return rock func _process(delta: float) -> bool: elapsed += delta match stage: 0: if elapsed < 0.3: return false main.get_node("EnemySpawner").set_process(false) main.get_node("AsteroidField").set_process(false) for hazard in get_nodes_in_group("asteroids") + get_nodes_in_group("rocks"): if is_instance_valid(hazard): hazard.free() fleet.spawn_ships(1, Vector2.ZERO, PackedStringArray([GameState.VESSEL_INTERCEPTOR])) game_state.fleet_inventory.set_amount(GameState.RESOURCE_ORE, 0) if not _markers().is_empty(): return _fail("a pickup marker existed before anything was collected") _drop_rock_on_fleet() stage = 1 elapsed = 0.0 return false 1: if elapsed < 0.4: return false # --- A. one marker, right resource, right amount -------------- var markers: Array = _markers() if markers.size() != 1: return _fail("collecting one rock raised %d markers" % markers.size()) var marker: Node2D = markers[0] if game_state.fleet_resource(GameState.RESOURCE_ORE) <= 0: return _fail("the rock was not actually collected, so the marker is reporting a pickup that did not happen") if marker.global_position.distance_to(fleet.ships[0].global_position) > 120.0: return _fail("the marker appeared %.0f away from where the pickup happened" \ % marker.global_position.distance_to(fleet.ships[0].global_position)) # --- B. built from the catalog's own glyph -------------------- var definitions: Script = load("res://ResourceDefinitions.gd") var ore: Resource = definitions.get_definition(GameState.RESOURCE_ORE) if not marker.colour.is_equal_approx(ore.color): return _fail("the marker is %s, but ore is %s" % [marker.colour, ore.color]) var glyph_scripts: Array = [] for child in marker.get_children(): glyph_scripts.append(child.get_script()) var probe: Node = ore.glyph_scene.instantiate() var expected: Script = probe.get_script() probe.free() if expected not in glyph_scripts: return _fail("the marker does not use the ore glyph the resource catalog defines") print("collecting ore raised one marker at the pickup point, in ore's own colour and glyph") stage = 2 elapsed = 0.0 return false 2: # --- C. it cleans itself up ----------------------------------- if elapsed < 1.5: return false if not _markers().is_empty(): return _fail("%d marker(s) still on screen 1.5s later - they accumulate" % _markers().size()) print("marker cleared itself up") # --- D. a refused pickup says nothing ------------------------- # Hold filled to capacity, so collect_cargo takes nothing. var capacity: int = game_state.fleet_inventory.total_capacity if capacity < 0: return _fail("the fleet hold has no capacity limit, so a refused pickup cannot be staged") game_state.fleet_inventory.set_amount(GameState.RESOURCE_ORE, capacity) _drop_rock_on_fleet() stage = 3 elapsed = 0.0 return false 3: if elapsed < 0.4: return false if not _markers().is_empty(): return _fail("a full hold refused the rock but a marker claimed it was collected") print("a pickup refused by a full hold raises no marker") print("TEST_PICKUP_FEEDBACK: PASS") quit(0) return true return false func _fail(message: String) -> bool: print("TEST_PICKUP_FEEDBACK: FAIL (%s)" % message) quit(1) return true