1
0
Fork 0

Refactoring

This commit is contained in:
Fabio Iotti 2024-08-15 11:18:54 +02:00
parent fb97d172f4
commit 491d0a0b32
Signed by: bruce965
GPG key ID: 4EC13D9158A96B4C
22 changed files with 361 additions and 230 deletions

View file

@ -1,66 +1,73 @@
[gd_scene load_steps=12 format=3 uid="uid://cdaf4bh0jaa45"]
[gd_scene load_steps=21 format=3 uid="uid://cdaf4bh0jaa45"]
[ext_resource type="PackedScene" uid="uid://dq00mi6jwsa1f" path="res://scenes/planet/planet.tscn" id="1_0p552"]
[ext_resource type="Script" path="res://scripts/game_logic.gd" id="1_kb05v"]
[ext_resource type="Script" path="res://scenes/player/player.gd" id="2_plgh6"]
[ext_resource type="Script" path="res://scripts/game_logic.gd" id="1_uj8ti"]
[ext_resource type="Resource" uid="uid://cp0dudi0f5r62" path="res://scenes/templates/templates.tres" id="2_1lypt"]
[ext_resource type="Script" path="res://scripts/player.gd" id="2_plgh6"]
[ext_resource type="Texture2D" uid="uid://bydmcc5d53ldx" path="res://icons/paw_print.svg" id="3_mxakn"]
[ext_resource type="Texture2D" uid="uid://1xh0qil16bkh" path="res://icons/character.svg" id="3_qxmev"]
[ext_resource type="Script" path="res://scenes/player/local_player.gd" id="4_7rlmh"]
[ext_resource type="Script" path="res://scripts/player_local.gd" id="4_7rlmh"]
[ext_resource type="Texture2D" uid="uid://dx1wjviioa8u5" path="res://icons/chip.svg" id="4_pgo63"]
[ext_resource type="Script" path="res://ui.gd" id="7_khbdl"]
[ext_resource type="PackedScene" uid="uid://dtlatmtuggp6x" path="res://scenes/nebula/nebula.tscn" id="7_sv4lv"]
[ext_resource type="Script" path="res://scripts/ui/planets_ui.gd" id="7_khbdl"]
[ext_resource type="PackedScene" uid="uid://dtlatmtuggp6x" path="res://scenes/background_nebula/background_nebula.tscn" id="7_sv4lv"]
[ext_resource type="Script" path="res://scripts/player_ai.gd" id="7_v73fw"]
[ext_resource type="Script" path="res://scripts/planet.gd" id="8_ve3b1"]
[ext_resource type="PackedScene" uid="uid://cpffyaoh8x5bp" path="res://scenes/ships_fleet/ships_fleet.tscn" id="9_be18b"]
[ext_resource type="PackedScene" uid="uid://ckfk1xgxfk1c3" path="res://scenes/trail/trail.tscn" id="10_b5ql7"]
[node name="Main" type="Node"]
[node name="Logic" type="Node" parent="." node_paths=PackedStringArray("neutral_player", "players", "planets")]
script = ExtResource("1_kb05v")
neutral_player = NodePath("Players/0_Nature")
players = [NodePath("Players/1_LocalPlayer"), NodePath("Players/2_AI")]
planets = [NodePath("../Game/Planets/Planet1"), NodePath("../Game/Planets/Planet2"), NodePath("../Game/Planets/Planet3"), NodePath("../Game/Planets/Planet4")]
[node name="Players" type="Node" parent="Logic"]
[node name="0_Nature" type="Node" parent="Logic/Players"]
[sub_resource type="Resource" id="Resource_mxp7y"]
script = ExtResource("2_plgh6")
color = Color(0.745, 0.745, 0.745, 1)
icon = ExtResource("3_mxakn")
[node name="1_LocalPlayer" type="Node" parent="Logic/Players" node_paths=PackedStringArray("ui")]
[sub_resource type="Resource" id="Resource_1dtpf"]
script = ExtResource("4_7rlmh")
ui = NodePath("../../../UI")
color = Color(0.184314, 0.329412, 1, 1)
color = Color(0.236993, 0.373968, 1, 1)
icon = ExtResource("3_qxmev")
[node name="2_AI" type="Node" parent="Logic/Players"]
script = ExtResource("2_plgh6")
[sub_resource type="Resource" id="Resource_7wtc7"]
script = ExtResource("7_v73fw")
color = Color(0.835294, 0.160784, 0, 1)
icon = ExtResource("4_pgo63")
[node name="Nebula" parent="." instance=ExtResource("7_sv4lv")]
[sub_resource type="Resource" id="Resource_50eg2"]
script = ExtResource("8_ve3b1")
location = Vector2(200, 200)
type = 0
[node name="Game" type="Node2D" parent="."]
[sub_resource type="Resource" id="Resource_2525o"]
script = ExtResource("8_ve3b1")
location = Vector2(952, 448)
type = 0
[node name="Planets" type="Node2D" parent="Game"]
[sub_resource type="Resource" id="Resource_irtww"]
script = ExtResource("8_ve3b1")
location = Vector2(450, 234)
type = 0
[node name="Planet1" parent="Game/Planets" instance=ExtResource("1_0p552")]
position = Vector2(200, 200)
[sub_resource type="Resource" id="Resource_wdycy"]
script = ExtResource("8_ve3b1")
location = Vector2(702, 414)
type = 0
[node name="Planet2" parent="Game/Planets" instance=ExtResource("1_0p552")]
position = Vector2(952, 448)
[node name="Main" type="Node"]
[node name="Planet3" parent="Game/Planets" instance=ExtResource("1_0p552")]
position = Vector2(450, 234)
[node name="GameLogic" type="Node" parent="." node_paths=PackedStringArray("planets_container", "planets_ui")]
script = ExtResource("1_uj8ti")
templates = ExtResource("2_1lypt")
planets_container = NodePath("../Planets")
planets_ui = NodePath("../PlanetsUI")
players = Array[ExtResource("2_plgh6")]([SubResource("Resource_mxp7y"), SubResource("Resource_1dtpf"), SubResource("Resource_7wtc7")])
planets = Array[ExtResource("8_ve3b1")]([SubResource("Resource_50eg2"), SubResource("Resource_2525o"), SubResource("Resource_irtww"), SubResource("Resource_wdycy")])
[node name="Planet4" parent="Game/Planets" instance=ExtResource("1_0p552")]
position = Vector2(702, 414)
[node name="BackgroundNebula" parent="." instance=ExtResource("7_sv4lv")]
[node name="Planets" type="Node2D" parent="."]
[node name="ShipsFleet" parent="." instance=ExtResource("9_be18b")]
position = Vector2(246, 394)
count = 29
[node name="UI" type="Control" parent="." node_paths=PackedStringArray("trail")]
[node name="PlanetsUI" type="Control" parent="." node_paths=PackedStringArray("trail")]
layout_mode = 3
anchors_preset = 15
anchor_right = 1.0
@ -71,5 +78,5 @@ mouse_filter = 2
script = ExtResource("7_khbdl")
trail = NodePath("Trail")
[node name="Trail" parent="UI" instance=ExtResource("10_b5ql7")]
[node name="Trail" parent="PlanetsUI" instance=ExtResource("10_b5ql7")]
visible = false

View file

@ -1,6 +1,6 @@
[gd_scene load_steps=5 format=3 uid="uid://dtlatmtuggp6x"]
[ext_resource type="Shader" path="res://scenes/nebula/nebula.gdshader" id="1_nqp0c"]
[ext_resource type="Shader" path="res://scenes/background_nebula/background_nebula.gdshader" id="1_nqp0c"]
[sub_resource type="FastNoiseLite" id="FastNoiseLite_8c2xm"]
@ -14,7 +14,7 @@ noise = SubResource("FastNoiseLite_8c2xm")
shader = ExtResource("1_nqp0c")
shader_parameter/noise = SubResource("NoiseTexture2D_cukca")
[node name="Nebula" type="ColorRect"]
[node name="BackgroundNebula" type="ColorRect"]
material = SubResource("ShaderMaterial_y72ex")
anchors_preset = 15
anchor_right = 1.0

View file

@ -1,5 +1,5 @@
extends Node2D
class_name Planet
class_name ControlPlanet
## The player currenly controlling this planet.
var player: Player :
@ -32,7 +32,7 @@ var is_selected: bool :
set(value):
%Selection.visible = value
func _on_input_listener_input_event(viewport: Node, event: InputEvent, shape_idx: int) -> void:
func _on_input_listener_input_event(_viewport: Node, event: InputEvent, _shape_idx: int) -> void:
# TODO: handle touch appropriately (InputEventScreenTouch).
if event is InputEventMouseButton and event.button_index == MOUSE_BUTTON_LEFT and event.is_pressed():
selected.emit(self)

View file

@ -1,8 +1,8 @@
[gd_scene load_steps=7 format=3 uid="uid://dq00mi6jwsa1f"]
[ext_resource type="PackedScene" uid="uid://dnerbdusnaofr" path="res://scenes/procedural_planet/procedural_planet.tscn" id="1_8mf3x"]
[ext_resource type="Script" path="res://scenes/planet/planet.gd" id="1_e208c"]
[ext_resource type="Shader" path="res://scenes/planet/planet_selection.gdshader" id="2_bl05u"]
[ext_resource type="Script" path="res://scenes/control_planet/control_planet.gd" id="1_e208c"]
[ext_resource type="Shader" path="res://scenes/control_planet/planet_selection.gdshader" id="2_bl05u"]
[ext_resource type="Texture2D" uid="uid://1xh0qil16bkh" path="res://icons/character.svg" id="2_kglxp"]
[sub_resource type="CircleShape2D" id="CircleShape2D_tsywx"]

View file

@ -1,10 +0,0 @@
extends Player
class_name LocalPlayer
@export var ui: GameUI
func _on_game_start(game: GameLogic) -> void:
ui._on_game_started(game)
func _on_game_tick(game: GameLogic, tick: int) -> void:
pass

View file

@ -1,14 +0,0 @@
extends Node
class_name Player
@export var color: Color = Color.MAGENTA
@export var icon: Texture2D
var pending_operations: Array[GameOperation] = []
func _on_game_start(game: GameLogic) -> void:
pass
func _on_game_tick(game: GameLogic, tick: int) -> void:
pass

View file

@ -1,22 +1,37 @@
extends Node2D
class_name ShipFleet
@export var departed_at: int
@export var arrives_at: int
@export var from: Vector2
@export var to: Vector2
@export var count: int :
set(value):
count = value
_update_instances_count()
#region Graphics
var instances: Array[Node2D] = []
@export var ship_template: PackedScene
@export var count: int :
set(value):
count = value
func _update_instances_count() -> void :
var diff = count - instances.size()
var diff = count - instances.size()
for i in range(diff):
var j = float(1 + instances.size())
var ship := ship_template.instantiate()
add_child(ship)
ship.position = Vector2.from_angle(j) * j * 2.
instances.push_back(ship)
for i in range(diff):
var j = float(1 + instances.size())
var ship := ship_template.instantiate()
add_child(ship)
ship.position = Vector2.from_angle(j) * j * 2.
instances.push_back(ship)
for i in range(-diff):
var ship: Node2D = instances.pop_back()
remove_child(ship)
for i in range(-diff):
var ship: Node2D = instances.pop_back()
remove_child(ship)
#endregion

View file

@ -0,0 +1,4 @@
class_name TemplateScenes
extends Resource
@export var control_planet: PackedScene

View file

@ -0,0 +1,8 @@
[gd_resource type="Resource" script_class="TemplateScenes" load_steps=3 format=3 uid="uid://cp0dudi0f5r62"]
[ext_resource type="PackedScene" uid="uid://dq00mi6jwsa1f" path="res://scenes/control_planet/control_planet.tscn" id="1_3rbtf"]
[ext_resource type="Script" path="res://scenes/templates/template_scenes.gd" id="1_yvn3m"]
[resource]
script = ExtResource("1_yvn3m")
control_planet = ExtResource("1_3rbtf")

View file

@ -1,69 +1,77 @@
extends Node
class_name GameLogic
extends Node
const LOGIC_TICKS_PER_SECOND: float = 20.
const LOGIC_SECONDS_PER_TICK = 1. / LOGIC_TICKS_PER_SECOND
const LOGIC_TICKS_PER_SECOND := 20.
const LOGIC_SECONDS_PER_TICK := 1. / LOGIC_TICKS_PER_SECOND
## Neutral player owning all non-conquered planets.
@export var neutral_player: Player
## Templates for spawnable stuff.
@export var templates: TemplateScenes
## Container for planets.
@export var planets_container: Node2D
## Interface to interact with planets.
@export var planets_ui: PlanetsUI
## Game players.
@export var players: Array[Player] = []
@export var players: Array[Player]
## Game planets.
@export var planets: Array[Planet] = []
@export var planets: Array[Planet]
var ticks_count: int
var extra_time: float
var _game: GameState
var _planet_controls: Array[ControlPlanet]
signal game_start(game: GameLogic)
signal game_tick(game: GameLogic, tick: int)
var _extra_time: float
func _ready() -> void:
_game_init()
game_start.emit(self)
# New game.
_game = GameState.new()
# Add players.
for i in range(players.size()):
_game.add_player()
# Add planets.
for i in range(planets.size()):
# Data.
var data := GameState.PlanetData.new()
data.position = Vector2i(planets[i].location)
data.grow_every_ticks = 10
data.player_id = (i + 1) if (i < players.size() - 1) else 0
data.population = 0
_game.add_planet(data)
# UI control.
var control: ControlPlanet = templates.control_planet.instantiate()
control.position = planets[i].location
control.player = players[data.player_id]
control.population = data.population
_planet_controls.push_back(control)
planets_container.add_child(control)
planets_ui.register_planet(control)
# Register UI signals.
_game.planet_player_changed.connect(_set_planet_player)
_game.planet_population_changed.connect(_set_planet_population)
planets_ui.fleet_dispatched.connect(_dispatch_fleet)
func _process(delta: float) -> void:
extra_time += delta
_extra_time += delta
while extra_time > LOGIC_SECONDS_PER_TICK:
extra_time -= LOGIC_SECONDS_PER_TICK
_game_tick(ticks_count)
ticks_count += 1
while _extra_time > LOGIC_SECONDS_PER_TICK:
_extra_time -= LOGIC_SECONDS_PER_TICK
_game.tick()
func _game_init() -> void:
ticks_count = 0
extra_time = 0.
func _set_planet_player(planet_id: int, player_id: int) -> void:
_planet_controls[planet_id].player = players[player_id]
for player in players:
game_start.connect(player._on_game_start)
game_tick.connect(player._on_game_tick)
func _set_planet_population(planet_id: int, population: int) -> void:
_planet_controls[planet_id].population = population
for i in range(planets.size()):
var planet := planets[i]
planet.player = players[i] if i < players.size() else neutral_player
planet.is_selected = false
func _game_tick(tick: int) -> void:
for planet in planets:
if planet.player != neutral_player and tick % 10 == 0:
planet.population += 1
for player in players:
for op in player.pending_operations:
if op is GameOperationSendFleet:
var count = min(op.max_count, op.from.population)
op.from.population -= count
if op.from.player == op.to.player:
op.to.population += count
else:
op.to.population -= count
if op.to.population <= 0:
op.to.player = op.from.player
op.to.population = abs(op.from.population)
else:
assert(false, "Unknown GameOperation: %s" % [op])
player.pending_operations.clear()
game_tick.emit(self, tick)
func _dispatch_fleet(from: ControlPlanet, to: ControlPlanet) -> void:
var player_id := players.find(from.player)
var from_planet_id := _planet_controls.find(from)
var to_planet_id := _planet_controls.find(to)
var max_count: int = ceil(from.population / 2.)
_game.dispatch_fleet(player_id, from_planet_id, to_planet_id, max_count)

View file

@ -1,2 +0,0 @@
extends RefCounted
class_name GameOperation

View file

@ -1,8 +0,0 @@
extends GameOperation
class_name GameOperationSendFleet
var from: Planet
var to: Planet
var max_count: int

102
scripts/game_state.gd Normal file
View file

@ -0,0 +1,102 @@
class_name GameState
extends Resource
class PlayerData:
var commands: Array[Command] = []
class PlanetData:
var position: Vector2i
var grow_every_ticks: int
var player_id: int ## 0 = none
var population: int
class FleetData:
var count: int
enum CommandType {
DISPATCH_FLEET,
}
class Command:
var type: CommandType
var wait_tick: int
class DispatchFleedCommand extends Command:
var from_planet_id: int
var to_planet_id: int
var max_count: int
func _init():
type = CommandType.DISPATCH_FLEET
signal game_ticked(tick: int)
signal planet_population_changed(planet_id: int, population: int)
signal planet_player_changed(planet_id: int, player_id: int)
var _players: Array[PlayerData] = []
var _planets: Array[PlanetData] = []
var _fleets: Array[FleetData] = []
var current_tick: int
## Add a player to the game.
## The first player is expected to be the game master / neutral player,
## who does not play and for whom the population never increases.
func add_player(data := PlayerData.new()) -> int:
_players.push_back(data)
return _players.size() - 1
## Add a planet to the game.
func add_planet(data := PlanetData.new()) -> int:
_planets.push_back(data)
return _planets.size() - 1
## Advance game status by one tick.
func tick() -> void:
current_tick += 1
for planet_id in range(_planets.size()):
var planet := _planets[planet_id]
if planet.player_id != 0 and current_tick % planet.grow_every_ticks == 0:
planet.population += 1
planet_population_changed.emit(planet_id, planet.population)
for player_id in range(_players.size()):
var player := _players[player_id]
if player.commands.size() > 0 && current_tick >= player.commands[0].wait_tick:
var command: Command = player.commands.pop_back()
match command.type:
CommandType.DISPATCH_FLEET:
_handle_dispatch_fleet(player_id, command)
_:
assert(false, "Unknown command: %s" % [command])
game_ticked.emit(current_tick)
## Dispatch a fleet.
func dispatch_fleet(player_id: int, from_planet_id: int, to_planet_id: int, max_count: int) -> void:
var dispatch := DispatchFleedCommand.new()
dispatch.from_planet_id = from_planet_id
dispatch.to_planet_id = to_planet_id
dispatch.max_count = max_count
_issue_command(player_id, dispatch)
func _issue_command(player_id: int, command: Command) -> void:
var commands := _players[player_id].commands
var index := commands.map(func (x): return x.wait_tick).bsearch(command.wait_tick, false)
commands.insert(index, command)
func _handle_dispatch_fleet(player_id: int, dispatch: DispatchFleedCommand) -> void:
var from = _planets[dispatch.from_planet_id]
var to = _planets[dispatch.to_planet_id]
var count = min(dispatch.max_count, from.population)
from.population -= count
if from.player_id == to.player_id:
to.population += count
else:
to.population -= count
if to.population <= 0:
to.player_id = from.player_id
to.population = abs(from.population)
planet_player_changed.emit(dispatch.to_planet_id, to.player_id)
planet_population_changed.emit(dispatch.from_planet_id, from.population)
planet_population_changed.emit(dispatch.to_planet_id, to.population)

10
scripts/planet.gd Normal file
View file

@ -0,0 +1,10 @@
class_name Planet
extends Resource
enum PlanetType {
TERRESTRIAL,
}
@export var location: Vector2
@export var type: PlanetType

9
scripts/player.gd Normal file
View file

@ -0,0 +1,9 @@
class_name Player
extends Resource
@export var color: Color = Color.MAGENTA
@export var icon: Texture2D
func process_game_tick(_game: GameLogic) -> void:
pass

5
scripts/player_ai.gd Normal file
View file

@ -0,0 +1,5 @@
class_name AIPlayer
extends Player
func process_game_tick(_game: GameLogic) -> void:
pass

5
scripts/player_local.gd Normal file
View file

@ -0,0 +1,5 @@
class_name LocalPlayer
extends Player
func process_game_tick(_game: GameLogic) -> void:
pass

80
scripts/ui/planets_ui.gd Normal file
View file

@ -0,0 +1,80 @@
class_name PlanetsUI
extends Control
@export var trail: Trail
signal fleet_dispatched(from: ControlPlanet, to: ControlPlanet)
func register_planet(control: ControlPlanet) -> void:
control.selected.connect(_on_planet_selected)
control.pointer_entered.connect(_on_planet_pointer_entered)
control.pointer_exited.connect(_on_planet_pointer_exited)
func _process(delta: float) -> void:
_update_trail(delta, false)
func _unhandled_input(event: InputEvent) -> void:
if event is InputEventMouse:
_handle_mouse_input(event)
#region Mouse input
var _last_cursor_position: Vector2
func _handle_mouse_input(event: InputEventMouse) -> void:
if event is InputEventMouseMotion:
# The trail follows the cursor.
_last_cursor_position = event.global_position
if event is InputEventMouseButton and event.button_index == MOUSE_BUTTON_LEFT and event.is_released():
# The trail disappears when no longer dragging.
_dragging_from_planet = false
# Detect mouse released on a planet and spawn a fleet.
if _selected_planet != null and _selected_planet.player is LocalPlayer and _pointed_planet != null:
fleet_dispatched.emit(_selected_planet, _pointed_planet)
#endregion
#region Planets
var _selected_planet: ControlPlanet
var _pointed_planet: ControlPlanet
var _dragging_from_planet: bool
func _on_planet_selected(planet: ControlPlanet) -> void:
if _selected_planet != null:
_selected_planet.is_selected = false
_selected_planet = planet
_selected_planet.is_selected = true
_dragging_from_planet = true
_update_trail(0., true)
func _on_planet_pointer_entered(planet: ControlPlanet) -> void:
_pointed_planet = planet
func _on_planet_pointer_exited(planet: ControlPlanet) -> void:
if _pointed_planet == planet:
_pointed_planet = null
#endregion
#region Trail
var _trail_opacity := 0.
func _update_trail(delta: float, snap_position: bool) -> void:
var show_trail := _dragging_from_planet and _selected_planet != null and _selected_planet.player is LocalPlayer
if show_trail or trail.visible:
_trail_opacity = Utils.damp(_trail_opacity, 1. if show_trail else 0., 1e-4, delta)
trail.color = Color(_selected_planet.player.color, _trail_opacity)
trail.visible = _trail_opacity > .01
if show_trail:
var target_position = _last_cursor_position if _pointed_planet == null else _pointed_planet.global_position
trail.start_position = _selected_planet.global_position
trail.end_position = target_position if snap_position else Utils.damp(trail.end_position, target_position, 1e-20, delta)
#endregion

View file

@ -1,4 +1,4 @@
class_name Util
class_name Utils
## Time-independent damping with exponential-decay.
##

88
ui.gd
View file

@ -1,88 +0,0 @@
extends Control
class_name GameUI
@export var trail: Trail
var game: GameLogic
func _on_game_started(game: GameLogic) -> void:
self.game = game
for planet in game.planets:
planet.selected.connect(_on_planet_selected)
planet.pointer_entered.connect(_on_planet_pointer_entered)
planet.pointer_exited.connect(_on_planet_pointer_exited)
func _process(delta: float) -> void:
_update_trail(delta, false)
func _unhandled_input(event: InputEvent) -> void:
if event is InputEventMouse:
_handle_mouse_input(event)
#region Mouse input
var last_cursor_position: Vector2
func _handle_mouse_input(event: InputEventMouse) -> void:
if event is InputEventMouseMotion:
# The trail follows the cursor.
last_cursor_position = event.global_position
if event is InputEventMouseButton and event.button_index == MOUSE_BUTTON_LEFT and event.is_released():
# The trail disappears when no longer dragging.
dragging_from_planet = false
# Detect mouse released on a planet and spawn a fleet.
if selected_planet != null and selected_planet.player is LocalPlayer and pointed_planet != null:
var op := GameOperationSendFleet.new()
op.from = selected_planet
op.to = pointed_planet
op.max_count = ceil(selected_planet.population / 2)
selected_planet.player.pending_operations.push_front(op)
#endregion
#region Planets
var selected_planet: Planet
var pointed_planet: Planet
var dragging_from_planet: bool
func _on_planet_selected(planet: Planet) -> void:
if selected_planet != null:
selected_planet.is_selected = false
selected_planet = planet
selected_planet.is_selected = true
dragging_from_planet = true
_update_trail(0., true)
func _on_planet_pointer_entered(planet: Planet) -> void:
pointed_planet = planet
func _on_planet_pointer_exited(planet: Planet) -> void:
if pointed_planet == planet:
pointed_planet = null
#endregion
#region Trail
var trail_opacity := 0.
func _update_trail(delta: float, snap_position: bool) -> void:
var show_trail := dragging_from_planet and selected_planet != null and selected_planet.player is LocalPlayer
if show_trail or trail.visible:
trail_opacity = Util.damp(trail_opacity, 1. if show_trail else 0., 1e-4, delta)
trail.color = Color(selected_planet.player.color, trail_opacity)
trail.visible = trail_opacity > .01
if show_trail:
var target_position = last_cursor_position if pointed_planet == null else pointed_planet.global_position
trail.start_position = selected_planet.global_position
trail.end_position = target_position if snap_position else Util.damp(trail.end_position, target_position, 1e-20, delta)
#endregion