From 6b1f1927cdc979adbcb445d6106b7ff25973580d Mon Sep 17 00:00:00 2001 From: Justin Spahr-Summers Date: Sun, 7 Jul 2024 16:41:55 +0100 Subject: [PATCH] Dumb, basically broken, trader AI --- actors/trader.gd | 62 +++++++++++++++++++++++++++++ actors/trader.tscn | 6 +++ galaxy/star_systems/scenes/sol.tscn | 47 +++++++++++++++++++++- planets/planet.tscn | 2 +- 4 files changed, 115 insertions(+), 2 deletions(-) create mode 100644 actors/trader.gd create mode 100644 actors/trader.tscn diff --git a/actors/trader.gd b/actors/trader.gd new file mode 100644 index 00000000..467febab --- /dev/null +++ b/actors/trader.gd @@ -0,0 +1,62 @@ +extends Node3D +class_name Trader + +## AI for a ship that behaves like a trader, avoiding combat. +## +## [b]This script expects the parent node to be a [Ship].[/b] + +# TODO: Deduplicate code with Pirate class. + +## For thrusting, the tolerance (in degrees) for being slightly off-rotated. +@export var direction_tolerance_deg: float = 10.0 + +## The tolerance (in m) for hitting the destination point, before selecting a new one. +@export var destination_tolerance: float = 1.0 + +@onready var _ship := self.get_parent() as Ship +var _direction_tolerance_rad: float +var _destination: Node3D = null + +func _ready() -> void: + self._direction_tolerance_rad = deg_to_rad(self.direction_tolerance_deg) + +func _select_new_destination() -> void: + var planets: Array[Node3D] = [] + planets.assign(self.get_tree().get_nodes_in_group("planets")) + if self._destination: + planets.erase(self._destination) + + self._destination = planets.pick_random() if planets else null + +func _desired_direction() -> Vector3: + if not self._destination: + return Vector3.ZERO + + return (self._destination.global_position - self._ship.global_position).normalized() + +func _pointing_in_direction(direction: Vector3) -> bool: + var current_direction := - self._ship.global_transform.basis.z + return current_direction.angle_to(direction) <= self._direction_tolerance_rad + +func _distance_to_destination() -> float: + if not self._destination: + return 0.0 + + return self._ship.global_position.distance_to(self._destination.global_position) + +func _physics_process(_delta: float) -> void: + if not self._destination: + self._select_new_destination() + + var desired_direction := self._desired_direction() + self._ship.rigid_body_direction.direction = desired_direction + + if not self._pointing_in_direction(desired_direction): + self._ship.rigid_body_thruster.throttle = 0.0 + return + + if self._distance_to_destination() > self.destination_tolerance: + self._ship.rigid_body_thruster.throttle = 1.0 + else: + self._ship.rigid_body_thruster.throttle = 0.0 + self._select_new_destination() diff --git a/actors/trader.tscn b/actors/trader.tscn new file mode 100644 index 00000000..7ffd865a --- /dev/null +++ b/actors/trader.tscn @@ -0,0 +1,6 @@ +[gd_scene load_steps=2 format=3 uid="uid://dpwohjd3mf1e"] + +[ext_resource type="Script" path="res://actors/trader.gd" id="1_1k1lj"] + +[node name="Trader" type="Node3D"] +script = ExtResource("1_1k1lj") diff --git a/galaxy/star_systems/scenes/sol.tscn b/galaxy/star_systems/scenes/sol.tscn index 05d2d099..ea611767 100644 --- a/galaxy/star_systems/scenes/sol.tscn +++ b/galaxy/star_systems/scenes/sol.tscn @@ -1,4 +1,4 @@ -[gd_scene load_steps=7 format=3 uid="uid://2mdsbbko7baw"] +[gd_scene load_steps=14 format=3 uid="uid://2mdsbbko7baw"] [ext_resource type="PackedScene" uid="uid://cji43wyk7116p" path="res://stars/star.tscn" id="1_j8iws"] [ext_resource type="PackedScene" uid="uid://b04hfgkcuq7k6" path="res://planets/planet.tscn" id="3_7gpxn"] @@ -6,6 +6,30 @@ [ext_resource type="Texture2D" uid="uid://bege8n4jjcej5" path="res://planets/sprites/planet_37.png" id="5_hnp7v"] [ext_resource type="Texture2D" uid="uid://dkelmabwfrb5x" path="res://planets/sprites/planet_23.png" id="5_k6fyb"] [ext_resource type="PackedScene" uid="uid://dqrul5pyjbxjc" path="res://ships/freighter/freighter.tscn" id="6_uk08c"] +[ext_resource type="Script" path="res://combat/shield.gd" id="7_pkdss"] +[ext_resource type="Script" path="res://combat/hull.gd" id="8_ibfoc"] +[ext_resource type="Script" path="res://power/battery.gd" id="9_w4i7k"] +[ext_resource type="PackedScene" uid="uid://dpwohjd3mf1e" path="res://actors/trader.tscn" id="10_dpriv"] + +[sub_resource type="Resource" id="Resource_oen30"] +resource_local_to_scene = true +script = ExtResource("7_pkdss") +max_integrity = 150.0 +integrity = 150.0 +recharge_rate = 5.0 +power_efficiency = 1.0 + +[sub_resource type="Resource" id="Resource_yterj"] +resource_local_to_scene = true +script = ExtResource("8_ibfoc") +max_integrity = 300.0 +integrity = 300.0 + +[sub_resource type="Resource" id="Resource_eyrkq"] +resource_local_to_scene = true +script = ExtResource("9_w4i7k") +max_power = 300.0 +power = 300.0 [node name="Sol" type="Node3D" groups=["star_system"]] @@ -36,6 +60,27 @@ texture = ExtResource("5_k6fyb") [node name="Freighter" parent="." instance=ExtResource("6_uk08c")] transform = Transform3D(0.759975, 0, -0.649952, 0, 1, 0, 0.649952, 0, 0.759975, -5.22228, 0, -4.59493) +[node name="CombatObject" parent="Freighter" index="2"] +shield = SubResource("Resource_oen30") +hull = SubResource("Resource_yterj") + +[node name="RigidBodyDirection" parent="Freighter" index="3"] +battery = SubResource("Resource_eyrkq") + +[node name="RigidBodyThruster" parent="Freighter" index="4"] +battery = SubResource("Resource_eyrkq") + +[node name="PowerManagementUnit" parent="Freighter" index="5"] +battery = SubResource("Resource_eyrkq") + +[node name="ShieldRecharger" parent="Freighter" index="7"] +battery = SubResource("Resource_eyrkq") +shield = SubResource("Resource_oen30") + +[node name="Trader" parent="Freighter" instance=ExtResource("10_dpriv")] + [editable path="Mars"] [editable path="Mercury"] [editable path="Venus"] +[editable path="Freighter"] +[editable path="Freighter/CombatObject/TargetOverlay"] diff --git a/planets/planet.tscn b/planets/planet.tscn index a5d41c59..fca3266c 100644 --- a/planets/planet.tscn +++ b/planets/planet.tscn @@ -14,7 +14,7 @@ bottom_radius = 1.0 height = 0.001 cap_bottom = false -[node name="Planet" type="Node3D"] +[node name="Planet" type="Node3D" groups=["planets"]] [node name="MinimapIcon" type="MeshInstance3D" parent="."] layers = 2