using Godot; namespace SpaceCapture; public partial class PlanetsUI : Control { Trail _trail; /// /// Container for trails. /// /// [Export] public Node2D TrailsContainer { get; set; } [Signal] public delegate void FleetDispatchedEventHandler(ControlPlanet from, ControlPlanet to); public void RegisterPlanet(ControlPlanet control) { control.Selected += OnPlanetSelected; control.PointerEntered += OnPlanetPointerEntered; control.PointerExited += OnPlanetPointerExited; } public override void _Ready() { _trail = SceneTemplates.Scenes.Trail.Instantiate(); _trail.Visible = false; TrailsContainer.AddChild(_trail); } public override void _Process(double delta) { UpdateTrail(delta, false); } public override void _UnhandledInput(InputEvent inputEvent) { if (inputEvent is InputEventMouse e) HandleMouseInput(e); } #region Mouse input Vector2 _lastCursorPosition; void HandleMouseInput(InputEventMouse inputEvent) { if (inputEvent is InputEventMouseMotion e) { // The trail follows the cursor. _lastCursorPosition = e.GlobalPosition; } if (inputEvent is InputEventMouseButton e2 && e2.ButtonIndex is MouseButton.Left && e2.IsReleased()) { // The trail disappears when no longer dragging. _draggingFromPlanet = false; // Detect mouse released on a planet and spawn a fleet. if (_selectedPlanet?.Player is PlayerLocal && _pointedPlanet is not null) EmitSignal(SignalName.FleetDispatched, _selectedPlanet, _pointedPlanet); } } #endregion #region Planets ControlPlanet _selectedPlanet; ControlPlanet _pointedPlanet; bool _draggingFromPlanet; void OnPlanetSelected(ControlPlanet planet) { if (_selectedPlanet is not null) _selectedPlanet.IsSelected = false; _selectedPlanet = planet; _selectedPlanet.IsSelected = true; _draggingFromPlanet = true; UpdateTrail(0.0, true); } void OnPlanetPointerEntered(ControlPlanet planet) { _pointedPlanet = planet; } void OnPlanetPointerExited(ControlPlanet planet) { if (_pointedPlanet == planet) _pointedPlanet = null; } #endregion #region Trail void UpdateTrail(double delta, bool snapPosition) { _trail.ShowTrail = _draggingFromPlanet && _selectedPlanet is not null && _selectedPlanet.Player is PlayerLocal; if (_trail.ShowTrail) { _trail.Color = _selectedPlanet.Player.Color; var targetPosition = _pointedPlanet?.GlobalPosition ?? _lastCursorPosition; _trail.StartPosition = _selectedPlanet.GlobalPosition; _trail.EndPosition = snapPosition ? targetPosition : Utils.Damp(_trail.EndPosition, targetPosition, 1e-20f, delta); } } #endregion }