Guide the fleet to the nearest unconquered scan target

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019AJMdB7iuHuLFZM1aBu3GD
This commit is contained in:
Loïc Wisniewski 2026-09-04 21:46:24 +02:00
commit 10d19a369b
9 changed files with 311 additions and 38 deletions

View file

@ -1,4 +1,4 @@
[gd_scene load_steps=48 format=3]
[gd_scene load_steps=49 format=3]
[ext_resource type="PackedScene" path="res://ui/menus/BuildMenu.tscn" id="menu_build"]
[ext_resource type="PackedScene" path="res://ui/menus/HangarMenu.tscn" id="menu_hangar"]
[ext_resource type="PackedScene" path="res://ui/menus/LabMenu.tscn" id="menu_lab"]
@ -10,6 +10,7 @@
[ext_resource type="PackedScene" path="res://ui/menus/SkillMenu.tscn" id="menu_skill"]
[ext_resource type="PackedScene" path="res://ui/menus/DevMenu.tscn" id="menu_dev"]
[ext_resource type="PackedScene" path="res://ui/menus/ScannerMenu.tscn" id="menu_scanner"]
[ext_resource type="PackedScene" path="res://ui/ScannerGuidance.tscn" id="scanner_guidance"]
[ext_resource type="Script" path="res://world/Starfield.gd" id="1"]
@ -296,6 +297,8 @@ offset_top = 188.0
offset_bottom = 252.0
script = ExtResource("32")
[node name="ScannerGuidance" parent="UI" instance=ExtResource("scanner_guidance")]
[node name="QuestButton" type="Control" parent="UI"]
anchor_left = 1.0
anchor_right = 1.0

View file

@ -12,6 +12,7 @@ const WORLD_TO_LOCAL: float = 0.04
const EXTRACTOR_BADGE_COLOR: Color = Color(1.0, 0.85, 0.3)
const EXTRACTOR_BADGE_OFFSET: Vector2 = Vector2(8.0, -8.0)
const EXTRACTOR_BADGE_RADIUS: float = 5.0
const SCANNER_TARGET_COLOR: Color = Color(0.3, 0.95, 1.0)
@onready var tracker: Node2D = get_node("../../../ExplorationTracker")
@onready var fleet: Node2D = get_node("../../../Fleet")
@ -53,6 +54,17 @@ func chunk_has_extractor_badge(chunk: Vector2i) -> bool:
return GameState.has_extractor_at(WorldGen.planet_data_at_chunk(chunk).planet_id)
func scanner_target_marker() -> Dictionary:
var target: Dictionary = GameState.active_scanner_target()
if target.is_empty():
return {}
return {
"position": Vector2(target.world_position) * WORLD_TO_LOCAL,
"planet_id": String(target.planet_id),
"definition_id": String(target.definition_id),
}
func _regular_polygon(center: Vector2, radius: float, sides: int, phase: float = 0.0) -> PackedVector2Array:
var pts: PackedVector2Array = PackedVector2Array()
for i in range(sides):
@ -103,6 +115,18 @@ func _draw() -> void:
for marker in building_markers():
_draw_marker_polygon(_regular_polygon(marker.position, marker.radius, marker.sides, marker.phase), marker.color)
# A scan is an intentional destination, distinct from passive exploration.
# Draw its reticle independently of the explored-chunk pass so the point is
# guaranteed to remain visible even when it lies beyond travelled space.
var scan_marker: Dictionary = scanner_target_marker()
if not scan_marker.is_empty():
var target_position := Vector2(scan_marker.position)
draw_arc(target_position, 11.0, 0.0, TAU, 24,
SCANNER_TARGET_COLOR, 2.5, true)
for direction in [Vector2.LEFT, Vector2.RIGHT, Vector2.UP, Vector2.DOWN]:
draw_line(target_position + direction * 13.0,
target_position + direction * 19.0, SCANNER_TARGET_COLOR, 2.0, true)
var fleet_local: Vector2 = fleet.get_centroid() * WORLD_TO_LOCAL
var marker_points: PackedVector2Array = PackedVector2Array([
fleet_local + Vector2(0, -10),