using Noesis; using StellarConquest.Model.Actions; using StellarConquest.Model.Core; using StellarConquest.Model.Planets; using StellarConquest.Model.Stars; using StellarConquest.Model.Universe; using System.Linq; using UnityEngine; using Grid = Noesis.Grid; using GUI = Noesis.GUI; using NoesisEventArgs = Noesis.EventArgs; namespace StellarConquest.Presentation.Unity.UI { public sealed class MapOrbitsControl : UserControl { private FrameworkElement _Root; private Grid _SystemOrbitsGrid; private Grid _OrbitsGrid; private Grid _JumpBeaconsGrid; private JumpBeaconControl _TopJumpBeaconControl; private JumpBeaconControl _TopRightJumpBeaconControl; private JumpBeaconControl _RightJumpBeaconControl; private JumpBeaconControl _BottomRightJumpBeaconControl; private JumpBeaconControl _BottomJumpBeaconControl; private JumpBeaconControl _BottomLeftJumpBeaconControl; private JumpBeaconControl _LeftJumpBeaconControl; private JumpBeaconControl _TopLeftJumpBeaconControl; private View _View; private int _FrameCount = 0; public MapOrbitsControl() { if (!Application.isPlaying) return; Initialized += OnInitialized; InitializeComponent(); } private void InitializeComponent() { GUI.LoadComponent(this, "Assets/User Interface/Screens/Game/Static/Map/MapOrbitsControl.xaml"); Loaded += (sender, e) => { _View = View; _View.Rendering += OnRendering; }; Unloaded += (sender, e) => { if (_View != null) _View.Rendering -= OnRendering; _View = null; }; _Root = Content as FrameworkElement; _SystemOrbitsGrid = _Root.FindName(nameof(_SystemOrbitsGrid)) as Grid; _OrbitsGrid = _Root.FindName(nameof(_OrbitsGrid)) as Grid; _JumpBeaconsGrid = _Root.FindName(nameof(_JumpBeaconsGrid)) as Grid; _TopJumpBeaconControl = _Root.FindName(nameof(_TopJumpBeaconControl)) as JumpBeaconControl; _TopRightJumpBeaconControl = _Root.FindName(nameof(_TopRightJumpBeaconControl)) as JumpBeaconControl; _RightJumpBeaconControl = _Root.FindName(nameof(_RightJumpBeaconControl)) as JumpBeaconControl; _BottomRightJumpBeaconControl = _Root.FindName(nameof(_BottomRightJumpBeaconControl)) as JumpBeaconControl; _BottomJumpBeaconControl = _Root.FindName(nameof(_BottomJumpBeaconControl)) as JumpBeaconControl; _BottomLeftJumpBeaconControl = _Root.FindName(nameof(_BottomLeftJumpBeaconControl)) as JumpBeaconControl; _LeftJumpBeaconControl = _Root.FindName(nameof(_LeftJumpBeaconControl)) as JumpBeaconControl; _TopLeftJumpBeaconControl = _Root.FindName(nameof(_TopLeftJumpBeaconControl)) as JumpBeaconControl; foreach (FrameworkElement element in _JumpBeaconsGrid.Children) element.MouseUp += (sender, e) => SelectJumpBeacon((StarSystemMetadata)element.Tag); } private void OnInitialized(object sender, NoesisEventArgs args) { } private void OnRendering(object sender, NoesisEventArgs e) { if (Visibility == Visibility.Collapsed) return; _FrameCount++; if (_FrameCount % 5 == 0) UpdateJumpBeaconEnabledState(); // Animation to show broken culling float radius = SessionState.Instance.StarSystem.GetRadius(); float hack = (Mathf.Cos(Time.timeSinceLevelLoad * 0.5f) + 1) * 0.5f + 0.2f; Debug.Log(hack); UpdateRadius(radius, hack); } private void UpdateRadius(float radius, float hack = 1.0f) { float JumpBeaconRadius = (radius + 110); float JumpBeaconRadiusDiagonal = JumpBeaconRadius * 0.71f; JumpBeaconRadius *= hack; JumpBeaconRadiusDiagonal *= hack; _TopJumpBeaconControl.X = 0; _TopJumpBeaconControl.Y = -JumpBeaconRadius; _TopRightJumpBeaconControl.X = JumpBeaconRadiusDiagonal; _TopRightJumpBeaconControl.Y = -JumpBeaconRadiusDiagonal; _RightJumpBeaconControl.X = JumpBeaconRadius; _RightJumpBeaconControl.Y = 0; _BottomRightJumpBeaconControl.X = JumpBeaconRadiusDiagonal; _BottomRightJumpBeaconControl.Y = JumpBeaconRadiusDiagonal; _BottomJumpBeaconControl.X = 0; _BottomJumpBeaconControl.Y = JumpBeaconRadius; _BottomLeftJumpBeaconControl.X = -JumpBeaconRadiusDiagonal; _BottomLeftJumpBeaconControl.Y = JumpBeaconRadiusDiagonal; _LeftJumpBeaconControl.X = -JumpBeaconRadius; _LeftJumpBeaconControl.Y = 0; _TopLeftJumpBeaconControl.X = -JumpBeaconRadiusDiagonal; _TopLeftJumpBeaconControl.Y = -JumpBeaconRadiusDiagonal; } private void SelectJumpBeacon(StarSystemMetadata metadata) { if (!PickingManager.Instance.InteractionFired && !UIStateMachine.Instance.IsCursorOverUI && !UIStateMachine.Instance.IsPrimaryOverlayVisible) if (SessionState.Instance.Player.Location.IsPlayerInStellarShip) { if (SessionState.Instance.Ship.FuelValue >= SessionState.Instance.Ship.FuelConsumption) { PickingManager.Instance.InteractionFired = true; UIStateMachine.Instance.GameScreen.TargetingControl.SelectTarget(SessionState.Instance.Ship.InstanceId, true, false); UIJumpAction jumpAction = new UIJumpAction(SessionState.Instance.Galaxy.InstanceId, metadata.Id); jumpAction.ExecuteServerSide(); } else UIStateMachine.Instance.GameScreen.ShowMessage(StatusActionType.Navigation, "INSUFFICIENT FUEL"); } } public void SetVisibility(bool visible) { if (visible) Visibility = Visibility.Visible; else Visibility = Visibility.Collapsed; } public void Update() { if (Visibility == Visibility.Collapsed) return; float radius = SessionState.Instance.StarSystem.GetRadius(); UpdateRadius(radius); // system orbits _SystemOrbitsGrid.Children.Clear(); Ellipse innerStarSystemRadius = new Ellipse(); innerStarSystemRadius.Width = radius * 2; innerStarSystemRadius.Height = radius * 2; innerStarSystemRadius.Stroke = FindResource("SystemOrbitStrokeBrush") as SolidColorBrush; innerStarSystemRadius.StrokeThickness = (float)FindResource("SystemOrbitStrokeThickness"); innerStarSystemRadius.StrokeDashArray = "13,13"; _SystemOrbitsGrid.Children.Add(innerStarSystemRadius); Ellipse outerStarSystemRadius = new Ellipse(); outerStarSystemRadius.Width = (radius + Constants.Universe.JumpRegionRadius) * 2; outerStarSystemRadius.Height = (radius + Constants.Universe.JumpRegionRadius) * 2; outerStarSystemRadius.Stroke = FindResource("SystemOrbitStrokeBrush") as SolidColorBrush; outerStarSystemRadius.StrokeThickness = (float)FindResource("SystemOrbitStrokeThickness"); outerStarSystemRadius.StrokeDashArray = "25,25"; _SystemOrbitsGrid.Children.Add(outerStarSystemRadius); // orbits _OrbitsGrid.Children.Clear(); if (SessionState.Instance.StarSystem.CountStars > 0 && SessionState.Instance.StarSystem.StarType != StarType.BlackHole) { foreach (BasePlanet planet in SessionState.Instance.StarSystem.Planets) { int distance = (int)(2 * Vector3.Distance(Vector3.zero, planet.Position.Convert())); Ellipse ellipse = new Ellipse(); ellipse.Width = distance; ellipse.Height = distance; ellipse.Stroke = FindResource("OrbitStrokeBrush") as SolidColorBrush; ellipse.StrokeThickness = (float)FindResource("OrbitStrokeThickness"); _OrbitsGrid.Children.Add(ellipse); } } else if (SessionState.Instance.StarSystem.StarType == StarType.BlackHole) { Ellipse midpointSystemRadius = new Ellipse(); midpointSystemRadius.Width = radius * 0.66f; midpointSystemRadius.Height = radius * 0.66f; midpointSystemRadius.Stroke = FindResource("SystemOrbitStrokeBrush") as SolidColorBrush; midpointSystemRadius.StrokeThickness = (float)FindResource("SystemOrbitStrokeThickness"); midpointSystemRadius.StrokeDashArray = "13,13"; _SystemOrbitsGrid.Children.Add(midpointSystemRadius); } else { if (SessionState.Instance.StarSystem.CountPlanets == 0) { Ellipse midpointSystemRadius = new Ellipse(); midpointSystemRadius.Width = radius * 0.5f; midpointSystemRadius.Height = radius * 0.5f; midpointSystemRadius.Stroke = FindResource("SystemOrbitStrokeBrush") as SolidColorBrush; midpointSystemRadius.StrokeThickness = (float)FindResource("SystemOrbitStrokeThickness"); midpointSystemRadius.StrokeDashArray = "13,13"; _SystemOrbitsGrid.Children.Add(midpointSystemRadius); } } // jump gates Location location = SessionState.Instance.Location; //if (location.CanMoveTop()) { _TopJumpBeaconControl.Visibility = Visibility.Visible; StarSystemMetadata connectionMetadata = SessionState.Instance.StarSystem.ConnectionsMetadata.FirstOrDefault( a => a.Id == location.AbsolutePosition.Top.Id); _TopJumpBeaconControl.Text = "T"; // connectionMetadata.Name != null ? connectionMetadata.Name : "Unknown"; _TopJumpBeaconControl.Tag = connectionMetadata; } //else //_TopJumpBeaconControl.Visibility = Visibility.Collapsed; //if (location.CanMoveTopRight()) { _TopRightJumpBeaconControl.Visibility = Visibility.Visible; StarSystemMetadata connectionMetadata = SessionState.Instance.StarSystem.ConnectionsMetadata.FirstOrDefault( a => a.Id == location.AbsolutePosition.TopRight.Id); _TopRightJumpBeaconControl.Text = "TR"; // connectionMetadata.Name != null ? connectionMetadata.Name : "Unknown"; _TopRightJumpBeaconControl.Tag = connectionMetadata; } //else //_TopRightJumpBeaconControl.Visibility = Visibility.Collapsed; //if (location.CanMoveRight()) { _RightJumpBeaconControl.Visibility = Visibility.Visible; StarSystemMetadata connectionMetadata = SessionState.Instance.StarSystem.ConnectionsMetadata.FirstOrDefault( a => a.Id == location.AbsolutePosition.Right.Id); _RightJumpBeaconControl.Text = "R"; // connectionMetadata.Name != null ? connectionMetadata.Name : "Unknown"; _RightJumpBeaconControl.Tag = connectionMetadata; } //else //_RightJumpBeaconControl.Visibility = Visibility.Collapsed; //if (location.CanMoveBottomRight()) { _BottomRightJumpBeaconControl.Visibility = Visibility.Visible; StarSystemMetadata connectionMetadata = SessionState.Instance.StarSystem.ConnectionsMetadata.FirstOrDefault( a => a.Id == location.AbsolutePosition.BottomRight.Id); _BottomRightJumpBeaconControl.Text = "BR"; // connectionMetadata.Name != null ? connectionMetadata.Name : "Unknown"; _BottomRightJumpBeaconControl.Tag = connectionMetadata; } //else //_BottomRightJumpBeaconControl.Visibility = Visibility.Collapsed; //if (location.CanMoveBottom()) { _BottomJumpBeaconControl.Visibility = Visibility.Visible; StarSystemMetadata connectionMetadata = SessionState.Instance.StarSystem.ConnectionsMetadata.FirstOrDefault( a => a.Id == location.AbsolutePosition.Bottom.Id); _BottomJumpBeaconControl.Text = "B"; // connectionMetadata.Name != null ? connectionMetadata.Name : "Unknown"; _BottomJumpBeaconControl.Tag = connectionMetadata; } //else //_BottomJumpBeaconControl.Visibility = Visibility.Collapsed; //if (location.CanMoveBottomLeft()) { _BottomLeftJumpBeaconControl.Visibility = Visibility.Visible; StarSystemMetadata connectionMetadata = SessionState.Instance.StarSystem.ConnectionsMetadata.FirstOrDefault( a => a.Id == location.AbsolutePosition.BottomLeft.Id); _BottomLeftJumpBeaconControl.Text = "BL"; // connectionMetadata.Name != null ? connectionMetadata.Name : "Unknown"; _BottomLeftJumpBeaconControl.Tag = connectionMetadata; } //else //_BottomLeftJumpBeaconControl.Visibility = Visibility.Collapsed; //if (location.CanMoveLeft()) { _LeftJumpBeaconControl.Visibility = Visibility.Visible; StarSystemMetadata connectionMetadata = SessionState.Instance.StarSystem.ConnectionsMetadata.FirstOrDefault( a => a.Id == location.AbsolutePosition.Left.Id); _LeftJumpBeaconControl.Text = "L"; // connectionMetadata.Name != null ? connectionMetadata.Name : "Unknown"; _LeftJumpBeaconControl.Tag = connectionMetadata; } //else //_LeftJumpBeaconControl.Visibility = Visibility.Collapsed; //if (location.CanMoveTopLeft()) { _TopLeftJumpBeaconControl.Visibility = Visibility.Visible; StarSystemMetadata connectionMetadata = SessionState.Instance.StarSystem.ConnectionsMetadata.FirstOrDefault( a => a.Id == location.AbsolutePosition.TopLeft.Id); _TopLeftJumpBeaconControl.Text = "TL"; // connectionMetadata.Name != null ? connectionMetadata.Name : "Unknown"; _TopLeftJumpBeaconControl.Tag = connectionMetadata; } //else //_TopLeftJumpBeaconControl.Visibility = Visibility.Collapsed; } public void UpdateJumpBeaconEnabledState() { foreach (FrameworkElement element in _JumpBeaconsGrid.Children) if (GameState.Instance.PlayerShip != null) element.IsEnabled = GameState.Instance.PlayerShip.ShipController.CanJump(); else element.IsEnabled = false; } } }