public void Update(TimeSpan timestamp, UpdateFrequency updateFlags) { runs++; OnRelease = OnRelease || LastFrameMouseDown & !Turret.IsShooting; var a = Turret.Azimuth; var b = Turret.Elevation; var TurretAimRay = Math.Sin(a) * Math.Cos(b) * Turret.WorldMatrix.Left + Math.Cos(a) * Math.Cos(b) * Turret.WorldMatrix.Forward + Math.Sin(b) * Turret.WorldMatrix.Up; var WallPlane = new Plane(Panels[Vector2I.Zero].GetPosition() - Panels[Vector2I.Zero].WorldMatrix.Backward, Panels[Vector2I.Zero].WorldMatrix.Backward); Vector3 Intersection; TrigHelpers.PlaneIntersection(WallPlane, Turret.GetPosition() + Turret.WorldMatrix.Up * 0.579 + Turret.WorldMatrix.Backward * 0.068, TurretAimRay, out Intersection); var CursorDirection = Intersection - Panels[Vector2I.Zero].GetPosition() + Panels[Vector2I.Zero].WorldMatrix.Backward * 1.25 + Panels[Vector2I.Zero].WorldMatrix.Right * 1.25; var CursorDist = CursorDirection.Length(); CursorDirection.Normalize(); // LCD wall configuration: // | | | // | | | // | | | // Cursor position, originating in the middle of the LCD wall, with unit in meters CursorPos = Vector3D.TransformNormal(CursorDirection, MatrixD.Transpose(Panels[Vector2I.Zero].WorldMatrix)) * CursorDist; CursorPos2D = new Vector2((float)CursorPos.X, (float)CursorPos.Y); if (runs % 10 == 0) { DebugBuilder.Clear(); SinViewDegree = Math.Sin(ViewAngleDegrees * Math.PI / 180); CosViewDegree = Math.Cos(ViewAngleDegrees * Math.PI / 180); SpriteScratchpad.Clear(); int i; AddSprite("CircleHollow", new Vector2(0, 0), new Vector2(5, 5 * (float)CosViewDegree)); for (i = 10000; i <= MapSize; i += 10000) { var CircleSize = MapOnScreenSizeMeters * PixelsPerMeter * i / MapSize; AddSprite("CircleHollow", new Vector2(0, 0), new Vector2(CircleSize, CircleSize * (float)CosViewDegree), new Color(1f, 0.4f, 0f, 0.005f)); } var gravDir = Controller.GetNaturalGravity(); // Create map matrix if (gravDir != Vector3D.Zero) { // Within gravity, align with gravity = down // Either use controller's forward direction or north as forward gravDir.Normalize(); var flatNorthDir = new Vector3D(0, 1, 0) - VectorHelpers.VectorProjection(new Vector3D(0, 1, 0), gravDir); flatNorthDir.Normalize(); var flatForwardDir = AlignWithNorth ? flatNorthDir : (Controller.WorldMatrix.Forward - VectorHelpers.VectorProjection(AlignWithNorth ? new Vector3D(0, 1, 0) : Controller.WorldMatrix.Forward, gravDir)); flatForwardDir.Normalize(); var flatLeftDir = Vector3D.Cross(flatForwardDir, gravDir); MapMatrix.Up = -gravDir; MapMatrix.Forward = flatForwardDir; MapMatrix.Left = flatLeftDir; var localNorthDir = Vector3D.TransformNormal(flatNorthDir, MatrixD.Transpose(MapMatrix)); var localWestDir = Vector3D.Cross(localNorthDir, new Vector3D(0, -1, 0)); AddTextSprite("N", LocalCoordsToMapPosition(localNorthDir * MapSize * 0.5, true), 4); AddTextSprite("S", LocalCoordsToMapPosition(-localNorthDir * MapSize * 0.5, true), 4); AddTextSprite("W", LocalCoordsToMapPosition(localWestDir * MapSize * 0.5, true), 4); AddTextSprite("E", LocalCoordsToMapPosition(-localWestDir * MapSize * 0.5, true), 4); } else { // Else... idk just align with world axis? MapMatrix = MatrixD.Identity; } var intelItems = IntelProvider.GetFleetIntelligences(timestamp); DebugBuilder.AppendLine(intelItems.Count.ToString()); SelectionCandidates.Clear(); ClosestItemKey = MyTuple.Create(IntelItemType.NONE, (long)0); ClosestItemDist = 0.3f; LocalCoordsScratchpad.Clear(); ScreenCoordsScratchpad.Clear(); if (ActionMode == ActionSelectPosition) { AddTextSprite("><", CursorPos2D, 1, "Debug"); if (OnRelease) { if (SelectFlatPos == Vector2.PositiveInfinity) { SelectFlatPos = CursorPos2D; } else { SelectedPosition = FlatPosToGlobalPos(SelectFlatPos, CursorPos2D); SelectPositionCallback(timestamp); SelectFlatPos = Vector2.PositiveInfinity; ActionMode = ActionNone; } OnRelease = false; } if (SelectFlatPos != Vector2.PositiveInfinity) { var selectAltitudePos = SelectFlatPos; selectAltitudePos.Y = CursorPos2D.Y; var midPosition = (selectAltitudePos + SelectFlatPos) * 0.5f; var lineLength = Math.Abs(selectAltitudePos.Y - SelectFlatPos.Y); AddSprite("CircleHollow", selectAltitudePos, new Vector2(20, 20)); AddSprite("CircleHollow", SelectFlatPos, new Vector2(30, 30 * (float)CosViewDegree)); AddSprite("SquareSimple", midPosition, new Vector2(2, lineLength * PixelsPerMeter)); } } foreach (var kvp in intelItems) { Vector3D localCoords; Vector2 flatPosition, altitudePosition; GetMapCoordsFromIntel(kvp.Value, timestamp, out localCoords, out flatPosition, out altitudePosition); ScreenCoordsScratchpad.Add(flatPosition); ScreenCoordsScratchpad.Add(altitudePosition); LocalCoordsScratchpad.Add(localCoords); DebugBuilder.AppendLine(localCoords.ToString()); var distToItem = (altitudePosition - CursorPos2D).Length(); if (distToItem < ClosestItemDist) { ClosestItemDist = distToItem; ClosestItemKey = kvp.Key; } } DrawContextMenu(); if (ActionMode == ActionNone) { SelectionCandidates.Add(ClosestItemKey); if (OnRelease) { if (ClosestItemKey.Item1 == IntelItemType.NONE) { SelectedItems.Clear(); } else if (ClosestItemKey.Item1 != IntelItemType.Waypoint) { if (SelectedItems.Count > 0 && SelectedItems[0].Item2 != ClosestItemKey.Item2) { SelectedItems.Clear(); } SelectedItems.Add(ClosestItemKey); } } } i = 0; foreach (var kvp in intelItems) { AddFleetIntelToMap(kvp.Value, timestamp, LocalCoordsScratchpad[i], ScreenCoordsScratchpad[2 * i], ScreenCoordsScratchpad[2 * i + 1]); i++; } // var text = Turret.IsShooting ? "[><]" : "><"; // AddTextSprite(text, CursorPos2D, 2, "Debug"); foreach (var kvp in Panels) { DrawSpritesForPanel(kvp.Key); } OnRelease = false; } LastFrameMouseDown = Turret.IsShooting; }
void AddFleetIntelToMap(IFleetIntelligence intel, TimeSpan localTime, Vector3D localCoords, Vector2 flatPosition, Vector2 altitudePosition) { if (localCoords.Length() > MapSize) { return; } var intelKey = MyTuple.Create(intel.Type, intel.ID); var color = Color.White; if (intel.Type == IntelItemType.Friendly) { if ((((FriendlyShipIntel)intel).AgentStatus & AgentStatus.DockedAtHome) != 0) { return; } color = Color.Blue; if (SelectionCandidates.Contains(intelKey)) { color = Color.LightSkyBlue; } else if (SelectedItems.Contains(intelKey)) { color = Color.Teal; } } else if (intel.Type == IntelItemType.Enemy) { color = Color.Red; var lastDetectedTime = localTime + IntelProvider.CanonicalTimeDiff - ((EnemyShipIntel)intel).LastValidatedCanonicalTime; if (lastDetectedTime > TimeSpan.FromSeconds(4)) { color = new Color(1f, 0f, 0f, 0.002f); } else if (lastDetectedTime > TimeSpan.FromSeconds(3)) { color = new Color(1f, 0f, 0f, 0.005f); } else if (lastDetectedTime > TimeSpan.FromSeconds(2)) { color = new Color(1f, 0f, 0f, 0.007f); } } else if (intel.Type == IntelItemType.Waypoint) { color = Color.Green; } else { return; } var middlePosition = (altitudePosition + flatPosition) * 0.5f; var lineLength = MapScale * Math.Abs((float)localCoords.Y) * (float)SinViewDegree; AddSprite("CircleHollow", altitudePosition, new Vector2(20, 20), color); if (intel.ID != Controller.CubeGrid.EntityId) { AddSprite("CircleHollow", flatPosition, new Vector2(30, 30 * (float)CosViewDegree), color); AddSprite("SquareSimple", middlePosition, new Vector2(2, lineLength * PixelsPerMeter), color); } if (intel.Type == IntelItemType.Friendly) { AddSprite("CircleHollow", altitudePosition, new Vector2(2 * ScannerRange * MapScale * PixelsPerMeter), color); if (Math.Abs((float)localCoords.Y) < ScannerRange) { AddSprite("CircleHollow", flatPosition, new Vector2(2 * (float)Math.Sqrt(ScannerRange * ScannerRange - localCoords.Y * localCoords.Y) * MapScale * PixelsPerMeter, 2 * (float)(Math.Sqrt(ScannerRange * ScannerRange - localCoords.Y * localCoords.Y) * MapScale * PixelsPerMeter * CosViewDegree)), color); } } return; }